orgバッファと専用編集バッファのコードの見た目を揃える
2025年にもなってタブスペースで悩むという貴重な体験をしましたが、無事に好みの設定にできました。
まず、普段編集する emacs-lisp-mode のファイルですが、他人様のファイルで特に指定のない状態ではインデントがタブ8で書かれていることも多いです。これは単純に tab-width
のデフォルト値が 8
だけという理由だと思いますが、emacs-lisp-mode のファイルを編集するだけならなんら問題ないです。
問題なのは、 org バッファ内の emacs lisp コードです。私は普段は、インデントはスペース2で統一しているので、org バッファ内の emacs lisp コードを org-edit-special (C-c ')
を呼び、専用バッファを emacs-lisp-mode で編集してから org バッファに戻ってくると、レイアウトが壊れることになります。タブで表現された箇所が幅8から幅2に縮むためですね。
解決策は、org バッファに戻る時に、タブ8をスペース2に変換してしまう、というシンプルなもので、次のようにしてみました。これで普段の見た目も維持され、さらにGitHubに配置するファイルの表示や、エクスポートしたHTMLファイルのレイアウトも崩れなくなりました。
(with-eval-after-load "org-src"
;; tab-width=8, indent-tabs-mode=t
(advice-add 'org-edit-special :after #'my-format-emacs-lisp-buffer)
;; tab-width=2, indent-tabs-mode=nil
(advice-add 'org-edit-src-abort :before #'my-format-emacs-lisp-for-org-buffer)
(advice-add 'org-edit-src-exit :before #'my-format-emacs-lisp-for-org-buffer))
;;;###autoload
(defun my-format-emacs-lisp-buffer ()
(interactive)
(when (eq major-mode 'emacs-lisp-mode)
(my-emacs-lisp-mode-conf)
(save-excursion
(save-restriction
(widen)
(untabify (point-min) (point-max))
(tabify (point-min) (point-max))
(indent-region (point-min) (point-max))))))
;;;###autoload
(defun my-format-emacs-lisp-for-org-buffer ()
(interactive)
(when (eq major-mode 'emacs-lisp-mode)
(setq-local indent-tabs-mode nil)
(setq-local tab-width 2)
(setq indent-line-function 'org-indent-line)
(save-excursion
(save-restriction
(widen)
(untabify (point-min) (point-max))
(indent-region (point-min) (point-max))))))
;;;###autoload
(defun my-emacs-lisp-mode-conf ()
(setq-local indent-tabs-mode t)
(setq-local tab-width 8)
(setq indent-line-function 'lisp-indent-line))
(when (autoload-if-found '(emacs-lisp-mode)
"elisp-mode" nil t)
(push '("\\.el\\'" . emacs-lisp-mode) auto-mode-alist)
(add-hook 'emacs-lisp-mode-hook #'my-emacs-lisp-mode-conf))