macvim-dev / macvim

Vim - the text editor - for macOS
https://macvim.org
Vim License
7.55k stars 682 forks source link

Ability to change what happens when pasting with Cmd+v the editor while still being able to use Cmd+v to paste in dialogs #1505

Open adamnovak opened 1 month ago

adamnovak commented 1 month ago

Is your feature request about something that is currently impossible or hard to do? Please describe the problem.

I'm trying to customize paste behavior in MacVim in insert mode, to add come <C-g>u sequences to create undo points before and after the pasted text.

I can do that with an inoremap <D-v>. But in order for <D-v> to make it to the Vim input processing, it can't be bound in the MacVim menu system to the paste: action. So the folks at SuperUser suggest:

macmenu Edit.Paste key=<nop>
noremap <D-v> "*P
cnoremap <D-v> <C-r><C-o>*
inoremap <D-v> <C-g>u<C-r><C-o>*

But if you do that, then paste doesn't work in dialogs and other non-Vim UI elements insider MacVim, such as the graphical find dialog. As noted in the MacVim help on customizing the menu:

(E.g. the menu item "Edit.Paste" must be bound to the action "paste:" otherwise pasting won't work in dialogs since that is the action that instructs them to paste something.)

And I can't find any documentation on how to either change what happens when a paste: action is received by the Vim layer, or to set what happens when a <D-v> is sent to the GUI layer when it's not bound to a menu option.

So I'm not able to achieve the configuration where pressing Command+v creates undo points around the pasted text in Vim's insert mode, but also still works on text boxes in the GUI.

Describe the solution you'd like

My ideal approach would be to have paste: reach the Vim core exactly as if <D-v> were being typed, so that remapping <D-v> with inoremap would Just Work without having to unbind it from the menu item.

Describe alternatives you've considered Other approaches would be:

Additional context I only barely know enough about Vim input processing to articulate what I want to achieve, so it's possible I'm missing something obvious about how pasting works in Vim.

ychin commented 1 month ago

Yeah I have been unsatisfied with how this is handled right now. The current way of associating a key with the menu is a very "Apple-like" way of handling shortcut keys, but at the same time makes it hard to configure with Vim key bindings. It's been on my list of to-fixes but I haven't quite got around to it.

Documenting some already-existing way to customize what the paste: action does by overwriting/replacing some VimScript function it already invokes.

Yes, this is definitely needed.

Providing an option on the macmenu command to set key sequences to be issued in Vim before/after the action is processed.

This is currently roughly how I plan to attack the issue, but that may change. There are some other considerations with improving the input (e.g. meta keys, modifyOtherKeys support) so I'm trying to think about it cohesively.

But the answer is for now, yeah it's a little annoying for sure.

adamnovak commented 1 month ago

Is there some already-existing way to hook the paste function that could be documented? If so, that would be a very useful workaround for me.

ychin commented 1 month ago

Is there some already-existing way to hook the paste function that could be documented? If so, that would be a very useful workaround for me.

No, there isn't. What you need to do is remove the paste menu item using aunmenu / tlunmenu and then manually remap <D-V> to paste yourself. It's hacky but that's the way to do it right now.

adamnovak commented 1 month ago

OK, I tried:

aunmenu Edit.Paste
tlunmenu Edit.Paste
noremap <D-v> "*P
cnoremap <D-v> <C-r><C-o>*
inoremap <D-v> <C-g>u<C-r><C-o>*<C-g>u

And that removes Paste from the Edit menu entirely and works to free up <D-v> for my bindings. But the items don't return to the menus when I change focus to a dialog box, I think because the Vim core is still in one of the modes covered by the unmenu commands, and <D-v> in the dialogs doesn't work without the menu option.

ychin commented 1 month ago

But the items don't return to the menus when I change focus to a dialog box,

Wait, what dialog boxes?

adamnovak commented 1 month ago

Under Edit -> Find -> Find... there's a standard-ish MacOS find and replace dialog. Here's a screenshot: Screenshot 2024-10-23 at 12 20 13

I end up with it because I mash Command + F when I want to find things sometimes, instead of remembering to do Escape and then slash.

In those text fields, I might want to paste something, and if I do that I want to do Command + F and then Command + V right after it. But if I unbind Command + V from the menus, I can't paste in the text fields in the dialog.

Maybe I just also need to unbind Command + F from the menus so I never see the dialog. I think I already wrote bindings for it to do go to normal mode and do slash, and then never investigated why they didn't work.

ychin commented 1 month ago

Ah right yeah. But yes this is why this method is kind of a hack. I personally recommend mapping another key for this purpose for now.