lsp-ui-doc 框宽度计算有误

lsp-ui-doc-position 是 top .

长度和位置计算错得有点离谱,有遇到过类似情况的吗?


  • OS: macOS Mojave Version 10.14.3
  • Emacs: emacs-26.1-z-mac-7.4
  • Graphic display: t

看了一下源码,lsp-ui-doc 的位置好是由以下函数决定的:

(defun lsp-ui-doc--move-frame (frame)
  "Place our FRAME on screen."
  (lsp-ui-doc--resize-buffer)
  (-let* (((left top _right _bottom) (window-edges nil nil nil t))
          (window (frame-root-window frame))
          ((width . height) (window-text-pixel-size window nil nil 10000 10000 t))
          (width (* (/ width 4) 3))  ;; <-  adjust width
          (width (+ width (* (frame-char-width frame) 1))) ;; margins
          (char-h (frame-char-height))
          (height (min (- (* lsp-ui-doc-max-height char-h) (/ char-h 2)) height))
          (frame-resize-pixelwise t))
    (set-frame-size frame width height t)
    (if (eq lsp-ui-doc-position 'at-point)
        (lsp-ui-doc--mv-at-point frame height left top)
      (set-frame-position frame
                          (if (and (>= left (+ width 10 (frame-char-width)))
                                 (not (lsp-ui-doc--next-to-side-window-p)))
                              10
                            (- (frame-pixel-width) width 10 (frame-char-width)))
                          (pcase lsp-ui-doc-position
                            ('top (+ top 10))
                            ('bottom (- (lsp-ui-doc--line-height 'mode-line)
                                        height
                                        10)))))))

我通过调整 frame 的宽度,暂时性解决了问题。

这个框的长宽和位置的决定方式感觉不够智能,最好能够自动调整位置,比如在光标上或者下,或则在窗口四个角落自动切换,通过这两种模式尽可能地避免遮挡光标的位置。

不过,该如何得到光标在frame中的位置呢?(Left 和 Top)

at-point 试过效果没?

Emacs里想得到这个不是很直接。首先GUI下Emacs有两个frame:outer frame和native frame。outer frame回比native多标题栏,工具栏之类的东西,而且具体包括哪些,不包括哪些取决于使用的窗口管理器。Childframe的座标是相对于native frame的原点的。而window-absolute-pixel-position返回的point的座标是相对于outer frame的。所以还不能直接用。

我用的函数:

(defun eldoc-box--point-position-relative-to-native-frame (&optional position window)
  "Return (X . Y) as the coordinate of POSITION in WINDOW.
The coordinate is relative to the native frame.

WINDOW nil means use selected window."
  (let* ((window (window-normalize-window window t))
	 (pos-in-window
	  (pos-visible-in-window-p
	   (or position (window-point window)) window t)))
    (when pos-in-window
      ;; change absolute to relative to native frame
      (let ((edges (window-edges window t nil t)))
	(cons (+ (nth 0 edges) (nth 0 pos-in-window))
	      (+ (nth 1 edges) (nth 1 pos-in-window)))))))

文档遮挡代码的问题我是靠自动左右切换解决的:一般来说我的代码都在80字左右,文档放右边不会遮;左右双屏的时候,如果光标在右边的窗口,文档会被显示在左边。这样一般不会有问题。

2 个赞

at-point 时, lsp-ui-doc 框过度偏右,如图:

右边一半已经超出屏幕了。

可以设置最大宽度 lsp-ui-doc-max-width