This is a very interesting question, but I'm not sure if your proposed approach is the best way! I tried to answer, but this first iteration may not be perfect. I assume that the LaTeX environment is simply limited to the \begin and \end commands (my LaTeX is a bit rusty!).
First, you need a function to return the environment to the cursor position. My function below goes to the previous \begin command, and then goes to the corresponding \end command, calculates whether the cursor is inside this area, and continues the process until a containing environment is found. It should handle nested environments. If not in LaTeX, an empty string is returned.
function! GetTeXEnv() let pos = getpos('.') let win = winsaveview() let env = '' let carry_on = 1 let search_ops = 'bWc' let b_start = line('.') while carry_on keepjumps let b_start = search('\\begin{',search_ops) let search_ops = 'bW' " Only accept a match at the cursor position on the " first cycle, otherwise we wouldn't go anywhere! let env = matchstr(getline('.'),'\\begin{\zs.\{-}\ze}') let env_esc = escape(env,'*') keepjumps let b_end = search('\\end{\s*' . env_esc . '\s*}','Wn') if b_start == 0 " finished searching; stop let carry_on = 0 elseif b_end > b_start && b_end < pos[1] " not inside this env; carry on let env = '' elseif b_end > b_start && b_end >= pos[1] && b_start <= pos[1] " found it; stop let carry_on = 0 endif endwhile call setpos('.',pos) call winrestview(win) return env endfunction
Now you can query the cursor environment using :echo GetTeXEnv() .
To change the behavior of the = key, you need to create another function that returns &= in the alignment environment, and = otherwise:
function! TeXEquals() return GetTeXEnv() =~ 'align\*\?' ? "&=" : "=" endfunction
Then you can reassign = in insert mode (only for TeX files)
autocmd FileType tex inoremap <silent> = <cr>=TeXEquals()<CR>
This seems to work in my LaTeX file example. Let me know if you find any problems or any ideas for improvement.
source share