Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to go to the last edit location across all buffers in vim?

Tags:

vim

It is easy to go to the last edit location in the current buffer. See How to go back to lines edited before the last one in Vim? The changelist is buffer local, each buffer has it's own changelist. However it is very common that I navigate away from that recently edited buffer to an other buffer, and it would be nice to somehow get back to the last edit location in the original buffer. Is there a way to go back to the place where the last insert or modify has happened?

like image 533
Gabor Marton Avatar asked Jan 18 '15 20:01

Gabor Marton


People also ask

How do I close all buffers in vim?

The pipes ( | ) break the string into three commands: %bd – Deletes all open buffers ( bd is short for bdelete ) e# – Opens the last buffer ( e is short for edit ) bd# – Deletes the [No Name] buffer that gets created.

How does the vi editor use buffers?

Whenever you delete something from a file, vi keeps a copy in a temporary file called the general buffer. You can also delete or copy lines into temporary files called named buffers that will let you reuse those lines during your current vi work session.

How do I go back in Gvim?

Remember, yo undo a change in Vim / Vi use the command u , and to redo a change which was undone use Ctrl-R .

How do I navigate buffers in vim?

Pressing Alt-F12 opens a window listing the buffers, and you can press Enter on a buffer name to go to that buffer. Or, press F12 (next) or Shift-F12 (previous) to cycle through the buffers.


2 Answers

You can put the following in your vimrc

autocmd InsertLeave * execute 'normal! mI'

and press `-I to jump back to the position where you left your Insert mode. Since I is an uppercase, it works across buffers.


Addendum (after the comment)

After reading @Garbor Marton's comment,

I wrote a function myself

let g:detect_mod_reg_state = -1
function! DetectRegChangeAndUpdateMark()
    let current_small_register = getreg('"-')
    let current_mod_register = getreg('""')
    if g:detect_mod_reg_state != current_small_register || 
                \ g:detect_mod_reg_state != current_mod_register
        normal! mM
        let g:detect_mod_reg_state = current_small_register
    endif
endfunction

" Mark I at the position where the last Insert mode occured across the buffer
autocmd InsertLeave * execute 'normal! mI'

" Mark M at the position when any modification happened in the Normal or Insert mode
autocmd CursorMoved * call DetectRegChangeAndUpdateMark()
autocmd InsertLeave * execute 'normal! mM'

I liked using the original I register specifically for the insert mode change, so here I use a M register for any modification including r,x,d,y AND last insert mode.

like image 137
Alby Avatar answered Oct 19 '22 16:10

Alby


You could do :windo normal`.

That said, I usually just use C-o (repeatedly).

If I "feel" that I will likely want to return to some point, I'll just hit mA (which records a cross-file/buffer mark) so I can just do `A from anywhere (even after restarting the editor).


Slightly off-topic, I love :Obsession (by Tim Pope) for really long-lived sessions that do a lot of cross-reference navigation.

like image 44
sehe Avatar answered Oct 19 '22 18:10

sehe