Neovim+vimtex+TeXLive2018でTeX環境を作ってみる。

以前に Neovim で \(\rm \LaTeX\) の環境構築をやって、Neovim では Vim にあった "--remote-*" コマンドラインオプションが削除されてしまったために、vimtex での inverse search ができずに挫折していました。
SyncTeX対応のPDFビューワ。でちょっと触れていますが、それを解決するために neovim-remote という Python モジュールを使って、Python インタフェース側から解決しましょうかというのがあったのですが、結局うまく行ってませんでした。

ぼちぼちあれから1年経つので、どうなってるのかな、と。もっとも Visual Studio Code + TeXLive でかなりいい感じの環境が手軽に構築できるので、あとは日本語入力のON/OFFをうまいことやってくれないかな、とかエディタ周りの使用感によって左右されるのかなとは思いますが。

まず、2019年4月5日現在、Neovim v0.4.0-529 には '--remote-*' 系オプションは実装されていないようです。これはすなわち、neovim-remote を使う必要がある、ということでしょう。現在の neovim-remote はバージョン 2.1.7 になっています。

'--remote-*' 系オプションに関する議論は、vimtex の Add support for neovim #262 あたりから始まって、neovim の restore --remote (+clientserver) #1750あたりに展開し、[WIP] Added clientserver --remote #8326あたりで作業に取り掛かっている方がいらっしゃるという状況です。

Neovim(というか nvim)は起動するとサーバソケット(Windowsの場合には名前付きパイプ)をオープンします。:echo v:servername
\\.\pipe\nvim-12345-0'
というような値を返してきます。

neovim-remote は、 'nvr' という実行形式ファイルを使って Neovimのサーバソケットと通信します。vimtex においてこの通信が本当に必要なのは、SyncTeX を利用するときだけです。Neovim から \(\rm \LaTeX\) を起動してコンパイルし、SumatraPDF で表示するだけならばぶっちゃけ不要です。
が、生成された PDF を見て、レイアウトがおかしかったりタイポがあったりしたときに、PDF の該当箇所をクリックすることで TeX 文書の該当箇所にジャンプしてくれる SyncTeX はとても便利です。

というような点を踏まえて、設定してみます。

まずは vimtex の wiki から Neovim のところに最初の設定が書いてあります。
let g:vimtex_compiler_progname = 'nvr'

次に vimtex の doc で、
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_view_general_options
  \ = '-reuse-instance -forward-search @tex @line @pdf'
  \ . ' -inverse-search "gvim --servername ' . v:servername
  \ . ' --remote-send \"^^'
  \ . ':drop \%f^:\%l^:normal\! zzzv^'
  \ . ':execute ''drop '' . fnameescape(''\%f'')^'
  \ . ':\%l^:normal\! zzzv^'
  \ . ':call remote_foreground('''.v:servername.''')^^\""'

となっているところを参照します。これは inverse-search に関する設定で、SumatraPDF に渡すオプションです。逆に言えば、これを設定する前にコマンドプロンプトから SumatraPDF をオプション付きで起動して動作するかどうかを確かめることができます。

なので手順を踏んでやってみます。

まず、あらかじめ TeX ファイルをコンパイルして PDF と SyncTeXファイルを作っておきます。ページ数などがある程度あったほうがいいので、ちょっと長めのファイルを用意します。ここでは TeXLiveに含まれている pxchfon.tex を使います。このパッケージは日本語のフォントを変更するときに必ずお世話になるものですから、PDFを手元に用意しておくのも無駄にはなりませんし。

適当なディレクトリを用意して、pxchfon.tex をダウンロードします。ここでは手動で PDF を作成するので、コマンドプロンプトを開いてそのディレクトリに移動し、latexmk pxchfon と実行します。
pxchfon.tex は uplatex で組版するようになっていますから、必要があれば latexmkrc を別途作成しておきます。
ちなみにうちのは以下のような感じです。
$latex = 'uplatex %O -kanji=utf8 -no-guess-input-enc -synctex=1 -interaction=nonstopmode %S';
$pdflatex = 'pdflatex %O -synctex=1 -interaction=nonstopmode %S';
$lualatex = 'lualatex -cmdx %O -synctex=1 -interaction=nonstopmode %S';
$xelatex = 'xelatex %O -synctex=1 -interaction=nonstopmode %S';
$biber = 'biber %O --bblencoding=utf8 -u -U --output_safechars %B';
$bibtex = 'upbibtex %O %B';
$makeindex = 'upmendex %O -o %D %S';
$dvipdf = 'dvipdfmx %O -o %D %S';
$dvips = 'dvips %O -z -f %S | convbkmk -u > %D';
$ps2pdf = 'ps2pdf.exe %O %S %D';
$pdf_mode = 3;
$pdf_previewer = '"C:/Program Files/SumatraPDF/SumatraPDF.exe" -reuse-instance';

この内容を、%USERPROFILE%\.config\latexmk\latexmkrc に保存しておきます。正確に言えば、latexmk は XDG Base Directory に準拠していますので、$XDG_CONFIG_HOME/latexmk/latexmkrc ということになります。うちでは他のプログラムで参照するものもあるので、環境変数 XDG_CONFIG_HOME を %USERPROFILE%/.config に設定しています。

TeXLive が適切にインストールされて設定されていれば、上記の latexmk で pxchfon.pdf と pxchfon.synctex.gz ができているはずです。

次に、SumatraPDF にパスが通っているかを確認します。Neovim からビューワを起動するときに、パスが通っていないと起動できません。コマンドプロンプトで sumatrapdf pxchfon.pdf として起動します。
また、nvr にパスが通っているかどうかも確認します。コマンドプロンプトで nvr として確認します。パスが通っていなければ Python の Scripts にもパスを通します。

次に、Neovim で pxchfon.tex を開きます。SyncTex の動作確認だけですので vimtex は組み込んでいなくても構いません。

Neovim で :echo v:servername してパイプ名を調べます。ここでは \\.\pipe\nvim-15280-0 という名前が返ってきましたのでこれを控えておきます。

SumatraPDFのオプション設定で、逆順検索コマンドラインを設定します。逆順というよりも逆方向だとは思いますが。
nvr --servername \\.\pipe\nvim-15280-0 --remote-send "%lG"


ここまでやったら、PDFの適当なところでダブルクリックしてみます。
ジャンプしましたか? うちではちゃんとジャンプできました。え? ていうかほんとにジャンプできました。おお、すごい。

ということは、Neovim の vimtex から latexmk でコンパイルして、SumatraPDF で PDF 表示させて、PDF から SyncTeX でソースの該当箇所に飛ぶことができるということですね。

ちなみに上記の nvr でパイプに送りつけているコマンドは、%lG (%l はダブルクリックした箇所の行番号で、Gコマンドで%l行に移動する、というだけ)です。

ということなので、あとは適切に .toml を書いておけばOKとなります。
[[plugins]]
# vimtex: LaTeX documentation support plugin
repo = 'lervag/vimtex'
depends = ['deoplete.nvim']
on_ft = 'tex'
hook_source='''
  if filereadable(expand('~/.config/nvim/vimtex-local.vim'))
    source ~/.config/nvim/vimtex-local.vim
  endif
'''
hook_post_source='''
  let $NVIM_LISTEN_ADDRESS=v:servername
'''
を dein_lazy.toml に、
"scriptencoding utf-8
" vim:set ts=4 sts=2 sw=2 tw=0 fenc=utf-8:

" vimtexの設定
let g:vimtex_view_general_viewer = 'SumatraPDF'
let g:vimtex_compiler_latexmk = {
  \ 'background' : 0,
  \ 'build_dir' : '',
  \ 'continuous' : 0,
  \ 'callback' : 1,
  \ 'executable' : 'latexmk',
  \ 'options' : [
  \   '-verbose',
  \   '-file-line-error',
  \   '-synctex=1',
  \   '-interaction=nonstopmode',
  \ ],
  \}

if has('nvim')
  " if running on Neovim
  let g:vimtex_compiler_progname = 'nvr'
  let g:vimtex_view_general_options
 \ = '-reuse-instance'
 \ . ' -forward-search @tex @line @pdf'
 \ . ' -inverse-search "nvr --servername ' . v:servername
 \ . ' --remote-send \"\%lG\""'
 \ . ' -console'
  let s:sumatra_args='-reuse-instance -inverse-search "nvr --servername ' . v:servername
   \ . ' --remote-send \"\%lG\""'
else
  if has('win32')
 " if running on Vim
 let g:vimtex_compiler_progname = 'c:/Apps/vim80/gvim'
 let g:vimtex_view_general_options = '-reuse-instance -forward-search @tex @line @pdf -inverse-search "c:\Apps\vim80\gvim --remote-silent +\%l \%f " -console'
 let s:sumatra_args='-reuse-instance -inverse-search "gvim --servername ' . v:servername
   \ . ' --remote-send \"\%lG\""'
  endif
endif

function Kick_SumatraPDF()
  execute '!start SumatraPDF' s:sumatra_args expand("%:t:r").'.pdf'
endfunction

nnoremap  :call Kick_SumatraPDF()
~/.config/nvim/vimtex-local.vim に保存します。
これで F8 キーでビューワが開いて逆方向検索もできるようになりました。

ここでは、以前にちゃんとビューワが開けなかったために明示的に Kick_SumatraPDF() という関数を作ってそれを実行させていますが、本来は <localleader>lv (ただし localleader は "\")でビューワが開くマッピングになっています。

簡単にまとめると、
  • \ll : vimtex-compile(コンパイルの実行)
  • \lv : vimtex-view(PDFの表示)
  • \lk : vimtex-stop (コンパイルの中止。ただしWindowsでは効かない)
  • \le : vimtex-errors(quickfixウィンドウの表示)
  • \lg : vimtex-status(コンパイルの状態を表示)
  • \lc : vimtex-clean(中間ファイル類を削除)
  • \li : vimtex-info(vimtexの状態を表示)
などとなっています。

余談ですが、TeXLive 2019 は今月末にリリースのようですね。

0 件のコメント:

コメントを投稿

Windowsでシンボリックリンクを試してみる。

きっかけは、1つのファイルを別の名前で起動したら違う動きになるようなスクリプトを書く、でした。  busybox なんかでは、同じ実行形式ファイルの名前を、lsにすればlsと同じ、cpとすればcpと同じ動作をするようにしてますが、Pythonスクリプトでそれと同じように argv...