branch: externals/vertico-posframe commit 91205469d92ff556a47d4143ee3fa7bda5d12075 Author: Feng Shu <tuma...@163.com> Commit: Feng Shu <tuma...@163.com>
Use cl-defmethod in vertico 1.1 --- vertico-posframe.el | 195 ++++++++++++++++++++++++++-------------------------- 1 file changed, 96 insertions(+), 99 deletions(-) diff --git a/vertico-posframe.el b/vertico-posframe.el index 5b519a69a0..009bef6986 100644 --- a/vertico-posframe.el +++ b/vertico-posframe.el @@ -7,7 +7,7 @@ ;; URL: https://github.com/tumashu/vertico-posframe ;; Version: 0.6.0 ;; Keywords: abbrev, convenience, matching, vertico -;; Package-Requires: ((emacs "26.0") (posframe "1.1.4") (vertico "0.13.0")) +;; Package-Requires: ((emacs "26.0") (posframe "1.1.4") (vertico "1.1")) ;; This file is part of GNU Emacs. @@ -181,42 +181,37 @@ minibuffer will not be hided by minibuffer-cover." (defvar exwm-workspace--workareas) (defvar exwm-workspace-current-index) -(defun vertico-posframe-refposhandler-default (&optional frame) - "The default posframe refposhandler used by vertico-posframe. -Optional argument FRAME ." +;;;###autoload +(define-minor-mode vertico-posframe-mode + "Display Vertico in posframe instead of the minibuffer." + :global t (cond - ;; EXWM environment - ((bound-and-true-p exwm--connection) - (or (ignore-errors - (let ((info (elt exwm-workspace--workareas - exwm-workspace-current-index))) - (cons (elt info 0) - (elt info 1)))) - ;; Need user install xwininfo. - (ignore-errors - (posframe-refposhandler-xwininfo frame)) - ;; Fallback, this value will incorrect sometime, for example: user - ;; have panel. - (cons 0 0))) - (t nil))) + (vertico-posframe-mode + (when (not (posframe-workable-p)) + (funcall (buffer-local-value 'vertico-posframe-fallback-mode (current-buffer)) 1))) + (t + (if (not (posframe-workable-p)) + (funcall (buffer-local-value 'vertico-posframe-fallback-mode (current-buffer)) -1) + ;; When vertico-posframe-mode is disabled, hide posframe and let + ;; the contents of minibuffer show again, this approach let + ;; vertico-posframe works with vertico multiform toggle. + (set-window-vscroll (active-minibuffer-window) 0) + (posframe-hide vertico-posframe--buffer))))) -(defun vertico-posframe-hidehandler (_) - "Hidehandler used by vertico-posframe." - (not (minibufferp))) +(cl-defmethod vertico--setup :after (&context (vertico-posframe-mode (eql t))) + "Setup minibuffer overlay, which pushes the minibuffer content down." + (add-hook 'minibuffer-exit-hook #'vertico-posframe--minibuffer-exit-hook nil 'local)) -(defun vertico-posframe-get-size (buffer) - "The default functon used by `vertico-posframe-size-function'." - (list - :height (buffer-local-value 'vertico-posframe-height buffer) - :width (buffer-local-value 'vertico-posframe-width buffer) - :min-height (or (buffer-local-value 'vertico-posframe-min-height buffer) - (let ((height (+ vertico-count 1))) - (min height (or (buffer-local-value 'vertico-posframe-height buffer) height)))) - :min-width (or (buffer-local-value 'vertico-posframe-min-width buffer) - (let ((width (round (* (frame-width) 0.62)))) - (min width (or (buffer-local-value 'vertico-posframe-width buffer) width)))))) +(defun vertico-posframe--minibuffer-exit-hook () + "The function used by `minibuffer-exit-hook'." + ;; `vertico--resize-window' have set `max-mini-window-height' to + ;; 1.0, so I think setting it to 1.0 here is safe :-). + (setq-local max-mini-window-height 1.0) + (posframe-hide vertico-posframe--buffer)) + +(cl-defmethod vertico--resize-window (_height &context (vertico-posframe-mode (eql t)))) -(defun vertico-posframe--display (_lines) +(cl-defmethod vertico--display-candidates :after (_candidates &context (vertico-posframe-mode (eql t))) "Display _LINES in posframe." (let ((buffer (current-buffer)) (point (point))) @@ -224,6 +219,34 @@ Optional argument FRAME ." (vertico-posframe--handle-minibuffer-window) (vertico-posframe--show buffer point))) +(defun vertico-posframe--handle-minibuffer-window () + "Handle minibuffer window." + (let ((show-minibuffer-p (vertico-posframe--show-minibuffer-p)) + (minibuffer-window (active-minibuffer-window))) + (setq-local max-mini-window-height 1) + (window-resize minibuffer-window + (- (window-pixel-height minibuffer-window)) + nil nil 'pixelwise) + ;; Hide the context showed in minibuffer. + (set-window-vscroll minibuffer-window 100) + (when show-minibuffer-p + (set-window-vscroll minibuffer-window 0)))) + +(defun vertico-posframe--show-minibuffer-p () + "Test show minibuffer or not." + (cl-some + (lambda (rule) + (cond ((functionp rule) + (funcall rule)) + ((and rule + (stringp rule) + (symbolp this-command)) + (string-match-p rule (symbol-name this-command))) + ((symbolp rule) + (symbol-value rule)) + (t nil))) + vertico-posframe-show-minibuffer-rules)) + (defun vertico-posframe--show (buffer window-point) "`posframe-show' of vertico-posframe. @@ -266,6 +289,14 @@ is called, window-point will be set to WINDOW-POINT." (setq-local cursor-type t) (setq-local cursor-in-non-selected-windows 'box)))) +(defun vertico-posframe-last-window () + "Get the last actived window before active minibuffer." + (let ((window (minibuffer-selected-window))) + (or (if (window-live-p window) + window + (next-window)) + (selected-window)))) + (defun vertico-posframe--get-border-color () "Get color of vertico-posframe border." (face-attribute @@ -279,51 +310,40 @@ is called, window-point will be set to WINDOW-POINT." face-fallback))) :background)) -(defun vertico-posframe--show-minibuffer-p () - "Test show minibuffer or not." - (cl-some - (lambda (rule) - (cond ((functionp rule) - (funcall rule)) - ((and rule - (stringp rule) - (symbolp this-command)) - (string-match-p rule (symbol-name this-command))) - ((symbolp rule) - (symbol-value rule)) - (t nil))) - vertico-posframe-show-minibuffer-rules)) - -(defun vertico-posframe--handle-minibuffer-window () - "Handle minibuffer window." - (let ((show-minibuffer-p (vertico-posframe--show-minibuffer-p)) - (minibuffer-window (active-minibuffer-window))) - (setq-local max-mini-window-height 1) - (window-resize minibuffer-window - (- (window-pixel-height minibuffer-window)) - nil nil 'pixelwise) - (set-window-vscroll minibuffer-window 100) - (when show-minibuffer-p - (set-window-vscroll minibuffer-window 0)))) - -(defun vertico-posframe-last-window () - "Get the last actived window before active minibuffer." - (let ((window (minibuffer-selected-window))) - (or (if (window-live-p window) - window - (next-window)) - (selected-window)))) +(defun vertico-posframe-refposhandler-default (&optional frame) + "The default posframe refposhandler used by vertico-posframe. +Optional argument FRAME ." + (cond + ;; EXWM environment + ((bound-and-true-p exwm--connection) + (or (ignore-errors + (let ((info (elt exwm-workspace--workareas + exwm-workspace-current-index))) + (cons (elt info 0) + (elt info 1)))) + ;; Need user install xwininfo. + (ignore-errors + (posframe-refposhandler-xwininfo frame)) + ;; Fallback, this value will incorrect sometime, for example: user + ;; have panel. + (cons 0 0))) + (t nil))) -(defun vertico-posframe--minibuffer-exit-hook () - "The function used by `minibuffer-exit-hook'." - ;; `vertico--resize-window' have set `max-mini-window-height' to - ;; 1.0, so I think setting it to 1.0 here is safe :-). - (setq-local max-mini-window-height 1.0) - (posframe-hide vertico-posframe--buffer)) +(defun vertico-posframe-hidehandler (_) + "Hidehandler used by vertico-posframe." + (not (minibufferp))) -(defun vertico-posframe--setup () - "Setup minibuffer overlay, which pushes the minibuffer content down." - (add-hook 'minibuffer-exit-hook #'vertico-posframe--minibuffer-exit-hook nil 'local)) +(defun vertico-posframe-get-size (buffer) + "The default functon used by `vertico-posframe-size-function'." + (list + :height (buffer-local-value 'vertico-posframe-height buffer) + :width (buffer-local-value 'vertico-posframe-width buffer) + :min-height (or (buffer-local-value 'vertico-posframe-min-height buffer) + (let ((height (+ vertico-count 1))) + (min height (or (buffer-local-value 'vertico-posframe-height buffer) height)))) + :min-width (or (buffer-local-value 'vertico-posframe-min-width buffer) + (let ((width (round (* (frame-width) 0.62)))) + (min width (or (buffer-local-value 'vertico-posframe-width buffer) width)))))) ;;;###autoload (defun vertico-posframe-cleanup () @@ -333,28 +353,5 @@ is called, window-point will be set to WINDOW-POINT." (when (minibufferp buffer) (posframe-delete-frame buffer)))) -;;;###autoload -(define-minor-mode vertico-posframe-mode - "Display Vertico in posframe instead of the minibuffer." - :global t - (cond - (vertico-posframe-mode - (if (not (posframe-workable-p)) - (funcall (buffer-local-value 'vertico-posframe-fallback-mode (current-buffer)) 1) - (advice-add #'vertico--display-candidates :after #'vertico-posframe--display) - (advice-add #'vertico--setup :after #'vertico-posframe--setup) - (advice-add #'vertico--resize-window :override #'ignore))) - (t - (if (not (posframe-workable-p)) - (funcall (buffer-local-value 'vertico-posframe-fallback-mode (current-buffer)) -1) - (advice-remove #'vertico--display-candidates #'vertico-posframe--display) - (advice-remove #'vertico--setup #'vertico-posframe--setup) - (advice-remove #'vertico--resize-window #'ignore) - ;; When vertico-posframe-mode is disabled, hide posframe and let - ;; the contents of minibuffer show again, this approach let - ;; vertico-posframe works with vertico multiform toggle. - (set-window-vscroll (active-minibuffer-window) 0) - (posframe-hide vertico-posframe--buffer))))) - (provide 'vertico-posframe) ;;; vertico-posframe.el ends here