Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for cursor position bug after formatting via clang format and undo #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 22 additions & 29 deletions autoload/clang_format.vim
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ function! clang_format#format(line1, line2)
endif
let args .= printf("-assume-filename=%s ", shellescape(escape(expand('%'), " \t")))
let args .= g:clang_format#extra_args
let clang_format = printf("%s %s --", g:clang_format#command, args)
return s:system(clang_format, join(getline(1, '$'), "\n"))
let clang_format = printf("%s %s --", g:clang_format#command, args) . " | " . "tail -n +" . a:line1
return s:system(clang_format, join(getline(1, a:line2), "\n"))
endfunction
" }}}

Expand All @@ -197,34 +197,27 @@ function! clang_format#replace(line1, line2)
let formatted = clang_format#format(a:line1, a:line2)

if s:success(formatted)
try
" Note:
" Replace current buffer with workaround not to move
" the cursor on undo (issue #8)
"
" The points are:
" - Do not touch the first line.
" - Use :put (p, P and :put! is not available).
"
" To meet above condition:
" - Delete all lines except for the first line.
" - Put formatted text except for the first line.
"
let i = stridx(formatted, "\n")
if i == -1 || getline(1) !=# formatted[:i-1]
throw "fallback"
endif

call setreg('g', formatted[i+1:], 'V')
undojoin | silent normal! 2gg"_dG
call setreg('g', formatted, 'V')

silent execute "normal! " . a:line1 . "G"
silent execute "normal! \"_" . (a:line2 - a:line1 + 1) . "dd"

if line('$') == 1 && nextnonblank(1) == 0 && col('$') == 1
"empty buffer case (happens after deletion of the whole
"buffer) => need to place formatted text after current
"line and delete first empty line
silent put g
silent normal! gg"_dd
elseif line('.') != a:line1
"moved one line up after deletion (happens after deletion
"to the end of buffer) => need to placed formatted text
"after current line
silent put g
catch
" Fallback:
" The previous way. It lets the cursor move to the first line
" on undo.
call setreg('g', formatted, 'V')
silent keepjumps normal! ggVG"gp
endtry
else
"normal situation => need to place formatted text before
"current line
silent put! g
endif
else
call s:error_message(formatted)
endif
Expand Down