brenton-leighton / multiple-cursors.nvim

A multi-cursor plugin for Neovim that works in normal, insert/replace, or visual modes, and with almost every command
Apache License 2.0
152 stars 4 forks source link

When entering visual mode after starting multiple-cursors, the selection column is off by one #46

Closed b0o closed 3 months ago

b0o commented 3 months ago

Current behavior:

https://github.com/brenton-leighton/multiple-cursors.nvim/assets/21299126/dbf33e55-8946-4b83-8703-7ad2429379f7

Changing the following line seems to fix the issue, but I'm not sure if it has unwanted side-effects:

diff --git a/lua/multiple-cursors/normal_mode_change.lua b/lua/multiple-cursors/normal_mode_change.lua
index b3e978d..dacc486 100644
--- a/lua/multiple-cursors/normal_mode_change.lua
+++ b/lua/multiple-cursors/normal_mode_change.lua
@@ -75,7 +75,7 @@ local function _v()

     -- Save cursor position as visual area start
     vc.visual_start_lnum = vc.lnum
-    vc.visual_start_col = vc.col
+    vc.visual_start_col = vc.col - 1

     -- Move cursor forward if there's a count
     if count > 0 then

Behavior after this change:

https://github.com/brenton-leighton/multiple-cursors.nvim/assets/21299126/7fbc5926-80c0-42ff-a550-d773504534c7

brenton-leighton commented 3 months ago

This doesn't happen for me on Neovim 0.9.4, which version are you using?

b0o commented 3 months ago

NVIM v0.10.0-dev-2751+g19d63563e1

brenton-leighton commented 3 months ago

Does your cursor move forward when you use the v command?

b0o commented 3 months ago

Nope, it stays in place until I move it with h/j/k/l.

b0o commented 3 months ago

I just noticed another thing that happens: when I've entered visual mode and press v again to return to normal mode, my "real" visual selection goes away as expected, but the virtual visual selections remain:

https://github.com/brenton-leighton/multiple-cursors.nvim/assets/21299126/7ef52b5e-a266-4732-ad2c-2d92cdb3e911

b0o commented 3 months ago

I think the original issue is a compatibility issue with which-key.

I noticed that if I wait a moment after pressing v before pressing l, the issue doesn't happen. I believe it's due to which-key overriding default mappings, leading to needing to wait for timeoutlen milliseconds for the mapped sequence to complete.

Disabling which-key fixes the original issue, but not the issue I described in my last comment.

brenton-leighton commented 3 months ago

I think the original issue is a compatibility issue with which-key.

I noticed that if I wait a moment after pressing v before pressing l, the issue doesn't happen. I believe it's due to which-key overriding default mappings, leading to needing to wait for timeoutlen milliseconds for the mapped sequence to complete.

OK thanks. Is there any issue with it being disabled/re-enabled with pre_hook/post_hook?

I just noticed another thing that happens: when I've entered visual mode and press v again to return to normal mode, my "real" visual selection goes away as expected, but the virtual visual selections remain:

Yeah I noticed that too. It's because v in visual mode isn't handled but it should be easy.

b0o commented 3 months ago

After searching through which-key's docs, it does not appear to have a way to disable it after setup has been called. There's an open issue for this: https://github.com/folke/which-key.nvim/issues/548.

However, there is a way to disable it for certain operators, like v:

-- make sure to run this code before calling setup()
-- refer to the full lists at https://github.com/folke/which-key.nvim/blob/main/lua/which-key/plugins/presets/init.lua
local presets = require("which-key.plugins.presets")
presets.operators["v"] = nil

I tested this and it does fix the issue.

Do you think there is any way this plugin could be made compatible with which-key by default? If not, I suppose this is an acceptable workaround.

brenton-leighton commented 3 months ago

Can you see if it works with this branch? I think I made an error in setting the key maps which would fail to replace local buffer key maps.

b0o commented 3 months ago

Unfortunately, it still has the issue.

brenton-leighton commented 3 months ago

Can you show me the output of :lua vim.print(vim.fn.maparg("v", "n", false, true)) (without creating cursors)?

b0o commented 3 months ago

The output is vim.empty_dict()

brenton-leighton commented 3 months ago

From what I can see it's not a problem with the mapping, I think there's something in which-key that delays calling the function for certain commands. When you use the v command and then a motion before timeoutlen, the function for the motion command is called before the function for the v command.

Temporarily setting timeoutlen to 0 would be a workaround, but it means <Leader> key maps won't work.

I don't think there's anything I can do, I think the best solution is for which-key to implement disable/enable functions.

b0o commented 3 months ago

That's okay, I think adding a note to the plugin compatibility section in the README about this workaround would be sufficient.

brenton-leighton commented 3 months ago

Done with #49