663

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?

Jawa
  • 2,312
  • 6
  • 33
  • 36
ereOn
  • 48,328
  • 33
  • 147
  • 228

14 Answers14

971
  • 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
Eduardo Cuomo
  • 13,985
  • 3
  • 93
  • 80
Kevin Vaughan
  • 12,450
  • 4
  • 25
  • 21
  • 16
    @HappyGreenKidNaps Map that caps lock key to control ASAP! – Aaron May 19 '17 at 19:39
  • I'm pretty attached to my caps lock, especially dealing with a lot of C macros, but you have other options. First, find an unmapped key (check both cases for letters; try adding a modifier or leader, using a symbol or function key, etc.) and map it to the case sensitive 'risky' combination. Second, configure vimundo to your liking so you can recover from an oops. (Non-portable hacks incoming:) Third, do the same but from your user keyboard config, e.g. Windows key + Z; for maps to sequences, try `xdotool` or `triggerhappy`. Finally, display your caps lock state (can't be done in Vimscript.)... – John P Aug 09 '17 at 22:19
  • 2
    Querying your caps lock state is very environment-dependent. I have heard that it can't be done in Vimscript, and at this point I've accepted it. If you want to go down that road, there's `xev -q`, `cat /proc/bus/input/devices` to find the device to query and `evtest` or `thd ... --dump /dev/input/event` to check the state, etc. If you absolutely must make a system-wide remapping, at least swap two locks like caps num - but the issue is more forgetting that it's on, because if you wanted it before, you'll keep using it, by whatever map. Risk breaking Vim before files/user/system. – John P Aug 09 '17 at 22:59
  • Other Vim script options: turn on 'confirm' to confirm quit/leave/etc.; for writing, I believe you would need an autocommand for BufWritePre with `confirm()`. Also, instead of mapping caps lock to ctrl, you could map it to a key or combination understood but unmapped by Vim, and then emulating caps lock exclusively while in insert/replace mode, by hand or by something like https://github.com/tpope/vim-capslock . You probably won't need it outside of Vim, but if you do, write an xmodmap script to revert your changes, or see if the program supports mappings of its own (and make notes.) – John P Aug 09 '17 at 23:58
  • 7
    zt / zz / zb - fixed cursor and move screen to **t**op/center(german:'**z**entrum')/ **b**ottom H / M / L - fixed screen and move cursor to **H**igh / **M**iddle / **L**ow position – eli Aug 10 '17 at 06:31
  • If you got used to `zz`, in Linux you can achive the caps lock security remapping with the `setxkbmap -option caps:x` command. In vim you can't remap that key. You wont need it anyways. Around here capitalize text with `gU`, right? :) – Rápli András May 04 '18 at 14:03
  • 3
    I prefer `z.` to `zz` just incase you happen to have caps lock on, `zz` wont be that friendly. – Anthony Awuley Mar 19 '19 at 20:29
  • `z.` sounds like the easiest avoidance. But if one is remapping, t, g, b are all oriented sensibly on a QWERTY keyboard. Move whatever "spellfile" does to something else. – GG2 Mar 19 '21 at 18:43
675

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 http://www.lagmonster.org/docs/vi2.html

Paul Wheeler
  • 11,951
  • 3
  • 21
  • 27
  • 106
    @ulidtko: efter (after in Swedish), yore (meaning the past), up, down, back, forward. (The words back and forward are longer than up and down, so naturally they move the screen a longer distance;) – Moberg Nov 12 '13 at 11:46
  • 16
    I guess yester, as in yesterday would be a better mnemonic though ^^ – Moberg Nov 13 '13 at 09:47
  • Both Ctrl-u and Ctrl-d move the cursor: "_The cursor is moved the same number of lines up in the file (if possible; when lines wrap and when hitting the end of the file there may be a difference)._" – Lex R Aug 26 '16 at 10:46
  • Thanks @LexR, I've updated the answer to reflect that distinction. – Paul Wheeler Dec 08 '16 at 23:11
  • 2
    `:help CTRL-E` says `Mnemonic: Extra lines.` – Niko Bellic Jan 27 '17 at 23:55
  • For Mnemonics I think of `Ctrl-b` : back `Ctrl-f` : forward `Ctrl-u` : up `Ctrl-d` : down `Ctrl-y` and `Ctrl-e` are kinda hopeless but they're next to u 'up' and d 'down' so that's about as close as it gets? – abenbot Dec 07 '18 at 14:51
  • I like the combination of `zt` + `3Ctrl+y` so that the current line will be at the top, but I'll still see part of the upper scope of the code I'm writting – aviggiano Jan 30 '21 at 13:04
43

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
GWW
  • 39,395
  • 8
  • 104
  • 101
  • 1
    note that if you only care about going to the bookmarked line, you could use 'g – Matt Briggs Aug 11 '10 at 13:32
  • 6
    "Vim requires the cursor to be in the current screen at all times" Vim users like to boast that everything is configurable in vim. This one isn't. I don't want my cursor moved while I'm scrolling through the file. Dealbreaker for me – gadelat May 08 '16 at 20:11
  • 9
    I've never had a situation where I wanted the cursor to be somewhere you couldn't see it. Sure, the cursor moves around when you scroll but you can go back to where you were trivially (so that you can see where you actually were, not just sort of guess). Double back-tick for one, `Ctrl-O` for another really great one, and "backtick, period" puts you back to where you were last editing. – dash-tom-bang Jun 20 '16 at 21:55
  • 3
    @gedalat, it's highly annoying in other editors when you scroll away, don't know where your cursor is anymore and have to use the mouse to click somewhere just so you can get the cursor back. Or you think you are "here", start typing and it suddenly jumps back to where the cursor was, at which point you can't jump back to where you had scrolled, because only the cursor positions are tracked. Having the cursor follow where you go is arguably a good thing. – Shahbaz Nov 23 '16 at 19:31
  • 1
    It is configurable, @gadelat. You just need to map this very answer (mark position with `mg`, scroll around, goto mark with `'g` and you are done. Now you can invoke the configurable key to go around and it will feel like the cursor never leaved the current position. Voilá! – DrBeco Feb 25 '17 at 16:56
  • Even if vim requires to have the cursor on the current screen. You could possibly "scroll" to every position in the file by folding the lines above and below you without moving. (see also my answer about the move-less plugin which takes advance of this idea) – snap Oct 31 '18 at 16:54
20

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.

the Tin Man
  • 150,910
  • 39
  • 198
  • 279
Way
  • 529
  • 2
  • 5
  • 12
17

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
  • 3
    I forget/confuse it every time: zt / zz / zb - fixed cursor and move screen to **t**op/center(german:'**z**entrum')/ **b**ottom H / M / L - fixed screen and move cursor to **H**igh / **M**iddle / **L**ow position – eli Aug 10 '17 at 06:29
15

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.

the Tin Man
  • 150,910
  • 39
  • 198
  • 279
Jesse Reza Khorasanee
  • 2,145
  • 3
  • 23
  • 41
  • 4
    And if you don't want the cursor always to be *right* in the middle, you can set it to a smaller value. For instance, `:set scrolloff=4` will require the cursor to always be at least 4 lines away from the top or bottom of the window, so you always have at least a little bit of context. – Soren Bjornstad Oct 10 '19 at 22:37
10

I've used these shortcuts in the past (note: separate key strokes i.e. tap z, let go, tap the subsequent key):

z enter --> moves current line to top of screen

z . --> moves current line to center of screen

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.

Razzle
  • 301
  • 2
  • 11
8

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.

eli
  • 1,516
  • 1
  • 17
  • 22
5

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.

yunzen
  • 30,001
  • 10
  • 64
  • 93
4

You may find answers to "Scrolling Vim relative to cursor, custom mapping" useful.

You can use ScrollToPercent(0) from that question to do this.

the Tin Man
  • 150,910
  • 39
  • 198
  • 279
ZyX
  • 49,123
  • 7
  • 101
  • 128
4

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)

Nicolas Raoul
  • 55,003
  • 52
  • 197
  • 338
4

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.

Yusuf Adeyemo
  • 199
  • 2
  • 9
Joe
  • 556
  • 4
  • 21
2

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.

Community
  • 1
  • 1
Oleg Khalidov
  • 4,470
  • 1
  • 23
  • 27
1

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.

the Tin Man
  • 150,910
  • 39
  • 198
  • 279
snap
  • 1,166
  • 1
  • 12
  • 18