Braindump

Emacs の Title bar と Mode line をカスタマイズ

December 14, 2021
emacs

この記事は Emacs Advent Calendar 2021 の15日目の記事です.

はじめに #

この記事では以下の画像のような title-bar と mode-line のカスタマイズ方法を紹介する.

/images/2021-12-customize-titlebar-and-modeline.jpg

Title bar のカスタマイズ #

この項目でやっていることは以下の記事とほとんど同じ

時刻表示するための設定は以下のとおり.

;; This shoud be set before exec `display-time`.
(setq display-time-string-forms '((format "%s %s %s" dayname monthname day)
                                  (format "  %s:%s" 24-hours minutes))
      frame-title-format '(" - " display-time-string " - "))

(display-time)

ポイントは display-time-string-forms に書式を設定してから (display-time) を実行しているところ.この順番を守らないと display-time-string-forms の default 値が使われてしまう (と こちらの記事に書いてあった).

title-bar をカスタマイズするためには frame-title-format をいじる. frame-title-format のより詳しい説明については Emacs Wiki を参照されたい.

display-time-string-forms の書式は helpful-variable で見つかる Document に詳しく書いてある.

/images/2021-12-display-time-string-forms.jpg

Mode line のカスタマイズ #

Mode line に表示される要素は mode-line-format が司っている.default値は以下のようになっている.

/images/2021-12-modeline.jpg

この中の任意の要素を置き換えることで mode line の表示をカスタマイズしていく.下の例では "%e"`mode-line-client を置き換えている.

(let ((format (cl-subst "Uwaaaaaaaaa!! " "%e"
                        (default-value 'mode-line-format)
                        :test #'equal)))
  (setq-default mode-line-format format))


(let ((format (cl-subst "Foooooooooo!! " 'mode-line-client
                        (default-value 'mode-line-format)
                        :test #'equal)))
  (setq-default mode-line-format format))
/images/2021-12-modeline-test.jpg

この置き換えは mode line のカスタマイズパッケージである moody.el が提供している moody-replace-element そのものである.

私は mode line パッケージとして moody.el を使用しているため,それを用いた設定を下に示す.パッケージ管理には leaf.el を用いている ( leaf入門記事).bufferの状態表示にはemacs-28から実装された絵文字を利用している.(時間があれば説明を追記します)

(leaf moody
    :ensure t
    :config
    (setq my--modeline-gui-rw-symbol "📖"
          my--modeline-tty-rw-symbol "RW"

          my--modeline-gui-ro-symbol "📙"
          my--modeline-tty-ro-symbol "RO"

          my--modeline-gui-mod-symbol "✏️"
          my--modeline-tty-mod-symbol "**")

    (defun my--modeline-status ()
      "Return buffer status: default symbols are read-only (📙)/(RO),
modified (✏️)/(**), or read-write (📖)/(RW)"
      (let ((read-only   buffer-read-only)
            (modified    (and buffer-file-name (buffer-modified-p))))
        ;; Use status letters for TTY display
        (cond
         (modified (if (display-graphic-p)
                       my--modeline-gui-mod-symbol
                     my--modeline-tty-mod-symbol))
         (read-only (if (display-graphic-p)
                        my--modeline-gui-ro-symbol
                      my--modeline-tty-ro-symbol))
         (t (if (display-graphic-p)
                my--modeline-gui-rw-symbol
              my--modeline-tty-rw-symbol)))))

    (setq x-underline-at-descent-line t
          moody-mode-line-height 26)
    (moody-replace-mode-line-buffer-identification)
    (moody-replace-vc-mode)
    (moody-replace-eldoc-minibuffer-message-function)
    (moody-replace-element 'mode-line-frame-identification
                           '(:eval
                             (propertize
                              (concat
                               " " (alist-get 'name (tab-bar--current-tab)) " ")
                              'face '(:weight bold))))
    (moody-replace-element 'mode-line-mule-info '(""))
    (moody-replace-element 'mode-line-client '(""))
    (moody-replace-element 'mode-line-remote '(""))
    (moody-replace-element 'mode-line-modified
                           '(:eval (my--modeline-status))))

buffer状態の表示を適応的に変更するコードは bespoke-modeline.elこちらを参考にさせて頂いた.

おわりに #

本投稿では title bar と mode line のカスタマイズを紹介した.

説明不足で申し訳ないが,時間があれば追記する.