From c031c7455934330e329c9286cc04175d94b00248 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Yngve=20Lerv=C3=A5g?= Date: Tue, 13 Oct 2015 00:10:50 +0200 Subject: [PATCH] Fixed dsc and csc (fixes #245 and #247) --- autoload/vimtex/change.vim | 106 ++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 18 deletions(-) diff --git a/autoload/vimtex/change.vim b/autoload/vimtex/change.vim index fd0d495..a3a21a4 100644 --- a/autoload/vimtex/change.vim +++ b/autoload/vimtex/change.vim @@ -29,8 +29,8 @@ function! vimtex#change#init_buffer() " {{{1 nnoremap (vimtex-delete-env) \ :call vimtex#change#env('') - nnoremap (vimtex-delete-cmd) vaBom`oxg``xdF\ - \:silent! call repeat#set("\(vimtex-delete-cmd)", v:count) + nnoremap (vimtex-delete-cmd) + \ :call vimtex#change#command_delete() nnoremap (vimtex-change-env) \ :call vimtex#change#env_prompt() @@ -56,32 +56,102 @@ endfunction " }}}1 +function! vimtex#change#get_command(...) " {{{1 + let l:position = a:0 > 0 ? a:1 : searchpos('\S', 'bcn') + let l:line = getline(l:position[0]) + let l:char = l:line[l:position[1]-1] + + for l:syntax in reverse(map(call('synstack', l:position), + \ 'synIDattr(v:val, ''name'')')) + if l:syntax ==# 'texStatement' + let l:p = searchpos('\\', 'bcn') + let l:c = matchstr(l:line, '\\\zs\w\+', l:p[1]-1) + return [l:c] + l:p + elseif l:syntax ==# 'texMatcher' + \ || (l:syntax ==# 'Delimiter' && l:char =~# '{\|}') + let l:curpos = getcurpos() + normal! vaBoh + let l:result = vimtex#change#get_command(searchpos('\S', 'bcn')) + call setpos('.', l:curpos) + return l:result + endif + endfor + + return ['', 0, 0] +endfunction + function! vimtex#change#command() " {{{1 - let pos_save = getpos('.') - let savereg = @a + " Get old command + let [l:old, l:line, l:col] = vimtex#change#get_command() + if l:old ==# '' | return | endif + + " Get new command + let l:new = input('Change ' . old . ' for: ') + let l:new = empty(l:new) ? l:old : l:new + + " Store current cursor position + let l:curpos = getcurpos() + if l:line == l:curpos[1] + let l:curpos[2] += len(l:new) - len(l:old) + endif " This is a hack to make undo restore the correct position normal! ix normal! x - normal! F\lve"ay - let old = @a - - let new = input('Change ' . old . ' for: ') - if empty(new) - let new = old - endif - let pos_save[2] += len(new) - len(old) - - let @a = new - normal! F\lcea - - let @a = savereg - call setpos('.', pos_save) + " Perform the change + let l:tmppos = copy(l:curpos) + let l:tmppos[1:2] = [l:line, l:col+1] + cal setpos('.', l:tmppos) + let l:savereg = @a + let @a = l:new + normal! cea + let @a = l:savereg + " Restore cursor position and create repeat hook + call setpos('.', l:curpos) silent! call repeat#set("\(vimtex-change-cmd)" . new . ' ', v:count) endfunction +function! vimtex#change#command_delete() " {{{1 + " Get old command + let [l:old, l:line, l:col] = vimtex#change#get_command() + if l:old ==# '' | return | endif + + " Store current cursor position + let l:curpos = getcurpos() + if l:line == l:curpos[1] + let l:curpos[2] -= len(l:old)+1 + endif + + " This is a hack to make undo restore the correct position + normal! ix + normal! x + + " Use temporary cursor position + let l:tmppos = copy(l:curpos) + let l:tmppos[1:2] = [l:line, l:col] + call setpos('.', l:tmppos) + normal! de + + " Delete surrounding braces if present + while getline('.')[l:col-1 :] =~# '^\s*{' + normal! f{vaBm`oxg``x + if l:line == l:curpos[1] + let l:curpos[2] -= 1 + if l:curpos[2] < 0 + let l:curpos[2] = 0 + endif + endif + let l:tmppos = getpos('.') + let l:col = l:tmppos[2] + endwhile + + " Restore cursor position and create repeat hook + call setpos('.', l:curpos) + silent! call repeat#set("\(vimtex-delete-cmd)", v:count) +endfunction + function! vimtex#change#close_environment() " {{{1 " Close delimiters let [lnum, cnum] = searchpairpos('\C\\left\>', '', '\C\\right\>', 'bnW',