From 638e33a98db3574261bc41b738186d5f6b87b39d Mon Sep 17 00:00:00 2001 From: Daniel Mendler Date: Fri, 18 Nov 2022 12:12:18 +0100 Subject: BREAKING CHANGE: Extract corfu-echo extension from corfu.el Enable corfu-echo-mode to enable echo messages. The corfu-infoframe somewhat conflicts with corfu-echo, since it is disturbing it both the info frame and the echo message pop up after each other. Therefore it makes sense to maintain corfu-echo as a separate extension, on the same level as corfu-infoframe. --- README.org | 2 +- corfu.el | 61 ------------------------- extensions/corfu-echo.el | 115 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 62 deletions(-) create mode 100644 extensions/corfu-echo.el diff --git a/README.org b/README.org index eeeebf5..d67d2cc 100644 --- a/README.org +++ b/README.org @@ -83,7 +83,6 @@ Here is an example configuration: ;; (corfu-preview-current nil) ;; Disable current candidate preview ;; (corfu-preselect-first nil) ;; Disable candidate preselection ;; (corfu-on-exact-match nil) ;; Configure handling of exact matches - ;; (corfu-echo-documentation nil) ;; Disable documentation in the echo area ;; (corfu-scroll-margin 5) ;; Use scroll margin ;; Enable Corfu only for certain modes. @@ -446,6 +445,7 @@ be enabled manually if desired. Furthermore it is possible to install all of the files separately, both ~corfu.el~ and the ~corfu-*.el~ extensions. Currently the following extensions come with the Corfu ELPA package: +- [[https://github.com/minad/corfu/blob/main/extensions/corfu-echo.el][corfu-echo]]: Display brief candidate documentation in the echo area. - [[https://github.com/minad/corfu/blob/main/extensions/corfu-history.el][corfu-history]]: =corfu-history-mode= remembers selected candidates and sorts the candidates by their history position. - [[https://github.com/minad/corfu/blob/main/extensions/corfu-indexed.el][corfu-indexed]]: =corfu-indexed-mode= allows you to select indexed candidates with diff --git a/corfu.el b/corfu.el index 41d25f2..bd1a047 100644 --- a/corfu.el +++ b/corfu.el @@ -126,18 +126,6 @@ separator: Only stay alive if there is no match and "Width of the bar in units of the character width." :type 'float) -(defcustom corfu-echo-documentation '(1.0 . 0.2) - "Show documentation string in the echo area after that number of seconds. -Set to nil to disable the echo message or to t for an instant message. -The value can be a pair of two floats to specify initial and subsequent -delay." - :type '(choice (const :tag "Never" nil) - (const :tag "Instant" t) - (number :tag "Delay in seconds") - (cons :tag "Two Delays" - (choice :tag "Initial " number) - (choice :tag "Subsequent" number)))) - (defcustom corfu-margin-formatters nil "Registry for margin formatter functions. Each function of the list is called with the completion metadata as @@ -208,10 +196,6 @@ The completion backend can override this with (t :background "gray")) "The background color used for the thin border.") -(defface corfu-echo - '((t :inherit completions-annotations)) - "Face used for echo area messages.") - (defface corfu-annotations '((t :inherit completions-annotations)) "Face used for annotations.") @@ -285,12 +269,6 @@ The completion backend can override this with (defvar-local corfu--change-group nil "Undo change group.") -(defvar-local corfu--echo-timer nil - "Echo area message timer.") - -(defvar-local corfu--echo-message nil - "Last echo message.") - (defvar corfu--frame nil "Popup frame.") @@ -305,8 +283,6 @@ The completion backend can override this with corfu--total corfu--preview-ov corfu--extra - corfu--echo-timer - corfu--echo-message corfu--change-group corfu--metadata) "Buffer-local state variables used by Corfu.") @@ -830,40 +806,6 @@ there hasn't been any input, then quit." (overlay-put corfu--preview-ov 'window (selected-window)) (overlay-put corfu--preview-ov (if (= beg end) 'after-string 'display) cand))) -(defun corfu--echo-cancel (&optional msg) - "Cancel echo timer and refresh MSG to prevent flicker during redisplay." - (when corfu--echo-timer - (cancel-timer corfu--echo-timer) - (setq corfu--echo-timer nil)) - (corfu--echo-show msg)) - -(defun corfu--echo-show (msg) - "Show MSG in echo area." - (when (or msg corfu--echo-message) - (setq msg (or msg "") - corfu--echo-message msg) - (corfu--message "%s" (if (text-property-not-all 0 (length msg) 'face nil msg) - msg - (propertize msg 'face 'corfu-echo))))) - -(defun corfu--echo-documentation () - "Show documentation string of current candidate in echo area." - (if-let* ((delay (if (consp corfu-echo-documentation) - (funcall (if corfu--echo-message #'cdr #'car) - corfu-echo-documentation) - corfu-echo-documentation)) - (fun (plist-get corfu--extra :company-docsig)) - (cand (and (>= corfu--index 0) - (nth corfu--index corfu--candidates)))) - (if (or (eq delay t) (<= delay 0)) - (corfu--echo-show (funcall fun cand)) - (corfu--echo-cancel) - (setq corfu--echo-timer - (run-at-time delay nil - (lambda () - (corfu--echo-show (funcall fun cand)))))) - (corfu--echo-cancel))) - (defun corfu--exhibit (&optional auto) "Exhibit Corfu UI. AUTO is non-nil when initializing auto completion." @@ -883,7 +825,6 @@ AUTO is non-nil when initializing auto completion." (corfu--candidates (corfu--candidates-popup beg) (corfu--preview-current beg end) - (corfu--echo-documentation) (redisplay 'force)) ;; XXX HACK Ensure that popup is redisplayed ;; 3) No candidates & corfu-quit-no-match & initialized => Confirmation popup. ((pcase-exhaustive corfu-quit-no-match @@ -900,7 +841,6 @@ AUTO is non-nil when initializing auto completion." (when corfu--preview-ov (delete-overlay corfu--preview-ov) (setq corfu--preview-ov nil)) - (corfu--echo-cancel corfu--echo-message) ;; Ensure that state is initialized before next Corfu command (when (and (symbolp this-command) (string-prefix-p "corfu-" (symbol-name this-command))) (corfu--update)) @@ -1099,7 +1039,6 @@ Quit if no candidate is selected." (remove-hook 'pre-command-hook #'corfu--pre-command 'local) (remove-hook 'post-command-hook #'corfu--post-command) (when corfu--preview-ov (delete-overlay corfu--preview-ov)) - (corfu--echo-cancel) (accept-change-group corfu--change-group) (mapc #'kill-local-variable corfu--state-vars)) diff --git a/extensions/corfu-echo.el b/extensions/corfu-echo.el new file mode 100644 index 0000000..9f01cdd --- /dev/null +++ b/extensions/corfu-echo.el @@ -0,0 +1,115 @@ +;;; corfu-echo.el --- Show candidate documentation in echo area -*- lexical-binding: t -*- + +;; Copyright (C) 2021-2022 Free Software Foundation, Inc. + +;; Author: Daniel Mendler +;; Maintainer: Daniel Mendler +;; Created: 2022 +;; Version: 0.1 +;; 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 . + +;;; Commentary: + +;; Show candidate documentation in echo area. Enable `corfu-echo-mode'. + +;;; Code: + +(require 'corfu) +(eval-when-compile + (require 'subr-x)) + +(defface corfu-echo + '((t :inherit completions-annotations)) + "Face used for echo area messages." + :group 'corfu-faces) + +(defcustom corfu-echo-delay '(1.0 . 0.2) + "Show documentation string in the echo area after that number of seconds. +Set to t for an instant message. The value can be a pair of two +floats to specify initial and subsequent delay." + :type '(choice (const :tag "Never" nil) + (const :tag "Instant" t) + (number :tag "Delay in seconds") + (cons :tag "Two Delays" + (choice :tag "Initial " number) + (choice :tag "Subsequent" number))) + :group 'corfu) + +(defvar-local corfu-echo--timer nil + "Echo area message timer.") + +(defvar-local corfu-echo--message nil + "Last echo message.") + +(defun corfu-echo--cancel (&optional hide) + "Cancel echo timer and optionally HIDE message." + (when corfu-echo--timer + (cancel-timer corfu-echo--timer) + (setq corfu-echo--timer nil)) + (corfu-echo--show (unless hide corfu-echo--message))) + +(defun corfu-echo--show (msg) + "Show MSG in echo area." + (when (or msg corfu-echo--message) + (setq msg (or msg "") + corfu-echo--message msg) + (corfu--message "%s" (if (text-property-not-all 0 (length msg) 'face nil msg) + msg + (propertize msg 'face 'corfu-echo))))) + +(defun corfu-echo--exhibit (&rest _) + "Show documentation string of current candidate in echo area." + (if-let* ((delay (if (consp corfu-echo-delay) + (funcall (if corfu-echo--message #'cdr #'car) + corfu-echo-delay) + corfu-echo-delay)) + (fun (plist-get corfu--extra :company-docsig)) + (cand (and (>= corfu--index 0) + (nth corfu--index corfu--candidates)))) + (if (or (eq delay t) (<= delay 0)) + (corfu-echo--show (funcall fun cand)) + (corfu-echo--cancel 'hide) + (setq corfu-echo--timer + (run-at-time delay nil + (lambda () + (corfu-echo--show (funcall fun cand)))))) + (corfu-echo--cancel 'hide))) + +(defun corfu-echo--teardown () + "Teardown echo display." + (corfu-echo--cancel 'hide) + (kill-local-variable 'corfu-echo--timer) + (kill-local-variable 'corfu-echo--message)) + +;;;###autoload +(define-minor-mode corfu-echo-mode + "Show candidate documentation in echo area." + :global t :group 'corfu + (cond + (corfu-echo-mode + (advice-add #'corfu--pre-command :before #'corfu-echo--cancel) + (advice-add #'corfu--exhibit :after #'corfu-echo--exhibit) + (advice-add #'corfu--teardown :before #'corfu-echo--teardown)) + (t + (advice-remove #'corfu--pre-command #'corfu-echo--cancel) + (advice-remove #'corfu--exhibit #'corfu-echo--exhibit) + (advice-remove #'corfu--teardown #'corfu-echo--teardown)))) + +(provide 'corfu-echo) +;;; corfu-echo.el ends here -- cgit v1.0