1 ;;; anything-match-plugin.el --- Multiple regexp matching methods for anything
3 ;; Author: rubikitch <rubikitch@ruby-lang.org>
5 ;; Maintainers: rubikitch <rubikitch@ruby-lang.org>
6 ;; Thierry Volpiatto <thierry.volpiatto@gmail.com>
8 ;; Copyright (C) 2008~2012, rubikitch, all rights reserved.
9 ;; Copyright (C) 2011~2012, Thierry Volpiatto, all rights reserved.
11 ;; Keywords: anything, matching
12 ;; X-URL: <http://repo.or.cz/w/anything-config.git>
14 ;; This file 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 2, or (at your option)
19 ;; This file 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.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with GNU Emacs; see the file COPYING. If not, write to
26 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 ;; Boston, MA 02110-1301, USA.
29 ;;; Auto documentation
33 ;; [EVAL] (autodoc-document-lisp-buffer :type 'user-variable :prefix "anything-mp" :var-value t)
34 ;; `anything-mp-matching-method'
35 ;; Default Value: multi3
36 ;; `anything-mp-highlight-delay'
38 ;; `anything-mp-highlight-threshold'
41 ;; * Internal variables
42 ;; [EVAL] (autodoc-document-lisp-buffer :type 'internal-variable :prefix "anything-mp" :var-value t)
43 ;; `anything-mp-default-match-functions'
44 ;; Default Value: (anything-mp-exact-match anything-mp-3-match)
45 ;; `anything-mp-default-search-functions'
46 ;; Default Value: (anything-mp-exact-search anything-mp-3-search)
47 ;; `anything-mp-default-search-backward-functions'
48 ;; Default Value: (anything-mp-exact-search-backward anything-mp-3-search-backward)
49 ;; `anything-mp-space-regexp'
50 ;; Default Value: "[\\ ] "
51 ;; `anything-mp-exact-pattern-str'
52 ;; Default Value: "autod"
53 ;; `anything-mp-exact-pattern-real'
54 ;; Default Value: "\nautod\n"
55 ;; `anything-mp-prefix-pattern-str'
57 ;; `anything-mp-prefix-pattern-real'
59 ;; `anything-mp-1-pattern-str'
61 ;; `anything-mp-1-pattern-real'
63 ;; `anything-mp-2-pattern-str'
65 ;; `anything-mp-2-pattern-real'
67 ;; `anything-mp-3-pattern-str'
68 ;; Default Value: "autod"
69 ;; `anything-mp-3-pattern-list'
70 ;; Default Value: ((identity . "autod"))
71 ;; `anything-mp-initial-highlight-delay'
74 ;; * Anything match plugin Functions
75 ;; [EVAL] (autodoc-document-lisp-buffer :type 'function :prefix "anything-mp")
76 ;; `anything-mp-set-matching-method'
77 ;; `anything-mp-make-regexps'
78 ;; `anything-mp-1-make-regexp'
79 ;; `anything-mp-exact-get-pattern'
80 ;; `anything-mp-exact-match'
81 ;; `anything-mp-exact-search'
82 ;; `anything-mp-exact-search-backward'
83 ;; `anything-mp-prefix-get-pattern'
84 ;; `anything-mp-prefix-match'
85 ;; `anything-mp-prefix-search'
86 ;; `anything-mp-prefix-search-backward'
87 ;; `anything-mp-1-get-pattern'
88 ;; `anything-mp-1-match'
89 ;; `anything-mp-1-search'
90 ;; `anything-mp-1-search-backward'
91 ;; `anything-mp-2-get-pattern'
92 ;; `anything-mp-2-match'
93 ;; `anything-mp-2-search'
94 ;; `anything-mp-2-search-backward'
95 ;; `anything-mp-3-get-patterns'
96 ;; `anything-mp-3-get-patterns-internal'
97 ;; `anything-mp-3-match'
98 ;; `anything-mp-3-search-base'
99 ;; `anything-mp-3-search'
100 ;; `anything-mp-3-search-backward'
101 ;; `anything-mp-3p-match'
102 ;; `anything-mp-3p-search'
103 ;; `anything-mp-3p-search-backward'
104 ;; `anything-mp-highlight-match'
105 ;; `anything-mp-highlight-region'
106 ;; `anything-mp-highlight-match-internal'
108 ;; *** END auto-documentation
112 ;; Change anything.el matching algorithm humanely.
113 ;; It gives anything.el search refinement functionality.
114 ;; exact match -> prefix match -> multiple regexp match
118 ;; Below are complete command list:
120 ;; `anything-mp-toggle-match-plugin'
121 ;; Turn on/off multiple regexp matching in anything.
123 ;;; Customizable Options:
125 ;; Below are customizable option list:
127 ;; `anything-mp-matching-method'
128 ;; Matching method for anything match plugin.
129 ;; default = (quote multi3)
130 ;; `anything-mp-highlight-delay'
131 ;; Highlight matches with `anything-match' face after this many seconds.
133 ;; `anything-mp-highlight-threshold'
134 ;; Minimum length of pattern to highlight.
136 ;; `anything-grep-candidates-fast-directory-regexp'
137 ;; *Directory regexp where a RAM disk (or tmpfs) is mounted.
139 ;; `anything-grep-candidates-requires-pattern'
140 ;; *Required length of input to grep search.
143 ;; A query of multiple regexp match is space-delimited string.
144 ;; Anything displays candidates which matches all the regexps.
145 ;; A regexp with "!" prefix means not matching the regexp.
146 ;; To include spaces to a regexp, prefix "\" before space,
147 ;; it is controlled by `anything-mp-space-regexp' variable.
149 ;; If multiple regexps are specified, first one also tries to match the source name.
150 ;; If you want to disable this feature, evaluate
151 ;; (setq anything-mp-match-source-name nil) .
152 ;; NOTE: This is obsolete and disabled in anything versions >= 1.3.7
154 ;; This file highlights patterns like `occur'. Note that patterns
155 ;; longer than `anything-mp-highlight-threshold' are highlighted. And
156 ;; region out of screen is highlighted after
157 ;; `anything-mp-highlight-delay' seconds.
159 ;; Highlight in Emacs is time-consuming process for slow computers. To
160 ;; disable it is to set nil to `anything-mp-highlight-delay'.
162 ;; anything-match-plugin is enable by default in anything.
163 ;; To disable/enable it use M-x anything-c-toggle-match-plugin.
174 (defvar anything-mp-default-match-functions nil
)
175 (defvar anything-mp-default-search-functions nil
)
176 (defvar anything-mp-default-search-backward-functions nil
)
178 (defun anything-mp-set-matching-method (var key
)
179 "Default function to set matching methods in anything match plugin."
180 (set-default var key
)
181 (case (symbol-value var
)
182 (multi1 (setq anything-mp-default-match-functions
183 '(anything-mp-exact-match anything-mp-1-match
)
184 anything-mp-default-search-functions
185 '(anything-mp-exact-search anything-mp-1-search
)
186 anything-mp-default-search-backward-functions
187 '(anything-mp-exact-search-backward
188 anything-mp-1-search-backward
)))
189 (multi2 (setq anything-mp-default-match-functions
190 '(anything-mp-exact-match anything-mp-2-match
)
191 anything-mp-default-search-functions
192 '(anything-mp-exact-search anything-mp-2-search
)
193 anything-mp-default-search-backward-functions
194 '(anything-mp-exact-search-backward
195 anything-mp-2-search-backward
)))
196 (multi3 (setq anything-mp-default-match-functions
197 '(anything-mp-exact-match anything-mp-3-match
)
198 anything-mp-default-search-functions
199 '(anything-mp-exact-search anything-mp-3-search
)
200 anything-mp-default-search-backward-functions
201 '(anything-mp-exact-search-backward
202 anything-mp-3-search-backward
)))
203 (multi3p (setq anything-mp-default-match-functions
204 '(anything-mp-exact-match anything-mp-3p-match
)
205 anything-mp-default-search-functions
206 '(anything-mp-exact-search anything-mp-3p-search
)
207 anything-mp-default-search-backward-functions
208 '(anything-mp-exact-search-backward
209 anything-mp-3p-search-backward
)))
210 (t (error "Unknow value: %s" anything-mp-matching-method
))))
212 (defgroup anything-match-plugin nil
213 "Anything match plugin."
216 (defcustom anything-mp-matching-method
'multi3
217 "Matching method for anything match plugin.
218 You can set here different methods to match candidates in anything.
219 Here are the possible value of this symbol and their meaning:
220 - multi1: Respect order, prefix of pattern must match.
221 - multi2: Same but with partial match.
222 - multi3: The best, multiple regexp match, allow negation.
223 - multi3p: Same but prefix must match.
225 :type
'(radio :tag
"Matching methods for anything"
226 (const :tag
"Multiple regexp 1 ordered with prefix match" multi1
)
227 (const :tag
"Multiple regexp 2 ordered with partial match" multi2
)
228 (const :tag
"Multiple regexp 3 matching no order, partial, best." multi3
)
229 (const :tag
"Multiple regexp 3p matching with prefix match" multi3p
))
230 :set
'anything-mp-set-matching-method
231 :group
'anything-match-plugin
)
233 (defface anything-match
234 '((t (:inherit match
)))
235 "Face used to highlight matches."
236 :group
'anything-match-plugin
)
238 (defcustom anything-mp-highlight-delay
0.7
239 "Highlight matches with `anything-match' face after this many seconds.
240 If nil, no highlight. "
242 :group
'anything-match-plugin
)
244 (defcustom anything-mp-highlight-threshold
2
245 "Minimum length of pattern to highlight.
246 The smaller this value is, the slower highlight is."
248 :group
'anything-match-plugin
)
255 (defvar anything-mp-space-regexp
"[\\ ] "
256 "Regexp to represent space itself in multiple regexp match.")
258 (defun anything-mp-make-regexps (pattern)
259 "Split PATTERN if it contain spaces and return resulting list.
260 If spaces in PATTERN are escaped, don't split at this place.
261 i.e \"foo bar\"=> (\"foo\" \"bar\")
262 but \"foo\ bar\"=> (\"foobar\")."
263 (if (string= pattern
"")
265 (loop for s in
(split-string
266 (replace-regexp-in-string anything-mp-space-regexp
269 collect
(replace-regexp-in-string "\000\000" " " s
))))
271 (defun anything-mp-1-make-regexp (pattern)
272 "Replace spaces in PATTERN with \"\.*\"."
273 (mapconcat 'identity
(anything-mp-make-regexps pattern
) ".*"))
280 (defvar anything-mp-exact-pattern-str nil
)
281 (defvar anything-mp-exact-pattern-real nil
)
283 (defun anything-mp-exact-get-pattern (pattern)
284 (unless (equal pattern anything-mp-exact-pattern-str
)
285 (setq anything-mp-exact-pattern-str pattern
286 anything-mp-exact-pattern-real
(concat "\n" pattern
"\n")))
287 anything-mp-exact-pattern-real
)
290 (defun anything-mp-exact-match (str &optional pattern
)
291 (string= str
(or pattern anything-pattern
)))
293 (defun anything-mp-exact-search (pattern &rest ignore
)
294 (and (search-forward (anything-mp-exact-get-pattern pattern
) nil t
)
297 (defun anything-mp-exact-search-backward (pattern &rest ignore
)
298 (and (search-backward (anything-mp-exact-get-pattern pattern
) nil t
)
306 (defvar anything-mp-prefix-pattern-str nil
)
307 (defvar anything-mp-prefix-pattern-real nil
)
309 (defun anything-mp-prefix-get-pattern (pattern)
310 (unless (equal pattern anything-mp-prefix-pattern-str
)
311 (setq anything-mp-prefix-pattern-str pattern
312 anything-mp-prefix-pattern-real
(concat "\n" pattern
)))
313 anything-mp-prefix-pattern-real
)
315 (defun anything-mp-prefix-match (str &optional pattern
)
316 (setq pattern
(or pattern anything-pattern
))
317 (let ((len (length pattern
)))
318 (and (<= len
(length str
))
319 (string= (substring str
0 len
) pattern
))))
321 (defun anything-mp-prefix-search (pattern &rest ignore
)
322 (search-forward (anything-mp-prefix-get-pattern pattern
) nil t
))
324 (defun anything-mp-prefix-search-backward (pattern &rest ignore
)
325 (and (search-backward (anything-mp-prefix-get-pattern pattern
) nil t
)
329 ;;; Multiple regexp patterns 1 (order is preserved / prefix).
333 (defvar anything-mp-1-pattern-str nil
)
334 (defvar anything-mp-1-pattern-real nil
)
336 (defun anything-mp-1-get-pattern (pattern)
337 (unless (equal pattern anything-mp-1-pattern-str
)
338 (setq anything-mp-1-pattern-str pattern
339 anything-mp-1-pattern-real
340 (concat "^" (anything-mp-1-make-regexp pattern
))))
341 anything-mp-1-pattern-real
)
343 (defun* anything-mp-1-match
(str &optional
(pattern anything-pattern
))
344 (string-match (anything-mp-1-get-pattern pattern
) str
))
346 (defun anything-mp-1-search (pattern &rest ignore
)
347 (re-search-forward (anything-mp-1-get-pattern pattern
) nil t
))
349 (defun anything-mp-1-search-backward (pattern &rest ignore
)
350 (re-search-backward (anything-mp-1-get-pattern pattern
) nil t
))
353 ;;; Multiple regexp patterns 2 (order is preserved / partial).
357 (defvar anything-mp-2-pattern-str nil
)
358 (defvar anything-mp-2-pattern-real nil
)
360 (defun anything-mp-2-get-pattern (pattern)
361 (unless (equal pattern anything-mp-2-pattern-str
)
362 (setq anything-mp-2-pattern-str pattern
363 anything-mp-2-pattern-real
364 (concat "^.*" (anything-mp-1-make-regexp pattern
))))
365 anything-mp-2-pattern-real
)
367 (defun* anything-mp-2-match
(str &optional
(pattern anything-pattern
))
368 (string-match (anything-mp-2-get-pattern pattern
) str
))
370 (defun anything-mp-2-search (pattern &rest ignore
)
371 (re-search-forward (anything-mp-2-get-pattern pattern
) nil t
))
373 (defun anything-mp-2-search-backward (pattern &rest ignore
)
374 (re-search-backward (anything-mp-2-get-pattern pattern
) nil t
))
377 ;;; Multiple regexp patterns 3 (permutation).
381 (defvar anything-mp-3-pattern-str nil
)
382 (defvar anything-mp-3-pattern-list nil
)
384 (defun anything-mp-3-get-patterns (pattern)
385 "Return `anything-mp-3-pattern-list', a list of predicate/regexp cons cells.
386 e.g ((identity . \"foo\") (identity . \"bar\")).
387 This is done only if `anything-mp-3-pattern-str' is same as PATTERN."
388 (unless (equal pattern anything-mp-3-pattern-str
)
389 (setq anything-mp-3-pattern-str pattern
390 anything-mp-3-pattern-list
391 (anything-mp-3-get-patterns-internal pattern
)))
392 anything-mp-3-pattern-list
)
394 (defun anything-mp-3-get-patterns-internal (pattern)
395 "Return a list of predicate/regexp cons cells.
396 e.g ((identity . \"foo\") (identity . \"bar\"))."
397 (unless (string= pattern
"")
398 (if (string-match "^!" pattern
)
399 (anything-mp-3-get-patterns-internal (concat ". " pattern
))
400 (loop for pat in
(anything-mp-make-regexps pattern
)
401 collect
(if (string= "!" (substring pat
0 1))
402 (cons 'not
(substring pat
1))
403 (cons 'identity pat
))))))
405 (defun anything-mp-3-match (str &optional pattern
)
406 "Check if PATTERN match STR.
407 When PATTERN contain a space, it is splitted and matching is done
408 with the several resulting regexps against STR.
409 e.g \"bar foo\" will match \"foobar\" and \"barfoo\".
410 Argument PATTERN, a string, is transformed in a list of
411 cons cell with `anything-mp-3-get-patterns' if it contain a space.
412 e.g \"foo bar\"=>((identity . \"foo\") (identity . \"bar\")).
413 Then each predicate of cons cell(s) is called with regexp of same
414 cons cell against STR (a candidate).
415 i.e (identity (string-match \"foo\" \"foo bar\")) => t."
416 (let ((pat (anything-mp-3-get-patterns (or pattern anything-pattern
))))
417 (loop for
(predicate . regexp
) in pat
418 always
(funcall predicate
(string-match regexp str
)))))
420 (defun anything-mp-3-search-base (pattern searchfn1 searchfn2
)
421 (loop with pat
= (if (stringp pattern
)
422 (anything-mp-3-get-patterns pattern
)
424 while
(funcall searchfn1
(or (cdar pat
) "") nil t
)
425 for bol
= (point-at-bol)
426 for eol
= (point-at-eol)
427 for
(b . e
) = (if (eq searchfn2
're-search-backward
)
430 if
(loop for
(pred . str
) in
(cdr pat
) always
432 (funcall pred
(funcall searchfn2 str e t
))))
433 do
(goto-char e
) and return t
434 else do
(goto-char e
)
437 (defun anything-mp-3-search (pattern &rest ignore
)
438 (when (stringp pattern
)
439 (setq pattern
(anything-mp-3-get-patterns pattern
)))
440 (anything-mp-3-search-base
441 pattern
're-search-forward
're-search-forward
))
443 (defun anything-mp-3-search-backward (pattern &rest ignore
)
444 (when (stringp pattern
)
445 (setq pattern
(anything-mp-3-get-patterns pattern
)))
446 (anything-mp-3-search-base
447 pattern
're-search-backward
're-search-backward
))
450 ;;; mp-3p- (multiple regexp pattern 3 with prefix search)
453 (defun anything-mp-3p-match (str &optional pattern
)
454 "Check if PATTERN match STR.
455 Same as `anything-mp-3-match' but more strict, matching against prefix also.
456 e.g \"bar foo\" will match \"barfoo\" but not \"foobar\" contrarily to
457 `anything-mp-3-match'."
458 (let* ((pat (anything-mp-3-get-patterns (or pattern anything-pattern
)))
460 (and (funcall (car first
) (anything-mp-prefix-match str
(cdr first
)))
461 (loop for
(predicate . regexp
) in
(cdr pat
)
462 always
(funcall predicate
(string-match regexp str
))))))
464 (defun anything-mp-3p-search (pattern &rest ignore
)
465 (when (stringp pattern
)
466 (setq pattern
(anything-mp-3-get-patterns pattern
)))
467 (anything-mp-3-search-base
468 pattern
'anything-mp-prefix-search
're-search-forward
))
470 (defun anything-mp-3p-search-backward (pattern &rest ignore
)
471 (when (stringp pattern
)
472 (setq pattern
(anything-mp-3-get-patterns pattern
)))
473 (anything-mp-3-search-base
474 pattern
'anything-mp-prefix-search-backward
're-search-backward
))
480 (defun anything-compile-source--match-plugin (source)
481 (let ((searchers (if (assoc 'search-from-end source
)
482 anything-mp-default-search-backward-functions
483 anything-mp-default-search-functions
)))
484 `(,(if (or (assoc 'candidates-in-buffer source
)
485 (equal '(identity) (assoc-default 'match source
)))
487 `(match ,@anything-mp-default-match-functions
488 ,@(assoc-default 'match source
)))
490 ,@(assoc-default 'search source
))
492 (add-to-list 'anything-compile-source-functions
'anything-compile-source--match-plugin t
)
495 ;;; Highlight matches.
498 (defun anything-mp-highlight-match ()
499 "Highlight matches after `anything-mp-highlight-delay' seconds."
500 (when (and anything-mp-highlight-delay
501 (not (string= anything-pattern
"")))
502 (anything-mp-highlight-match-internal (window-end (anything-window)))
503 (run-with-idle-timer anything-mp-highlight-delay nil
504 'anything-mp-highlight-match-internal
505 (with-current-buffer anything-buffer
(point-max)))))
506 (add-hook 'anything-update-hook
'anything-mp-highlight-match
)
508 (defun anything-mp-highlight-region (start end regexp face
)
512 (while (and (setq me
(re-search-forward regexp nil t
))
514 (< 0 (- (match-end 0) (match-beginning 0))))
515 (unless (anything-pos-header-line-p)
516 (put-text-property (match-beginning 0) me
'face face
))))))
518 (defun anything-mp-highlight-match-internal (end)
519 (when (anything-window)
520 (set-buffer anything-buffer
)
521 (let ((requote (loop for
(pred . re
) in
522 (anything-mp-3-get-patterns anything-pattern
)
523 when
(and (eq pred
'identity
)
525 anything-mp-highlight-threshold
))
526 collect re into re-list
528 (if (and re-list
(>= (length re-list
) 1))
529 (mapconcat 'identity re-list
"\\|")
530 (regexp-quote anything-pattern
)))))
531 (when (>= (length requote
) anything-mp-highlight-threshold
)
532 (anything-mp-highlight-region
533 (point-min) end requote
'anything-match
)))))
536 ;;; Toggle anything-match-plugin
539 (defvar anything-mp-initial-highlight-delay nil
)
542 (defun anything-mp-toggle-match-plugin ()
543 "Turn on/off multiple regexp matching in anything.
544 i.e anything-match-plugin."
546 (let ((anything-match-plugin-enabled
547 (member 'anything-compile-source--match-plugin
548 anything-compile-source-functions
)))
549 (flet ((disable-match-plugin ()
550 (setq anything-compile-source-functions
551 (delq 'anything-compile-source--match-plugin
552 anything-compile-source-functions
))
553 (setq anything-mp-initial-highlight-delay
554 anything-mp-highlight-delay
)
555 (setq anything-mp-highlight-delay nil
))
556 (enable-match-plugin ()
557 (unless anything-mp-initial-highlight-delay
558 (setq anything-mp-initial-highlight-delay
559 anything-mp-highlight-delay
))
560 (setq anything-compile-source-functions
561 (cons 'anything-compile-source--match-plugin
562 anything-compile-source-functions
))
563 (unless anything-mp-highlight-delay
564 (setq anything-mp-highlight-delay
565 anything-mp-initial-highlight-delay
))))
566 (if anything-match-plugin-enabled
567 (when (y-or-n-p "Really disable match-plugin? ")
568 (disable-match-plugin)
569 (message "Anything-match-plugin disabled"))
570 (when (y-or-n-p "Really enable match-plugin? ")
571 (enable-match-plugin)
572 (message "Anything-match-plugin enabled"))))))
575 ;;;; Grep-candidates plug-in
577 (defcustom anything-grep-candidates-fast-directory-regexp nil
578 "*Directory regexp where a RAM disk (or tmpfs) is mounted.
580 If non-nil, grep-candidates plugin gets faster because it uses
581 grep as synchronous process.
583 ex. (setq anything-grep-candidates-fast-directory-regexp \"^/tmp/\")"
587 (defcustom anything-grep-candidates-requires-pattern
2
588 "*Required length of input to grep search.
590 The greater this value is, the faster grep-candidates works."
594 (defun agp-candidates (&optional filter
)
595 "Normal version of grep-candidates candidates function.
596 Grep is run by asynchronous process."
597 (start-process-shell-command
598 "anything-grep-candidates" nil
599 (agp-command-line-2 filter
(anything-attr-defined 'search-from-end
))))
601 (defun agp-candidates-synchronous-grep (&optional filter
)
602 "Faster version of grep-candidates candidates function.
603 Grep is run by synchronous process.
604 It is faster when candidate files are in ramdisk."
605 (let ((x (split-string
606 (shell-command-to-string
607 (agp-command-line-2 filter
(anything-attr-defined 'search-from-end
)))
609 (unless (equal x
'("")) x
)))
611 (defun agp-candidates-synchronous-grep--direct-insert-match (&optional filter
)
612 "[EXPERIMENTAL]Fastest version of grep-candidates candidates function at the cost of absense of transformers.
613 Grep is run by synchronous process.
614 It is faster when candidate files are in ramdisk.
616 If (direct-insert-match) is in the source, this function is used."
617 (with-current-buffer (anything-candidate-buffer 'global
)
618 (call-process-shell-command
619 (agp-command-line-2 filter
(anything-attr-defined 'search-from-end
))
622 (defun agp-command-line (query files
&optional limit filter search-from-end
)
623 "Build command line used by grep-candidates from QUERY, FILES, LIMIT, and FILTER."
624 (let ((allfiles (mapconcat (lambda (f) (shell-quote-argument (expand-file-name f
)))
627 (when search-from-end
628 (insert "tac " allfiles
))
629 (if (< (length query
) anything-grep-candidates-requires-pattern
)
630 (unless search-from-end
631 (insert "cat " allfiles
))
632 (when search-from-end
(insert " | "))
633 (loop with exist-ary
= (file-exists-p (concat (car files
) ".ary"))
634 for
(flag . re
) in
(anything-mp-3-get-patterns-internal query
)
637 (setq re
(replace-regexp-in-string "^-" "\\-" re
))
638 (unless (zerop i
) (insert " | "))
639 (if (and (not (cdr files
))
640 (not search-from-end
)
644 (insert "sary " (shell-quote-argument re
))
646 (if (eq flag
'identity
) "" "-v ")
647 (shell-quote-argument re
)))
648 (when (and (not search-from-end
) (zerop i
))
649 (insert " " allfiles
))))
651 (when limit
(insert (format " | head -n %d" limit
)))
652 (when filter
(insert " | " filter
))
655 (defun agp-command-line-2 (filter &optional search-from-end
)
656 "Build command line used by grep-candidates from FILTER and current source."
659 (anything-mklist (anything-interpret-value (anything-attr 'grep-candidates
)))
660 (anything-candidate-number-limit (anything-get-current-source))
661 filter search-from-end
))
663 (defun anything-compile-source--grep-candidates (source)
664 (anything-aif (assoc-default 'grep-candidates source
)
667 (let ((use-fast-directory
668 (and anything-grep-candidates-fast-directory-regexp
670 anything-grep-candidates-fast-directory-regexp
671 (or (car (anything-mklist (anything-interpret-value it
))) "")))))
672 (cond ((not (anything-interpret-value it
)) nil
)
673 ((and use-fast-directory
(assq 'direct-insert-match source
))
674 (anything-log "fastest version (use-fast-directory and direct-insert-match)")
675 `((candidates . agp-candidates-synchronous-grep--direct-insert-match
)
679 (anything-log "faster version (use-fast-directory)")
680 `((candidates . agp-candidates-synchronous-grep
)
684 (anything-log "normal version")
685 '((candidates . agp-candidates
)
688 (add-to-list 'anything-compile-source-functions
'anything-compile-source--grep-candidates
)
690 (anything-document-attribute 'grep-candidates
"grep-candidates plug-in"
691 "grep-candidates plug-in provides anything-match-plugin.el feature with grep and head program.
692 It is MUCH FASTER than normal match-plugin to search from vary large (> 1MB) candidates.
693 Make sure to install these programs.
695 It expands `candidates' and `delayed' attributes.
697 `grep-candidates' attribute accepts a filename or list of filename.
698 It also accepts 0-argument function name or variable name.")
700 ;; (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message))))
701 ;; (let ((a "~/.emacs.el")) (anything '(((name . "grep-test") (grep-candidates . a) (action . message) (delayed)))))
702 ;; (let ((a "~/.emacs.el")) (anything '(((name . "grep-test") (grep-candidates . (lambda () a)) (action . message) (delayed)))))
703 ;; (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed) (candidate-number-limit . 2))))
704 ;; (let ((anything-candidate-number-limit 2)) (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed)))))
707 ;; unit test for match plugin are now in developper-tools/unit-test-match-plugin.el
709 (provide 'anything-match-plugin
)
711 ;;; anything-match-plugin.el ends here