今回は前回の記事と違い、Neovim 専用の話題です。
Neovim 内の端末で操作しているとき、「このディレクトリーを起点として Vim コマンドを実行したいな」なんて事がよくあります。より具体的には、「カレントディレクトリーを渡して denite を起動したい」と思ったんですね。
いくつか方法はあると思うのですが、これを以下のように実現することを考えました。
- ディレクトリーを移動する度に Neovim にディレクトリー名を通知する。
- zsh の
$chpwd_functions
を使います。 - bash では無理っぽい?1
- 端末内(Terminal-Job モード)で特定のキーを押したら保存したカレントディレクトリー名で denite を起動する。
Neovim の公式 Wiki を見ますととにかくありとあらゆる言語で Neovim を操作出来ることが分かります。今回は(多分)一番メジャーな Python で書いてみました。
Python で Neovim に接続する
neovim-client モジュールを使います。予めインストールしておきましょう。
pip3 install neovim
さて、Neovim への接続には attach
関数を利用します。$NVIM_LISTEN_ADDRESS
という環境変数に Socket ファイルへのフルパスが渡されていますのでこれを使いましょう。
import os
from neovim import attach
nvim = attach('socket', path=os.environ['NVIM_LISTEN_ADDRESS'])
後は command
メソッドで Vimscript を実行出来ます。
nvim.command('let b:__pwd__ = "{}"'.format(os.getcwd()))
これだけです。実際にはディレクトリー名のエスケープや環境変数が設定されていなかったときの対応も必要です。完全版のソースはここに置いています。
後はこの Python スクリプトを zsh に設定するだけです。
neovim-pwd() {
(( $+commands[neovim_pwd.py] )) && neovim_pwd.py
}
if [[ -n $NVIM_LISTEN_ADDRESS ]]; then
neovim-pwd
chpwd_functions+=( neovim-pwd )
fi
このように .zshrc
に追記しておくと、Neovim 内の端末でのみ、カレントディレクトリーを Neovim に通知してくれるようになります。後は Vim 側でこれを使うだけですね。
" ステータスラインにカレントディレクトリーを表示します
tnoremap <A-z><A-z> <C-\><C-n>:echo 'pwd is ' . b:__pwd__<CR>i
noremap <A-z><A-z> :echo 'pwd is ' . b:__pwd__<CR>
" カレントディレクトリーから denite を起動します
tnoremap <A-z><A-n> <C-\><C-n>:call denite#start([{'name': 'file', 'args': ['', b:__pwd__]}])<CR>
noremap <A-z><A-n> :call denite#start([{'name': 'file', 'args': ['', b:__pwd__]}])<CR>
見事、端末内からカレントディレクトリーが通知出来ています。直接 denite も起動可能です。便利ですね。