13

Often times I edit a file - think my work is done - then close the file and move on to the next thing. But then I realise I need to go back to that code and tweak it a bit more.
If I open the file again, I can use the . mark and jump to the position of the last edit with '..
Now I'm trying to find a way to use vim's marks to jump to locations in files I have recently visited, but not changed.
I know I can set a mark manually, but most of the time, I don't expect to come back and so I don't set a mark and need to use a mark that vim generates automatically.
The " mark seems like this could be a way to achieve this, from :h motion.

" To the cursor position when last exiting the current buffer. Defaults to the first character of the first line. See |last-position-jump| for how to use this for each opened file. Only one position is remembered per buffer, not one for each window. As long as the buffer is visible in a window the position won't be changed. {not in Vi}.

However if I

  • close all windows showing a buffer (but the buffer is still present in the buffer list). or:
  • kill all instances of the buffer

the mark doesn't seem to update, how can I use a mark to jump to a location of the last cursor position in the buffer/file?

5
  • 3
    I think you are looking for Ctrl+o and Ctrl+i ... :h jump-motions for more info
    – Sundeep
    Commented Jun 10, 2016 at 3:44
  • @spasic thats not a bad suggestion, but once you make a few dozen jumps, the position would be lost in a massive jump list. By scoping the marks to the buffer you have a smaller list of marks/locations to manage Commented Jun 10, 2016 at 3:50
  • If you didn't read it already, I think this tip would be interesting. Maybe you'll have to tweak your viminfo
    – statox
    Commented Jun 10, 2016 at 12:17
  • @statox thanks. I saw that and the tip in the vim help. I think those solutions cause automatic jumping to the " mark when you open a file. I really wanted to only jump to the last cursor position manually. Also, I just couldn't make sense of when the " mark gets set and updated so to me the " mark is unusable. Commented Jun 10, 2016 at 12:28
  • Quite frankly, I find this question confusing, but I'd like to help. Thus, if @the_velour_fog is still around, it would be great to hear some additional explanations and see what can be done to achieve the desired vim behavior.
    – dsimic
    Commented Sep 5, 2023 at 6:52

3 Answers 3

7

Here is a classic solution: use

`H

to jump to the last HTML file and so on…

augroup VIMRC
  autocmd!

  autocmd BufLeave *.css  normal! mC
  autocmd BufLeave *.html normal! mH
  autocmd BufLeave *.js   normal! mJ
  autocmd BufLeave *.php  normal! mP
augroup END
1
  • 2
    thanks, this seems like it could really be useful. I've loaded it into my vimrc to try it out. I've changed to autocmd to WinLeave as I've noticed BufLeave doesn't seem to fire when you close a split and the buffer is still open somewhere else. I know its a bit of an edge case, but WinLeave seems to work over a wider range of "file closing" type situations, but I'm still just testing... Commented Jun 10, 2016 at 12:32
4

I wrote this vimscript statement which seems to work

autocmd BufLeave * :normal ml

Explanation

  • BufLeave auto command: this seems to trigger when you
    • move to another window
    • when you close the last window displaying the buffer
    • when you close the buffer itself with bd
  • :normal - it seems by default, the command part of autocmd is an ex command. So to tell vim to run a normal mode command , you need to add :normal
  • ml - set a mark l (mnemonic: last)

Usage

to recall the cursor position from the last time you were in the buffer simply hit

'l

or

`l
0

If you'd like your cursor to restore the last position known to viminfo, you can use

autocmd BufReadPost * call setpos(".", getpos("'\""))

romainl's answer has been particularly useful to me, and I have been using this a lot (since I am a web dev):

augroup VIMRC
    autocmd!
    autocmd BufLeave,WinLeave *.html normal! mH
    autocmd BufLeave,WinLeave *.css normal! mC
    autocmd BufLeave,WinLeave *.js normal! mJ
augroup end

nnoremap <space>h `Hzz
nnoremap <space>c `Czz
nnoremap <space>j `Jzz

The final potentially useful thing is the option, :help 'nostartofline:

               *'startofline'* *'sol'* *'nostartofline'* *'nosol'*
'startofline' 'sol' boolean (default on)
            global
            {not in Vi}
    When "on" the commands listed below move the cursor to the first
    non-blank of the line.  When off the cursor is kept in the same column
    (if possible).  This applies to the commands: CTRL-D, CTRL-U, CTRL-B,
    CTRL-F, "G", "H", "M", "L", gg, and to the commands "d", "<<" and ">>"
    with a linewise operator, with "%" with a count and to buffer changing
    commands (CTRL-^, :bnext, :bNext, etc.).  Also for an Ex command that
    only has a line number, e.g., ":25" or ":+".
    In case of buffer changing commands the cursor is placed at the column
    where it was the last time the buffer was edited.
    NOTE: This option is set when 'compatible' is set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.