Fix: scroll/click doc frame make it disappear after 1s
- Add eldoc-box--last-point - eldoc-box--display sets eldoc-box-hover-mode to t in doc buffer - eldoc-box--maybe-cleanup checks more things to decide whether to clear frame - eldoc-box--eldoc-message-function sets eldoc-box--last-point to (point)
This commit is contained in:
parent
152d422aba
commit
f0b1bd23c5
40
eldoc-box.el
40
eldoc-box.el
@ -122,6 +122,9 @@
|
|||||||
(let ((doc-buffer (get-buffer-create eldoc-box--buffer)))
|
(let ((doc-buffer (get-buffer-create eldoc-box--buffer)))
|
||||||
(with-current-buffer doc-buffer
|
(with-current-buffer doc-buffer
|
||||||
(setq mode-line-format nil)
|
(setq mode-line-format nil)
|
||||||
|
;; without this, clicking childframe will make doc buffer the current buffer
|
||||||
|
;; and `eldoc-box--maybe-cleanup' in `eldoc-box--cleanup-timer' will clear the childframe
|
||||||
|
(setq eldoc-box-hover-mode t)
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(insert str)
|
(insert str)
|
||||||
(eldoc-box--get-frame doc-buffer))))
|
(eldoc-box--get-frame doc-buffer))))
|
||||||
@ -199,19 +202,37 @@ Checkout `lsp-ui-doc--make-frame', `lsp-ui-doc--move-frame'."
|
|||||||
(defvar eldoc-box--cleanup-timer nil
|
(defvar eldoc-box--cleanup-timer nil
|
||||||
"The timer used to cleanup childframe after ElDoc.")
|
"The timer used to cleanup childframe after ElDoc.")
|
||||||
|
|
||||||
|
(defvar eldoc-box--last-point 0
|
||||||
|
;; used in `eldoc-box--maybe-cleanup'
|
||||||
|
"Last point when eldoc-box showed childframe.")
|
||||||
|
|
||||||
(defun eldoc-box--maybe-cleanup ()
|
(defun eldoc-box--maybe-cleanup ()
|
||||||
"Clean up after ElDoc."
|
"Clean up after ElDoc."
|
||||||
;; timer is global, so this function will be called outside
|
;; timer is global, so this function will be called outside
|
||||||
;; the buffer with `eldoc-box-hover-mode' enabled
|
;; the buffer with `eldoc-box-hover-mode' enabled
|
||||||
(if eldoc-box-hover-mode
|
(if (and (frame-parameter eldoc-box--frame 'visibility)
|
||||||
;; if eldoc-last-message is nil, the childframe is cleared
|
(or (and (not eldoc-last-message) ; 1
|
||||||
(eldoc-box--eldoc-message-function eldoc-last-message)
|
(not (eq (point) eldoc-box--last-point)) ; 2
|
||||||
;; sometimes you switched buffer when childframe is on.
|
(not (eq (current-buffer) (get-buffer eldoc-box--buffer)))) ; 3
|
||||||
|
(not eldoc-box-hover-mode))) ; 4
|
||||||
|
;; 1. Obviously, last-message nil means we are not on a valid symbol anymore.
|
||||||
|
;; 2. Or are we? If you scroll the childframe with mouse wheel
|
||||||
|
;; `eldoc-pre-command-refresh-echo-area' will set `eldoc-last-message' to nil.
|
||||||
|
;; Without the point test, this function, called by `eldoc-box--cleanup-timer'
|
||||||
|
;; will clear the doc frame, not good
|
||||||
|
;; 3. If scrolling can't satisfy you and you clicked the childframe
|
||||||
|
;; both 1. and 2. are satisfied. 3. is the last hope to prevent this function
|
||||||
|
;; from clearing your precious childframe. There is another safety pin in
|
||||||
|
;; `eldoc-box--display' that works with 3.
|
||||||
|
;; 4. Sometimes you switched buffer when childframe is on.
|
||||||
;; it wouldn't go away unless you goes back and let eldoc shut it off.
|
;; it wouldn't go away unless you goes back and let eldoc shut it off.
|
||||||
;; if childframe is visible and we are not in `eldoc-box-hover-mode', hide childframe
|
;; So if we are not in `eldoc-box-hover-mode', clear childframe
|
||||||
(when (frame-parameter eldoc-box--frame 'visibility)
|
(eldoc-box-quit-frame)
|
||||||
(eldoc-box-quit-frame)))
|
;; so you didn't clear the doc frame this time, and the last timer has ran out
|
||||||
(setq eldoc-box--cleanup-timer nil))
|
;; setup another one to make sure the doc frame is cleared
|
||||||
|
;; once the condition above it met
|
||||||
|
(setq eldoc-box--cleanup-timer
|
||||||
|
(run-with-idle-timer 1 nil #'eldoc-box--maybe-cleanup))))
|
||||||
|
|
||||||
(defun eldoc-box--eldoc-message-function (str &rest args)
|
(defun eldoc-box--eldoc-message-function (str &rest args)
|
||||||
"Front-end for eldoc. Display STR in childframe and ARGS works like `message'."
|
"Front-end for eldoc. Display STR in childframe and ARGS works like `message'."
|
||||||
@ -219,7 +240,8 @@ Checkout `lsp-ui-doc--make-frame', `lsp-ui-doc--move-frame'."
|
|||||||
(let ((doc (apply #'format str args)))
|
(let ((doc (apply #'format str args)))
|
||||||
(unless (and eldoc-box-only-multi-line (eq (cl-count ?\n doc) 0))
|
(unless (and eldoc-box-only-multi-line (eq (cl-count ?\n doc) 0))
|
||||||
(eldoc-box--display doc)
|
(eldoc-box--display doc)
|
||||||
;; Why a timer? ElDoc is mainly use in minibuffer,
|
(setq eldoc-box--last-point (point))
|
||||||
|
;; Why a timer? ElDoc is mainly used in minibuffer,
|
||||||
;; where the text is constantly being flushed by other commands
|
;; where the text is constantly being flushed by other commands
|
||||||
;; so ElDoc doesn't try very hard to cleanup
|
;; so ElDoc doesn't try very hard to cleanup
|
||||||
(when eldoc-box--cleanup-timer (cancel-timer eldoc-box--cleanup-timer))
|
(when eldoc-box--cleanup-timer (cancel-timer eldoc-box--cleanup-timer))
|
||||||
|
Loading…
Reference in New Issue
Block a user