consult-selectrum.el (4515B)
1 ;;; consult-selectrum.el --- Selectrum integration for Consult -*- lexical-binding: t -*- 2 3 ;; Copyright (C) 2021, 2022 Free Software Foundation, Inc. 4 5 ;; This file is part of GNU Emacs. 6 7 ;; This program is free software: you can redistribute it and/or modify 8 ;; it under the terms of the GNU General Public License as published by 9 ;; the Free Software Foundation, either version 3 of the License, or 10 ;; (at your option) any later version. 11 12 ;; This program is distributed in the hope that it will be useful, 13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 ;; GNU General Public License for more details. 16 17 ;; You should have received a copy of the GNU General Public License 18 ;; along with this program. If not, see <http://www.gnu.org/licenses/>. 19 20 ;;; Commentary: 21 22 ;; Integration code for the Selectrum completion system. This package 23 ;; is automatically loaded by Consult. 24 25 ;;; Code: 26 27 (require 'consult) 28 29 ;; NOTE: It is not guaranteed that Selectrum is available during compilation! 30 (defvar selectrum-default-value-format) 31 (defvar selectrum-highlight-candidates-function) 32 (defvar selectrum-is-active) 33 (defvar selectrum-refine-candidates-function) 34 (defvar selectrum--history-hash) 35 (declare-function selectrum-exhibit "ext:selectrum") 36 (declare-function selectrum-get-current-candidate "ext:selectrum") 37 38 (defun consult-selectrum--filter-adv (orig pattern cands category highlight) 39 "Advice for ORIG `consult--completion-filter' function. 40 See `consult--completion-filter' for arguments PATTERN, CANDS, CATEGORY 41 and HIGHLIGHT." 42 ;; Do not use selectrum-is-active here, since we want to always use 43 ;; the Selectrum filtering when Selectrum is installed, even when 44 ;; Selectrum is currently not active. 45 ;; However if `selectrum-refine-candidates-function' is the default 46 ;; function, which uses the completion styles, the Selectrum filtering 47 ;; is not used and the original function is called. 48 (if (and (eq completing-read-function 'selectrum-completing-read) 49 (not (eq selectrum-refine-candidates-function 50 'selectrum-refine-candidates-using-completions-styles))) 51 (if highlight 52 (funcall selectrum-highlight-candidates-function pattern 53 (funcall selectrum-refine-candidates-function pattern cands)) 54 (funcall selectrum-refine-candidates-function pattern cands)) 55 (funcall orig pattern cands category highlight))) 56 57 (defun consult-selectrum--candidate () 58 "Return current selectrum candidate." 59 (and selectrum-is-active (selectrum-get-current-candidate))) 60 61 (defun consult-selectrum--refresh (&optional reset) 62 "Refresh completion UI, keep current candidate unless RESET is non-nil." 63 (when selectrum-is-active 64 (when consult--narrow 65 (setq-local selectrum-default-value-format nil)) 66 (when reset 67 (setq-local selectrum--history-hash nil)) 68 (selectrum-exhibit (not reset)))) 69 70 (defun consult-selectrum--split-wrap (orig split) 71 "Wrap candidates highlight/refinement ORIG function. 72 The input is split by the SPLIT function." 73 (lambda (str cands) 74 (funcall orig (cadr (funcall split str 0)) cands))) 75 76 (defun consult-selectrum--split-setup-adv (orig split) 77 "Advice for `consult--split-setup' to be used by Selectrum. 78 79 ORIG is the original function. 80 SPLIT is the splitter function." 81 (if (not selectrum-is-active) 82 (funcall orig split) 83 (setq-local 84 selectrum-refine-candidates-function 85 (consult-selectrum--split-wrap selectrum-refine-candidates-function split) 86 selectrum-highlight-candidates-function 87 (consult-selectrum--split-wrap selectrum-highlight-candidates-function split)))) 88 89 (defun consult-selectrum--crm-adv (&rest args) 90 "Setup crm for Selectrum given ARGS." 91 (consult--minibuffer-with-setup-hook 92 (lambda () 93 (when selectrum-is-active 94 (setq-local selectrum-default-value-format nil))) 95 (apply args))) 96 97 (add-hook 'consult--completion-candidate-hook #'consult-selectrum--candidate) 98 (add-hook 'consult--completion-refresh-hook #'consult-selectrum--refresh) 99 (advice-add #'consult-completing-read-multiple :around #'consult-selectrum--crm-adv) 100 (advice-add #'consult--completion-filter :around #'consult-selectrum--filter-adv) 101 (advice-add #'consult--split-setup :around #'consult-selectrum--split-setup-adv) 102 (define-key consult-async-map [remap selectrum-insert-current-candidate] 'selectrum-next-page) 103 104 (provide 'consult-selectrum) 105 ;;; consult-selectrum.el ends here