さて、いくつかの基本をまっすぐにしましょう。
構文テーブルのネストが可能です
構文テーブルは、バッファ全体に対してグローバルである必要はありません。それらをテキストプロパティとして特定の領域に適用できます。これは、バッククォートで囲まれた領域にのみ構文テーブルを適用できることを意味しますelisp
。
どうやってやるの?
これを行う方法の1つを次に示します。このメソッドは、フォントロックがバッファを通過する直前にそれを実行するため、フォントロックの問題を特に防止する必要があります。
(defun endless/set-syntax-then-fontify (beg end loudly)
"Apply elisp syntax table to relevant regions before calling font-lock."
(save-match-data
(save-excursion
(save-restriction
(widen)
(narrow-to-region beg end)
(while (search-forward "`" nil 'noerror)
;; Using `end' here excludes the `, I don't know which syntax you
;; want to apply to that.
(let ((left (match-end 0)))
(when (search-forward "`" nil 'noerror)
(add-text-properties
left (match-beginning 0)
(list 'syntax-table emacs-lisp-mode-syntax-table))))))))
(font-lock-default-fontify-region beg end loudly))
メジャーモードの定義では、以下を追加する必要があります。
(set (make-local-variable 'font-lock-fontify-region-function)
#'endless/set-syntax-then-fontify)
構文テーブルは構文強調表示と同じではありません
シンタックスハイライター(フォントロックシステム)は、情報の一部としてシンタックステーブルを使用するため、上記のソリューションでは、ハイライターが正常に機能しないようにする必要があります。
ただし、これはデータの一部にすぎません。elispバッファーで表示されるように、バッククォート内のテキストも正確に色付けしたい場合は、上記の関数を拡張して具体的に行う必要があります。
(defun endless/set-syntax-then-fontify (beg end loudly)
"Apply elisp syntax table to relevant regions before calling font-lock."
(save-match-data
(save-excursion
(save-restriction
(widen)
(narrow-to-region beg end)
(while (search-forward "`" nil 'noerror)
;; Using `end' here excludes the `, I don't know which syntax you
;; want to apply to that.
(let ((left (match-end 0)))
(when (search-forward "`" nil 'noerror)
(add-text-properties
left (match-beginning 0)
(list 'syntax-table emacs-lisp-mode-syntax-table))))))))
(font-lock-default-fontify-region beg end loudly)
;; Do some specific elisp fontifying here
(save-match-data
(save-excursion
(save-restriction
(widen)
(narrow-to-region beg end)
(while (search-forward "`" nil 'noerror)
(let ((left (match-end 0)))
(when (search-forward "`" nil 'noerror)
;; Call some function to fontify elisp between `left' and (match-beginning 0)
)))))))