如何让Emacs接收长诊断时仅下划线标注部分文本?
给Eglot实现VS Code式的长范围诊断简化显示
首先你之前的advice写法直接搞崩了通知流程,问题出在两点:一是eglot-handle-notification是普通函数,不是CLOS方法,不能用cl-defmethod来定义advice;二是参数列表完全不对,这个函数的实际参数是server method params,你写的参数和实际匹配不上,导致通知无法正常传递。
先把advice改对,保证通知能正常转发:
(defun pre-process-diagnostics (orig-fun server method params) (apply orig-fun server method params)) (advice-add 'eglot-handle-notification :around #'pre-process-diagnostics) (message "Eglot-X: diagnostic filtering enabled.")
接下来实现核心需求:让长范围诊断只在开头显示标记,完全不用修改服务器发送的原始诊断数据,只在渲染前调整显示范围即可。
Eglot默认用flymake处理诊断渲染,我们可以在LSP诊断转成flymake格式的环节动手——也就是eglot--diagnostics-to-flymake函数。给它加个around advice,把超过指定长度的诊断范围缩成起始位置的单个字符:
(defun eglot-shorten-long-diagnostics (orig-fun diagnostics &rest args) (let ((processed-diags (mapcar (lambda (diag) ;; 这里把20设为长度阈值,超过20个字符的诊断就缩成开头一个字符 (if (> (- (eglot:range-end (eglot:diagnostic-range diag)) (eglot:range-start (eglot:diagnostic-range diag))) 20) (progn (setf (eglot:diagnostic-range diag) (make-eglot:range :start (eglot:range-start (eglot:diagnostic-range diag)) :end (eglot:range-start (eglot:diagnostic-range diag)))) diag) diag)) diagnostics))) (apply orig-fun processed-diags args))) (advice-add 'eglot--diagnostics-to-flymake :around #'eglot-shorten-long-diagnostics)
这样flymake只会在诊断范围的第一个字符下方渲染标记,不会把整段文本都标亮。
如果觉得默认的flymake下划线和VS Code的三点视觉差异大,可以调整样式把波浪线弄矮,模拟三点效果:
;; 调整警告和错误的下划线样式 (set-face-attribute 'flymake-warning nil :underline '(:style wave :color "orange" :height 0.2)) (set-face-attribute 'flymake-error nil :underline '(:style wave :color "red" :height 0.2))
高度设为0.2后,波浪线会变得很短,视觉上和VS Code的三点标记基本一致。
要是你用的是flycheck而非flymake,只需要把advice加到eglot--diagnostics-to-flycheck函数上,逻辑完全一致。
内容的提问来源于stack exchange,提问作者Abdelghani
相关产品推荐
相关产品推荐

