我想知道在使用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具有环境意识。
期待您的建议。
答案 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的答案可能更适合。