dotemacs

My Emacs configuration
git clone git://git.entf.net/dotemacs
Log | Files | Refs | LICENSE

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