[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/corfu f434fed5f8 3/9: Add corfu-doc-popup
From: |
ELPA Syncer |
Subject: |
[elpa] externals/corfu f434fed5f8 3/9: Add corfu-doc-popup |
Date: |
Thu, 17 Nov 2022 14:57:28 -0500 (EST) |
branch: externals/corfu
commit f434fed5f8aec5bef142ad87d3b439841be263e6
Author: Yuwei Tian <fishtai0@gmail.com>
Commit: Daniel Mendler <mail@daniel-mendler.de>
Add corfu-doc-popup
---
extensions/corfu-doc-popup.el | 547 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 547 insertions(+)
diff --git a/extensions/corfu-doc-popup.el b/extensions/corfu-doc-popup.el
new file mode 100644
index 0000000000..39e75cd2d5
--- /dev/null
+++ b/extensions/corfu-doc-popup.el
@@ -0,0 +1,547 @@
+;;; corfu-doc-popup.el --- Documentation popup for Corfu -*- lexical-binding:
t -*-
+
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; Author: Yuwei Tian <fishtai0@gmail.com>
+;; Maintainer: Daniel Mendler <mail@daniel-mendler.de>
+;; Created: 2021
+;; Version: 0.9
+;; Keywords: corfu popup documentation convenience
+;; Package-Requires: ((emacs "27.1") (corfu "0.28"))
+;; Homepage: https://github.com/minad/corfu
+
+;; This file is part of GNU Emacs.
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Display a documentation popup for completion candidate when using Corfu.
+
+;;; Code:
+
+(require 'corfu)
+(eval-when-compile
+ (require 'subr-x))
+
+(defgroup corfu-doc-popup nil
+ "Display documentation popup alongside corfu."
+ :group 'corfu
+ :prefix "corfu-doc-popup-")
+
+(defcustom corfu-doc-popup-auto t
+ "Display documentation popup automatically."
+ :type 'boolean)
+
+(defcustom corfu-doc-popup-delay 0.1
+ "The number of seconds to wait before displaying the documentation popup.
+
+The value of nil means no delay."
+ :type '(choice (const :tag "never (nil)" nil)
+ (const :tag "immediate (0)" 0)
+ (number :tag "seconds")))
+
+(defcustom corfu-doc-popup-transition nil
+ "The method to transition the documentation popup when browsing candidates.
+
+The documentation popup transition only works when `corfu-auto-delay'
+is non-nil and its value is greater than 0.
+
+If this is nil, there is no transition (do nothing), the doc popup
+preserves the content of the last candidate.
+
+If the value is 'clear, the documentation content of the last candidate
+will be cleared on documentation popup transition.
+
+If the value is 'hide, the documentation popup will be hidden
+when brwosing candidates.
+
+It is recommended to select the corresponding transition method
+according to the value of `corfu-doc-popup-delay' to reduce flicker or
+documentation update delay."
+ :type '(choice (const :tag "no transition (nil)" nil)
+ (const :tag "clear content" clear)
+ (const :tag "hide popup" hide)))
+
+(defcustom corfu-doc-popup-max-width 80
+ "The max width of the corfu doc popup in characters."
+ :type 'integer)
+
+(defcustom corfu-doc-popup-max-height 10
+ "The max height of the corfu doc popup in characters."
+ :type 'integer)
+
+(defcustom corfu-doc-popup-resize-frame t
+ "Non-nil means resize the corfu doc popup automatically.
+
+If this is nil, do not resize corfu doc popup automatically."
+ :type 'boolean)
+
+(defvar corfu-doc-popup--frame nil
+ "Doc frame.")
+
+(defvar corfu-doc-popup--frame-parameters
+ (let* ((cw (default-font-width))
+ (lmw (* cw corfu-left-margin-width))
+ (rmw (* cw corfu-right-margin-width))
+ (fp (copy-alist corfu--frame-parameters)))
+ (setf (alist-get 'left-fringe fp) (ceiling lmw)
+ (alist-get 'right-fringe fp) (ceiling rmw))
+ fp)
+ "Default doc child frame parameters.")
+
+(defvar corfu-doc-popup--auto-timer nil
+ "Corfu doc popup auto display timer.")
+
+(defvar-local corfu-doc-popup--candidate nil
+ "Completion candidate for the doc popup.")
+
+(defvar-local corfu-doc-popup--cf-popup-edges nil
+ "Coordinates of the corfu popup's edges.
+
+The coordinates list has the form (LEFT TOP RIGHT BOTTOM) where all
+values are in pixels relative to the origin - the position (0, 0)
+- of FRAME's display. For terminal frames all values are
+relative to LEFT and TOP which are both zero.
+
+See `frame-edges' for details.")
+
+(defvar corfu-doc-popup--cf-window nil
+ "Window where the corfu popup is located.")
+
+(defvar-local corfu-doc-popup--direction nil
+ "Position direction of the doc popup relative to the corfu popup.")
+
+(defconst corfu-doc-popup--state-vars
+ '(corfu-doc-popup--candidate
+ corfu-doc-popup--cf-popup-edges
+ corfu-doc-popup--cf-window
+ corfu-doc-popup--direction)
+ "Buffer-local state variables used by corfu-doc-popup.")
+
+(defun corfu-doc-popup--visible-p ()
+ "Determine whether the doc popup is visible."
+ (and (frame-live-p corfu-doc-popup--frame)
+ (frame-visible-p corfu-doc-popup--frame)))
+
+(defun corfu-doc-popup--get-doc ()
+ "Get the documentation for the current completion candidate.
+
+The documentation is trimmed.
+Returns nil if an error occurs or the documentation content is empty."
+ (when-let
+ ((doc
+ (cond
+ ((= corfu--total 0) nil) ;; No candidates
+ ((< corfu--index 0) nil) ;; No candidate selected
+ (t
+ (if-let*
+ ((fun (plist-get corfu--extra :company-doc-buffer))
+ (res
+ ;; fix showing candidate location
+ ;; when fetch helpful documentation
+ (save-excursion
+ (let ((inhibit-message t)
+ (message-log-max nil))
+ (funcall fun (nth corfu--index corfu--candidates))))))
+ (let ((buf (or (car-safe res) res)))
+ (with-current-buffer buf
+ (buffer-string)))
+ nil))))) ;; No documentation available
+ (unless (string-empty-p (string-trim doc))
+ doc)))
+
+(defun corfu-doc-popup--size (&optional width height)
+ "Calculate popup size in the form of (width height).
+
+If WIDTH and HEIGHT is speicified, just return (WIDTH HEIGHT)."
+ (let ((max-width (* (frame-char-width) corfu-doc-popup-max-width))
+ (max-height (* (frame-char-height) corfu-doc-popup-max-height)))
+ (if (and width height)
+ (list (min width max-width) (min height max-height))
+ (pcase-let*
+ ((lfw (alist-get 'left-fringe corfu-doc-popup--frame-parameters))
+ (rfw (alist-get 'right-fringe corfu-doc-popup--frame-parameters))
+ (`(,popup-width ,popup-height)
+ (if (not corfu-doc-popup-resize-frame)
+ (list (or width
+ ;; left margin + inner width + right margin
+ (+ lfw max-width rfw))
+ (or height max-height))
+ (pcase-let
+ ((`(,win-width . ,win-height)
+ (save-window-excursion
+ (with-current-buffer " *corfu-doc-popup*"
+ (set-window-dedicated-p nil nil)
+ (set-window-buffer nil (current-buffer))
+ (window-text-pixel-size
+ nil (point-min) (point-max)
+ (* (default-font-width) corfu-doc-popup-max-width)
+ (* (default-line-height)
corfu-doc-popup-max-height))))))
+ (list (or width win-width) (or height win-height))))))
+ (list (min popup-width max-width) (min popup-height max-height))))))
+
+(defun corfu-doc-popup--frame-geometry (&optional frame)
+ "Return position and size geometric attributes of FRAME.
+
+The geometry represents the position and size in pixels
+in the form of (X Y WIDTH HEIGHT).
+
+FRAME must be a live frame and defaults to the selected one."
+ (pcase-let
+ ((`(,x . ,y) (frame-position frame)))
+ (list x y (frame-pixel-width frame) (frame-pixel-height frame))))
+
+(defun corfu-doc-popup--display-area-horizontal (width height)
+ "Calculate the horizontal display area for the doc popup.
+
+The WIDTH and HEIGHT of the doc popup are in pixels.
+
+The calculated area is in the form (X Y WIDTH HEIGHT DIRECTION).
+DIRECTION indicates the horizontal position direction of the doc popup
+relative to the corfu popup, its value can be 'right or 'left."
+ (pcase-let*
+ ((a-x 0) (a-y 0) (a-width width) (a-height height) (a-direction 'right)
+ (border
+ (alist-get 'child-frame-border-width
corfu-doc-popup--frame-parameters))
+ ;; space between candidates popup and doc popup
+ (space (- border)) ;; share the border
+ (lfw (alist-get 'left-fringe corfu-doc-popup--frame-parameters))
+ (rfw (alist-get 'right-fringe corfu-doc-popup--frame-parameters))
+ (`(,_pfx ,_pfy ,pfw ,_pfh)
+ (corfu-doc-popup--frame-geometry (frame-parent corfu--frame)))
+ (`(,cfx ,cfy ,cfw ,_cfh) (corfu-doc-popup--frame-geometry corfu--frame))
+ (x-on-right (+ cfx cfw space))
+ ;; width remaining right
+ (w-remaining-right (- pfw 1 x-on-right border lfw rfw border))
+ (x-on-left (- cfx space pfw))
+ ;; width remaining left
+ (w-remaining-left (- cfx space 1 border lfw rfw border)))
+ (cond
+ ((> w-remaining-right width)
+ (setq a-x x-on-right))
+ ((and (< w-remaining-right width)
+ (> w-remaining-left width))
+ (setq a-x x-on-left
+ a-direction 'left)
+ ;; workaround for emacs bug#58627
+ (when (eq window-system 'ns)
+ (setq a-x (- cfx space 1 border lfw width rfw border))))
+ ((>= w-remaining-right w-remaining-left)
+ (setq a-x x-on-right
+ a-width w-remaining-right))
+ (t
+ (setq a-x x-on-left
+ a-direction 'left
+ a-width w-remaining-left)
+ ;; workaround for emacs bug#58627
+ (when (eq window-system 'ns)
+ (setq a-x 1))))
+ (setq a-y cfy)
+ (list a-x a-y a-width a-height a-direction)))
+
+(defun corfu-doc-popup--display-area-vertical (width height)
+ "Calculate the vertical display area for the doc popup.
+
+The WIDTH and HEIGHT of the doc popup are in pixels.
+
+The calculated area is in the form (X Y WIDTH HEIGHT DIRECTION).
+DIRECTION indicates the vertical position direction of the doc popup
+relative to the corfu popup, its value can be 'bottom or 'top."
+ (pcase-let*
+ ((a-x 0) (a-y 0) (a-height height) (a-direction 'bottom)
+ (border
+ (alist-get 'child-frame-border-width
+ corfu-doc-popup--frame-parameters))
+ (space (- border))
+ (lfw (alist-get 'left-fringe corfu-doc-popup--frame-parameters))
+ (rfw (alist-get 'right-fringe corfu-doc-popup--frame-parameters))
+ (lh (default-line-height))
+ (`(,_pfx ,_pfy ,pfw ,pfh)
+ (corfu-doc-popup--frame-geometry (frame-parent corfu--frame)))
+ (`(,cfx ,cfy ,_cfw ,cfh) (corfu-doc-popup--frame-geometry corfu--frame))
+ (cf-on-cursor-bottom-p
+ (>= cfy
+ (+ (cadr (window-inside-pixel-edges))
+ (window-tab-line-height)
+ (or (cdr (posn-x-y (posn-at-point (point)))) 0)
+ lh)))
+ (y-on-top (max 0 (- cfy space border height border)))
+ (h-remaining-top (- cfy border border))
+ (y-on-bottom (+ cfy cfh space))
+ (h-remaining-bottom (- pfh y-on-bottom border border))
+ (a-width (min width (- pfw cfx border lfw rfw border))))
+ (if cf-on-cursor-bottom-p
+ (setq a-y y-on-bottom
+ a-height (min h-remaining-bottom height))
+ (setq a-y y-on-top
+ a-height (min h-remaining-top height)
+ a-direction 'top))
+ (setq a-height (min a-height (* (floor (/ a-height lh)) lh)))
+ (unless cf-on-cursor-bottom-p
+ (setq a-y (max 0 (- cfy space border height border))))
+ (setq a-x cfx)
+ (list a-x a-y a-width a-height a-direction)))
+
+(defun corfu-doc-popup--display-area (&optional direction width height)
+ "Calculate the display area for the doc popup.
+
+If DIRECTION is specified, the display area in the corresponding direction
+is calculated first, its value can be 'bottom, 'top,'right or 'left.
+
+The pixel size of the doc popup can be specified with the optional
+arguments WIDTH and HEIGHT.
+
+The calculated area is in the form (X Y WIDTH HEIGHT DIRECTION).
+DIRECTION indicates the position direction of the doc popup relative to
+the corfu popup, its value is 'bottom, 'top, 'right or 'left."
+ (cond
+ ((member direction '(right left))
+ (apply #'corfu-doc-popup--display-area-horizontal
+ (corfu-doc-popup--size)))
+ ((member direction '(bottom top))
+ (apply #'corfu-doc-popup--display-area-vertical
+ (corfu-doc-popup--size)))
+ (t
+ (pcase-let*
+ ((`(,width ,height) ;; popup inner width and height
+ (corfu-doc-popup--size width height))
+ (`(,v-x ,v-y ,v-w ,v-h ,v-d)
+ (corfu-doc-popup--display-area-vertical width height)))
+ (if (and (>= v-h height) (>= v-w width))
+ (list v-x v-y v-w v-h v-d)
+ (pcase-let
+ ((`(,h-x ,h-y ,h-w ,h-h ,h-d)
+ (corfu-doc-popup--display-area-horizontal width height)))
+ (if (>= (* v-w v-h) (* h-w h-h))
+ (list v-x v-y v-w v-h v-d)
+ (list h-x h-y h-w h-h h-d))))))))
+
+(defun corfu-doc-popup--show (&optional candidate candidate-index)
+ "Show the doc popup.
+
+The optional CANDIDATE is the completion candidate for the doc popup.
+
+The optional CANDIDATE-INDEX is the the current completion candidate index,
+it should be compared with the value recorded by `corfu--index'."
+ (when (and corfu-mode
+ (corfu--popup-support-p)
+ (frame-live-p corfu--frame)
+ (frame-visible-p corfu--frame)
+ (or (null candidate-index)
+ (equal candidate-index corfu--index)))
+ (when (null candidate)
+ (setq candidate (and (> corfu--total 0) (>= corfu--index 0)
+ (nth corfu--index corfu--candidates))))
+ (if (not candidate)
+ (corfu-doc-popup--hide)
+ (let ((should-update-doc-p
+ (not (string= candidate corfu-doc-popup--candidate)))
+ doc-updated-p
+ ;; check if the coordinates of the corfu popup have changed
+ (cfp-edges-changed-p
+ (not (equal (frame-edges corfu--frame 'inner-edges)
+ corfu-doc-popup--cf-popup-edges))))
+ (if (not should-update-doc-p)
+ (when (and (not (string-empty-p
+ (string-trim
+ (with-current-buffer " *corfu-doc-popup*"
+ (buffer-string)))))
+ (not (corfu-doc-popup--visible-p)))
+ (make-frame-visible corfu-doc-popup--frame))
+ (if-let* ((doc (corfu-doc-popup--get-doc)))
+ (progn
+ ;; turn on word wrap and hide fringe indicators
+ (with-current-buffer
+ (corfu--make-buffer " *corfu-doc-popup*" doc)
+ (setq-local line-move-visual t)
+ (setq-local truncate-partial-width-windows nil)
+ (setq truncate-lines nil
+ word-wrap t
+ fringe-indicator-alist `(,(cons 'continuation nil))))
+ (setq doc-updated-p t))
+ (corfu-doc-popup--hide)))
+ (when (or (and (not should-update-doc-p) cfp-edges-changed-p)
+ doc-updated-p)
+ (pcase-let
+ ((`(,area-x ,area-y ,area-w ,area-h ,area-d)
+ (apply
+ #'corfu-doc-popup--display-area
+ corfu-doc-popup--direction
+ (when (not should-update-doc-p)
+ (let ((border
+ (alist-get 'child-frame-border-width
+ corfu-doc-popup--frame-parameters)))
+ (list (- (frame-pixel-width corfu-doc-popup--frame)
+ border border)
+ (- (frame-pixel-height corfu-doc-popup--frame)
+ border border)))))))
+ (setq corfu-doc-popup--frame
+ (corfu--make-frame corfu-doc-popup--frame
+ corfu-doc-popup--frame-parameters
+ (get-buffer " *corfu-doc-popup*")
+ area-x area-y area-w area-h)
+ corfu-doc-popup--direction area-d)))
+ (if doc-updated-p
+ (setq corfu-doc-popup--candidate candidate
+ corfu-doc-popup--cf-popup-edges
+ (frame-edges corfu--frame 'inner-edges)
+ corfu-doc-popup--cf-window (selected-window))
+ (when cfp-edges-changed-p
+ (setq corfu-doc-popup--cf-popup-edges
+ (frame-edges corfu--frame 'inner-edges))))))))
+
+(defun corfu-doc-popup--hide ()
+ "Clear the doc popup buffer content and hide it."
+ (when (frame-live-p corfu-doc-popup--frame)
+ (make-frame-invisible corfu-doc-popup--frame)
+ (corfu-doc-popup--clear-buffer)))
+
+(defun corfu-doc-popup--clear-buffer ()
+ "Clear the doc popup buffer content."
+ (with-current-buffer (get-buffer " *corfu-doc-popup*")
+ (let ((inhibit-read-only t))
+ (erase-buffer))))
+
+(defun corfu-doc-popup--transition ()
+ "Transition when updating the doc popup."
+ (when (corfu-doc-popup--visible-p)
+ (when (and (not (null corfu-doc-popup-delay))
+ (> corfu-doc-popup-delay 0))
+ (pcase corfu-doc-popup-transition
+ ('clear
+ (corfu-doc-popup--clear-buffer)
+ (corfu-doc-popup--show corfu-doc-popup--candidate))
+ ('hide (make-frame-invisible corfu-doc-popup--frame))
+ (_ (corfu-doc-popup--show corfu-doc-popup--candidate))))))
+
+(defun corfu-doc-popup-scroll-up (&optional n)
+ "Scroll text of doc popup window upward N lines.
+
+If ARG is omitted or nil, scroll upward by a near full screen.
+See `scroll-up' for details."
+ (interactive "p")
+ (when-let ((cf-doc-buf (and (corfu-doc-popup--visible-p)
+ (get-buffer " *corfu-doc-popup*"))))
+ (with-selected-frame corfu-doc-popup--frame
+ (with-current-buffer cf-doc-buf
+ (funcall #'scroll-up n)))))
+
+(defun corfu-doc-popup-scroll-down (&optional n)
+ "Scroll text of doc popup window down N lines.
+
+If ARG is omitted or nil, scroll down by a near full screen."
+ (interactive "p")
+ (corfu-doc-popup-scroll-up (- (or n 1))))
+
+;;;###autoload
+(define-minor-mode corfu-doc-popup-mode
+ "Corfu doc popup minor mode."
+ :global nil
+ :group 'corfu
+ (cond
+ (corfu-doc-popup-mode
+ (corfu-doc-popup--show)
+ (add-hook 'completion-in-region-mode-hook #'corfu-doc-popup--setup))
+ (t
+ (corfu-doc-popup--teardown)
+ (remove-hook 'completion-in-region-mode-hook #'corfu-doc-popup--setup))))
+
+(defun corfu-doc-popup-toggle ()
+ "Toggle the doc popup display or hide.
+
+When using this command to manually hide the doc popup, it will
+not be displayed until this command is called again. Even if the
+corfu doc mode is turned on and `corfu-doc-popup-auto' is set to Non-nil."
+ (interactive)
+ (when corfu-doc-popup-mode
+ (if (corfu-doc-popup--visible-p)
+ (progn
+ (corfu-doc-popup--teardown)
+ (remove-hook 'completion-in-region-mode-hook
+ #'corfu-doc-popup--setup))
+ (corfu-doc-popup--show)
+ (corfu-doc-popup--setup)
+ (add-hook 'completion-in-region-mode-hook #'corfu-doc-popup--setup))))
+
+(defun corfu-doc-popup--post-command ()
+ "Update the doc popup after last command."
+ (when corfu-preselect-first
+ (advice-remove 'corfu--exhibit #'corfu-doc-popup--cf-exhibit-after-advice))
+ (when (and (frame-live-p corfu--frame)
+ (frame-visible-p corfu--frame))
+ (if-let ((candidate
+ (and (> corfu--total 0) (>= corfu--index 0)
+ (nth corfu--index corfu--candidates))))
+ (progn
+ (when corfu-doc-popup--auto-timer
+ (cancel-timer corfu-doc-popup--auto-timer)
+ (setq corfu-doc-popup--auto-timer nil))
+ (if (and (string= candidate corfu-doc-popup--candidate)
+ (eq (selected-window) corfu-doc-popup--cf-window)
+ (frame-live-p corfu-doc-popup--frame))
+ (corfu-doc-popup--show candidate)
+ (corfu-doc-popup--transition)
+ (setq corfu-doc-popup--auto-timer
+ (run-with-timer
+ corfu-doc-popup-delay nil
+ #'corfu-doc-popup--show nil corfu--index))))
+ (corfu-doc-popup--hide))))
+
+(defun corfu-doc-popup--cf-exhibit-after-advice (&rest _args)
+ "After advice for `corfu--exhibit'.
+To display the doc popup for the preselected completion candidate."
+ (when (and corfu--candidates (>= corfu--index 0))
+ (corfu-doc-popup--post-command)))
+
+(defun corfu-doc-popup--setup ()
+ "Setup corfu-doc-popup."
+ (if (not completion-in-region-mode)
+ (corfu-doc-popup--teardown)
+ (when corfu-doc-popup-mode
+ (if corfu-doc-popup-auto
+ (progn
+ ;; display the doc popup for the preselected first candidate
+ (when corfu-preselect-first
+ (advice-add 'corfu--exhibit :after
+ #'corfu-doc-popup--cf-exhibit-after-advice))
+ (add-hook 'post-command-hook #'corfu-doc-popup--post-command
+ 'append 'local))
+ (let ((sym (make-symbol "corfu-doc-popup--teardown"))
+ (buf (current-buffer)))
+ (fset sym
+ (lambda ()
+ (let ((candidate
+ (and (> corfu--total 0) (>= corfu--index 0)
+ (nth corfu--index corfu--candidates))))
+ (unless
+ (and completion-in-region-mode
+ (string= candidate corfu-doc-popup--candidate)
+ (eq (selected-window) corfu-doc-popup--cf-window)
+ (frame-live-p corfu-doc-popup--frame))
+ (remove-hook 'post-command-hook sym 'local)
+ (with-current-buffer (if (buffer-live-p buf)
+ buf
+ (current-buffer))
+ (corfu-doc-popup--teardown))))))
+ (add-hook 'post-command-hook sym 'append 'local))))))
+
+(defun corfu-doc-popup--teardown ()
+ "Teardown corfu-doc-popup."
+ (remove-hook 'post-command-hook #'corfu-doc-popup--post-command 'local)
+ (corfu-doc-popup--hide)
+ (mapc #'kill-local-variable corfu-doc-popup--state-vars))
+
+(provide 'corfu-doc-popup)
+;;; corfu-doc-popup.el ends here
- [elpa] externals/corfu updated (0d0b2c9fd9 -> ef048aeb01), ELPA Syncer, 2022/11/17
- [elpa] externals/corfu 6d010877f9 8/9: Increase corfu-doc-popup-delay, ELPA Syncer, 2022/11/17
- [elpa] externals/corfu abe4a14d52 2/9: Add optional argument to hack redisplay when move the frame, ELPA Syncer, 2022/11/17
- [elpa] externals/corfu f434fed5f8 3/9: Add corfu-doc-popup,
ELPA Syncer <=
- [elpa] externals/corfu 0632308f33 1/9: Make create buffer and make frame code reusable, ELPA Syncer, 2022/11/17
- [elpa] externals/corfu ef048aeb01 9/9: Remove corfu-doc-popup-transition, ELPA Syncer, 2022/11/17
- [elpa] externals/corfu 666678e7e9 7/9: Remove corfu-doc-popup group, ELPA Syncer, 2022/11/17
- [elpa] externals/corfu c63d92f141 4/9: Rename corfu-info to corfu-doc-buffer, ELPA Syncer, 2022/11/17
- [elpa] externals/corfu b02b68a2b8 6/9: Revert "Add optional argument to hack redisplay when move the frame", ELPA Syncer, 2022/11/17
- [elpa] externals/corfu 0438c9085d 5/9: Update README, ELPA Syncer, 2022/11/17