diff --git a/docs/manual/configuring/keybinds.md b/docs/manual/configuring/keybinds.md index a7c5a6266..412c22185 100644 --- a/docs/manual/configuring/keybinds.md +++ b/docs/manual/configuring/keybinds.md @@ -35,6 +35,16 @@ keymaps via {option}`vim.keymaps`. end ''; } + { + # `ft` restricts the keymap to buffers of the given filetypes. + # Instead of a global mapping, a `FileType` autocmd creates a + # buffer-local mapping when such a buffer is opened. + key = "p"; + mode = "n"; + action = "Git push"; + desc = "Push commit"; + ft = ["fugitive"]; + } ]; } ``` diff --git a/docs/manual/release-notes/rl-26.12.md b/docs/manual/release-notes/rl-26.12.md index e53f82054..7405e6bb2 100644 --- a/docs/manual/release-notes/rl-26.12.md +++ b/docs/manual/release-notes/rl-26.12.md @@ -66,6 +66,12 @@ ## Changelog {#sec-release-26-12-changelog} +[theol-git](https://github.com/theol-git): + +- Added an `ft` option to {option}`vim.keymaps`, scoping a keymap to the given + filetypes via a `FileType` autocmd. Defaults to an empty list, i.e. a global + mapping. + [Snoweuph](https://github.com/snoweuph) [bun ORM]: https://bun.uptrace.dev/ diff --git a/modules/neovim/init/mappings.nix b/modules/neovim/init/mappings.nix index b9fe9225c..d39e9e883 100644 --- a/modules/neovim/init/mappings.nix +++ b/modules/neovim/init/mappings.nix @@ -38,6 +38,16 @@ expr = mkBool false "Means that the action is actually an expression. Equivalent to adding to a map."; unique = mkBool false "Whether to fail if the map is already defined. Equivalent to adding to a map."; noremap = mkBool true "Whether to use the 'noremap' variant of the command, ignoring any custom mappings on the defined action. It is highly advised to keep this on, which is the default."; + + ft = mkOption { + type = listOf str; + default = []; + description = '' + The filetypes that this keybind should apply to, e.g. `[ "fugitive" ]`. + When non-empty, the keymap is created buffer-locally via a FileType + autocmd instead of globally. + ''; + }; }; mapType = submodule { @@ -110,6 +120,13 @@ in { silent = true; action = "cnext"; } + { + key = "p"; + mode = "n"; + action = "Git push"; + desc = "Push commit"; + ft = ["fugitive"]; + } ]; ''; default = {}; diff --git a/modules/wrapper/rc/config.nix b/modules/wrapper/rc/config.nix index de14c0842..09d81c34a 100644 --- a/modules/wrapper/rc/config.nix +++ b/modules/wrapper/rc/config.nix @@ -5,7 +5,7 @@ }: let inherit (builtins) map mapAttrs filter; inherit (lib.lists) partition; - inherit (lib.attrsets) mapAttrsToList; + inherit (lib.attrsets) mapAttrsToList optionalAttrs; inherit (lib.strings) concatLines concatMapStringsSep optionalString; inherit (lib.trivial) showWarnings; inherit (lib.generators) mkLuaInline; @@ -43,7 +43,20 @@ in { remap = !keymap.noremap; }; - toLuaKeymap = bind: "vim.keymap.set(${toLuaObject bind.mode}, ${toLuaObject bind.key}, ${toLuaObject (getAction bind)}, ${toLuaObject (getOpts bind)})"; + toLuaKeymap = keymap: let + isFtKeymap = keymap.ft != []; + opts = getOpts keymap // optionalAttrs isFtKeymap {buffer = true;}; + setKeymapLua = "vim.keymap.set(${toLuaObject keymap.mode}, ${toLuaObject keymap.key}, ${toLuaObject (getAction keymap)}, ${toLuaObject opts})"; + in + if isFtKeymap + then '' + vim.api.nvim_create_autocmd("FileType", { + pattern = ${toLuaObject keymap.ft}, + callback = function() + ${setKeymapLua} + end, + })'' + else setKeymapLua; keymaps = concatLines (map toLuaKeymap (filter (x: x.key != null) cfg.keymaps)); in {