2009年10月12日月曜日

sshでリモートからemacsclient

という訳で、sshで自宅から職場の強力マシンに入れるようになったし、rsyncで同期もできるし、Xアプリも使えるようになった。自宅にいるも職場にいるもあまり意識せずにほぼ同じ感覚で作業できるようになったわけだ。

しかしもう一つ。

作業の多くをEmacsの中で行なっているので、当然Emacsは常に立ち上げっぱなし。終了して起動し直す事なんて特に理由がない限りはない。当然職場PC上でもEmacsは常時起動しっぱなしだ。
で、自宅から職場PCに入って一番最初に起動するのもEmacsなわけだが、職場でやっていた作業の続きができない。diredでディレクトリを開いていたりファイルを開いていたり、shell-modeの中で何かやっていたり、Pythonその他を動かしている事もある。場合によっては時間のかかる処理を流しっぱなしにしている事もある。
その様子を見たり続きをしたいこともあるが、それにはまさにその、職場PCで動いているEmacsに入らないといけない。sshログインして別のEmacsプロセスを起動しても無理だ。

そこで思い出したのがemacsclinet。(以前はgnuclientという名前だったような気が...)

職場PCで使っているEmacsで M-x server-start とすると、Emacs serverが起動する。
そして自宅からsshで職場PCにログインしたら

workpc$ emacsclient -d localhost:10.0 test.txt

のようにすると、手元(homepc)でEmacsのウィンドウ(フレーム)が開いてtest.txtファイルのバッファが開く。そしてそれは職場PCで動いているEmacsと同じプロセスであり、当然他のバッファも見られるしその中で作業もできる。本当に中途半端な状態で職場を出て、その続きを自宅でしたり、あるいはその逆もできる訳だ。

なお、-dで指定しているのはXのディスプレイだが、サーバーEmacsと同じディスプレイの場合には既に開いているEmacsの中でtest.txtバッファが開く。今回のように別のディスプレイを指定すると、新たなフレームが開く。

指定したファイル(test.txt)のバッファをkill-bufferすると、emacsclient自身は終了する。しかしフレームは残るのでその中で作業を続けることは普通にできる。
が、先にフレームを閉じてしまいtest.txtのバッファをkill-bufferし忘れると、なぜかemacsclient自体は終了しない。起動時にファイル名を求めるというのはそういう意味だったのか...
まあプロセスを殺せばいいんだけど、ちょっとしっくりしない。

ちなみに、localhost:10.0 というのは、sshで入った時のこちら側に割り当てられたDISPLAYだ。試している限りでは、一段sshと二段sshでは自動で環境変数DISPLAYが正しく設定されているが、三段sshでは自動では":0.0"と正しい値が設定されていない。なので自分で

workpc$ export DISPLAY=localhost:10.0

のようにしないとXのウィンドウを手元に持ってこられないので注意。
また、"10.0"の"10"の部分はログイン状況によって異なるようだ。
一段・二段sshの時の値から推測すると、10あたりから順番に大きな数を使うようになっているようだが、この辺りの正式な説明は見付けられなかった。

なにはともあれ自宅から職場PCで起動しているEmacsに横入りして作業できるようになった。
普通のターミナル上でならばscreenでも使うところなのだろうが、Emacsメインの人間にとってはemacsclientの方が100万倍便利。

ただしEmacsでサーバーを起動しておかないといけないので、うっかり忘れないように.emacsに下のコード片を加えて自動で起動するようにしておいた。

(when (equal (getenv "DISPLAY") ":0.0")
(server-start))

0 件のコメント: