How to move screen without moving cursor in Vim?
Asked Answered
V

14

824

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?

Visor answered 11/8, 2010 at 13:21 Comment(0)
F
1183
  • zz - move current line to the middle of the screen (warning: ZZ is save and exit, so watch out for caps lock)
  • zt - move current line to the top of the screen
  • zb - move current line to the bottom of the screen
Fend answered 11/8, 2010 at 13:34 Comment(11)
@HappyGreenKidNaps Map that caps lock key to control ASAP!Redevelop
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.)...Reyreyes
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.Reyreyes
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 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.)Reyreyes
zt / zz / zb - fixed cursor and move screen to top/center(german:'zentrum')/ bottom <---> H / M / L - fixed screen and move cursor to High / Middle / Low positionGutta
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? :)Fluorescein
I prefer z. to zz just incase you happen to have caps lock on, zz wont be that friendly.Gabion
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.Benzoin
Be aware that z. puts the cursor at first non-blank in the line, while zz leaves the cursor in the same column.Pelting
Note that zt and zb are affected by your scrolloff value. Eg: if scolloff=15, then zt will have 15 lines before your cursor (and zb will have 15 lines after).Flagitious
@Redevelop hey from 5.5 years in the future. Excuse me, I like my Caps lock. Just use leader<key2> like a sane person and deal with 2 keystrokesMajor
H
841

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

Harbinger answered 27/6, 2012 at 21:43 Comment(7)
@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;)Football
I guess yester, as in yesterday would be a better mnemonic though ^^Football
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)."Ponderous
:help CTRL-E says Mnemonic: Extra lines.Premiere
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?Hygienist
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 writtingDarelldarelle
You can try "Expose" one more line for Ctrl-e. And "Yester-line" for Ctrl-y (vi.stackexchange.com/questions/5195/…). I always think of "Yahweh" living above, and "Evil" below.Montreal
C
46

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
Creolized answered 11/8, 2010 at 13:25 Comment(6)
note that if you only care about going to the bookmarked line, you could use 'gWriest
"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 mePsychophysiology
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.Argenteuil
@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.Capernaum
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á!Vapor
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)Trophoplasm
U
34

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.

Unjaundiced answered 12/8, 2019 at 3:10 Comment(2)
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.Ottinger
Shorter, fun little useful triviaMajor
F
24

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

Felsite answered 10/10, 2019 at 15:47 Comment(1)
these are great, z then t is a bit of a stretch 🤸‍♂️ for my little stumpsAllegorize
H
22

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.

Haplology answered 10/5, 2017 at 9:33 Comment(2)
How about just setting 'scrolloff' to half the value of 'lines'?Canterbury
unfortunately "nnoremap o o<ESC>zza" loses the autoindent, but this works around it by adding and removing a temporary character '.' "nnoremap o o.<ESC>zzxa"Unmuzzle
H
19

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
Heighttopaper answered 18/2, 2016 at 7:35 Comment(1)
I forget/confuse it every time: zt / zz / zb - fixed cursor and move screen to top/center(german:'zentrum')/ bottom <---> H / M / L - fixed screen and move cursor to High / Middle / Low positionGutta
G
19

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.

Gutta answered 9/3, 2020 at 20:24 Comment(0)
I
8

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.

Infrangible answered 3/3, 2017 at 13:23 Comment(0)
D
8

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.

Davilman answered 31/10, 2019 at 14:6 Comment(0)
S
5

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)

Solution answered 9/8, 2017 at 8:28 Comment(0)
C
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.

Coypu answered 11/8, 2010 at 13:30 Comment(0)
N
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.

Naoma answered 6/11, 2015 at 19:31 Comment(0)
T
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.

Trophoplasm answered 18/4, 2018 at 5:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.