commit | author | age
|
5cb5f7
|
1 |
;;; helm-source.el --- Helm source creation. -*- lexical-binding: t -*- |
C |
2 |
|
|
3 |
;; Copyright (C) 2015 ~ 2018 Thierry Volpiatto <thierry.volpiatto@gmail.com> |
|
4 |
|
|
5 |
;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com> |
|
6 |
;; URL: http://github.com/emacs-helm/helm |
|
7 |
|
|
8 |
;; This program is free software; you can redistribute it and/or modify |
|
9 |
;; it under the terms of the GNU General Public License as published by |
|
10 |
;; the Free Software Foundation, either version 3 of the License, or |
|
11 |
;; (at your option) any later version. |
|
12 |
|
|
13 |
;; This program is distributed in the hope that it will be useful, |
|
14 |
;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
15 |
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
16 |
;; GNU General Public License for more details. |
|
17 |
|
|
18 |
;; You should have received a copy of the GNU General Public License |
|
19 |
;; along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
20 |
|
|
21 |
;;; Commentary: |
|
22 |
|
|
23 |
;; Interface to create helm sources easily. |
|
24 |
;; Actually the eieo objects are transformed in alist for compatibility. |
|
25 |
;; In the future this package should allow creating source as eieo objects |
|
26 |
;; without conversion to alist, teaching helm to read such a structure. |
|
27 |
;; The compatibility with alists would be kept. |
|
28 |
|
|
29 |
;;; Code: |
|
30 |
|
|
31 |
(require 'cl-lib) |
|
32 |
(require 'eieio) |
|
33 |
(require 'helm-lib) |
|
34 |
|
|
35 |
(defvar helm-fuzzy-sort-fn) |
|
36 |
(defvar helm-fuzzy-match-fn) |
|
37 |
(defvar helm-fuzzy-search-fn) |
|
38 |
|
|
39 |
(declare-function helm-init-candidates-in-buffer "helm.el") |
|
40 |
(declare-function helm-interpret-value "helm.el") |
|
41 |
(declare-function helm-fuzzy-highlight-matches "helm.el") |
|
42 |
|
|
43 |
|
|
44 |
(defgeneric helm--setup-source (source) |
|
45 |
"Prepare slots and handle slot errors before creating a helm source.") |
|
46 |
|
|
47 |
(defgeneric helm-setup-user-source (source) |
|
48 |
"Allow users modifying slots in SOURCE just before creation.") |
|
49 |
|
|
50 |
|
|
51 |
;;; Classes for sources |
|
52 |
;; |
|
53 |
;; |
|
54 |
(defclass helm-source () |
|
55 |
((name |
|
56 |
:initarg :name |
|
57 |
:initform nil |
|
58 |
:custom string |
|
59 |
:documentation |
|
60 |
" The name of the source. |
|
61 |
A string which is also the heading which appears |
|
62 |
above the list of matches from the source. Must be unique.") |
|
63 |
|
|
64 |
(header-name |
|
65 |
:initarg :header-name |
|
66 |
:initform nil |
|
67 |
:custom function |
|
68 |
:documentation |
|
69 |
" A function returning the display string of the header. |
|
70 |
Its argument is the name of the source. This attribute is useful to |
|
71 |
add an additional information with the source name. |
|
72 |
It doesn't modify the name of the source.") |
|
73 |
|
|
74 |
(init |
|
75 |
:initarg :init |
|
76 |
:initform nil |
|
77 |
:custom function |
|
78 |
:documentation |
|
79 |
" Function called with no parameters when helm is started. |
|
80 |
It is useful for collecting current state information which can be |
|
81 |
used to create the list of candidates later. |
|
82 |
Initialization of `candidates-in-buffer' is done here |
|
83 |
with `helm-init-candidates-in-buffer'.") |
|
84 |
|
|
85 |
(candidates |
|
86 |
:initarg :candidates |
|
87 |
:initform nil |
|
88 |
:custom (choice function list) |
|
89 |
:documentation |
|
90 |
" Specifies how to retrieve candidates from the source. |
|
91 |
It can either be a variable name, a function called with no parameters |
|
92 |
or the actual list of candidates. |
|
93 |
|
|
94 |
The list must be a list whose members are strings, symbols |
|
95 |
or (DISPLAY . REAL) pairs. |
|
96 |
|
|
97 |
In case of (DISPLAY . REAL) pairs, the DISPLAY string is shown |
|
98 |
in the Helm buffer, but the REAL one is used as action |
|
99 |
argument when the candidate is selected. This allows a more |
|
100 |
readable presentation for candidates which would otherwise be, |
|
101 |
for example, too long or have a common part shared with other |
|
102 |
candidates which can be safely replaced with an abbreviated |
|
103 |
string for display purposes. |
|
104 |
|
|
105 |
Note that if the (DISPLAY . REAL) form is used then pattern |
|
106 |
matching is done on the displayed string, not on the real |
|
107 |
value.") |
|
108 |
|
|
109 |
(update |
|
110 |
:initarg :update |
|
111 |
:initform nil |
|
112 |
:custom function |
|
113 |
:documentation |
|
114 |
" Function called with no parameters at before \"init\" function |
|
115 |
when `helm-force-update' is called.") |
|
116 |
|
|
117 |
(cleanup |
|
118 |
:initarg :cleanup |
|
119 |
:initform nil |
|
120 |
:custom function |
|
121 |
:documentation |
|
122 |
" Function called with no parameters when *helm* buffer is |
|
123 |
closed. It is useful for killing unneeded candidates buffer. |
|
124 |
|
|
125 |
Note that the function is executed BEFORE performing action.") |
|
126 |
|
|
127 |
(keymap |
|
128 |
:initarg :keymap |
|
129 |
:initform helm-map |
|
130 |
:custom sexp |
|
131 |
:documentation |
|
132 |
" Specific keymap for this source. |
|
133 |
default value is `helm-map'.") |
|
134 |
|
|
135 |
(action |
|
136 |
:initarg :action |
|
137 |
:initform 'identity |
|
138 |
:custom (alist :key-type string |
|
139 |
:value-type function) |
|
140 |
:documentation |
|
141 |
" An alist of (DISPLAY . FUNCTION) pairs, a variable name or a function. |
|
142 |
FUNCTION is called with one parameter: the selected candidate. |
|
143 |
|
|
144 |
An action other than the default can be chosen from this list |
|
145 |
of actions for the currently selected candidate (by default |
|
146 |
with TAB). The DISPLAY string is shown in the completions |
|
147 |
buffer and the FUNCTION is invoked when an action is |
|
148 |
selected. The first action of the list is the default. |
|
149 |
|
|
150 |
You should use `helm-make-actions' to build this alist easily.") |
|
151 |
|
|
152 |
(persistent-action |
|
153 |
:initarg :persistent-action |
|
154 |
:initform nil |
|
155 |
:custom function |
|
156 |
:documentation |
|
157 |
" Can be a either a Function called with one parameter (the |
|
158 |
selected candidate) or a cons cell where first element is this |
|
159 |
same function and second element a symbol (e.g never-split) |
|
160 |
that inform `helm-execute-persistent-action' to not split his |
|
161 |
window to execute this persistent action. |
|
162 |
Example: |
|
163 |
|
|
164 |
(defun foo-persistent-action (candidate) |
|
165 |
(do-something candidate)) |
|
166 |
|
|
167 |
:persistent-action '(foo-persistent-action . never-split) ; Don't split |
|
168 |
or |
|
169 |
:persistent-action 'foo-persistent-action ; Split |
|
170 |
|
|
171 |
When specifying :persistent-action by slot directly, foo-persistent-action |
|
172 |
will be executed without quitting helm when hitting `C-j'. |
|
173 |
|
|
174 |
Note that other persistent actions can be defined using other |
|
175 |
bindings than `C-j' by simply defining an interactive function bound |
|
176 |
to a key in the keymap source. |
|
177 |
The function should create a new attribute in source before calling |
|
178 |
`helm-execute-persistent-action' on this attribute. |
|
179 |
Example: |
|
180 |
|
|
181 |
(defun helm-ff-persistent-delete () |
|
182 |
\"Delete current candidate without quitting.\" |
|
183 |
(interactive) |
|
184 |
(with-helm-alive-p |
|
185 |
(helm-attrset 'quick-delete '(helm-ff-quick-delete . never-split)) |
|
186 |
(helm-execute-persistent-action 'quick-delete))) |
|
187 |
|
|
188 |
This function is then bound in `helm-find-files-map'.") |
|
189 |
|
|
190 |
(persistent-action-if |
|
191 |
:initarg :persistent-action-if |
|
192 |
:initform nil |
|
193 |
:custom function |
|
194 |
:documentation |
|
195 |
" Similar from persistent action but it is a function that should |
|
196 |
return an object suitable for persistent action when called , i.e. a |
|
197 |
function or a cons cell. |
|
198 |
Example: |
|
199 |
|
|
200 |
(defun foo-persistent-action (candidate) |
|
201 |
(cond (something |
|
202 |
;; Don't split helm-window. |
|
203 |
(cons (lambda (_ignore) |
|
204 |
(do-something candidate)) |
|
205 |
'no-split)) |
|
206 |
;; Split helm-window. |
|
207 |
(something-else |
|
208 |
(lambda (_ignore) |
|
209 |
(do-something-else candidate))))) |
|
210 |
|
|
211 |
:persistent-action-if 'foo-persistent-action |
|
212 |
|
|
213 |
Here when hitting `C-j' one of the lambda's will be executed |
|
214 |
depending on something or something-else condition, splitting or not |
|
215 |
splitting as needed. |
|
216 |
See `helm-find-files-persistent-action-if' definition as another example.") |
|
217 |
|
|
218 |
(persistent-help |
|
219 |
:initarg :persistent-help |
|
220 |
:initform nil |
|
221 |
:custom string |
|
222 |
:documentation |
|
223 |
" A string to explain persistent-action of this source. It also |
|
224 |
accepts a function or a variable name. |
|
225 |
It will be displayed in `header-line' or in `minibuffer' depending |
|
226 |
of value of `helm-echo-input-in-header-line' and `helm-display-header-line'.") |
|
227 |
|
|
228 |
(help-message |
|
229 |
:initarg :help-message |
|
230 |
:initform nil |
|
231 |
:custom (choice string function) |
|
232 |
:documentation |
|
233 |
" Help message for this source. |
|
234 |
If not present, `helm-help-message' value will be used.") |
|
235 |
|
|
236 |
(multiline |
|
237 |
:initarg :multiline |
|
238 |
:initform nil |
|
239 |
:custom (choice boolean integer) |
|
240 |
:documentation |
|
241 |
" Allow multiline candidates. |
|
242 |
When non-nil candidates will be separated by `helm-candidate-separator'. |
|
243 |
You can customize the color of this separator with `helm-separator' face. |
|
244 |
Value of multiline can be an integer which specify the maximum size of the |
|
245 |
multiline string to display, if multiline string is longer than this value |
|
246 |
it will be truncated.") |
|
247 |
|
|
248 |
(requires-pattern |
|
249 |
:initarg :requires-pattern |
|
250 |
:initform nil |
|
251 |
:custom integer |
|
252 |
:documentation |
|
253 |
" If present matches from the source are shown only if the |
|
254 |
pattern is not empty. Optionally, it can have an integer |
|
255 |
parameter specifying the required length of input which is |
|
256 |
useful in case of sources with lots of candidates.") |
|
257 |
|
|
258 |
(candidate-transformer |
|
259 |
:initarg :candidate-transformer |
|
260 |
:initform nil |
|
261 |
:custom (choice function list) |
|
262 |
:documentation |
|
263 |
" It's a function or a list of functions called with one argument |
|
264 |
when the completion list from the source is built. The argument |
|
265 |
is the list of candidates retrieved from the source. The |
|
266 |
function should return a transformed list of candidates which |
|
267 |
will be used for the actual completion. If it is a list of |
|
268 |
functions, it calls each function sequentially. |
|
269 |
|
|
270 |
This can be used to transform or remove items from the list of |
|
271 |
candidates. |
|
272 |
|
|
273 |
Note that `candidates' is run already, so the given transformer |
|
274 |
function should also be able to handle candidates with (DISPLAY |
|
275 |
. REAL) format.") |
|
276 |
|
|
277 |
(filtered-candidate-transformer |
|
278 |
:initarg :filtered-candidate-transformer |
|
279 |
:initform nil |
|
280 |
:custom (choice function list) |
|
281 |
:documentation |
|
282 |
" It has the same format as `candidate-transformer', except the |
|
283 |
function is called with two parameters: the candidate list and |
|
284 |
the source. |
|
285 |
|
|
286 |
This transformer is run on the candidate list which is already |
|
287 |
filtered by the current pattern. While `candidate-transformer' |
|
288 |
is run only once, it is run every time the input pattern is |
|
289 |
changed. |
|
290 |
|
|
291 |
It can be used to transform the candidate list dynamically, for |
|
292 |
example, based on the current pattern. |
|
293 |
|
|
294 |
In some cases it may also be more efficent to perform candidate |
|
295 |
transformation here, instead of with `candidate-transformer' |
|
296 |
even if this transformation is done every time the pattern is |
|
297 |
changed. For example, if a candidate set is very large then |
|
298 |
`candidate-transformer' transforms every candidate while only |
|
299 |
some of them will actually be displayed due to the limit |
|
300 |
imposed by `helm-candidate-number-limit'. |
|
301 |
|
|
302 |
Note that `candidates' and `candidate-transformer' is run |
|
303 |
already, so the given transformer function should also be able |
|
304 |
to handle candidates with (DISPLAY . REAL) format.") |
|
305 |
|
|
306 |
(filter-one-by-one |
|
307 |
:initarg :filter-one-by-one |
|
308 |
:initform nil |
|
309 |
:custom (choice function list) |
|
310 |
:documentation |
|
311 |
" A transformer function that treat candidates one by one. |
|
312 |
It is called with one arg the candidate. |
|
313 |
It is faster than `filtered-candidate-transformer' or |
|
314 |
`candidate-transformer', but should be used only in sources |
|
315 |
that recompute constantly their candidates, e.g `helm-source-find-files'. |
|
316 |
Filtering happen early and candidates are treated |
|
317 |
one by one instead of re-looping on the whole list. |
|
318 |
If used with `filtered-candidate-transformer' or `candidate-transformer' |
|
319 |
these functions should treat the candidates transformed by the |
|
320 |
`filter-one-by-one' function in consequence.") |
|
321 |
|
|
322 |
(display-to-real |
|
323 |
:initarg :display-to-real |
|
324 |
:initform nil |
|
325 |
:custom function |
|
326 |
:documentation |
|
327 |
" Transform the selected candidate when passing it to action. |
|
328 |
|
|
329 |
Function called with one parameter, the selected candidate. |
|
330 |
|
|
331 |
Avoid recomputing all candidates with candidate-transformer |
|
332 |
or filtered-candidate-transformer to give a new value to REAL, |
|
333 |
instead the selected candidate is transformed only when passing it |
|
334 |
to action. |
|
335 |
|
|
336 |
Note that this is NOT a transformer, |
|
337 |
so the display will not be modified by this function.") |
|
338 |
|
|
339 |
(real-to-display |
|
340 |
:initarg :real-to-display |
|
341 |
:initform nil |
|
342 |
:custom function |
|
343 |
:documentation |
|
344 |
" Recompute all candidates computed previously with other transformers. |
|
345 |
|
|
346 |
Function called with one parameter, the selected candidate. |
|
347 |
|
|
348 |
The real value of candidates will be shown in display. |
|
349 |
Note: This have nothing to do with display-to-real. |
|
350 |
It is unuseful as the same can be performed by using more than |
|
351 |
one function in transformers, it is kept only for backward compatibility.") |
|
352 |
|
|
353 |
(marked-with-props |
|
354 |
:initarg :marked-with-props |
|
355 |
:initform nil |
|
356 |
:custom (choice boolean symbol) |
|
357 |
:documentation |
|
358 |
" Get candidates with their properties in `helm-marked-candidates'. |
|
359 |
Allow using the FORCE-DISPLAY-PART of `helm-get-selection' in marked |
|
360 |
candidates, use t or 'withprop to pass it to `helm-get-selection'.") |
|
361 |
|
|
362 |
(action-transformer |
|
363 |
:initarg :action-transformer |
|
364 |
:initform nil |
|
365 |
:custom (choice function list) |
|
366 |
:documentation |
|
367 |
" It's a function or a list of functions called with two |
|
368 |
arguments when the action list from the source is |
|
369 |
assembled. The first argument is the list of actions, the |
|
370 |
second is the current selection. If it is a list of functions, |
|
371 |
it calls each function sequentially. |
|
372 |
|
|
373 |
The function should return a transformed action list. |
|
374 |
|
|
375 |
This can be used to customize the list of actions based on the |
|
376 |
currently selected candidate.") |
|
377 |
|
|
378 |
(pattern-transformer |
|
379 |
:initarg :pattern-transformer |
|
380 |
:initform nil |
|
381 |
:custom (choice function list) |
|
382 |
:documentation |
|
383 |
" It's a function or a list of functions called with one argument |
|
384 |
before computing matches. Its argument is `helm-pattern'. |
|
385 |
Functions should return transformed `helm-pattern'. |
|
386 |
|
|
387 |
It is useful to change interpretation of `helm-pattern'.") |
|
388 |
|
|
389 |
(candidate-number-limit |
|
390 |
:initarg :candidate-number-limit |
|
391 |
:initform nil |
|
392 |
:custom integer |
|
393 |
:documentation |
|
394 |
" Override `helm-candidate-number-limit' only for this source.") |
|
395 |
|
|
396 |
(volatile |
|
397 |
:initarg :volatile |
|
398 |
:initform nil |
|
399 |
:custom boolean |
|
400 |
:documentation |
|
401 |
" Indicates the source assembles the candidate list dynamically, |
|
402 |
so it shouldn't be cached within a single Helm |
|
403 |
invocation. It is only applicable to synchronous sources, |
|
404 |
because asynchronous sources are not cached.") |
|
405 |
|
|
406 |
(match |
|
407 |
:initarg :match |
|
408 |
:initform nil |
|
409 |
:custom (choice function list) |
|
410 |
:documentation |
|
411 |
" List of functions called with one parameter: a candidate. The |
|
412 |
function should return non-nil if the candidate matches the |
|
413 |
current pattern (see variable `helm-pattern'). |
|
414 |
|
|
415 |
When using `candidates-in-buffer' its default value is `identity' and |
|
416 |
don't have to be changed, use the `search' slot instead. |
|
417 |
|
|
418 |
This attribute allows the source to override the default |
|
419 |
pattern matching based on `string-match'. It can be used, for |
|
420 |
example, to implement a source for file names and do the |
|
421 |
pattern matching on the basename of files, since it's more |
|
422 |
likely one is typing part of the basename when searching for a |
|
423 |
file, instead of some string anywhere else in its path. |
|
424 |
|
|
425 |
If the list contains more than one function then the list of |
|
426 |
matching candidates from the source is constructed by appending |
|
427 |
the results after invoking the first function on all the |
|
428 |
potential candidates, then the next function, and so on. The |
|
429 |
matching candidates supplied by the first function appear first |
|
430 |
in the list of results and then results from the other |
|
431 |
functions, respectively. |
|
432 |
|
|
433 |
This attribute has no effect for asynchronous sources (see |
|
434 |
attribute `candidates'), since they perform pattern matching |
|
435 |
themselves. |
|
436 |
|
|
437 |
Note that FUZZY-MATCH slot will overhide value of this slot.") |
|
438 |
|
|
439 |
(fuzzy-match |
|
440 |
:initarg :fuzzy-match |
|
441 |
:initform nil |
|
442 |
:custom boolean |
|
443 |
:documentation |
|
444 |
" Enable fuzzy matching in this source. |
|
445 |
This will overwrite settings in MATCH slot, and for |
|
446 |
sources built with child class `helm-source-in-buffer' the SEARCH slot. |
|
447 |
This is an easy way of enabling fuzzy matching, but you can use the MATCH |
|
448 |
or SEARCH slots yourself if you want something more elaborated, mixing |
|
449 |
different type of match (See `helm-source-buffers' class for example). |
|
450 |
|
|
451 |
This attribute is not supported for asynchronous sources |
|
452 |
since they perform pattern matching themselves.") |
|
453 |
|
|
454 |
(redisplay |
|
455 |
:initarg :redisplay |
|
456 |
:initform 'identity |
|
457 |
:custom (choice list function) |
|
458 |
:documentation |
|
459 |
" A function or a list of functions to apply to current list |
|
460 |
of candidates when redisplaying buffer with `helm-redisplay-buffer'. |
|
461 |
This is only interesting for modifying and redisplaying the whole list |
|
462 |
of candidates in async sources. |
|
463 |
It uses `identity' by default for when async sources are mixed with |
|
464 |
normal sources, in this case these normal sources are not modified and |
|
465 |
redisplayed as they are.") |
|
466 |
|
|
467 |
(nomark |
|
468 |
:initarg :nomark |
|
469 |
:initform nil |
|
470 |
:custom boolean |
|
471 |
:documentation |
|
472 |
" Don't allow marking candidates when this attribute is present.") |
|
473 |
|
|
474 |
(nohighlight |
|
475 |
:initarg :nohighlight |
|
476 |
:initform nil |
|
477 |
:custom boolean |
|
478 |
:documentation |
|
479 |
" Disable highlighting matches in this source. |
|
480 |
This will disable generic highlighting of matches, |
|
481 |
but some specialized highlighting can be done from elsewhere, |
|
482 |
i.e from `filtered-candidate-transformer' or `filter-one-by-one' slots. |
|
483 |
So use this to either disable completely highlighting in your source, |
|
484 |
or to disable highlighting and use a specialized highlighting matches |
|
485 |
function for this source. |
|
486 |
Remember that this function should run AFTER all filter functions if those |
|
487 |
filter functions are modifying face properties, though it is possible to |
|
488 |
avoid this by using new `add-face-text-property' in your filter functions.") |
|
489 |
|
|
490 |
(allow-dups |
|
491 |
:initarg :allow-dups |
|
492 |
:initform nil |
|
493 |
:custom boolean |
|
494 |
:documentation |
|
495 |
" Allow helm collecting duplicates candidates.") |
|
496 |
|
|
497 |
(history |
|
498 |
:initarg :history |
|
499 |
:initform nil |
|
500 |
:custom symbol |
|
501 |
:documentation |
|
502 |
" Allow passing history variable to helm from source. |
|
503 |
It should be a quoted symbol. |
|
504 |
Passing the history variable here have no effect |
|
505 |
so add it also in the `helm' call with the :history keyword. |
|
506 |
The main point of adding the variable here |
|
507 |
is to make it available when resuming.") |
|
508 |
|
|
509 |
(coerce |
|
510 |
:initarg :coerce |
|
511 |
:initform nil |
|
512 |
:custom function |
|
513 |
:documentation |
|
514 |
" It's a function called with one argument: the selected candidate. |
|
515 |
This function is intended for type convertion. In normal case, |
|
516 |
the selected candidate (string) is passed to action |
|
517 |
function. If coerce function is specified, it is called just |
|
518 |
before action function. |
|
519 |
|
|
520 |
Example: converting string to symbol |
|
521 |
(coerce . intern)") |
|
522 |
|
|
523 |
(mode-line |
|
524 |
:initarg :mode-line |
|
525 |
:initform nil |
|
526 |
:custom (choice string sexp) |
|
527 |
:documentation |
|
528 |
" Source local `helm-mode-line-string' (included in |
|
529 |
`mode-line-format'). It accepts also variable/function name.") |
|
530 |
|
|
531 |
(header-line |
|
532 |
:initarg :header-line |
|
533 |
:initform nil |
|
534 |
:custom (choice string function) |
|
535 |
:documentation |
|
536 |
" Source local `header-line-format'. |
|
537 |
It will be displayed in `header-line' or in `minibuffer' depending |
|
538 |
of value of `helm-echo-input-in-header-line' and `helm-display-header-line'. |
|
539 |
It accepts also variable/function name.") |
|
540 |
|
|
541 |
(resume |
|
542 |
:initarg :resume |
|
543 |
:initform nil |
|
544 |
:custom function |
|
545 |
:documentation |
|
546 |
" Function called with no parameters at end of initialization |
|
547 |
when `helm-resume' is started. |
|
548 |
If this function try to do something against `helm-buffer', \(e.g updating, |
|
549 |
searching etc...\) probably you should run it in a timer to ensure |
|
550 |
`helm-buffer' is ready.") |
|
551 |
|
|
552 |
(follow |
|
553 |
:initarg :follow |
|
554 |
:initform nil |
|
555 |
:custom integer |
|
556 |
:documentation |
|
557 |
" Enable `helm-follow-mode' for this source only. |
|
558 |
With a value of 1 enable, a value of -1 or nil disable the mode. |
|
559 |
See `helm-follow-mode' for more infos.") |
|
560 |
|
|
561 |
(follow-delay |
|
562 |
:initarg :follow-delay |
|
563 |
:initform nil |
|
564 |
:custom integer |
|
565 |
:documentation |
|
566 |
" `helm-follow-mode' will execute persistent-action after this delay. |
|
567 |
Otherwise value of `helm-follow-input-idle-delay' is used if non--nil, |
|
568 |
If none of these are found fallback to `helm-input-idle-delay'.") |
|
569 |
|
|
570 |
(multimatch |
|
571 |
:initarg :multimatch |
|
572 |
:initform t |
|
573 |
:custom boolean |
|
574 |
:documentation |
|
575 |
" Use the multi-match algorithm when non-nil. |
|
576 |
I.e Allow specifying multiple patterns separated by spaces. |
|
577 |
When a pattern is prefixed by \"!\" the negation of this pattern is used, |
|
578 |
i.e match anything but this pattern. |
|
579 |
It is the standard way of matching in helm and is enabled by default. |
|
580 |
It can be used with fuzzy-matching enabled, but as soon helm detect a space, |
|
581 |
each pattern will match by regexp and will not be fuzzy.") |
|
582 |
|
|
583 |
(match-part |
|
584 |
:initarg :match-part |
|
585 |
:initform nil |
|
586 |
:custom function |
|
587 |
:documentation |
|
588 |
" Allow matching only one part of candidate. |
|
589 |
If source contain match-part attribute, match is computed only |
|
590 |
on part of candidate returned by the call of function provided |
|
591 |
by this attribute. The function should have one arg, candidate, |
|
592 |
and return only a specific part of candidate. |
|
593 |
On async sources, as matching is done by the backend, this have |
|
594 |
no effect apart for highlighting matches.") |
|
595 |
|
|
596 |
(before-init-hook |
|
597 |
:initarg :before-init-hook |
|
598 |
:initform nil |
|
599 |
:custom symbol |
|
600 |
:documentation |
|
601 |
" A local hook that run at beginning of initilization of this source. |
|
602 |
i.e Before the creation of `helm-buffer'. |
|
603 |
|
|
604 |
Should be a variable (defined with defvar). |
|
605 |
Can be also an anonymous function or a list of functions |
|
606 |
directly added to slot, this is not recommended though.") |
|
607 |
|
|
608 |
(after-init-hook |
|
609 |
:initarg :after-init-hook |
|
610 |
:initform nil |
|
611 |
:custom symbol |
|
612 |
:documentation |
|
613 |
" A local hook that run at end of initilization of this source. |
|
614 |
i.e After the creation of `helm-buffer'. |
|
615 |
|
|
616 |
Should be a variable. |
|
617 |
Can be also an anonymous function or a list of functions |
|
618 |
directly added to slot, this is not recommended though.") |
|
619 |
|
|
620 |
(delayed |
|
621 |
:initarg :delayed |
|
622 |
:initform nil |
|
623 |
:custom (choice null integer) |
|
624 |
:documentation |
|
625 |
" This slot have no more effect and is just kept for backward compatibility. |
|
626 |
Please don't use it.") |
|
627 |
|
|
628 |
(group |
|
629 |
:initarg :group |
|
630 |
:initform helm |
|
631 |
:custom symbol |
|
632 |
:documentation |
|
633 |
" The current source group, default to `helm' when not specified.")) |
|
634 |
|
|
635 |
"Main interface to define helm sources." |
|
636 |
:abstract t) |
|
637 |
|
|
638 |
(defclass helm-source-sync (helm-source) |
|
639 |
((candidates |
|
640 |
:initform '("ERROR: You must specify the `candidates' slot, either with a list or a function")) |
|
641 |
|
|
642 |
(migemo |
|
643 |
:initarg :migemo |
|
644 |
:initform nil |
|
645 |
:custom boolean |
|
646 |
:documentation |
|
647 |
" Enable migemo. |
|
648 |
When multimatch is disabled, you can give the symbol 'nomultimatch as value |
|
649 |
to force not using generic migemo matching function. |
|
650 |
In this case you have to provide your own migemo matching funtion |
|
651 |
that kick in when `helm-migemo-mode' is enabled. |
|
652 |
Otherwise it will be available for this source once `helm-migemo-mode' |
|
653 |
is enabled when non-nil.") |
|
654 |
|
|
655 |
(match-strict |
|
656 |
:initarg :match-strict |
|
657 |
:initform nil |
|
658 |
:custom function |
|
659 |
:documentation |
|
660 |
" When specifying a match function within a source and |
|
661 |
helm-multi-match is enabled, the result of all matching |
|
662 |
functions will be concatened, which in some cases is not what |
|
663 |
is wanted. When using `match-strict' only this or these |
|
664 |
functions will be used. You can specify those functions as a |
|
665 |
list of functions or a single symbol function. |
|
666 |
|
|
667 |
NOTE: This have the same effect as using :MULTIMATCH nil.")) |
|
668 |
|
|
669 |
"Use this class to make helm sources using a list of candidates. |
|
670 |
This list should be given as a normal list, a variable handling a list |
|
671 |
or a function returning a list. |
|
672 |
Matching is done basically with `string-match' against each candidate.") |
|
673 |
|
|
674 |
(defclass helm-source-async (helm-source) |
|
675 |
((candidates-process |
|
676 |
:initarg :candidates-process |
|
677 |
:initform nil |
|
678 |
:custom function |
|
679 |
:documentation |
|
680 |
" This attribute is used to define a process as candidate. |
|
681 |
The value must be a process. |
|
682 |
|
|
683 |
NOTE: |
|
684 |
When building the source at runtime you can give directly a process |
|
685 |
as value, otherwise wrap the process call into a function. |
|
686 |
The process buffer should be nil, otherwise, if you use |
|
687 |
`helm-buffer' give to the process a sentinel.") |
|
688 |
|
|
689 |
(multimatch :initform nil)) |
|
690 |
|
|
691 |
"Use this class to define a helm source calling an external process. |
|
692 |
The :candidates slot is not allowed even if described because this class |
|
693 |
inherit from `helm-source'.") |
|
694 |
|
|
695 |
(defclass helm-source-in-buffer (helm-source) |
|
696 |
((init |
|
697 |
:initform 'helm-default-init-source-in-buffer-function) |
|
698 |
|
|
699 |
(data |
|
700 |
:initarg :data |
|
701 |
:initform nil |
|
702 |
:custom (choice list string) |
|
703 |
:documentation |
|
704 |
" A string, a list or a buffer that will be used to feed the `helm-candidates-buffer'. |
|
705 |
This data will be passed in a function added to the init slot and |
|
706 |
the buffer will be build with `helm-init-candidates-in-buffer' or directly |
|
707 |
with `helm-candidates-buffer' if data is a buffer. |
|
708 |
This is an easy and fast method to build a `candidates-in-buffer' source.") |
|
709 |
|
|
710 |
(migemo |
|
711 |
:initarg :migemo |
|
712 |
:initform nil |
|
713 |
:custom boolean |
|
714 |
:documentation |
|
715 |
" Enable migemo. |
|
716 |
When multimatch is disabled, you can give the symbol 'nomultimatch as value |
|
717 |
to force not using generic migemo matching function. |
|
718 |
In this case you have to provide your own migemo matching funtion |
|
719 |
that kick in when `helm-migemo-mode' is enabled. |
|
720 |
Otherwise it will be available for this source once `helm-migemo-mode' |
|
721 |
is enabled when non-nil.") |
|
722 |
|
|
723 |
(candidates |
|
724 |
:initform 'helm-candidates-in-buffer) |
|
725 |
|
|
726 |
(volatile |
|
727 |
:initform t) |
|
728 |
|
|
729 |
(match |
|
730 |
:initform '(identity)) |
|
731 |
|
|
732 |
(get-line |
|
733 |
:initarg :get-line |
|
734 |
:initform 'buffer-substring-no-properties |
|
735 |
:custom function |
|
736 |
:documentation |
|
737 |
" A function like `buffer-substring-no-properties' or `buffer-substring'. |
|
738 |
This function converts region from point at line-beginning and point |
|
739 |
at line-end in the `helm-candidate-buffer' to a string which will be displayed |
|
740 |
in the `helm-buffer', it takes two args BEG and END. |
|
741 |
By default, `helm-candidates-in-buffer' uses |
|
742 |
`buffer-substring-no-properties' which does no conversion and doesn't carry |
|
743 |
text properties.") |
|
744 |
|
|
745 |
(search |
|
746 |
:initarg :search |
|
747 |
:initform '(helm-candidates-in-buffer-search-default-fn) |
|
748 |
:custom (choice function list) |
|
749 |
:documentation |
|
750 |
" List of functions like `re-search-forward' or `search-forward'. |
|
751 |
Buffer search function used by `helm-candidates-in-buffer'. |
|
752 |
By default, `helm-candidates-in-buffer' uses `re-search-forward'. |
|
753 |
The function should take one arg PATTERN. |
|
754 |
If your search function needs to handle negation like multimatch, |
|
755 |
this function should returns in such case a cons cell of two integers defining |
|
756 |
the beg and end positions to match in the line previously matched by |
|
757 |
`re-search-forward' or similar, and move point to next line |
|
758 |
(See how the `helm-mm-3-search-base' and `helm-fuzzy-search' functions are working). |
|
759 |
|
|
760 |
NOTE: FUZZY-MATCH slot will overhide value of this slot.") |
|
761 |
|
|
762 |
(search-strict |
|
763 |
:initarg :search-strict |
|
764 |
:initform nil |
|
765 |
:custom function |
|
766 |
:documentation |
|
767 |
" When specifying a search function within a source and |
|
768 |
helm-multi-match is enabled, the result of all searching |
|
769 |
functions will be concatened, which in some cases is not what |
|
770 |
is wanted. When using `search-strict' only this or these |
|
771 |
functions will be used. You can specify those functions as a |
|
772 |
list of functions or a single symbol function. |
|
773 |
|
|
774 |
NOTE: This have the same effect as using a nil value for |
|
775 |
:MULTIMATCH slot.")) |
|
776 |
|
|
777 |
"Use this source to make helm sources storing candidates inside a buffer. |
|
778 |
|
|
779 |
The buffer storing candidates is generated by `helm-candidate-buffer' function |
|
780 |
and all search are done in this buffer, results are transfered to the `helm-buffer' |
|
781 |
when done. |
|
782 |
Contrarily to `helm-source-sync' candidates are matched using a function |
|
783 |
like `re-search-forward' (see below documentation of `:search' slot) which makes |
|
784 |
the search much faster than matching candidates one by one. |
|
785 |
If you want to add search functions to your sources, don't use `:match' which |
|
786 |
will raise an error, but `:search'. |
|
787 |
See `helm-candidates-in-buffer' for more infos.") |
|
788 |
|
|
789 |
(defclass helm-source-dummy (helm-source) |
|
790 |
((candidates |
|
791 |
:initform '("dummy")) |
|
792 |
|
|
793 |
(filtered-candidate-transformer |
|
794 |
:initform (lambda (_candidates _source) (list helm-pattern))) |
|
795 |
|
|
796 |
(multimatch |
|
797 |
:initform nil) |
|
798 |
|
|
799 |
(accept-empty |
|
800 |
:initarg :accept-empty |
|
801 |
:initform t |
|
802 |
:custom boolean |
|
803 |
:documentation |
|
804 |
" Allow exiting with an empty string. |
|
805 |
You should keep the default value.") |
|
806 |
|
|
807 |
(match |
|
808 |
:initform 'identity) |
|
809 |
|
|
810 |
(volatile |
|
811 |
:initform t))) |
|
812 |
|
|
813 |
(defclass helm-source-in-file (helm-source-in-buffer) |
|
814 |
((init :initform (lambda () |
|
815 |
(let ((file (helm-attr 'candidates-file)) |
|
816 |
(count 1)) |
|
817 |
(with-current-buffer (helm-candidate-buffer 'global) |
|
818 |
(insert-file-contents file) |
|
819 |
(goto-char (point-min)) |
|
820 |
(while (not (eobp)) |
|
821 |
(add-text-properties |
|
822 |
(point-at-bol) (point-at-eol) |
|
823 |
`(helm-linum ,count)) |
|
824 |
(cl-incf count) |
|
825 |
(forward-line 1)))))) |
|
826 |
(get-line :initform #'buffer-substring) |
|
827 |
(candidates-file |
|
828 |
:initarg :candidates-file |
|
829 |
:initform nil |
|
830 |
:custom string |
|
831 |
:documentation |
|
832 |
" A filename. |
|
833 |
Each line number of FILE is accessible with helm-linum property |
|
834 |
from candidate display part.")) |
|
835 |
|
|
836 |
"The contents of the FILE will be used as candidates in buffer.") |
|
837 |
|
|
838 |
|
|
839 |
;;; Error functions |
|
840 |
;; |
|
841 |
;; |
|
842 |
(defun helm-default-init-source-in-buffer-function () |
|
843 |
(helm-init-candidates-in-buffer 'global |
|
844 |
'("ERROR: No buffer handling your data, use either the `init' slot or the `data' slot."))) |
|
845 |
|
|
846 |
|
|
847 |
;;; Internal Builder functions. |
|
848 |
;; |
|
849 |
;; |
|
850 |
(defun helm--create-source (object) |
|
851 |
"[INTERNAL] Build a helm source from OBJECT. |
|
852 |
Where OBJECT is an instance of an eieio class." |
|
853 |
(cl-loop for s in (object-slots object) |
|
854 |
for slot-val = (slot-value object s) |
|
855 |
when slot-val |
|
856 |
collect (cons s (unless (eq t slot-val) slot-val)))) |
|
857 |
|
|
858 |
(defun helm-make-source (name class &rest args) |
|
859 |
"Build a `helm' source named NAME with ARGS for CLASS. |
|
860 |
Argument NAME is a string which define the source name, so no need to use |
|
861 |
the keyword :name in your source, NAME will be used instead. |
|
862 |
Argument CLASS is an eieio class object. |
|
863 |
Arguments ARGS are keyword value pairs as defined in CLASS." |
|
864 |
(declare (indent 2)) |
|
865 |
(let ((source (apply #'make-instance class name args))) |
|
866 |
(setf (slot-value source 'name) name) |
|
867 |
(helm--setup-source source) |
|
868 |
(helm-setup-user-source source) |
|
869 |
(helm--create-source source))) |
|
870 |
|
|
871 |
(defun helm-make-type (class &rest args) |
|
872 |
(let ((source (apply #'make-instance class args))) |
|
873 |
(setf (slot-value source 'name) nil) |
|
874 |
(helm--setup-source source) |
|
875 |
(helm--create-source source))) |
|
876 |
|
|
877 |
(defvar helm-mm-default-search-functions) |
|
878 |
(defvar helm-mm-default-match-functions) |
|
879 |
|
|
880 |
(defun helm-source-mm-get-search-or-match-fns (source method) |
|
881 |
(let ((defmatch (helm-aif (slot-value source 'match) |
|
882 |
(helm-mklist it))) |
|
883 |
(defmatch-strict (helm-aif (and (eq method 'match) |
|
884 |
(slot-value source 'match-strict)) |
|
885 |
(helm-mklist it))) |
|
886 |
(defsearch (helm-aif (and (eq method 'search) |
|
887 |
(slot-value source 'search)) |
|
888 |
(helm-mklist it))) |
|
889 |
(defsearch-strict (helm-aif (and (eq method 'search-strict) |
|
890 |
(slot-value source 'search-strict)) |
|
891 |
(helm-mklist it))) |
|
892 |
(migemo (slot-value source 'migemo))) |
|
893 |
(cl-case method |
|
894 |
(match (cond (defmatch-strict) |
|
895 |
(migemo |
|
896 |
(append helm-mm-default-match-functions |
|
897 |
defmatch '(helm-mm-3-migemo-match))) |
|
898 |
(defmatch |
|
899 |
(append helm-mm-default-match-functions defmatch)) |
|
900 |
(t helm-mm-default-match-functions))) |
|
901 |
(search (cond (defsearch-strict) |
|
902 |
(migemo |
|
903 |
(append helm-mm-default-search-functions |
|
904 |
defsearch '(helm-mm-3-migemo-search))) |
|
905 |
(defsearch |
|
906 |
(append helm-mm-default-search-functions defsearch)) |
|
907 |
(t helm-mm-default-search-functions)))))) |
|
908 |
|
|
909 |
|
|
910 |
;;; Modifiers |
|
911 |
;; |
|
912 |
(cl-defun helm-source-add-action-to-source-if (name fn source predicate |
|
913 |
&optional (index 4)) |
|
914 |
"Same as `helm-add-action-to-source-if' but for SOURCE defined as eieio object. |
|
915 |
You can use this inside a `helm--setup-source' method for a SOURCE defined as |
|
916 |
an eieio class." |
|
917 |
(let* ((actions (slot-value source 'action)) |
|
918 |
(action-transformers (slot-value source 'action-transformer)) |
|
919 |
(new-action (list (cons name fn))) |
|
920 |
(transformer (lambda (actions candidate) |
|
921 |
(cond ((funcall predicate candidate) |
|
922 |
(helm-append-at-nth |
|
923 |
actions new-action index)) |
|
924 |
(t actions))))) |
|
925 |
(cond ((functionp actions) |
|
926 |
(setf (slot-value source 'action) (list (cons "Default action" actions)))) |
|
927 |
((listp actions) |
|
928 |
(setf (slot-value source 'action) (helm-interpret-value actions source)))) |
|
929 |
(when (or (symbolp action-transformers) (functionp action-transformers)) |
|
930 |
(setq action-transformers (list action-transformers))) |
|
931 |
(setf (slot-value source 'action-transformer) |
|
932 |
(delq nil (append (list transformer) action-transformers))))) |
|
933 |
|
|
934 |
|
|
935 |
;;; Methods to build sources. |
|
936 |
;; |
|
937 |
;; |
|
938 |
(defun helm-source--persistent-help-string (string source) |
|
939 |
(substitute-command-keys |
|
940 |
(concat "\\<helm-map>\\[helm-execute-persistent-action]: " |
|
941 |
(or (format "%s (keeping session)" string) |
|
942 |
(slot-value source 'header-line))))) |
|
943 |
|
|
944 |
(defun helm-source--header-line (source) |
|
945 |
(substitute-command-keys |
|
946 |
(concat "\\<helm-map>\\[helm-execute-persistent-action]: " |
|
947 |
(helm-aif (or (slot-value source 'persistent-action) |
|
948 |
(slot-value source 'action)) |
|
949 |
(cond ((and (symbolp it) |
|
950 |
(functionp it) |
|
951 |
(eq it 'identity)) |
|
952 |
"Do Nothing") |
|
953 |
((and (symbolp it) |
|
954 |
(boundp it) |
|
955 |
(listp (symbol-value it)) |
|
956 |
(stringp (caar (symbol-value it)))) |
|
957 |
(caar (symbol-value it))) |
|
958 |
((or (symbolp it) (functionp it)) |
|
959 |
(helm-symbol-name it)) |
|
960 |
((listp it) |
|
961 |
(let ((action (car it))) |
|
962 |
;; It comes from :action ("foo" . function). |
|
963 |
(if (stringp (car action)) |
|
964 |
(car action) |
|
965 |
;; It comes from :persistent-action |
|
966 |
;; (function . 'nosplit) Fix Issue #788. |
|
967 |
(if (or (symbolp action) |
|
968 |
(functionp action)) |
|
969 |
(helm-symbol-name action))))) |
|
970 |
(t "")) |
|
971 |
"") |
|
972 |
" (keeping session)"))) |
|
973 |
|
|
974 |
(defmethod helm--setup-source :primary ((_source helm-source))) |
|
975 |
|
|
976 |
(defmethod helm--setup-source :before ((source helm-source)) |
|
977 |
(when (slot-value source 'delayed) |
|
978 |
(warn "Deprecated usage of helm `delayed' slot in `%s'" |
|
979 |
(slot-value source 'name))) |
|
980 |
(helm-aif (slot-value source 'keymap) |
|
981 |
(and (symbolp it) (setf (slot-value source 'keymap) (symbol-value it)))) |
|
982 |
(helm-aif (slot-value source 'persistent-help) |
|
983 |
(setf (slot-value source 'header-line) |
|
984 |
(helm-source--persistent-help-string it source)) |
|
985 |
(setf (slot-value source 'header-line) (helm-source--header-line source))) |
|
986 |
(when (and (slot-value source 'fuzzy-match) helm-fuzzy-sort-fn) |
|
987 |
(setf (slot-value source 'filtered-candidate-transformer) |
|
988 |
(helm-aif (slot-value source 'filtered-candidate-transformer) |
|
989 |
(append (helm-mklist it) |
|
990 |
(list helm-fuzzy-sort-fn)) |
|
991 |
(list helm-fuzzy-sort-fn)))) |
|
992 |
(unless (slot-value source 'nohighlight) |
|
993 |
(setf (slot-value source 'filtered-candidate-transformer) |
|
994 |
(helm-aif (slot-value source 'filtered-candidate-transformer) |
|
995 |
(append (helm-mklist it) |
|
996 |
(list #'helm-fuzzy-highlight-matches)) |
|
997 |
(list #'helm-fuzzy-highlight-matches)))) |
|
998 |
(when (numberp (helm-interpret-value (slot-value source 'multiline))) |
|
999 |
(setf (slot-value source 'filtered-candidate-transformer) |
|
1000 |
(helm-aif (slot-value source 'filtered-candidate-transformer) |
|
1001 |
(append (helm-mklist it) |
|
1002 |
(list #'helm-multiline-transformer)) |
|
1003 |
(list #'helm-multiline-transformer))))) |
|
1004 |
|
|
1005 |
(defmethod helm-setup-user-source ((_source helm-source))) |
|
1006 |
|
|
1007 |
(defmethod helm--setup-source ((source helm-source-sync)) |
|
1008 |
(when (slot-value source 'fuzzy-match) |
|
1009 |
(helm-aif (slot-value source 'match) |
|
1010 |
(setf (slot-value source 'match) |
|
1011 |
(append (helm-mklist it) |
|
1012 |
(list helm-fuzzy-match-fn))) |
|
1013 |
(setf (slot-value source 'match) helm-fuzzy-match-fn))) |
|
1014 |
(when (slot-value source 'multimatch) |
|
1015 |
(setf (slot-value source 'match) |
|
1016 |
(helm-source-mm-get-search-or-match-fns source 'match))) |
|
1017 |
(helm-aif (and (null (slot-value source 'multimatch)) |
|
1018 |
(slot-value source 'migemo)) |
|
1019 |
(unless (eq it 'nomultimatch) ; Use own migemo fn. |
|
1020 |
(setf (slot-value source 'match) |
|
1021 |
(append (helm-mklist (slot-value source 'match)) |
|
1022 |
'(helm-mm-3-migemo-match)))))) |
|
1023 |
|
|
1024 |
(defmethod helm--setup-source ((source helm-source-in-buffer)) |
|
1025 |
(let ((cur-init (slot-value source 'init))) |
|
1026 |
(helm-aif (slot-value source 'data) |
|
1027 |
(setf (slot-value source 'init) |
|
1028 |
(delq |
|
1029 |
nil |
|
1030 |
(list |
|
1031 |
(and (null (eq 'helm-default-init-source-in-buffer-function |
|
1032 |
cur-init)) |
|
1033 |
cur-init) |
|
1034 |
(lambda () |
|
1035 |
(helm-init-candidates-in-buffer |
|
1036 |
'global |
|
1037 |
(cond ((functionp it) (funcall it)) |
|
1038 |
((and (bufferp it) (buffer-live-p it)) |
|
1039 |
(with-current-buffer it (buffer-string))) |
|
1040 |
(t it))))))))) |
|
1041 |
(when (slot-value source 'fuzzy-match) |
|
1042 |
(helm-aif (slot-value source 'search) |
|
1043 |
(setf (slot-value source 'search) |
|
1044 |
(append (helm-mklist it) |
|
1045 |
(list helm-fuzzy-search-fn))) |
|
1046 |
(setf (slot-value source 'search) (list helm-fuzzy-search-fn)))) |
|
1047 |
(when (slot-value source 'multimatch) |
|
1048 |
(setf (slot-value source 'search) |
|
1049 |
(helm-source-mm-get-search-or-match-fns source 'search))) |
|
1050 |
(helm-aif (and (null (slot-value source 'multimatch)) |
|
1051 |
(slot-value source 'migemo)) |
|
1052 |
(unless (eq it 'nomultimatch) |
|
1053 |
(setf (slot-value source 'search) |
|
1054 |
(append (helm-mklist (slot-value source 'search)) |
|
1055 |
'(helm-mm-3-migemo-search))))) |
|
1056 |
(let ((mtc (slot-value source 'match))) |
|
1057 |
(cl-assert (or (equal '(identity) mtc) |
|
1058 |
(eq 'identity mtc)) |
|
1059 |
nil "Invalid slot value for `match'") |
|
1060 |
(cl-assert (eq (slot-value source 'volatile) t) |
|
1061 |
nil "Invalid slot value for `volatile'"))) |
|
1062 |
|
|
1063 |
(defmethod helm--setup-source ((source helm-source-async)) |
|
1064 |
(cl-assert (null (slot-value source 'candidates)) |
|
1065 |
nil "Incorrect use of `candidates' use `candidates-process' instead") |
|
1066 |
(cl-assert (null (slot-value source 'multimatch)) |
|
1067 |
nil "`multimatch' not allowed in async sources.") |
|
1068 |
(cl-assert (null (slot-value source 'fuzzy-match)) |
|
1069 |
nil "`fuzzy-match' not supported in async sources.")) |
|
1070 |
|
|
1071 |
(defmethod helm--setup-source ((source helm-source-dummy)) |
|
1072 |
(let ((mtc (slot-value source 'match))) |
|
1073 |
(cl-assert (or (equal '(identity) mtc) |
|
1074 |
(eq 'identity mtc)) |
|
1075 |
nil "Invalid slot value for `match'") |
|
1076 |
(cl-assert (eq (slot-value source 'volatile) t) |
|
1077 |
nil "Invalid slot value for `volatile'") |
|
1078 |
(cl-assert (equal (slot-value source 'candidates) '("dummy")) |
|
1079 |
nil "Invalid slot value for `candidates'") |
|
1080 |
(cl-assert (eq (slot-value source 'accept-empty) t) |
|
1081 |
nil "Invalid slot value for `accept-empty'"))) |
|
1082 |
|
|
1083 |
|
|
1084 |
;;; User functions |
|
1085 |
;; |
|
1086 |
;; Sources |
|
1087 |
(defmacro helm-build-sync-source (name &rest args) |
|
1088 |
"Build a synchronous helm source with name NAME. |
|
1089 |
Args ARGS are keywords provided by `helm-source-sync'." |
|
1090 |
(declare (indent 1)) |
|
1091 |
`(helm-make-source ,name 'helm-source-sync ,@args)) |
|
1092 |
|
|
1093 |
(defmacro helm-build-async-source (name &rest args) |
|
1094 |
"Build a asynchronous helm source with name NAME. |
|
1095 |
Args ARGS are keywords provided by `helm-source-async'." |
|
1096 |
(declare (indent 1)) |
|
1097 |
`(helm-make-source ,name 'helm-source-async ,@args)) |
|
1098 |
|
|
1099 |
(defmacro helm-build-in-buffer-source (name &rest args) |
|
1100 |
"Build a helm source with name NAME using `candidates-in-buffer' method. |
|
1101 |
Args ARGS are keywords provided by `helm-source-in-buffer'." |
|
1102 |
(declare (indent 1)) |
|
1103 |
`(helm-make-source ,name 'helm-source-in-buffer ,@args)) |
|
1104 |
|
|
1105 |
(defmacro helm-build-dummy-source (name &rest args) |
|
1106 |
"Build a helm source with name NAME using `dummy' method. |
|
1107 |
Args ARGS are keywords provided by `helm-source-dummy'." |
|
1108 |
(declare (indent 1)) |
|
1109 |
`(helm-make-source ,name 'helm-source-dummy ,@args)) |
|
1110 |
|
|
1111 |
(defmacro helm-build-in-file-source (name file &rest args) |
|
1112 |
"Build a helm source with NAME name using `candidates-in-files' method. |
|
1113 |
Arg FILE is a filename, the contents of this file will be |
|
1114 |
used as candidates in buffer. |
|
1115 |
Args ARGS are keywords provided by `helm-source-in-file'." |
|
1116 |
(declare (indent 1)) |
|
1117 |
`(helm-make-source ,name 'helm-source-in-file |
|
1118 |
:candidates-file ,file ,@args)) |
|
1119 |
|
|
1120 |
|
|
1121 |
(provide 'helm-source) |
|
1122 |
|
|
1123 |
;; Local Variables: |
|
1124 |
;; byte-compile-warnings: (not obsolete) |
|
1125 |
;; coding: utf-8 |
|
1126 |
;; indent-tabs-mode: nil |
|
1127 |
;; End: |
|
1128 |
|
|
1129 |
;;; helm-source ends here |