gpt4 book ai didi

emacs - Emacs 可以 fontify elisp 字符串常量吗?

转载 作者:行者123 更新时间:2023-12-02 03:45:01 24 4
gpt4 key购买 nike

困境:可读性还是可维护性?

让我们看看下面的函数。它做什么并不重要,重要的是它使用了字符串 "(let\\*?[\t]*":

的两倍
(defun setq-expression-or-sexp ()
"Return the smallest list that contains point.
If inside VARLIST part of `let' form,
return the corresponding `setq' expression."
(interactive)
(ignore-errors
(save-excursion
(up-list)
(let ((sexp (preceding-sexp)))
(backward-list 1)
(cond
((looking-back "(let\\*?[ \t]*")
(cons 'setq
(if (= (length sexp) 1)
(car sexp)
(cl-mapcan
(lambda (x) (unless (listp x) (list x nil)))
sexp))))
((progn
(up-list)
(backward-list 1)
(looking-back "(let\\*?[ \t]*"))
(cons 'setq sexp))
(t
sexp))))))

由于必须在两个(或更多)位置更新字符串是件令人头疼的事情,我必须像这样defconst:

(defconst regex-let-form "(let\\*?[ \t]*")

尽管代码变得更易于维护,但它的可读性也变得更差,因为很难一眼看出 regex-let-form 到底是什么:

(defun setq-expression-or-sexp ()
"Return the smallest list that contains point.
If inside VARLIST part of `let' form,
return the corresponding `setq' expression."
(interactive)
(ignore-errors
(save-excursion
(up-list)
(let ((sexp (preceding-sexp)))
(backward-list 1)
(cond
((looking-back regex-let-form)
(cons 'setq
(if (= (length sexp) 1)
(car sexp)
(cl-mapcan
(lambda (x) (unless (listp x) (list x nil)))
sexp))))
((progn
(up-list)
(backward-list 1)
(looking-back regex-let-form))
(cons 'setq sexp))
(t
sexp))))))

想法:为什么不两者兼而有之?

既然它是一个常量,为什么不 font-lock并使 regex-let-form 看起来像 "(let\\*?[\t]*"?这是一项可行的工作,因为:

  1. 可以像这样对标识符进行字体锁定:http://www.emacswiki.org/emacs/PrettyLambda ,甚至如此:rainbow-mode .

  2. 并且可以对常量进行字体锁定。它已经为 c++ 模式完成,但据我所知,emacs-lisp-mode 还没有。

那么就只剩下连接两者了。不幸的是,我不知道足够的 font-lock 内部人员可以做到这一点,但也许其他人会这样做?或者是否已经有一个包可以做到这一点?

最佳答案

调整来自 this answer 的代码,我已经解决了问题:

(font-lock-add-keywords 
'emacs-lisp-mode
'((fl-string-constant . 'font-lock-constant-face)) 'append)

(defun fl-string-constant (_limit)
(while (not
(ignore-errors
(save-excursion
(skip-chars-forward "'")
(let ((opoint (point))
(obj (read (current-buffer)))
obj-val)
(and (symbolp obj)
(risky-local-variable-p obj)
(special-variable-p obj)
(stringp (setq obj-val (eval obj)))
(progn
(put-text-property
(1- (point)) (point) 'display
(format "%c\"%s\"" (char-before) obj-val))
(set-match-data (list opoint (point)))
t))))))
(if (looking-at "\\(\\sw\\|\\s_\\)")
(forward-sexp 1)
(forward-char 1)))
t)

这会在常量名称之后显示字符串常量的值。它也可以很好地与 fontified 字符串常量一起使用。速度有点问题 - 欢迎提出改进建议。

此外,我找不到比 risky-local-variable-p 更好的方法来确定这是一个常数。文档说 defconst 标记变量因为特殊和危险,但没有别的。

关于emacs - Emacs 可以 fontify elisp 字符串常量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17620072/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com