Vim Tips Wiki
(fix wrong function call)
(use recommended augroup casing)
Line 48: Line 48:
 
endfunction
 
endfunction
   
augroup JumpCursorOnEdit
+
augroup jumpCursorOnEdit
 
autocmd!
 
autocmd!
 
autocmd BufReadPost * call s:ResCur()
 
autocmd BufReadPost * call s:ResCur()

Revision as of 11:51, 28 November 2010

Tip 80 Printable Monobook Previous Next

created June 15, 2001 · complexity intermediate · author Charles E Campbell · version 6.0


Here's something for your vimrc which will allow you to restore your cursor position in a file over several editing sessions. This technique uses the viminfo option:

" Tell vim to remember certain things when we exit
"  '10  :	marks will be remembered for up to 10 previously edited files
"  "100 :	will save up to 100 lines for each register
"  :20  :	up to 20 lines of command-line history will be remembered
"  %    : 	saves and restores the buffer list
"  n... : 	where to save the viminfo files
set viminfo='10,\"100,:20,%,n~/.viminfo

" When we reload, tell vim to restore the cursor to the saved position.
function! s:ResCur()
	if expand("<afile>:p:h") !=? $TEMP
		let l:prevl = line("'\"")
		if line(prevl) > 0 && line(prevl) <= line("$")
			let b:doopenfold = 1
			if (foldlevel(prevl) > foldlevel(prevl - 1))
				let prevl = prevl - 1
				let b:doopenfold = 2
			endif
			execute prevl
		endif
	endif
endfunction

" Need to postpone using "zv" until after reading the modelines.
function! s:UnfoldCur()
	if exists("b:doopenfold")
		execute "normal! zv"
		if b:doopenfold == 2
			execute "+1"
		endif
		unlet b:doopenfold
	endif
endfunction

augroup jumpCursorOnEdit
	autocmd!
	autocmd BufReadPost * call s:ResCur()
	autocmd BufWinEnter * call s:UnfoldCur()
augroup END

If you're on Unix, the viminfo example above is probably fine as is (but check up on Vim's help for viminfo to see if you like the settings above). For Windows you'll need to change the "n" suboption to something like:

set viminfo='10,\"100,:20,%,nc:\\some\\place\\under\\Windows\\_viminfo

This tip is a somewhat improved version of the example given for :help line().

Limitations

  • At least one editor of this article who used the example with VIM Version 7.1.318 experienced the cursor being restored to the same line, but not the same column. Vim 7.1 as installed on Solaris 9 does the same thing -- the cursor is restored to the correct line, but not the column.

Additional Information

Comments

 TO DO 

  • I have cleaned up the nonstandard formatting given to the tip.
  • Someone probably needs to restore at least part of the original tip, per my next comment.
  • The most complex of the proposed solutions from the original tip has been kept. Since it was the last such solution, there is a reasonable hope that it would be the best. But I don't think it is. As noted (in "Limitations") it doesn't restore the column position. That's by design! It uses "exe <linenumber>" to restore the position, and so is not satisfactory IMHO.
  • I haven't taken the time to understand all that fold stuff. I suppose it would be useful to some, so I'm reluctant to delete it. But it's frustrating how, unless you are familiar with the issue that the author is addressing, you would need to study the tip for ages to work out why it works like this, and what it actually does. Use of "JumpCursorOnEdit_foo" as a variable name is a worry. The exe "+".1 is just exe "+1".

On my system, I copy the restore-last-position code from vimrc_example.vim (a file distributed with Vim). That code is the basis of the first solution in the tip (now deleted). vimrc_example also makes the help 'last-position-jump' obsolete. That first solution deserves deletion IMHO because it has a totally inexplicable "norm $" that doesn't seem at all useful to me.

My current feeling is that vimrc_example should be explained, and perhaps the second solution (currently deleted) should be shown. I'm not at all sure that the third solution (the one currently in the tip) is worthwhile. JohnBeckett 08:58, 5 March 2009 (UTC)


Personally, I think the example given in :help line() is fine. It does just what I want. --xaprb

The help example mentioned above is:

This autocommand jumps to the last known position in a file
just after opening it, if the '"' mark is set:
:au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif

Altering the vimtip version to use g` instead of g' made it return to the line and character instead of just the line eg

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

--bristley


This is from an old gentoo vimrc. It mostly works, I add it because it's much simpler than the one above, but I don't understand either really:

" When editing a file, always jump to the last cursor position
autocmd BufReadPost *
      \ if ! exists("g:leave_my_cursor_position_alone") |
      \     if line("'\"") > 0 && line ("'\"") <= line("$") |
      \         exe "normal g'\"" |
      \     endif |
      \ endif

--jamax