I have previously asked this in StackOverflow (May 2015), but without getting any replies that I was completely happy with.

This ought to be simple: I want to configure Vim to set number whenever the editor is in Ex mode (to get visible line numbers), but never have that option set in visual mode. How?

If the solution involves having to start ex instead of vim, that's fine, but the solution should ideally also cover the case of entering Ex mode from visual mode (using Q in Vim visual mode, for example), and the case where I switch back to visual mode (using :vi in Ex mode).

The closest I've come is the following suggestion (which I would be happy if someone could explain to me, because I don't fully understand it):

let &number = mode(1) ==# 'ce'
nnoremap <silent> Q :set number<CR>Q

This works for turning number on when entering Ex mode, but will leave it activated upon entering Vim visual mode again.

A solution that also works in nvi would be nice, but not necessary.

  • 2
    In an ideal world, you'd need VisualEnter and VisualLeave events as we have InsertEnter and InsertLeave events. At best you could override the key sequences that change the current mode. But there will always be uncaught mode changes. If that's really that important, open an RFC-issue on vim github to ask for such events (You may also want NormalEnter and Leave and so on). Then, writing what you're looking for will be a piece of cake. – Luc Hermitte Jan 17 '17 at 7:23

For Vim.

1) Create a mapping to enter Ex mode and turn on numbers:

nnoremap Q Qset number<CR>

2) Create a function to turn numbering off:

fun! NoNumber()
    set nonumber
    return ''

3) Arrange for numbers to be turned off when in Normal mode. If you use the statusline or ruler, you can add a function there (this is why the above function returns an empty string) since the statusline and ruler aren't updated in Ex mode.

If you've already customised your statusline, you can prepend to it with:

set statusline^=%{NoNumber()}

If you haven't, there are example statusline formats under :h 'statusline'.

Similarly for the ruler:

set rulerformat^=%{NoNumber()}

You will need both if you have set laststatus=1. Adding the function to 'titlestring' might also be an option.

Bear in mind that functions added to the statusline, ruler, or title will be called frequently. I haven't noticed a performance hit in this case, but beware.

A bit of extra information. The mapping for Q issues set number in Ex mode, leaving that text on the screen. If this bothers you, you could enable numbering before entering Ex mode:

nnoremap Q :set number<CR>Q

However you must have 'lazyredraw' set or the screen will be updated before entering Ex mode, firing off NoNumber() from e.g. the statusline, and negating the effect of set number in the mapping.

You're probably out of luck with Nvi.

P.S. I nearly forgot: to have line numbers active if you start Vim in Ex mode, e.g. with vim -E, just add set number to your vimrc.

P.P.S. The question states that numbering should never be on in Normal mode. This is just as well, because with this approach you literally can't turn numbering on without removing the NoNumber function from the statusline, ruler, or title.

  • This works well, thanks! I don't use statusline, but I use the ruler, so I used set rulerformat^=%{NoNumber()} (I'll customise it later). Much appreciated. – Kusalananda Jan 17 '17 at 10:43

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.