Emacsでは、Markdownでも見出しをアウトラインとして扱えるため、折りたたみや章単位の移動などの編集作業がスムーズにできます。
markdown-mode と outline-minor-mode を組み合わせ、最低限の構造操作に絞った環境を整えました。

;; Markdown編集
(use-package markdown-mode
:ensure t
:mode (("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode))
:config
(setq markdown-command "markdown"))
(with-eval-after-load 'outline
(define-key outline-minor-mode-map (kbd "C-c C-n")
#'outline-next-visible-heading)
(define-key outline-minor-mode-map (kbd "C-c C-p")
#'outline-previous-visible-heading)
(define-key outline-minor-mode-map (kbd "C-c C-u")
#'outline-up-heading))Code language: Lisp (lisp)
1. markdown-mode
Emacsで文章を書くとなると、Org modeが中心ですが、最近はMarkdownがよく使われます。
ChatGPTなどの出力コピーも、Markdown記法が使われています。
長いMarkdownを編集するときに、見出しを構造として扱えるだけで、作業はかなり楽になります。
そこで、Markdown編集には markdown-mode を使うことにしました1。
これは事実上の標準で、余計な癖がなく、長く使えそうです。
;; Markdown編集
(use-package markdown-mode
:ensure t
:mode (("\\.md\\'" . markdown-mode)
("\\.markdown\\'" . markdown-mode)))Code language: Lisp (lisp)
2. 見出しをTABで開閉する
Markdownの見出しは、# の数で階層が決まっており、アウトラインそのものです。
TABキーを押すだけで、見出しの開閉が使えます。
また、Shift+TABキーでは、全体の見出しの開閉ができます。
2.1. 見出し移動のキーバインド
次は、見出し間の移動です。
- 次の見出しへ移動(C-c C-n)
- 前の見出しへ移動(C-c C-p)
- 親見出しへ戻る(C-c C-u)
長い記事でも、今書いている章だけを開いて、他は畳む。
見出し以下が一塊として扱えるので、「章を丸ごと入れ替える」操作が安全にできます。
2.2. 見出し単位の移動や上げ下げ(outline-minor-mode)
見出し単位の編集は、outline-minor-modeのコマンドを使います。
よく使うものを C-c と 方向キーで実行できるようにしました。
- サブツリーを上に移動
C-c UP - サブツリーを下に移動
C-c DOWN - サブツリーのレベルを上げる
C-c LEFT - サブツリーのレベルを下げる
C-c RIGHT
(with-eval-after-load 'outline
(define-key outline-minor-mode-map (kbd "C-c <down>")
#'outline-next-visible-heading)
(define-key outline-minor-mode-map (kbd "C-c <up>")
#'outline-previous-visible-heading)
(define-key outline-minor-mode-map (kbd "C-c <left>")
#'outline-up-heading)
(define-key outline-minor-mode-map (kbd "C-c <right>")
#'outline-forward-same-level))Code language: Lisp (lisp)
- カーソルが リスト項目上 → リスト項目(+子)を移動
- それ以外(見出し上) → 見出しサブツリー全体を移動
3. 見出し単位の切り取り・貼り付け(自作関数)
kill と yank だけでも章ごとの移動はできますが、操作ミスのリスクがあります。
そのため、markdown-kill-subtreeとmarkdown-yank-subtree関数を作りました。
C-c C-k と C-c C-y に割り当てました。
Org mode の org-cut-subtree / org-paste-subtree と似た操作感です。
3.1. markdown-kill-subtree の実装
削除直後に次の見出しへ移動するため、連続した章の削除や整理がスムーズになります。
(defun markdown-kill-subtree ()
"Kill the current Markdown subtree."
(interactive)
(outline-mark-subtree)
(kill-region (region-beginning) (region-end))
(setq mark-active nil)
(outline-next-visible-heading))Code language: Lisp (lisp)
3.2. markdown-yank-subtree の実装
見出しの先頭で挿入が行われるため、位置がずれません。
挿入後も挿入した章の見出しにカーソルが戻るため、続けて操作しやすくなります。
(defun markdown-yank-subtree ()
"Yank the killed Markdown subtree."
(interactive)
(outline-back-to-heading)
(yank)
(newline)
(outline-back-to-heading))Code language: Lisp (lisp)
3.3. 実際の使用例
例えば、以下のような構成の記事があったとします:
# はじめに
## 背景
## 目的
# 方法
## 環境構築
## 実装
# まとめCode language: PHP (php)
「方法」の章を「はじめに」の前に移動したい場合:
- 「方法」の見出し上で
C-c C-k - 「はじめに」の見出し上へ移動
C-c C-y
これだけで、章全体が安全に移動します。
- markdown-modeはJason Blevinsによって開発され、2007年から継続的にメンテナンスされているEmacsの定番パッケージです。GitHubで2,000以上のスターを獲得しており、MELPA経由で簡単にインストールできます。 – jrblevin/markdown-mode – GitHub