モードラインの表示を少しだけシンプルにする。

Emacs を拡張していくと、モードラインの表示が長くなりすぎてしまいます。現在の表示がこんな感じ。

マイナーモードの表示部分が長過ぎるので、その部分を折り畳めるようにすると、こんな感じになります。

M-x toggle-mode-line-minor-modes か mode-line-modes の横のコロン「:」をクリックでトグルできます。コードは以下。

(defvar mode-line-minor-modes nil
  "実際に折り畳まれる部分。")

(defun mode-line-minor-modes ()
  "変数 `mode-line-minor-modes' を設定する。"
  (unless (local-variable-p 'mode-line-modes)
    (make-local-variable 'mode-line-modes))
  (unless mode-line-minor-modes
    (setq mode-line-minor-modes
          (catch 'res
            (dolist (elt (default-value 'mode-line-modes) 'none)
              (when (and (consp elt)
                         (equal (car elt) :propertize)
                         (member '("" minor-mode-alist) (cdr elt)))
                (throw 'res elt)))))))

(defun toggle-mode-line-minor-modes ()
  "モードライン上のマイナーモードの表示/非表示を切り替える。"
  (interactive)
  (mode-line-minor-modes)
  (let* ((desc-fn (lambda () (interactive)
                    (describe-function 'toggle-mode-line-minor-modes)))
         (format `(:propertize
                   ":"
                   mouse-face
                   mode-line-highlight
                   local-map
                   (keymap (mode-line keymap
                                      (mouse-2 . ,desc-fn)
                                      (down-mouse-1
                                       . toggle-mode-line-minor-modes))))))
    (cond
     ((equal mode-line-minor-modes 'none)
      ;; 折り畳める部分が存在しない
      nil)
     ((member mode-line-minor-modes mode-line-modes)
      ;; 折り畳む
      (setq mode-line-modes
            (let ((lst (remove mode-line-minor-modes mode-line-modes)))
              (if (member format lst) lst (cons format lst)))))
     (t
      ;; 伸長する
      (setq mode-line-modes (cons format (default-value 'mode-line-modes)))))))

;; 特定のモードに対して常に有効にする。
(add-hook 'emacs-lisp-mode-hook 'toggle-mode-line-minor-modes)