forked from radian-software/selectrum
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselectrum-helm.el
132 lines (115 loc) · 4.68 KB
/
selectrum-helm.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
;;; selectrum-helm.el --- Use Selectrum for Helm -*- lexical-binding: t -*-
;; Copyright (C) 2020 Radon Rosborough
;; Author: Radon Rosborough <[email protected]>
;; Created: 15 Apr 2020
;; Homepage: https://github.com/raxod502/selectrum
;; Keywords: extensions
;; Package-Requires: ((emacs "25.1") (helm "3.6.1") (selectrum "2.0"))
;; SPDX-License-Identifier: MIT
;; Version: 2.0
;;; Commentary:
;; This file provides a minor mode that causes all Helm commands to
;; redirect to use Selectrum instead, at some loss of functionality.
;;; Code:
;; To see the outline of this file, run M-x outline-minor-mode and
;; then press C-c @ C-t. To also show the top-level functions and
;; variable declarations in each section, run M-x occur with the
;; following query: ^;;;;* \|^(
(require 'cl-lib)
(require 'let-alist)
(require 'map)
(require 'subr-x)
(require 'selectrum)
(declare-function helm "ext:helm")
(declare-function helm-get-current-source "ext:helm")
(cl-defun selectrum-helm--normalize-source (source &optional only-one)
"Normalize single Helm SOURCE alist.
ONLY-ONE non-nil means don't add section headers."
(let-alist source
(when .init
(funcall .init))
(let ((cands (cond
((functionp .candidates)
(funcall .candidates))
((symbolp .candidates)
(symbol-value .candidates))
(t
.candidates))))
(dolist (func (if (functionp .candidate-transformer)
(list .candidate-transformer)
.candidate-transformer))
(setq cands (funcall func cands)))
(setq cands (mapcar
(lambda (cand)
(when (consp cand)
(setq cand
(propertize
(car cand)
'selectrum-helm-return
(cdr cand))))
(setq cand
(propertize
cand
'selectrum-helm-action
.action
'selectrum-candidate-display-suffix
(unless only-one
(when-let ((name .name))
(when (string-suffix-p ":" name)
(setq name
(substring name 0 (1- (length name)))))
(format " [%s]" name)))
'selectrum-helm-source
.name))
cand)
cands))
cands)))
(cl-defun selectrum-helm--normalize-sources (sources)
"Given SOURCES as passed to `helm', return flat list of candidate strings."
(cond
((symbolp sources)
(setq sources (symbol-value sources)))
((symbolp (car-safe (car-safe sources)))
(setq sources (list sources))))
(apply #'append (mapcar (lambda (source)
(selectrum-helm--normalize-source
source (= 1 (length sources))))
sources)))
(defun selectrum-helm--adapter (&rest plist)
"Receive arguments to `helm' and invoke `selectrum-read' instead.
For PLIST, see `helm'. This is an `:override' advice for `helm'."
(let* ((result (selectrum-read
(or (plist-get plist :prompt) "pattern: ")
(selectrum-helm--normalize-sources
(plist-get plist :sources))
:default-candidate (plist-get plist :preselect)
:initial-input (plist-get plist :input)
:history (plist-get plist :history)))
(cand (or (get-text-property 0 'selectrum-helm-return result)
result)))
(when-let ((action (get-text-property 0 'selectrum-helm-action result)))
(if (functionp action)
(funcall action cand)
(when (symbolp action)
(setq action (symbol-value action)))
(funcall (cdr (car action)) cand)))))
;;;###autoload
(define-minor-mode selectrum-helm-mode
"Minor mode to use Selectrum to implement Helm commands."
:global t
:group 'selectrum
(if selectrum-helm-mode
(progn
(advice-add #'helm :override #'selectrum-helm--adapter)
(advice-add #'helm-get-current-source :override #'ignore))
(advice-remove #'helm #'selectrum-helm--adapter)
(advice-remove #'helm-get-current-source #'ignore)))
;;;; Closing remarks
(provide 'selectrum-helm)
;; Local Variables:
;; checkdoc-verb-check-experimental-flag: nil
;; indent-tabs-mode: nil
;; outline-regexp: ";;;;* "
;; sentence-end-double-space: nil
;; End:
;;; selectrum-helm.el ends here