2

I know that I can get the first and last visible lines in the current buffer by using line('w0') and line('w$'), but is there a way to do it for other buffers that are visible but not active as well?

For example if I have a split window, left is buffer number 3 (current), and right is buffer number 4. How to get first and last visible lines for buffer 4 without moving the cursor there in vimscript?

3

In Neovim you can't. In Vim it's trivial:

echo line('w0', winid)

Note that you have to provide window ID, not simply buffer ID.

5
  • I was checking he: line() on neovim and there is no extra param indeed...
    – skamsie
    Dec 18 '20 at 12:41
  • 1
    Introduced in 8.1.1967. Similarly, getcurpos() supports an optional winid argument since 8.2.1727.
    – user938271
    Dec 18 '20 at 12:43
  • @Matt do you of any alternatives to line() that would work in neovim as well?
    – skamsie
    Dec 18 '20 at 12:47
  • 1
    @skamsie Neovim still lacks win_execute() and such. So currently the only way is win_gotoid() and back.
    – Matt
    Dec 18 '20 at 12:58
  • @Matt weirdly enough, on Neovim, on line 619 of :he usr_41.txt I can see win_execute() listed, but it does not work when you try to use it.
    – skamsie
    Dec 18 '20 at 13:07
2

Even though the answer from @Matt is the obvious solution for vim, I needed something that will work in neovim as well, so I ended up writing a function that works in both editors.

function! GetVisibleLines()
  let l:visible_w = gettabinfo(tabpagenr())[0]['windows']
  let l:current_w = win_getid()
  let l:visible_l = []

  for w in l:visible_w
    noautocmd call win_gotoid(w)
    call add(
          \ l:visible_l,
          \ {'win': w,
          \  'buf': getwininfo(w)[0]['bufnr'],
          \  'lines': [line('w0'), line('w$')]})
  endfor

  noautocmd call win_gotoid(l:current_w)
  return l:visible_l
endfunction

It returns a list with an item for each visible window for the current tab containing the window id, the buffer and the visible lines (first and last)

Example

:echo GetVisibleLines()
-----------------------

[ 
  {'buf': 4, 'win': 1015, 'lines': [1, 25]},
  {'buf': 4, 'win': 1001, 'lines': [418, 441]},
  {'buf': 2, 'win': 1000, 'lines': [1, 12]}
]
1
  • There is also the option with lua to call vim.api.nvim_win_call(winid, function() return {vim.fn.line('w0'), vim.fn.line('w$')} end)
    – Oliv
    Sep 21 at 12:33

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.