目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回

Emacs では数多くの関数がキーに割り当てられています。その中には押しやすいものもあれば、押しづらいものもあります。また、全ての関数がキーに割り当てられているわけではないため、頻繁に使う関数なのに

M-x hogehoge [Enter]

などと実行しなければならない場合もあります。

という状況ではありますが、Emacs のキーバインドはフルカスタマイズ可能です。カスタマイズするしかないでしょう。:-)

ポリシー

私は以下のことを念頭に置いて、キーバインドを変更しています。

  • デフォルトのキーバインドは、極力変更しない。
  • 連打することがあるコマンドは1ストローク(例: Ctrl-t)。
  • 連打する必要が少ない、もしくはやや危険なコマンドは2ストローク(例: Ctrl-q Ctrl-h)。
  • 2ストロークにする時は、全て Ctrl-q Ctrl-h のような Ctrl を介したものにする。例えば Ctrl-q h だと、Ctrl キーを一旦ニュートラルにする必要があるので、Ctrl-q Ctrl-h より確実に遅い。
  • カーソルキーやファンクションキーは遠いので、極力使わない。

知っておくべきこと

例えば、Ctrl-n というキーを押すと next-line という関数が呼ばれます。Ctrl-f は forward-char です。ただの a というキーにも self-insert-command という関数が割り当てられています。

このように、全てのキーに関数が割り当てられています。

では、どうやって調べたらよいでしょうか?これを調べるヘルプコマンドが、以下になります。ミニバッファに関数名が表示されます。

F1 c 調べたいキー操作

F1 c 自体も、もちろん関数呼び出しとなっています。上の方法で調べると、describe-key-briefly という関数だと分かります。

逆に、ある関数がどのキーに割り当てられているのかは、F1 w で分かります。

以上を知っていれば、現在のキーバインドがどのように設定されているか分かるはずです。

よく使うヘルプコマンド一覧を記載しておきますね。F1 Ctrl-h すると、一覧から以下のヘルプを選択することも出来ます。

キー 関数名 説明
F1 c describe-key-briefly 指定したキーに対応する関数名を、ミニバッファに表示
F1 k describe-key 指定したキーに対応する、関数のヘルプを表示
F1 f describe-function 指定した関数のヘルプを表示
F1 w where-is 指定した関数に対応する、全てのキーを表示
F1 b describe-bindings 現在のバッファのキーバインド一覧を出力
F1 m describe-mode 現在のバッファのメジャーモードとマイナーモードの説明を出力
F1 a apropos キーワードにマッチする関数と変数を検索
F1 i info Infoを閲覧

基本となる設定方法

global-map

一例として。Ctrl-z すると、M-x shell を実行できるようにしてみます。

デフォルトで Ctrl-z に割り当てられている関数は、iconify-or-deiconify-frame です。フレームが最小化されます。これを置き換えます。

設定内容はこちらになります。~/.emacs に記載します。

(define-key global-map (kbd "C-z") 'shell)

define-key が関数名です。後ろの global-map, (kbd "C-z"), 'shelldefine-key への引数になります。

global-map というのは全てのバッファに影響するキーマップです。

(kbd "C-z")Ctrl-z というキーのことだと思って下さい。他に (kbd "C-x C-p"), (kbd "M-p"), (kbd "C-M-p"), (kbd "C-,"), (kbd "<right>"), (kbd "<f8>") などが使えます。(kbd "ほげ") の ほげ の部分は、F1 c した後、調べたいキーを押すと分かります。

'shell は関数名です。' (シングルクォート) を忘れないで下さい。

global-map 以外のキーマップ

有名なところでは、esc-map と ctl-x-map があります。global-map と同じく、全てのバッファに影響するキーマップです。

以下は設定の一例です。M-jEsc-j すると、goto-line を実行します。

(define-key esc-map (kbd "j") 'goto-line)

後述しますが、キーマップを自作することも出来ます。

他にも c-mode-base-map や dired-mode-map、isearch-mode-map などがあります。apropos で調べられます。

Ctrl-u F1 a -map$ [Enter]

Emacs の Info や、elisp のソースを確認するのも良いと思います。

キーマップを自作する

デフォルトのキーバインドをできるだけ変更しないで、自分好みの設定をしようとするとあることに気づくはずです。

「どのキーも埋まっているじゃん。。。」

使わなそうなキーなら良いのですが、実は使えるキーで、後で後悔するかもしれません。

ここで、Ctrl-なんとか というキーを一つずつ調べてみました。結果、Ctrl-q の使用頻度が少ないことに気がつきました。

Ctrl-q には quoted-insert という関数が割り当てられています。コントロールコード(ASCII コードの Ctrl-l や Ctrl-i 等)を挿入できます。

そこで、ctrl-q-map を作ってみることにしました。

そうすると、Ctrl-q Ctrl-アルファベットCtrl-q 記号 などを自由に使えるようになります。quoted-insert は Ctrl-q Ctrl-q に追いやることにします。

前置きが長くなりましたが、設定内容を下記に記載します。「your-favorite-funca〜your-favorite-funcz」はもちろん、割り当てたい関数名にしてください。

(defvar ctl-q-map (make-keymap))                 ;;; (★a)
(define-key global-map (kbd "C-q") ctl-q-map)    ;;; (★b)
(define-key ctl-q-map (kbd "C-a") 'your-favorite-funca)
(define-key ctl-q-map (kbd "C-b") 'your-favorite-funcb)
.
.
(define-key ctl-q-map (kbd "C-q") 'quoted-insert)
.
.
(define-key ctl-q-map (kbd "C-z") 'your-favorite-funcz)

;;; (★a) ctrl-q-map という変数を新たに定義しました。
;;;       新規作成したキーマップを代入しています。
;;;
;;; (★b) ctrl-q-map を Ctrl-q に割り当てています。

かなり自由に設定できるようになりましたね!

引数を指定したキーバインドの設定

-第4回- カーソル移動 」の「スクロールアップ、スクロールダウン」の Ctrl-u 1 Ctrl-v のような操作をキーに割り当てることもできます。

一例として1行スクロールアップする機能(Ctrl-u 1 Ctrl-v に相当)を Ctrl-; に割り当てることにします。

方法1

(1) 1行スクロールアップする関数 scroll-up1 を新規作成します。

(defun scroll-up1 ()
  (interactive)
  (scroll-up 1))

(2) scroll-up1 を Ctrl-; に割り当てます。

(define-key global-map (kbd "C-;") 'scroll-up1)

方法2

1行スクロールアップする無名関数を作って、直接 Ctrl-; に割り当てます。

(define-key global-map (kbd "C-;") (lambda () (interactive) (scroll-up 1)))

参考資料

今回は少しだけ「emacs 雑記」を参考にさせて頂きました。keybind のページ ですね。

英語ですが、Info にも詳しい説明が書いてあります。

  1. M-x info [Enter]
  2. 以下の行で Enter
    • * Emacs: (emacs). The extensible self-documenting text editor.
  3. g を押したあと、Key Bindings [Enter]

最新の Info って誰か翻訳していないのかなあ。手元にあるのは 20.6 の日本語マニュアル…。

第5回終わり。

目次 / 第1回 第2回 第3回 第4回 第5回 第6回 第7回 第8回 第9回