neovim × neoterm = 最強
vimmerの皆さんこんにちは。
今回はneovimにて実装されたターミナルモードの便利な使い方を紹介していきます。
通常のvimでも、ターミナルコマンドを使うことができましたが、neovimではもうターミナルそのものを使用できるのでとても便利です。
(厳密には違う?かもしれませんが、今の所通常のターミナルとの相違点は無いように感じます)
参考:私が使用している便利なプラグイン一覧
vim とても強力なプラグインたち
neovim × neotermでできること (私がやっていること…)
vimからコマンド1つで
- Python を走らせる
- c++ をコンパイル (cmake)
- texをコンパイル
- catkin_make (ROS) を実行
といった便利なことができます.みなさんもぜひneovimでターミナルモードを使いこなしましょう.
ちなみに,私はvimのnormalモード中で
<Space>p 画面を上下に分割し、下半分にターミナルを出現させ現在編集していたPythonスクリプトを実行。
<Space>c 画面を上下に分割し、下半分にターミナルを出現させROSのcatkin_makeを実行。
という風にキーマッピングをしています。
neotermとは
kassio氏が公開しているneovimのターミナルに関するプラグインです。
kassio/neotermのgithubページはこちら。
https://github.com/kassio/neoterm
例えば、、、こんなことができます。
ターミナルウィンドウの表示に関するマッピング
neotermを入れたら、まずはターミナルウィンドウを表示させたいですよね。
そこで以下のようにマッピングします。
nnoremap <c-t><c-t> :Ttoggle<CR>
tnoremap <c-t><c-t> <C-¥><C-n>:Ttoggle<CR>
割り当てるキーは皆さんのお好みのマッピングにしてもらえば良いのですが、参考までに私は Ctrl + t のダブルタップに割り当てています。
:Ttoggleはneotermのコマンド。ターミナルウィンドウのトグル(on-offの切替)です。
ターミナルモード中はコロンで始まるコマンドは入力できないので、一度 <C-\><C-n> でターミナルモードを抜けてノーマルモードに戻ってから :Ttoggle コマンドを実行します。
ターミナルウィンドウのサイズを変更する
neotermではデフォルトで画面半分のサイズのターミナルウィンドウが出現すると思いますが、変数をイジればお好みのサイズに変更することができます。
let g:neoterm_size = winheight(0)/3
augroup AutoTermHeight
autocmd!
autocmd VimResized * let g:neoterm_size = winheight(0)/3
augroup END
グローバル変数 g:neoterm_size に値を入れることで、ターミナルウィンドウの行数を調節します。
上記例のように、私はターミナルウィンドウのサイズを画面三分の一の高さになるように設定しています。また、オートコマンドで画面がリサイズされる度に g:neoterm_sizeをアップデートしています。
neotermの基本的なコマンド
:Tnew
ターミナルを開くコマンドです。
初期設定では水平方向に画面が分割されるが、設定によっては垂直方向に分割したり、新しいウィンドウで開くこともできるようになります。
Ctrl + dで端末を終了させると自動的に分割されたウィンドウが閉じられます。
:T <command>
ターミナルを開き,コマンドを実行します。
例えば、:T cd ~/Documents など。
nnoremap (keymapping) :T (command)<CR>
nnoremap (keymapping) :T (command)<CR><C-w>j
このようにマッピングすると良いと思います。
2段目は、分割した後にターミナルのウィンドウに移動するバージョンです。ターミナルを水平分割で開いた後もフォーカスは元のウィンドウのままとなるので、<C-w>j でターミナルのウィンドウにフォーカスを移動しています。
どちらが使いやすいかはお好みで。
現在編集しているpythonプロジェクトを走らせる
画面下半分にターミナルウィンドウが出現して、現在編集しているpythonを走らせることができます。
nnoremap @p :T python %<CR><c-w>j
:T
ターミナルを開く。
python %<CR>
pythonを走らせる。(%はカレントファイル名を表します。)
<c-w>j
水平分割で開いた後に、ターミナルにフォーカスを移動。この記述はお好みでどうぞ。
cmakeを走らせる
同様にcmakeを走らせる。
nnoremap @C :T cd %:h && cd ../build && cmake .. && make<CR><c-w>j
:T
ターミナルを開く。
cd %:h
今編集しているファイルがあるフォルダに移動。(%:hで現在開いているファイルのディレクトリを取得できます。)
cd ../build
今いるフォルダからbuildフォルダに移動します。
cmake .. && make
cmakeを実行。
お気づきかもしれませんが,これだと1つ上の階層がプロジェクトのルート(CMakeLists.txtのある場所)だと決め打ちしています.
ちゃんと使えるようにするならCMakeLists.txtのあるディレクトリに移動するシェルを書く必要があるとおもいますが…
catkin_makeを走らせる (ROS)
同様にcatkin_makeを走らせる.
nnoremap <silent> @c :T roscd && catkin_make<CR><c-w>j
:T
ターミナルを開く。
roscd
catkin_wsに移動する。
catkin_make
catkin_makeを実行。
その他
最近は、コマンド1つでgitにpushする機能を割り当てたり、
コマンド1つでTexのコンパイルが実行できるようにしてみたりと、
(日本語の文書作成にvimを使うとは何事か!と突っ込まれそうですが、それでも私はvimを使います。Vim愛。)
ターミナルを用いるショートカットを色々と考えてはvimrcの行数を増やしています。
アイデア次第でNeotermを用いて様々なショートカットが考えられると思います。
dein.tomlでのNeotermの設定
私がdein(プラグイン管理のためのプラグイン)で設定しているtomlファイルを載せておきます。
私が記述している主な設定
- 水平分割でターミナルを開く
- 垂直分割でターミナルを開く
- 新しいタブでターミナルを開く
- 新しいタブでターミナルを複数開く(2×2, 2×3, 2×4)
- CMakeを走らせる
- CatkinMakeを走らせる
- 現在開いているPythonスクリプトを走らせる
- 現在開いているTexをコンパイルする
- Neovimのconfigファイルをアップデート(~/.config/nvim をgit pull)
- 現在開いているファイルを含んだgitディレクトリをコメント付でgit push
一部では、外部シェルスクリプトに依存しているものもありますが。
# neovim terminal plugin
[[plugins]]
repo = 'kassio/neoterm'
hook_add = '''
let g:neoterm_autoinsert = 1
let g:neoterm_autoscroll = 1
" # let g:neoterm_split_on_tnew = 1
let g:neoterm_default_mod = "belowright"
let g:neoterm_size = winheight(0)/3
augroup AutoTermHeight
autocmd!
autocmd VimResized * let g:neoterm_size = winheight(0)/3
augroup END
function! NTermInNewTab()
let l:tmp = g:neoterm_default_mod
let g:neoterm_default_mod = "tab"
Tnew
let g:neoterm_default_mod = l:tmp
endfunction
function! NTermCurrentDir()
let l:cmd = "cd " .expand("%:p:h")
call neoterm#exec({ 'cmd': [ cmd , '' ] })
Topen
endfunction
function! NTermCMake()
let l:cmd = "cd " .expand("%:p:h")
let l:cmd = l:cmd . " && source ~/.config/nvim/scripts/AutoCMake.sh"
call neoterm#exec({ 'cmd': [ cmd , '' ] })
Topen
endfunction
function! NTermCatkinMake()
let l:cmd = "roscd"
let l:cmd = l:cmd . " && catkin_make"
call neoterm#exec({ 'cmd': [ cmd , '' ] })
Topen
endfunction
function! NTermPython( ... )
if expand("%:e") != 'py'
echo '[error] Invalid file extension.'
return
endif
let l:cmd = "python " .expand("%:p")
for arg in a:000
let l:cmd = l:cmd . " " . arg
"let l:cmd.cmd = [ l:cmd.cmd, arg ]
endfor
call neoterm#exec({ 'cmd': [ cmd ] })
"T python l:cmd
Topen
endfunction
function! NTermTexCompile()
if expand("%:e") != 'tex'
echo '[error] Invalid file extension.'
return
endif
let l:cmd = "cd " .expand("%:p:h")
let l:cmd = l:cmd . " && platex " . expand("%:p")
let l:cmd = l:cmd . " && dvipdfmx " . expand("%:p:r") . ".dvi"
call neoterm#exec({ 'cmd': [ cmd , '' ] })
Topen
endfunction
function! GitPush( comment )
let l:cmd = "cd " .expand("%:p:h")
let l:cmd = l:cmd . " && source ~/.config/nvim/scripts/GitPush.sh " . a:comment
call neoterm#exec({ 'cmd': [ cmd , '' ] })
Topen
endfunction
function! UpdateConfig()
let l:cmd = "cd ~/.config/nvim"
let l:cmd = l:cmd . " && git pull"
call neoterm#exec({ 'cmd': [ cmd , '' ] })
Topen
" execute "source ~/.config/nvim/init.vim"
endfunction
function! NTermMulti( v_num, h_num )
let l:tmp = g:neoterm_default_mod
let g:neoterm_default_mod = "tab"
Tnew
" # vertical split
let g:neoterm_default_mod = "vertical"
for i in range( a:h_num - 1 )
Tnew
endfor
" # holizontal split
let g:neoterm_default_mod = "aboveleft"
for i in range( a:h_num )
for i in range( a:v_num - 1 )
Tnew
endfor
" # move to left window
execute "winc l"
endfor
" # move to top-left window
execute "winc t"
let g:neoterm_default_mod = l:tmp
endfunction
function! NTermHolizontalSplit()
let l:tmp = g:neoterm_default_mod
let g:neoterm_default_mod = "aboveleft"
Tnew
let g:neoterm_default_mod = l:tmp
endfunction
function! NTermVerticalSplit()
let l:tmp = g:neoterm_default_mod
let g:neoterm_default_mod = "vertical"
Tnew
let g:neoterm_default_mod = l:tmp
endfunction
nnoremap <silent> <c-t><c-t> :Ttoggle<CR>
tnoremap <silent> <c-t><c-t> <C-\><C-n>:Ttoggle<CR>
nnoremap <c-t><c-h> :call NTermHolizontalSplit()<CR>
nnoremap <c-t><c-v> :call NTermVerticalSplit()<CR>
command! CMake call NTermCMake()
command! CatkinMake call NTermCatkinMake()
command! -nargs=* Python call NTermPython(<f-args>)
"command! -nargs=* Python :T python %:p <f-args>
command! TexCompile call NTermTexCompile()
command! UpdateConfig call UpdateConfig()
command! -nargs=1 GitPush call GitPush(<f-args>)
command! -nargs=+ NTermMulti call NTermMulti(<f-args>)
command! NTermMulti4 call NTermMulti(2,2)
command! NTermMulti6 call NTermMulti(3,2)
command! NTermMulti8 call NTermMulti(4,2)
'''
みなさんもNeotermを用いて便利なショートカットを色々割り当ててみてはいかがでしょう。
それでは。
参考:私が使用している便利なプラグイン一覧
vim とても強力なプラグインたち