雑文発散

«前の日記(2014-10-08) 最新 次の日記(2014-10-10)» 編集
過去の日記

2014-10-09 [長年日記]

[Emacs] Emacs で Markdown 編集時に gfm-mode にすると word wrap が効いてしまうのを抑制する

markdown-mode に gfm-mode が含まれているのを知ってから、Markdown の編集時にはそれを使うようにしている。

ただ、gfm-mode でファイルを開くと、強制的に word-wrap が有効になってしまうのがちょっと自分とは合わなかった。毎回 M-x toggle-word-wrap を叩いて、word-wrap をオフにしていたんだけど、さすがにちょっとこの手順を何度も繰り返すのはエンジニアじゃないよなぁと思って、四苦八苦の記録。

M-x toggle-word-wrap の他にも、M-x set-variable word-wrap nilでもオフにすることができたので、まずはじめに gfm-mode の hook で word-wrap をオフにしてみた。

(add-hook 'gfm-mode-hook
      '(lambda()
         (setq word-warp nil)))

ところが、これだとうまくいかなかった。gfm-mode-hook が呼ばれていないのかと思って、hook に仕込んだ無名関数内に (message) を仕込んでプリントデバッグをしてみたら、しっかり呼ばれている。なんで word-wrap nil でうまく動かないのか分からない。

仕方ないので、今度は gfm-mode の中身を見る。

gfm-mode の実体は markdown-mode.el の中にある。markdown-mode の拡張として、その差分だけ定義している感じ。

gfm-mode の中では、visual-line-mode があればそれを、無ければ longline-mode を有効にしていた。

  (cond ((fboundp 'visual-line-mode)
         (visual-line-mode 1))
        ((fboundp 'longlines-mode)
         (longlines-mode 1)))

オレが使っている Emacs 24.4 には visual-line-mode が存在するので、そちらが有効になっていた。

では、こいつを無効にすれば良いのか?と思って、gfm-mode-hook に次のコードを追加した。

(add-hook 'gfm-mode-hook
      '(lambda()
         (visual-line-mode 0)))

これでも word-wrap が無効にならない。というか、visual-line-mode の無効化はこれで良いのかもあいまいなまま、次は visual-line-mode の実装を見て行ったら、この中で word-wrap が有効化されているのが分かった。

(define-minor-mode visual-line-mode
  "Toggle visual line based editing (Visual Line mode).
With a prefix argument ARG, enable Visual Line mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
the mode if ARG is omitted or nil.

When Visual Line mode is enabled, `word-wrap' is turned on in
this buffer, and simple editing commands are redefined to act on
visual lines, not logical lines.  See Info node `Visual Line
Mode' for details."

じゃあ、visual-line-mode の起動時に word-wrap をオフにしちゃえばいいんじゃないか?と思って、そちらの hook に word-wrap nil を仕込んでみた。

(add-hook 'visual-line-mode-hook
      '(lambda()
         (setq word-wrap nil)))

するとようやく gfm-mode でファイルを開いた時、word-wrap をオフにすることができた。

gfm-mode の動作をコントロールするのに、visual-line-mode の hook に設定するという流れは、何か間違っているような気がするのだけど、とりあえず期待の動作にはなっているので、いったんこれで良しとする。