Skip to content

Commit

Permalink
Move completion candidate listup logic from dialog proc to LineEditor
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng committed Apr 1, 2024
1 parent 1f9111f commit 4c645a4
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 36 deletions.
20 changes: 6 additions & 14 deletions lib/reline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,21 +222,13 @@ def get_screen_size
return unless config.autocompletion

journey_data = completion_journey_data
if just_cursor_moving and journey_data.nil?
# Auto complete starts only when edited
return
end
if journey_data
result = journey_data.list.drop(1)
pointer = journey_data.pointer - 1
target = journey_data.list[journey_data.pointer]
else
pre, target, post = retrieve_completion_block(true)
return if target.nil? || target.empty?
return unless journey_data

target = journey_data.list[journey_data.pointer]
result = journey_data.list.drop(1)
pointer = journey_data.pointer - 1
return if target.empty? || (result == [target] && pointer < 0)

result = call_completion_proc_with_checking_args(pre, target, post)
return if result and result.size == 1 and result[0] == target
end
target_width = Reline::Unicode.calculate_width(target)
x = cursor_pos.x - target_width
if x < 0
Expand Down
52 changes: 30 additions & 22 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -886,33 +886,32 @@ def dialog_proc_scope_completion_journey_data
end

private def move_completed_list(direction)
if @completion_journey_state
if (delta = { up: -1, down: +1 }[direction])
@completion_journey_state.pointer = (@completion_journey_state.pointer + delta) % @completion_journey_state.list.size
end
else
preposing, target, postposing = retrieve_completion_block
return false unless target

list = call_completion_proc
return false unless list.is_a?(Array)
@completion_journey_state ||= retrieve_completion_journey_state
return false unless @completion_journey_state

candidates = list.select{ |item| item.start_with?(target) }
return false if candidates.empty?

pre = preposing.split("\n", -1).last || ''
post = postposing.split("\n", -1).first || ''
pointer = direction == :up ? candidates.size : 1
@completion_journey_state = CompletionJourneyState.new(
@line_index, pre, target, post, [target] + candidates, pointer
)
if (delta = { up: -1, down: +1 }[direction])
@completion_journey_state.pointer = (@completion_journey_state.pointer + delta) % @completion_journey_state.list.size
end

completed = @completion_journey_state.list[@completion_journey_state.pointer]
set_current_line(@completion_journey_state.pre + completed + @completion_journey_state.post, @completion_journey_state.pre.bytesize + completed.bytesize)
true
end

private def retrieve_completion_journey_state
preposing, target, postposing = retrieve_completion_block
list = call_completion_proc
return unless list.is_a?(Array)

candidates = list.select{ |item| item.start_with?(target) }
return if candidates.empty?

pre = preposing.split("\n", -1).last || ''
post = postposing.split("\n", -1).first || ''
CompletionJourneyState.new(
@line_index, pre, target, post, [target] + candidates, 0
)
end

private def run_for_operators(key, method_symbol, &block)
if @waiting_operator_proc
if VI_MOTIONS.include?(method_symbol)
Expand Down Expand Up @@ -1131,15 +1130,24 @@ def input_key(key)
else
normal_char(key)
end

unless completion_occurs
@completion_state = CompletionState::NORMAL
@completion_journey_state = nil
end

if @in_pasting
clear_dialogs
else
return old_lines != @buffer_of_lines
return
end

modified = old_lines != @buffer_of_lines
if !completion_occurs && modified && !@config.disable_completion && @config.autocompletion
# Auto complete starts only when edited
process_insert(force: true)
@completion_journey_state = retrieve_completion_journey_state
end
modified
end

def scroll_into_view
Expand Down
13 changes: 13 additions & 0 deletions test/reline/yamatanooroti/test_rendering.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,19 @@ def test_autocomplete_target_is_wrapped
EOC
end

def test_force_insert_before_autocomplete
start_terminal(20, 20, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --autocomplete}, startup_message: 'Multiline REPL.')
write('Sy')
write(";St\t\t")
close
assert_screen(<<~'EOC')
Multiline REPL.
prompt> Sy;Struct
String
Struct
EOC
end

def test_simple_dialog_with_scroll_key
start_terminal(20, 50, %W{ruby -I#{@pwd}/lib #{@pwd}/test/reline/yamatanooroti/multiline_repl --dialog long,scrollkey}, startup_message: 'Multiline REPL.')
write('a')
Expand Down

0 comments on commit 4c645a4

Please sign in to comment.