vim-visual-multi icon indicating copy to clipboard operation
vim-visual-multi copied to clipboard

Adding cursor with `<M-key>` calling `<Plug>` adds an empty newline (only once)

Open woertsposzibllen4me opened this issue 1 year ago • 1 comments

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

  1. 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.

  1. Initially, the of by one error was called whenever I called <Plug>(VM-Add-Cursor-At-Pos)
  2. Then remapping to the plugins defaults with some custom binds worked.
  3. Then that stopped working with no changes.
  4. 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.
  5. 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.
  6. ---> Actually, this is only true when using leader keys for the plug, which might maybe be because my leader is space.
  7. 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 with M-k and M-j but also m-t or m-b etc.. so this is not related to being j or k and 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.

woertsposzibllen4me avatar Aug 31 '24 20:08 woertsposzibllen4me

This is happening to me too, once again with C-n. Probably the same as #243

:VMDebug gives me this 2024-09-12_17-32

renxzen avatar Sep 12 '24 21:09 renxzen

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.

dpetka2001 avatar Nov 29 '24 12:11 dpetka2001

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

woertsposzibllen4me avatar Dec 05 '24 06:12 woertsposzibllen4me