Don't center screen when hitting end in vim - vim

With nowrap and when on a long line, hitting the end button takes the cursor to the end of the line (of course). Furthermore, the screen will be centered on the cursor.
It will take the cursor from here:
to here:
How can I make it scroll right only up to "line."? And thus have the last "this is a long line." aligned to the right of the window?
Edit: I already know about sidescroll and sidescrolloff but those only apply when using the arrow keys. It doesn't change behavior for the end key, and thus don't solve my problem.

if you check :h ze
ze Scroll the text horizontally to position the cursor
at the end (right side) of the screen. This only
works when 'wrap' is off. {not in Vi}
so if you create a mapping, map $ or <end> to $ze or <end>ze, it should work as you wish.
hope it helps.
EDIT
if you want to map like what you wanted in INSERT mode:
:set sidescroll=1
:inoremap <End> <Esc><End>zei

Related

VIM: How do I move the cursor to the left of the screen?

I know that 0 moves to the beginning of the line and $ to the end of the line, but I am working with long lines with nowrap set. I want to jump to the left side of the screen.
How would I do that?
While we are at it, how do I jump to the right of the screen?
g0 to move to beginning
g$ to move to end
gm to move to middle
g^ to move to first non-blank character
Further Reading
start from :h g_ for in-built help
vim moving with hjkl in long lines (screen lines)

Vim: Why can't I map to the <j> key?

I saw this key bind in tips.txt:
:map <C-U> <C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y><C-Y>
Which results in smooth scrolling up for CTRL-U. It only moves the viewport though, and I'd like to also move the cursor, so for scrolling down I tried:
:map <C-D> <C-E><j><C-E><j><C-E><j><C-E><j><C-E><j><C-E><j><C-E><j><C-E><j>
Since CTRL-E moves the viewport down and j moved the cursor down. This doesn't work however. When I press CTRL-D the viewport just hops one line down and the terminal beeps.
How do I map CTRL+D to scroll and move the cursor?
You shouldn't have the angled brackets (</>) around j.

move the text after the cursor to a new line

I am Vim newbie, and I'm using MacVim on OSX Snow Leopard. One of the most common actions I have to take is to move the cursor to a new line but also move the text after the cursor to the new line. I know that pressing 'o' in normal or visual mode moves the cursor to a new line and switches the mode to insert.
What I'd like to do is move the cursor to a new line, and move the text after the cursor to that new line as well, preferably staying in the normal mode? Is this possible? How can I accomplish this task?
If the cursor is on a <space> as in ([] marks the cursor):
lorem ipsum[ ]dolor sit amet
the simplest is to do r<CR>, that is "replace the current character with a linebreak".
Otherwise, use #knittl's solution.
So you want to move everything in the current line, which comes after the cursor to the next line? Read: insert a line break??
(move cursor)
i (or a)
<return>
<esc> (or ^C)
To map this sequence of keystrokes to a single key, follow #thb's suggestion and use the :map command:
:map <F2> i<CR><ESC>
:map <F2> i<CR>
This keeps vi in insert mode.
As I answered in this post, How do I insert a linebreak where the cursor is without entering into insert mode in Vim?.
Please try Control + j.
The code below achieves the same behavior as "normal" editors (for the lack of better terms on the top of my mind) except that you'd have to press "enter" twice instead of once.
I also wanted to get rid of the space if it's right before my current character.
There might be an easier way and I totally welcome edits :-)
" in ~/.vimrc or ~/.vimrc.after if you're using janus
nnoremap <cr><cr> :call ReturnToNewLine()<cr>
function ReturnToNewLine()
let previous_char = getline(".")[col(".")-2]
" if there's a space before our current position, get rid of it first
if previous_char == ' '
execute "normal! \<bs>\<esc>"
endif
execute "normal! i\<cr>\<esc>"
endfunction
This remaps pressing enter twice to going to insert mode, placing a carriage return and escaping.
The reason I'm using this mapping (enter twice) is because I was used to this functionality with other text editors by pressing a enter; also, typing enter twice is fast.
Another thing that I found useful in this context was allowing vim to move right after the last character (in case I wanted to move the last character to a new line). So I have the following in my ~/.vimrc as well.
set virtualedit=onemore
Note that I'm using nnoremap (normal mode non-recursive) instead of map (which is VERY dangerous) (check this out for more information on the differences http://learnvimscriptthehardway.stevelosh.com/chapters/05.html)
You need to map some keys to do a line break at the cursor,
I found the following mapping easy to use, just go to your vimrc and add this line:
:map <silent> bl i<CR><ESC>
to assign a line break at cursor to "bl" combo

How to make a shortcut for moving between Vim windows?

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

"Minimizing" vertical VIM window splits

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.

Resources