EmacsでMarkdownを書くときの折り返しをいい感じにする設定
EmacsでMarkdownを書くとき、画面上の行の折り返しに関していい感じの設定をしてみます。
Emacsは執筆時点での最新バージョン29.1を使っています。
何が問題?
Emacsでテキストファイルを書く際にはauto-fill機能を有効にしていました。ですが、Markdownなどの記法では勝手に改行されると困ることがあります。
例えばリンク関係。[〜](〜)
の途中で勝手に改行されると都合が悪いです。
箇条書きなども途中で改行が入ると出力結果が変わってしまう。
- 箇条書き。
改行が入った場合。 - 箇条書き。改行が無い場合。
ということでauto-fillは無効にするのですが、以下のような編集画面になります。truncate-lines
が有効かどうかでどちらかになります。ちなみにM-x toggle-truncate-lines
で切り替わります。(画像の緑の四角はカーソルです)
truncate-lines有効
truncate-lines無効
truncate-lines
有効の場合は良さそうに見えますが、カーソルの移動が論理行単位なので編集しにくいです。具体的には、上記の例だとEmacs
のE
にカーソルがある状態で下に1つ移動するとn
ではなくその下の空行に行きます。他にも論理行と表示上の物理行の違いで色々と編集しにくいです。
一方、truncate-lines
無効だと長い行はカーソルを右に移動しないと見ることができず、非常に一覧性が悪いです。これも編集しにくい。
上記問題を解決するEmacs設定を調べてみました。
Emacsの設定
何はともあれ、最終的に自分の設定はこうなりました。
(use-package markdown-mode
:mode ("\\.md\\'" . markdown-mode)
:init
(add-hook 'markdown-mode-hook #'turn-off-auto-fill)
(add-hook 'markdown-mode-hook #'turn-on-visual-line-mode))
(use-package word-wrap-mode
:hook (visual-line-mode . word-wrap-whitespace-mode)
:config
(add-to-list 'word-wrap-whitespace-characters ?\]))
(use-package visual-fill-column
:hook (visual-line-mode . visual-fill-column-mode)
:init
(setq visual-line-fringe-indicators '(left-curly-arrow nil))
:config
(setq visual-fill-column-width 78))
(use-package adaptive-wrap
:hook (visual-line-mode . adaptive-wrap-prefix-mode))
markdown-mode
まずmarkdown-modeをインストールします。
markdown-modeではauto-fillを無効にして、visual-line-modeを有効にしています。
(add-hook 'markdown-mode-hook #'turn-off-auto-fill)
(add-hook 'markdown-mode-hook #'turn-on-visual-line-mode)
visual-line-modeはEmacs標準に含まれていて、カーソル移動を物理行単位にしてくれます。
参考: Visual Line Mode (GNU Emacs Manual)
word-wrap-whitespace-mode
visual-line-modeを有効時にすると、右端の折り返しが単語単位(word-wrap)になる効果もあります。この「単語単位」というのが曲者で、スペースかタブで区切られたものを単語と認識します。つまり英語ならうまく機能しますが、日本語のように単語をスペースで区切らない言語だとうまく機能しません。特に技術系テキストのような英単語まじりの日本語になると都合が悪いです。
visual-line-mode無効
visual-line-mode有効
スペースがenglish words
の部分にしかないため、そこで折り返されていて不自然な感じになってしまっています。
これを解決するためには、スペース、タブ以外の文字も単語区切りとして認識させるため、word-wrap-whitespace-mode
を有効にします。これはEmacs標準のword-wrap-mode.elに含まれています。
visual-fill-columnとword-wrap-whitespace-mode有効
さらにリンク表記の]
も単語区切りとして認識させてみます。
(add-to-list 'word-wrap-whitespace-characters ?\])
すると以下のように[〜]
の途中で切られていたのが、
word-wrap-whitespace-modeデフォルト設定
以下のように]
の後で切られるようになりました。
word-wrap-whitespace-mode追加設定
visual-fill-column
visual-line-mode
だと折り返しはウィンドウの右端になりますが、それを任意のカラム位置にするのがvisual-fill-columnです。これもインストールします。
visual-fill-column-width
を設定するとそのカラム位置で折り返してくれます。自分は78に設定しました。
(setq visual-fill-column-width 78)
あとfringe部分の表示設定もしていて、折り返された行のfringeに矢印を表示するかどうかがvisual-line-fringe-indicators
で設定できます。自分は左側のみに表示させています。
(setq visual-line-fringe-indicators '(left-curly-arrow nil))
左右両方に表示させる場合は以下です。
(setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow))
adaptive-wrap
adaptive-wrapのadaptive-wrap-prefix-mode
を使うと、リストなどで折り返しがあった場合にインデントを付けてくれます。これもインストールします。
adaptive-wrap-prefix-mode無効
adaptive-wrap-prefix-mode有効
表示上はインデントが付いて行始まりにスペースがあるように見えますが、実際のテキストファイル上にはスペース等は入りません。リストで折り返しが入っても見やすくなります。
禁則処理
日本語の禁則処理まわりを考慮する場合は、上記設定とは別に以下を設定に書いておくと良いかもしれません。(他の設定等で自動で読み込まれているなら、明示的に書かなくても大丈夫)
(require 'kinsoku)
まとめ
Zennで記事を書くときはMarkdown記法で書くわけですが、Emacsで書こうとしたらちょっと不便だったので、良い設定ができないかと調べた結果です。Emacs 29.1に新しく入ったword-wrap-whitespace-mode
を見つけたのが一番の収穫かもしれません。
まだ一部で微妙なところもありますが、とりあえず常用できる設定になったのではないかと思います。
Discussion