plugins: better compatability with nullable keybinds

Mostly involves filtering keybinds that are null in cases where the
keybind is the attrname, and optionalString for manual lua keybind
registration.
This commit is contained in:
alfarel 2026-03-14 22:18:05 -04:00
commit f040b4a943
No known key found for this signature in database
8 changed files with 185 additions and 155 deletions

View file

@ -5,7 +5,7 @@
}: let
inherit (lib.modules) mkIf;
inherit (lib.strings) optionalString;
inherit (lib.attrsets) optionalAttrs;
inherit (lib.attrsets) mapAttrs' optionalAttrs;
inherit (lib.generators) mkLuaInline;
inherit (lib.attrsets) attrValues filterAttrs mapAttrsToList;
inherit (lib.lists) map optional optionals elem;
@ -98,51 +98,57 @@ in {
preset = "luasnip";
};
keymap = {
${mappings.complete} = ["show" "fallback"];
${mappings.close} = ["hide" "fallback"];
${mappings.scrollDocsUp} = ["scroll_documentation_up" "fallback"];
${mappings.scrollDocsDown} = ["scroll_documentation_down" "fallback"];
${mappings.confirm} = ["accept" "fallback"];
keymap =
mapAttrs' (mapping-name: action: {
name = mappings.${mapping-name};
value = action;
}) (filterAttrs (mapping-name: _action: mappings.${mapping-name} != null) {
complete = ["show" "fallback"];
close = ["hide" "fallback"];
scrollDocsUp = ["scroll_documentation_up" "fallback"];
scrollDocsDown = ["scroll_documentation_down" "fallback"];
confirm = ["accept" "fallback"];
next = [
"select_next"
"snippet_forward"
(mkLuaInline
# lua
''
function(cmp)
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
has_words_before = col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
${mappings.next} = [
"select_next"
"snippet_forward"
(mkLuaInline
# lua
''
function(cmp)
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
has_words_before = col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
if has_words_before then
return cmp.show()
if has_words_before then
return cmp.show()
end
end
end
'')
"fallback"
];
${mappings.previous} = [
"select_prev"
"snippet_backward"
"fallback"
];
};
'')
"fallback"
];
previous = [
"select_prev"
"snippet_backward"
"fallback"
];
});
# cmdline is not enabled by default, we're just providing keymaps in
# case the user enables them
cmdline.keymap = {
${mappings.complete} = ["show" "fallback"];
${mappings.close} = ["hide" "fallback"];
${mappings.scrollDocsUp} = ["scroll_documentation_up" "fallback"];
${mappings.scrollDocsDown} = ["scroll_documentation_down" "fallback"];
# NOTE: mappings.confirm is skipped because our default, <CR> would
# lead to accidental triggers of blink.accept instead of executing
# the cmd
${mappings.next} = ["select_next" "show" "fallback"];
${mappings.previous} = ["select_prev" "fallback"];
};
cmdline.keymap =
mapAttrs' (mapping-name: action: {
name = mappings.${mapping-name};
value = action;
}) (filterAttrs (mapping-name: _action: mappings.${mapping-name} != null) {
complete = ["show" "fallback"];
close = ["hide" "fallback"];
scrollDocsUp = ["scroll_documentation_up" "fallback"];
scrollDocsDown = ["scroll_documentation_down" "fallback"];
# NOTE: mappings.confirm is skipped because our default, <CR> would
# lead to accidental triggers of blink.accept instead of executing
# the cmd
next = ["select_next" "show" "fallback"];
previous = ["select_prev" "fallback"];
});
};
};
};

View file

@ -3,6 +3,7 @@
config,
...
}: let
inherit (lib.attrsets) filterAttrs mapAttrs';
inherit (lib.modules) mkIf;
inherit (lib.strings) optionalString;
inherit (lib.generators) mkLuaInline;
@ -72,48 +73,53 @@ in {
formatting.format = cfg.format;
# `cmp` and `luasnip` are defined above, in the `nvim-cmp` section
mapping = {
${mappings.complete} = mkLuaInline "cmp.mapping.complete()";
${mappings.close} = mkLuaInline "cmp.mapping.abort()";
${mappings.scrollDocsUp} = mkLuaInline "cmp.mapping.scroll_docs(-4)";
${mappings.scrollDocsDown} = mkLuaInline "cmp.mapping.scroll_docs(4)";
${mappings.confirm} = mkLuaInline "cmp.mapping.confirm({ select = true })";
mapping =
mapAttrs' (mapping-name: action: {
name = mappings.${mapping-name};
value = action;
}) (filterAttrs (mapping-name: _action: mappings.${mapping-name} != null)
{
complete = mkLuaInline "cmp.mapping.complete()";
close = mkLuaInline "cmp.mapping.abort()";
scrollDocsUp = mkLuaInline "cmp.mapping.scroll_docs(-4)";
scrollDocsDown = mkLuaInline "cmp.mapping.scroll_docs(4)";
confirm = mkLuaInline "cmp.mapping.confirm({ select = true })";
${mappings.next} = mkLuaInline ''
cmp.mapping(function(fallback)
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
next = mkLuaInline ''
cmp.mapping(function(fallback)
local has_words_before = function()
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
end
if cmp.visible() then
cmp.select_next_item()
${optionalString luasnipEnable ''
elseif luasnip.locally_jumpable(1) then
luasnip.jump(1)
''}
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end)
'';
if cmp.visible() then
cmp.select_next_item()
${optionalString luasnipEnable ''
elseif luasnip.locally_jumpable(1) then
luasnip.jump(1)
''}
elseif has_words_before() then
cmp.complete()
else
fallback()
end
end)
'';
${mappings.previous} = mkLuaInline ''
cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
${optionalString luasnipEnable ''
elseif luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
''}
else
fallback()
end
end)
'';
};
previous = mkLuaInline ''
cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
${optionalString luasnipEnable ''
elseif luasnip.locally_jumpable(-1) then
luasnip.jump(-1)
''}
else
fallback()
end
end)
'';
});
};
};
};