From f68d0c24776f70feb018ac530fa9e2fff0d51880 Mon Sep 17 00:00:00 2001 From: TJ DeVries Date: Fri, 19 Nov 2021 14:09:43 -0500 Subject: [PATCH] fix: Better mappings handling --- doc/telescope.txt | 16 ++++++- lua/telescope/builtin/init.lua | 11 +---- lua/telescope/mappings.lua | 88 ++++++++++++++++++++++++---------- lua/telescope/pickers.lua | 16 ++++++- 4 files changed, 92 insertions(+), 39 deletions(-) diff --git a/doc/telescope.txt b/doc/telescope.txt index 437d537..baa061f 100644 --- a/doc/telescope.txt +++ b/doc/telescope.txt @@ -1747,7 +1747,7 @@ You can also add additional options for mappings of any type ("action" and } < -There are three main places you can configure |telescope.mappings|. These are +There are four main places you can configure |telescope.mappings|. These are ordered from the lowest priority to the highest priority. 1. |telescope.defaults.mappings| @@ -1766,7 +1766,19 @@ ordered from the lowest priority to the highest priority. }, } < -3. `attach_mappings` function for a particular picker. +3. The `mappings` key for a particular picker. +> + require("telescope.builtin").fd { + mappings = { + i = { + asdf = function() + print "You typed asdf" + end, + }, + }, + } +< +4. `attach_mappings` function for a particular picker. > require("telescope.builtin").find_files { attach_mappings = function(_, map) diff --git a/lua/telescope/builtin/init.lua b/lua/telescope/builtin/init.lua index 74323d4..19f316a 100644 --- a/lua/telescope/builtin/init.lua +++ b/lua/telescope/builtin/init.lua @@ -492,16 +492,7 @@ local apply_config = function(mod) return vim.deepcopy(pconf) end)() - if pconf.mappings then - defaults.attach_mappings = function(_, map) - for mode, tbl in pairs(pconf.mappings) do - for key, action in pairs(tbl) do - map(mode, key, action) - end - end - return true - end - end + opts.__name = k if pconf.attach_mappings and opts.attach_mappings then local opts_attach = opts.attach_mappings diff --git a/lua/telescope/mappings.lua b/lua/telescope/mappings.lua index 04fbda2..248f93b 100644 --- a/lua/telescope/mappings.lua +++ b/lua/telescope/mappings.lua @@ -87,7 +87,7 @@ --- } --- --- ---- There are three main places you can configure |telescope.mappings|. These are +--- There are four main places you can configure |telescope.mappings|. These are --- ordered from the lowest priority to the highest priority. --- --- 1. |telescope.defaults.mappings| @@ -105,7 +105,19 @@ --- }, --- } --- ---- 3. `attach_mappings` function for a particular picker. +--- 3. The `mappings` key for a particular picker. +--- +--- require("telescope.builtin").fd { +--- mappings = { +--- i = { +--- asdf = function() +--- print "You typed asdf" +--- end, +--- }, +--- }, +--- } +--- +--- 4. `attach_mappings` function for a particular picker. --- --- require("telescope.builtin").find_files { --- attach_mappings = function(_, map) @@ -222,6 +234,8 @@ local telescope_map = function(prompt_bufnr, mode, key_bind, key_func, opts) return end + key_bind = a.nvim_replace_termcodes(key_bind, true, true, true) + opts = opts or {} if opts.noremap == nil then opts.noremap = true @@ -278,14 +292,52 @@ local extract_keymap_opts = function(key_func) return {} end -mappings.apply_keymap = function(prompt_bufnr, attach_mappings, buffer_keymap) - local applied_mappings = { n = {}, i = {} } +local termcode_mt = { + __index = function(t, k) + return rawget(t, a.nvim_replace_termcodes(k, true, true, true)) + end, + + __newindex = function(t, k, v) + rawset(t, a.nvim_replace_termcodes(k, true, true, true), v) + end, +} + +local mode_mt = { + __index = function(t, k) + k = string.lower(k) + if rawget(t, k) then + return rawget(t, k) + end + + local val = setmetatable({}, termcode_mt) + rawset(t, k, val) + return val + end, + + __newindex = function(t, k, v) + rawset(t, string.lower(k), v) + end, +} + +-- Apply the keymaps for a given set of configurations +mappings.apply_keymap = function(prompt_bufnr, attach_mappings, ...) + local mappings_applied = setmetatable({}, mode_mt) + + -- Set the mappings_config, and make sure that all transformations are applied + local mappings_config = setmetatable({}, mode_mt) + for mode, mode_map in pairs(vim.tbl_deep_extend("force", mappings.default_mappings or {}, ...)) do + for key_bind, val in pairs(mode_map) do + mappings_config[mode][key_bind] = val + end + end 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 + -- Skip maps that are disabled by the user + if mappings_config[mode][key_bind] == false then + return + end + mappings_applied[mode][key_bind] = true telescope_map(prompt_bufnr, mode, key_bind, key_func, opts) end @@ -304,26 +356,10 @@ mappings.apply_keymap = function(prompt_bufnr, attach_mappings, buffer_keymap) end end - for mode, mode_map in pairs(buffer_keymap or {}) do - mode = string.lower(mode) - + for mode, mode_map in pairs(mappings_config) do 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 + if not mappings_applied[mode][key_bind] then + mappings_applied[mode][key_bind] = true telescope_map(prompt_bufnr, mode, key_bind, key_func, extract_keymap_opts(key_func)) end end diff --git a/lua/telescope/pickers.lua b/lua/telescope/pickers.lua index 6006cb9..152c5b7 100644 --- a/lua/telescope/pickers.lua +++ b/lua/telescope/pickers.lua @@ -66,8 +66,12 @@ function Picker:new(opts) local layout_strategy = vim.F.if_nil(opts.layout_strategy, config.values.layout_strategy) local obj = setmetatable({ + -- Metadata reserved for telescope. Do not use if you're not telescope + __name = opts.__name, + prompt_title = vim.F.if_nil(opts.prompt_title, config.values.prompt_title), results_title = vim.F.if_nil(opts.results_title, config.values.results_title), + -- either whats passed in by the user or whats defined by the previewer preview_title = opts.preview_title, @@ -108,6 +112,7 @@ function Picker:new(opts) track = vim.F.if_nil(opts.track, false), stats = {}, + mappings = opts.mappings or {}, attach_mappings = opts.attach_mappings, file_ignore_patterns = vim.F.if_nil(opts.file_ignore_patterns, config.values.file_ignore_patterns), @@ -559,7 +564,16 @@ function Picker:find() }) ) - mappings.apply_keymap(prompt_bufnr, self.attach_mappings, config.values.mappings) + mappings.apply_keymap( + prompt_bufnr, + self.attach_mappings, + -- Lowest priority: user config defaults + config.values.mappings or {}, + -- user picker defaults + (config.pickers[self.__name] or {}).mappings or {}, + -- explicit mappings via opts + self.mappings or {} + ) tx.send() main_loop()