back

Lisp の式を編集する際に、自分でよく利用している思われるコマンドをリストしてみました。
下表の C-M-a といった表記の中で、C- は Control キー、M- は Meta キーを意味します。Meta キーは、ESC または Alt で代用することができます。また ESC は、C-[ とタイプしても同じです。したがって、例えば C-M-a にバインドされている beginning-of-defun を実行するには、C-[ C-a, ESC C-a, Alt-Control-a というように複数のタイプの仕方があります。

バインドコマンド名M-x describe-function
C-M-abeginning-of-defun Move backward to the beginning of a defun. With ARG, do it that many times. Negative arg -N means move forward to Nth following beginning of defun. Returns t unless search stops due to beginning or end of buffer.
C-M-bbackward-sexpMove backward across one balanced expression (sexp). With ARG, do it that many times. Negative arg -N means move forward across N balanced expressions.
C-M-ddown-listMove forward down one level of parentheses. With ARG, do this that many times. A negative argument means move backward but still go down a level.
C-M-eend-of-defun Move forward to next end of defun. With argument, do it that many times. Negative argument -N means move back to Nth preceding end of defun.
C-M-fforward-sexpMove forward across one balanced group of parentheses. With ARG, do it that many times. Negative arg -N means move backward across N groups of parentheses.
C-M-hmark-defun Put mark at end of this defun, point at beginning. The defun marked is the one that contains point or follows point.
C-M-kkill-sexpKill the sexp (balanced expression) following point. With ARG, kill that many sexps after point. Negative arg -N means kill N sexps before point.
C-M-nforward-listMove forward across one balanced group of parentheses. With ARG, do it that many times. Negative arg -N means move backward across N groups of parentheses.
C-M-osplit-line Split current line, moving portion beyond point vertically down. If the current line starts with `fill-prefix', insert it on the new line as well. With prefix ARG, don't insert `fill-prefix' on new line.
C-M-pbackward-listMove backward across one balanced group of parentheses. With ARG, do it that many times. Negative arg -N means move forward across N groups of parentheses.
C-M-qindent-pp-sexp Indent each line of the list starting just after point, or prettyprint it. A prefix argument specifies pretty-printing.
C-M-ttranspose-sexpsLike M-t but applies to sexps. Does not work on a sexp that point is in the middle of if it is a list or string.
C-M-ubackward-up-listMove backward out of one level of parentheses. With ARG, do this that many times. A negative argument means move forward but still to a less deep spot.
C-M-DEL
ESC<C-backspace>
backward-kill-sexpKill the sexp (balanced expression) preceding point. With ARG, kill that many sexps before point. Negative arg -N means kill N sexps after point.
C-M-@
C-M-SPC
mark-sexpSet mark ARG sexps from point. The place mark goes is the same place <C-M-right> would move to with the same argument. Interactively, if this command is repeated or (in Transient Mark mode) if the mark is active, it marks the next ARG sexps after the ones already marked.
M-mback-to-indentationMove point to the first non-whitespace character on this line.
なしup-listMove forward out of one level of parentheses. With ARG, do this that many times. A negative argument means move backward but still to a less deep spot.
なしkill-backward-up-list※Kill the form containing the current sexp, leaving the sexp itself. A prefix argument ARG causes the relevant number of surrounding forms to be removed.
なしraise-sexp※Raise ARG sexps higher up the tree.
なしinsert-pair※Enclose following ARG sexps in a pair of OPEN and CLOSE characters. Leave point after the first character. A negative ARG encloses the preceding ARG sexps instead. No argument is equivalent to zero: just insert characters and leave point between. If `parens-require-spaces' is non-nil, this command also inserts a space before and after, depending on the surrounding characters. If region is active, insert enclosing characters at region boundaries. If arguments OPEN and CLOSE are nil, the character pair is found from the variable `insert-pair-alist' according to the last input character with or without modifiers. If no character pair is found in the variable `insert-pair-alist', then the last input character is inserted ARG times.
なしdelete-pair※ Delete a pair of characters enclosing the sexp that follows point.

右端の列は describe-function の結果を一生懸命コピペしたもの^^;。実際、和訳のマニュアルなどを読んでもその挙動を把握できないコマンドも多いです。一番よいのは、コマンドの定義箇所を直接参照することだと思います。

上の表の※印が付いた kill-backward-up-list, raise-sexp, insert-pair, delete-pair は、Emacs22 から追加されたコマンドです。これらに up-list を加えたコマンドのいずれも、キーバインドされていません。しかし、便利なので私はキーに割り当てています。とはいえ、空いているキーを探して割り当てるのは難しいので、新しくプレフィックスキーを定義しています。Emacs は、C-[ (ESCと同じ)を多用するので、個人的にはこの C-[ の2度押しでやっています。他にも、プレフィックスにすると良さそうなキーがありますね。

以下は、私が行っている設定です。

(define-prefix-command 'esc-esc-map)
(define-key esc-map "\e" 'esc-esc-map)
(define-key esc-esc-map "\e" 'keyboard-escape-quit)

;; キーバインドを追加
(define-key esc-esc-map "\C-h" 'kill-backward-up-list)
(define-key esc-esc-map "\C-u" 'up-list)
(define-key esc-esc-map "h" 'raise-sexp)

;; キーバインドの変更
(define-key esc-esc-map "\C-k" 'backward-kill-sexp)
(define-key esc-map "\C-m" 'back-to-indentation)

kill-backward-up-list と raise-sexp が分かり難そうなので、図入りで説明してみましょう。

kill-backward-up-list の図解

まず、下は編集前の状態です。キーバインドは上に書いた設定を行ったものとします。

before_edit.png

kill-backward-up-list は、ポイント位置に続く1個のS式を残して、そのS式を取り囲んでいるS式を引数分だけ取り除きます。したがって、C-u 2 C-[ C-[ C-h とタイプすると次のようになります。

kill-backward-up-list-2.png

let式を1個だけ残して、それを取り囲んでいる condition-case と、defun が取り除かれています。また、ポイントに続く1個のS式だけを残しますから、error も削除されています。
引数なしで実行した場合は、ポイント位置の let式を残して、1階層上の condition-case を取り除きます。あらかじめ書いておくと、引数なしで実行した場合、kill-backward-up-list は、次に説明する raise-sexp を引数なしで実行した場合と同じ編集結果になります。*1

kill-backward-up-list-1.png

raise-sexp の図解

raise-sexp は、ポイント位置の S式を引数分だけ残して、それらを取り囲んでいる S式をひとつだけ取り除くコマンドです。

編集前の状態。

before_edit.png

C-u 2 C-[ C-[ h とタイプしたところ。

raise-sexp-2

ポイント位置の S式を引数分の2個、つまり let と error を残して、それを囲んでいる condition-case が取り除かれています。

次は、C-[ C-[ h とタイプしたところ。1個(let)残して1個(condition-case)取り除かれています。引数なしで、kill-backward-up-list を実行したときと同じ結果です。

raise-sexp-1.png

kill-backward-up-list と raise-sexp は、良く似ているようで紛らわしいですが、纏めると下表のようになります。引数なしで実行した場合の挙動が同じなのがよく分かります(1個残して1個取り除く)。

kill-backward-up-listraise-sexp
取り除くポイント位置のS式を囲んでいるS式を引数階層分、取り除くポイント位置のS式を囲んでいるS式を1個、取り除く
残すポイント位置のS式を1個、残すポイント位置のS式を引数分、残す

*1実際には、S式の途中にポイントがあるような場合だと、引数なしで実行した場合の両者の挙動は若干異なります。raise-sexp の場合、ポイント位置のS式全体ではなく、ポイント位置から forward-sexp で移動したポイントの領域が残ります。

その他

先に挙げたコマンド表の中で、down-list, up-list, backward-up-list などもよく似ています。down-list が内側前方に入っていく感じだとすると、backward-up-list は、外側後方へ出る、up-list は、外側前方へ出るといった感じです。どれも便利なコマンドですから、ぜひ覚えましょう。


Last modified: Tue Dec 11 16:13:47 JST 2007
Copyright (C) 2007 Kazushi NODA All Right Reserved.

Valid HTML 4.01 Transitional Valid CSS