Basically map H and L based on the cursor positon. If I press H the cursor should go to top of the screen and if I press H again I want to scroll up by one page.

2 Answers 2


This is actually a fantastic idea! I might steal this for my own .vimrc... :P

Anyway, this can be done with <expr> mappings. I also found this stack overflow answer extremely helpful. Onto the solution...

nnoremap <expr> H getcurpos()[1] == line("w0") ? "\<PageUp>" : "H"
nnoremap <expr> L getcurpos()[1] == line("w$") ? "\<PageDown>" : "L"

xnoremap <expr> H getcurpos()[1] == line("w0") ? "\<PageUp>" : "H"
xnoremap <expr> L getcurpos()[1] == line("w$") ? "\<PageDown>" : "L"

Basically, the way this works is by first evaluating a vimscript expression, and running the resulting string as a sequence of normal mode keys. The expression is

getcurpos()[1] == line("w0")

Note that getcurpos seems to be a vim 8 feature. If you're on an older vim and you don't have this, you could do getpos('.') instead.

getcurpos()[1] will give you the current line number, and line("w0") will give you the first visible line and line("w$") will give you the last visible line.

Further reading...

  • 1
    Can also just use line(). e.g. nnoremap <expr> H line('.') == line("w0") ? "\<PageUp>" : "H" Commented Nov 14, 2017 at 18:57
  • Thanks for the answer, it works in regular vim8. One other suggestion to your answer is to put the cursor on the top line after <PageUp> and on the bottom line after the <PageDown> so that its easier to scroll pages. But unfortunately, I just started using Spacevim as it comes with tons of plugins and somehow the H and L move the cursor to the fourth line from the top and fourth line from the bottom. I guess I have to figure out how to disable it. I would be greatful, If any one can help me.
    – raj
    Commented Nov 14, 2017 at 19:09
  • 1
    You probably have scrolloff set. That is the vertical distance in lines to keep the cursor from top or bottom of the display.
    – Wolf
    Commented Nov 14, 2017 at 19:43

I use a non-zero value for 'scrolloff' so this one handles &scrolloff > 0 and has a few other small enhancements compared to DJMcMayhem's fine submission:

  • Incorporates a suggestion that I like from this comment to keep the cursor at the top/bottom of the screen after paging up/down.
  • Uses line() rather than getcurpos() for consistency and to avoid any potential compatibility issues with getcurpos() and earlier versions of Vim
  • Uses the more Vim-like (to me anyways) CtrlF and CtrlB


nnoremap <expr> H line(".") - &scrolloff == line("w0") ? "\<C-B>H" : "H"
nnoremap <expr> L line(".") + &scrolloff == line("w$") ? "\<C-F>L" : "L"

Similarly for xnoremap.

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.