How to flip windows in vim? [duplicate] - vim

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
To switch from vertical split to horizontal split fast in Vim
If I have 2 horizontally split windows, how to rotate them to get 2 vertically split windows?
And how to switch buffers?

If you have them split vertically C-wJ to move one to the bottom
If you have them split horizontally C-wL to move one to the right
To rotate in a 'column' or 'row' of split windows, C-wC-r
The following commands can be used to change the window layout. For example,
when there are two vertically split windows, CTRL-W K will change that in
horizontally split windows. CTRL-W H does it the other way around.

Ctrl-w H or type :wincmd H to go from horizontal to vertical layout.
Ctrl-w J or type :wincmd J to go from vertical to horizontal layout.
Ctrl-w r or type :wincmd r to swap the two buffers but keep the window layout the same.
Ctrl-w w or type :wincmd w to move the cursor between the two windows/buffers.
You may wish to bind one or more of these sequences to make it faster to type. I put this in my .vimrc so that ,l moves the cursor to the next buffer in the current tab:
let mapleader = ","
nmap <Leader>l <C-w>w

CTRL-W SHIFT-H will rotate the orientation, CTRL-W H moves to the left window, CTRL-W L moves to the right. See
:help split
and
:help ^w
for more information.

The current answers all work great if you only have two windows open. If you have more than that, the logic for moving windows around can get hairy.
I have this in my .vimrc to allow me to 'yank' and 'delete' a buffer and then paste it into a window over the current buffer or as a [v]split.
fu! PasteWindow(direction) "{{{
if exists("g:yanked_buffer")
if a:direction == 'edit'
let temp_buffer = bufnr('%')
endif
exec a:direction . " +buffer" . g:yanked_buffer
if a:direction == 'edit'
let g:yanked_buffer = temp_buffer
endif
endif
endf "}}}
"yank/paste buffers
:nmap <silent> <leader>wy :let g:yanked_buffer=bufnr('%')<cr>
:nmap <silent> <leader>wd :let g:yanked_buffer=bufnr('%')<cr>:q<cr>
:nmap <silent> <leader>wp :call PasteWindow('edit')<cr>
:nmap <silent> <leader>ws :call PasteWindow('split')<cr>
:nmap <silent> <leader>wv :call PasteWindow('vsplit')<cr>
:nmap <silent> <leader>wt :call PasteWindow('tabnew')<cr>

Related

vim: shortcut to resize split windows

When I have split windows in Vim, I can resize the windows using :resize +1/-1. I wanted to add a shortcut for it that worked like split windows in terminator. In terminator, if I have two windows on top of each other, CTRL Shift Up / Down moves the separator between the two windows, meaning, if I'm in the top window and press CTRL Shift Down, the top window increases. On the other hand, if I'm in the bottom window, CTRL Shift Down decreases the bottom window. So, it truly moves the separator.
With split windows in vim, I tried to remap like this:
:nnoremap <silent> <c-Up> :resize -1<CR>
:nnoremap <silent> <c-Down> :resize +1<CR>
This works fine if I'm on the top window (pressing CTRL UP decreases the size of the window and CTRL Down increases the size). But when I move to the bottom window it behaves correctly but it has a weird effect (CTRL UP also decreases the size of the window). So, I can't simulate moving the separator.
Is it possible o run a command depending on which window I'm located at?
Your code wasn't that wrong just needed a little changes.
Now you can resize all the panes in both horizontal and vertical way:
:nnoremap <silent> <c-Up> :resize -1<CR>
:nnoremap <silent> <c-Down> :resize +1<CR>
:nnoremap <silent> <c-left> :vertical resize -1<CR>
:nnoremap <silent> <c-right> :vertical resize +1<CR>
You can define a function in .vimrc
function! MoveSeparator(PlusMinus)
let num=tabpagewinnr(tabpagenr())
let pm=a:PlusMinus
if num == "2"
let pm = pm == '+' ? '-' : '+'
end
exec "resize " . pm . "1"
endfunction
nnoremap <silent> <C-UP> :call MoveSeparator("-")<CR>
nnoremap <silent> <C-DOWN> :call MoveSeparator("+")<CR>

vimdiff and move among left and right pane

I am using vimdiff for the first time. Online I found written that to move from the left pane you use CTRL + w + Left or right arrow
This does not work for me. But I see that if I press just CTRL + w and press w for a sec and let it go, it switches pane after ~500ms.
Is this how it is supposed to work? Am I doing something wrong?
Ctrl+w and right and left arrow can be used to move between any split windows on vim, not only vimdiff splits.
These keys do work here on cygwin; also, Ctrl+w w also moves to the next window, but without the delay you mentioned.
It is possible that you have mapped these keys in your .vimrc or via some vim plugin. You can check this with :map w, :map <left> and :map <right>.
As moving between windows is something that you use often, you may consider using the following mappings:
nnoremap <C-J> <C-W>j
nnoremap <C-K> <C-W>k
nnoremap <C-H> <C-W>h
nnoremap <C-L> <C-W>l
Then you can use Ctrl+h and Ctrl+l to move left and right, without moving your hands from the home row. And the nnoremap will ensure that these works despite of any other mappings that you may have.
Press Ctrl + W and then (after releasing Ctrl + W) press the arrow keys to change the pane.
It is very useful to use set mouse=a in your .vimrc file. It gives you possibility to switch between windows using mouse. Additionally you can resize windows using it.
If you prefer to use keyboard I have also mapped arrow keys in .vimrc in this way:
map <C-Left> <C-W>j
map <C-Down> <C-W>k
map <C-Up> <C-W>h
map <C-Right> <C-W>l
To move among left and right pane, Press ctrl+w and then ctrl+r. This is both left and right vice-versa.
You can also use :wincmd w for next window, and :wincmd W for previous window.
The :wincmd is especially useful when ctrl+w is captured by the environment. For example see: https://stackoverflow.com/a/73749587/811335

VIM auto resize focused window

I am slowly learning vim and its powerful capabilities.
I have a question in regards to splitting windows (mainly horizontal splits).
Is there a way to automatically resize the currently selected (focused) window? Let's say, for example, a setting so that the focused window will always take up 70% of the screen.
Using Ctrl-w (number) +/- every time is not really efficient, especially when I am jumping between a few files constantly.
Also it would be cool if there was a way to restrict it to only horizontally splitted windows.
The 'winheight' setting determines the minimal number of lines for the current window. Some users set this to 999 for "Rolodex mode". The following sets this to 70%:
:let &winheight = &lines * 7 / 10
For anything fancier, you can hook into the WinEnter event via an :autocmd, and then set the window height to N via :Nwincmd _. Stupid example:
:autocmd WinEnter * execute winnr() * 2 . 'wincmd _'
Sounds like you want golden-ratio : Resize windows automatically using the Golden Ratio.
Once I found out you could disable the "automatic" part of golden-ratio, I started using it myself with these settings:
" Don't resize automatically.
let g:golden_ratio_autocommand = 0
" Mnemonic: - is next to =, but instead of resizing equally, all windows are
" resized to focus on the current.
nmap <C-w>- <Plug>(golden_ratio_resize)
" Fill screen with current window.
nnoremap <C-w>+ <C-w><Bar><C-w>_
I use these mapping for split screens:
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-h> <C-w>h
nnoremap <C-l> <C-w>l
nnoremap c<C-j> :bel sp new<cr>
nnoremap c<C-k> :abo sp new<cr>
nnoremap c<C-h> :lefta vsp new<cr>
nnoremap c<C-l> :rightb vsp new<cr>
nnoremap g<C-j> <C-w>j<C-w>_
nnoremap g<C-k> <C-w>k<C-w>_
nnoremap g<C-h> <C-w>h<C-w>_
nnoremap g<C-l> <C-w>l<C-w>_
nnoremap d<C-j> <C-w>j<C-w>c
nnoremap d<C-k> <C-w>k<C-w>c
nnoremap d<C-h> <C-w>h<C-w>c
nnoremap d<C-l> <C-w>l<C-w>c
This way if you want to jump between splits you can use C-hjkl. If you want to "create" a split you can use cC-hjkl. If you want to maximize a split you can use gC-hjkl. And if you want to delete a split you can use dC-hjkl.
If you want specifically 70% instead of maximized that you could use
nnoremap g<C-j> <C-w>j:let &winheight = &lines * 7 / 10<cr>
for example.

How to swap files between windows in VIM? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
When I work with VIM, I always have multiple windows visible. Sometimes I would like to have an easy way, to swap those windows in places. Is there any Plugin, Macro, etc to make this more easy? BTW, I use MiniBufExplorer.
There are a few useful commands built in which give you a certain amount of control, but it's not comprehensive. The main ones are:
Ctrl-W, r (i.e. hold CTRL, press W, release CTRL, press r) - which rotates the windows (The first window becomes the second one, the second one becomes the third one, etc.)
Ctrl-W, x - swap the current window with the next one
Ctrl-W, Shift-H - move this window to the far left
Ctrl-W, Shift-K - move this window to the top
(and similarly for Ctrl-W, Shift-J and Ctrl-W, Shift-L). See:
:help window-moving
for more information.
I wrote and have been using the following code snippet in my vimrc for
copy-pasting my Vim windows.
This defines for example the following shortcuts:
<c-w>y: "Yanks the window", i.e. stores the number of the buffer in the
current window in a global variable.
<c-w>pp: "Puts the window in Place of the current window", i.e. it reads the
buffer number stored previously and opens that buffer in the current window.
It also stores the number of the buffer that used to be in the current
window.
If by "swapping those windows in places", you mean "opening the buffer in
window A in window B, and vice versa, without changing the position of the
windows", you can use the following keyboard sequence to swap the windows:
Select window A (either with mouse or with keyboard commands)
Press <c-w>y (yanking the buffer number)
Select window B
Press <c-w>pp (pasting the buffer)
Select window A
Press <c-w>pp (pasting the buffer again)
It works only in Vim >= 7.0.
if version >= 700
function! HOpen(dir,what_to_open)
let [type,name] = a:what_to_open
if a:dir=='left' || a:dir=='right'
vsplit
elseif a:dir=='up' || a:dir=='down'
split
end
if a:dir=='down' || a:dir=='right'
exec "normal! \<c-w>\<c-w>"
end
if type=='buffer'
exec 'buffer '.name
else
exec 'edit '.name
end
endfunction
function! HYankWindow()
let g:window = winnr()
let g:buffer = bufnr('%')
let g:bufhidden = &bufhidden
endfunction
function! HDeleteWindow()
call HYankWindow()
set bufhidden=hide
close
endfunction
function! HPasteWindow(direction)
let old_buffer = bufnr('%')
call HOpen(a:direction,['buffer',g:buffer])
let g:buffer = old_buffer
let &bufhidden = g:bufhidden
endfunction
noremap <c-w>d :call HDeleteWindow()<cr>
noremap <c-w>y :call HYankWindow()<cr>
noremap <c-w>p<up> :call HPasteWindow('up')<cr>
noremap <c-w>p<down> :call HPasteWindow('down')<cr>
noremap <c-w>p<left> :call HPasteWindow('left')<cr>
noremap <c-w>p<right> :call HPasteWindow('right')<cr>
noremap <c-w>pk :call HPasteWindow('up')<cr>
noremap <c-w>pj :call HPasteWindow('down')<cr>
noremap <c-w>ph :call HPasteWindow('left')<cr>
noremap <c-w>pl :call HPasteWindow('right')<cr>
noremap <c-w>pp :call HPasteWindow('here')<cr>
noremap <c-w>P :call HPasteWindow('here')<cr>
endif
In my opinion, http://vimcasts.org/episodes/working-with-windows/ has the perfect answer for this question. In brief:
ctrl-w w cycle between the open windows
ctrl-w h focus the window to the left
ctrl-w j focus the window to the down
ctrl-w k focus the window to the up
ctrl-w l focus the window to the right
ctrl-w r rotate all windows
ctrl-w x exchange current window with its neighbour
ctrl-w H move current window to far left
ctrl-w J move current window to bottom
ctrl-w K move current window to top
ctrl-w L move current window to far right
I asked a similar question around the same time: I wanted a way to swap windows specifically without altering an arbitrarily complicated layout. I ended up making a vim plugin out of one of the solutions that was suggested. It's called WindowSwap.vim; install it with your preferred vim plugin manager and give it a whirl.
With WindowSwap.vim, you'd simply
<Leader>yw to yank a window.
Move your cursor to another window.
<Leader>pw to paste that window, swapping it with the position of
the first one.
The key combinations are of course configurable to your preferences.
As <c-w>r or <c-w>x has a restriction that you can't rotate or exchange windows When vertical and horizontal window splits are mixed. And <c-w>H may make the window layout change beyond your expectation especially when you have many windows.
So you may do some work to satisfy your particular needs of window/buffer switching. Here is am example to switching the current window with the top left window(typically I make it vertically maximized):
function! SwitchMainWindow()
let l:current_buf = winbufnr(0)
exe "buffer" . winbufnr(1)
1wincmd w
exe "buffer" . l:current_buf
endfunction
nnoremap <c-w><c-e> :call SwitchMainWindow()<cr>

To switch from vertical split to horizontal split fast in Vim

How can you switch your current windows from horizontal split to vertical split and vice versa in Vim?
I did that a moment ago by accident but I cannot find the key again.
Vim mailing list says (re-formatted for better readability):
To change two vertically split
windows to horizonally split
Ctrl-w t Ctrl-w K
Horizontally to vertically:
Ctrl-w t Ctrl-w H
Explanations:
Ctrl-w t makes the first (topleft) window current
Ctrl-w K moves the current window to full-width at the very top
Ctrl-w H moves the current window to full-height at far left
Note that the t is lowercase, and the K and H are uppercase.
Also, with only two windows, it seems like you can drop the Ctrl-w t part because if you're already in one of only two windows, what's the point of making it current?
Ctrl-w followed by H, J, K or L (capital) will move the current window to the far left, bottom, top or right respectively like normal cursor navigation.
The lower case equivalents move focus instead of moving the window.
When you have two or more windows open horizontally or vertically and want to switch them all to the other orientation, you can use the following:
(switch to horizontal)
:windo wincmd K
(switch to vertical)
:windo wincmd H
It's effectively going to each window individually and using ^WK or ^WH.
The following ex commands will (re-)split any number of windows:
To split vertically (e.g. make vertical dividers between windows), type :vertical ball
To split horizontally, type :ball
If there are hidden buffers, issuing these commands will also make the hidden buffers visible.
In VIM, take a look at the following to see different alternatives for what you might have done:
:help opening-window
For instance:
Ctrl-W s
Ctrl-W o
Ctrl-W v
Ctrl-W o
Ctrl-W s
...
Horizontal to vertical split
Ctrl+W for window command,
followed by Shift+H or Shift+L
Vertical to horizontal split
Ctrl+W for window command,
followed by Shift+K or Shift+J
Both solutions apply when only two windows exist.
After issuing the window command Ctrl+W, one is basically moving the window in the direction indicated by Shift+direction letter.
Opening help in a vertical split by default
Add both of these lines to .vimrc:
cabbrev help vert help
cabbrev h vert h
cabbrev stands for command abbreviation.
:vert[ical] {cmd} always executes the cmd in a vertically split window.
Inspired by Steve answer, I wrote simple function that toggles between vertical and horizontal splits for all windows in current tab. You can bind it to mapping like in the last line below.
function! ToggleWindowHorizontalVerticalSplit()
if !exists('t:splitType')
let t:splitType = 'vertical'
endif
if t:splitType == 'vertical' " is vertical switch to horizontal
windo wincmd K
let t:splitType = 'horizontal'
else " is horizontal switch to vertical
windo wincmd H
let t:splitType = 'vertical'
endif
endfunction
nnoremap <silent> <leader>wt :call ToggleWindowHorizontalVerticalSplit()<cr>
Following Mark Rushakoff's tip above, here is my mapping:
" vertical to horizontal ( | -> -- )
noremap <c-w>- <c-w>t<c-w>K
" horizontal to vertical ( -- -> | )
noremap <c-w>\| <c-w>t<c-w>H
noremap <c-w>\ <c-w>t<c-w>H
noremap <c-w>/ <c-w>t<c-w>H
Edit: use Ctrl-w r to swap two windows if they are not in the good order.

Resources