#!/usr/bin/env ruby
=begin
= gnuclientを便利に使おう
== 概要
gnuclientを便利に使うためのラッパーを提供する。
gnuclientとはすでに起動しているemacsを使って外部からファイル編集命令をだしたり、elispを実行させるためのプログラム。
当然.emacsに
(gnuserv-start)
の一行を加えてgnuservを立ち上げる必要がある。
* 標準入力をgnuclientに送る。これでemacsをページャとして利用。
* screenと共に使っているとき、
* emacsのwindowへ飛ばす。
* emacsでgnuserv-editしたとき(すなわち、サーバでの編集終了)に元のwindowへ戻る。
== 必要なもの
* (()) 3.9.9以上
* (())
== Emacs側での設定
以下のフォームを.emacsに加える。
\C-c\C-cでバッファを保存して編集を終了するようにした。
一時的な編集なのでわざわざ確認をするまでもない。
また\C-x\C-cでも編集を終了するようにしている。
デフォルトでは\C-x#になっている。
デフォルトでemacsの終了に割り当てられているが、実際につこてみればここに割り当てる意味がわかってくるだろう(笑)。
((-そのときemacsはM-x save-buffers-kill-emacsで終了する。-))
(setq screen-command "/usr/bin/screen")
(setq gnuserv-winconf nil)
(defun gnuserv-edit-finish ()
(interactive)
(and (buffer-modified-p)
(y-or-n-p (concat "Save file " (buffer-file-name) "?" ))
(save-buffer))
(condition-case nil
(gnuserv-edit)
(error (if buffer-read-only
(kill-buffer (current-buffer)))
(delete-frame)
nil))
(set-window-configuration gnuserv-winconf)
(with-temp-buffer
(insert-file-contents "~/.screen-gnuclient")
(unless (zerop (buffer-size))
(call-process screen-command nil nil nil "-X" "select" (buffer-string)))))
(defun finish-buffer ()
(interactive)
(if (gnuserv-buffer-p (current-buffer))
(gnuserv-edit-finish)
(when (buffer-file-name)
(and (buffer-modified-p)
(y-or-n-p (concat "Save file " (buffer-file-name) "?" ))
(save-buffer)))
(kill-buffer (current-buffer))))
(easy-mmode-define-minor-mode
gnuserv-edit-mode "" nil ""
'(("\C-c\C-c" . (lambda ()
(interactive)
(save-buffer)
(finish-buffer)))))
(defun gnuserv-find-file (file)
(interactive)
(setq gnuserv-winconf (current-window-configuration))
(find-file file)
(gnuserv-edit-mode t))
(setq gnuserv-find-file-function 'gnuserv-find-file)
(define-key ctl-x-map "\C-c" 'gnuserv-edit-finish)
=end
#' font-lock hack
#$EmacsWindow = "emacs" # Emacsを起動しているwindowの番号or名前
$EmacsWindow = "0" # Emacsを起動しているwindowの番号or名前
$screen = "/usr/bin/screen"
$gnuclient = "/usr/bin/gnuclient"
$window_no_file = "#{ENV['HOME']}/.screen-gnuclient"
# screen管轄である
def screen?
ENV['TERM'] =~ 'screen'
end
def jump_to_emacs
unless $EmacsWindow == ENV['WINDOW']
system $screen, "-X", "select", $EmacsWindow
end
end
def edit
if screen?
jump_to_emacs
end
exec $gnuclient, *ARGV
end
def view_stdin
require 'tempfile'
temp = Tempfile.new "gnuclientrbtmp"
temp.write $stdin.read
temp.close
if screen?
jump_to_emacs
end
# system $gnuclient, "-v", "-q", temp.path
system $gnuclient, temp.path
end
def main
begin
open( $window_no_file, "w" ) do |f|
f.write ENV['WINDOW']
end
case ARGV.length
when 0
view_stdin
else
edit
end
ensure
File::unlink $window_no_file if File::exist? $window_no_file
end
end
main