Adding cursor with `<M-key>` calling `<Plug>` adds an empty newline (only once)
This started as a different problem which seemingly got resolved by its own, but also unveiled what appears to be a more persisting minor bug.
So the below doesn't really matter but I kept it for context or in case it goes wrong gain...
Initial issue, which got resolved
Describe the issue:
Cursor position added with <Plug>(VM-Add-Cursor-At-Pos) is off by one character.
https://github.com/user-attachments/assets/d577b2b6-95f9-482b-aecc-fc3badc21a3f
Steps to reproduce
- Use
<Plug>(VM-Add-Cursor-At-Pos)
Fix
\\\ Accurately adds cursor, so a simple custom rebind to that would probably be fine but just thought I'd point this one out. I'll try rebinding with an alternative method, but I kinda liked Plug cause it's simple to understand ahah
-- this will work
vim.keymap.set("n", "<M-J>", "<Plug>(VM-Add-Cursor-Down)", { noremap = true, silent = true })
vim.keymap.set("n", "<M-K>", "<Plug>(VM-Add-Cursor-Up)", { noremap = true, silent = true })
-- btw these^ are ever so slightly buggy, they might add an empty new line on the first use in a session.
-- Adding cursors, first cursor is added with [I]nitial key as to pause the keymap to navigate better.
vim.keymap.set("n", "<leader>C", "\\\\\\", { noremap = false, silent = true })
vim.keymap.set("n", "<leader>T", "\\\\<Space>", { noremap = false, silent = true })
vim.keymap.set("n", "<leader>I", "\\\\\\\\\\<Space>", { noremap = false, silent = true })
- Operating System: Windows 11
- Vim Version: 0.10.1
- commit SHA/branch: 38b0e8d
EDIT : looks like a difficult keybind plugin, from reading other posts ... and, well, the code I showed as my fix just stopped working... It was completely fine, did not touch anything, doesn't work anymore 🤷
EDIT2: I am experiencing new behavior again where my initial example in the video seems to be working as intented, partially... will update.
EDIT3: So after going through the five stages of grief... It seems a stable solution has been found.
- Initially, the of by one error was called whenever I called
<Plug>(VM-Add-Cursor-At-Pos) - Then remapping to the plugins defaults with some custom binds worked.
- Then that stopped working with no changes.
- Then calling
<Plug>(VM-Add-Cursor-At-Pos)seemed to not cause an off by one error, but calling<Plug>(VM-Add-Cursor-At-Pos)<Plug>(VM-Toggle-Mappings)in immediate succesion from one keybind did. - However, calling two keybinds which each trigger one of those actions in immediate succesion, will work, but will also trigger a displacement of the "live" cursor by 2 characters to the right after placing the "plugin" cursor.
- ---> Actually, this is only true when using leader keys for the plug, which might maybe be because my leader is space.
- Finally, the first keybind issued with
<M-something>will usually create a new emtpy new line on the first use of the session, if no additional cursor were spawned beforehand. This is true withM-kandM-jbut alsom-torm-betc.. so this is not related to beingjorkand some up/down line interaction, I guess...
Therefore my (currently) working implementaion will be:
-- First cursor is added with [I]nitial key as to pause the keymap to navigate better.
-- avoid displacement issues by using <leader>I and not <M-I> as initial bind
vim.api.nvim_set_keymap("n", "<Leader>I", "<M-L><M-H>", { noremap = false, silent = true })
-- Dropoff cursor at current position
vim.api.nvim_set_keymap("n", "<M-L>", "<Plug>(VM-Add-Cursor-At-Pos)", { noremap = true, silent = true })
-- Toggle cursors shifting with HJKL
vim.api.nvim_set_keymap("n", "<M-H>", "<Plug>(VM-Toggle-Mappings)", { noremap = true, silent = true })
-- Add cursors up/down
vim.api.nvim_set_keymap("n", "<M-K>", "<Plug>(VM-Add-Cursor-Up)", { noremap = true, silent = true })
vim.api.nvim_set_keymap("n", "<M-J>", "<Plug>(VM-Add-Cursor-Down)", { noremap = true, silent = true })
Anyways, I'm very sorry for anybody who read all that... but the only surely garanteed bug that was detected here is that the first keybind issued with M-m to add a cursor, will add an empty newline.
TLDR
Actual current issue:
When no cursor was previously added, spawning a new cursor with a keybind involving M (as in alt, or option) will create an emtpy new line.
video:
https://github.com/user-attachments/assets/3bd7b042-3775-4929-9738-51eee3bef58f
EDIT: noticed it happens with C-n initiation too.
This is happening to me too, once again with C-n. Probably the same as #243
:VMDebug gives me this
I solved this with the following configuration
{
"mg979/vim-visual-multi",
event = "LazyFile",
init = function()
vim.g.VM_theme = "purplegray"
vim.g.VM_mouse_mappings = 1
vim.schedule(function()
vim.g.VM_maps = {
["I BS"] = "",
["Goto Next"] = "",
["Goto Prev"] = "",
}
end)
end,
},
Not sure if this applies to everyone, but this works for me. I lazy-load the plugin because there are some default mappings overlapping (e.g. <C-up/down> for creating cursor up/down). I could just disable/change those mappings, but preferred to lazy-load the plugin, so that they are simply overwritten. LazyFile is LazyVim specific and it's just an alias for { "BufReadPost", "BufNewFile", "BufWritePre" }, so you could just use those events if you want to lazy-load.
Otherwise you can just simply don't lazy-load the plugin and it will still work, but if you have any overlapping mappings you would have to change them in your personal configuration.
FINAL EDIT WITH SOLUTION:
Ok so in my case I had a compatibility issue with autopairs, which has a provided hack already there: https://github.com/mg979/vim-visual-multi/issues/172#issuecomment-2260332100
The solution shown in the linked response however was insufficient for me, I still had an emtpy newline on startup, until I added those lines:
vim.g.VM_maps = {
["Goto Next"] = "]v", -- whatever rebind u wish for
["Goto Prev"] = "[v",
}
This is because I also had another conflict with the treesitter-textobject plugin regarding its use of ]something bindings.
Full fix code for both comp. issues:
config = function()
-- Hack around issue with conflicting insert mode <BS> mapping
-- between this plugin and nvim-autopairs
vim.api.nvim_create_autocmd("User", {
pattern = "visual_multi_start",
callback = function()
pcall(vim.keymap.del, "i", "<BS>", { buffer = 0 })
end,
})
vim.api.nvim_create_autocmd("User", {
pattern = "visual_multi_exit",
callback = function()
require("nvim-autopairs").force_attach()
end,
})
-- Fixes conflict with treesitter-textobjects
vim.g.VM_maps = {
["Goto Next"] = "]v",
["Goto Prev"] = "[v",
}
end