2

I use the keybinding Ctrl+W >/< to increase/decrease width of the split window, and that works just fine when the split window is in the left.

However when I switch to any split beside the one on the far left, I don't feel like this specific movement is natural because now the key binding Ctrl+W > starts to increase the current split window and vice versa .

Is there any way to make Ctrl+W >/< consistent, i.e., always increase / decrease the width of the current split irrespective of its position?

A more accurate query is a way that makes Ctrl+W >/< move the split window's vertical line right (>) or left (<) with relation to decrease / increase in width of the current split ?

D. Ben Knoble
  • 26,070
  • 3
  • 29
  • 65
xquilt
  • 81
  • 7

2 Answers2

1

Consider the following layout. If you are in window 2, what should ctrl-w > do? It's ambiguous regardless of whether you think > should widen the window, or move the split bar.

vim takes the following definitions: 1) > always increases the width of a window- makes it greater (>). 2) The right split is always moved unless it's impossible, in which case the left split is moved.

----------------
|    |    |    |
|  1 |  2 |  3 |
|    |    |    |
----------------

It seems that (besides the apparent reversion of < and >) the most confusing case is around the latter portion of (2), where > moves the left split to the left.

We can use the following map to handle this special case (based on Maxim Kim's suggestion).

func! Resize(dir, count) abort
    let l:dir = a:dir
    if winnr('l') == winnr()
        let l:dir = !l:dir
    endif
    execute 'vert resize' (l:dir ? '+' : '-') . a:count
endfunc
nnoremap <c-w>> :<c-u>call Resize(1, v:count1)<cr>
nnoremap <c-w>< :<c-u>call Resize(0, v:count1)<cr>
Mass
  • 14,080
  • 1
  • 22
  • 47
0

Just a note about consistency: current behavior is consistent, increase or decrease window size. For the leftmost/rightmost windows though it is impossible to decrease/increase to the left/right due to natural constraints (terminal window/gui window) thus it does it eating space of other splits.

So back to your request, what you can do is to analyze output of winlayout function and decide what to do with the split depending on current window position.

It wouldn't be that simple, so here is the simplified example that would "work" only for a simple layout (all windows are vertically split):

func! Resize(dir, count) abort
    if winnr('$') == 1 | return | endif
    let dir = a:dir
    if winnr() == winnr('$')
        let dir = !dir
    endif
    let cmd_dir = dir ? '+' : '-'
    exe "vert resize ". cmd_dir . a:count
endfunc
nnoremap <C-w>> :<C-u>call Resize(1, v:count1)<CR>
nnoremap <C-w>< :<C-u>call Resize(0, v:count1)<CR>
Maxim Kim
  • 13,376
  • 2
  • 18
  • 46
  • I included it right now and it worked just fine , but turned out that actual behavior i needed was the vertical line movement with relation to the size . i edited the question and hopefully its unambiguous this time – xquilt Sep 26 '21 at 18:16
  • it wouldn't be that simple. First you should define behavior of the mappings for various split windows in many different layouts (for example: vert, hor, vert, vert, hor, vert, hor, hor...) and only after that you could script it analyzing where current window is splitted in, using output of winlayout func... – Maxim Kim Sep 26 '21 at 18:24
  • yes ,that seems quite convoluted . however the current binding is the closest one to the desired behavior – xquilt Sep 26 '21 at 18:31
  • @polendina for a simple layout, check updated version. You can try to enhance it with better analysis where your current window is and what to do then. – Maxim Kim Sep 26 '21 at 18:33
  • how is the first proposal different from the default behavior? – Mass Sep 26 '21 at 18:33
  • @Mass it is the same, indeed. – Maxim Kim Sep 26 '21 at 18:34
  • @Mass the proposal itself was ambiguous and couldn't describe the actual needs to achieve the behavior , i intuitively felt that i need to move the left number line/left border of each split with the > to move the left border right / and < for the left border of the split to move left – xquilt Sep 26 '21 at 18:39
  • @MaximKim for a layout with just vertical splits , the function works if there are two splits . however if there are a third one in the middle ,then the left border of the third split is the one that moves – xquilt Sep 26 '21 at 18:48
  • @polendina Then you should probably clearly define everything in your question, given the layout if I am in this split and press this map, I want this. And that is for all edge cases. Hopefully then somebody would be able to help you. – Maxim Kim Sep 26 '21 at 18:53