config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

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