Dmitry Negoda
Dmitry Negoda

Reputation: 3189

Preserve last editing position in VIM

When I quit VIM and open the same file again, I am positioned at the start of the file. How can I preserve the last cursor position?

Upvotes: 94

Views: 52944

Answers (11)

DevSolar
DevSolar

Reputation: 70243

The last edit position is automatically preserved by Vim, and is available as "special" jump mark .. Other special marks include " (position you saved from) and ' (position you jumped from).

You can jump to a mark by typing '<mark>, so '. will take you to the place of the last edit, '' will take you back to where you were, and '" takes you to the position you saved the file at.

That and more about Vim marks at Vim.Wikia.

Mariano's answer then shows how to set up an autocmd that gets called every time after a buffer has been read (BufReadPost) for any file type (*) and then actually does '" (jump to position you saved from).

Upvotes: 38

GreenMarty
GreenMarty

Reputation: 382

Neovim lua solution from Neovim repo issue

  • covers edge cases like last cursors pos being outside buffer and ignored file types.
vim.api.nvim_create_autocmd('BufRead', {
  callback = function(opts)
    vim.api.nvim_create_autocmd('BufWinEnter', {
      once = true,
      buffer = opts.buf,
      callback = function()
        local ft = vim.bo[opts.buf].filetype
        local last_known_line = vim.api.nvim_buf_get_mark(opts.buf, '"')[1]
        if
          not (ft:match('commit') and ft:match('rebase'))
          and last_known_line > 1
          and last_known_line <= vim.api.nvim_buf_line_count(opts.buf)
        then
          vim.api.nvim_feedkeys([[g`"]], 'nx', false)
        end
      end,
    })
  end,
})

Basically this is what it does:

  • uses nested auto commands.

  • outer autocmd activates on "BufRead" (= after reading the file into the buffer) and creates create:

    • inner autocmd opon "BufWinEnter" (= After a buffer is displayed in a window.)
      • do file types and number of lines in lastpos vs lines in file checks
      • based on result restore position or do nothing
  • sources:

Upvotes: 0

1of7
1of7

Reputation: 31

In support of other posts, a version that works in a neovim init.lua is:

vim.api.nvim_create_autocmd('BufReadPost', { command = "silent! normal! g`"zv" })

The command is just one line, no line break in the middle. This is a bit more direct, and seems to align more with the nvim documentation on autocmd.

Upvotes: -1

thiagowfx
thiagowfx

Reputation: 5690

A more up-to-date version of the currently accepted answer:

silent! source $VIMRUNTIME/defaults.vim

Upvotes: 18

MetaEd
MetaEd

Reputation: 3871

The "out of the box" .vimrc enables this with the statement:

source $VIMRUNTIME/vimrc_example.vim

You may just need to restore this statement in your .vimrc. In any case, see vimrc_example.vim and also see the line() function in the Vim manual for a discussion of how it works.

Upvotes: 50

Kazuya  Gosho
Kazuya Gosho

Reputation: 1195

For Neovim users who are looking for a pure Lua version:

-- Restore cursor position
vim.api.nvim_create_autocmd({ "BufReadPost" }, {
    pattern = { "*" },
    callback = function()
        vim.api.nvim_exec('silent! normal! g`"zv', false)
    end,
})

Upvotes: 18

gsone
gsone

Reputation: 1231

I'm adding more complete example to @Mariano answer https://stackoverflow.com/a/14449484/108654 with some additional checks

" Only do this part when compiled with support for autocommands
if has("autocmd")
  augroup redhat
  autocmd!
  " When editing a file, always jump to the last cursor position
  autocmd BufReadPost *
  \ if line("'\"") > 0 && line ("'\"") <= line("$") |
  \   exe "normal! g'\"" |
  \ endif
  augroup END
endif

Upvotes: 6

Andy Beverley
Andy Beverley

Reputation: 292

Make sure ~/.viminfo is readable and writable by the user running vim. Somehow I had ended up with a copy readable only by root in my standard user home directory, which meant that the last cursor position could not be stored.

Upvotes: 9

Greg Dietsche
Greg Dietsche

Reputation: 1050

There is a plugin (I am the author) called vim-lastplace that will intelligently return you to the last edit that you made.

It also has a configuration option to ignore certain file types. By default it will ignore commit messages for git, svn, and mercurial. For these file types it will start your cursor at the first line. The code snippets above will jump into the middle of your commit message file (where you left off in your previous commit) even though that's probably not what you want. vim-lastplace fixes this problem.

Upvotes: 21

Mariano
Mariano

Reputation: 839

Taken from http://amix.dk/vim/vimrc.html

" Return to last edit position when opening files (You want this!)
autocmd BufReadPost *
     \ if line("'\"") > 0 && line("'\"") <= line("$") |
     \   exe "normal! g`\"" |
     \ endif

Upvotes: 83

tdammers
tdammers

Reputation: 20721

You could try the :mks command (make session). It stores a script file which, when run through vim, restores your current editing session, including all open files and the cursor position.

Upvotes: 0

Related Questions