Skip to content

Commit

Permalink
Cache symbol completion result
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng committed Oct 17, 2024
1 parent 5151467 commit f012adc
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 3 deletions.
22 changes: 19 additions & 3 deletions lib/irb/completion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,22 @@ def doc_namespace(_preposing, matched, _postposing, bind:)
retrieve_completion_data(matched, bind: bind, doc_namespace: true)
end

def clear_symbol_cache
@all_symbols = nil
end

def symbol_candidates(prefix, first:, last:)
limit = first + last
symbols = @all_symbols ||= Symbol.all_symbols.sort
start_index = symbols.bsearch_index { |sym| sym.to_s >= prefix }
end_index = (start_index...symbols.size).bsearch { |i| !symbols[i].start_with?(prefix) } || symbols.size
if end_index - start_index <= limit
symbols[start_index..end_index]
else
symbols[start_index, first] + symbols[end_index - last, last]
end
end

def retrieve_completion_data(input, bind:, doc_namespace:)
case input
# this regexp only matches the closing character because of irb's Reline.completer_quote_characters setting
Expand Down Expand Up @@ -280,12 +296,12 @@ def retrieve_completion_data(input, bind:, doc_namespace:)
nil
else
sym = $1
candidates = Symbol.all_symbols.collect do |s|
s.inspect
candidates = symbol_candidates(sym[1..], first: 50, last: 50).filter_map do |s|
ins = s.inspect
ins if ins.start_with?(sym)
rescue EncodingError
# ignore
end
candidates.grep(/^#{Regexp.quote(sym)}/)
end
when /^::([A-Z][^:\.\(\)]*)$/
# Absolute Constant or class methods
Expand Down
1 change: 1 addition & 0 deletions lib/irb/input-method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ def gets
Reline.output = @stdout
Reline.prompt_proc = @prompt_proc
Reline.auto_indent_proc = @auto_indent_proc if @auto_indent_proc
@completor.clear_symbol_cache if @completor.respond_to? :clear_symbol_cache
if l = Reline.readmultiline(@prompt, false, &@check_termination_proc)
Reline::HISTORY.push(l) if !l.empty?
@line[@line_no += 1] = l + "\n"
Expand Down

0 comments on commit f012adc

Please sign in to comment.