Is there a way to get 10 lines above and beneath the current cursor?

Similar to set scrolloff=10 but I only want to do it ONCE, not change the setting...

Clarification: I want at least 10 lines. If there's already 10+ lines above and below the cursor then the command shouldn't change anything. zz and z. are close but they do a little too much.

Sorry for the exacting request, I'm not sure there's an easy way to do this

  • Does z. do what you want? Commented May 7, 2020 at 20:39
  • @ChristianBrabandt Or zz which is the same but leaves the cursor in the same column...
    – filbranden
    Commented May 7, 2020 at 20:53
  • 1
    Thanks for the suggestions! z. and zz are close to what I need but if the cursor is already close to center then I don't want to move it. Sorry to be choosy! @ChristianBrabandt @filbranden
    – NDavis
    Commented May 7, 2020 at 21:13
  • 1
    @filbranden ah yes, I remember. I tend to ignore that command, because it is so close to ZZ Commented May 8, 2020 at 5:57
  • 1
    It can be done with a mapping and a function... If I have some time tomorrow I'll see if I can write something that does that.
    – filbranden
    Commented May 8, 2020 at 7:11

2 Answers 2


The brute force way to do it:

:let scrolloff_before = &scrolloff | set scrolloff=10 | redraw | let &scrolloff = scrolloff_before | unlet scrolloff_before

This works by saving the current 'scrolloff' value in a variable, setting it to 10, redrawing the screen so the update is applied (which is necessary because we are running all the commands in a single command-line), and then resetting 'scrolloff' to the original value. Finally, we remove the variable, which isn't really necessary but it's nice to be tidy.

Obviously you don't want to type that in every time, so you can make a command by adding the following to your .vimrc:

command ScrollOff10 let s:scrolloff_before = &scrolloff | set scrolloff=10 | redraw | let &scrolloff = s:scrolloff_before

As we're now in a script, we can use script-local variables to decrease the chances of our variable overwriting a pre-existing one (and we don't bother to unlet it, as it's not visible outside the script.

Or a mapping:

nnoremap <F1> :let s:scrolloff_before = &scrolloff<CR>:set scrolloff=10<CR>:let &scrolloff = s:scrolloff_before<CR>

This version doesn't need the :redraw either, because instead of concatenating the commands with :bar, we're entering them one at a time with (mapped) presses of the Return key.


This is essentially packing @Rich's solution (temporarily setting 'scrolloff') into a function, to improve readability.

I'm also defining a command and a mapping with a little bit more of flexibility (allowing a custom offset to be specified through a "count") and usability.

function! ScrollOffset(offset)
    let save_scrolloff = &l:scrolloff
    let &l:scrolloff = a:offset ? a:offset : 10
    let &l:scrolloff = save_scrolloff

command! -bar -count=0 ScrollOffset call ScrollOffset(<count>)

nnoremap <silent> z. :<C-u>call ScrollOffset(v:count)<CR>

You can employ it by using one of the following commands:

  • z. to scroll with a default of 10
  • :ScrollOffset does the same.
  • 5z. to scroll with a custom offset of 5 (specified as a "count" to the command)
  • :ScrollOffset 5 does the same.
  • :5ScrollOffset also does the same.
  • 1
    thanks for putting it in the function :)
    – NDavis
    Commented May 11, 2020 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.