vim-matchup icon indicating copy to clipboard operation
vim-matchup copied to clipboard

Feature request: expand the SAME last selection outwards with `<C-o>` instead of press again `i%` or `a%`

Open juanMarinero opened this issue 5 months ago • 4 comments
trafficstars

The vmap C-o is logical and easier to press than i% or a%

  • o to go to other end of highlighted text, O in visual block mode. References :h visual-change
  • Based on these described purposes of vmaps o/O I think it's natural to press (in any visual mode) C-o to expand same as last pair-blocks selection
  • ...instead of trigger again i% (or a% or alike). Which is more difficult to trigger and less logical: we already did the mental effort the first time (when we changed to visual mode) to decide to use i% (or a% or alike), now we just want to keep that policy with a simple logical vmap.

How to use urxvtcd/indent_object.vim, see Additional context at the end.

  • Go to [char/line/block] visual mode: v, V or <C-v>
  • Press ii to select all lines with the same indent
  • (Optional) Press again ii (or Ctrl-O) to expand to lines of 1 less-deep indent. Repeat as needed
  • (Optional) Press o and j/k to add/substract lines. Repeat as needed

How to use vim-matchup:

  • Go to [char/line] visual mode v or V
  • Press for example i%
  • (Optional) Press again i% (do not use Ctrl-O cause it's only available for vim-indent-object) to expand to lines of 1 less-deep "any" block. Repeat as needed
  • (Optional) Press o and j/k to add/substract lines. Repeat as needed
  • Note in block-visual mode <C-v> the selection is as expected: a rectangle. Probably not what you want.

The solution I'd like

I do not request <C-o> to replace %i (as describe in FAQS: The maps 1i% and 1a% are difficult to press. You may use the following maps I% and A% for convenience:[...]).

I request <C-o> to repeat the SAME last expand of selection outwards, it could be i% or a% (or even {count}i% vs {count}a%).

Alternatives

If not possible (or difficult) to save last expand function to distinguish i% or a% (or even {count}i% vs {count}a%), then just remap <C-o> to i% as I use it much more frequently than a%. FAQs shows how to make I% act as 1i%, I would need help to make <C-o> behave like i% please.

Additional context urxvtcd/vim-indent-object in its usage (and :h <Plug>(indent-object_repeat)maps

xmap <C-o> <Plug>(indent-object_repeat)

See plugin/indent_object.vim:

xnoremap <silent> <Plug>(indent-object_repeat) :<C-u>call indent_object#repeat_visual_mapping()<CR>

and autoload/indent_object.vim

function! indent_object#repeat_visual_mapping()
   [...]

juanMarinero avatar May 27 '25 10:05 juanMarinero

The only problem with this is <c-o> is a built in feature in visual mode in vim.

You should be able to put

xmap <c-o> i%

or

xmap <c-o> <plug>(matchup-i%)

in your configuration.. does that work?

andymass avatar May 31 '25 01:05 andymass

Hi @andymass ! Thanks for your answer!

  • Initially :verbose xmap i% echoes x i% <Plug>(matchup-i%)
  • But if in my vimrc I set xmap <c-o> <plug>(matchup-i%) then :verbose xmap i% echoes No mapping found. And indeed, Ctrl-O acts like i% (in visual mode), while i% triggers nothing. Btw. I commented <C-o> mapping of urxvtcd/indent_object.vim in all these tests.
  • These symptons are not limited to <c-o>: if instead of xmap <c-o> <plug>(matchup-i%) I set xmap <leader>z <plug>(matchup-i%) then <leader>z works and i% triggers nothing

On the other hand xmap <c-o> i% works and let's i% still work.

I experience all this in both Vim 9.1 and NVIM v0.11.1.

I never encountered/realized this issue: that two shortcuts cannot call the same command (a <Plug> one). Docs, AI and google-searc do not help me, I guess because I ask wrong questions. HELP me to understand this issue please.


Maybe this is why urxvtcd/indent_object.vim maps next:

  • xmap ii <Plug>(indent-object_linewise-none)
  • xmap <C-o> <Plug>(indent-object_repeat)
  • Btw. also omap ii <Plug>(indent-object_blockwise-none)

...instead of

  • xmap ii <Plug>(indent-object_linewise-none)
  • xmap <C-o> <Plug>(indent-object_linewise-none)

<c-o> is a built in feature in visual mode in vim

Initially :verbose xmap <c-o> echoes No mapping found, ~~so I think that it's not a visual default map~~. And that's OK since :map and alike only show user-defined mappings and excludes built-in ones, though :map-commands does not explicit say it, maybe somewhere else it's stated. Proof is that:

  • :verbose map o shows no map when it's to go to other end of highlighted text, see :h visual-change.
  • or that even if :verbose map c-o shows no map, the <C-o> it's a normal mode map for sure as :h CTRL-O echoes:
							*CTRL-O*
CTRL-O			Go to [count] Older cursor position in jump list
			(not a motion command).

Thus this triggers a new question: How to list the built-in keybindings?

Anyhow, since :h CTRL-O says nothing about visual maps and <C-o> triggers no action in visual mode, then I think that your statement is not right, thus <c-o> is NOT a built in feature in visual mode in vim.


TLDR:

  • Why two Vim maps cannot call same command (a <Plug> one) ?
  • How to list the built-in keybindings in Neo/Vim?
  • My original request. xmap <c-o> i% solves my Alternatives, but not the The solution I'd like:

I request <C-o> to repeat the SAME last expand of selection outwards, it could be i% or a% (or even {count}i% vs {count}a%).

juanMarinero avatar May 31 '25 08:05 juanMarinero

Why two Vim maps cannot call same command (a <Plug> one) ?

This is actually by design and documented here: https://github.com/andymass/vim-matchup/blob/56c714495ec7f40cf2c7e92fb124067c7951e650/doc/matchup.txt#L181

The idea is if you manually map something to owned by vim-matchup, the plugin assumes you want that instead of the default. If you don't want that, the recommendation is:

:xmap <c-o> i%

To keep both maps.

How to list the built-in keybindings in Neo/Vim?

:help v_<c-o>

In general, type :help v_ then press tab to list built-ins in visual mode.

My original request. xmap i% solves my Alternatives, but not the The solution I'd like:

Ahh, I understand your request now. Let me think how to achieve.

andymass avatar May 31 '25 14:05 andymass

  • [x] Why two Vim maps cannot call same command (a <Plug> one) ? Ahhh by plugin design, understood.

  • [x] How to list the built-in keybindings in Neo/Vim? I'm so happy to learn this. Thank you very much!

Shame on me! The beginning of vim-docs (or :h help-context) states this very clear:

			  WHAT			PREPEND    EXAMPLE
		      Normal mode command      (nothing)   :help x
		      Visual mode command	  v_	   :help v_u
		      Insert mode command	  i_	   :help i_<Esc>
		      Command-line command	  :	   :help :quit
		      Command-line editing	  c_	   :help c_<Del>
		      Vim command argument	  -	   :help -r
		      Option			  ''	   :help 'textwidth'

TLDR:

  • For visual ~maps~ built-in keybindings prepend v_, for example :h v_u shows
							*v_u*
{Visual}u		Make highlighted text lowercase (for {Visual} see
			|Visual-mode|).
  • For normal built-in keybindings prepend nothing, like :h u shows
<Undo>		or					*undo* *<Undo>* *u*
u			Undo [count] changes.

Terminology. I hope this distinction helps other Vim newbies like me. Both next are shortcuts:

  • Built-in keybindings are defined by Neo/Vim, they are called Normal mode command, Visual mode command, etc. in the vim-docs
  • Maps defined by user (like plugin installed)

Also great <TAB> advise @andymass ! 🎉 ...vimfaq suggests this too:

4.2. How do I search for a keyword in the Vim help files?
[...]
You can press the Tab key after typing a partial help keyword to expand to
the matching keyword. You can continue to press the Tab key to see other
keyword matches.
  • [x] <c-o> is a built in feature in visual mode in vim I was wrong, you were right. It's a built-in keybinding as :help v_CTRL-O shows:
- CTRL-O switches to Visual mode for the duration of one command. *v_CTRL-O*
  • [x] My original request. xmap <c-o> i% solves my Alternatives Thanks again!

  • [ ] The solution I'd like: <C-o> to repeat the SAME last expand of selection outwards It was not easy to explain, so I insisted with the "SAME" word.

  • Great that now it's understood.

  • But I repeat, if this request is difficult, or not very useful-requested, then please just keep this ticket open and don’t prioritize solving it. If very difficult or not possible, then close the issue.

juanMarinero avatar Jun 01 '25 11:06 juanMarinero