2012-08-06 67 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文件中工作。如果您發現任何問題或有任何改進想法,請告知我們。