Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support menu-complete-backward command for upward navigation #677

Merged
merged 1 commit into from
Apr 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 15 additions & 13 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ def reset_variables(prompt = '', encoding:)
@waiting_operator_vi_arg = nil
@completion_journey_state = nil
@completion_state = CompletionState::NORMAL
@completion_occurs = false
@perfect_matched = nil
@menu_info = nil
@searching_prompt = nil
Expand Down Expand Up @@ -1118,42 +1119,35 @@ def input_key(key)
end
old_lines = @buffer_of_lines.dup
@first_char = false
completion_occurs = false
@completion_occurs = false
if @config.editing_mode_is?(:emacs, :vi_insert) and key.char == "\C-i".ord
if !@config.disable_completion
process_insert(force: true)
if @config.autocompletion
@completion_state = CompletionState::NORMAL
completion_occurs = move_completed_list(:down)
@completion_occurs = move_completed_list(:down)
else
@completion_journey_state = nil
result = call_completion_proc
if result.is_a?(Array)
completion_occurs = true
@completion_occurs = true
complete(result, false)
end
end
end
elsif @config.editing_mode_is?(:emacs, :vi_insert) and key.char == :completion_journey_up
if not @config.disable_completion and @config.autocompletion
process_insert(force: true)
@completion_state = CompletionState::NORMAL
completion_occurs = move_completed_list(:up)
end
elsif @config.editing_mode_is?(:vi_insert) and ["\C-p".ord, "\C-n".ord].include?(key.char)
# In vi mode, move completed list even if autocompletion is off
if not @config.disable_completion
process_insert(force: true)
@completion_state = CompletionState::NORMAL
completion_occurs = move_completed_list("\C-p".ord == key.char ? :up : :down)
@completion_occurs = move_completed_list("\C-p".ord == key.char ? :up : :down)
end
elsif Symbol === key.char and respond_to?(key.char, true)
process_key(key.char, key.char)
else
normal_char(key)
end

unless completion_occurs
unless @completion_occurs
@completion_state = CompletionState::NORMAL
@completion_journey_state = nil
end
Expand All @@ -1164,7 +1158,7 @@ def input_key(key)
end

modified = old_lines != @buffer_of_lines
if !completion_occurs && modified && !@config.disable_completion && @config.autocompletion
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
Expand Down Expand Up @@ -1433,6 +1427,14 @@ def finish
end
end

private def completion_journey_up(key)
if not @config.disable_completion and @config.autocompletion
@completion_state = CompletionState::NORMAL
@completion_occurs = move_completed_list(:up)
end
end
alias_method :menu_complete_backward, :completion_journey_up

# Editline:: +ed-unassigned+ This editor command always results in an error.
# GNU Readline:: There is no corresponding macro.
private def ed_unassigned(key) end # do nothing
Expand Down
46 changes: 46 additions & 0 deletions test/reline/test_key_actor_emacs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -789,6 +789,52 @@ def test_completion
assert_line_around_cursor('foo_ba', '')
end

def test_autocompletion_with_upward_navigation
@config.autocompletion = true
@line_editor.completion_proc = proc { |word|
%w{
Readline
Regexp
RegexpError
}.map { |i|
i.encode(@encoding)
}
}
input_keys('Re')
assert_line_around_cursor('Re', '')
input_keys("\C-i", false)
assert_line_around_cursor('Readline', '')
input_keys("\C-i", false)
assert_line_around_cursor('Regexp', '')
@line_editor.input_key(Reline::Key.new(:completion_journey_up, :completion_journey_up, false))
assert_line_around_cursor('Readline', '')
ensure
@config.autocompletion = false
end

def test_autocompletion_with_upward_navigation_and_menu_complete_backward
@config.autocompletion = true
@line_editor.completion_proc = proc { |word|
%w{
Readline
Regexp
RegexpError
}.map { |i|
i.encode(@encoding)
}
}
input_keys('Re')
assert_line_around_cursor('Re', '')
input_keys("\C-i", false)
assert_line_around_cursor('Readline', '')
input_keys("\C-i", false)
assert_line_around_cursor('Regexp', '')
@line_editor.input_key(Reline::Key.new(:menu_complete_backward, :menu_complete_backward, false))
assert_line_around_cursor('Readline', '')
ensure
@config.autocompletion = false
end

def test_completion_with_indent
@line_editor.completion_proc = proc { |word|
%w{
Expand Down
46 changes: 46 additions & 0 deletions test/reline/test_key_actor_vi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,52 @@ def test_completion
assert_line_around_cursor('foo_bar', '')
end

def test_autocompletion_with_upward_navigation
@config.autocompletion = true
@line_editor.completion_proc = proc { |word|
%w{
Readline
Regexp
RegexpError
}.map { |i|
i.encode(@encoding)
}
}
input_keys('Re')
assert_line_around_cursor('Re', '')
input_keys("\C-i", false)
assert_line_around_cursor('Readline', '')
input_keys("\C-i", false)
assert_line_around_cursor('Regexp', '')
@line_editor.input_key(Reline::Key.new(:completion_journey_up, :completion_journey_up, false))
assert_line_around_cursor('Readline', '')
ensure
@config.autocompletion = false
end

def test_autocompletion_with_upward_navigation_and_menu_complete_backward
@config.autocompletion = true
@line_editor.completion_proc = proc { |word|
%w{
Readline
Regexp
RegexpError
}.map { |i|
i.encode(@encoding)
}
}
input_keys('Re')
assert_line_around_cursor('Re', '')
input_keys("\C-i", false)
assert_line_around_cursor('Readline', '')
input_keys("\C-i", false)
assert_line_around_cursor('Regexp', '')
@line_editor.input_key(Reline::Key.new(:menu_complete_backward, :menu_complete_backward, false))
assert_line_around_cursor('Readline', '')
ensure
@config.autocompletion = false
end

def test_completion_with_disable_completion
@config.disable_completion = true
@line_editor.completion_proc = proc { |word|
Expand Down