corfu-indexed.el (3585B)
1 ;;; corfu-indexed.el --- Select indexed candidates -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2022-2024 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: 1.3 9 ;; Package-Requires: ((emacs "27.1") (compat "29.1.4.4") (corfu "1.3")) 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 ;; This package is a Corfu extension, which prefixes candidates with indices if 30 ;; enabled via `corfu-indexed-mode'. It allows you to select candidates with 31 ;; prefix arguments. This is designed to be a faster alternative to selecting a 32 ;; candidate with `corfu-next' and `corfu-previous'. 33 34 ;;; Code: 35 36 (require 'corfu) 37 (eval-when-compile 38 (require 'cl-lib)) 39 40 (defface corfu-indexed 41 '((default :height 0.75) 42 (((class color) (min-colors 88) (background dark)) 43 :foreground "#f4f4f4" :background "#323232") 44 (((class color) (min-colors 88) (background light)) 45 :foreground "#404148" :background "#d7d7d7") 46 (t :background "black")) 47 "Face used for the candidate index prefix." 48 :group 'corfu-faces) 49 50 (defcustom corfu-indexed-start 0 51 "Start of the indexing." 52 :group 'corfu 53 :type 'natnum) 54 55 (defvar corfu-indexed--commands 56 '(corfu-insert corfu-complete) 57 "Commands that should be indexed.") 58 59 ;;;###autoload 60 (define-minor-mode corfu-indexed-mode 61 "Prefix candidates with indices." 62 :global t :group 'corfu) 63 64 (cl-defmethod corfu--prepare :before (&context (corfu-indexed-mode (eql t))) 65 (when (and prefix-arg (memq this-command corfu-indexed--commands)) 66 (let ((index (+ corfu--scroll 67 (- (prefix-numeric-value prefix-arg) 68 corfu-indexed-start)))) 69 (if (and (>= index 0) 70 (< index corfu--total) 71 (< index (+ corfu--scroll corfu-count))) 72 (setq corfu--index index) 73 (message "Out of range") 74 (setq this-command #'ignore))))) 75 76 (cl-defmethod corfu--affixate :around (cands &context (corfu-indexed-mode (eql t))) 77 (setq cands (cdr (cl-call-next-method cands))) 78 (let* ((space #(" " 0 1 (face (:height 0.5 :inherit corfu-indexed)))) 79 (width (if (length> cands (- 10 corfu-indexed-start)) 2 1)) 80 (fmt (concat space 81 (propertize (format "%%%ds" width) 82 'face 'corfu-indexed) 83 space)) 84 (align 85 (propertize (make-string width ?\s) 86 'display 87 `(space :align-to (+ left ,(1+ width)))))) 88 (cl-loop for cand in cands for index from corfu-indexed-start do 89 (setf (cadr cand) 90 (concat 91 (propertize " " 'display (format fmt index)) 92 align 93 (cadr cand)))) 94 (cons t cands))) 95 96 (provide 'corfu-indexed) 97 ;;; corfu-indexed.el ends here