Help us understand the problem. What is going on with this article?

Vim でテストコード書きながらその場でテスト流すのを tmux の send-keys で超快適にやる

More than 3 years have passed since last update.

Vim でテストコードを書きながら、Vim を抜けずその場でそのファイルとかその行のテストを流したい

send-keys.gif

そういうとき Emacs とか Atom だとプラグインでやってたけど、いまいち Vim だとそういうやり方がしっくりこないなと思っていたところで「もう tmux で別ペイン開いといて send-keys するのでいいのでは」という結論になった。

この方法だとテストの種類によって変えるのも実行コマンドを変えるだけで簡単にできるし、実際にテストを流すのが Docker コンテナの中、とかいうときにもそのまま応用できるのでなかなかよい。

具体的にどういうことができるかというと、これから書く例では、tmux を左右の2ペインに分割しておいて、

  • 左ペインに Vim
  • 右ペインにテストコマンドを実行したい場所

が設定された状態で、Vim でテストコードを書きながら右ペインでテストを実行するというもの。

send-keys を実行するスクリプト

まずは send-keys を実行するスクリプトを用意する。

tmux-send-keys-to-right-pane

#!/usr/bin/env sh

session=$(tmux display-message -p '#S')
window=${session}:$(tmux display-message -p '#I')

args=""

for arg in $@; do
  args="${args}""${arg} "
done

tmux send-keys -t right C-z "${args}" C-m

かなり雑だけどこんな感じとか。

これに実行権限をつけてパスの通るところに置くなりした上で、tmux のウィンドウ上で右ペインを起動して、例えば左ペイン側で

$ tmux-send-keys-to-right-pane ls -la

とすると右ペインで ls -la が実行されると思う。

これで実行する対象をテストのコマンドにすれば、当然右ペインではテストが実行される。

Vim の中から↑のスクリプトを実行する

ここからは Vim の設定になります!

とりあえず .vimrc に直接設定を書いて参ります!また、私事で大変恐縮なのですが、今私が Ruby on Rails で Minitest を書いており、それを実行したいという気持ちがあることから、Ruby on Rails で Minitest を実行するのを例として説明したいと思います!大変申し訳ございません。

よろしいでしょうか。では .vimrc に以下を記載してください!

.vimrc

command! RailsTest echo s:rails_test(expand('%'), getpos('.'))

function! s:rails_test(file, pos)
  let l:cmd = printf('tmux-send-keys bin/rails test %s:%d', a:file, a:pos[1])
  return system(l:cmd)
endfunction

nnoremap <Leader>rt :<C-u>RailsTest<Return>

簡単に説明しますと、これでやりたいことができるやつです!簡単すぎましたかね?もう少しだけ説明しますと、これは Vim のバッファ上で実行するもので、バッファのファイルとカーソル位置を Rails (5) のテストコマンドに渡しまして、そしてテストを実行する、そういうものであります。

ここでは RailsTest というコマンドが定義されておりまして、そして <Leader>rt がバインドされておりますので、つまりこれを読み込んだ後に左ペインの Vim で Minitest のファイルを開き、そして右ペインでは Rails のルートディレクトリをカレントディレクトリとした状態で <Leader>rt とキーをストローキングしますと、右ペインの方で bin/rails test <バッファのファイル名>:<行番号> が実行されまして、はい、実行されます。もちろん Vim 内部で同期的に実行するわけではございませんので、テストの実行中に Vim の動作がブロックされるということはないのでご安心ください。先ほど申し上げました通り、右ペインで Docker コンテナの bash とかを実行しておけばそのままコマンドを書き換えることなく Docker コンテナでテストが実行できますし、上記をコピペしてコマンド名と関数名、そして

  let l:cmd = printf('tmux-send-keys bin/rails test %s:%d', a:file, a:pos[1])

ここの行を書き換えれば任意のコマンドを実行することができるので便利に使っていただけると思います。ちなみに tmuxinator とかそういうやつは一度も使ったことがありません。あと参考にしました thanks to http://superuser.com/questions/492266/run-or-send-a-command-to-a-tmux-pane-in-a-running-tmux-session すごーいフレンズ

5t111111
kodanshatech
現代ビジネス、FRIDAYデジタル、ブルーバックス、FRaU、ViVi、VOCEなど講談社のウェブメディアやデジタルコンテンツ開発を行っています。
https://kodansha.tech/ja
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした