@@ -10,6 +10,7 @@ local renderer = require('blink.cmp.windows.lib.render')
10
10
local autocmp_config = config .windows .autocomplete
11
11
local autocomplete = {
12
12
items = {},
13
+ has_selected = nil ,
13
14
context = nil ,
14
15
event_targets = {
15
16
on_position_update = {},
@@ -25,7 +26,7 @@ function autocomplete.setup()
25
26
max_height = autocmp_config .max_height ,
26
27
border = autocmp_config .border ,
27
28
winhighlight = autocmp_config .winhighlight ,
28
- cursorline = true ,
29
+ cursorline = false ,
29
30
scrolloff = autocmp_config .scrolloff ,
30
31
})
31
32
@@ -64,6 +65,7 @@ function autocomplete.open_with_items(context, items)
64
65
65
66
autocomplete .context = context
66
67
autocomplete .update_position (context )
68
+ autocomplete .set_has_selected (autocmp_config .preselect )
67
69
68
70
-- todo: some logic to maintain the selection if the user moved the cursor?
69
71
vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { 1 , 0 })
73
75
function autocomplete .open ()
74
76
if autocomplete .win :is_open () then return end
75
77
autocomplete .win :open ()
78
+ autocomplete .set_has_selected (autocmp_config .preselect )
76
79
end
77
80
78
81
function autocomplete .close ()
79
82
if not autocomplete .win :is_open () then return end
80
83
autocomplete .win :close ()
84
+ autocomplete .has_selected = autocmp_config .preselect
81
85
autocomplete .event_targets .on_close ()
82
86
end
83
87
function autocomplete .listen_on_close (callback ) autocomplete .event_targets .on_close = callback end
@@ -136,49 +140,57 @@ end
136
140
function autocomplete .select_next ()
137
141
if not autocomplete .win :is_open () then return end
138
142
139
- local current_line = vim .api .nvim_win_get_cursor (autocomplete .win :get_win ())[1 ]
140
- local line_count = vim .api .nvim_buf_line_count (autocomplete .win :get_buf ())
141
143
local cycle_from_bottom = config .windows .autocomplete .cycle .from_bottom
142
- local is_last_completion = current_line == line_count
143
-
144
- -- at the end of completion list and the config is not enabled: do nothing
145
- if is_last_completion and not cycle_from_bottom then return end
146
- if is_last_completion then
147
- -- at the end of completion list and the config is enabled: cycle back to first completion
148
- vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { 1 , 0 })
149
- autocomplete .event_targets .on_select (autocomplete .get_selected_item (), autocomplete .context )
144
+ local l = # autocomplete .items
145
+ local line = vim .api .nvim_win_get_cursor (autocomplete .win :get_win ())[1 ]
146
+ -- We need to ajust the disconnect between the line position
147
+ -- on the window and the selected item
148
+ if not autocomplete .has_selected then line = line - 1 end
149
+ if line == l then
150
+ -- at the end of completion list and the config is not enabled: do nothing
151
+ if not cycle_from_bottom then return end
152
+ line = 1
150
153
else
151
- -- select next completion
152
- vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { current_line + 1 , 0 })
153
- autocomplete .event_targets .on_select (autocomplete .get_selected_item (), autocomplete .context )
154
+ line = line + 1
154
155
end
156
+
157
+ autocomplete .set_has_selected (true )
158
+
159
+ autocomplete .win :set_option_values (' cursorline' , true )
160
+ vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { line , 0 })
161
+ autocomplete .event_targets .on_select (autocomplete .get_selected_item (), autocomplete .context )
155
162
end
156
163
157
164
function autocomplete .select_prev ()
158
165
if not autocomplete .win :is_open () then return end
159
166
160
- local current_line = vim .api .nvim_win_get_cursor (autocomplete .win :get_win ())[1 ]
161
- local line_count = vim .api .nvim_buf_line_count (autocomplete .win :get_buf ())
162
167
local cycle_from_top = config .windows .autocomplete .cycle .from_top
163
- local is_first_completion = current_line == 1
164
-
165
- -- at the beginning of completion list and the config is not enabled: do nothing
166
- if is_first_completion and not cycle_from_top then return end
167
- if is_first_completion then
168
- -- at the beginning of completion list and the config is enabled: cycle back to last completion
169
- vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { line_count , 0 })
170
- autocomplete .event_targets .on_select (autocomplete .get_selected_item (), autocomplete .context )
168
+ local l = # autocomplete .items
169
+ local line = vim .api .nvim_win_get_cursor (autocomplete .win :get_win ())[1 ]
170
+ if line <= 1 then
171
+ if not cycle_from_top then return end
172
+ line = l
171
173
else
172
- -- select previous completion
173
- vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { math.max (current_line - 1 , 1 ), 0 })
174
- autocomplete .event_targets .on_select (autocomplete .get_selected_item (), autocomplete .context )
174
+ line = line - 1
175
175
end
176
+
177
+ autocomplete .set_has_selected (true )
178
+
179
+ autocomplete .win :set_option_values (' cursorline' , true )
180
+ vim .api .nvim_win_set_cursor (autocomplete .win :get_win (), { line , 0 })
181
+ autocomplete .event_targets .on_select (autocomplete .get_selected_item (), autocomplete .context )
176
182
end
177
183
178
184
function autocomplete .listen_on_select (callback ) autocomplete .event_targets .on_select = callback end
179
185
180
186
---- ------ Rendering ----------
181
187
188
+ function autocomplete .set_has_selected (selected )
189
+ if not autocomplete .win :is_open () then return end
190
+ autocomplete .has_selected = selected
191
+ autocomplete .win :set_option_values (' cursorline' , selected )
192
+ end
193
+
182
194
function autocomplete .draw ()
183
195
local draw_fn = autocomplete .get_draw_fn ()
184
196
local icon_gap = config .nerd_font_variant == ' mono' and ' ' or ' '
247
259
248
260
function autocomplete .get_selected_item ()
249
261
if not autocomplete .win :is_open () then return end
250
- local current_line = vim .api .nvim_win_get_cursor (autocomplete .win :get_win ())[1 ]
251
- return autocomplete .items [current_line ]
262
+ if not autocomplete .has_selected then return end
263
+ local line = vim .api .nvim_win_get_cursor (autocomplete .win :get_win ())[1 ]
264
+ return autocomplete .items [line ]
252
265
end
253
266
254
267
return autocomplete
0 commit comments