0

Does vim have a way of arranging split windows in a grid pattern? (Preferably, without closing existing splits, and without using a plugin.)

Tmux has some predefined windowpane layouts. For example, ctrl+b alt+1 will divide the window horizonally (i.e., it moves existing splits into a tall, skinny configuration). And ctrl+b alt+2 will divide the window vertically (it moves existing splits into a short, wide configuration).

The one I'm interested in is tmux's ctrl+b alt+5. If you have an even number of splits, it will arrange the splits in a regular grid pattern. (Except for 8 splits, for some reason. But if there are 9 splits, ctrl+b alt+5 produces a 3x3 grid.)

In vim, using various combinations of ctrl+w H, ctrl+w J, ctrl+w K, ctrl+w L, ctrl+w r, and ctrl+w x, I can reproduce the tmux preset layouts, except for tmux ctrl+b alt+5. And I know that I can get the grid layout by closing and re-splitting a window; but I would like to avoid that.

So, to restate my question: Does vim have a way of arranging split windows in a grid pattern? (Preferably, without closing existing splits, and without using a plugin.)

This question from 2015 is basically the same as mine: How can I get my windows back into a grid formation? (I guess I'm wondering if the answer is still "not really").

I am using vim version 8.1, on WSL Ubuntu in Windows Terminal on Windows 10. (I know vim 9 exists, and I will upgrade sooner or later. If the grid layout functionaly exists in version 9, please let me know.)

Thanks for any help.

m_mlvx
  • 109
  • 4

1 Answers1

1

I have created the vim-orpheus plugin to display in the grid all the unsaved buffer at a glance with the command:

:Qall

I have also added the :Grid command to show all the listed buffer at a glance:

enter image description here

If you are only interested by the code of the Grid command here is the code:

let s:height_factor = 3

function! s:getwindowsize(winnr) let ret = winwidth(a:winnr) let ret = ret * winheight(a:winnr) * s:height_factor return ret endfunction

function! s:getlargestwindow() let ret = 0 let largestsize = 0 for winnr in range(1, winnr('$')) let currentsize = s:getwindowsize(winnr) if currentsize > largestsize let ret = winnr let largestsize = currentsize endif endfor return ret endfunction

function! s:addonewindow() let winnr = s:getlargestwindow() execute winnr . 'wincmd w' if winheight(winnr) * s:height_factor > winwidth(winnr) wincmd s else wincmd v endif " wincmd = endfunction

function! s:spreadbuffers(buffers) if len(a:buffers) == 0 return endif if winnr('$') > 1 execute 'b' . a:buffers[1] only endif for i in range(2, len(a:buffers)) call s:addonewindow() endfor let winnr = 0 for bufnr in a:buffers let winnr = winnr + 1 execute winnr . 'wincmd w' execute 'b' . bufnr endfor endfunction

function! s:getlistedbuffers() let buffers = range(1, bufnr('$')) let buffers = filter(buffers, 'bufexists(v:val)') let buffers = filter(buffers, 'getbufinfo(v:val)[0].listed') return buffers endfunction

function! s:spreadlistedbuffers() let buffers = s:getlistedbuffers() call s:spreadbuffers(buffers) 1wincmd w endfunction

" Grid All Listed command! Grid call s:spreadlistedbuffers()

Vivian De Smedt
  • 16,336
  • 3
  • 18
  • 37