corfu-echo.el (3877B)
1 ;;; corfu-echo.el --- Show candidate documentation in echo area -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2021-2024 Free Software Foundation, Inc. 4 5 ;; Author: Daniel Mendler <mail@daniel-mendler.de> 6 ;; Maintainer: Daniel Mendler <mail@daniel-mendler.de> 7 ;; Created: 2022 8 ;; Package-Requires: ((emacs "28.1") (compat "30") (corfu "1.5")) 9 ;; URL: https://github.com/minad/corfu 10 11 ;; This file is part of GNU Emacs. 12 13 ;; This program is free software: you can redistribute it and/or modify 14 ;; it under the terms of the GNU General Public License as published by 15 ;; the Free Software Foundation, either version 3 of the License, or 16 ;; (at your option) any later version. 17 18 ;; This program is distributed in the hope that it will be useful, 19 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 20 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 ;; GNU General Public License for more details. 22 23 ;; You should have received a copy of the GNU General Public License 24 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 25 26 ;;; Commentary: 27 28 ;; Show candidate documentation in echo area. Enable `corfu-echo-mode'. 29 30 ;;; Code: 31 32 (require 'corfu) 33 (eval-when-compile 34 (require 'subr-x)) 35 36 (defface corfu-echo 37 '((t :inherit completions-annotations)) 38 "Face used for echo area messages." 39 :group 'corfu-faces) 40 41 (defcustom corfu-echo-delay '(2.0 . 1.0) 42 "Show documentation string in the echo area after that number of seconds. 43 The value can be a pair of two floats to specify initial and 44 subsequent delay." 45 :type '(choice (const :tag "Never" nil) 46 (number :tag "Delay in seconds") 47 (cons :tag "Two Delays" 48 (choice :tag "Initial " number) 49 (choice :tag "Subsequent" number))) 50 :group 'corfu) 51 52 (defvar corfu-echo--timer nil 53 "Echo area message timer.") 54 55 (defvar corfu-echo--message nil 56 "Last echo message.") 57 58 (defun corfu-echo--cancel (&optional msg) 59 "Cancel echo timer and refresh MSG." 60 (when corfu-echo--timer 61 (cancel-timer corfu-echo--timer) 62 (setq corfu-echo--timer nil)) 63 (corfu-echo--show msg) 64 (unless corfu-echo--message 65 (setq corfu-echo--timer nil 66 corfu-echo--message nil))) 67 68 (defun corfu-echo--show (msg) 69 "Show MSG in echo area." 70 (when (or msg corfu-echo--message) 71 (setq msg (or msg "") 72 corfu-echo--message msg) 73 (corfu--message "%s" (if (text-property-not-all 0 (length msg) 'face nil msg) 74 msg 75 (propertize msg 'face 'corfu-echo))))) 76 77 ;;;###autoload 78 (define-minor-mode corfu-echo-mode 79 "Show candidate documentation in echo area." 80 :global t :group 'corfu) 81 82 (cl-defmethod corfu--exhibit :after (&context (corfu-echo-mode (eql t)) &optional _auto) 83 (if-let (((not (minibufferp))) 84 (delay (if (consp corfu-echo-delay) 85 (funcall (if corfu-echo--message #'cdr #'car) 86 corfu-echo-delay) 87 corfu-echo-delay)) 88 (extra (nth 4 completion-in-region--data)) 89 (fun (plist-get extra :company-docsig)) 90 (cand (and (>= corfu--index 0) 91 (nth corfu--index corfu--candidates)))) 92 (if (<= delay 0) 93 (corfu-echo--show (funcall fun cand)) 94 (corfu-echo--cancel) 95 (setq corfu-echo--timer 96 (run-at-time delay nil 97 (lambda () 98 (corfu-echo--show (funcall fun cand)))))) 99 (corfu-echo--cancel))) 100 101 (cl-defmethod corfu--teardown :before (_buf &context (corfu-echo-mode (eql t))) 102 (corfu-echo--cancel)) 103 104 (cl-defmethod corfu--prepare :before (&context (corfu-echo-mode (eql t))) 105 ;; The refreshing is needed to prevent flicker if corfu-echo-delay=t. 106 (corfu-echo--cancel corfu-echo--message)) 107 108 (provide 'corfu-echo) 109 ;;; corfu-echo.el ends here