Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ;, , repeat keys interoperate with native ;, , #176

Open
llllvvuu opened this issue Jul 18, 2023 · 8 comments
Open

Make ;, , repeat keys interoperate with native ;, , #176

llllvvuu opened this issue Jul 18, 2023 · 8 comments
Labels
enhancement New feature or request

Comments

@llllvvuu
Copy link

If you do Leap then native f/t, ; will repeat the Leap motion rather than the native f/t motion.

Workaround: use different bindings for Leap repeat

@ggandor
Copy link
Owner

ggandor commented Jul 19, 2023

If anyone can solve this (interop with native f/t), I'd be very happy to hear how (I couldn't yet).

@llllvvuu
Copy link
Author

llllvvuu commented Jul 19, 2023

I think this happens also with leap.nvim and flit.nvim. leap then flit -> ; still repeats the leap. Maybe related: ggandor/flit.nvim#29 (comment)

@IndianBoy42
Copy link
Contributor

off the top of my head maybe you could use vim.on_key to see when fFtT is hit and unmap the leap repeat mappings from there (may need vim.schedule), and then remap it when leap is activated.

@llllvvuu
Copy link
Author

IIRC this works in vim-sneak so there could be some inspiration there

@Subjective
Copy link

@ggandor nvim-treesitter/nvim-treesitter-textobjects#359 provides a repeatable movements engine that interops with native ;/, and allows other plugins to hook into it.

In their README, they also mention https://github.com/ghostbuster91/nvim-next as being a more focused and lightweight alternative that provides out of the box ;/, integrations with the former and several other plugins. Would it be possible to provide a repeat api for leap that either can hook into?

Taken directly from the README for nvim-treesitter-textobjects

You can make the movements repeatable like ; and ,.

local ts_repeat_move = require "nvim-treesitter.textobjects.repeatable_move"

-- 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)

-- Optionally, make builtin f, F, t, T also repeatable with ; and ,
vim.keymap.set({ "n", "x", "o" }, "f", ts_repeat_move.builtin_f)
vim.keymap.set({ "n", "x", "o" }, "F", ts_repeat_move.builtin_F)
vim.keymap.set({ "n", "x", "o" }, "t", ts_repeat_move.builtin_t)
vim.keymap.set({ "n", "x", "o" }, "T", ts_repeat_move.builtin_T)

You can even make a custom repeat behaviour.

-- This repeats the last query with always previous direction and to the start of the range.
vim.keymap.set({ "n", "x", "o" }, "<home>", function()
  ts_repeat_move.repeat_last_move({forward = false, start = true})
end)

-- This repeats the last query with always next direction and to the end of the range.
vim.keymap.set({ "n", "x", "o" }, "<end>", function()
  ts_repeat_move.repeat_last_move({forward = true, start = false})
end)

Furthermore, you can make any custom movements (e.g. from another plugin) repeatable with the same keys. This doesn't need to be treesitter-related.

-- example: make gitsigns.nvim movement repeatable with ; and , keys.
local gs = require("gitsigns")

-- make sure forward function comes first
local next_hunk_repeat, prev_hunk_repeat = ts_repeat_move.make_repeatable_move_pair(gs.next_hunk, gs.prev_hunk)
-- Or, use `make_repeatable_move` or `set_last_move` functions for more control. See the code for instructions.

vim.keymap.set({ "n", "x", "o" }, "]h", next_hunk_repeat)
vim.keymap.set({ "n", "x", "o" }, "[h", prev_hunk_repeat)
Alternative way is to use a repeatable movement managing plugin such as [nvim-next]
Taken from the README for nvim-next

Repeateable movements reborn!

By default vim allows repeating default movements like f/F/t/T and others using ; and ,. However, the builtin mechanism is not extendable and as soon as we start using some custom movements we are left to implement the repeating on your own. Some plugins provide that options some don't. But even when they do, they do it in a way that steals ; for themselves.

While I don't use repeating movments often with default motions, I would like to use them with motions like next-treesitter-method, next-diagnostic, next-git-change, etc that comes from many different plugins.

This plugin is a repeatable movments engine that other plugins can hook into. You can think of it as of nvim-cmp but for movements.

The idea is that other plugins like for example git-signs will expose logic to perform some movement, and then we will wrap it with an adapter and plug into that engine.

@ggandor ggandor changed the title ;, , repeat keys don't interoperate with native ;, ; Make ;, , repeat keys interoperate with native ;, , Jul 22, 2023
@ggandor ggandor added the enhancement New feature or request label Jul 22, 2023
@ggandor
Copy link
Owner

ggandor commented Jul 22, 2023

@Subjective Interesting project, but it's not interoping with native ;/,, it actually reimplements f/F/t/T. (At the moment, dot-repeat, cancelling a change operation, and forcing v are broken, for example. Which is fine, the readme states the plugin is in a very early state, and this is the authors first plugin, I'm just noting.)

Would it be possible to provide a repeat api for leap that either can hook into?

I'm not sure what other API we would need to provide other than the repeat parameter in the leap function (the "writing a custom adapter" part is yet to be finished in the readme).

@ggandor
Copy link
Owner

ggandor commented Jul 22, 2023

I think this happens also with leap.nvim and flit.nvim. leap then flit -> ; still repeats the leap. Maybe related: ggandor/flit.nvim#29 (comment)

Interop between leap and flit is doable with some autocommand and expression mapping magic, someone just needs to do it :)

@Subjective
Copy link

IIRC this works in vim-sneak so there could be some inspiration there

Seems like vim-sneak just remaps f/F after sneaking.

https://github.com/justinmk/vim-sneak/blob/29ec9167d4a609f74c130b46265aa17eb2736e6a/doc/sneak.txt#L431

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants