LaTeX-suite じゃない vim-latex を使ってvimによるLaTeX作成環境を整える
2017-1-7 追記 このページに今でも検索から辿り着く方がいるようなので追記. 以下で説明しているvim-latexですが,Latex-Suiteと名前が被っているということで2015年3月にvimtexに名称が変わりました.
それに伴い変数のprefixがg:latex_... = ...
から g:vimtex_... = ...
に変更されています.
他にもいろいろと機能が追加・更新されていますので,使用する際はhelpの一読をお勧めします.
どうでもいい話
vimでのLaTeX文章作成を補助するプラグインとして,代表的なものに LaTeX-suite a.k.a. Vim-LaTeXがあります. 自分も遥か前にこんな記事を 書いてしばらく使っていたんですが,いかんせんLaTeX-suiteは巨大すぎて, 何をやっているのかよく分からないとこも多かったため,結局使わなくなってしまいま した.
それからは自分があまりプラグインを使用しない派になったこともあって,特に何も使わ ずにtexを書いていましたが,最近emacsにAUCTeX というものがあることを知りました. AUCTeXで羨ましいなと思ったのは, 数式のプレビュー機能です. vimではこんな風に画像は扱えないのでtexを書くときだけemacsを使おうかなと思っちゃ うぐらい魅力的でした.実際Evilを使って Emacsを試してみたんですが,自分には半日と持ちませんでした..
で,数式のプレビューとは言わなくてもtex文章作成は時間がかかるので,やっぱり何か 良いプラグインが無いかなと思って久しぶりに探してみ たところ, https://github.com/lervag/vim-latex を発 見しました.
本題
名前が紛らわしいですが,LaTeX-suiteではないvim-latexというものがあります (以下でvim-latexといったらこのプラグンのことです).
https://github.com/lervag/vim-latex
vimでLaTeX文章作成をサポートするためのプラグインです.主な機能としては,
などがあります.インストール方法はgithubのドキュメントに書いてあるとおりです. このプラグインは自分で設定が変更しやすくなっていますし,プラグイン自体も読みやす いと思います.また,ヘルプがしっかりしている点も良いです.
ちなみに,tex自体の補完やスニペットを使いたいという場合は,何か別のプラグイン (例えばneocomplete, ultisnips, neosnippet, emmet-vimなど)を使うことになります.
また,自分は使ったことがありませんが他のLaTeX用プラグインとしては LaTeX-Boxなどもあります.
基本的な使い方
vim-latexはhelpが充実していますので,とりあえずヘルプを読みましょう.
なんでもいいから設定例が知りたいという場合はこの文章の末尾に自分の設定例がありま す.
代表的なコマンド / マッピング
いろいろコマンドやマッピングがありますが,とりあえずよく使いそうなもの
コマンド(()内はデフォルトマッピングです)
VimLatexHelp
(<localleader>lh
) : vim-latex関連の現在のマッピング設定が表示されます.VimLatexStatus
(<localleader>lg
) : latxmkのステータス(実行中かどうかなど)を表示VimLatexStop
(<localleader>lk
) : 現在のバッファのlatexmkを停止しますVimLatexClean
(<localleader>lc
) :latexmk -c
を使ってファイルを削除します.VimLatexCompileToggle
(<localleader>lc
) : latexmk を使ってファイルをコンパイル / 停止VimLatexErrors
(<localleader>le
) : コンパイル時のエラーをquickfixに表示VimLatexOutput
(<localleader>lo
) : コンパイルの出力を表示VimLatexTocOpen
(<localleader>lt
) : アウトラインの表示VimLatexView
(<localleader>lv
) : ビューワを用いて生成したファイルを開く
オペレータ
a$
/i$
: $..$ 内を選択ae
/ie
: environmentを選択ad
/id
: delimiterを選択[[
/]]
: セクション開始位置 / セクション終了位置まで選択
その他主要マッピング
[[
/]]
(normal mode) : 前のセクション / 次のセクションに移動%
(normal mode) : begin / end 間の移動dse
(normal mode) : 現在のenvironmentを削除しますcse
(normal mode) : 現在のenvironmentを変更します(プロンプトが出る)tse
(normal mode) : 現在のenvironmentの*をトグルしますks]]
(insert mode) : environmentを閉じます<C-x><C-o>
(insert mode) : \refや\citeを入力中の場合補完します
基本的な使い方としては<localleader>ll
でtexファイルをコンパイル,
<localleader>le
や<localleader>lo
で出力をチェックし,
<localleader>lv
でビューワで確認といった感じになると思います.
ちなみにlocalleaderのデフォルトはバックスラッシュだと思います.
自分で変更したい場合は.vimrcでlet maplocalleader = "\<Space>"
とかすればできま
す.
latexmkによるコンパイル
latexmkというのは platex hoge.tex && platex hoge.tex && dvipdfmx hoge
みたいな
処理を自動でおこなってくれるコマンドです.TexLive等でインストールすれば最初から
使えます.vim-latexではこのlatexmkを使ってtex文章のコンパイルをおこないます.
latexmkを使用する場合には,latexmk用の設定ファイルが必要です.
unix系なら~/.latexmkrcに以下のようなファイルを作っておきます
$latex='platex -kanji=utf8 -guess-input-enc -synctex=1 -interaction=nonstopmode %S'; $dvipdf='dvipdfmx %S'; $bibtex='pbibtex -kanji=utf8 %B';
platexのsynctex=1のオプションは後述するSyncTeXを使用するのに必要です.
さて,以上のように設定すると,あるTeX文章があったときにlatexmk -pdfdvi
hoge.tex
とすればplatex hoge && dvipdfmx hoge
としてpdfを生成してくれます.
latexmkのオプションは以下のように.vimrcに設定します.
let g:latex_latexmk_options = '-pdfdvi'
texファイルが分割されている場合
texファイルを\input{}命令を使って分割するということがあると思います. vim-latexではそのような場合に最初から対応していて,再帰的に親ディレクトリ を遡って親のtexファイルを探してくれます.特に何か設定する必要はありません.
つまり,例えば以下のような構成に対応できます.
main.tex
chapter1/chapter1.tex
chapter2/chapter2.tex
...
main.tex内で\input{}命令を使ってchapter1/chapter1.texなどを取り込みます. ただし,以下のような場合は駄目です.
a/main.tex
b/chapter1.tex
このようなファイル構成に対応したい場合はtexファイルの先頭に%! TEX root =
/path/to/main.tex
のように記述します.
自動コンパイル
g:latex_latexmk_continuous
を1に設定し,:VimLatexCompileToggle
(<localleader>ll
)をすると,ファイルが上書きされると自動的にlatexmkを実行す
るようになります(停止する場合は再び:VimLatexCompileToggle
).この場合自動更新に
対応しているビューワを使うとさらに便利です.ただし,大きいファイルを編集している場合には
この機能はオフにした方がいいかもしれません.
この機能を使用するためには+clientserver機能のあるvimが必要です.端末のvimで実行 すると自動的にgvimが起動します.
自動コンパイルをおこなうプラグインとしてはvim-latex-live-preview などがありますが,こちらは+pythonが必要です.
\refや\citeの補完
\refや\citeを入力中に<C-x><C-o>
を押すと適当に補完してくれます.
bibtexにも対応しています.ただ補完時に候補を集めるため\citeはちょっと重いです.
アウトライン表示
:VimLatexTocOpen
(<localleader>lt
) を実行すると,現在編集中のファイルのア
ウトラインを表示してくれます.ファイルが分割されていてもokです.
ビューワの設定
使用するビューワは以下のように設定します.今自分の作業PCはMacなので Skimを 指定しています.
let g:latex_view_method = 'general' let g:latex_view_general_viewer = '/Applications/Skim.app/Contents/MacOS/Skim'
:VimLatexView
をしたとき,コンパイルしたファイルと同名のpdfファイルがあれば
pdfファイルを,dviファイルがあればdviファイルを開きます.
折り畳み
vim-latexにはfoldの設定ファイルがついてきます. vimのfoldのキーマッピングはいろ
いろありますが,とりあえずzR
で全ての折りたたみを展開,zM
で全ての折りたたみ
を閉じます. 折りたたみをオフにしたい場合にはlet g:latex_fold_enabled = 0
とし
ます.
SyncTexの設定
SyncTex という機能を使うと,ソースコードと生成したfファイルの位置の対応付けをお こなうことができるようになります.SyncTexを使う場合にはlatexmkのオプションで指定 します.
pdfファイルでSyncTeXが使えるかどうかはビューワによります. MuPDF, SumatraPDF, okular, SkimなどがSyncTexに対応しています.
試してないですがvim-latexはMuPDF, SumatraPDFにデフォルトで対応しているようです. また,helpにokularの設定例が載っています.
Skimの場合以下のようにすれば<localleader>ls
でSyncTeXを使ってカーソル位置
の文章を検索ができます.
function! s:syncTexForward() call system('/Applications/Skim.app/Contents/SharedSupport/displayline -g ' \ . line(".") . " " \ . g:latex#data[b:latex.id].out() . " " \ . expand('%:p')) endfunction autocmd FileType tex \ nnoremap <buffer> <localleader>ls :call <SID>syncTexForward()<CR>
TeXの一部分だけプレビューする
.vimrcに以下のように設定して,ビジュアルモードでプレビューしたい部分を選択して
<localleader>la
とすれば一部分だけプレビューできるようになります
(Windowsの場合は最後のsystem部分を適当に変更する必要があります).
function! s:previewTex() range let l:tmp = @@ silent normal gvy let l:selected = split(@@, "\n") let @@ = l:tmp let l:template1 = ["\\documentclass[a4paper]{jsarticle}", \"\\usepackage[dvipdfmx]{graphicx}", \"\\usepackage{amsmath,amssymb,bm}", \"\\pagestyle{empty}", \"\\begin{document}"] let l:template2 = ["\\end{document}"] let l:output_file = "preview.tex" call writefile(extend(extend(l:template1, l:selected), template2), l:output_file) silent call system("latexmk -pdfdvi preview &") endfunction autocmd FileType tex \ nnoremap <buffer> <localleader>la :call latex#motion#next_section(0,1,0)<CR>v:call latex#motion#next_section(0,0,1)<CR>:call <SID>previewTex()<CR> \ | vnoremap <buffer> <localleader>la :call <SID>previewTex()<CR>
やっていることは単純で,選択範囲をもとにpreview.texを作成して,それをコンパイル
します.また,上の例ではvim-latexの関数を使って,ノーマルモードで
<localleader>la
を実行した場合現在のセクションをプレビューします.
AUCTeXのように数式を画像で置き換えるということはできませんが,自動更新のある ビューワを使ってpreview.pdfを表示させておくとまぁ便利なんじゃないかと思います.
設定例
自分の設定は以下のようになっています.一部デフォルト設定を明示的に記述していま す.ビューワ等はMac用の設定になっていますので,他環境で使用する場合には適当に 変更が必要です.
なお,vim-latexは2014年現在でも活発に開発が行われていますので,オプション名が変 更あるいは追加される可能性は十分あります.
augroup MyAutoCmd autocmd! augroup END let g:latex_latexmk_enabled = 1 let g:latex_latexmk_options = '-pdfdvi' let g:latex_view_method = 'general' "let g:latex_view_general_viewer = 'open' let g:latex_view_general_viewer = '/Applications/Skim.app/Contents/MacOS/Skim' " fold let g:latex_fold_parts = [ \ "appendix", \ "frontmatter", \ "mainmatter", \ "backmatter", \ ] let g:latex_fold_sections = [ \ "part", \ "chapter", \ "section", \ "subsection", \ "subsubsection", \ ] let g:latex_fold_enabled = 1 let g:latex_fold_automatic = 1 let g:latex_fold_envs = 0 " 自動コンパイル let g:latex_latexmk_continuous = 1 let g:latex_latexmk_background = 1 " コンパイル終了後のエラー通知オフ let g:latex_latexmk_callback = 0 let g:latex_toc_split_pos = "topleft" let g:latex_toc_width = 10 " SyncTex function! s:syncTexForward() call system('/Applications/Skim.app/Contents/SharedSupport/displayline -g ' \ . line(".") . " " \ . g:latex#data[b:latex.id].out() . " " \ . expand('%:p')) endfunction " Preview function! s:previewTex() range let l:tmp = @@ silent normal gvy let l:selected = split(@@, "\n") let @@ = l:tmp let l:template1 = ["\\documentclass[a4paper]{jsarticle}", \"\\usepackage[dvipdfmx]{graphicx}", \"\\usepackage{amsmath,amssymb,bm}", \"\\pagestyle{empty}", \"\\begin{document}"] let l:template2 = ["\\end{document}"] let l:output_file = "preview.tex" call writefile(extend(extend(l:template1, l:selected), template2), l:output_file) silent call system("latexmk -pdfdvi preview &") endfunction autocmd MyAutoCmd FileType tex \ nnoremap <buffer> <Space>la :call latex#motion#next_section(0,1,0)<CR>v:call latex#motion#next_section(0,0,1)<CR>:call <SID>previewTex()<CR> \ | vnoremap <buffer> <Space>la :call <SID>previewTex()<CR> \ | nnoremap <buffer> <Space>ls :call <SID>syncTexForward()<CR> " for neocomplete if !exists('g:neocomplete#sources#omni#input_patterns') let g:neocomplete#sources#omni#input_patterns = {} endif let g:neocomplete#sources#omni#input_patterns.tex = '\\ref{\s*[0-9A-Za-z_:]*' "\citeも自動補完するなら "let g:neocomplete#sources#omni#input_patterns.tex = '\\cite{\s*[0-9A-Za-z_:]*\|\\ref{\s*[0-9A-Za-z_:]*'
自分はなるべく.vimrcに書く派なのでtex filetype用のマッピングをautocmdで色々設定 していますが,それが嫌な人は vim/after/filetype/tex.vimとかに書くといいんじゃないで しょうか.
2017-1-7 追記 今自分は以下のように設定しています.
let g:tex_flavor = "latex" let g:vimtex_latexmk_enabled = 1 let g:vimtex_latexmk_options = '-pdfdvi' let g:vimtex_view_method = 'general' let g:vimtex_view_general_viewer \ = '/Applications/Skim.app/Contents/SharedSupport/displayline' let g:vimtex_view_general_options = '-r @line @pdf @tex' let g:vimtex_latexmk_callback_hooks = ['UpdateSkim'] function! UpdateSkim(status) if !a:status | return | endif let l:out = b:vimtex.out() let l:tex = expand('%:p') let l:cmd = [g:vimtex_view_general_viewer, '-r'] if !empty(system('pgrep Skim')) call extend(l:cmd, ['-g']) endif if has('nvim') call jobstart(l:cmd + [line('.'), l:out, l:tex]) elseif has('job') call job_start(l:cmd + [line('.'), l:out, l:tex]) else call system(join(l:cmd + [line('.'), shellescape(l:out), shellescape(l:tex)], ' ')) endif endfunction let g:vimtex_latexmk_continuous = 1 let g:vimtex_latexmk_background = 1 let g:vimtex_latexmk_callback = 1 let g:vimtex_toc_split_pos = "topleft" let g:vimtex_toc_width = 10 " for neocomplete if !exists('g:neocomplete#sources#omni#input_patterns') let g:neocomplete#sources#omni#input_patterns = {} endif let g:neocomplete#sources#omni#input_patterns.tex = '\\ref{\s*[0-9A-Za-z_:]*' let g:neocomplete#sources#omni#input_patterns.tex = '\\cite{\s*[0-9A-Za-z_:]*\|\\ref{\s*[0-9A-Za-z_:]*'