Vim Tips Wiki
m (split into sections so that people looking for the simple solution don't get confused)
(→‎Comments: replies to comments that don't apply)
Line 115: Line 115:
 
:au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
 
:au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
 
</pre>
 
</pre>
  +
  +
----
  +
:The problem with the solution in {{help|line()}} is that there's no reason it shouldn't restore the column position if the line happens to be one line long, so the first conditional is redundant. [[User:Andres.p|Andres.p]] 18:07, December 1, 2010 (UTC)
   
 
----
 
----
Line 123: Line 126:
   
 
----
 
----
  +
:The tip already uses g` instead of g' to restore to ''line:column'', so this comment no longer applies. [[User:Andres.p|Andres.p]] 18:07, December 1, 2010 (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 <s>(the one currently in the tip)</s> 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}}, 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)

Revision as of 18:07, 1 December 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, 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'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

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

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

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

Optionally add a function that takes care of selectively unfolding right after restoring the cursor position:

if has("folding")
    function! UnfoldCur()
        if ! &foldenable
            return
        endif

        let l:pline = line(".")

        if l:pline > 1
            let l:pfold = foldlevel(l:pline)
            let l:ufold = foldlevel(l:pline - 1)

            if l:ufold > 0
                execute "normal!" (l:pfold > l:ufold ? l:ufold : l:pfold) . "zo"
                return 1
            endif
        endif
    endfunction
endif

And modify the augroup:

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

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

Additional Information

Comments

Andres.p, thanks for the significant effort you've put into this tip! I do have some suggestions:

  • First of all, please don't remove the TipImported, TipNew, TipProposed, etc. templates. They are used for page organization and navigation. Removing the Review template is fine.
  • Please don't remove the Comments section, we leave them in to encourage contribution. On this wiki, we have a custom of using a Comments section in the page itself, rather than the talk pages, when discussing content.
  • This particular tip needs a good introduction explaining what problem is being solved. As mentioned in the old comments below, there are a few much simpler solutions widely available. These solutions should be mentioned, then explain why the solution given above is better (what specific issues does it solve?). For many people, the simple examples are sufficient (or they haven't noticed the issues solved by the more complex script above).

Thanks again!

--Fritzophrenic 14:31, December 1, 2010 (UTC)


Hello, Fritzophrenic.
  • I removed the TipImported and TipNew, etc. templates because it is new code. I don't really care either way if they stay or don't, or maybe I'm misinterpreting their meaning and usage.
  • Sorry for removing the comments section; I'll keep it in mind from now on.
  • The particular issue it solves is the same as the original tip, which is unfolding just so that the previous cursor prosition ('") is unfolded. It's almost the same as :normal! zv, except that if ('") happens to be the start of a new folding section, it does not get unfolded; the upper line does. I'll eventually get around wording this in comprehensible way.
Anyway, sorry and thanks for letting me know! I'm new around here. Andres.p 17:45, December 1, 2010 (UTC)

Here are some old comments which are still applicable:


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

The problem with the solution in :help line() is that there's no reason it shouldn't restore the column position if the line happens to be one line long, so the first conditional is redundant. Andres.p 18:07, December 1, 2010 (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

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

The tip already uses g` instead of g' to restore to line:column, so this comment no longer applies. Andres.p 18:07, December 1, 2010 (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, except that the autocmd is styled across lines instead of concatenated into a single line. Andres.p 18:07, December 1, 2010 (UTC)