commit
da8113682f
19
README.org
19
README.org
@ -12,17 +12,34 @@ Get the file, add to load path, and
|
|||||||
* Usage
|
* Usage
|
||||||
** Function
|
** Function
|
||||||
- =eldoc-box-hover-mode= :: Show documentation upon hover. Note that you need to enable ElDoc mode for this to work.
|
- =eldoc-box-hover-mode= :: Show documentation upon hover. Note that you need to enable ElDoc mode for this to work.
|
||||||
|
- =eldoc-box-hover-at-point-mode= :: This minor mode shows doc at point. Don't try to enable both minor mode: you can only enable one in the same time.
|
||||||
** Face
|
** Face
|
||||||
- =eldoc-box-border= :: Adjust =:background= of this face for border color.
|
- =eldoc-box-border= :: Adjust =:background= of this face for border color.
|
||||||
- =eldoc-box-body= :: Adjust =:background= of this face for background color of childframe.
|
- =eldoc-box-body= :: Adjust =:background= of this face for background color of childframe.
|
||||||
** Variable
|
** Variable
|
||||||
- =eldoc-box-max-pixel-width= & =eldoc-box-max-pixel-height= :: Set them according to the screen resolution of your machine.
|
- =eldoc-box-max-pixel-width= & =eldoc-box-max-pixel-height= :: Set them according to the screen resolution of your machine.
|
||||||
- =eldoc-box-only-multi-line= :: Set this to non-nil and eldoc-box only display multi-line message in childframe. One line messages are left in minibuffer.
|
- =eldoc-box-only-multi-line= :: Set this to non-nil and eldoc-box only display multi-line message in childframe. One line messages are left in minibuffer.
|
||||||
- =eldoc-box-cleanup-interval= :: After this amount of seconds will eldoc-box attempt to cleanup the childframe. E.g. if it is set to 1, the childframe is cleared 1 second after you moved the point to somewhere else (that doesn't have a doc to show).
|
- =eldoc-box-cleanup-interval= :: After this amount of seconds will eldoc-box attempt to cleanup the childframe. E.g. if it is set to 1, the childframe is cleared 1 second after you moved the point to somewhere else (that doesn't have a doc to show). This doesn't apply to =eldoc-box-hover-at-point-mode=, in that mode the childframe is cleared as soon as point moves.
|
||||||
** Use with eglot
|
** Use with eglot
|
||||||
As of writing this README, eglot doesn't have a public mode hook, use this hook:
|
As of writing this README, eglot doesn't have a public mode hook, use this hook:
|
||||||
#+BEGIN_SRC emacs-lisp
|
#+BEGIN_SRC emacs-lisp
|
||||||
(add-hook 'eglot--managed-mode-hook #'eldoc-box-hover-mode t)
|
(add-hook 'eglot--managed-mode-hook #'eldoc-box-hover-mode t)
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
** Help at point hack
|
||||||
|
If all you need is a "help at point" popup to be used with eglot, here is my hack:
|
||||||
|
#+BEGIN_SRC emacs-lisp
|
||||||
|
(defun moon-help-at-point ()
|
||||||
|
(interactive)
|
||||||
|
(when eglot--managed-mode
|
||||||
|
(require 'eldoc-box)
|
||||||
|
(let ((eldoc-box-position-function #'eldoc-box--default-at-point-position-function))
|
||||||
|
(eldoc-box--display
|
||||||
|
(eglot--dbind ((Hover) contents range)
|
||||||
|
(jsonrpc-request (eglot--current-server-or-lose) :textDocument/hover
|
||||||
|
(eglot--TextDocumentPositionParams))
|
||||||
|
(when (seq-empty-p contents) (eglot--error "No hover info here"))
|
||||||
|
(eglot--hover-info contents range))))
|
||||||
|
(add-hook 'pre-command-hook #'eldoc-box-quit-frame t t)))
|
||||||
|
#+END_SRC
|
||||||
* Contributors
|
* Contributors
|
||||||
- [[https://github.com/joaotavora][João Távora]]
|
- [[https://github.com/joaotavora][João Távora]]
|
||||||
|
104
eldoc-box.el
104
eldoc-box.el
@ -59,7 +59,12 @@
|
|||||||
(defvar eldoc-box-cleanup-interval 1
|
(defvar eldoc-box-cleanup-interval 1
|
||||||
"After this amount of seconds will eldoc-box attempt to cleanup the childframe.
|
"After this amount of seconds will eldoc-box attempt to cleanup the childframe.
|
||||||
E.g. if it is set to 1, the childframe is cleared 1 second after
|
E.g. if it is set to 1, the childframe is cleared 1 second after
|
||||||
you moved the point to somewhere else (that doesn't have a doc to show)")
|
you moved the point to somewhere else (that doesn't have a doc to show).
|
||||||
|
This doesn't apply to =eldoc-box-hover-at-point-mode=,
|
||||||
|
in that mode the childframe is cleared as soon as point moves.")
|
||||||
|
|
||||||
|
(defvar eldoc-box-clear-with-C-g nil
|
||||||
|
"If set to non-nil, eldoc-box clears cildframe when you hit \C-g.")
|
||||||
|
|
||||||
(defvar eldoc-box-frame-parameters
|
(defvar eldoc-box-frame-parameters
|
||||||
'(
|
'(
|
||||||
@ -92,11 +97,20 @@ you moved the point to somewhere else (that doesn't have a doc to show)")
|
|||||||
|
|
||||||
(defvar eldoc-box-max-pixel-width 800
|
(defvar eldoc-box-max-pixel-width 800
|
||||||
"Maximum width of doc childframw in pixel.
|
"Maximum width of doc childframw in pixel.
|
||||||
Consider your machine's screen's resolution when setting this variable.")
|
Consider your machine's screen's resolution when setting this variable.
|
||||||
|
Set it to a function with no argument
|
||||||
|
if you want to dynamically change the maximum width.")
|
||||||
|
|
||||||
(defvar eldoc-box-max-pixel-height 700
|
(defvar eldoc-box-max-pixel-height 700
|
||||||
"Maximum height of doc childframw in pixel.
|
"Maximum height of doc childframw in pixel.
|
||||||
Consider your machine's screen's resolution when setting this variable.")
|
Consider your machine's screen's resolution when setting this variable.
|
||||||
|
Set it to a function with no argument
|
||||||
|
if you want to dynamically change the maximum height.")
|
||||||
|
|
||||||
|
(defvar eldoc-box-position-function #'eldoc-box--default-upper-corner-position-function
|
||||||
|
"Eldoc-box uses this function to set childframe's position.
|
||||||
|
This should be a function that returns a (X . Y) cons cell.
|
||||||
|
It will be passes with two arguments: WIDTH and HEIGHT of the childframe.")
|
||||||
|
|
||||||
;;;;; Function
|
;;;;; Function
|
||||||
(defvar eldoc-box--frame nil ;; A backstage variable
|
(defvar eldoc-box--frame nil ;; A backstage variable
|
||||||
@ -113,15 +127,35 @@ Consider your machine's screen's resolution when setting this variable.")
|
|||||||
"Displays hover documentations in a childframe. This mode is buffer local."
|
"Displays hover documentations in a childframe. This mode is buffer local."
|
||||||
:lighter " ELDOC-BOX"
|
:lighter " ELDOC-BOX"
|
||||||
(if eldoc-box-hover-mode
|
(if eldoc-box-hover-mode
|
||||||
(add-function :before-until (local 'eldoc-message-function)
|
(progn (add-function :before-until (local 'eldoc-message-function)
|
||||||
#'eldoc-box--eldoc-message-function)
|
#'eldoc-box--eldoc-message-function)
|
||||||
|
(when eldoc-box-clear-with-C-g
|
||||||
|
(advice-add #'keyboard-quit :before #'eldoc-box-quit-frame)))
|
||||||
(remove-function (local 'eldoc-message-function) #'eldoc-box--eldoc-message-function)
|
(remove-function (local 'eldoc-message-function) #'eldoc-box--eldoc-message-function)
|
||||||
|
(advice-remove #'keyboard-quit #'eldoc-box-quit-frame)
|
||||||
;; if minor mode is turned off when childframe is visible
|
;; if minor mode is turned off when childframe is visible
|
||||||
;; hide it
|
;; hide it
|
||||||
(when eldoc-box--frame
|
(when eldoc-box--frame
|
||||||
(delete-frame eldoc-box--frame)
|
(delete-frame eldoc-box--frame)
|
||||||
(setq eldoc-box--frame nil))))
|
(setq eldoc-box--frame nil))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-minor-mode eldoc-box-hover-at-point-mode
|
||||||
|
"A convenient minor mode to display doc at point.
|
||||||
|
You can use C-g to hide the doc."
|
||||||
|
:lighter ""
|
||||||
|
(if eldoc-box-hover-at-point-mode
|
||||||
|
(progn (setq-local
|
||||||
|
eldoc-box-position-function
|
||||||
|
#'eldoc-box--default-at-point-position-function)
|
||||||
|
(setq-local eldoc-box-clear-with-C-g t)
|
||||||
|
(add-hook 'pre-command-hook #'eldoc-box-quit-frame t t)
|
||||||
|
(eldoc-box-hover-mode))
|
||||||
|
(eldoc-box-hover-mode -1)
|
||||||
|
(remove-hook 'pre-command-hook #'eldoc-box-quit-frame t)
|
||||||
|
(kill-local-variable 'eldoc-box-position-function)
|
||||||
|
(kill-local-variable 'eldoc-box-clear-with-C-g)))
|
||||||
|
|
||||||
;;;; Backstage
|
;;;; Backstage
|
||||||
;;;;; Variable
|
;;;;; Variable
|
||||||
(defvar eldoc-box--buffer " *eldoc-box*"
|
(defvar eldoc-box--buffer " *eldoc-box*"
|
||||||
@ -138,8 +172,8 @@ Consider your machine's screen's resolution when setting this variable.")
|
|||||||
;; and `eldoc-box--maybe-cleanup' in `eldoc-box--cleanup-timer' will clear the childframe
|
;; and `eldoc-box--maybe-cleanup' in `eldoc-box--cleanup-timer' will clear the childframe
|
||||||
(setq eldoc-box-hover-mode t)
|
(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)))
|
||||||
|
|
||||||
|
|
||||||
(defun eldoc-box--window-side ()
|
(defun eldoc-box--window-side ()
|
||||||
@ -150,6 +184,45 @@ Consider your machine's screen's resolution when setting this variable.")
|
|||||||
'left
|
'left
|
||||||
'right)))
|
'right)))
|
||||||
|
|
||||||
|
(defun eldoc-box--default-upper-corner-position-function (width _)
|
||||||
|
"The default function to set childframe position.
|
||||||
|
Used by `eldoc-box-position-function'.
|
||||||
|
Position is calculated base on WIDTH and HEIGHT of chilframe text window"
|
||||||
|
(cons (pcase (eldoc-box--window-side) ; x position + a little padding (16)
|
||||||
|
;; display doc on right
|
||||||
|
('left (- (frame-outer-width (selected-frame)) width 16))
|
||||||
|
;; display doc on left
|
||||||
|
('right 16))
|
||||||
|
;; y position + a little padding (16)
|
||||||
|
16))
|
||||||
|
|
||||||
|
(defun eldoc-box--default-at-point-position-function (width height)
|
||||||
|
"Set `eldoc-box-position-function' to this function to have childframe appear under point.
|
||||||
|
Position is calculated base on WIDTH and HEIGHT of chilframe text window"
|
||||||
|
;; (window-absolute-pixel-position)
|
||||||
|
;; (posn-x-y (posn-at-point))
|
||||||
|
(let* ((point-pos (window-absolute-pixel-position))
|
||||||
|
(frame-pos (frame-edges nil 'native-edges))
|
||||||
|
(x (- (car point-pos) (car frame-pos))) ; relative to native frame
|
||||||
|
(y (- (cdr point-pos) (nth 1 frame-pos)))
|
||||||
|
(en (frame-char-width))
|
||||||
|
(em (frame-char-height))
|
||||||
|
(frame-geometry (frame-geometry))
|
||||||
|
(tool-bar (if (and tool-bar-mode
|
||||||
|
(alist-get 'tool-bar-external frame-geometry))
|
||||||
|
(cdr (alist-get 'tool-bar-size frame-geometry))
|
||||||
|
0)))
|
||||||
|
(cons (if (< (- (frame-inner-width) width) x)
|
||||||
|
;; space on the right of the pos is not enough
|
||||||
|
;; put to left
|
||||||
|
(max 0 (- x width))
|
||||||
|
(+ x en))
|
||||||
|
(if (< (- (frame-inner-height) height) y)
|
||||||
|
;; space under the pos is not enough
|
||||||
|
;; put above
|
||||||
|
(max 0 (- y height))
|
||||||
|
(+ y em tool-bar)))))
|
||||||
|
|
||||||
(defun eldoc-box--get-frame (buffer)
|
(defun eldoc-box--get-frame (buffer)
|
||||||
"Return a childframe displaying BUFFER.
|
"Return a childframe displaying BUFFER.
|
||||||
Checkout `lsp-ui-doc--make-frame', `lsp-ui-doc--move-frame'."
|
Checkout `lsp-ui-doc--make-frame', `lsp-ui-doc--move-frame'."
|
||||||
@ -174,23 +247,20 @@ Checkout `lsp-ui-doc--make-frame', `lsp-ui-doc--move-frame'."
|
|||||||
(let* ((size
|
(let* ((size
|
||||||
(window-text-pixel-size
|
(window-text-pixel-size
|
||||||
window nil nil
|
window nil nil
|
||||||
eldoc-box-max-pixel-width
|
(if (functionp eldoc-box-max-pixel-width) (funcall eldoc-box-max-pixel-width) eldoc-box-max-pixel-width)
|
||||||
eldoc-box-max-pixel-height t))
|
(if (functionp eldoc-box-max-pixel-height) (funcall eldoc-box-max-pixel-height) eldoc-box-max-pixel-height)
|
||||||
|
t))
|
||||||
(width (car size))
|
(width (car size))
|
||||||
(height (cdr size))
|
(height (cdr size))
|
||||||
(width (+ width (frame-char-width frame))) ; add margin
|
(width (+ width (frame-char-width frame))) ; add margin
|
||||||
(frame-resize-pixelwise t))
|
(frame-resize-pixelwise t)
|
||||||
|
(pos (funcall eldoc-box-position-function width height)))
|
||||||
(set-frame-size frame width height t)
|
(set-frame-size frame width height t)
|
||||||
;; move position
|
;; move position
|
||||||
(set-frame-position frame (pcase (eldoc-box--window-side) ; x position + a little padding (16)
|
(set-frame-position frame (car pos) (cdr pos)))
|
||||||
;; display doc on right
|
|
||||||
('left (- (frame-outer-width main-frame) width 16))
|
|
||||||
;; display doc on left
|
|
||||||
('right 16))
|
|
||||||
;; y position + a little padding (16)
|
|
||||||
16))
|
|
||||||
(setq eldoc-box--frame frame)))
|
(setq eldoc-box--frame frame)))
|
||||||
|
|
||||||
|
|
||||||
;;;;; ElDoc
|
;;;;; ElDoc
|
||||||
|
|
||||||
(defvar eldoc-box--cleanup-timer nil
|
(defvar eldoc-box--cleanup-timer nil
|
||||||
|
Loading…
Reference in New Issue
Block a user