I am trying to implement a way to get automatic completion when typing Latex environments. Consider the following situation:
\begin{|}
\end{}
where |
stands for the position of the cursor. Then I type the name of the environment, say tabular
and press Enter
and I would like it to automatically fill the brackets after \end
.
I originally thought of using double cursors but then I read the plugins for multiple cursors are not so sturdy. By the way, is it really so?
Regardless, I came up with the following solution. I have a plugin (namely quicktex) that allows me to enter some keys in insert mode and substitute them with arbitrary commands, so I set <Space><Space>
to be replaced by
"\\begin{}\<CR>\\end{}\<CR><++>\<ESC>2?}\<CR>:call InEnv(1)\<CR>i"
and I put the following code in my tex.vim
file:
" Am I in environment mode?
let s:env = 0
" Enter/exit environment mode
function! InEnv(on)
let s:env = a:on
if a:on ==? 1
inoremap <CR> <ESC>:call BuildEnv()<CR>A<CR>
elseif a:on ==? 0
iunmap <CR>
endif
endfunction
" Finds out the length of the environment name (when cursor is inside the brackets relative to \begin)
function! EnvNameLength()
call search("}", "cz")
execute "normal! h"
let s:end = col(".")
call search("{", "b")
return s:end - col(".")
endfunction
" Copies environment name and pastes it
function! CopyEnvName()
let s:len = EnvNameLength()
execute "normal! lv" . (s:len-1) . "ly"
call search("end{", "e")
execute "normal! p"
endfunction
" Builds environment
function! BuildEnv()
if s:env ==? 1
call CopyEnvName()
call search("begin", "b")
endif
call InEnv(0)
endfunction
This works perfectly but I feel it's a bit clumsy because of the continuous mapping/unmapping of the <CR>
key. I would like to avoid remapping any keys. Is there any way to accomplish that?