@@ -213,28 +213,17 @@ function Picker:clear_extra_rows(results_bufnr)
213213 end
214214
215215 if not ok then
216- log .debug (msg )
216+ log .debug (" Failed to set lines: " , msg )
217217 end
218218
219219 log .trace (" Clearing:" , worst_line )
220220end
221221
222- function Picker :highlight_displayed_rows (results_bufnr , prompt )
223- if not self .sorter or not self . sorter .highlighter then
222+ function Picker :highlight_one_row (results_bufnr , prompt , display , row )
223+ if not self .sorter .highlighter then
224224 return
225225 end
226226
227- vim .api .nvim_buf_clear_namespace (results_bufnr , ns_telescope_matching , 0 , - 1 )
228-
229- local displayed_rows = vim .api .nvim_buf_get_lines (results_bufnr , 0 , - 1 , false )
230- for row_index = 1 , math.min (# displayed_rows , self .max_results ) do
231- local display = displayed_rows [row_index ]
232-
233- self :highlight_one_row (results_bufnr , prompt , display , row_index - 1 )
234- end
235- end
236-
237- function Picker :highlight_one_row (results_bufnr , prompt , display , row )
238227 local highlights = self .sorter :highlighter (prompt , display )
239228
240229 if highlights then
@@ -352,22 +341,19 @@ function Picker:find()
352341 self .prompt_prefix = prompt_prefix
353342 self :_reset_prefix_color ()
354343
355- -- First thing we want to do is set all the lines to blank.
356- self .max_results = popup_opts .results .height
344+ -- TODO: This could be configurable in the future, but I don't know why you would
345+ -- want to scroll through more than 10,000 items.
346+ --
347+ -- This just lets us stop doing stuff after tons of things.
348+ self .max_results = 1000
357349
358- -- TODO(scrolling): This may be a hack when we get a little further into implementing scrolling.
359350 vim .api .nvim_buf_set_lines (results_bufnr , 0 , self .max_results , false , utils .repeated_table (self .max_results , " " ))
360351
361- -- TODO(status): I would love to get the status text not moving back and forth. Perhaps it is just a problem with
362- -- virtual text & prompt buffers or something though. I can't figure out why it would redraw the way it does.
363- --
364- -- A "hacked" version of this would be to calculate where the area I want the status to go and put a new window there.
365- -- With this method, I do not need to worry about padding or antying, just make it take up X characters or something.
366352 local status_updater = self :get_status_updater (prompt_win , prompt_bufnr )
367353 local debounced_status = debounce .throttle_leading (status_updater , 50 )
368354
369355 local tx , rx = channel .mpsc ()
370- self .__on_lines = tx .send
356+ self ._on_lines = tx .send
371357
372358 local find_id = self :_next_find_id ()
373359
@@ -412,25 +398,14 @@ function Picker:find()
412398
413399 local start_time = vim .loop .hrtime ()
414400
415- local prompt = self :_get_prompt ()
416- local on_input_result = self ._on_input_filter_cb (prompt ) or {}
417-
418- local new_prompt = on_input_result .prompt
419- if new_prompt then
420- prompt = new_prompt
421- end
422-
423- local new_finder = on_input_result .updated_finder
424- if new_finder then
425- self .finder :close ()
426- self .finder = new_finder
427- end
401+ local prompt = self :_get_next_filtered_prompt ()
428402
429403 -- TODO: Entry manager should have a "bulk" setter. This can prevent a lot of redraws from display
430404 if self .cache_picker == false or not (self .cache_picker .is_cached == true ) then
431405 self .sorter :_start (prompt )
432406 self .manager = EntryManager :new (self .max_results , self .entry_adder , self .stats )
433407
408+ vim .api .nvim_buf_clear_namespace (results_bufnr , ns_telescope_matching , 0 , - 1 )
434409 local process_result = self :get_result_processor (find_id , prompt , debounced_status )
435410 local process_complete = self :get_result_completor (self .results_bufnr , find_id , prompt , status_updater )
436411
@@ -447,26 +422,8 @@ function Picker:find()
447422 async .util .sleep (self .debounce - diff_time )
448423 end
449424 else
450- -- resume previous picker
451- local index = 1
452- for entry in self .manager :iter () do
453- self :entry_adder (index , entry , _ , true )
454- index = index + 1
455- end
456- self .cache_picker .is_cached = false
457- -- if text changed, required to set anew to restart finder; otherwise hl and selection
458- if self .cache_picker .cached_prompt ~= self .default_text then
459- self :reset_prompt ()
460- self :set_prompt (self .default_text )
461- else
462- -- scheduling required to apply highlighting and selection appropriately
463- await_schedule (function ()
464- self :highlight_displayed_rows (self .results_bufnr , self .cache_picker .cached_prompt )
465- if self .cache_picker .selection_row ~= nil then
466- self :set_selection (self .cache_picker .selection_row )
467- end
468- end )
469- end
425+ -- TODO(scroll): This can only happen once, I don't like where it is.
426+ self :_resume_picker ()
470427 end
471428 end
472429 end )
@@ -476,10 +433,10 @@ function Picker:find()
476433 on_lines = function (...)
477434 find_id = self :_next_find_id ()
478435
479- self ._result_completed = false
480436 status_updater { completed = false }
481- tx . send (... )
437+ self . _on_lines (... )
482438 end ,
439+
483440 on_detach = function ()
484441 self :_detach ()
485442 end ,
@@ -753,7 +710,7 @@ function Picker:refresh(finder, opts)
753710 self ._multi = MultiSelect :new ()
754711 end
755712
756- self .__on_lines (nil , nil , nil , 0 , 1 )
713+ self ._on_lines (nil , nil , nil , 0 , 1 )
757714end
758715
759716function Picker :set_selection (row )
@@ -856,6 +813,8 @@ function Picker:set_selection(row)
856813 self ._selection_row = row
857814
858815 self :refresh_previewer ()
816+
817+ vim .api .nvim_win_set_cursor (self .results_win , { row + 1 , 0 })
859818end
860819
861820function Picker :refresh_previewer ()
@@ -918,43 +877,41 @@ function Picker:entry_adder(index, entry, _, insert)
918877
919878 self :_increment " displayed"
920879
921- -- TODO: Don't need to schedule this if we schedule the adder.
922880 local offset = insert and 0 or 1
923- vim .schedule (function ()
924- if not vim .api .nvim_buf_is_valid (self .results_bufnr ) then
925- log .debug " ON_ENTRY: Invalid buffer"
926- return
927- end
881+ if not vim .api .nvim_buf_is_valid (self .results_bufnr ) then
882+ log .debug " ON_ENTRY: Invalid buffer"
883+ return
884+ end
928885
929- -- TODO: Does this every get called?
930- -- local line_count = vim.api.nvim_win_get_height(self.results_win)
931- local line_count = vim .api .nvim_buf_line_count (self .results_bufnr )
932- if row > line_count then
933- return
934- end
886+ -- TODO: Does this every get called?
887+ -- local line_count = vim.api.nvim_win_get_height(self.results_win)
888+ local line_count = vim .api .nvim_buf_line_count (self .results_bufnr )
889+ if row > line_count then
890+ return
891+ end
935892
936- if insert then
937- if self .sorting_strategy == " descending" then
938- vim .api .nvim_buf_set_lines (self .results_bufnr , 0 , 1 , false , {})
939- end
893+ if insert then
894+ if self .sorting_strategy == " descending" then
895+ vim .api .nvim_buf_set_lines (self .results_bufnr , 0 , 1 , false , {})
940896 end
897+ end
941898
942- local set_ok , msg = pcall (vim .api .nvim_buf_set_lines , self .results_bufnr , row , row + offset , false , { display })
943- if set_ok and display_highlights then
944- self .highlighter :hi_display (row , prefix , display_highlights )
945- end
899+ local set_ok , msg = pcall (vim .api .nvim_buf_set_lines , self .results_bufnr , row , row + offset , false , { display })
900+ if set_ok and display_highlights then
901+ self .highlighter :hi_display (row , prefix , display_highlights )
902+ self :highlight_one_row (self .results_bufnr , self :_get_prompt (), display , row )
903+ end
946904
947- if not set_ok then
948- log .debug (" Failed to set lines..." , msg )
949- end
905+ if not set_ok then
906+ log .debug (" Failed to set lines..." , msg )
907+ end
950908
951- -- This pretty much only fails when people leave newlines in their results.
952- -- So we'll clean it up for them if it fails.
953- if not set_ok and display :find " \n " then
954- display = display :gsub (" \n " , " | " )
955- vim .api .nvim_buf_set_lines (self .results_bufnr , row , row + 1 , false , { display })
956- end
957- end )
909+ -- This pretty much only fails when people leave newlines in their results.
910+ -- So we'll clean it up for them if it fails.
911+ if not set_ok and display :find " \n " then
912+ display = display :gsub (" \n " , " | " )
913+ vim .api .nvim_buf_set_lines (self .results_bufnr , row , row + 1 , false , { display })
914+ end
958915end
959916
960917function Picker :_reset_track ()
@@ -1025,6 +982,8 @@ function Picker:get_status_updater(prompt_win, prompt_bufnr)
1025982end
1026983
1027984function Picker :get_result_processor (find_id , prompt , status_updater )
985+ local count = 0
986+
1028987 local cb_add = function (score , entry )
1029988 self .manager :add_entry (self , score , entry )
1030989 status_updater { completed = false }
@@ -1045,6 +1004,8 @@ function Picker:get_result_processor(find_id, prompt, status_updater)
10451004 return
10461005 end
10471006
1007+ count = count + 1
1008+
10481009 -- TODO: Probably should asyncify this / cache this / do something because this probably takes
10491010 -- a ton of time on large results.
10501011 log .trace (" Processing result... " , entry )
@@ -1060,6 +1021,13 @@ function Picker:get_result_processor(find_id, prompt, status_updater)
10601021 end
10611022
10621023 self .sorter :score (prompt , entry , cb_add , cb_filter )
1024+
1025+ -- Only on the first addition do we want to set the selection.
1026+ -- This allows us to handle moving the cursor to the bottom or top of the window
1027+ -- depending on the strategy.
1028+ if count == 1 then
1029+ self :_do_selection (prompt )
1030+ end
10631031 end
10641032end
10651033
@@ -1075,12 +1043,9 @@ function Picker:get_result_completor(results_bufnr, find_id, prompt, status_upda
10751043 status_updater { completed = true }
10761044
10771045 self :clear_extra_rows (results_bufnr )
1078- self :highlight_displayed_rows (results_bufnr , prompt )
10791046 self .sorter :_finish (prompt )
10801047
10811048 self :_on_complete ()
1082-
1083- self ._result_completed = true
10841049 end )
10851050end
10861051
@@ -1226,6 +1191,46 @@ function Picker:_detach()
12261191 self .closed = true
12271192end
12281193
1194+ function Picker :_get_next_filtered_prompt ()
1195+ local prompt = self :_get_prompt ()
1196+ local on_input_result = self ._on_input_filter_cb (prompt ) or {}
1197+
1198+ local new_prompt = on_input_result .prompt
1199+ if new_prompt then
1200+ prompt = new_prompt
1201+ end
1202+
1203+ local new_finder = on_input_result .updated_finder
1204+ if new_finder then
1205+ self .finder :close ()
1206+ self .finder = new_finder
1207+ end
1208+
1209+ return prompt
1210+ end
1211+
1212+ function Picker :_resume_picker ()
1213+ -- resume previous picker
1214+ local index = 1
1215+ for entry in self .manager :iter () do
1216+ self :entry_adder (index , entry , _ , true )
1217+ index = index + 1
1218+ end
1219+ self .cache_picker .is_cached = false
1220+ -- if text changed, required to set anew to restart finder; otherwise hl and selection
1221+ if self .cache_picker .cached_prompt ~= self .default_text then
1222+ self :reset_prompt ()
1223+ self :set_prompt (self .default_text )
1224+ else
1225+ -- scheduling required to apply highlighting and selection appropriately
1226+ await_schedule (function ()
1227+ if self .cache_picker .selection_row ~= nil then
1228+ self :set_selection (self .cache_picker .selection_row )
1229+ end
1230+ end )
1231+ end
1232+ end
1233+
12291234pickers ._Picker = Picker
12301235
12311236return pickers
0 commit comments