[分享] 把 eldoc 输出放在 headline 上

eldoc 显示在 minibuffer 里,输入代码的时候时有时无,非常难受,就把显示搬到 headline 上了。

https://git.sr.ht/~meow_king/eldoc-headline/tree/main/item/eldoc-headline.el

(defgroup eldoc-headline nil
  "Tree Sitter enabled Typst Writing."
  :group 'eldoc)

(defcustom eldoc-headline-disable-echo-area nil
  "Whether to disable `eldoc-display-in-echo-area' or not."
  :type 'boolean
  :group 'eldoc-headline)

(defvar eldoc-headline--string "")

(defun eldoc-headline-display (docs _interactive)
  (let ((width (1- (window-width (minibuffer-window))))
        (string
         (with-temp-buffer
           (eldoc--echo-area-render docs)
           (buffer-substring (goto-char (point-min))
                             (progn (end-of-visible-line)
                                    (point))))))
    (setq eldoc-headline--string
          (if (> (length string) width)  ; truncation to happen
              (truncate-string-to-width string width)
            string))))

(defun eldoc-headline--setup()
  (add-to-list 'header-line-format '(:eval eldoc-headline--string))
  (if eldoc-headline-disable-echo-area
      (remove-hook 'eldoc-display-functions #'eldoc-display-in-echo-area))
  (add-hook 'eldoc-display-functions #'eldoc-headline-display))

(defun eldoc-headline--cleanup()
  (setq header-line-format (delete '(:eval eldoc-headline--string) header-line-format))
  (if eldoc-headline-disable-echo-area
      (add-hook 'eldoc-display-functions #'eldoc-display-in-echo-area))
  (remove-hook 'eldoc-display-functions #'eldoc-headline-display))

;;;###autoload
(define-minor-mode eldoc-headline-local-mode
  "Toogle buffer local eldoc headline mode."
  :init-value nil
  :group 'eldoc-headline
  :lighter "eldoc-headline"
  (if eldoc-headline-local-mode (eldoc-headline--setup)
    (eldoc-headline--cleanup)))

(define-globalized-minor-mode eldoc-headline-mode eldoc-headline-local-mode
  (lambda () (eldoc-headline-local-mode 1)))

效果:

1 个赞

sideline-eldoc 是另一個選擇,連結 GitHub - ginqi7/sideline-eldoc .

2 个赞

tooltip-mode我一直是关闭的,今于看到一个视频发现tooltip,然后看了下tooltip源码好像是C实现的x-show-tip,这样可比frame那好多了,sideline看了下好像是overlay实现的也没有C实现的快。于是稍微研究了下,用x-show-tip来显示eldoc,可能跟tooltip-mode冲突,对我个人是没问题,因为我不用tooltip-mode。代码如下:

;; 使用tooltip显示eldoc,`x-show-tip'是原生c实现的,不卡
  (defun get-eldoc-msg ()
    (when eldoc--doc-buffer
      (with-current-buffer eldoc--doc-buffer
        (buffer-substring
         (goto-char (point-min))
         (progn
           (end-of-visible-line)
           (point))))))
  (defun eldoc-tooltip-display (docs _interactive)
    (let* ((p (window-absolute-pixel-position))
           (x (car p))
           (h (line-pixel-height))
           (y
            (if header-line-format
                (- (cdr p) h) ;; 修复开启`header-line-format'时y值不正确
              (cdr p)))
           (text (get-eldoc-msg)))
      (when (and p (not (equal text "")))
        (setq y (+ y h))
        ;; (add-face-text-property 0 (length text) 'tooltip t text)
        (x-show-tip
         text
         (selected-frame)
         `((name . "tooltip")
           (internal-border-width . 2)
           (border-width . 1)
           (no-special-glyphs . t)
           (left . ,x) ;; 设置left后会忽略`x-show-tip'最后的DX参数
           (top . ,y) ;; 设置top后会忽略`x-show-tip'最后的DY参数
           (foreground-color . ,(face-attribute 'default :foreground))
           (background-color . ,(face-attribute 'default :background))
           ;; (border-color . "#ffff00")
           )
         20 ;; 显示20秒
         0
         0))))
  ;; 因为我们是用的`eldoc--doc-buffer',所以必须运行在它更新后
  (add-hook 'eldoc-display-functions #'eldoc-tooltip-display 10)
  (add-hook 'pre-command-hook 'x-hide-tip) ;; 不隐藏的话,就一直显示不太好

效果如图: image

2 个赞

有一个eldoc-box的包,可供选择。

sideline-eldoc 和 eldoc-box 是目前最好的两个选择了吧