Skip to content

Commit

Permalink
Align completion menu items
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng committed Nov 29, 2023
1 parent 8937279 commit 53c5b9e
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
30 changes: 26 additions & 4 deletions lib/reline/line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,29 @@ module CompletionState
end

CompletionJourneyData = Struct.new(:preposing, :postposing, :list, :pointer)
MenuInfo = Struct.new(:target, :list)

class MenuInfo
attr_reader :list

def initialize(list)
@list = list
end

def lines(screen_width)
return [] if @list.empty?

list = @list.sort
sizes = list.map { |item| Reline::Unicode.calculate_width(item) }
item_width = sizes.max + 2
num_cols = [screen_width / item_width, 1].max
num_rows = list.size.fdiv(num_cols).ceil
list_with_padding = list.zip(sizes).map { |item, size| item + ' ' * (item_width - size) }
aligned = (list_with_padding + [nil] * (num_rows * num_cols - list_with_padding.size)).each_slice(num_rows).to_a.transpose
aligned.map do |row|
row.join.rstrip
end
end
end

PROMPT_LIST_CACHE_TIMEOUT = 0.5
MINIMUM_SCROLLBAR_HEIGHT = 1
Expand Down Expand Up @@ -1192,7 +1214,7 @@ def just_move_cursor
private def show_menu
scroll_down(@highest_in_all - @first_line_started_from)
@rerender_all = true
@menu_info.list.sort!.each do |item|
@menu_info.lines(@screen_size.last).each do |item|
Reline::IOGate.move_cursor_column(0)
@output.write item
@output.flush
Expand Down Expand Up @@ -1227,8 +1249,8 @@ def editing_mode
@config.editing_mode
end

private def menu(target, list)
@menu_info = MenuInfo.new(target, list)
private def menu(_target, list)
@menu_info = MenuInfo.new(list)
end

private def complete_internal_proc(list, is_menu)
Expand Down
25 changes: 25 additions & 0 deletions test/reline/test_line_editor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,29 @@ def test_range_subtract
expected_result = [3...5, 7...8, 9...10, 13...17, 19...20]
assert_equal expected_result, editor.send(:range_subtract, base_ranges, subtract_ranges)
end

def test_menu_info_format
list = %w[aa b c d e f g hhh i j k]
col3 = [
'aa e i',
'b f j',
'c g k',
'd hhh'
]
col2 = [
'aa g',
'b hhh',
'c i',
'd j',
'e k',
'f'
]
assert_equal(col3, Reline::LineEditor::MenuInfo.new(list).lines(19))
assert_equal(col3, Reline::LineEditor::MenuInfo.new(list).lines(15))
assert_equal(col2, Reline::LineEditor::MenuInfo.new(list).lines(14))
assert_equal(col2, Reline::LineEditor::MenuInfo.new(list).lines(10))
assert_equal(list, Reline::LineEditor::MenuInfo.new(list).lines(9))
assert_equal(list, Reline::LineEditor::MenuInfo.new(list).lines(0))
assert_equal([], Reline::LineEditor::MenuInfo.new([]).lines(10))
end
end

0 comments on commit 53c5b9e

Please sign in to comment.