---@tag telescope.mappings ---@brief [[ --- |telescope.mappings| is used to configure the keybindings within --- a telescope picker. These keybinds are only local to the picker window --- and will be cleared once you exit the picker. --- --- We provide multiple different ways of configuring, as described below, --- to provide an easy to use experience for changing the default behavior --- of telescope or extending for your own purposes. --- --- To see many of the builtin actions that you can use as values for this --- table, see |telescope.actions| --- --- Format is: --- --- { --- mode = { ..keys } --- } --- --- --- where {mode} is the one character letter for a mode ('i' for insert, 'n' for normal). --- --- For example: --- --- mappings = { --- i = { --- [""] = require('telescope.actions').close, --- }, --- } --- --- --- To disable a keymap, put `[map] = false`
--- For example: --- --- { --- ..., --- [""] = false, --- ..., --- } --- --- Into your config. --- --- To override behavior of a key, simply set the value --- to be a function (either by requiring an action or by writing --- your own function) --- --- { --- ..., --- [""] = require('telescope.actions').select_default, --- ..., --- } --- --- --- If the function you want is part of `telescope.actions`, then you can --- simply give a string. --- For example, the previous option is equivalent to: --- --- { --- ..., --- [""] = "select_default", --- ..., --- } --- --- --- You can also add other mappings using tables with `type = "command"`. --- For example: --- --- { --- ..., --- ["jj"] = { "", type = "command" }, --- ["kk"] = { "echo \"Hello, World!\"", type = "command" },) --- ..., --- } --- --- --- You can also add additional options for mappings of any type ("action" and "command"). --- For example: --- --- { --- ..., --- [""] = { --- actions.move_selection_next, type = "action", --- opts = { nowait = true, silent = true } --- }, --- ..., --- } --- --- --- There are three main places you can configure |telescope.mappings|. These are --- ordered from the lowest priority to the highest priority. --- --- 1. |telescope.defaults.mappings| --- 2. In the |telescope.setup()| table, inside a picker with a given name, use the `mappings` key --- --- require("telescope").setup { --- pickers = { --- find_files = { --- mappings = { --- n = { --- ["kj"] = "close", --- }, --- }, --- }, --- }, --- } --- --- 3. `attach_mappings` function for a particular picker. --- --- require("telescope.builtin").find_files { --- attach_mappings = function(_, map) --- map("i", "asdf", function(_prompt_bufnr) --- print "You typed asdf" --- end) --- -- needs to return true if you want to map default_mappings and --- -- false if not --- return true --- end, --- } --- ---@brief ]] local a = vim.api local actions = require "telescope.actions" local config = require "telescope.config" local mappings = {} mappings.default_mappings = config.values.default_mappings or { i = { [""] = actions.move_selection_next, [""] = actions.move_selection_previous, [""] = actions.close, [""] = actions.move_selection_next, [""] = actions.move_selection_previous, [""] = actions.select_default, [""] = actions.select_horizontal, [""] = actions.select_vertical, [""] = actions.select_tab, [""] = actions.preview_scrolling_up, [""] = actions.preview_scrolling_down, [""] = actions.results_scrolling_up, [""] = actions.results_scrolling_down, [""] = actions.toggle_selection + actions.move_selection_worse, [""] = actions.toggle_selection + actions.move_selection_better, [""] = actions.send_to_qflist + actions.open_qflist, [""] = actions.send_selected_to_qflist + actions.open_qflist, [""] = actions.complete_tag, [""] = actions.which_key, [""] = actions.which_key, -- keys from pressing [""] = { "", type = "command" }, -- disable c-j because we dont want to allow new lines #2123 [""] = actions.nop, }, n = { [""] = actions.close, [""] = actions.select_default, [""] = actions.select_horizontal, [""] = actions.select_vertical, [""] = actions.select_tab, [""] = actions.toggle_selection + actions.move_selection_worse, [""] = actions.toggle_selection + actions.move_selection_better, [""] = actions.send_to_qflist + actions.open_qflist, [""] = actions.send_selected_to_qflist + actions.open_qflist, -- TODO: This would be weird if we switch the ordering. ["j"] = actions.move_selection_next, ["k"] = actions.move_selection_previous, ["H"] = actions.move_to_top, ["M"] = actions.move_to_middle, ["L"] = actions.move_to_bottom, [""] = actions.move_selection_next, [""] = actions.move_selection_previous, ["gg"] = actions.move_to_top, ["G"] = actions.move_to_bottom, [""] = actions.preview_scrolling_up, [""] = actions.preview_scrolling_down, [""] = actions.results_scrolling_up, [""] = actions.results_scrolling_down, ["?"] = actions.which_key, }, } __TelescopeKeymapStore = __TelescopeKeymapStore or setmetatable({}, { __index = function(t, k) rawset(t, k, {}) return rawget(t, k) end, }) local keymap_store = __TelescopeKeymapStore local _mapping_key_id = 0 local get_next_id = function() _mapping_key_id = _mapping_key_id + 1 return _mapping_key_id end local assign_function = function(prompt_bufnr, func) local func_id = get_next_id() keymap_store[prompt_bufnr][func_id] = func return func_id end local telescope_map = function(prompt_bufnr, mode, key_bind, key_func, opts) if not key_func then return end opts = opts or {} if opts.noremap == nil then opts.noremap = true end if opts.silent == nil then opts.silent = true end if type(key_func) == "string" then key_func = actions[key_func] elseif type(key_func) == "table" then if key_func.type == "command" then a.nvim_buf_set_keymap(prompt_bufnr, mode, key_bind, key_func[1], opts or { silent = true, }) return elseif key_func.type == "action_key" then key_func = actions[key_func[1]] elseif key_func.type == "action" then key_func = key_func[1] end end local key_id = assign_function(prompt_bufnr, key_func) local prefix local map_string if opts.expr then map_string = string.format([[luaeval("require('telescope.mappings').execute_keymap(%s, %s)")]], prompt_bufnr, key_id) else if mode == "i" and not opts.expr then prefix = "" elseif mode == "n" then prefix = ":" else prefix = ":" end map_string = string.format("%slua require('telescope.mappings').execute_keymap(%s, %s)", prefix, prompt_bufnr, key_id) end a.nvim_buf_set_keymap(prompt_bufnr, mode, key_bind, map_string, opts) end local extract_keymap_opts = function(key_func) if type(key_func) == "table" and key_func.opts ~= nil then -- we can't clear this because key_func could be a table from the config. -- If we clear it the table ref would lose opts after the first bind -- We need to copy it so noremap and silent won't be part of the table ref after the first bind return vim.deepcopy(key_func.opts) end return {} end mappings.apply_keymap = function(prompt_bufnr, attach_mappings, buffer_keymap) local applied_mappings = { n = {}, i = {} } local map = function(mode, key_bind, key_func, opts) mode = string.lower(mode) local key_bind_internal = a.nvim_replace_termcodes(key_bind, true, true, true) applied_mappings[mode][key_bind_internal] = true telescope_map(prompt_bufnr, mode, key_bind, key_func, opts) end if attach_mappings then local attach_results = attach_mappings(prompt_bufnr, map) if attach_results == nil then error( "Attach mappings must always return a value. `true` means use default mappings, " .. "`false` means only use attached mappings" ) end if not attach_results then return end end for mode, mode_map in pairs(buffer_keymap or {}) do mode = string.lower(mode) for key_bind, key_func in pairs(mode_map) do local key_bind_internal = a.nvim_replace_termcodes(key_bind, true, true, true) if not applied_mappings[mode][key_bind_internal] then applied_mappings[mode][key_bind_internal] = true telescope_map(prompt_bufnr, mode, key_bind, key_func, extract_keymap_opts(key_func)) end end end -- TODO: Probably should not overwrite any keymaps for mode, mode_map in pairs(mappings.default_mappings) do mode = string.lower(mode) for key_bind, key_func in pairs(mode_map) do local key_bind_internal = a.nvim_replace_termcodes(key_bind, true, true, true) if not applied_mappings[mode][key_bind_internal] then applied_mappings[mode][key_bind_internal] = true telescope_map(prompt_bufnr, mode, key_bind, key_func, extract_keymap_opts(key_func)) end end end end mappings.execute_keymap = function(prompt_bufnr, keymap_identifier) local key_func = keymap_store[prompt_bufnr][keymap_identifier] assert(key_func, string.format("Unsure of how we got this failure: %s %s", prompt_bufnr, keymap_identifier)) key_func(prompt_bufnr) vim.api.nvim_exec_autocmds("User TelescopeKeymap", {}) end mappings.clear = function(prompt_bufnr) keymap_store[prompt_bufnr] = nil end return mappings