3737(require 'goto-addr )
3838(require 'markdown-mode )
3939(require 'cl-lib )
40- (require 'posframe )
4140
4241(when (featurep 'xwidget-internal )
4342 (require 'xwidget ))
@@ -145,14 +144,29 @@ Only the `background' is used in this face."
145144 :group 'lsp-ui-doc )
146145
147146(defvar lsp-ui-doc-frame-parameters
148- '((no-focus-on-map . t )
147+ '((left . -1 )
148+ (no-focus-on-map . t )
149+ (min-width . 0 )
150+ (width . 0 )
151+ (min-height . 0 )
152+ (height . 0 )
153+ (internal-border-width . 1 )
149154 (vertical-scroll-bars . nil )
150155 (horizontal-scroll-bars . nil )
156+ (right-fringe . 0 )
157+ (menu-bar-lines . 0 )
158+ (tool-bar-lines . 0 )
159+ (line-spacing . 0 )
160+ (unsplittable . t )
161+ (undecorated . t )
162+ (top . -1 )
163+ (visibility . nil )
151164 (mouse-wheel-frame . nil )
152- (no-accept-focus . nil )
165+ (no-other-frame . t )
153166 (inhibit-double-buffering . t )
154- (cursor-type . box)
155- (drag-internal-border . t ))
167+ (drag-internal-border . t )
168+ (no-special-glyphs . t )
169+ (desktop-dont-save . t ))
156170 " Frame parameters used to create the frame." )
157171
158172(defvar lsp-ui-doc-render-function nil
@@ -351,7 +365,10 @@ We don't extract the string that `lps-line' is already displaying."
351365 (when (overlayp lsp-ui-doc--inline-ov)
352366 (delete-overlay lsp-ui-doc--inline-ov))
353367 (when (lsp-ui-doc--get-frame)
354- (posframe-hide (lsp-ui-doc--make-buffer-name))))
368+ (unless lsp-ui-doc-use-webkit
369+ (lsp-ui-doc--with-buffer
370+ (erase-buffer )))
371+ (make-frame-invisible (lsp-ui-doc--get-frame))))
355372
356373(defun lsp-ui-doc--buffer-width ()
357374 " Calcul the max width of the buffer."
@@ -386,6 +403,19 @@ We don't extract the string that `lps-line' is already displaying."
386403 (xwidget-resize (lsp-ui-doc--webkit-get-xwidget) offset-width offset-height))
387404 (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
388405
406+ (defun lsp-ui-doc--resize-buffer ()
407+ " If the buffer's width is larger than the current frame, resize it."
408+ (if lsp-ui-doc-use-webkit
409+ (lsp-ui-doc--webkit-execute-script
410+ " [document.querySelector('#lsp-ui-webkit').offsetWidth, document.querySelector('#lsp-ui-webkit').offsetHeight];"
411+ 'lsp-ui-doc--webkit-resize-callback )
412+
413+ (let* ((frame-width (frame-width ))
414+ (fill-column (min lsp-ui-doc-max-width (- frame-width 5 ))))
415+ (when (> (lsp-ui-doc--buffer-width) (min lsp-ui-doc-max-width frame-width))
416+ (lsp-ui-doc--with-buffer
417+ (fill-region (point-min ) (point-max )))))))
418+
389419(defun lsp-ui-doc--mv-at-point (frame width height start-x start-y )
390420 " Move FRAME to be where the point is.
391421WIDTH is the child frame width.
@@ -429,11 +459,12 @@ FRAME just below the symbol at point."
429459 (if (eq lsp-ui-doc-position 'at-point )
430460 (lsp-ui-doc--mv-at-point frame width height left top)
431461 (set-frame-position frame
432- (max (- frame-right width ) 0 )
462+ (max (- frame-right width 10 ( frame-char-width )) 10 )
433463 (pcase lsp-ui-doc-position
434- ('top top)
464+ ('top ( + top 10 ) )
435465 ('bottom (- (lsp-ui-doc--line-height 'mode-line )
436- height)))))))
466+ height
467+ 10 )))))))
437468
438469(defun lsp-ui-doc--visit-file (filename )
439470 " Visit FILENAME in the parent frame."
@@ -464,31 +495,26 @@ FN is the function to call on click."
464495 (lsp-ui-doc--put-click (match-beginning 0 ) (match-end 0 )
465496 'browse-url-at-mouse )))))
466497
467- (defvar lsp-ui-doc--render-string nil
468- " The string to render in the documentation popup." )
469- (defvar lsp-ui-doc--render-symbol nil
470- " The symbol to render documentation for." )
471-
472- (defun lsp-ui-doc--render-buffer ()
473- " Set the buffer with `lsp-ui-doc--render-string' ."
498+ (defun lsp-ui-doc--render-buffer (string symbol )
499+ " Set the buffer with STRING."
474500 (lsp-ui-doc--with-buffer
475501 (if lsp-ui-doc-use-webkit
476502 (progn
477503 (lsp-ui-doc--webkit-execute-script
478504 (format
479505 " renderMarkdown('%s', '%s');"
480- lsp-ui-doc--render- symbol
481- (url-hexify-string lsp-ui-doc--render- string))
506+ symbol
507+ (url-hexify-string string))
482508 'lsp-ui-doc--webkit-resize-callback ))
483509 (erase-buffer )
484510 (let ((inline-p (lsp-ui-doc--inline-p)))
485511 (insert (concat (unless inline-p (propertize " \n " 'face '(:height 0.2 )))
486- (s-trim lsp-ui-doc--render- string)
512+ (s-trim string)
487513 (unless inline-p (propertize " \n\n " 'face '(:height 0.3 ))))))
488514 (lsp-ui-doc--make-clickable-link))
489515 (setq-local face-remapping-alist `((header-line lsp-ui-doc-header)))
490516 (setq-local window-min-height 1 )
491- (setq header-line-format (when lsp-ui-doc-header (concat " " lsp-ui-doc--render- symbol))
517+ (setq header-line-format (when lsp-ui-doc-header (concat " " symbol))
492518 mode-line-format nil
493519 cursor-type nil )))
494520
@@ -593,66 +619,49 @@ HEIGHT is the documentation number of lines."
593619(defun lsp-ui-doc--inline-p ()
594620 " Return non-nil when the documentation should be display without a child frame."
595621 (or (not lsp-ui-doc-use-childframe)
596- (not (posframe-workable -p))
622+ (not (display-graphic -p ))
597623 (not (fboundp 'display-buffer-in-child-frame ))))
598624
599625(defun lsp-ui-doc--display (symbol string )
600626 " Display the documentation."
601- (setq lsp-ui-doc--render-symbol symbol
602- lsp-ui-doc--render-string string)
603627 (when (and lsp-ui-doc-use-webkit (not (featurep 'xwidget-internal )))
604628 (setq lsp-ui-doc-use-webkit nil ))
605629 (if (or (null string) (string-empty-p string))
606630 (lsp-ui-doc--hide-frame)
607- (lsp-ui-doc--render-buffer)
631+ (lsp-ui-doc--render-buffer string symbol )
608632 (if (lsp-ui-doc--inline-p)
609633 (lsp-ui-doc--inline)
610- (when (or (not lsp-ui-doc-use-webkit)
611- (not (lsp-ui-doc--get-frame)))
634+ (unless (lsp-ui-doc--get-frame)
612635 (lsp-ui-doc--set-frame (lsp-ui-doc--make-frame)))
636+ (unless lsp-ui-doc-use-webkit
637+ (lsp-ui-doc--resize-buffer)
638+ (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
613639 (unless (frame-visible-p (lsp-ui-doc--get-frame))
614640 (make-frame-visible (lsp-ui-doc--get-frame))))))
615641
616- (defun lsp-ui-doc--posframe-poshandler-point-top-left-corner (info )
617- " Place the posframe at the top-left corner of the point without covering the
618- point.
619-
620- The structure of INFO is defined in the documentation of `posframe-show' ."
621- (let* ((frame (plist-get info :posframe ))
622- (height (frame-pixel-height frame)))
623- (posframe-poshandler-point-bottom-left-corner info (- height))))
624-
625642(defun lsp-ui-doc--make-frame ()
626643 " Create the child frame and return it."
627644 (lsp-ui-doc--delete-frame)
628- (let* ((before-make-frame-hook nil )
629- (buffer-name (lsp-ui-doc--make-buffer-name))
630- (buffer (get-buffer-create buffer-name))
631- (params (append lsp-ui-doc-frame-parameters
632- `((name . " " )
633- (default-minibuffer-frame . ,(selected-frame ))
634- (minibuffer . ,(minibuffer-window )))))
635- (position (pcase (list lsp-ui-doc-position lsp-ui-doc-alignment)
636- ('(top frame) #'posframe-poshandler-frame-top-right-corner )
637- ('(top window) #'posframe-poshandler-window-top-right-corner )
638- ('(bottom frame) #'posframe-poshandler-frame-bottom-right-corner )
639- ('(bottom window) #'posframe-poshandler-window-bottom-right-corner )
640- ('(at-point frame) #'lsp-ui-doc--posframe-poshandler-point-top-left-corner )
641- ('(at-point window) #'lsp-ui-doc--posframe-poshandler-point-top-left-corner )))
642- (frame (posframe-show buffer
643- :width lsp-ui-doc-max-width
644- :height lsp-ui-doc-max-height
645- :poshandler position
646- :internal-border-width 1
647- :internal-border-color lsp-ui-doc-border
648- :left-fringe t
649- :right-fringe t
650- :background-color (face-background 'lsp-ui-doc-background nil t )
651- :override-parameters params))
652- (window (frame-root-window frame)))
645+ (let* ((after-make-frame-functions nil )
646+ (before-make-frame-hook nil )
647+ (name-buffer (lsp-ui-doc--make-buffer-name))
648+ (buffer (get-buffer name-buffer))
649+ (params (append lsp-ui-doc-frame-parameters
650+ `((name . " " )
651+ (default-minibuffer-frame . ,(selected-frame ))
652+ (minibuffer . ,(minibuffer-window ))
653+ (left-fringe . ,(frame-char-width ))
654+ (background-color . ,(face-background 'lsp-ui-doc-background nil t )))))
655+ (window (display-buffer-in-child-frame
656+ buffer
657+ `((child-frame-parameters . , params ))))
658+ (frame (window-frame window)))
653659 (with-current-buffer buffer
654- (lsp-ui-doc-frame-mode 1 )
655- (visual-line-mode 1 ))
660+ (lsp-ui-doc-frame-mode 1 ))
661+ (set-frame-parameter nil 'lsp-ui-doc-buffer buffer)
662+ (set-window-dedicated-p window t )
663+ (redirect-frame-focus frame (frame-parent frame))
664+ (set-face-background 'internal-border lsp-ui-doc-border frame)
656665 (set-face-background 'fringe nil frame)
657666 (run-hook-with-args 'lsp-ui-doc-frame-hook frame window)
658667 (when lsp-ui-doc-use-webkit
@@ -661,8 +670,6 @@ The structure of INFO is defined in the documentation of `posframe-show'."
661670 (interactive )
662671
663672 (let ((xwidget-event-type (nth 1 last-input-event)))
664- (when (eq xwidget-event-type 'load-changed )
665- (lsp-ui-doc--render-buffer))
666673 ; ; (when (eq xwidget-event-type 'load-changed)
667674 ; ; (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
668675
@@ -720,7 +727,7 @@ BUFFER is the buffer where the request has been made."
720727(defun lsp-ui-doc--delete-frame ()
721728 " Delete the child frame if it exists."
722729 (-when-let (frame (lsp-ui-doc--get-frame))
723- (posframe- delete-frame (lsp-ui-doc--make-buffer-name) )
730+ (delete-frame frame )
724731 (lsp-ui-doc--set-frame nil )))
725732
726733(defun lsp-ui-doc--visible-p ()
@@ -759,27 +766,6 @@ before, or if the new window is the minibuffer."
759766 (and (buffer-live-p it) it)
760767 (kill-buffer it)))
761768
762- (define-minor-mode lsp-ui-doc-frame-mode
763- " Marker mode to add additional key bind for lsp-ui-doc-frame."
764- :init-value nil
765- :lighter " "
766- :group lsp-ui-doc
767- :keymap `(([?q ] . lsp-ui-doc-unfocus-frame)))
768-
769- (defun lsp-ui-doc-focus-frame ()
770- " Focus into lsp-ui-doc-frame."
771- (interactive )
772- (when (lsp-ui-doc--frame-visible-p)
773- (lsp-ui-doc--with-buffer
774- (setq cursor-type t ))
775- (select-frame-set-input-focus (lsp-ui-doc--get-frame))))
776-
777- (defun lsp-ui-doc-unfocus-frame ()
778- " Unfocus from lsp-ui-doc-frame."
779- (interactive )
780- (when-let ((frame (frame-parent (lsp-ui-doc--get-frame))))
781- (select-frame-set-input-focus frame)))
782-
783769(define-minor-mode lsp-ui-doc-mode
784770 " Minor mode for showing hover information in child frame."
785771 :init-value nil
@@ -797,17 +783,11 @@ before, or if the new window is the minibuffer."
797783 (cl-callf copy-tree frameset-filter-alist)
798784 (push '(lsp-ui-doc-frame . :never ) frameset-filter-alist)))
799785 (add-hook 'post-command-hook 'lsp-ui-doc--make-request nil t )
800- (add-hook 'delete-frame-functions 'lsp-ui-doc--on-delete nil t )
801- (advice-add #'posframe--redirect-posframe-focus
802- :before-until (lambda (&rest _ )
803- lsp-ui-doc-frame-mode)
804- '((name . lsp-ui-doc--dont-redirect-posframe))))
786+ (add-hook 'delete-frame-functions 'lsp-ui-doc--on-delete nil t ))
805787 (t
806788 (lsp-ui-doc-hide)
807789 (remove-hook 'post-command-hook 'lsp-ui-doc--make-request t )
808- (remove-hook 'delete-frame-functions 'lsp-ui-doc--on-delete t )
809- (advice-remove #'posframe--redirect-posframe-focus
810- 'lsp-ui-doc--dont-redirect-posframe ))))
790+ (remove-hook 'delete-frame-functions 'lsp-ui-doc--on-delete t ))))
811791
812792(defun lsp-ui-doc-enable (enable )
813793 " Enable/disable ‘lsp-ui-doc-mode’.
@@ -845,5 +825,26 @@ It is supposed to be called from `lsp-ui--toggle'"
845825 (cancel-timer lsp-ui-doc--unfocus-frame-timer))
846826 (add-hook 'post-command-hook 'lsp-ui-doc--glance-hide-frame ))
847827
828+ (define-minor-mode lsp-ui-doc-frame-mode
829+ " Marker mode to add additional key bind for lsp-ui-doc-frame."
830+ :init-value nil
831+ :lighter " "
832+ :group lsp-ui-doc
833+ :keymap `(([?q ] . lsp-ui-doc-unfocus-frame)))
834+
835+ (defun lsp-ui-doc-focus-frame ()
836+ " Focus into lsp-ui-doc-frame."
837+ (interactive )
838+ (when (lsp-ui-doc--frame-visible-p)
839+ (lsp-ui-doc--with-buffer
840+ (setq cursor-type t ))
841+ (select-frame-set-input-focus (lsp-ui-doc--get-frame))))
842+
843+ (defun lsp-ui-doc-unfocus-frame ()
844+ " Unfocus from lsp-ui-doc-frame."
845+ (interactive )
846+ (when-let ((frame (frame-parent (lsp-ui-doc--get-frame))))
847+ (select-frame-set-input-focus frame)))
848+
848849(provide 'lsp-ui-doc )
849850; ;; lsp-ui-doc.el ends here
0 commit comments