Answers:
下面的代码使用带有函数的字体锁定规则而不是regexp,该函数$VAR
仅在出现在双引号字符串内时才搜索的出现。该函数(syntax-ppss)
用于确定这一点。
字体锁定规则使用该prepend
标志将其自身添加到现有字符串突出显示的顶部。(请注意,许多程序包都t
为此使用。不幸的是,这会覆盖现有突出显示的所有方面。例如,使用时prepend
将保留字符串背景色(如果有),同时替换前景色。)
(defun sh-script-extra-font-lock-is-in-double-quoted-string ()
"Non-nil if point in inside a double-quoted string."
(let ((state (syntax-ppss)))
(eq (nth 3 state) ?\")))
(defun sh-script-extra-font-lock-match-var-in-double-quoted-string (limit)
"Search for variables in double-quoted strings."
(let (res)
(while
(and (setq res
(re-search-forward
"\\$\\({#?\\)?\\([[:alpha:]_][[:alnum:]_]*\\|[-#?@!]\\)"
limit t))
(not (sh-script-extra-font-lock-is-in-double-quoted-string))))
res))
(defvar sh-script-extra-font-lock-keywords
'((sh-script-extra-font-lock-match-var-in-double-quoted-string
(2 font-lock-variable-name-face prepend))))
(defun sh-script-extra-font-lock-activate ()
(interactive)
(font-lock-add-keywords nil sh-script-extra-font-lock-keywords)
(if (fboundp 'font-lock-flush)
(font-lock-flush)
(when font-lock-mode
(with-no-warnings
(font-lock-fontify-buffer)))))
您可以通过将最后一个函数添加到合适的钩子来调用use,例如:
(add-hook 'sh-mode-hook 'sh-script-extra-font-lock-activate)
2
将字体锁定规则中的替换为,则0
它应该可以工作。(您可能需要扩展正则表达式以包括尾部}
以${FOO}
正确突出显示。)此数字是指匹配项的regexp子组,0
表示应突出显示整个匹配项。
我通过以下方式改进了@Lindydancer的答案:
sh-script-extra-font-lock-is-in-double-quoted-string
函数,因为它仅使用一次$10
,$1
等)突出显示。破解代码
(defun sh-script-extra-font-lock-match-var-in-double-quoted-string (limit)
"Search for variables in double-quoted strings."
(let (res)
(while
(and (setq res (progn (if (eq (get-byte) ?$) (backward-char))
(re-search-forward
"[^\\]\\$\\({#?\\)?\\([[:alpha:]_][[:alnum:]_]*\\|[-#?@!]\\|[[:digit:]]+\\)"
limit t)))
(not (eq (nth 3 (syntax-ppss)) ?\")))) res))
(defvar sh-script-extra-font-lock-keywords
'((sh-script-extra-font-lock-match-var-in-double-quoted-string
(2 font-lock-variable-name-face prepend))))
(defun sh-script-extra-font-lock-activate ()
(interactive)
(font-lock-add-keywords nil sh-script-extra-font-lock-keywords)
(if (fboundp 'font-lock-flush)
(font-lock-flush)
(when font-lock-mode (with-no-warnings (font-lock-fontify-buffer)))))
[^\\\\]
为可写[^\\]
,这是一组不应该匹配的字符,你的代码中包含反斜线的两倍。在较旧的Emacs版本中必须使用font-lock-fontify-buffer
,在较新的版本中应调用,font-lock-flush
并且font-lock-fontify-buffer
不建议从elisp 调用。我的原始代码遵循此规则,而您的代码则没有。无论如何,将其迁移到GitHub存档并共同努力可能是一个更好的主意。
[^\\]
逃脱]
吗?据我所知,这就是正则表达式在Java中的工作方式。
sh-mode
吗?也许可以将其添加到Emacs本身。