在LaTeX环境中进行Vim操作

时间:2012-08-06 16:32:59

标签: vim latex

我想知道在使用vim编写代码/乳胶时,当我在某个特定环境中时,如何触发某个动作。例如,假设我正在编写tex并在对齐环境中,那么我希望我输入的每个等号转换为& =。

我现在想的是相当麻烦。这是我的vimrc中的伪代码。这就是它的样子

Shortcut for environment opens start and end tag for align environment (Using imap)
The above action also initiates a counter variable, sets it to 1
If counter is 1, every equals sign I enter should be entered as an &=.
Shortcut to force counter to zero when I move out of the environment. (Using imap)

我想知道是否有更简单的方法来解决这个问题。这只是一个例子。这里的主要想法是让vim具有环境意识。

期待您的建议。

3 个答案:

答案 0 :(得分:2)

事实上,我通常会解决这类问题。例如,我用普通的=符号编写它,然后在视觉上选择该区域并使用:s/=/\&=/g。如果你想在“环境”之后做多件事,你可以创建一个函数并触发一个键来执行它。例如:

vnoremap <leader>la :call <SID>latexAlign()<cr>

function! s:latexAlign() range
  exe ":'<,'>s/=/\&=/g"
  " add more stuff here...
endfunction

但是,我认为您的解决方案会更好,以防您以后再进行编辑。 vim中的htmlcomplete文件处理这种情况:

let stylestart = searchpair('<style\>', '', '<\/style\>', "bnW")
let styleend   = searchpair('<style\>', '', '<\/style\>', "nW")
if stylestart != 0 && styleend != 0
   if stylestart <= curline && styleend >= curline
      let start = col('.') - 1
      let b:csscompl = 1
      while start >= 0 && line[start - 1] =~ '\(\k\|-\)'
         let start -= 1
      endwhile
   endif
endif

您可以看到它如何使用searchpair来确定它是否在<style></style>标记内。有关详细信息,请参阅:help searchpair()

答案 1 :(得分:2)

这是一个非常有趣的问题,但我不确定您建议的方法是最好的方法!我试过一个答案,但第一次迭代可能并不完美。我假设LaTeX环境只是由\begin\end命令分隔(我的LaTeX有点生锈!)。

首先,您需要一个函数来返回光标位置的环境。我的函数跳转到上一个\begin命令,然后跳转到匹配的\end命令,计算光标是否在此区域内,并继续该过程,直到找到包含的环境。它应该处理嵌套环境。如果不在LaTeX环境中,则返回空字符串。

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

现在,您可以使用:echo GetTeXEnv()查询光标的环境。

要更改=键的行为,您需要创建另一个在对齐环境中返回&=的函数,否则=

function! TeXEquals()
    return GetTeXEnv() =~ 'align\*\?' ? "&=" : "="
endfunction

然后,您可以在插入模式下重新映射=(仅适用于TeX文件)

autocmd FileType tex inoremap <silent> = <c-r>=TeXEquals()<CR>

这似乎适用于我的示例LaTeX文件。如果您发现任何问题或有任何改进意见,请告诉我。

答案 2 :(得分:0)

如果您正在寻找“环境意识”,如果您的意思是“我是否在乳胶文件中?”您可以使用autocommand 启用行为。

Vim识别大量文件类型,您可以确保默认识别您正在编辑的文件类型:

:echo &filetype

编辑Python文件时,我得到python。如果你只需要这个用于乳胶,并且你从该Vim变量得到满意的响应,你可以设置一个使用它的autocommand,否则你可以在其中指定扩展,它看起来像这样:

autocmd BufReadPost,BufNewFile,BufEnter *.tex, *.latex call MyFunction()

RedPost,NewFile和Enter是一些可能的Vim互动,当文件扩展名以MyFunction.text结尾时会触发.latex

如果您真正需要的是一些代码示例,它将执行您的描述所述,那么Conner的答案可能更适合。