37
37
(require 'goto-addr )
38
38
(require 'markdown-mode )
39
39
(require 'cl-lib )
40
- (require 'posframe )
41
40
42
41
(when (featurep 'xwidget-internal )
43
42
(require 'xwidget ))
@@ -145,14 +144,29 @@ Only the `background' is used in this face."
145
144
:group 'lsp-ui-doc )
146
145
147
146
(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 )
149
154
(vertical-scroll-bars . nil )
150
155
(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 )
151
164
(mouse-wheel-frame . nil )
152
- (no-accept-focus . nil )
165
+ (no-other-frame . t )
153
166
(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 ))
156
170
" Frame parameters used to create the frame." )
157
171
158
172
(defvar lsp-ui-doc-render-function nil
@@ -351,7 +365,10 @@ We don't extract the string that `lps-line' is already displaying."
351
365
(when (overlayp lsp-ui-doc--inline-ov)
352
366
(delete-overlay lsp-ui-doc--inline-ov))
353
367
(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))))
355
372
356
373
(defun lsp-ui-doc--buffer-width ()
357
374
" Calcul the max width of the buffer."
@@ -386,6 +403,19 @@ We don't extract the string that `lps-line' is already displaying."
386
403
(xwidget-resize (lsp-ui-doc--webkit-get-xwidget) offset-width offset-height))
387
404
(lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
388
405
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
+
389
419
(defun lsp-ui-doc--mv-at-point (frame width height start-x start-y )
390
420
" Move FRAME to be where the point is.
391
421
WIDTH is the child frame width.
@@ -429,11 +459,12 @@ FRAME just below the symbol at point."
429
459
(if (eq lsp-ui-doc-position 'at-point )
430
460
(lsp-ui-doc--mv-at-point frame width height left top)
431
461
(set-frame-position frame
432
- (max (- frame-right width ) 0 )
462
+ (max (- frame-right width 10 ( frame-char-width )) 10 )
433
463
(pcase lsp-ui-doc-position
434
- ('top top)
464
+ ('top ( + top 10 ) )
435
465
('bottom (- (lsp-ui-doc--line-height 'mode-line )
436
- height)))))))
466
+ height
467
+ 10 )))))))
437
468
438
469
(defun lsp-ui-doc--visit-file (filename )
439
470
" Visit FILENAME in the parent frame."
@@ -464,31 +495,26 @@ FN is the function to call on click."
464
495
(lsp-ui-doc--put-click (match-beginning 0 ) (match-end 0 )
465
496
'browse-url-at-mouse )))))
466
497
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."
474
500
(lsp-ui-doc--with-buffer
475
501
(if lsp-ui-doc-use-webkit
476
502
(progn
477
503
(lsp-ui-doc--webkit-execute-script
478
504
(format
479
505
" 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))
482
508
'lsp-ui-doc--webkit-resize-callback ))
483
509
(erase-buffer )
484
510
(let ((inline-p (lsp-ui-doc--inline-p)))
485
511
(insert (concat (unless inline-p (propertize " \n " 'face '(:height 0.2 )))
486
- (s-trim lsp-ui-doc--render- string)
512
+ (s-trim string)
487
513
(unless inline-p (propertize " \n\n " 'face '(:height 0.3 ))))))
488
514
(lsp-ui-doc--make-clickable-link))
489
515
(setq-local face-remapping-alist `((header-line lsp-ui-doc-header)))
490
516
(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))
492
518
mode-line-format nil
493
519
cursor-type nil )))
494
520
@@ -593,66 +619,49 @@ HEIGHT is the documentation number of lines."
593
619
(defun lsp-ui-doc--inline-p ()
594
620
" Return non-nil when the documentation should be display without a child frame."
595
621
(or (not lsp-ui-doc-use-childframe)
596
- (not (posframe-workable -p))
622
+ (not (display-graphic -p ))
597
623
(not (fboundp 'display-buffer-in-child-frame ))))
598
624
599
625
(defun lsp-ui-doc--display (symbol string )
600
626
" Display the documentation."
601
- (setq lsp-ui-doc--render-symbol symbol
602
- lsp-ui-doc--render-string string)
603
627
(when (and lsp-ui-doc-use-webkit (not (featurep 'xwidget-internal )))
604
628
(setq lsp-ui-doc-use-webkit nil ))
605
629
(if (or (null string) (string-empty-p string))
606
630
(lsp-ui-doc--hide-frame)
607
- (lsp-ui-doc--render-buffer)
631
+ (lsp-ui-doc--render-buffer string symbol )
608
632
(if (lsp-ui-doc--inline-p)
609
633
(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)
612
635
(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)))
613
639
(unless (frame-visible-p (lsp-ui-doc--get-frame))
614
640
(make-frame-visible (lsp-ui-doc--get-frame))))))
615
641
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
-
625
642
(defun lsp-ui-doc--make-frame ()
626
643
" Create the child frame and return it."
627
644
(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)))
653
659
(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)
656
665
(set-face-background 'fringe nil frame)
657
666
(run-hook-with-args 'lsp-ui-doc-frame-hook frame window)
658
667
(when lsp-ui-doc-use-webkit
@@ -661,8 +670,6 @@ The structure of INFO is defined in the documentation of `posframe-show'."
661
670
(interactive )
662
671
663
672
(let ((xwidget-event-type (nth 1 last-input-event)))
664
- (when (eq xwidget-event-type 'load-changed )
665
- (lsp-ui-doc--render-buffer))
666
673
; ; (when (eq xwidget-event-type 'load-changed)
667
674
; ; (lsp-ui-doc--move-frame (lsp-ui-doc--get-frame)))
668
675
@@ -720,7 +727,7 @@ BUFFER is the buffer where the request has been made."
720
727
(defun lsp-ui-doc--delete-frame ()
721
728
" Delete the child frame if it exists."
722
729
(-when-let (frame (lsp-ui-doc--get-frame))
723
- (posframe- delete-frame (lsp-ui-doc--make-buffer-name) )
730
+ (delete-frame frame )
724
731
(lsp-ui-doc--set-frame nil )))
725
732
726
733
(defun lsp-ui-doc--visible-p ()
@@ -759,27 +766,6 @@ before, or if the new window is the minibuffer."
759
766
(and (buffer-live-p it) it)
760
767
(kill-buffer it)))
761
768
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
-
783
769
(define-minor-mode lsp-ui-doc-mode
784
770
" Minor mode for showing hover information in child frame."
785
771
:init-value nil
@@ -797,17 +783,11 @@ before, or if the new window is the minibuffer."
797
783
(cl-callf copy-tree frameset-filter-alist)
798
784
(push '(lsp-ui-doc-frame . :never ) frameset-filter-alist)))
799
785
(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 ))
805
787
(t
806
788
(lsp-ui-doc-hide)
807
789
(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 ))))
811
791
812
792
(defun lsp-ui-doc-enable (enable )
813
793
" Enable/disable ‘lsp-ui-doc-mode’.
@@ -845,5 +825,26 @@ It is supposed to be called from `lsp-ui--toggle'"
845
825
(cancel-timer lsp-ui-doc--unfocus-frame-timer))
846
826
(add-hook 'post-command-hook 'lsp-ui-doc--glance-hide-frame ))
847
827
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
+
848
849
(provide 'lsp-ui-doc )
849
850
; ;; lsp-ui-doc.el ends here
0 commit comments