junegunn / vim-peekaboo

:eyes: " / @ / CTRL-R
1.13k stars 39 forks source link

<C-r> mappings gets inserted literally with/in "Visual-block Insert" mode #22

Open blueyed opened 9 years ago

blueyed commented 9 years ago

When using Visual-block Insert (CTRL-V from normal mode, select a region, then I), the <C-r> mapping does not work: it enters the right hand side literally:

:call peekaboo#peek(1, 'ctrl-r',  0)
junegunn commented 9 years ago

Thanks, I can reproduce the problem. I've just realized that i_CTRL-O does not work in that mode at all. Duh, is it an expected behavior?

blueyed commented 9 years ago

I don't know.. the help for v_b_I is rather short:

Visual-block Insert v_b_I
With a blockwise selection, I{string} will insert {string} at the start of block on every line of the block, provided that the line extends into the block. Thus lines that are short will remain unmodified. TABs are split to retain visual columns. See v_b_I_example.

junegunn commented 9 years ago

Hmm, with Vim behaving this way, I have no idea how to fix it :confused:

blueyed commented 9 years ago

Maybe it could be disabled / skipped in this case? It would need to hook into InsertEnter maybe and/or look at mode() and visualmode(), doing nothing if it's CTRL-V.

junegunn commented 9 years ago

visualmode() only tells what the previous visual mode was. So if we

  1. Enter blockwise-visual mode
  2. Esc
  3. Do something in normal mode
  4. Enter ordinary insert mode (i, a)

then, visualmode() will still return CTRL-V, and we can't use it to determine whether we should temporarily disable CTRL-R or not.

blueyed commented 9 years ago

I see. But using mode(1) should do? I could imagine using a <expr> mapping instead of the current one, if that's possible, and it would check mode(1) against CTRL-V.

junegunn commented 9 years ago

Hmm, do you mean checking mode(1) on InsertEnter?

blueyed commented 9 years ago

No, with the insert mapping (which needs to be turned into a <expr> mapping the probably). It would skip any action (and return "") if mode(1) is CTRL-V.

junegunn commented 9 years ago

Then, wouldn't it return i? e.g. inoremap <expr> xxx mode(1)

blueyed commented 9 years ago

Yes, it returns i then.. :/

It seems to be required to hook into InsertEnter/InsertLeave then, as outlined in https://github.com/Raimondi/delimitMate/issues/138#issuecomment-42515065.

junegunn commented 9 years ago

But doing so still has the same problem I mentioned above (C-V, normal, insert), visualmode() is not a perfect way to determine if we're in blockwise-insert mode.

junegunn commented 9 years ago

Maybe we could fix this by changing the current mapping to <expr> mapping and not using <c-o>, I'll check if it's viable.

junegunn commented 9 years ago

No it's not :hankey:

Error detected while processing function peekaboo#peek..<SNR>32_init:
line   13:
E523: Not allowed here: vertical botright 30new
blueyed commented 9 years ago

There would be visualmode(1) which clears the current mode after getting it (which might have side effects, if others rely on it). But without being able to use <expr> it does not help much, does it?

junegunn commented 9 years ago

Oh, I wasn't aware of visualmode(1), but I don't think we should use it because of its global side-effect.

But without being able to use it does not help much, does it?

You're right.

By the way, I'm starting to wonder if this (not allowing <c-o> is vbi) can be a bug of vim itself. If that's the case, I mean if this is a known issue of Vim, we probably shouldn't try too hard to find a complicated workaround for it and just let the users know about it and suggest them to iunmap if it severely hinders their workflow.

nick-s-b commented 9 years ago

Thank you for this thread. I finally understand why nmap <F3> a<C-R>=strftime("%Y-%m-%d %a %I:%M %p")<CR><Esc> doesn't work on my setup (I have peekaboo installed).

junegunn commented 9 years ago

@nick-s-b No, it's unrelated. Your problem is easily fixed by using non-recursive map.

nnoremap <F3> a<C-R>=strftime("%Y-%m-%d %a %I:%M %p")<CR><Esc>

See: https://github.com/junegunn/vim-peekaboo#peekaboo-conflicts-with-my-maps-and-abbrevs

nick-s-b commented 9 years ago

Thank you so much junegunn! Works perfectly now!

seletskiy commented 8 years ago

@junegunn: I guess, you can workaround that issue by mapping I in the visual-mode and keep tracking state changes to determine whether vim in the CTRL-V I mode or just I, like I've done in the following commit: https://github.com/reconquest/vim-pythonx/commit/88848306ee873e591ad165e3fafc40e59bf98484

junegunn commented 8 years ago

@seletskiy Thanks, maybe it's the only option. But unfortunately once this plugin defines the mapping it will no longer be compatible with the plugins that also define the same mapping, right? That is not ideal :(

seletskiy commented 8 years ago

@junegunn: If you feel particularly hacky, you can try to save/restore user-mapping back and forth. Or just print warning, if mappings are clashing and write concise howto in the readme about how to use vim-peekaboo mapping for I with other plugins. User always can do something like that:

vnoremap <expr> I peekaboo#WorkaroundBlockWiseInsert() && doMyPreviousIActions()

Much better, I guess, than having plugin completely broken in the block-wise insert.

josefson commented 1 year ago

Did anybody find a workaround this issue?