Emacsの起動画面のカスタマイズについて

最近余裕が全然ないため、今回は小ネタです。

Emacsの起動画面は、常時起動組にとってはほとんど目にする機会が無く、カスタマイズのモチベーションがなかなかわきません。自分も週に何度か目にする程度で、デスクトップの壁紙並にほとんど見る機会が無いわけです。

しかしながら逆に考えると、普段目にすることがないレアな画面だけに、見ただけで気分が盛り上がるようなカスタマイズをしておけば、Emacs立ち上げ直後のテンションが低い状態から一気に気分が盛り上がって89%もの進捗をあげることが出来るかもしれません。

また、壁紙はプロジェクターに接続した時にちらっと見えて気まずい空気が流れてしまうことがあるように、Emacsもいつプレゼン中にクラッシュして起動し直すことがあるか分かりません。そんな時に、見ている人が思わず オッ とツイートしてしまうような画面にしておけば、恥ずかしい思いをせずに済むのではないでしょうか。

<img src="https://qiita-image-store.s3.amazonaws.com/0/603/1841716c-5be8-ab4e-a0dd-a3943f596f2d.png" width=400>
 **盛り上がりそうな起動画面例**

ということで、起動画面のカスタマイズについてすこし書いてみたいと思います。

# デフォルトの起動画面

GUIでのEmacsの起動画面は以下のようです。

|Emacs 24.5|Emacs 26.0.xx|
|---|---|
|![emacs-24.png](https://qiita-image-store.s3.amazonaws.com/0/603/e271c6dc-8add-1810-3709-ff77a3bb6f4b.png) | ![emacs-25.png](https://qiita-image-store.s3.amazonaws.com/0/603/f670c4bf-847d-df3f-5245-94be4eddad92.png)|

画面上中央にEmacsのロゴが入り、下はEmacsについての情報が並んでいます。リンクをカーソールで選択したりマウスでクリックすると、Webサイトや付属のドキュメントファイルやInfoが表示されます。入門ドキュメントにすぐにアクセスできるのは便利そうですが、実はこのドキュメントを見ようとするだけでも基本的なEmacsの操作が要求されるため、なかなか見る機会は無さそうです。

Emacsロゴについてはバージョンが上がる度に少しずつ変化しており、25からはフラットなデザインになりました。

# ロゴ画像の変更

まず、簡単なロゴ画像を変更する方法です。

カスタマイズ変数の `fancy-splash-image` に表示させたい画像を設定します。 `M-x customize-apropos` で fancy と入れて設定項目を呼び出すか、 .emacs に以下のように直接書いて設定します。

```elisp
;; 設定例
(setq fancy-splash-image (expand-file-name "~/201406_kei_201309rev.png"))
```

ファイル名はフルパスが要求されますので、 `expand-file-name` を通しておくと便利です。
設定できる画像の種類ですが、 Emacs が読めるファイルであれば大丈夫です。 jpeg や png あたりが無難だと思います。
また、絵のサイズに条件があり、画像の高さがあまり大きいと表示されません。感覚的には半分ぐらいより小さい必要がありますが、具体的には `use-fancy-splash-screens-p` 関数を実行して `t` になればOKです。詳しくは `startup.el` コードを参照してみて下さい。

Emacsを再起動するか、 `M-x display-about-screen` とすると以下のように起動画面のロゴが変わります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/603/e7733d7d-89b6-a2ad-a28a-4d452edc6e7a.png" width="400" />
 **※画像出典：プロ生さん(http://pronama.azurewebsites.net/pronama/)**

いちいち再起動するのは大変ですので、 `display-about-screen` で何度も表示しながら調整することになると思います。その際、Emacsでは一度読み込んだ画像はキャッシュされて再読込されないので、もし画像を修正した場合は `clear-image-cache` 関数を呼ぶようにしてください。

ちなみに、 `startup.el` の `fancy-splash-head` のコードを見ると、謎の画像センタリング方法が書いてあり参考になります。

# もっとかっこいい画面にしたい

単純にロゴ画像を変えるだけでは、硬派な Emacs ぽさがまだ残っており少々盛り上がりに欠けます。あまりカスタマイズできるポイントも少ないですし、そもそも起動画面のコードもシンプルなので、まるっきり違うバッファを作るというのはいかがでしょうか。

例えば、適当な壁紙的画像を imagemagick の `convert` コマンド等で動的に装飾してみました。

```elisp
;; 独自起動画面バッファ
(defun my-fancy-startup-screen (&rest args)
  (clear-image-cache)
  (let* ((pwidth (window-pixel-width))
         (pheight (* pwidth 0.75))
         (file (expand-file-name "~/some-background.jpg"))
         (tfile "/tmp/emacs-splash.jpg")
         (color "white")
         (font "/usr/share/fonts/corefonts/times.ttf")
         (rt (/ pwidth 1000.0))
         (size1 (* 80.0 rt)) (size2 (* 16.0 rt)) (size3 (* 24.0 rt))
         (x1 (* 50 rt)) (y1 (- pheight (* 120 rt)))
         (x2 (* 50 rt)) (y2 (- pheight (* 60 rt)))
         (x3 (* 40 rt)) (y3 (* 40 rt))
         (qtxt (replace-regexp-in-string "\t" "    " (with-temp-buffer (call-process "fortune" nil t nil) (buffer-string))))
         (args
          (list file "-resize" (format "%dx%d" (- pwidth 1) (- pwidth 1))
                "-fill" color "-font" font
                "-pointsize" (format "%d" size1) "-annotate" (format "+%d+%d" x1 y1) "GNU Emacs"
                "-pointsize" (format "%d" size2) "-annotate" (format "+%d+%d" x2 y2) (emacs-version)
                "-pointsize" (format "%d" size3) "-annotate" (format "+%d+%d" x3 y3) qtxt
                tfile)))
    (apply 'call-process "convert" nil nil nil args)
    (let ((frame (fancy-splash-frame)))
      (save-selected-window
        (select-frame frame)
        (switch-to-buffer "*About GNU Emacs*")
        (setq buffer-undo-list t)
        (let ((inhibit-read-only t))
          (erase-buffer)
          (insert (propertize " " 'display (create-image tfile)) "\n\n")
          (set-buffer-modified-p nil)
          (goto-char (point-min))
          (force-mode-line-update))
        (use-local-map splash-screen-keymap)
        (setq buffer-read-only t)))))

;; fancy-about-screen 関数を乗っ取る
(advice-add 'fancy-about-screen :around 'my-fancy-startup-screen)

;; 乗っ取り解除用
;; (advice-remove 'fancy-about-screen 'my-fancy-startup-screen)

```

適当な画像やフォントを準備し、このコードを評価して `M-x display-about-screen` すると、以下のような画面になります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/603/c10b98c2-6800-b6e8-feec-3965214b292f.png" width=500 />
 **意識高い起動画面**

`fortune` コマンドによる日替わり名言も追加されて、かなり意識高い画面になりました。起動画面を表示するタイミングで毎回画像を生成するため、若干起動時間が伸びますが、毎回違う画像を選ぶようにしたり、あるいはWebからネコ画像を検索してダウンロードしてくるといったようなセレンディピティな展開も可能です。もちろん非同期で画像を扱うようにすれば、急いでいるときはスキップさせるといったコードにも出来ます。

なお、今回はあまり真面目に考えずに advice を使ってしまいました。 `startup.el` を眺めると、もっと別のカスタマイズ方法が見つかるかも知れません。

# もっと実用的に

画像とかどうでもいいので、もっと実用的な起動画面が欲しいという場合は、 `dashboard` パッケージはいかかでしょうか？

- [GitHub - rakanalh/emacs-dashboard: A shameless extraction of Spacemac s startup screen](https://github.com/rakanalh/emacs-dashboard)

<img src="https://github.com/rakanalh/emacs-dashboard/raw/master/screenshot.png" width="400" />
 **dashboard起動画面**


Recent Files, Bookmarks, Projects などのような、実用的な一覧が表示され、すぐに作業が再開出来て便利そうです。
Spacemacs の起動画面から持ってきたアイデアだそうです。

# そもそも起動画面を表示しない

最後に、起動画面を表示しない方法ですが、以下のように .emacs に書きます。

```elisp
(setq inhibit-startup-screen t)
```

おそらく、なんとなくですが、これが一番ニーズが多いのではないでしょうか。


以上になります。