6

vimを使用してコード/ラテックスを書いているときに、特定の環境内にいるときに特定のアクションをトリガーする方法を知りたいです。たとえば、tex を書いていて align 環境の中で、入力するすべての等号を &= に変換したいとします。

私が今考えていることは、かなり面倒です。これは、私の 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 が環境を認識できるようにすることです。

あなたの提案を楽しみにしています。

4

3 に答える 3

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

キーの動作を変更するには、align 環境で=戻る別の関数を作成する必要があります。&==

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

次に、挿入モードで再マップ=できます (TeX ファイルのみ)。

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

これは、サンプルの LaTeX ファイルで機能するようです。問題が見つかった場合、または改善のアイデアがあればお知らせください。

于 2012-08-06T18:33:10.790 に答える
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

<style></style>検索ペアを使用して、タグ内にあるかどうかを判断する方法を確認できます。詳細については、を参照:help searchpair()してください。

于 2012-08-06T17:12:15.177 に答える
0

あなたが「環境意識」を探しているなら、それが「私はラテックスファイルにいますか?」という意味なら。で動作を有効にすることができますautocommand

Vim は豊富なファイル タイプを認識します。編集中のファイル タイプがデフォルトで認識されるようにするには、次のようにします。

:echo &filetype

Pythonファイルを編集するpythonと、結果として得られます。これが latex のみに必要で、その Vim 変数から満足のいく応答が得られる場合はautocommand、それを使用する を設定できます。それ以外の場合は、拡張子を指定できます。次のようになります。

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

RedPost、NewFile、Enter は、ファイルMyFunction拡張子が.text.latex

あなたが本当に必要としているのが、あなたの説明が述べていることを実行するコード例である場合、おそらくコナーの答えがより適しています。

于 2012-08-06T18:28:02.863 に答える