3

There may be any number of nested vertical and horizontal splits on a Vim screen. I'd like to find the (x, y) coords, in terms of columns and lines inside Vim, of the top-left corner of the current window.

It's easy to find the dimensions of the current window (winheight(0) and winwidth(0)), how many windows there are (winnr('$')), as well as all of their widths and heights (winrestcmd()), but this doesn't say enough about the adjacency of windows to each other. All we know is that windows with smaller numbers will generally be towards the top and left of those with larger numbers. Also, I'm not even sure how to find the number of lines and columns of the whole Vim screen (including all of the windows and the command line)...

Right now I'm doing this. It's suitable for me, but it makes the mouse cursor flicker a bit.

funct! CountLinesAboveWindow()
    let lz_setting = &lazyredraw
    set lazyredraw
    let original_nr = winnr()
    let last_nr = original_nr
    let lines_above = 0
    while 1
        wincmd k
        let nr = winnr()
        if nr == last_nr
            break
        endif
        let lines_above = lines_above + winheight(0) + 1
        let last_nr = nr
    endwhile
    exe original_nr . "wincmd w"
    let &lazyredraw = lz_setting
    return lines_above
endfunct!
#And similarly for CountColumnsToTheLeftOfWindow()

Is there a more elegant way? It has to be faster than the above, which excludes :mksession as an option.

The reason I want this is to write functions screenline() and screencol(), analogous to the built-in winline() and wincol().

1
  • I agree that this is a problem because I just wrote a routine that scans up and down (the purpose is to auto-readjust window heights to fit to content if it fits) and profiling shows that wincmd j or k are eating up LOTS of time by actually going and switching the focused window. I simply need to fetch for each window both its dimensions and its offset. (and its buffer line count but that's easy) Without actually physically switching to these windows.
    – Steven Lu
    Apr 2, 2016 at 4:30

1 Answer 1

6

screenrow() and screencol() give you the coordinates relative to the top left corner of the "screen" (i.e. of Vim's window). The manual warns you that something like :echo screencol() will return the column in the command line (i.e. 1). It works better from within a map:

nnoremap <silent> GG :echom screencol()<CR>

Your Answer

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

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