2012-08-06 32 views
6

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

我现在想的是相当麻烦。这是我的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具有环境意识。

期待您的建议。

+0

我已经编辑了标题来指定LaTeX,否则这将是一个非常宽泛的问题。检测代码环境的方法在不同的语言中会有很大的不同。 – 2012-08-06 19:18:53

回答

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()

+0

嗨,对不起,很大的延迟。我有很多工作要做,并且陷入困境。 这不是我正在寻找的。一旦我完成了代码,我不想改变。我想让它知道我在里面。不过,我从你的回答中学到了很多东西,非常感谢。 – WiFO215 2012-08-27 12:48:23

0

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

Vim认识了丰富的文件类型,你可以通过做确保您正在编辑的文件类型,默认情况下认可:

:echo &filetype 

当编辑Python文件,我得到python结果。如果您需要这个只有乳胶和你从Vim的变量一个满意的答复,您可以设置使用,一个autocommand,否则,你可以指定它的扩展,它应该是这样的:

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

在哪里在RedPost,NEWFILE和输入是一些可能的Vim的相互作用将触发MyFunction当文件扩展名的.text.latex结束

如果你真正需要的是一些代码示例,会做什么你描述的状态,那么也许康纳的答案更适合。

+2

通过“环境”,海报意味着由语法确定的LaTeX文件的特定区域,而不是文件类型。 – 2012-08-06 18:43:46

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文件中工作。如果您发现任何问题或有任何改进想法,请告知我们。