Vim Tips Wiki
(greatly simplify everything into one autocmd; fix zv when upper line is foldlevel <= 0)
Tag: Visual edit
 
(43 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{review}}
 
 
{{TipImported
 
{{TipImported
 
|id=80
 
|id=80
 
|previous=79
 
|previous=79
 
|next=81
 
|next=81
|created=June 15, 2001
+
|created=2001
 
|complexity=intermediate
 
|complexity=intermediate
 
|author=Charles E Campbell
 
|author=Charles E Campbell
Line 12: Line 11:
 
|category2=
 
|category2=
 
}}
 
}}
  +
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:
 
  +
== Plugins ==
  +
* The [https://github.com/farmergreg/vim-lastplace vim-lastplace] plugin will open your files at the last edit position. It is smart enough to handle commit messages correctly too!
  +
  +
== Doing It Manually ==
 
Here is 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, so be sure to have viminfo enabled with reasonable options (it is enabled by default):
 
<pre>
 
<pre>
 
" Tell vim to remember certain things when we exit
 
" Tell vim to remember certain things when we exit
" '10 : marks will be remembered for up to 10 previously edited files
+
" '10 : marks will be remembered for up to 10 previously edited files
" "100 : will save up to 100 lines for each register
+
" "100 : will save up to 100 lines for each register
" :20 : up to 20 lines of command-line history will be remembered
+
" :20 : up to 20 lines of command-line history will be remembered
" % : saves and restores the buffer list
+
" % : saves and restores the buffer list
" n... : where to save the viminfo files
+
" n... : where to save the viminfo files
 
set viminfo='10,\"100,:20,%,n~/.viminfo
 
set viminfo='10,\"100,:20,%,n~/.viminfo
 
</pre>
   
 
If you are 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 will need to change the "n" suboption to something like:
function! s:ResCur()
 
 
<pre>
let l:pline = line("'\"")
 
 
set viminfo='10,\"100,:20,%,nc:\\some\\place\
 
</pre>
   
  +
Afterwards, add the main function that restores the cursor position and its autocmd so that it gets triggered:
if pline > 0 && &foldenable
 
 
<pre>
let l:uline = pline - 1
 
 
function! ResCur()
let l:pfold = foldlevel(pline)
 
 
if line("'\"") <= line("$")
let l:ufold = foldlevel(uline)
 
 
normal! g`"
 
  +
return 1
if ufold > 0
 
 
endif
if pfold > ufold
 
execute uline
 
endif
 
execute "normal! zv"
 
endif
 
endif
 
 
execute "normal! g'\""
 
 
endfunction
 
endfunction
   
augroup jumpCursor
+
augroup resCur
autocmd!
+
autocmd!
autocmd BufWinEnter * call s:ResCur()
+
autocmd BufWinEnter * call ResCur()
 
augroup END
 
augroup END
 
</pre>
 
</pre>
   
  +
This tip is an improved version of the example given for {{help|last-position-jump}}. It fixes a problem where the cursor position will not be restored if the file only has a single line.
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:
 
   
  +
==Partial Foldlevel Restore==
  +
The following will unfold like {{help|zv}}, except that when the cursor matches the start of a new folding level, it will unfold just so that the cursor line is visible without doing the same for the contained folded section.
  +
  +
The functionality depends on ''ResCur()'' to achieve the desired effect when re-reading a file.
 
<pre>
 
<pre>
  +
if has("folding")
set viminfo='10,\"100,:20,%,nc:\\some\\place\\under\\Windows\\_viminfo
 
  +
function! UnfoldCur()
 
if !&foldenable
 
return
 
endif
 
let cl = line(".")
  +
if cl <= 1
  +
return
  +
endif
 
let cf = foldlevel(cl)
 
let uf = foldlevel(cl - 1)
  +
let min = (cf > uf ? uf : cf)
  +
if min
 
execute "normal!" min . "zo"
  +
return 1
  +
endif
  +
endfunction
 
endif
 
</pre>
 
</pre>
   
  +
Finish by modifying the previously added augroup:
This tip is a somewhat improved version of the example given for {{help|line()}}.
 
 
<pre>
 
  +
augroup resCur
==Limitations==
 
  +
autocmd!
*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.
 
  +
if has("folding")
  +
autocmd BufWinEnter * if ResCur() | call UnfoldCur() | endif
  +
else
  +
autocmd BufWinEnter * call ResCur()
  +
endif
  +
augroup END
 
</pre>
   
 
==Additional Information==
 
==Additional Information==
*Help for viminfo is at: :he 'viminfo'
+
*Help for viminfo is at: {{help|viminfo}}.
 
*Part of this tip has made its way into the manual: {{help|last-position-jump}}.
 
*Part of this tip has made its way into the manual: {{help|last-position-jump}}.
  +
*There is an improved {{script|id=3059}} version of last-position-jump that also works for easy Vim
   
 
==Comments==
 
==Comments==
 
{{todo}}
 
{{todo}}
  +
*It looks like `:mkview` and `:loadview` are much better solutions to this (see http://stackoverflow.com/questions/8854371)
*I have cleaned up the nonstandard formatting given to the tip.
 
  +
::Sorry if I am mistakenly messing with your formatting.
*Someone probably needs to restore at least part of the original tip, per my next comment.
 
  +
::I currently use this simple alternative:
*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.
 
  +
augroup resCur
*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 <tt>exe "+".1</tt> is just <tt>exe "+1"</tt>.
 
  +
autocmd!
  +
autocmd BufReadPost * call setpos(".", getpos("'\""))
  +
augroup END
  +
::--andresp (probably not logged in atm)
  +
*Check my comment following, and the explanation after that (refactored from Anres.p's comment with dealt-with material omitted).
  +
*I have not yet looked at the current solution. [[User:JohnBot|JohnBot]] 07:14, January 22, 2011 (UTC)
   
 
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.
 
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. [[User:JohnBeckett|JohnBeckett]] 08:58, 5 March 2009 (UTC)
+
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 <s>(the one currently in the tip)</s> is worthwhile. [[User:JohnBeckett|JohnBeckett]] 08:58, 5 March 2009 (UTC)
 
 
----
 
----
  +
:The solution in vimrc_example.vim is exactly the same as {{help|line}} and {{help|last-position-jump}}, except that the autocmd is styled across lines instead of concatenated into a single line. [[User:Andres.p|Andres.p]] 18:07, December 1, 2010 (UTC)
Personally, I think the example given in {{help|line()}} is fine. It does just what I want. --xaprb
 
   
  +
:The reason why the code in vimrc_example.vim ''shouldn't'' be explained I already gave in a previous comment that was deleted by the bot. :) It performs a redundant conditional that keeps from restoring the column position when the file is one line long... [[User:Andres.p|Andres.p]] 21:55, January 22, 2011 (UTC)
The help example mentioned above is:
 
  +
::This is exactly why we ''should'' mention the version in the :help. We need to know why the :help version can't just be used as-is. I personally have not paid much attention to this tip exactly because I have thought the version in the :help to be enough for my needs. --[[User:Fritzophrenic|Fritzophrenic]] 15:53, January 24, 2011 (UTC)
<pre>
 
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
 
</pre>
 
   
----
+
---
  +
: Just a note that this won't work if ~/.viminfo is owned by root (if you're running as a regular user), of course this isn't surprising. I'm just not sure how I ended up with ~/.viminfo owned by root. [[User:Bostonvaulter|Bostonvaulter]] ([[User talk:Bostonvaulter|talk]]) 20:11, October 5, 2012 (UTC)
Altering the vimtip version to use g` instead of g' made it return to the line and character instead of just the line eg
 
<pre>
 
:au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif
 
</pre>
 
 
--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:
 
<pre>
 
" 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
 
</pre>
 
 
--jamax
 
 
----
 

Latest revision as of 12:36, 4 April 2020

Tip 80 Printable Monobook Previous Next

created 2001 · complexity intermediate · author Charles E Campbell · version 6.0


Plugins[]

  • The vim-lastplace plugin will open your files at the last edit position. It is smart enough to handle commit messages correctly too!

Doing It Manually[]

Here is 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, so be sure to have viminfo enabled with reasonable options (it is enabled by default):

" 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

If you are 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 will need to change the "n" suboption to something like:

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

Afterwards, add the main function that restores the cursor position and its autocmd so that it gets triggered:

function! ResCur()
  if line("'\"") <= line("$")
    normal! g`"
    return 1
  endif
endfunction

augroup resCur
  autocmd!
  autocmd BufWinEnter * call ResCur()
augroup END

This tip is an improved version of the example given for :help last-position-jump. It fixes a problem where the cursor position will not be restored if the file only has a single line.

Partial Foldlevel Restore[]

The following will unfold like :help zv, except that when the cursor matches the start of a new folding level, it will unfold just so that the cursor line is visible without doing the same for the contained folded section.

The functionality depends on ResCur() to achieve the desired effect when re-reading a file.

if has("folding")
  function! UnfoldCur()
    if !&foldenable
      return
    endif
    let cl = line(".")
    if cl <= 1
      return
    endif
    let cf  = foldlevel(cl)
    let uf  = foldlevel(cl - 1)
    let min = (cf > uf ? uf : cf)
    if min
      execute "normal!" min . "zo"
      return 1
    endif
  endfunction
endif

Finish by modifying the previously added augroup:

augroup resCur
  autocmd!
  if has("folding")
    autocmd BufWinEnter * if ResCur() | call UnfoldCur() | endif
  else
    autocmd BufWinEnter * call ResCur()
  endif
augroup END

Additional Information[]

Comments[]

 TO DO 

Sorry if I am mistakenly messing with your formatting.
I currently use this simple alternative:
augroup resCur
  autocmd!
  autocmd BufReadPost * call setpos(".", getpos("'\""))
augroup END
--andresp (probably not logged in atm)
  • Check my comment following, and the explanation after that (refactored from Anres.p's comment with dealt-with material omitted).
  • I have not yet looked at the current solution. JohnBot 07:14, January 22, 2011 (UTC)

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)


The solution in vimrc_example.vim is exactly the same as :help line and :help last-position-jump, except that the autocmd is styled across lines instead of concatenated into a single line. Andres.p 18:07, December 1, 2010 (UTC)
The reason why the code in vimrc_example.vim shouldn't be explained I already gave in a previous comment that was deleted by the bot. :) It performs a redundant conditional that keeps from restoring the column position when the file is one line long... Andres.p 21:55, January 22, 2011 (UTC)
This is exactly why we should mention the version in the :help. We need to know why the :help version can't just be used as-is. I personally have not paid much attention to this tip exactly because I have thought the version in the :help to be enough for my needs. --Fritzophrenic 15:53, January 24, 2011 (UTC)

---

Just a note that this won't work if ~/.viminfo is owned by root (if you're running as a regular user), of course this isn't surprising. I'm just not sure how I ended up with ~/.viminfo owned by root. Bostonvaulter (talk) 20:11, October 5, 2012 (UTC)