Skip to content
Tags

キーバインド構造化補助ライブラリ、 keyset をリリースしました

2014/11/11

MELPA に登録されているので、 package.el からインストールできます。

これは何?

keyset は emacs のキーバインドの構造化を補助するための簡単なライブラリです。 キーシーケンスを抽象化して、できる限り設定ファイルにキーバインドが 直書きされるのを避けるために作られました。また、キーシーケンスの定義を レイアウト毎に切り替えることができるようにしてあるため、 qwerty 用と dvorak 用で別々のキーシーケンスを用意することが可能です。

きっかけ

keyset を作るきっかけは dvorak 配列への移行を考えたことでした。 自分は evil を使っているのこともあって、 hjkl によるカーソル移動を どうするかは問題でした。できれば dvorak でも似たような配置で 使いたかったのです。

しかしながら、個人的に設定したキーバインドの中には hjkl にならったものもあり、仮にそれらも dvorak 用に変更したとしても、 今度は qwerty を使わざるを得ない状況に出くわした時に 痛い目を見るのは明らかでした。

そのために、キーシーケンスを抽象化できて、なおかつ qwerty や dvorak で 切り替えができるようなライブラリが必要でした。

使い方

keyset はユーザーが動作を予想しやすいよう、なるべく単純な作りになっています。 基本的に、使用するのは keyset-defkeykeyset-key の二つです。

簡単な使い方

まずは keyset-defkey です。これはその名の通りキーシーケンスを定義します。 また、 defkey となっていますが実は関数です。

単純な使い方として、例えば emacs で一般的に次の行へ移るために使われる “C-n” を :next-line という名前で定義してみましょう。 keyset は (require 'keyset) としてロードされているとします。

(keyset-defkey :next-line "C-n")

これで :next-line という名前でキーシーケンスが定義されました。 また、 keyset-defkey で定義するキーシーケンスの名前には キーワード(コロンから始まるシンボル)を使用します。 キーワードを使用する理由は後述の keyset 内でのキーシーケンス表現にあります。

次に、 keyset-key を使用してキーシーケンスを取得します。 keyset-key が返すキーシーケンスは define-key などで使えるオブジェクトで、 現段階ではベクタです。これを define-key などの設定で使用します。

(define-key any-map (keyset-key :next-line) 'any-command)

以上が keyset の基本的な流れです。こうすることによってキーバインドの直書きを 避けることができます。

もう少しだけ実践的な例

実際にはもう少しややこしくなるはずです。例えば emacs で一般的に次へ移ることを 意味するのは “n” で、次の行へというのはそれに ctrl を足したものだったりします。 そこで :next として “n” を定義して、 :next-line でそれを参照するように してみましょう。

(keyset-defkey :next "n")
(keyset-defkey :next-line '(:C :next))

:next-line の定義内容がリストに変わりました。そしてその内容は、 ctrl を意味する :C と定義済みのキーシーケンスを指す :next になっています。 もうおわかりですね、そうです、これはキーシーケンス :next にモディファイアキー ctrl を付与するという意味です!あとは先程の例と同じように define-key で 使用するだけです。

また、キーシーケンスを加工することは keyset-key でも行うことができます。 :next-line の代わりに :next を用いるならば次のようにします。

(define-key any-map (keyset-key :C :next) 'any-command)

これも同じ結果になります。どちらの方法を用いるかはユーザーの自由です。 また、 keyset-key の場合はリストにまとめる必要はありません。

keyset 内でのキーシーケンス表現

keyset ではキーシーケンスを表現するために、文字列やキーワード、シンボル、 そしてそれらで構成されたリストが使用することができます。それらの意味は 次のとおりです。

文字列

文字列は kbd マクロで使用する形式のものが使えます。意味も kbd マクロの ものと同じです。

例:

  • “abc”
  • “RET”
  • “C-x C-c”
  • “<f11>”

キーワード

キーワードには二つの意味があります。 それは、モディファイアキーと定義済みキーシーケンスです。

まず、モディファイアキーですが、これを示すキーワードは あらかじめ用意されています。それがこちらです。

意味 短い名前 長い名前
Alt :A :alt
Hyper :H :hyper
Meta :M :meta
Super :s :super
Shift :S :shift
Control :C :control

また、同じモディファイアキーが重複して設定されても一つとして扱われます。

;; どちらも同じ結果になる
(keyset-key :C "n")
(keyset-key :C :C :C "n")

そして、それ以外のキーワードはすべてキーシーケンス名として解釈されます。

シンボル

シンボルは、キーシーケンスのベクタ表記で用いるものと同じ意味を持ちます。 つまり、下記のコードはどれも同じことを意味しています。

[remap command]
(kbd "<remap> <command>")
(keyset-key 'remap 'command)

リスト

リストはすべて再帰的に展開されます。したがって、ネストしていても構いません。 これは keyset のユーザーが自身でリストの展開をしなくていいようにするために 導入されています。

;; どちらも同じ結果になる
(keyset-key :C "x" :C "c")
(keyset-key '((:C) "x") :C () "c")

レイアウトについて

最初にも書いたとおり、 keyset ではレイアウト毎にキーシーケンスを 切り替えることができます。この機能を使うには keyset-defkey&rest 引数を使用し、 keyset-layout を使いたいレイアウトに設定します。

例えば、 vim の次の行に相当するものを用意したい場合には次のようになります。

;; デフォルトで "j" 、 dvorak で "h"
(keyset-defkey :vim-next-line "j" :dvorak "h")

;; dvorak を使う
(setq keyset-layout :dvorak)

;; "h" が使われる
(define-key any-map (keyset-key :vim-next-line) 'any-command)

注意点として keyset-layout の変更は keyset-key の呼び出しより前に行う 必要があります。また、レイアウト名は自由に決めることができますが、 キーワードを使うことが望ましいです。ちなみに、デフォルトのレイアウトは :default となっていて、他のレイアウト向けにキーシーケンスが 定義されていない場合はこちらのものが使用されます。

おまけ

keyset には keyset-key と同じような関数として keyset-key-string が 用意されています。これは keyset-key の戻り値を kbd 形式の 文字列にしたもので、動作確認などに活用してみてください。

長くなってしまいましたが、ここまで読んでいただきありがとうございます。

広告

From → Emacs

コメントする

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。