この記事の目標
vim を使って Latex のコードを書く方へ,少しだけ便利な設定を共有します.
\begin{hoge} の文章で改行をしたときに \end{hoge} を補完するように vimrc に設定を追記します.
環境・前提事項
私の VIM は バージョン 8.2.200 です.プラグインは使っていません.
最新バージョンでしか使えない機能など,特別なものは含まれていないと思います.
ただし "\begin{hoge}\begin{fuga}" と一行に複数回 "\begin{}" を登場させる方には,
意図通りの動作にならない可能性が高いです.
実践
vimrc に以下の内容を追記します.
function! s:AutoEndComp()
let l:line_char=getline('.')
if count(l:line_char,"\\begin{")
let l:len=stridx(l:line_char,"}")-(stridx(l:line_char,"\\begin{")+7)
let l:obj_name=strpart(l:line_char,stridx(l:line_char,"\\begin{")+7,l:len)
let l:command="\<CR>\\end{"..l:obj_name.."}\<Esc>O "
call feedkeys(l:command,'n')
else
call feedkeys("\<CR>",'n')
endif
endfunction
inoremap <CR> <C-\><C-O>:call <SID>AutoEndComp()<CR>
解説
改行すると関数 AutoEndComp() が呼び出されます.この関数の大まかなアルゴリズムは以下の通りです.
まず,関数 getline() によりカーソルがある行を抜き出し,文字列変数 line_char に格納します.変数の前にある「l:」はローカル変数であることを明示する接頭辞です.この接頭辞はこちらのページで
接頭辞を関数内で省略した場合は「l:」になる.
と解説されている通り,省略することもできます.
次に関数 count() により文字列変数 line_char に文字列 "\begin{" がいくつ含まれるかを調べます.
ひとつも含まれていない場合は else 節が実行され,通常の改行となります.
ひとつでも含まれている場合は else 前の部分が実行され,以下の処理となります.
- \begin{hoge} の "hoge" の部分の文字数をカウントします.そのために関数 stridx(str, "extr") を使っています.この関数は,文字列変数 str における文字列 "extr" が始まる位置を返します.この関数をうまいこと使い "hoge" の文字数を変数 len に格納します.
- "hoge" の部分の具体的な名前を調べます.そのために関数 strpart(str, "extr", len) を使います.この関数は,文字列変数 str の中で文字列 "extr" が始まる位置から文字数 len だけ文字列を抽出します.抽出した文字列を文字列変数 obj_name に格納します.
- \end{hoge} を補完するために関数 feedkeys() を使用します.第一引数に改行したときの振る舞いを与えます.ここでは見栄えを優先して,文字列変数 command を導入しています.let により文字列を結合する際には,let str=char1..char2のように,ピリオドを二つ使います.
気がついた点,不備などありましたら,ぜひご指摘ください.
(5月9日追記)文字列を結合する方法について
訂正前: let str=char1.char2のように,ピリオドを使います
訂正後: let str=char1..char2のように,ピリオドを二つ使います
文字列の結合はこちらのページで解説されている通り,
ピリオド二つの利用が推奨されていました.
実践に示したソースコードの該当箇所も書き換えました.
@htsign様にご指摘いただきました.改めて感謝します.