corfu-indexed.el (3558B)
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 ;; 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 ;; This package is a Corfu extension, which prefixes candidates with indices if 29 ;; enabled via `corfu-indexed-mode'. It allows you to select candidates with 30 ;; prefix arguments. This is designed to be a faster alternative to selecting a 31 ;; 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 (defcustom corfu-indexed-start 0 50 "Start of the indexing." 51 :group 'corfu 52 :type 'natnum) 53 54 (defvar corfu-indexed--commands 55 '(corfu-insert corfu-complete) 56 "Commands that should be indexed.") 57 58 ;;;###autoload 59 (define-minor-mode corfu-indexed-mode 60 "Prefix candidates with indices." 61 :global t :group 'corfu) 62 63 (cl-defmethod corfu--prepare :before (&context (corfu-indexed-mode (eql t))) 64 (when (and prefix-arg (memq this-command corfu-indexed--commands)) 65 (let ((index (+ corfu--scroll 66 (- (prefix-numeric-value prefix-arg) 67 corfu-indexed-start)))) 68 (if (and (>= index 0) 69 (< index corfu--total) 70 (< index (+ corfu--scroll corfu-count))) 71 (setq corfu--index index) 72 (message "Out of range") 73 (setq this-command #'ignore))))) 74 75 (cl-defmethod corfu--affixate :around (cands &context (corfu-indexed-mode (eql t))) 76 (setq cands (cdr (cl-call-next-method cands))) 77 (let* ((space #(" " 0 1 (face (:height 0.5 :inherit corfu-indexed)))) 78 (width (if (length> cands (- 10 corfu-indexed-start)) 2 1)) 79 (fmt (concat space 80 (propertize (format "%%%ds" width) 81 'face 'corfu-indexed) 82 space)) 83 (align 84 (propertize (make-string width ?\s) 85 'display 86 `(space :align-to (+ left ,(1+ width)))))) 87 (cl-loop for cand in cands for index from corfu-indexed-start do 88 (setf (cadr cand) 89 (concat 90 (propertize " " 'display (format fmt index)) 91 align 92 (cadr cand)))) 93 (cons t cands))) 94 95 (provide 'corfu-indexed) 96 ;;; corfu-indexed.el ends here