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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

feat: Provide a hook that be called when first do custom mapping

mrbeardad opened this issue · comments

Some command require user input, says surround, get input in first call and feed the same input keys for subsequent call.
For example,

          cursor1
           v
This is "st|ring"
This is "st|ring"
           ^
           cursor2
  1. press ds, await user input
  2. press ", delete the quote at cursor1
  3. automatically feedkeys("\"") after call custom function at cursor2, thus, the subsequent calls no longer wait for user input

The simplest solution maybe adding a parameter is_init for custom mapping function.

image

Do you want to get a character after the command? I have implemented it with two functions in the input module:

  • get_motion_char() for getting a valid motion character (so operator pending mode, like for normal mode d or y)
  • get_char() for getting any printable character (like for normal mode f or t)

I think you can use the get_char() function like this:

local char = require("multiple-cursors.input").get_motion_char()

It returns nil if the character entered isn't valid

Cutsom mapping function is called for every cursor position, but I have to call get_motion_char only once.

OK good point, let me see what I can do.

Does this work: feat_custom_func_get_char

So for each table in the custom_key_maps table you can add another element, "m" for a motion character or "c" for a printable character. Then the character will be passed to your function. E.g.

custom_key_maps = {
    {{"n", "i"}, "<C-/>", function(char) vim.print(char) end, "c"},
  },                               ^^^^                       ^^^

I've made a pr #11 , is there anything duplicate with thie branch?

Only get one char maybe not enough, for example, also surround, cs<char1><char2> to change surrounding <char1> to <char2>

Only get one char maybe not enough, for example, also surround, cs<char1><char2> to change surrounding <char1> to <char2>

Does this work? get_two_chars

Yes, it works well.

Maybe it could be more extensible.

custom_key_maps = {
  {"n", "<Leader>x", function(chars) vim.print(unpacked(chars)) end, {"c","m","o"}}
  -- "c" means any character, "m" means motion, "o" means textobj
}

Maybe it could be more extensible.

custom_key_maps = {
  {"n", "<Leader>x", function(chars) vim.print(unpacked(chars)) end, {"c","m","o"}}
  -- "c" means any character, "m" means motion, "o" means textobj
}
  • I don't think it's possible to use one option to get an arbitrary number of characters, the wrapper function needs to know the number of characters to get from the user. I'm also not sure what the use case for more than two characters is.
  • By textobj do you mean treesitter text objects? I'm not sure how this will work, but I think they would be a per-cursor variable.
  • I have had to make some changes to how elements in custom_key_maps are defined. Functions now receive register and count1, and then optionally motion_cmd, char or char1, char2. It's documented here.

@mrbeardad by textobj do you mean text object motions or text object selection?

In the plugin_compatibility branch I've added support for text object selections for the input.get_motion_cmd() function. Is this what you wanted when you asked for getting two characters?

I've also added the custom key map option "mc" to get a motion command then a character. In theory this could be used for a surround command, but I've looked at mini.surround and kylechui/nvim-surround and they don't have functions that can be called with the motion and character as arguments.

The closest thing I can get working is to map a different key sequence to the surround command, e.g. for mini.pairs:

custom_key_maps = {
  {"n", "<Leader>sa", function(_, count1, motion_cmd, char)
    vim.cmd("normal " .. count1 .. "sa" .. motion_cmd .. char)
  end, "mc"},
},

But since it uses a different key sequence while multiple cursors is active it's not ideal.

In the plugin_compatibility branch I've added support for text object selections for the input.get_motion_cmd() function. Is this what you wanted when you asked for getting two characters?

Yes, some motions require one char, such as w, and some require two char, such as f{char} and aw, even some require three char, such as anw in mini.surround. So it is hard to set all of these maps.

I've pre-researched using q macros recording to implement multiple cursors, the
demo is here, it seems successful. Thus, custom_key_maps is no longer needed. When user has done a completed normal command, repeat it at virtual cursors.

Yes, some motions require one char, such as w, and some require two char, such as f{char} and aw, even some require three char, such as anw in mini.surround. So it is hard to set all of these maps.

w and aw are handled by the "m" (motion command) option, and f{char} is handled by the "mc" (motion command then character) option. I can find anything on what anw means.

Anyway if you aren't using it I can remove the "cc" option and get_two_chars function.