I have vsplit two windows and make them same width.
Now I want to decrease the left window by five characters and increase the right window by five characters,when the cursor is in the left window, how to input command in normal mode or ex mode?
In general Ctrl-W commands do it.
Specifically here N Ctrl-W < shrinks the current window by one (or N if specified) column and N Ctrl-W > extends by one column (or N if specified).
Type :help window-resize for all related commands.
There are ways to do this in normal and ex-mode.
Let us just show you for your example.
In normal mode: 5followed by Ctrl + w at the same time, this should be finalized by <.
For better experience, you might like to map it to some key,
nnoremap <F5> <c-w><
This will allow you to press F5 again and again to decrease the size and stop at desired size.
In ex mode: You can use :vertical res N, where N is a absolute number. More details at :h window-resize
Related
I can map 'jj' to
imap jj <Esc>
and I can even map letters to tab navigation
map tj :tabprevious<CR>
map tk :tabnext<CR>
But I can't map g to page up (even though spacebar acts as page down)
map <Space> <PageDown>
map g <PageUp>
According to this "When you try to map multiple key sequences, you won't be able to start them with lower or upper case letters ("Too dangerous to map that"), but the punctuation and control characters are fair game." Can anyone confirm this?
If so, how does one assign a function to an unmapped key like 'g'
This isn't answering your question, but I thought it may be helpful to the problem you are having with your RSI. It maps the spacebar to toggle between fast and slow move modes. Normally pressing j or k will scroll down one line. Pressing space will turn on fast move mode, where pressing j or k will scroll down/up 10 lines. Press space again to go back to normal. This will only work in vim, not just plain vi (most "vi" programs are just symlinks to vim anyway though).
It works in both normal and visual edit modes.
To use it, put this code somewhere in your ~/.vimrc file:
map <Space> :call ToggleFastMoveMode()<CR>
vmap <Space> :call ToggleFastMoveMode()<CR>gv
let g:fastMoveMode = 0
function! ToggleFastMoveMode()
let g:fastMoveMode = 1 - g:fastMoveMode
if (g:fastMoveMode == 0)
noremap j j
vnoremap j j
noremap k k
vnoremap k k
else
noremap j 10j
vnoremap j 10j
noremap k 10k
vnoremap k 10k
endif
endfunction
(Edit - original answer suggested native Ctrl-f and Ctrl-b, but answer was updated as the goal here is to avoid using Ctrl and Shift)
A few points to add
Leaving the issue of choosing the right character to you, assuming we chose X for now.
I can think of two reasons why map X <PageUp> isn't working for you.
Your version of vi may not support PageUp/PageDown. If this is the issue then try instead to map to vi's page jumping (B for back, accompanied by for forward) eg. map X <C-b>.
Another other option is that it doesn't work 'as expected'. In vi PageUp/PageDown act on the 'viewport' not the cursor. So if you'r looking at the top of the file, but the cursor is not at the top or won't do anything. PageDown won't 'work' if your cursor is two lines from the bottom either.
To address this you could combine the 'move viewport up' <C-b> and the 'move cursor to the top of viewport' H eg. map X <C-b>H (The opposite being map X <C-f>L). Or specifying the number of lines to jump yourself map X 30k (Op. map X 30j).
Then the issue of choosing the right character to overwrite. Vi has a lot of native commands, so many in fact that only a handful of characters don't do something natively.
So if your goal is to avoid RSI, then of course overwrite something. But make sure to overwrite something that isn't too useful for you personally.
Natively:
f searches for a given symbol on the line you are currnetly on (can be very useful, but not critical I guess)
g on it's own does nothing, but gg moves cursor to top of file. Choosing g may cause issus as vim (not the original vi) will interpret two quick keypresses as go to top of file instead of do two PageUp's.
Let’s say I have single Vim tab displaying 9 buffers (equally separated, like a 3×3 table).
Currently, to get from the top left window to the bottom right one, I have to press 3, Ctrl+W, J, and then 3, Ctrl+W, L. This is cumbersome, and I would like to just be able to press Ctrl+9 to go to the 9th window, and Ctrl+3 to go to the 3rd window, etc.
Is there any easy way I can map something like this in Vim?
There's a much simpler solution than using the mouse or hard-set movement mappings; they will break if the window numberings are different from what you have in mind for a 3x3 matrix, or if you decide to work with less than 9 windows. Here's how:
Include the following in your .vimrc:
let i = 1
while i <= 9
execute 'nnoremap <Leader>' . i . ' :' . i . 'wincmd w<CR>'
let i = i + 1
endwhile
Now you can just press <Leader><number> and be taken to the window number you want. I wouldn't recommend going beyond 9, because IMO, the utility of having multiple viewports follows a Rayleigh distribution and quickly becomes useless with too many viewports in one window.
It will be helpful if you have the window number displayed in your statusline to aid you in quickly figuring out which window you're on and which window you want to go to. To do that, use this little function and add it accordingly in your statusline.
function! WindowNumber()
let str=tabpagewinnr(tabpagenr())
return str
endfunction
See it in action in your statusline:
set laststatus=2
set statusline=win:%{WindowNumber()}
Note that the above line will replace your statusline. It was just meant for illustration purposes, to show how to call the function. You should place it where ever you think is appropriate in your statusline. Here's what mine looks like:
Update
romainl asked for my status line in the comments, so here it is:
"statusline
hi StatusLine term=bold cterm=bold ctermfg=White ctermbg=235
hi StatusHostname term=bold cterm=bold ctermfg=107 ctermbg=235 guifg=#799d6a
hi StatusGitBranch term=bold cterm=bold ctermfg=215 ctermbg=235 guifg=#ffb964
function! MyGitBranchStyle()
let branch = GitBranch()
if branch == ''
let branchStyle = ''
else
let branchStyle = 'git:' . branch
end
return branchStyle
endfunction
function! WindowNumber()
let str=tabpagewinnr(tabpagenr())
return str
endfunction
set laststatus=2
set statusline=%#StatusLine#%F%h%m%r\ %h%w%y\ col:%c\ lin:%l\,%L\ buf:%n\ win:%{WindowNumber()}\ reg:%{v:register}\ %#StatusGitBranch#%{MyGitBranchStyle()}\ \%=%#StatusLine#%{strftime(\"%d/%m/%Y-%H:%M\")}\ %#StatusHostname#%{hostname()}
The last line should be a single line (be careful if your setup automatically breaks it into multiple lines). I know there are ways to keep it organized with incremental string joins in each step, but I'm too lazy to change it. :) The GitBranch() function (with other git capabilities) is provided by the git.vim plugin. There's a bug in it as noted here and I use the fork with the bug fix. However, I'm leaving both links and the blog here to give credit to all.
Also, note that I use a dark background, so you might have to change the colours around a bit if you are using a light scheme (and also to suit your tastes).
Better, more general answer:
Use countCtrl+wCtrl+w to jump to the count window below/right of the current one.
For example, if you're in the top left of a 3x3 grid and want to jump to the bottom left you'd use 7Ctrl+wCtrl+w.
Specific 3x3 grid answer:
If you're always using a 3x3 layout you could try these mappings for the numpad, which always jump to the top left and then move the appropriate amount from there, with the key's position on the keypad jumping to the window's with 'equivalent' position on the screen:
noremap <k7> 1<c-w><c-w>
noremap <k8> 2<c-w><c-w>
noremap <k9> 3<c-w><c-w>
noremap <k4> 4<c-w><c-w>
noremap <k5> 5<c-w><c-w>
noremap <k6> 6<c-w><c-w>
noremap <k1> 7<c-w><c-w>
noremap <k2> 8<c-w><c-w>
noremap <k3> <c-w>b
Edited: turns out c-w c-w goes to the top left at the start automatically. The explicit 1 is required in the first mapping, as c-w c-w without a count toggles between the current and the previously selected window.
(The Ctrl-W t mapping always goes to the top-left most window, the Ctrl-W b mapping always goes to the bottom-rightmost).
Alternatively you could map each number to jump to the Nth window, so k6 would be 6 c-w c-w, rather than trying to lay out the keys as on screen.
I prefer use standard vim keys(jkhl).
noremap <C-J> <C-W>w
noremap <C-K> <C-W>W
noremap <C-L> <C-W>l
noremap <C-H> <C-W>h
There is a trick if you notice that the first two maps can jump clock wise or the reverse, rather than just jumping up or down.
And you can also switch to any window directly with <Number><C-J>, for example, 2<C-J> will go to the 2nd window.
Not exactly what you're looking for, but if you're using a terminal that supports it, you can set the following options:
:set mouse+=a
:set ttymouse=xterm2
and click on a buffer to switch to it. Yes, with the mouse.
A bunch of other mouse behavior works too - you can click to move the insertion point, drag to select text or resize splits, and use the scroll wheel.
Ermmm... I'm pretty sure that this will not keep window layout as it is, but I use
:buf sys
to go to system.h,
:buf Sing
to go to MyLargeNamedClassSingleton.cpp
buf will do autocomplete (possibly menucompletion if so configured) so you can do
:buf part<Tab>
to list what files could match the part you typed. Beats the crap out of navigating buffers all around.
But I understand, this doesn't answer your specific question of course :)
I like to move around with the arrow keys.
I map ctr+direction to move to the next window partition in that direction.
map <C-UP> <C-W><C-UP>
map <C-DOWN> <C-W><C-DOWN>
map <C-LEFT> <C-W><C-LEFT>
map <C-RIGHT> <C-W><C-RIGHT>
You cant jump directly from one window to another but I find that it makes it very easy to move between windows
I recently discovered Ctrl+E and Ctrl+Y shortcuts for Vim that respectively move the screen up and down with a one line step, without moving the cursor.
Do you know any command that leaves the cursor where it is but moves the screen so that the line which has the cursor becomes the first line? (having a command for the last line would be a nice bonus).
I can achieve this by manually pressing Ctrl+E (or Ctrl+Y) the proper number of times, but having a command that somehow does this directly would be nice.
Any ideas?
zz - move current line to the middle
of the screen
(Careful with zz, if you happen to have Caps Lock on accidentally, you will save and exit vim!)
zt - move current line
to the top of the screen
zb - move
current line to the bottom of the
screen
Additionally:
Ctrl-y Moves screen up one line
Ctrl-e Moves screen down one line
Ctrl-u Moves cursor & screen up ½ page
Ctrl-d Moves cursor & screen down ½ page
Ctrl-b Moves screen up one page, cursor to last line
Ctrl-f Moves screen down one page, cursor to first line
Ctrl-y and Ctrl-e only change the cursor position if it would be moved off screen.
Courtesy of www.lagmonster.org/docs/vi2.html
Vim requires the cursor to be in the current screen at all times, however, you could bookmark the current position scroll around and then return to where you were.
mg # This book marks the current position as g (this can be any letter)
<scroll around>
`g # return to g
I'm surprised no one is using the Scrolloff option which keeps the cursor in the middle of the page.
Try it with:
:set so=999
It's the first recommended method on the Vim wiki and works well.
I've used these shortcuts in the past (note: separate key strokes i.e. tap z, let go, tap the subsequent key):
z t ...or... z enter --> moves current line to top of screen
z z ...or... z . --> moves current line to center of screen
z b ...or... z - --> moves current line to bottom
If it's not obvious:
enter means the Return or Enter key.
. means the DOT or "full stop" key (.).
- means the HYPHEN key (-)
For what it's worth, z. avoids the danger of saving and closing Vi by accidentally typing ZZ if the caps-lock is on.
More info: :help scroll-cursor
Here's my solution in vimrc:
"keep cursor in the middle all the time :)
nnoremap k kzz
nnoremap j jzz
nnoremap p pzz
nnoremap P Pzz
nnoremap G Gzz
nnoremap x xzz
inoremap <ESC> <ESC>zz
nnoremap <ENTER> <ENTER>zz
inoremap <ENTER> <ENTER><ESC>zzi
nnoremap o o<ESC>zza
nnoremap O O<ESC>zza
nnoremap a a<ESC>zza
So that the cursor will stay in the middle of the screen, and the screen will move up or down.
To leave the cursor in the same column when you use Ctrl+D, Ctrl+F, Ctrl+B, Ctrl+U, G, H, M, L, gg
you should define the following option:
:set nostartofline
my mnemonic for scrolling...
Adding to other answers also pay attention to ze and zs, meaning: move screen to the left/right of the cursor (without moving the cursor)
+-------------------------------+
^ |
|c-e (keep cursor) |
|H(igh) zt (top) |
| ^ |
| ze | zs |
|M(iddle) zh/zH <--zz--> zl/zL |
| | |
| v |
|L(ow) zb (bottom) |
|c-y (keep cursor) |
v |
+-------------------------------+
also look at the position of h and l and t and b and (with qwertz keyboard) c-e and c-y (also the "y" somehow points to the bottom) on the keyboard to remember where the screen is moving.
Enter vim and type:
:help z
z is the vim command for redraw, so it will redraw the file relative to where you position the cursor. The options you have are as follows:
z+ - Redraws the file with the cursor at top of the window and at first non-blank character of your line.
z- - Redraws the file with the cursor at bottom of the window and at first non-blank character of your line.
z. - Redraws the file with the cursor at centre of the window and at first non-blank character of your line.
zt - Redraws file with the cursor at top of the window.
zb - Redraws file with the cursor at bottom of the window.
zz - Redraws file with the cursor at centre of the window.
You can prefix your cursor move commands with a number and that will repeat that command that many times
10Ctrl+E will do Ctrl+E 10 times instead of one.
zEnter does exactly what this question asks for.
It works where strangely zz would not work (vim 7.4.1689 on Ubuntu 2016.04 LTS with no special .vimrc)
You may find answers to "Scrolling Vim relative to cursor, custom mapping" useful.
You can use ScrollToPercent(0) from that question to do this.
Sometimes it is useful to scroll the text with the K and J keys, so I have this "scroll mode" function in my .vimrc (also bound to zs).
See scroll_mode.vim.
I wrote a plugin which enables me to navigate the file without moving the cursor position. It's based on folding the lines between your position and your target position and then jumping over the fold, or abort it and don't move at all.
It's also easy to fast-switch between the cursor on the first line, the last line and cursor in the middle by just clicking j, k or l when you are in the mode of the plugin.
I guess it would be a good fit here.
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.
I use horizontal and vertical window splits in religiously in VIM and up until recently, I enjoyed the comfort of two commands to effectively hide (or minimize) my horizontal splits. I set them up adding the following lines to my .vimrc file:
set winminheight=0
map <C-J> <C-W>j<C-W>_
map <C-K> <C-W>k<C-W>_
Hitting Control-j or Control-k navigates through horizontal splits by going up or down. What I'd like to accomplish is the same thing for vertical splits by showing or hiding the left or right split using Control-Shift-h and Control-Shift-l; h moving to the left, l moving to the right. I have tried the following with little to no success:
set winminwidth=0
map <S-C-L> 500<C-W>h<C-W>_
map <S-C-H> 500<C-W>l<C-W>_
The action would be similar to utilizing Control-w-< and Control-w->, only moving the vertical split completely to the left or write, not just one line at a time.
Any ideas on how to accomplish this? Thanks.
First up, you won't be able to use <S-C- (shift + control) in your code (see below). But you can use the 'mapleader' as your "shift" and then use the <C-h> and <C-l> like you want to. Like this:
set winminwidth=0
nmap <Leader><C-h> <C-W>h500<C-W>>
nmap <Leader><C-l> <C-W>l500<C-W>>
The common leader keys in vim are comma and back-slash:
:let mapleader = ","
But you'll find that this gets annoying to require 3 keystrokes for this, so you might as well just drop the control key stroke. This way (if your leader is comma) you can just press ",h" and ",l" to go to the splits to your left and right:
set winminwidth=0
nmap <Leader>h <C-W>h500<C-W>>
nmap <Leader>l <C-W>l500<C-W>>
" (FTW) :D
...
A guy named Tony Chapman answers why you can't use control + shift:
Vim maps its Ctrl+printable_key
combinations according to ASCII. This
means that "Ctrl+lowercase letter" is
the same as the corresponding
"Ctrl+uppercase letter" and that
Ctrl+<key> (where <key> is a printable
key) is only defined when <key> is in
the range 0x40-0x5F, a lowercase
letter, or a question mark. It also
means that Ctrl-[ is the same as Esc,
Ctrl-M is the same as Enter, Ctrl-I is
the same as Tab.
So yes, Ctrl-s and Ctrl-S (i.e. Ctrl-s
and Ctrl-Shift-s) are the same to
Vim. This is by design and is not
going to change.
Try
set winminwidth=0
map <S-C-L> <C-W>h<C-W>|
map <S-C-H> <C-W>l<C-W>|
This doesn't move a window completely to the left or right (that's <C-W>H and <C-W>L), it just moves the cursor to the left (or right) window and maximizes that window horizontally.
See :help CTRL-W_bar for more.
Crl-w 1 |
will minimize current window in Vim.