1

What I'm looking for is a programmatic way of changing which window Ctrl+w, Ctrl+p will jump to.

The reason why I want to do this is that I have an autocmd like the following

autocmd BufEnter  SpecialWindow call MyFunction()

where

function! MyFunction()
    let current_win_id = win_getid()
    windo ...
    call win_gotoid(current_win_id)
endfunction

therefore, as soon as I jump to the SpecialWindow from AnotherWindow, the meaning of Ctrl+w, Ctrl+p is such that it does not jump to AnotherWindow (desired behavior), but it jumps to the bottom-right window, the last one visited by windo.

If you are interested in why I'm asking this question, please see this.

  • 1
    You mean Ctrl-W Ctrl-P? – B Layer Aug 15 at 8:56
  • @BLayer yes I do. I'll correct it later, or you can do it now – Enrico Aug 15 at 9:30
1

One option is for you to save what the previous window was before the windo command. Then, later, jump to that window before jumping to your target window.

function! MyFunction()
  let previous_win_id = win_getid(winnr('#'))
  let current_win_id = win_getid()
  windo ...
  call win_gotoid(previous_win_id)
  call win_gotoid(current_win_id)
endfunction

A better solution, though, is to use the win_execute() function instead of the windo command. The win_execute() function prevents the side effects of entering a window while executing a command in that window, that includes updating the previous window (and the current window too.)

You need to use an explicit for loop to run the command on every window. You can use gettabinfo() to find the window ids of the windows in the current tab.

function! MyFunction()
  for winid in gettabinfo(tabpagenr())[0]['windows']
    call win_execute(winid, '...')
  endfor
endfunction

If you want to iterate over every window in every tab, you can either use gettabinfo() with no arguments (to get info for all tabs) and two nested for loops (one for the list of tabs, then another one for the windows in that tab. Or you can use getwininfo() directly, which returns information for all windows in all tabs in a flattened list, so you need a single for loop.

If you're simply trying to set a variable or option in the other windows (e.g. disable 'relativenumber'), then you can use setwinvar() for windows in the current tab, or settabwinvar() more generally.

For example, to disable the 'relativenumber' in all windows of all tabs:

function! MyFunction()
  for tabinfo in gettabinfo()
    let tabnr = tabinfo['tabnr']
    for winid in tabinfo['windows']
      call settabwinvar(tabnr, winid, '&relativenumber', 0)
    endfor
  endfor
endfunction
| improve this answer | |
  • 1
    Wow! What a comprehensive answer! I'll get it tomorrow and accept. – Enrico Aug 15 at 17:55
  • 1
    @EnricoMariaDeAngelis Your question was very well formulated and also included the context and motivation, so thank you for that! – filbranden Aug 15 at 18:01
  • Hello, you might be interested in this new question of mine, which I tried to craft accurately. – Enrico Oct 17 at 13:46

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.