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
	 Yuan Fu
						Yuan Fu