0

Currently my vimrc has the following:

" Uncomment the following to have Vim jump to the last position when
" reopening a file
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif

This jumps to the last position when reopening a file, which is good. However, this position occasionally starts at the bottom of the screen. I often find myself using zz immediately after to center the line in the window. How can I make this centering always happen automatically?


Based on Maxim Kim's answer, I tried the following: au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | exe "normal! zz" | endif. This works inconsistently. Sometimes the last-visited line is placed in the center, whereas other times it is placed at the bottom. It seems to be essentially random - I can't reproduce the behavior consistently. Note that this works more often than exe "normal! g'\"zz" did.

4
  • what about adding zz to what you already have?
    – Maxim Kim
    Jul 8 at 6:34
  • are you sure it is "random"? Have you tried to check if your '" mark line number is in buffer lines range for the file where it didn't work?
    – Maxim Kim
    Jul 9 at 6:29
  • I would bet it isn't actually random, but I've been unable to find a way to cause it consistently thus far. Can you explain how I'd check what you're describing? I'm not familiar with that
    – Drake P
    Jul 9 at 6:32
  • well, looks like it depends on a filetype -- for some of them I can confirm I have the same issue as you have. I mean If I grab the contents of the file where it doesn't work and put it into plain text and do the same -- it works.
    – Maxim Kim
    Jul 9 at 6:53
1

You already have all details needed to solve your issue -- zz.

Add it to the

exe "normal! g`\""

Where exe executes a string as ex commands (here it is needed to overcome vimscript limitations with | and autocommand). Normal commands could be executed as ex commands using normal ex command... anyway this line jumps to a mark " without changing jumplist (as stated in :h g').

With

exe "normal! g`\"zz"

you should get what you need.

" restore cursor position
augroup restore_pos | au!
    au BufReadPost *
                \ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
                \ |   exe "normal! g`\"zz"
                \ | endif
augroup end

UPDATE

Looks like for zz another event should be used instead of BufReadPost:

" restore cursor position
augroup restore_pos | au!
    au BufWinEnter *
                \ if line("'\"") >= 1 && line("'\"") <= line("$") && &ft !~# 'commit'
                \ |   exe 'normal! g`"zz'
                \ | endif
augroup end

Here BufWinEnter is used instead and by its description it is fired when buffer is displayed in a window. I guess displayed is a key here -- vim can't center position for the buffer which is not yet displayed and that might happen with BufReadPost event.

5
  • This is not working for me. Adding zz where you specified does not fix the behavior of it still opening with the last-visited line at the bottom of the screen. Also, worth noting, my line says normal! g'\"" (g apostrophe), whereas yours says normal! g`\"" (g backtick). Not sure if relevant but I thought I'd point it out
    – Drake P
    Jul 9 at 2:19
  • Well, works in my vim
    – Maxim Kim
    Jul 9 at 4:32
  • Please see my edit to the question adding new information. Does this lead to any insights?
    – Drake P
    Jul 9 at 5:37
  • try to figure out whether your if condition is true for the buffers where it doesn't work.
    – Maxim Kim
    Jul 9 at 6:31
  • Ah, the BufWinEnter line works consistently! Thanks for the help :)
    – Drake P
    Jul 9 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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