vim から GNU Screen を叩く

f:id:shocrunch:20150222015333g:plain

vim から GNU Screen を叩く

GNU Screen の -X オプションをラップした vim-slime が便利です。

vim-slime: https://github.com/jpalardy/vim-slime

オリジナルは jpalardy さんのものですが、いくつか fork されているので
そちらも目を通してみると、有用な情報が手に入るかもしれません。

インストール

Neobundle でインストールが可能です。

NeoBundle 'jpalardy/vim-slime'

使い方

使い方は :help slime.txtを参照すればわかりますが、普通に使うものだけ紹介

  • normal mode で<C-c><C-c>で、 vim の buffer を送信
  • visual mode で<C-c><C-c>で、選択中の文字を送信
  • normal mode で<C-c>vで、session name, window name を再設定する

また、初回実行時には screen の session name と window name の入力を求められます。
これを適切に設定してあげる必要があります。

  • session name って?? なにを入力すればいいの??
    • 端末上で screen -ls と打ち込むと以下のように出てくる。
      4909.pts-0.bigcool などが session name です。
        There are screens on:
            7984.pts-6.bigcool    (2015年02月22日 00時05分08秒)   (Detached)
            7956.pts-4.bigcool    (2015年02月22日 00時05分05秒)   (Detached)
            4909.pts-0.bigcool    (2015年02月21日 23時20分55秒)   (Attached)
        
    • この表示結果をコピペしてもいいですが<tab>補完が効くので安心してください。
    • いま開いている screen の sessionname を知りたいときは、
      screen のエスケープシーケンスを叩いて:sessionnameと打てば教えてくれます。

自分の都合のいいようにパッチを書いた

vim-slime は使いやすいんですが、
複数の window に対してコマンドを一斉送信したかったのでちょっといじりました。

パッチの効果

  • 複数の window に対して送信できるようにする
    • 想像していたような動きをしなかった場合はman screen内の、atを参照してください。 解決策がみつかるかもしれません。
  • screen 内で vim を開いている場合、session name を自動的に設定する

パッチの当て方

Neobundle でインストールした人を対象に説明します。

  1. パッチをダウンロードする
    下に貼ってあるパッチをすべてコピーし、適当なファイル名で保存してください。(例えば patch.txt とか)

  2. パッチを当てる準備
    "1."でダウンロードしたパッチを、$HOME/.vim/以下にあるvim-slimeのディレクトリへコピーします
    sh $ cp patch.txt ~/.vim/bundle/vim-slime/

  3. パッチを当てる
    パッチのコピー先へ移動して、パッチを当てます。 sh $ cd ~/.vim/bundle/vim-slime/ $ patch -p1 < patch.txt

作成したパッチ

diff --git a/plugin/slime.vim b/plugin/slime.vim
index f94b36a..79267f2 100644
--- a/plugin/slime.vim
+++ b/plugin/slime.vim
@@ -19,7 +19,7 @@ end
 function! s:ScreenSend(config, text)
   call s:WritePasteFile(a:text)
   call system("screen -S " . shellescape(a:config["sessionname"]) . " -p " . shellescape(a:config["windowname"]) . " -X readreg p " . g:slime_paste_file)
-  call system("screen -S " . shellescape(a:config["sessionname"]) . " -p " . shellescape(a:config["windowname"]) . " -X paste p")
+  call system("screen -S " . shellescape(a:config["sessionname"]) . " -p " . shellescape(a:config["windowname"]) . " -X at " . shellescape(a:config["windowname"]) . "# paste p")
 endfunction
 
 function! s:ScreenSessionNames(A,L,P)
@@ -28,7 +28,7 @@ endfunction
 
 function! s:ScreenConfig() abort
   if !exists("b:slime_config")
-    let b:slime_config = {"sessionname": "", "windowname": "0"}
+    let b:slime_config = {"sessionname": $STY, "windowname": "0"}
   end
 
   " screen needs a file, so set a default if not configured