Hatena::ブログ(Diary)

mooz deceives you

(about 'mooz) ; => "See http://mooz.github.com/index-ja.html"

 | 

September 21 (Mon), 2009

Emacs ユーザにおすすめのアドオン KeySnail

注意

現在の KeySnail にはプラグインシステムというものが導入され、これまで以上に拡張性が高まっています。最新版の KeySnail は以下のページよりダウンロードすることが可能です。

no title

プラグインについては次のエントリを参照してください。

KeySnail 1.0 の新機能「プラグインシステム」を使う - mooz deceives you

KeySnail とは

KeySnailFirefoxキーバインドを極限までカスタマイズすることが可能なアドオンです。このアドオンが keyconfig などの「ショートカットキーカスタマイズ系」の拡張機能と比較して優れている点は、次の四つ (or 人によっては三つ) となります。

  • キーボードショートカットに「連続したキーの組み合わせ」を指定することが可能
  • モードごとのキー割り当てが可能な為、同じショートカットキーに別々のコマンドを割り当てられる
  • あらかじめ多くの組み込みコマンドが用意されておりJavaScript に慣れていないユーザも気軽に使い始められる
  • 開発者が Emacs ユーザのため、 Emacs に特化した使い方が可能なようになっている

f:id:mooz:20090929213907p:image

「連続したキーの組み合わせ」を指定可能

KeySnail では単なるショートカットキーだけでなく、連続したキーの組み合わせにコマンドを割り当てることが可能となっています。連続したキーの組み合わせ、というのは例えば次のようなものを意味します。

  1. まず Ctrl + x を押す
  2. 次に Ctrl + f を押す

こういったキーの組み合わせにコマンドを割り当てることの利点は、「キーボードショートカットキーと比べ割り当てられるコマンドの数がはるかに多い」というところにあります。

例えばキーボードショートカットでは Ctrl + x にコマンド 1 、 Ctrl + y にコマンド 2 、というようにコマンドの数が増えるにつれ、空いているキーがどんどん減っていってしまいました。

f:id:mooz:20090921124550p:image

ここで「連続したキーの組み合わせ」が使えると、まず Ctrl + z を押した後に〜、まず Ctrl + y を押した後に〜といったような割り当てが行えるため、コマンドの数が増えるにつれキーのほうが足りなくなってしまう、という事態はまず生じないかと思われます。

f:id:mooz:20090921124546p:image

Emacs ではこういったキーの組み合わせ (キーシーケンス) への関数割り当てが日常茶飯事ですので、違和感なく使い始めることができるのではないでしょうか。のちに詳しく説明しますが、あらかじめ Emacs キーバインド一式も用意されています。

モードごとのキー割り当てが可能

この拡張機能は、モード (状況) ごとにキーの割り当てを行うことが可能となっています。具体的には、次のようなもののことを言います。

  • 通常のブラウジングをしている
  • キャレットブラウジング (F7 キーを押して入ることが可能) をしている
  • テキストを編集している

例えばただの j とか k にショートカットキーを割り当てたいとき、そのまま割り当てを行うと、「テキストボックス内などで j と k の文字が入力できない」事態が生じます。

この拡張機能ではモードごとに割り当てを行うことが可能なため、通常のブラウジングをしているときにだけ j / k にコマンドを割り当てておき、テキストを編集しているときは何もしない、ということができます。

f:id:mooz:20090921124650p:image

あらかじめ多くのコマンドが用意されている

KeySnail にはあらかじめ多くの組み込みコマンドが用意されています。

f:id:mooz:20090921124851p:image

キーバインドを追加するときに「組み込みコマンド」か「オリジナルコマンド」を選ぶことができ、「組み込みコマンド」を選択すると、利用可能なコマンドが一覧表示されます。

f:id:mooz:20090921124850p:image

プログラミングとかよく分からないよ、という方も気軽に使い始めることが可能となっています。

Emacs に特化した使い方

作者がもっとも力を入れているのがこの部分です。はてな界隈を席巻した Vimperator の牙城を崩すべく、日々奮起しています。

例えば Emacs ユーザが喜びそうな機能としては、次のようなものがあげられます。

  • キーシーケンスへの関数割り当て
  • 初期化ファイル (.emacs に相当する .keysnail.js) によるカスタマイズ
  • キルリング (複数クリップボード)
  • prompt.read (elisp での completing-read に相当)
  • prompt.selector (ソースがひとつだけの anything.el もどき)
  • 前置引数機能
  • 豊富な文字列編集コマンド
    • 矩形操作コマンド (C-x r t, C-x r d, C-x r o, ...)
    • capitalize-word, upcase-word, downcase-word (M-c, M-u, M-l)
    • recenter (C-l)
  • ちゃちなキーボードマクロ

この中でも「キルリング」や「プロンプト機能 / セレクタ機能」、「矩形操作コマンド」などはなかなか他の拡張機能にはなかったのではないでしょうか。(プロンプト機能に関しては Vimperator の completer に完全なる敗北を喫していますが……)

キルリング

キルリングに関しては、次のようなデモビデオを作成してみました。結構ぐだぐだなので、 1:03 あたりまで飛ばして見るのが吉です。

D

Ctrl + y を押してテキストを貼り付けた後、 Alt + y を押すことでキルリングの中身を順々に張り付けて行くことが可能となっています。

また、 Ctrl + Alt + y を押せばキルリングの中身一覧が表示されますので、その中から張り付けたいテキストを選ぶ、ということも可能となっています。この機能は後述する「プロンプト機能」を使って実現されています。

prompt.read / prompt.selector

prompt.read は Emacs lisp における completing-read のような機能です。これは「コマンド内でユーザからの入力を受け取り、その値を使いたい」という場合に重宝します。

例えば Emacs では C-x r t に割り当てられている矩形置換コマンドは、 KeySnail で次のように実現されています。

function (aEvent) {
    var input = aEvent.originalTarget;
    prompt.read("String rectangle:", function (aStr) {
        command.replaceRectangle(input, aStr);
    });
}

このコマンドを実際に使用しているのが、以下の動画になります。

D

ステータスバーの下に入力エリアが現れているのが確認できるかと思います。ここに入力された " * " という文字列が、今回は aStr として command.replaceRectangle に渡っています。

prompt.read ではあらかじめ補完候補を渡しておけば、 Tab による補完が効きます。このあたりの使い方は次の関数説明を参照して下さい。

/**
 * プロンプトから文字列を読み込み <aCallback> を実行する
 * @param {string} aMsg プロンプトに表示される文字列
 * @param {function} aCallback 文字列を読み込んだ後で実行される関数
 * @param {object} aUserArg <aCallback> の第二引数として利用可能な任意のオブジェクト (通常は null で OK)
 * @param {[string]} aCollection 補完候補を「文字列の配列」として指定する
 * @param {string} aInitialInput プロンプトの初期文字列
 * @param {string} aInitialCount 補完候補の初期インデックス
 * @param {string} aGroup ヒストリのグループ (任意文字列を指定可能)
 *    <aCallback> は次のようにして二つの引数をとる.
 *    function callback(str, arg) { ... }
 *    str にはプロンプトから読み込まれた文字列が代入される
 *    <aUserArg> に値が設定されている場合は arg を通じてその値を使用することができる.
 */
read: function (aMsg, aCallback, aUserArg, aCollection, aInitialInput, aInitialCount, aGroup) { /***/ }
prompt.selector

prompt.selector はある候補の中からユーザに一つを選ばせ、その値を煮るなり焼くなりする、という機能です。

次の動画をご覧下さい。

D

ここでは prompt.selector にブックマークツールバーのアイテムを渡し、その候補の中から適当なサイトを選んで URL を開いています。

入力欄には正規表現を複数個、スペースで区切って使用することができます。また、動画にもあるように XUL/Migemo のインストールされた環境であれば、その機能を使ってマッチングを行うことも可能となっています。

この動画で使用している機能は、初期化ファイルに次のような記述を行うことで使用可能となります。

キーバインド一式

KeySnail インストール時のウィザードで次のようにキースキームとして Emacs / w3m を選ぶと、多くの Emacs ライクなキーバインドが使用可能となります。

f:id:mooz:20090921125047p:image

前置引数機能

vimperator に vim の count があるように、 KeySnail には Emacs の prefix argument があります。

例えばテキストボックス内で C-u C-u # と打ち込んでみてください。 ################ というように、 # が 16 個入力されたかと思います。

KeySnail では特に指定をしなければコマンドが前置引数の数だけ繰りかえされますので、コマンド独自に前置引数を扱いたいといった方は、編集画面で「前置引数付与時にコマンドを繰り返さない」にチェックを入れてください。

その他の機能

一時的に KeySnail を無効にする

Gmail など、独自のアクセスキーを用意しているウェブページとショートカットキーカスタマイズ系の拡張機能は、相性があまり良くありません。よくあるのが Gmail で j / k を押してカーソルを上下に移動させようと思っても、拡張機能でカスタマイズしたほうのコマンドが呼ばれてしまい、うまくいかないといった問題です。

KeySnail には「ホットキーによるサスペンド機能」や「URL 正規表現指定による自動サスペンド機能」が用意されているため、こういった問題を回避することができます。

たとえばサスペンドキーに F2 を指定しておけば、 F2 を押すことで一時的に KeySnail を無効にすることができます。もう一度 F2 キーを押せば、再び KeySnail が有効となります。

f:id:mooz:20090921125125p:image

こうやっていちいちサスペンドキーを押すのも面倒だ、という方はあらかじめ KeySnail をサスペンドさせておきたいページの URL を設定しておくこともできます。

f:id:mooz:20090921125201p:image

初期化ファイルによるカスタマイズ

KeySnail の設定は、全て .keysnail.js」 いうファイルの中に入ります。この中にはユーザが任意の JavaScript を記述することが可能となっています。

実際に .keysnail.js をエディタで開いてみてください。次のようなエリアが見つかることかと思います。

// この領域は, GUI により初期化ファイルを生成した際にも引き継がれます
// 特殊キー, キーバインド定義, フック, ブラックリスト以外のコードは, この中に書くようにして下さい
//{{%PRESERVE%
// ここにコードを入力
//}}%PRESERVE%

ここにあるとおり、 GUI による設定を行う方で JavaScript プログラムを書きたいという方は、スクリプトを //{{%PRESERVE% と //}}%PRESERVE% の行ではさむようにして記述するようにして下さい。

  • 特殊キー
  • キーバインド定義
  • フック
  • ブラックリスト

といった設定の記述に関しては KeySnail が自動で検出して保存してくれるため、上記のエリアに含める必要はありません。むしろ含めてしまうと面倒なことになります。

まとめ

長くなりましたが、 KeySnail のざっとした説明は以上です。この拡張機能の利点はユーザが独自にカスタマイズしていける、というところにあると思っていますので、どんどん自分好みにカスタマイズしていってみてください。

最後にですが、バグ報告や要望などありましたら、メールや Twitter にてお気軽に連絡下さい。

また、 見つかりませんでした にレビューを投稿していただけると、「実験的なアドオン」から「承認済みのアドオン」へ移行する可能性が強まり、自動アップデートが行えるようになるかもしれません。

 | 
Connection: close