2

How do you set a window-local option (number) in literally every window/buffer?

I was to bind <leader>t to toggle the number option in every buffer, using a global variable g:linum_status as the source of truth for whether line numbers should be active or not.

Basically, I'm trying to figure out how to make number act like a global option, even though it's window-local.

I have the following options set initially

let g:linum_status = 0
set nonumber

and had the following (broken) function ToggleLinum

function! ToggleLinum()
  if g:linum_status
    bufdo execute "set nonumber"
    let g:linum_status = 0
  else
    bufdo execute "set number"
    let g:linum_status = 1
  endif
endfunction

This function, however, only toggles the number option in the current buffer.

I tried switching bufdo to windo, which is a little better. Now all of the windows in the focused tab switch, which is actually fairly intuitive.

Still though, is there a way to make flip number on or off for "every" buffer, possibly exempting things like netrw file exploring buffers.

1 Answer 1

2

You could try the following code:

nnoremap <silent> <leader>t :<c-u>call ToggleLinum()<cr>

function! ToggleLinum() abort
    let orig_win = win_getid()
    let ft_to_ignore = ['netrw']
    if &l:number
        tabdo windo if index(ft_to_ignore, &ft) < 0 | setl nonumber | endif
    else
        tabdo windo if index(ft_to_ignore, &ft) < 0 | setl number | endif
    endif
    call win_gotoid(orig_win)
endfunction

It uses :tabdo to iterate over the tab pages, and :windo to iterate over the windows in each of them.

If, in addition to netrw, you wanted to ignore other filetypes, you could add them to the list ft_to_ignore. For example, to also ignore quickfix windows:

let ft_to_ignore = ['netrw', 'qf']

The function decides whether it should enable or disable 'number' in all windows based on the value of this option in the current window (&l:number).

Since :tabdo and :windo will change the focused window (it will become the last window in the last tab page) you can use win_getid() to save the unique ID of the original window, and win_gotoid() to get back to it, once the function has finished toggling 'number' everywhere.


You can nest windo inside tabdo? What kind of thing are they syntactically?

Honestly, I don't know what is the correct term for these keywords. But I can try to help you understand why it makes sense to nest them. From :h :tabdo:

It works like doing this:
        :tabfirst
        :{cmd}
        :tabnext
        :{cmd}
        etc.

Then, from :h :windo:

It works like doing this:
        CTRL-W t
        :{cmd}
        CTRL-W w
        :{cmd}
        etc.

In the first snippet of code, the one given in :h :tabdo, replace {cmd} with the 2nd snippet of code (increasing the level of indentation to better see the 2 different levels of nesting); it should give you the following pseudo-code, which still looks valid:

:tabfirst
    CTRL-W t
    :{cmd}
    CTRL-W w
    :{cmd}
    etc.
:tabnext
    CTRL-W t
    :{cmd}
    CTRL-W w
    :{cmd}
    etc.
etc.

FWIW, the way I see tabdo and windo, is like tab triggers in UltiSnips. That is, they are expanded into snippets of code. In the help, {cmd} is a placeholder which, in the snippet, will be replaced with the command (or here another snippet) you pass to :tabdo/:windo as an argument.

1
  • Wow. You can nest windo inside tabdo? What kind of thing are they syntactically? Commented Nov 25, 2017 at 20:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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