ChatGPT解决这个技术问题 Extra ChatGPT

How to move screen without moving cursor in Vim?

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?


E
Eduardo Cuomo

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


@HappyGreenKidNaps Map that caps lock key to control ASAP!
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.)...
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.
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 position
I prefer z. to zz just incase you happen to have caps lock on, zz wont be that friendly.
M
Matthias Braun

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


@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;)
I guess yester, as in yesterday would be a better mnemonic though ^^
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)."
:help CTRL-E says Mnemonic: Extra lines.
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?
G
GWW

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

note that if you only care about going to the bookmarked line, you could use 'g
"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
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.
@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.
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á!
t
the Tin Man

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.


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.
this is beautiful
t
the Tin Man

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.


I thing this solution is more what the OP needed. I applied it and it works like a charm.
How about just setting 'scrolloff' to half the value of 'lines'?
unfortunately "nnoremap o ozza" loses the autoindent, but this works around it by adding and removing a temporary character '.' "nnoremap o o.zzxa"
a
alxndr

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


these are great, z then t is a bit of a stretch 🤸‍♂️ for my little stumps
A
Alexander Rumyantsev

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

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 position
M
MacMartin

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.


y
yunzen

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.


Y
Yusuf Adeyemo

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.


N
Nicolas Raoul

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)


t
the Tin Man

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

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


C
Community

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.


t
the Tin Man

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.