Yixing Lao
Yixing Lao

Reputation: 1438

Vim - Scroll Below the End of the Document

When we edit the last few lines of a document in vim, those lines are displayed at the bottom part of the screen, which is a little uncomfortable for me. Is there a way to scroll below the end of the document, so that the bottom lines in the document can be displayed at the top of the screen? (Currently Sublime Text has such capability.)

I've done some searches, the closest answer I could find is to use "set scrolloff=10". But that is not what I am looking for. Since it doesn't display the bottom lines of the document at the top of the screen.

Thanks in advance!

Upvotes: 22

Views: 10172

Answers (4)

Matthew Willcockson
Matthew Willcockson

Reputation: 1436

In addition to set scrolloff=10, some of the other answers mentioned Ctrl+E.

I wanted the default motion key j to scroll the cursor as normal if the cursor isn't on the last line of the file, and then when the cursor is on the last line, j should scroll the file (in this case using Ctrl+E).

Placing the following in a .vimrc file enables this behaviour.

function! Scroll()
    " what count was given with j? defaults to 1 (e.g. 10j to move 10 lines
    " down, j the same as 1j)
    let l:count = v:count1
    " how far from the end of the file is the current cursor position?
    let l:distance = line("$") - line(".")
    " if the number of times j should be pressed is greater than the number of
    " lines until the bottom of the file
    if l:count > l:distance
        " if the cursor isn't on the last line already
        if l:distance > 0
            " press j to get to the bottom of the file
            execute "normal! " . l:distance . "j"
        endif
        " then press Ctrl+E for the rest of the count
        execute "normal! " . (l:count - l:distance) . "\<C-e>"
    " if the count is smaller and the cursor isn't on the last line
    elseif l:distance > 0
        " press j the requested number of times
        execute "normal! " . l:count . "j"
    else
        " otherwise press Ctrl+E the requested number of times
        execute "normal! " . l:count . "\<C-e>"
    endif
endfunction
nnoremap j <Cmd>call Scroll()<CR>
nnoremap <Down> <Cmd>call Scroll()<CR>

Note: I'm not an expert Vim scripter, please edit with improvements

The last line also enables the same behaviour for the down arrow key .

For Neovim, putting the following in init.lua would do the same:

local line = vim.fn.line
local nvim_input = vim.api.nvim_input
local function scroll()
  -- what count was given with j? defaults to 1 (e.g. 10j to move 10 lines
  -- down, j the same as 1j)
  local count1 = vim.v.count1
  -- how far from the end of the file is the current cursor position?
  local distance = line("$") - line(".")
  -- if the number of times j should be pressed is greater than the number of
  -- lines until the bottom of the file
  if count1 > distance then
    -- if the cursor isn't on the last line already
    if distance > 0 then
      -- press j to get to the bottom of the file
      nvim_input(distance.."<Down>")
    end
    -- then press Ctrl+E for the rest of the count
    nvim_input((count1 - distance).."<C-e>")
  -- if the count is smaller and the cursor isn't on the last line
  elseif distance > 0 then
    -- press j as much as requested
    nvim_input(count1.."<Down>")
  else
    -- otherwise press Ctrl+E the requested number of times
    nvim_input(count1.."<C-e>")
  end
end

vim.keymap.set("n", "j", scroll, {
    desc = "continue scrolling past end of file with j",
})
vim.keymap.set("n", "<Down>", scroll, {
    desc = "continue scrolling past end of file with ↓",
})

Upvotes: 1

albusshin
albusshin

Reputation: 4010

In addition to @Kent's answer, zz would allow you to bring the current line to the middle of the screen, which in my opinion is more convenient to see the context of the current line of text/code.

Also, zb would bring the current line to the bottom of the screen, which may also help sometimes.

Upvotes: 31

Pak
Pak

Reputation: 736

In normal mode you can use CTRL-E to scroll down and CTRL-Y to scroll up without moving the position of the cursor (unless the cursor would get pushed off the screen). If you're at the end of the document pressing CTRL-E will scroll past the end until the last line is at the top of the screen. I tend to like this method better than zt or zz since I can see it scrolling rather having the screen just jump ahead.

There are some caveats. For example, CTRL-Y when using the Windows key bindings is mapped to redo. Check out :help scrolling for more info.

Upvotes: 13

Kent
Kent

Reputation: 195229

Is there a way to scroll below the end of the document, so that the bottom lines in the document can be displayed at the top of the screen?

If I understood your requirement right, zt (or z<cr>) can do that when your cursor on the last line (in fact works on any line, :h zt for details)

example:

enter image description here

Upvotes: 24

Related Questions