xyzzyのカスタマイズ

| コメント(0) このエントリーを含むはてなブックマーク

いくつか自分で試してみたカスタマイズについて説明します。方針としてはなじんだemacsの操作にできるだけ近づけようということです。もちろん、なんでもかんでもというわけではなく、xyzzyの方が便利なところはそのまま使っていきます。

インクリメンタルサーチ

emacsと同じように"Ctrl-S"でインクリメンタルサーチを行なうには~/.xyzzyに以下の行を追加します。

(require "isearch")

dabbrev

dabbrevとはdynamic abbreviationの略で、同じバッファ内を検索してワードを補完してくれる機能です。この機能を利用するには~/.xyzzyに以下の行を追加します。ついでに、emacsと同じ"Meta-/"に補完するためのキーを割り当てます。

(require "dabbrev")
(global-set-key #\M-/ 'dabbrev-expand)

キーバインド

同じ機能が提供されていてもemacsとxyzzyではキーバインドが異なっています。それらもemacs風にしておきましょう。以下では、ぼくがよく使うundoとquery-replaceのキーバインドを変えています。

(global-set-key #\C-/ 'undo)
(global-set-key #\M-% 'query-replace)

このほか、repeat-complex-commandという以前実行したコマンドの履歴の中から選択して再度実行するコマンドがemacs, xyzzy共通にあります。単純に同じ操作を繰り返す場合にも使いますが、以前の操作を少しだけ変えて実行したいときに特に重宝します。

これはemacs19(mule)ではCtrl-x ESC、emacs20ではCtrl-x ESC ; およびCtrl-x ESC ESCに割り付けられていますが、xyzzyではEsc pです。emacsでも履歴の間を行き来するのは、Esc pとEsc nを使うので、キー操作としてはxyzzyの方がシンプルです。というわけで、このまま使うことにします。

DeleteキーとBackSpaceキー

emacsとxyzzyではDeleteキーとBackSpaceキーの役割が違っています。以下の表を見てください。

DeleteBackSpace
emacsカーソル位置の一つ前の文字を削除Ctrl-Hと同じでヘルプを呼び出すキーのプレフィックス
xyzzyカーソル位置の文字を削除カーソル位置の一つ前の文字を削除

さて、JIS配列のキーボードの場合、Deleteキーは若干押しにくい場所にあります。このため、emacsではbobcatというライブラリを使って DeleteキーとBackSpaceキーを入れ替えている人がたくさんいました(Deleteキーを押すとC-hになる)。そこで、このbobcatを使った状態のemacsをシミュレートする方法を以下に述べます。

この場合、Deleteキーが押されたときにC-hとみなすにようにするという方法がまず思い浮かびますが、C-hは、c-modeやlisp-mode 等の各モードの中で関数を再割り当てされてしまうため、フックなどを使ってその度ごとに設定しなおす必要がでてきて面倒です(そもそも現バージョンの xyzzyではDeleteキーを仮想的に他のキーとみなすことはできないようです)。そこで逆に、C-hをDeleteキーとみなすように設定し、 Deleteキーにヘルプ呼び出し等自分の望みの機能を設定するようにします。

(setf (svref *kbd-translate-table* (char-code #\C-h)) #\Delete)
(global-set-key #\Delete 'my-func)

この場合はDeleteキーやCtrl-hキーを押したときに、my-funcという関数が実行されます。

マウスだけでコピー・ペースト

xyzzyでは他アプリケーションとクリップボード経由でデータのやりとりをする場合、C-InsertやS-Insertという昔のIBMのアプリケーションのようなキー操作をしなければなりません。これはなかなかつらいので、X Window System上のemacsのようにマウス操作だけで、クリップボード操作ができるようにしてみました。

(defun mouse-right-press ()
  (interactive)
  (mouse-left-press)
  (paste-from-clipboard)) 
(global-set-key #\LBtnUp 'copy-selection-to-clipboard) 
(global-set-key #\RBtnUp 'mouse-right-press)
(global-set-key #\MBtnUp 'mouse-menu-popup)

これでマウス左ボタンで範囲を選択した瞬間にクリップボードにコピーされ、マウス右ボタンをクリックした位置にクリップボードからペーストされるようになります。標準では、マウス右ボタンを離したときに表示されるポップアップメニューは、真中ボタンに割り付けています。

write-file

emacs でもxyzzyでもC-x C-wというキーでwrite-fileというコマンドが呼び出されますが、若干動作が異なります。emacsのwrite-fileではバッファーの名前や割り付けられているファイル名も新しく指定されたファイルに変わりますが、xyzzyではそのままです。xyzzyでもemacsと同様の動作に設定したい場合には、~/.xyzzyに以下の行を追加します。

(define-key ctl-x-map #\C-w 'emacs-write-file)

find-other-fileのデフォルト

間違えたファイルを開いてしまった場合などに、そのバッファを破棄して、別のファイルを開くという手順を一度に行いたくなります。emacsでも xyzzyでも、find-other-file(C-x C-v)というコマンドで可能ですが、emacs20では、破棄するバッファのファイル名がミニバッファに表示されます。もとのファイル名と新しいファイル名が似ている場合にはこれはかなり便利です。xyzzyでは、そのファイルのあるディレクトリがミニバッファに表示されますが、これをemacs20と同じ動作に変えることが可能です。以下のように設定します。

(setq *find-other-file-requires-file-name* t)

コンパイルエラーの表示

CやJavaのソースファイルをコンパイルしたとき、エラーが発生したファイル・行に直接飛びたくなります。emacsでは、そういう場合next-errorというコマンドを使います。キーバインドはC-x ` (バッククォート)です。

xyzzyにもnext-errorはありますが、emacsとはかなり使い方が異なります。コンパイルするところから手順を比較してみましょう。

emacsxyzzy
コンパイル"compile"という専用のコマンドexecute-subprocessコマンド(C-x &)で普通の外部コマンドと同様にコンパイルするためのコマンド(javac等)を指定して実行する
コンパイル後のカレントバッファウィンドウが分割されて、実行結果のバッファが表示されますが、カレントバッファはコンパイル前と同じウィンドウが分割されて、実行結果のバッファが表示され、カレントバッファはそちらへと移動する
エラーが発生しているファイル・行への飛び方その場でnext-errorコマンド(C-x `) 初回のみ、バッファの先頭に移動してからfirst-errorコマンド(F10)。二回目以降はnext-errorコマンド(F11またはC-x `)。

上記のようにxyzzyの方が若干手順が煩雑です(逆に柔軟性には富んでいますが)。そこでほぼemacsのnext-errorのような動きをする emacs-next-errorというコマンドを作ってみました。コンパイル後にその場でemacs-next-errorを実行すると、初回か二回目以降かを判断して、first-errorとnext-errorのうち適切な方を呼び出します。下の例では"C-x `"にこのコマンドを割り付けています。日本語キーボードではこのキーは打ちにくいので、F11などに割り付けた方がいいかもしれません。

(defun emacs-next-error (&optional arg)
  (interactive "p")
  (if (not editor::*error-list*)
      (progn
        (goto-char (point-min))
        (first-error arg nil))
    (next-error arg)))

(define-key ctl-x-map #\` 'emacs-next-error)

上記では、コンパイルについて説明しましたが、grepで指定したパターンに合致するファイル・行に飛ぶ場合も同じです。

statusバーにカーソル位置の文字コードを表示する

以下の式を ~/.xyzzy に記述すると、ステータスバーにカーソル位置の文字コードが表示されるようになります。

(setq *status-bar-format* "%t%c%u")

"%t"が時刻、"%c"がxyzzyの内部コード、"%u"がUnicodeを示し、左からこの順番で表示されます。このほか"%p"でカーソル位置を表示することもできます。

Unixサーバ上のファイルのバックアップファイル

xyzzyはファイルを編集する場合には、編集前の状態をバックアップファイルとして残しておくのがデフォルトです。"ファイル名~" とか "ファイル名...~1" がそうです。たくさんできて、うざったく感じたりもしますが、編集中のファイルがこわれてしまったときに安心です。

さて、emacsでもそうでしたが、xyzzyはバックアップファイルを作成する場合、もとのファイルをバックアップファイルにリネームします。そうするともとのファイルがなくなってしまうので、新規に作成して、編集中のバッファの内容を保存します。

コピーよりリネームの方が処理も軽いし、確実なのですが、UnixまたはLinuxマシンのファイルをsambaを介して共有している場合はちょっとやっかいなことになります。WindowsからはUnix(Linux)マシンのファイルのパーミッションを参照したり変更したりすることができないので、パーミッションが編集後保存したファイルに引き継がれず、デフォルトのパーミッションになってしまうのです。つまり、せっかく実行権を設定したファイルなのに、編集するとそれが消えてしまったりするわけですね。

これを防ぐには、以下の式を~/.xyzzyに追加します。

(setq backup-by-copying :remote)

これでネットワークドライブ上のファイルのみコピーでバックアップを作成します。値を:remoteではなく t にするとローカルのドライブでもコピーでバックアップを作成するようになりますが、あまり意味がないでしょう。

コメントする