Skip to content

Commit

Permalink
feat(keys): you can now create buffer-local filetype keymaps by speci…
Browse files Browse the repository at this point in the history
…fying `ft=`. Fixes #1076
  • Loading branch information
folke committed Oct 5, 2023
1 parent 19d1b3a commit c42e63c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 21 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ can be a `LazyKeys` table with the following key-value pairs:
- **[1]**: (`string`) lhs **_(required)_**
- **[2]**: (`string|fun()`) rhs **_(optional)_**
- **mode**: (`string|string[]`) mode **_(optional, defaults to `"n"`)_**
- **ft**: (`string|string[]`) `filetype` for buffer-local keymaps **_(optional)_**
- any other option valid for `vim.keymap.set`

Key mappings will load the plugin the first time they get executed.
Expand Down
72 changes: 51 additions & 21 deletions lua/lazy/core/handler/keys.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ local Loader = require("lazy.core.loader")
---@field noremap? boolean
---@field remap? boolean
---@field expr? boolean
---@field ft? string|string[]
---@field id string

---@class LazyKeysHandler:LazyHandler
Expand Down Expand Up @@ -53,7 +54,7 @@ end
function M.opts(keys)
local opts = {}
for k, v in pairs(keys) do
if type(k) ~= "number" and k ~= "mode" and k ~= "id" then
if type(k) ~= "number" and k ~= "mode" and k ~= "id" and k ~= "ft" then
opts[k] = v
end
end
Expand All @@ -64,33 +65,62 @@ end
function M:_add(keys)
local lhs = keys[1]
local opts = M.opts(keys)
vim.keymap.set(keys.mode, lhs, function()
local plugins = self.active[keys.id]

-- always delete the mapping immediately to prevent recursive mappings
self:_del(keys)
self.active[keys.id] = nil
---@param buf? number
local function add(buf)
vim.keymap.set(keys.mode, lhs, function()
local plugins = self.active[keys.id]

Util.track({ keys = lhs })
Loader.load(plugins, { keys = lhs })
Util.track()
-- always delete the mapping immediately to prevent recursive mappings
self:_del(keys, buf)
self.active[keys.id] = nil

local feed = vim.api.nvim_replace_termcodes("<Ignore>" .. lhs, true, true, true)
-- insert instead of append the lhs
vim.api.nvim_feedkeys(feed, "i", false)
end, {
desc = opts.desc,
nowait = opts.nowait,
-- we do not return anything, but this is still needed to make operator pending mappings work
expr = true,
})
if plugins then
Util.track({ keys = lhs })
Loader.load(plugins, { keys = lhs })
Util.track()
end

local feed = vim.api.nvim_replace_termcodes("<Ignore>" .. lhs, true, true, true)
-- insert instead of append the lhs
vim.api.nvim_feedkeys(feed, "i", false)
end, {
desc = opts.desc,
nowait = opts.nowait,
-- we do not return anything, but this is still needed to make operator pending mappings work
expr = true,
buffer = buf,
})
end

if keys.ft then
vim.api.nvim_create_autocmd("FileType", {
pattern = keys.ft,
callback = function(event)
if self.active[keys.id] then
add(event.buf)
else
-- Only create the mapping if its managed by lazy
-- otherwise the plugin is supposed to manage it
if keys[2] then
self:_del(keys, event.buf)
end
end
end,
})
else
add()
end
end

---@param keys LazyKeys
function M:_del(keys)
pcall(vim.keymap.del, keys.mode, keys[1])
---@param buf number?
function M:_del(keys, buf)
pcall(vim.keymap.del, keys.mode, keys[1], { buffer = buf })
if keys[2] then
vim.keymap.set(keys.mode, keys[1], keys[2], M.opts(keys))
local opts = M.opts(keys)
opts.buffer = buf
vim.keymap.set(keys.mode, keys[1], keys[2], opts)
end
end

Expand Down

0 comments on commit c42e63c

Please sign in to comment.