rhysd/vim-clang-format

last edit mark is tampered after ClangFormat

shreejun opened this issue · 3 comments

Select a line in visual mode and do :ClangFormat. It formats only the selected line as expected. Move around the cursor to other lines, and then press `. in order to jump to the line formatted earlier. It jumps to the end of the file instead.

I'm facing this same issue when enabling the option that automatically formats upon leaving insert mode (g:clang_format#auto_format_on_insert_leave). In such cases, I often navigate away and then want to come back to that last edit using "g;", but it instead brings me to the end of the file.

In short, it seems like running any of these clang-format commands (automatically or manually) pollutes the vim change list, when I would prefer it didn't. (I'm guessing (pure speculation) that these commands overwrite the entire buffer with one that is equivalent everywhere except where you asked for formatting, which would cause vim to add an entry to its change list pointing at the last line of the file).

I think we need to use the builtin ":keepjumps" command somehow to achieve what we want.

See here:
https://stackoverflow.com/questions/17431246/prevent-vim-from-remembering-a-change

I think I figured out how to fix this issue:

In this function:

function! clang_format#replace_ranges(ranges, ...) abort

I added the "keepjumps" keyword to two nearby commands that edit the file (as shown below):

Before:

    if line('$') > len(splitted)
        execute len(splitted) .',$delete' '_'
    endif
    call setline(1, splitted)

After:

    if line('$') > len(splitted)
        execute 'keepjumps' . len(splitted) .',$delete' '_'
    endif
    keepjumps call setline(1, splitted)

This appears to give the desired result in both my scenario and the scenario posted by shreejun.