dotemacs

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

corfu-indexed.el (3753B)


      1 ;;; corfu-indexed.el --- Select indexed candidates -*- lexical-binding: t -*-
      2 
      3 ;; Copyright (C) 2022  Free Software Foundation, Inc.
      4 
      5 ;; Author: Luis Henriquez-Perez <luis@luishp.xyz>, 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.23"))
     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 <http://www.gnu.org/licenses/>.
     26 
     27 ;;; Commentary:
     28 
     29 ;; This package is a Corfu extension, which prefixes candidates with indices and
     30 ;; allows you to select with prefix arguments. This is designed to be a faster
     31 ;; alternative to selecting a candidate with `corfu-next' and `corfu-previous'.
     32 
     33 ;;; Code:
     34 
     35 (require 'corfu)
     36 (eval-when-compile
     37   (require 'cl-lib))
     38 
     39 (defface corfu-indexed
     40   '((default :height 0.75)
     41     (((class color) (min-colors 88) (background dark))
     42      :foreground "#f4f4f4" :background "#323232")
     43      (((class color) (min-colors 88) (background light))
     44      :foreground "#404148" :background "#d7d7d7")
     45     (t :background "black"))
     46   "Face used for the candidate index prefix."
     47   :group 'corfu-faces)
     48 
     49 (defvar corfu-indexed--commands
     50   '(corfu-insert corfu-complete)
     51   "Commands that should be indexed.")
     52 
     53 (defun corfu-indexed--affixate (cands)
     54   "Advice for `corfu--affixate' which prefixes the CANDS with an index."
     55   (setq cands (cdr cands))
     56   (let* ((space #(" " 0 1 (face (:height 0.5 :inherit corfu-indexed))))
     57          (width (if (> (length cands) 10) 2 1))
     58          (fmt (concat space
     59                       (propertize (format "%%%ds" width)
     60                                   'face 'corfu-indexed)
     61                       space))
     62          (align
     63           (propertize (make-string width ?\s)
     64                       'display
     65                       `(space :align-to (+ left ,(1+ width))))))
     66     (cl-loop for cand in cands for index from 0 do
     67       (setf (cadr cand)
     68             (concat
     69              (propertize " " 'display (format fmt index))
     70              align
     71              (cadr cand))))
     72     (cons t cands)))
     73 
     74 (defun corfu-indexed--handle-prefix (orig &rest args)
     75   "Handle prefix argument before calling ORIG function with ARGS."
     76   (if (and current-prefix-arg (called-interactively-p t))
     77       (let ((corfu--index (+ corfu--scroll (prefix-numeric-value current-prefix-arg))))
     78         (if (or (< corfu--index 0)
     79                 (>= corfu--index corfu--total)
     80                 (>= corfu--index (+ corfu--scroll corfu-count)))
     81             (message "Out of range")
     82           (funcall orig)))
     83     (apply orig args)))
     84 
     85 ;;;###autoload
     86 (define-minor-mode corfu-indexed-mode
     87   "Prefix candidates with indices."
     88   :global t :group 'corfu
     89   (cond
     90    (corfu-indexed-mode
     91     (advice-add #'corfu--affixate :filter-return #'corfu-indexed--affixate)
     92     (dolist (cmd corfu-indexed--commands)
     93       (advice-add cmd :around #'corfu-indexed--handle-prefix)))
     94    (t
     95     (advice-remove #'corfu--affixate #'corfu-indexed--affixate)
     96     (dolist (cmd corfu-indexed--commands)
     97       (advice-remove cmd #'corfu-indexed--handle-prefix)))))
     98 
     99 (provide 'corfu-indexed)
    100 ;;; corfu-indexed.el ends here