1

I use the following mappings to toggle relative numbers in visual mode:

nnoremap <silent> v v:<c-u>set nonu rnu<cr>gv
nnoremap <silent> V V0:<c-u>set nonu rnu<cr>gv
nnoremap <silent> <c-v> <c-v>:<c-u>set nonu rnu<cr>gv
vnoremap <esc> <esc>:set nornu nu<cr>

I would like to use the same mappings, but add a conditional check before performing the operation to exclude certain buffers types from this behavior.

I tried adding this to a function but was not successful.

Does anyone know how I can achieve this?

3
  • 1
    Perhaps you could edit to show what you tried? Then we can point out the missing ideas – D. Ben Knoble Dec 13 '20 at 19:37
  • @D.BenKnoble I'm not sure how helpful it would be. I just wrapped set nonu rnu<cr>gv into a function and tried calling it. What's the problem you're having with understanding the question? – Nathan Dec 13 '20 at 20:04
  • 3
    I’m not misunderstanding it, per se, but it’s often easier to say “well X doesn’t work because A and B, do Y instead” then to say “do you want Z?” In this case, you need to learn the difference between the right-hand-side of map commands (happen in the mode of the mapping) and functions (always Ex commands)—but I didn’t know that’s the issue until I saw your function body – D. Ben Knoble Dec 13 '20 at 20:12
2

Function bodies are pure Ex, so you need (e.g.)

normal! v
set nonumber norelativenumber
normal! gv

Though note that between :normal! v and :normal! gv, the commands aren’t like the mapping where you are literally typing : and then have to delete the range <C-u> etc.

Simpler here would just be

set nonumber norelativenumber
normal! v

However, this may not leave you in visual mode! :normal! works better with complete commands.

As a solution, you could try and expr mapping and

return 'v'

Or just insert the function call between v and gv with :<C-u>call MyFunction()<CR>.

4
  • Thanks @D.BenKnoble. I'll give it a shot and will report back. Much appreciated. – Nathan Dec 13 '20 at 23:24
  • Works great. I posted my final solution in my original question. Cheers! – Nathan Dec 15 '20 at 0:29
  • @Nathan I think it would be more appropriate if you posted that as an answer, rather than an edit of your question. There's a small drawback in the way you've implemented it, in that V and Ctrl-V will now trigger characterwise visual mode rather than linewise/blockwise... Perhaps leave the normal! v out of the function and run that in the mappings after the toggle command has been executed? – filbranden Dec 15 '20 at 0:31
  • @filbranden sounds good. I just posted it as an answer. Would you mind showing how to run that in the mappings after the toggle command has been executed. I'm not versed enough in vimscript to understand what you mean. – Nathan Dec 15 '20 at 0:34
2

Here's what I put together based on @D.BenKnoble answer (with help from @filbranden):

function! s:relativeLineNumbers()
  if (&filetype != 'coc-explorer')
    set nonu rnu
  endif
endfunction
command RelativeLineNumbers call s:relativeLineNumbers()
nnoremap <silent>v v:<c-u>RelativeLineNumbers<cr>gv
nnoremap <silent>V V0:<c-u>RelativeLineNumbers<cr>gv
nnoremap <silent><c-v> <c-v>:<c-u>RelativeLineNumbers<cr>gv
vnoremap <esc> <c-c>:set nornu nu<cr>

Note: I selected his answer rather than my own however.

4
  • 1
    Try this: nnoremap <silent> V :ToggleRelativeLineNumbers<cr>V and remove the normal! v from the function... – filbranden Dec 15 '20 at 0:56
  • Worked perfectly! Thank you. – Nathan Dec 15 '20 at 1:01
  • 1
    Awesome! Please update your answer with the settings that worked for you. I'll be happy to upvote it once you do! – filbranden Dec 15 '20 at 1:18
  • 1
    Done! Cheers!!! – Nathan Dec 16 '20 at 2:05

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.