折り畳み表示

emacs を使いだして困ったことの一つが、ファイルを折り畳み表示する (一覧性を高める) 方法がなかなか分からなかったことです。

Vim ではインデント単位で折り畳む設定が便利なんですが (set fdm=indent)、emacs ではどうするのか、調べることすらままならない状態でした。

ようやく "Outline minor mode" というものが使えることが分かり (折り畳み = folding という用語では見つからないわけです)、さらに以下の補助関数が出来上がりました:

(defun outline-hide-body (&rest rxs)
  (outline-minor-mode t)
  (and rxs
       (set (make-local-variable 'outline-regexp)
            (join-list rxs "\\|")))
  (hide-body))

(defun join-list (lst &optional delim)
  (cond ((null lst) "")
        ((null (cdr lst)) (car lst))
        (t
         (concat (car lst)
                 (or delim "")
                 (join-list (cdr lst) (or delim ""))))))

言語を問わず手軽に利用できるようになっています。outline-hide-body という関数に任意の数の正規表現を渡すと、それに従って折り畳みが行われます。

なお、多くのスクリプト言語にあるような配列 join 関数が見つけられなかったため、再発明かもしれませんが join-list という関数も併せて作ってみました。

使用例:

(add-hook 'javascript-mode-hook '(lambda()
                                   (outline-hide-body "//+" "function")))

行コメントまたは "function" で始まる行から折り畳んで表示されます。


追記 [20070409]:

コメントにて

(join-list rxs "\\|")

の部分は

(mapconcat 'identity rxs "\\|")

と置き換えられることを教えていただきました (あらためて、有り難うございます)。

ヘルプによると、引数リストは

(mapconcat FUNCTION SEQUENCE SEPARATOR)

となっていて、まさに "join" がマッピング関数を取れるように進化したような関数ですね。重宝しそうです。