corfu-echo.el (4185B)
1 ;;; corfu-echo.el --- Show candidate documentation in echo area -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2021-2022 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 ;; Version: 0.1 9 ;; Package-Requires: ((emacs "27.1") (corfu "0.34")) 10 ;; Homepage: https://github.com/minad/corfu 11 12 ;; This file is part of GNU Emacs. 13 14 ;; This program is free software: you can redistribute it and/or modify 15 ;; it under the terms of the GNU General Public License as published by 16 ;; the Free Software Foundation, either version 3 of the License, or 17 ;; (at your option) any later version. 18 19 ;; This program is distributed in the hope that it will be useful, 20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 ;; GNU General Public License for more details. 23 24 ;; You should have received a copy of the GNU General Public License 25 ;; along with this program. If not, see <https://www.gnu.org/licenses/>. 26 27 ;;; Commentary: 28 29 ;; Show candidate documentation in echo area. Enable `corfu-echo-mode'. 30 31 ;;; Code: 32 33 (require 'corfu) 34 (eval-when-compile 35 (require 'subr-x)) 36 37 (defface corfu-echo 38 '((t :inherit completions-annotations)) 39 "Face used for echo area messages." 40 :group 'corfu-faces) 41 42 (defcustom corfu-echo-delay '(2.0 . 1.0) 43 "Show documentation string in the echo area after that number of seconds. 44 Set to t for an instant message. The value can be a pair of two 45 floats to specify initial and subsequent delay." 46 :type '(choice (const :tag "Never" nil) 47 (const :tag "Instant" t) 48 (number :tag "Delay in seconds") 49 (cons :tag "Two Delays" 50 (choice :tag "Initial " number) 51 (choice :tag "Subsequent" number))) 52 :group 'corfu) 53 54 (defvar-local corfu-echo--timer nil 55 "Echo area message timer.") 56 57 (defvar-local corfu-echo--message nil 58 "Last echo message.") 59 60 (defun corfu-echo--refresh () 61 "Refresh message to avoid flicker." 62 (corfu-echo--cancel corfu-echo--message)) 63 64 (defun corfu-echo--cancel (&optional msg) 65 "Cancel echo timer and refresh MSG." 66 (when corfu-echo--timer 67 (cancel-timer corfu-echo--timer) 68 (setq corfu-echo--timer nil)) 69 (corfu-echo--show msg) 70 (unless corfu-echo--message 71 (kill-local-variable 'corfu-echo--timer) 72 (kill-local-variable 'corfu-echo--message))) 73 74 (defun corfu-echo--show (msg) 75 "Show MSG in echo area." 76 (when (or msg corfu-echo--message) 77 (setq msg (or msg "") 78 corfu-echo--message msg) 79 (corfu--message "%s" (if (text-property-not-all 0 (length msg) 'face nil msg) 80 msg 81 (propertize msg 'face 'corfu-echo))))) 82 83 (defun corfu-echo--exhibit (&rest _) 84 "Show documentation string of current candidate in echo area." 85 (if-let* ((delay (if (consp corfu-echo-delay) 86 (funcall (if corfu-echo--message #'cdr #'car) 87 corfu-echo-delay) 88 corfu-echo-delay)) 89 (fun (plist-get corfu--extra :company-docsig)) 90 (cand (and (>= corfu--index 0) 91 (nth corfu--index corfu--candidates)))) 92 (if (or (eq delay t) (<= 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 ;;;###autoload 102 (define-minor-mode corfu-echo-mode 103 "Show candidate documentation in echo area." 104 :global t :group 'corfu 105 (cond 106 (corfu-echo-mode 107 (advice-add #'corfu--pre-command :before #'corfu-echo--refresh) 108 (advice-add #'corfu--exhibit :after #'corfu-echo--exhibit) 109 (advice-add #'corfu--teardown :before #'corfu-echo--cancel)) 110 (t 111 (advice-remove #'corfu--pre-command #'corfu-echo--refresh) 112 (advice-remove #'corfu--exhibit #'corfu-echo--exhibit) 113 (advice-remove #'corfu--teardown #'corfu-echo--cancel)))) 114 115 (provide 'corfu-echo) 116 ;;; corfu-echo.el ends here