坂田裕輔 / Emacsのウインドウレイアウト

Created Thu, 13 Feb 2025 11:56:46 +0900 Modified Thu, 13 Feb 2025 11:56:46 +0900
1595 Words

長年の悩み=ウインドウレイアウトを保存したい=が解決した

仕事をしていると、仕事に必要なファイルをいくつか開いて、それらを見ながら作業することが普通だ。

僕はEmacsで作業をしているときに、左側にファイルのリスト、右上に編集中のファイル、その下にコマンドの実行状況を表示することが多い。

Emacsのようなエディタは一度立ち上げたら終了させないのが、Unixの流儀だそうだが、Windowsのばあい、Windowsの再起動を要求されることがしばしばある。

Emacsを終了してしまうと、せっかく注意深く幅等を指定して保存しておいた画面レイアウトが崩れてしまう。

ウィンドウのレイアウトとそれぞれのウインドウに表示されているファイルの組み合わせを覚えていてくれるとすごく楽だ。

elscreenとかEybrowse、Perspectiveなどいろいろなものを試したが、レイアウトを保存できなかったり、挙動がよくわからなかったりで、うまくいっていなかった。

burlyで解決した

それがふと思い立って、また検索してみると、同じような悩みをみんな持っている事がわかった。Using EmacsのZamanskyさんが同じような悩みをEpisode 52で話していた。これ、どうにかなっているはずだ!と思い、Episodeの続きを探してみたら、Episode 76で解決していた。タイトルがBookmarksで始まっていたので、今まで気づかなかった。

burlyというツールをいれれば、問題が一気に解決する。

おまけに、このツールはレイアウトをEmacs標準のbookmarkに保存してくれるので、新しいファイルが増えることもない。

ウインドウレイアウトの例

ブログ執筆中

右側にファイル(エントリ)のリスト、左上に編集中の文書、左下にコマンドの実行状況(プレビュー用のサーバの動作)。

ブログの執筆中は過去の記事なんかもみることがあるので、そういうのを参照しながら執筆している。

./2025-02-13-12-43-13.png

長文執筆中

左側に文書のアウトライン(imenu-list)、右上に編集中の文書、右下にTask List。

右下にタスクリストのファイルをおいておくことで、執筆中に気になったことを、そこにメモ書きしていく。そうすると、気が散らなくてよい。

長文の執筆中は、左側を上下に分けて、下に参考資料を表示することもある。

プログラミング

左側にプロジェクト関係のファイル(Projectile)、右上に編集中のファイル、右下にコンソール(ログを表示)。

ブログ執筆とほぼ同じだ。考えてみると、画面を3分割させるのが標準的なレイアウトなのかも。

おまけの設定

ちょっとしたおまけだが、neotreeでファイルを開くと、最後に作成したウインドウにファイルを表示するようになるようだ。

編集ウインドウを上下に分けて、下にコンソールを表示していると、neotreeがそのウインドウにファイルを表示してしまうことがある。これは地味にストレスで、だんだんneotreeをつかわなくなる理由でもあった。

ChatGPTに聞いて以下の関数を作成してもらい、問題が解決した。あるファイルを開いているときに、そこからneotreeを開くと、neotreeが元のファイルがあったウインドウにに常にファイルを開いてくれるようになる。

ChatGPT、ありがたいね。

(defvar my-neotree-last-window nil
  "NeoTree を開く前にアクティブだったウィンドウを記憶する。")

(defun my-neotree-open-in-last-window ()
  "NeoTree で選択したファイルを、NeoTree を開く前にアクティブだったウィンドウで開く。"
  (interactive)
  (let ((node (neo-buffer--get-filename-current-line))) ;; 選択中のファイル名取得
    (when (and node my-neotree-last-window)
      (select-window my-neotree-last-window)  ;; NeoTree を開く前のウィンドウに戻る
      (find-file node))))  ;; ファイルを開く

(defun my-neotree-save-last-window ()
  "NeoTree を開く前のウィンドウを記憶する。"
  (unless (eq (selected-window) (neo-global--get-window))
    (setq my-neotree-last-window (selected-window))))  ;; NeoTree を開く前のウィンドウを保存

;; NeoTree の `RET` や `TAB` をカスタマイズ
(with-eval-after-load 'neotree
  (define-key neotree-mode-map (kbd "RET") 'my-neotree-open-in-last-window)
  (define-key neotree-mode-map (kbd "TAB") 'my-neotree-open-in-last-window)
  (advice-add 'neotree-show :before 'my-neotree-save-last-window))  ;; NeoTree を開く前にウィンドウを保存