4

My .vimrc remaps 0 to ^ in normal and visual+search modes.

:nmap 0 ^
:vmap 0 ^

Ideally, I would like 00 to go to the true beginning of the line (i.e., what 0 does by default). Is this possible in a .vimrc? If that is not directly possible, is it possible to have 0 go to the true beginning if the cursor is already at the whitespace beginning?

2 Answers 2

5

One disadvantage of creating a Vim mapping for 00 (in addition to the mapping for 0) is that, when you use the 0 motion, Vim will wait for the next key to tell whether what you wanted was 00, so using 0 on its own will feel awkward due to that delay. (This is generally an issue when creating mappings that have another valid mapping or keybinding as a prefix.)

One way to accomplish something like you want (pressing 0 twice to go to the true beginning) is to create a conditional mapping for the 0 key, which will go to the whitespace beginning of the line in the normal case, but that will instead jump to the true beginning of the line if the cursor is right after the initial indentation.

You can create such a mapping with:

nnoremap <expr> 0 virtcol('.') == indent('.')+1 ? '0' : '^'
xnoremap <expr> 0 virtcol('.') == indent('.')+1 ? '0' : '^'
onoremap <expr> 0 virtcol('.') == indent('.')+1 ? '0' : '^'

This will program the mapping in Normal (n), Visual (x) and Operator-Pending (o) modes. (Operator-Pending mode means you can use d0 or c0 and Vim will use the mapping for the 0 part.)

Note that the way this expression is coded, Vim will "toggle" between the two possible beginnings of a line as you keep pressing 0, so if you're at the true beginning and press 0, you'll end up at the whitespace beginning. One possible drawback of this approach is that you might use O by itself to go to the whitespace beginning of a line, but if you were already there, you'll end up at the true beginning instead, which makes the mapping somewhat counter intuitive in some cases.

You could change the mapping to always go to the whitespace beginning of a line whenever the cursor is somewhere past that column, then go to the true beginning whenever the cursor is before that column, that way pressing 0 more than twice will no longer toggle, but keep at the true beginning.

Another UX option would be to have the first use of 0 always go to the whitespace beginning of the line and repeated uses of 0 to then move to the true beginning of the line, but that's fairly more complex to program, since it's hard to detect what the last key used was. You might need to use a global variable to track whether you've just pressed 0 and then some autocommands tracking whether the cursor was moved and clear that global variable, in order to detect that another key or motion was used after the last 0. That's possible doable, but definitely much harder to implement.

5

You can use nnoremap to achieve this (see the first chapter of the 'Tuning Vim' section of the user guide with :help usr_40.txt and also see :help nnoremap), although there will be a slight delay when pressing the single 0 as vim waits to see if you're going to press it again...

nnoremap 0 ^
nnoremap 00 0
vnoremap 0 ^
vnoremap 00 0

To avoid the delay you could instead use:

nnoremap <LEADER>0 ^
vnoremap <LEADER>0 ^

and preserve the original 0 motion.

However...

It usually pays to learn the default/core vim commands rather than remapping them - what if you want to change from the end of the current line to the first non-whitespace character? In visual mode you could use your proposed 0 mapping to highlight the text and then hit c to change it. But if you try the normal mode way (hitting c0) you will find that the default 0 motion is used, not the remapped motion above. So in the end this remapping actually blocks off a part of vim's capabilities (although see the answer from @filbranden to fix this)...

Using the <LEADER>0 mapping also has this problem, but at least you could in principle catch yourself beforehand and correctly use c^ since it's still available because you didn't remap it (but then you're burdened by needing to keep these two options in mind...)

If you really don't want to get used to using ^, you can avoid putting remaps in your .vimrc altogether and use these two motions instead of ^:

0w

That doesn't require any remaps and so you'll be happier if you have to use vim on a machine without your config (another reason to get comfortable with the defaults).

Note that this still doesn't solve the issue raised above: c0w is not the same is c^ in normal mode! You'll just end up with a w sitting at in the first column of the line.

I am not arguing that remaps are bad - I have many of them in the ~900 lines of my .vimrc (although nearly all of them prefixed by the <LEARDER> key) - I'm saying it's good to carefully consider and research whether a given remap is 'covering up' vim's default capabilities.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.