@@ -2,6 +2,7 @@ local a = vim.api
22
33local action_state = require " telescope.actions.state"
44local utils = require " telescope.utils"
5+ local mappings = require " telescope.mappings"
56
67local Path = require " plenary.path"
78local os_sep = Path .path .sep
@@ -191,4 +192,140 @@ fb_utils.selection_callback = function(current_picker, absolute_path)
191192 end )
192193end
193194
195+ fb_utils .get_fb_prompt = function ()
196+ local prompt_buf = vim .tbl_filter (function (b )
197+ return vim .bo [b ].filetype == " TelescopePrompt"
198+ end , vim .api .nvim_list_bufs ())
199+ -- vim.ui.{input, select} might be telescope pickers
200+ if # prompt_buf > 1 then
201+ for _ , buf in ipairs (prompt_buf ) do
202+ local current_picker = action_state .get_current_picker (prompt_buf )
203+ if current_picker .finder ._browse_files then
204+ prompt_buf = buf
205+ break
206+ end
207+ end
208+ else
209+ prompt_buf = prompt_buf [1 ]
210+ end
211+ return prompt_buf
212+ end
213+
214+ local set_prompt = function (prompt_bufnr )
215+ local value = action_state .get_selected_entry ().value
216+ local current_picker = action_state .get_current_picker (prompt_bufnr )
217+ current_picker :reset_prompt (value )
218+ end
219+
220+ local get_action = function (action_name , keymappings )
221+ return vim .tbl_filter (function (mapping )
222+ return mapping .func [1 ] == action_name
223+ end , keymappings )[1 ].func
224+ end
225+
226+ -- keep_mappings: array of {mode = "n|i", lhs = string }k
227+ local clear_mappings = function (prompt_bufnr , keep_mappings )
228+ mappings .clear (prompt_bufnr )
229+ for _ , m in ipairs { " n" , " i" } do
230+ vim .tbl_map (function (keymap )
231+ local keep_map = vim .tbl_filter (function (map )
232+ if map .mode == m and map .lhs == keymap .lhs then
233+ return true
234+ end
235+ end , keep_mappings )
236+ if vim .tbl_isempty (keep_map ) then
237+ vim .api .nvim_buf_del_keymap (prompt_bufnr , m , keymap .lhs )
238+ end
239+ end , vim .api .nvim_buf_get_keymap (prompt_bufnr , m ))
240+ end
241+ end
242+
243+ local function clear_buffer_mappings (bufnr )
244+ for _ , mode in ipairs { " n" , " i" } do
245+ local buffer_mappings = vim .api .nvim_buf_get_keymap (bufnr , mode )
246+ for _ , mapping in ipairs (buffer_mappings ) do
247+ vim .api .nvim_buf_del_keymap (bufnr , mode , mapping .lhs )
248+ end
249+ end
250+ end
251+
252+ -- TODO
253+ -- [x] handle ESC, <C-c>
254+ -- [ ] multiple prompts?
255+ -- [ ] refactor into components
256+ -- [ ] namespace for mappings ...
257+ -- highlighting with prompt callback
258+ fb_utils .input = function (opts , on_confirm )
259+ opts .prompt_bufnr = vim .F .if_nil (opts .prompt_bufnr , fb_utils .get_fb_prompt ())
260+ local current_picker = action_state .get_current_picker (opts .prompt_bufnr )
261+ local picker_status = {
262+ prompt = current_picker :_get_prompt (),
263+ prompt_prefix = current_picker .prompt_prefix ,
264+ title = current_picker .prompt_title ,
265+ selection_strategy = current_picker .selection_strategy ,
266+ on_input_filter_cb = current_picker ._on_input_filter_cb ,
267+ attach_mappings = current_picker .attach_mappings ,
268+ }
269+
270+ mappings .clear (opts .prompt_bufnr )
271+
272+ opts .on_input_filter_cb = vim .F .if_nil (opts .on_input_filter_cb )
273+ opts .prompt_prefix = vim .F .if_nil (opts .prompt_prefix , current_picker .prompt_prefix )
274+
275+ current_picker .selection_strategy = vim .F .if_nil (opts .selection_strategy , " none" )
276+ current_picker .prompt_border :change_title (opts .prompt )
277+ -- vim.fn.prompt_setprompt(opts.prompt_bufnr, opts.prompt_prefix)
278+ current_picker .prompt_prefix = opts .prompt_prefix
279+ current_picker :reset_prompt (opts .default or " " )
280+ current_picker ._on_input_filter_cb = vim .F .if_nil (opts .on_input_filter_cb , function () end )
281+
282+ local _on_confirm = function (_ , confirm_opts )
283+ confirm_opts = confirm_opts or {}
284+ confirm_opts .nil_input = vim .F .if_nil (confirm_opts .nil_input , false )
285+ local prompt = current_picker :_get_prompt ()
286+ current_picker ._finder_attached = true
287+ current_picker .prompt_border :change_title (picker_status .title )
288+ current_picker .selection_strategy = picker_status .selection_strategy
289+ current_picker .prompt_prefix = picker_status .prompt_prefix
290+ current_picker ._on_input_filter_cb = picker_status .on_input_filter_cb
291+ current_picker ._finder_attached = true
292+ vim .fn .prompt_setprompt (opts .prompt_bufnr , picker_status .prompt_prefix )
293+ current_picker :reset_prompt " "
294+ -- clear all input mappings prior to re-attaching original fb mappings
295+ clear_buffer_mappings (opts .prompt_bufnr )
296+ mappings .clear (opts .prompt_bufnr )
297+ require (" telescope.actions.mt" ).clear_all ()
298+ mappings .apply_keymap (opts .prompt_bufnr , picker_status .attach_mappings , require (" telescope.config" ).values .mappings )
299+ on_confirm (not confirm_opts .nil_input and prompt or nil )
300+ end
301+
302+ local attach_mappings = function (_ , map )
303+ local actions = require " telescope.actions"
304+ for _ , action in ipairs { actions .move_selection_next , actions .move_selection_previous } do
305+ action :enhance {
306+ pre = function ()
307+ current_picker :_toggle_finder_attach ()
308+ end ,
309+ post = function ()
310+ set_prompt (opts .prompt_bufnr )
311+ current_picker :_toggle_finder_attach ()
312+ end ,
313+ }
314+ actions .select_default :replace (_on_confirm )
315+ actions .close :replace (function ()
316+ _on_confirm (_ , { nil_input = true })
317+ end )
318+ map (" i" , " <C-c>" , actions .close )
319+ map (" i" , " <CR>" , actions .select_default )
320+ map (" n" , " <ESC>" , actions .close )
321+ return false
322+ end
323+ end
324+ -- clear all mappings prior to attaching input mappings
325+ clear_buffer_mappings (opts .prompt_bufnr )
326+ mappings .clear (opts .prompt_bufnr )
327+ require (" telescope.actions.mt" ).clear_all ()
328+ mappings .apply_keymap (opts .prompt_bufnr , attach_mappings , {})
329+ end
330+
194331return fb_utils
0 commit comments