Emacs の ruby-mode で二重の式展開があるとハイライトが壊れる問題


問題

Emacs の ruby-mode で二重の式展開があるとハイライトが壊れてしまいます。たとえば下の ruby プログラムをみてください。

puts の引数に二重の式展開があり、それ以降の色付けがおかしくなっています。

解決策

ruby-mode のソースコードを開きます。私の場合は cask を使ってインストールしているので下記のパスにありました。

/Applications/Emacs.app/Contents/Resources/lisp/progmodes/ruby-mode.el.gz

これを開いて 108 行目付近を下記のように修正します。 注意:この修正は私が適当に考えた正規表現を使っているので、他の ruby プログラムのハイライトがおかしくなってしまう可能性があります。たとえば三重式展開は配慮していません。

  (defconst ruby-expression-expansion-re
-    "\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\|\\$[^a-zA-Z \n]\\)\\)"))
+    "\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#{[^{^}]*#{[^}]*}[^}]*}\\)\\|\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\|\\$[^a-zA-Z \n]\\)\\)"))

下記を実行してコンパイルし ruby-mode を再読込します。

M-x byte-compile-file /Applications/Emacs.app/Contents/Resources/lisp/progmodes/ruby-mode.el.gz
M-x load-file /Applications/Emacs.app/Contents/Resources/lisp/progmodes/ruby-mode.elc

さっきのファイルを閉じて開き直すと…

解決!

解決策2

会社でアドバイス頂戴したところによると、わざわざコンパイルしなくても定数を上書きできるそうです。

init.el
 (defalias '~ruby-syntax-propertize-function
    (syntax-propertize-rules
     ;; 文字列2重展開があるとシンタックスハイライトがおかしくなるので、 ruby-expression-expansion-re を修正したやつを追加
     ("\\(?:[^\\]\\|\\=\\)\\(\\\\\\\\\\)*\\(#{[^{^}]*#{[^}]*}[^}]*}\\)\\|\\(#\\({[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\|\\(\\$\\|@\\|@@\\)\\(\\w\\|_\\)+\\|\\$[^a-zA-Z \n]\\)\\)"
      (0 (ignore (ruby-syntax-propertize-expansion))))))

  (defun ~ruby-fix-syntax-propertize ()
    (add-function :before (local 'syntax-propertize-function) '~ruby-syntax-propertize-function))
  (add-hook 'ruby-mode-hook '~ruby-fix-syntax-propertize t)