diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a43cdc2..54e9e388 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,12 @@ There are following change types: - Add new plugin integrations: - 'folke/snacks.nvim' +## mini.clue + +### Expand + +- Allow mode arrays for clues and triggers for parity with `modes` parameter of `vim.keymap.set` . By @pkazmier, PR #2202. + ## mini.hues ### Expand diff --git a/doc/mini-clue.txt b/doc/mini-clue.txt index 16585f0b..3be7e5c8 100644 --- a/doc/mini-clue.txt +++ b/doc/mini-clue.txt @@ -237,8 +237,7 @@ this module plus all || mappings in Normal and Visual modes: >lua miniclue.setup({ triggers = { -- Leader triggers - { mode = 'n', keys = '' }, - { mode = 'x', keys = '' }, + { mode = { 'n', 'x' }, keys = '' }, -- `[` and `]` keys { mode = 'n', keys = '[' }, @@ -248,27 +247,21 @@ this module plus all || mappings in Normal and Visual modes: >lua { mode = 'i', keys = '' }, -- `g` key - { mode = 'n', keys = 'g' }, - { mode = 'x', keys = 'g' }, + { mode = { 'n', 'x' }, keys = 'g' }, -- Marks - { mode = 'n', keys = "'" }, - { mode = 'n', keys = '`' }, - { mode = 'x', keys = "'" }, - { mode = 'x', keys = '`' }, + { mode = { 'n', 'x' }, keys = "'" }, + { mode = { 'n', 'x' }, keys = '`' }, -- Registers - { mode = 'n', keys = '"' }, - { mode = 'x', keys = '"' }, - { mode = 'i', keys = '' }, - { mode = 'c', keys = '' }, + { mode = { 'n', 'x' }, keys = '"' }, + { mode = { 'i', 'c' }, keys = '' }, -- Window commands { mode = 'n', keys = '' }, -- `z` key - { mode = 'n', keys = 'z' }, - { mode = 'x', keys = 'z' }, + { mode = { 'n', 'x' }, keys = 'z' }, }, clues = { @@ -311,8 +304,7 @@ modes and add descriptions to mapping groups: >lua require('mini.clue').setup({ -- Register `` as trigger triggers = { - { mode = 'n', keys = '' }, - { mode = 'x', keys = '' }, + { mode = { 'n', 'x' }, keys = '' }, }, -- Add descriptions for mapping groups @@ -398,20 +390,15 @@ In this module submode can be implemented following these steps: triggers = { -- This can also set up directly `m` as a trigger, but make -- sure to not also use ``, as they would "overlap" - { mode = 'n', keys = '' }, - { mode = 'x', keys = '' }, + { mode = { 'n', 'x' }, keys = '' }, }, clues = { { mode = 'n', keys = 'm', desc = '+Move' }, - { mode = 'n', keys = 'mh', postkeys = 'm' }, - { mode = 'n', keys = 'mj', postkeys = 'm' }, - { mode = 'n', keys = 'mk', postkeys = 'm' }, - { mode = 'n', keys = 'ml', postkeys = 'm' }, - { mode = 'x', keys = 'mh', postkeys = 'm' }, - { mode = 'x', keys = 'mj', postkeys = 'm' }, - { mode = 'x', keys = 'mk', postkeys = 'm' }, - { mode = 'x', keys = 'ml', postkeys = 'm' }, + { mode = { 'n', 'x' }, keys = 'mh', postkeys = 'm' }, + { mode = { 'n', 'x' }, keys = 'mj', postkeys = 'm' }, + { mode = { 'n', 'x' }, keys = 'mk', postkeys = 'm' }, + { mode = { 'n', 'x' }, keys = 'ml', postkeys = 'm' }, }, }) < @@ -534,8 +521,9 @@ Each element can be one of: - Callable (function) returning either of the previous two. A clue table is a table with the following fields: -- `(string)` - single character describing **single** mode short-name of - key combination as in `nvim_set_keymap()` ('n', 'x', 'i', 'o', 'c', etc.). +- `(string|table)` - single character describing mode short-name of + key combination as in `nvim_set_keymap()` ('n', 'x', 'i', 'o', 'c', etc.), + or a array thereof. - `(string)` - key combination for which clue will be shown. "Human-readable" key names as in |key-notation| (like "", "", "", etc.) are allowed. @@ -671,8 +659,7 @@ Generate clues for `g` key Contains clues for the following triggers: >lua - { mode = 'n', keys = 'g' } - { mode = 'x', keys = 'g' } + { mode = { 'n', 'x' }, keys = 'g' } < Return ~ `(table)` Array of clues. @@ -697,14 +684,10 @@ Generate clues for marks Contains clues for the following triggers: >lua - { mode = 'n', keys = "'" } - { mode = 'n', keys = "g'" } - { mode = 'n', keys = '`' } - { mode = 'n', keys = 'g`' } - { mode = 'x', keys = "'" } - { mode = 'x', keys = "g'" } - { mode = 'x', keys = '`' } - { mode = 'x', keys = 'g`' } + { mode = { 'n', 'x' }, keys = "'" } + { mode = { 'n', 'x' }, keys = "g'" } + { mode = { 'n', 'x' }, keys = '`' } + { mode = { 'n', 'x' }, keys = 'g`' } < Note: if you use "g" as trigger (like to enable |MiniClue.gen_clues.g()|), don't add "g'" and "g`" as triggers: they already will be taken into account. @@ -722,10 +705,8 @@ Generate clues for registers Contains clues for the following triggers: >lua - { mode = 'n', keys = '"' } - { mode = 'x', keys = '"' } - { mode = 'i', keys = '' } - { mode = 'c', keys = '' } + { mode = { 'n', 'x' }, keys = '"' } + { mode = { 'i', 'c' }, keys = '' } < Parameters ~ {opts} `(table|nil)` Options. Possible keys: @@ -769,8 +750,7 @@ Generate clues for `z` key Contains clues for the following triggers: >lua - { mode = 'n', keys = 'z' } - { mode = 'x', keys = 'z' } + { mode = { 'n', 'x' }, keys = 'z' } < Return ~ `(table)` Array of clues. diff --git a/lua/mini/clue.lua b/lua/mini/clue.lua index 5f077334..218ed3ce 100644 --- a/lua/mini/clue.lua +++ b/lua/mini/clue.lua @@ -233,8 +233,7 @@ --- miniclue.setup({ --- triggers = { --- -- Leader triggers ---- { mode = 'n', keys = '' }, ---- { mode = 'x', keys = '' }, +--- { mode = { 'n', 'x' }, keys = '' }, --- --- -- `[` and `]` keys --- { mode = 'n', keys = '[' }, @@ -244,27 +243,21 @@ --- { mode = 'i', keys = '' }, --- --- -- `g` key ---- { mode = 'n', keys = 'g' }, ---- { mode = 'x', keys = 'g' }, +--- { mode = { 'n', 'x' }, keys = 'g' }, --- --- -- Marks ---- { mode = 'n', keys = "'" }, ---- { mode = 'n', keys = '`' }, ---- { mode = 'x', keys = "'" }, ---- { mode = 'x', keys = '`' }, +--- { mode = { 'n', 'x' }, keys = "'" }, +--- { mode = { 'n', 'x' }, keys = '`' }, --- --- -- Registers ---- { mode = 'n', keys = '"' }, ---- { mode = 'x', keys = '"' }, ---- { mode = 'i', keys = '' }, ---- { mode = 'c', keys = '' }, +--- { mode = { 'n', 'x' }, keys = '"' }, +--- { mode = { 'i', 'c' }, keys = '' }, --- --- -- Window commands --- { mode = 'n', keys = '' }, --- --- -- `z` key ---- { mode = 'n', keys = 'z' }, ---- { mode = 'x', keys = 'z' }, +--- { mode = { 'n', 'x' }, keys = 'z' }, --- }, --- --- clues = { @@ -307,8 +300,7 @@ --- require('mini.clue').setup({ --- -- Register `` as trigger --- triggers = { ---- { mode = 'n', keys = '' }, ---- { mode = 'x', keys = '' }, +--- { mode = { 'n', 'x' }, keys = '' }, --- }, --- --- -- Add descriptions for mapping groups @@ -394,20 +386,15 @@ --- triggers = { --- -- This can also set up directly `m` as a trigger, but make --- -- sure to not also use ``, as they would "overlap" ---- { mode = 'n', keys = '' }, ---- { mode = 'x', keys = '' }, +--- { mode = { 'n', 'x' }, keys = '' }, --- }, --- clues = { --- { mode = 'n', keys = 'm', desc = '+Move' }, --- ---- { mode = 'n', keys = 'mh', postkeys = 'm' }, ---- { mode = 'n', keys = 'mj', postkeys = 'm' }, ---- { mode = 'n', keys = 'mk', postkeys = 'm' }, ---- { mode = 'n', keys = 'ml', postkeys = 'm' }, ---- { mode = 'x', keys = 'mh', postkeys = 'm' }, ---- { mode = 'x', keys = 'mj', postkeys = 'm' }, ---- { mode = 'x', keys = 'mk', postkeys = 'm' }, ---- { mode = 'x', keys = 'ml', postkeys = 'm' }, +--- { mode = { 'n', 'x' }, keys = 'mh', postkeys = 'm' }, +--- { mode = { 'n', 'x' }, keys = 'mj', postkeys = 'm' }, +--- { mode = { 'n', 'x' }, keys = 'mk', postkeys = 'm' }, +--- { mode = { 'n', 'x' }, keys = 'ml', postkeys = 'm' }, --- }, --- }) --- < @@ -529,8 +516,9 @@ end --- - Callable (function) returning either of the previous two. --- --- A clue table is a table with the following fields: ---- - `(string)` - single character describing **single** mode short-name of ---- key combination as in `nvim_set_keymap()` ('n', 'x', 'i', 'o', 'c', etc.). +--- - `(string|table)` - single character describing mode short-name of +--- key combination as in `nvim_set_keymap()` ('n', 'x', 'i', 'o', 'c', etc.), +--- or a array thereof. --- - `(string)` - key combination for which clue will be shown. --- "Human-readable" key names as in |key-notation| (like "", "", --- "", etc.) are allowed. @@ -721,8 +709,7 @@ end --- --- Contains clues for the following triggers: >lua --- ---- { mode = 'n', keys = 'g' } ---- { mode = 'x', keys = 'g' } +--- { mode = { 'n', 'x' }, keys = 'g' } --- < ---@return table Array of clues. MiniClue.gen_clues.g = function() @@ -874,14 +861,10 @@ end --- --- Contains clues for the following triggers: >lua --- ---- { mode = 'n', keys = "'" } ---- { mode = 'n', keys = "g'" } ---- { mode = 'n', keys = '`' } ---- { mode = 'n', keys = 'g`' } ---- { mode = 'x', keys = "'" } ---- { mode = 'x', keys = "g'" } ---- { mode = 'x', keys = '`' } ---- { mode = 'x', keys = 'g`' } +--- { mode = { 'n', 'x' }, keys = "'" } +--- { mode = { 'n', 'x' }, keys = "g'" } +--- { mode = { 'n', 'x' }, keys = '`' } +--- { mode = { 'n', 'x' }, keys = 'g`' } --- < --- Note: if you use "g" as trigger (like to enable |MiniClue.gen_clues.g()|), --- don't add "g'" and "g`" as triggers: they already will be taken into account. @@ -912,17 +895,11 @@ MiniClue.gen_clues.marks = function() --stylua: ignore return { - -- Normal mode - describe_marks('n', "'"), - describe_marks('n', "g'"), - describe_marks('n', "`"), - describe_marks('n', "g`"), - - -- Visual mode - describe_marks('x', "'"), - describe_marks('x', "g'"), - describe_marks('x', "`"), - describe_marks('x', "g`"), + -- Normal and visual mode + describe_marks({ 'n', 'x' }, "'"), + describe_marks({ 'n', 'x' }, "g'"), + describe_marks({ 'n', 'x' }, "`"), + describe_marks({ 'n', 'x' }, "g`"), } end @@ -930,10 +907,8 @@ end --- --- Contains clues for the following triggers: >lua --- ---- { mode = 'n', keys = '"' } ---- { mode = 'x', keys = '"' } ---- { mode = 'i', keys = '' } ---- { mode = 'c', keys = '' } +--- { mode = { 'n', 'x' }, keys = '"' } +--- { mode = { 'i', 'c' }, keys = '' } --- < ---@param opts table|nil Options. Possible keys: --- - `(boolean)` - whether to show contents of all possible @@ -972,11 +947,8 @@ MiniClue.gen_clues.registers = function(opts) --stylua: ignore return { - -- Normal mode - describe_registers('n', '"'), - - -- Visual mode - describe_registers('x', '"'), + -- Normal and Visual mode + describe_registers({ 'n', 'x' }, '"'), -- Insert mode describe_registers('i', ''), @@ -1084,8 +1056,7 @@ end --- --- Contains clues for the following triggers: >lua --- ---- { mode = 'n', keys = 'z' } ---- { mode = 'x', keys = 'z' } +--- { mode = { 'n', 'x' }, keys = 'z' } --- < ---@return table Array of clues. MiniClue.gen_clues.z = function() @@ -1328,7 +1299,10 @@ H.map_buf_triggers = function(buf_id) if not H.is_valid_buf(buf_id) or H.is_disabled(buf_id) then return end for _, trigger in ipairs(H.get_config(nil, buf_id).triggers) do - H.map_trigger(buf_id, trigger) + local modes = type(trigger.mode) == 'table' and trigger.mode or { trigger.mode } + for _, mode in ipairs(modes) do + H.map_trigger(buf_id, { mode = mode, keys = trigger.keys }) + end end end @@ -1336,7 +1310,10 @@ H.unmap_buf_triggers = function(buf_id) if not H.is_valid_buf(buf_id) or H.is_disabled(buf_id) then return end for _, trigger in ipairs(H.get_config(nil, buf_id).triggers) do - H.unmap_trigger(buf_id, trigger) + local modes = type(trigger.mode) == 'table' and trigger.mode or { trigger.mode } + for _, mode in ipairs(modes) do + H.unmap_trigger(buf_id, { mode = mode, keys = trigger.keys }) + end end end @@ -1780,7 +1757,8 @@ H.clues_get_all = function(mode) -- Order of clue precedence: config clues < buffer mappings < global mappings local config_clues = H.clues_normalize(H.get_config().clues) or {} - local mode_clues = vim.tbl_filter(function(x) return x.mode == mode end, config_clues) + local mode_filter = function(x) return type(x.mode) == 'table' and vim.tbl_contains(x.mode, mode) or x.mode == mode end + local mode_clues = vim.tbl_filter(mode_filter, config_clues) for _, clue in ipairs(mode_clues) do local lhsraw = H.replace_termcodes(clue.keys) @@ -1949,11 +1927,13 @@ H.make_clues_with_register_contents = function(mode, prefix) end -- Predicates ----------------------------------------------------------------- -H.is_trigger = function(x) return type(x) == 'table' and type(x.mode) == 'string' and type(x.keys) == 'string' end +H.is_trigger = function(x) + return type(x) == 'table' and (type(x.mode) == 'string' or type(x.mode) == 'table') and type(x.keys) == 'string' +end H.is_clue = function(x) if type(x) ~= 'table' then return false end - local mandatory = type(x.mode) == 'string' and type(x.keys) == 'string' + local mandatory = (type(x.mode) == 'string' or type(x.mode) == 'table') and type(x.keys) == 'string' local extra = (x.desc == nil or type(x.desc) == 'string' or vim.is_callable(x.desc)) and (x.postkeys == nil or type(x.postkeys) == 'string') return mandatory and extra diff --git a/readmes/mini-clue.md b/readmes/mini-clue.md index b8e5a825..edbcf7e9 100644 --- a/readmes/mini-clue.md +++ b/readmes/mini-clue.md @@ -98,38 +98,36 @@ local miniclue = require('mini.clue') miniclue.setup({ triggers = { -- Leader triggers - { mode = 'n', keys = '' }, - { mode = 'x', keys = '' }, + { mode = { 'n', 'x' }, keys = '' }, + + -- `[` and `]` keys + { mode = 'n', keys = '[' }, + { mode = 'n', keys = ']' }, -- Built-in completion { mode = 'i', keys = '' }, -- `g` key - { mode = 'n', keys = 'g' }, - { mode = 'x', keys = 'g' }, + { mode = { 'n', 'x' }, keys = 'g' }, -- Marks - { mode = 'n', keys = "'" }, - { mode = 'n', keys = '`' }, - { mode = 'x', keys = "'" }, - { mode = 'x', keys = '`' }, + { mode = { 'n', 'x' }, keys = "'" }, + { mode = { 'n', 'x' }, keys = '`' }, -- Registers - { mode = 'n', keys = '"' }, - { mode = 'x', keys = '"' }, - { mode = 'i', keys = '' }, - { mode = 'c', keys = '' }, + { mode = { 'n', 'x' }, keys = '"' }, + { mode = { 'i', 'c' }, keys = '' }, -- Window commands { mode = 'n', keys = '' }, -- `z` key - { mode = 'n', keys = 'z' }, - { mode = 'x', keys = 'z' }, + { mode = { 'n', 'x' }, keys = 'z' }, }, clues = { -- Enhance this by adding descriptions for mapping groups + miniclue.gen_clues.square_brackets(), miniclue.gen_clues.builtin_completion(), miniclue.gen_clues.g(), miniclue.gen_clues.marks(), diff --git a/tests/screenshots/tests-test_clue.lua---Clues---handles-an-array-of-modes b/tests/screenshots/tests-test_clue.lua---Clues---handles-an-array-of-modes new file mode 100644 index 00000000..60630966 --- /dev/null +++ b/tests/screenshots/tests-test_clue.lua---Clues---handles-an-array-of-modes @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ ┌ ─────────────────────┐ +07|~ │ a │ Clue a │ +08|~ └──────────────────────────────┘ +09|[No Name] 0,0-1 +10| + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111123333333332222222222222222222222 +07|1111111124445666666666666666666666666662 +08|1111111122222222222222222222222222222222 +09|7777777777777777777777777777777777777777 +10|8888888888888888888888888888888888888888 diff --git a/tests/screenshots/tests-test_clue.lua---Clues---handles-an-array-of-modes-002 b/tests/screenshots/tests-test_clue.lua---Clues---handles-an-array-of-modes-002 new file mode 100644 index 00000000..505d82b2 --- /dev/null +++ b/tests/screenshots/tests-test_clue.lua---Clues---handles-an-array-of-modes-002 @@ -0,0 +1,23 @@ +--|---------|---------|---------|---------| +01| +02|~ +03|~ +04|~ +05|~ +06|~ ┌ ─────────────────────┐ +07|~ │ a │ Clue a │ +08|~ └──────────────────────────────┘ +09|[No Name] 0,0-1 +10|-- VISUAL -- 1 + +--|---------|---------|---------|---------| +01|0000000000000000000000000000000000000000 +02|1111111111111111111111111111111111111111 +03|1111111111111111111111111111111111111111 +04|1111111111111111111111111111111111111111 +05|1111111111111111111111111111111111111111 +06|1111111123333333332222222222222222222222 +07|1111111124445666666666666666666666666662 +08|1111111122222222222222222222222222222222 +09|7777777777777777777777777777777777777777 +10|8888888888889999999999999999999999999999 diff --git a/tests/test_clue.lua b/tests/test_clue.lua index 507d3906..52ea14a1 100644 --- a/tests/test_clue.lua +++ b/tests/test_clue.lua @@ -314,6 +314,13 @@ T['setup()']['creates triggers for already created buffers'] = function() validate_trigger_keymap('n', 'g', other_buf_id) end +T['setup()']['creates triggers for an array of modes'] = function() + load_module({ triggers = { { mode = { 'n', 'x' }, keys = 'g' } } }) + validate_trigger_keymap('n', 'g') + validate_trigger_keymap('x', 'g') + validate_no_trigger_keymap('c', 'g') +end + T['setup()']['creates triggers only in listed buffers'] = function() local buf_id_nolisted = child.api.nvim_create_buf(false, true) make_test_map('n', 'a') @@ -1852,6 +1859,21 @@ T['Clues']['handles no description'] = function() child.expect_screenshot() end +T['Clues']['handles an array of modes'] = function() + load_module({ + clues = { { mode = { 'n', 'x' }, keys = 'a', desc = 'Clue a' } }, + triggers = { { mode = { 'n', 'x' }, keys = '' } }, + window = { delay = 0 }, + }) + + type_keys(' ') + child.expect_screenshot() + + type_keys('') + type_keys('v', ' ') + child.expect_screenshot() +end + T['Clues']['shows as group a single non-exact clue'] = function() load_module({ clues = { { mode = 'n', keys = 'aaa', desc = 'Clue a' } },