vimtricks.wiki Concise Vim tricks, one at a time.

How do I make Vim automatically jump to where I last edited when reopening a file?

Answer

autocmd BufReadPost * if line("'\"") > 0 && line("'\"") <= line("$") | exe "normal! g`\"" | endif

Explanation

Vim remembers the last cursor position for every file you edit (stored in the viminfo or shada file), but by default it opens files at line 1. Adding a BufReadPost autocmd that jumps to the '" mark restores your cursor to exactly where you left off — line and column — every time you reopen a file.

How it works

  • The '" mark is a special automatic mark that records the cursor position when you last exited the buffer
  • BufReadPost fires after a file has been read into a buffer
  • line("'\"" returns the line number of the '" mark, or 0 if it doesn't exist
  • The condition checks that the mark exists and the line is still within the file (in case lines were deleted externally)
  • g'" jumps to the exact position of the '" mark

Setup

Add this to your vimrc:

autocmd BufReadPost *
  \ if line("'\"" ) > 0 && line("'\"" ) <= line("$")
  \|   exe "normal! g`\""
  \| endif

Or in Vim 8.2+ and Neovim, you can simply source the built-in defaults:

runtime defaults.vim

The defaults.vim file includes this autocmd along with other sensible defaults.

Example

You are editing main.go and your cursor is on line 42, column 15 inside a function. You close Vim. Later, you run vim main.go and your cursor lands right back on line 42, column 15 — no need to search or remember where you were.

This is especially powerful across a multi-file project. Every file remembers its own last position independently.

Tips

  • The position data is stored in the viminfo file (Vim) or shada file (Neovim) — make sure these are not disabled in your config
  • Ensure viminfo includes the ' option to remember marks for files: :set viminfo+=!,'100 remembers marks for the last 100 files
  • Exclude certain file types where restoring position makes no sense, like git commit messages:
autocmd BufReadPost *
  \ if line("'\"" ) > 0 && line("'\"" ) <= line("$") && &filetype != 'gitcommit'
  \|   exe "normal! g`\""
  \| endif
  • Use g"(with backtick) instead ofg'"` (with quote) to restore the exact column position, not just the line
  • You can manually jump to this mark at any time with '" or `" — the autocmd just automates it on file open
  • If the position seems wrong after external edits, it is because the '" mark still references the old line number — the condition line("'\"" ) <= line("$") prevents jumping past the end of the file in that case

Next

How do I edit multiple lines at once using multiple cursors in Vim?