Class: Textbringer::CompletionPopup
- Inherits:
-
Object
- Object
- Textbringer::CompletionPopup
- Defined in:
- lib/textbringer/completion_popup.rb,
sig/lib/textbringer/completion_popup.rbs
Constant Summary collapse
- MAX_VISIBLE_ITEMS =
10- MIN_WIDTH =
20- MAX_WIDTH =
60
Instance Attribute Summary collapse
-
#items ⇒ Object
readonly
Returns the value of attribute items.
-
#selected_index ⇒ Object
readonly
Returns the value of attribute selected_index.
-
#start_point ⇒ Object
readonly
Returns the value of attribute start_point.
Class Method Summary collapse
Instance Method Summary collapse
- #accept ⇒ Object
- #calculate_scroll_offset(visible_count) ⇒ Integer
- #calculate_width ⇒ Integer
- #cancel ⇒ nil
- #close ⇒ String
- #create_or_update_window ⇒ Textbringer::FloatingWindow
- #current_item ⇒ Object
- #display_width(str) ⇒ Integer
- #format_item(item) ⇒ String
- #hide ⇒ Textbringer::FloatingWindow
-
#initialize ⇒ CompletionPopup
constructor
A new instance of CompletionPopup.
- #render ⇒ Integer
- #select_next ⇒ nil
- #select_previous ⇒ nil
- #show(items:, start_point:, prefix: "") ⇒ Object
- #visible? ⇒ Boolean
- #visible_item_count ⇒ Integer
Constructor Details
#initialize ⇒ CompletionPopup
Returns a new instance of CompletionPopup.
13 14 15 16 17 18 19 |
# File 'lib/textbringer/completion_popup.rb', line 13 def initialize @floating_window = nil @items = [] @selected_index = 0 @start_point = nil @prefix = "" end |
Instance Attribute Details
#items ⇒ Object (readonly)
Returns the value of attribute items.
7 8 9 |
# File 'lib/textbringer/completion_popup.rb', line 7 def items @items end |
#selected_index ⇒ Object (readonly)
Returns the value of attribute selected_index.
7 8 9 |
# File 'lib/textbringer/completion_popup.rb', line 7 def selected_index @selected_index end |
#start_point ⇒ Object (readonly)
Returns the value of attribute start_point.
7 8 9 |
# File 'lib/textbringer/completion_popup.rb', line 7 def start_point @start_point end |
Class Method Details
.instance ⇒ Textbringer::CompletionPopup
9 10 11 |
# File 'lib/textbringer/completion_popup.rb', line 9 def self.instance @instance ||= new end |
Instance Method Details
#accept ⇒ Hash[untyped, untyped] #accept ⇒ nil
67 68 69 70 71 72 |
# File 'lib/textbringer/completion_popup.rb', line 67 def accept return nil unless visible? && !@items.empty? item = current_item close item end |
#calculate_scroll_offset(visible_count) ⇒ Integer
149 150 151 152 153 154 155 |
# File 'lib/textbringer/completion_popup.rb', line 149 def calculate_scroll_offset(visible_count) if @selected_index < visible_count 0 else @selected_index - visible_count + 1 end end |
#calculate_width ⇒ Integer
108 109 110 111 112 113 114 115 116 |
# File 'lib/textbringer/completion_popup.rb', line 108 def calculate_width max_label_width = @items.map { |item| display_width(item[:label]) }.max || 0 max_detail_width = @items.map { |item| item[:detail] ? display_width(item[:detail]) + 2 : 0 }.max || 0 width = max_label_width + max_detail_width + 2 # padding [[width, MIN_WIDTH].max, MAX_WIDTH].min end |
#cancel ⇒ nil
74 75 76 77 |
# File 'lib/textbringer/completion_popup.rb', line 74 def cancel close nil end |
#close ⇒ String
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/textbringer/completion_popup.rb', line 38 def close if @floating_window @floating_window.close @floating_window = nil end @items = [] @selected_index = 0 @start_point = nil @prefix = "" end |
#create_or_update_window ⇒ Textbringer::FloatingWindow
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/textbringer/completion_popup.rb', line 86 def create_or_update_window lines = visible_item_count columns = calculate_width if @floating_window && !@floating_window.deleted? @floating_window.resize(lines, columns) y, x = FloatingWindow.calculate_cursor_position(lines, columns, Window.current) @floating_window.move_to(y: y, x: x) else @floating_window = FloatingWindow.at_cursor( lines: lines, columns: columns, face: :completion_popup, current_line_face: :completion_popup_selected ) end end |
#current_item ⇒ Hash[untyped, untyped] #current_item ⇒ nil
79 80 81 82 |
# File 'lib/textbringer/completion_popup.rb', line 79 def current_item return nil if @items.empty? @items[@selected_index] end |
#display_width(str) ⇒ Integer
118 119 120 121 |
# File 'lib/textbringer/completion_popup.rb', line 118 def display_width(str) return 0 unless str Buffer.display_width(str) end |
#format_item(item) ⇒ String
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/textbringer/completion_popup.rb', line 157 def format_item(item) label = item[:label] || "" detail = item[:detail] # Build the display string result = label if detail result = "#{label} #{detail}" end # Truncate if too long width = calculate_width if display_width(result) > width result = truncate_to_width(result, width - 1) + "…" end result end |
#hide ⇒ Textbringer::FloatingWindow
34 35 36 |
# File 'lib/textbringer/completion_popup.rb', line 34 def hide @floating_window&.hide end |
#render ⇒ Integer
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/textbringer/completion_popup.rb', line 123 def render buffer = @floating_window.buffer buffer.read_only = false begin buffer.clear # Calculate visible range with scroll visible_count = visible_item_count scroll_offset = calculate_scroll_offset(visible_count) visible_items = @items[scroll_offset, visible_count] visible_items.each_with_index do |item, index| line = format_item(item) buffer.insert(line) buffer.insert("\n") end # Go to the selected line so current_line_face highlights it relative_index = @selected_index - scroll_offset buffer.goto_line(relative_index + 1) buffer.beginning_of_line ensure buffer.read_only = true end end |
#select_next ⇒ nil
53 54 55 56 57 58 |
# File 'lib/textbringer/completion_popup.rb', line 53 def select_next return unless visible? && !@items.empty? @selected_index = (@selected_index + 1) % @items.size render @floating_window.redisplay end |
#select_previous ⇒ nil
60 61 62 63 64 65 |
# File 'lib/textbringer/completion_popup.rb', line 60 def select_previous return unless visible? && !@items.empty? @selected_index = (@selected_index - 1) % @items.size render @floating_window.redisplay end |
#show(items:, start_point:, prefix:) ⇒ Textbringer::FloatingWindow #show(items:, start_point:, prefix:) ⇒ nil
21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/textbringer/completion_popup.rb', line 21 def show(items:, start_point:, prefix: "") @items = items @start_point = start_point @prefix = prefix @selected_index = 0 return if @items.empty? create_or_update_window render @floating_window.show end |
#visible? ⇒ Boolean
49 50 51 |
# File 'lib/textbringer/completion_popup.rb', line 49 def visible? @floating_window&.visible? || false end |
#visible_item_count ⇒ Integer
104 105 106 |
# File 'lib/textbringer/completion_popup.rb', line 104 def visible_item_count [@items.size, MAX_VISIBLE_ITEMS].min end |