" LaTeX plugin for Vim " " Maintainer: Karl Yngve LervÄg " Email: karl.yngve@gmail.com " function! latex#change#init(initialized) " {{{1 if g:latex_mappings_enabled nnoremap dse :call latex#change#env('') nnoremap cse :call latex#change#env_prompt() nnoremap dsc vaBom`oxg``xdF\ nnoremap csc :call latex#change#command() nnoremap tse :call latex#change#toggle_env_star() nnoremap tsd :call latex#change#toggle_delim() nnoremap :call latex#change#to_command()i inoremap =latex#change#to_command() inoremap ]] =latex#change#close_environment() endif endfunction function! latex#change#command() " {{{1 let pos_save = getpos('.') let savereg = @a " 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) endfunction function! latex#change#close_environment() " {{{1 " Close delimiters let [lnum, cnum] = searchpairpos('\C\\left\>', '', '\C\\right\>', 'bnW', \ 'latex#util#in_comment()') if lnum > 0 let line = strpart(getline(lnum), cnum - 1) let bracket = matchstr(line, '^\\left\zs\((\|\[\|\\{\||\|\.\)\ze') for [open, close] in [ \ ['(', ')'], \ ['\[', '\]'], \ ['\\{', '\\}'], \ ['|', '|'], \ ['\.', '|'], \ ] let bracket = substitute(bracket, open, close, 'g') endfor return '\right' . bracket endif " Close environment let env = latex#util#get_env() if env == '\[' return '\]' elseif env == '\(' return '\)' elseif env != '' return '\end{' . env . '}' endif endfunction function! latex#change#delim(open, close) " {{{1 let [d1, l1, c1, d2, l2, c2] = latex#util#get_delim() let line = getline(l1) let line = strpart(line,0,c1 - 1) . a:open . strpart(line, c1 + len(d1) - 1) call setline(l1, line) if l1 == l2 let n = len(a:open) - len(d1) let c2 += n let pos = getpos('.') let pos[2] += n call setpos('.', pos) endif let line = getline(l2) let line = strpart(line,0,c2 - 1) . a:close . strpart(line, c2 + len(d2) - 1) call setline(l2, line) endfunction function! latex#change#env(new_env) " {{{1 let [env, l1, c1, l2, c2] = latex#util#get_env(1) if a:new_env == '' let beg = '' let end = '' elseif a:new_env == '\[' || a:new_env == '[' let beg = '\[' let end = '\]' elseif a:new_env == '\(' || a:new_env == '(' let beg = '\(' let end = '\)' else let beg = '\begin{' . a:new_env . '}' let end = '\end{' . a:new_env . '}' endif let n1 = len(env) - 1 let n2 = len(env) - 1 if env != '\[' && env != '\(' let n1 += 8 let n2 += 6 endif let line = getline(l1) let line = strpart(line, 0, c1 - 1) . l:beg . strpart(line, c1 + n1) call setline(l1, line) let line = getline(l2) let line = strpart(line, 0, c2 - 1) . l:end . strpart(line, c2 + n2) call setline(l2, line) endfunction function! latex#change#env_prompt() " {{{1 let new_env = input('Change ' . latex#util#get_env() . ' for: ', '', \ 'customlist,' . s:sidwrap('input_complete')) if empty(new_env) return else call latex#change#env(new_env) endif endfunction function! latex#change#to_command() " {{{1 " Get current line let line = getline('.') " Get cursor position let pos = getpos('.') " Return if there is no word at cursor if mode() == 'n' let column = pos[2] - 1 else let column = pos[2] - 2 endif if column <= 1 || line[column] =~ '\s' return '' endif " Prepend a backslash to beginning of the current word normal! B let column = getpos('.')[2] if line[column - 1] != '\' let line = strpart(line, 0, column - 1) . '\' . strpart(line, column - 1) call setline('.', line) endif " Append opening braces to the end of the current word normal! E let column = getpos('.')[2] let pos[2] = column + 1 if line[column - 1] != '{' let line = strpart(line, 0, column) . '{' . strpart(line, column) call setline('.', line) let pos[2] += 1 endif " Restore cursor position call setpos('.', pos) return '' endfunction function! latex#change#toggle_delim() " {{{1 " " Toggle \left and \right variants of delimiters " let [d1, l1, c1, d2, l2, c2] = latex#util#get_delim() if d1 == '' return 0 elseif d1 =~ 'left' let newd1 = substitute(d1, '\\left', '', '') let newd2 = substitute(d2, '\\right', '', '') elseif d1 !~ '\cbigg\?' let newd1 = '\left' . d1 let newd2 = '\right' . d2 else return endif let line = getline(l1) let line = strpart(line, 0, c1 - 1) . newd1 . strpart(line, c1 + len(d1) - 1) call setline(l1, line) if l1 == l2 let n = len(newd1) - len(d1) let c2 += n let pos = getpos('.') let pos[2] += n call setpos('.', pos) endif let line = getline(l2) let line = strpart(line, 0, c2 - 1) . newd2 . strpart(line, c2 + len(d2) - 1) call setline(l2, line) endfunction function! latex#change#toggle_env_star() " {{{1 let env = latex#util#get_env() if env == '\(' return elseif env == '\[' let new_env = equation elseif env[-1:] == '*' let new_env = env[:-2] else let new_env = env . '*' endif call latex#change#env(new_env) endfunction function! latex#change#wrap_selection(wrapper) " {{{1 keepjumps normal! `>a} execute 'keepjumps normal! `o\end{' . env . '}' execute 'keepjumps normal! ` normal! gvgq endif else execute 'keepjumps normal! `>a\end{' . env . '}' execute 'keepjumps normal! `'), '\zs\d\+_\ze.*$') function! s:input_complete(lead, cmdline, pos) " {{{1 let suggestions = [] for entry in g:latex_complete_environments let env = entry.word if env =~ '^' . a:lead call add(suggestions, env) endif endfor return suggestions endfunction function! s:search_and_skip_comments(pat, ...) " {{{1 " Usage: s:search_and_skip_comments(pat, [flags, stopline]) let flags = a:0 >= 1 ? a:1 : '' let stopline = a:0 >= 2 ? a:2 : 0 let saved_pos = getpos('.') " search once let ret = search(a:pat, flags, stopline) if ret " do not match at current position if inside comment let flags = substitute(flags, 'c', '', 'g') " keep searching while in comment while latex#util#in_comment() let ret = search(a:pat, flags, stopline) if !ret break endif endwhile endif if !ret " if no match found, restore position call setpos('.', saved_pos) endif return ret endfunction " }}}1 " vim: fdm=marker sw=2