mini.nvim
mini.nvim copied to clipboard
Repeatable movement across modules with `;` and `,`
Contributing guidelines
- [X] I have read CONTRIBUTING.md
- [X] I have read CODE_OF_CONDUCT.md
Module(s)
mini.jump, mini.ai, mini.bracketed
Description
Hi, and thank you for this incredible project, it is slowly conquering my config :)
I think it would be cool if modules that deal with movements were able to make them repeatable with , and ;. Some examples of this behaviour would be:
- with mini.bracketed, pressing
]itakes you to the next indent, and pressing;afterwards takes you to the next one again. Pressing,would instead bring you to the previous one. Same could be done with the movements that are local to the buffer, such as treesitter nodes, diagnostics, comment blocks etc. - with mini.ai, pressing
g['takes you to the first quote in a pair, pressing;afterwards does it again. This is also implented in nvim-treesitter/nvim-treesitter-textobjects - with mini.jump, this is already working with the
;key. It would be a matter of integrating it with the general mechanism used for the other modules.
There is an implementation of this in https://github.com/nvim-treesitter/nvim-treesitter-textobjects/blob/master/lua/nvim-treesitter/textobjects/repeatable_move.lua It is written so that other plugins can hook into it, making their respective moves repeatable, but I feel like such a mechanism would be better suited to a project like this, as it is more general in scope and it already has many modules it can be hooked into.
Thanks for the suggestion!
An idea of generalizable repeatable jump is interesting and I'll take a look at implementation in 'nvim-treesitter'.
However, my first instinct is that I don't really like the idea of overriding ";" and ",". Not sure why, though. Probably because they are somewhat special and the first one is already taken by 'min.jump'. I'll think about it.
I ended up monkeypatching the mini functions on my config's side. It's really nice to use, you can use this snippet to try it out (requires nvim-treesitter-textobjects):
local ts_repeat_move = require("nvim-treesitter.textobjects.repeatable_move")
local minibracketed = require('mini.bracketed')
for key, _ in pairs(minibracketed.config) do
local move_fn = minibracketed[key]
minibracketed[key] = function(direction, opts)
local function repeatable_move(inopts)
move_fn(inopts.forward and 'forward' or 'backward', opts)
end
ts_repeat_move.set_last_move(repeatable_move, {
forward = direction == 'forward' or direction == 'last',
})
move_fn(direction, opts)
end
end
local miniai = require('mini.ai')
local move_cursor = miniai.move_cursor
miniai.move_cursor = function(side, ai_type, id, opts)
local function repeatable_move_cursor(inopts)
local new_opts = vim.tbl_extend('force', opts, {
search_method = inopts.forward and 'next' or 'prev'
})
move_cursor(side, ai_type, id, new_opts)
end
ts_repeat_move.set_last_move(
repeatable_move_cursor,
{ forward = opts.search_method ~= 'prev' and opts.search_method ~= 'cover_or_prev' }
)
move_cursor(side, ai_type, id, opts)
end
local minijump = require('mini.jump')
local jump = minijump.jump
minijump.jump = function(target, backward, till, number)
local function repeatable_jump(inopts)
jump(target, not inopts.forward, till, 1)
end
ts_repeat_move.set_last_move(
repeatable_jump,
{ forward = not backward }
)
jump(target, backward, till, number)
end
-- Repeat movement with ; and ,
-- ensure ; goes forward and , goes backward regardless of the last direction
vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move_next)
vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_previous)
-- vim way: ; goes to the direction you were moving.
-- vim.keymap.set({ "n", "x", "o" }, ";", ts_repeat_move.repeat_last_move)
-- vim.keymap.set({ "n", "x", "o" }, ",", ts_repeat_move.repeat_last_move_opposite)
mini.jump, mini.ai, mini.bracketed
I think this would apply to all plugins, likely even user commands.
I think it would be cool if modules that deal with movements were able to make them repeatable with , and ;. Some examples of this behaviour would be:
If unclear what key is used, then the user should specify such behavior.
, and ; are already taken and useful on same line actions with off by 1 or 2 f/t-movements, which makes it a potential poor fit:
*;*
; Repeat latest f, t, F or T [count] times. See |cpo-;|
*,*
, Repeat latest f, t, F or T in opposite direction
[count] times. See also |cpo-;|
,and;are already taken and useful on same line actions with off by 1 or 2 f/t-movements, which makes it a potential poor fit:
From the 'mini.nvim' perspective a more important argument is that ; is already used by 'mini.jump'. if it hadn't, overriding both ; and , might have been fine.
From the 'mini.nvim' perspective a more important argument is that
;is already used by 'mini.jump'. if it hadn't, overriding both;and,might have been fine.
Yes, mini.jump already extends the default , and ; keymaps to work across line boundaries. This would be about generalizing , and ; to work with all modules that deal with jumps and not just mini.jump.
In my point of view, the fact that these keymaps are already used in mini.jump is a feature rather than a bug, as using these same keys in all modules for the action "repeat the last jump" would provide a consistent user experience. For now, those keys are only useful for single character search.
See also https://github.com/mawkler/demicolon.nvim