make-filelist.rb: Remove extra comment
[anything-config.git] / anything-match-plugin.el
blob11664b212b3bffe7e9d3c37415ccaf943589138a
1 ;;; anything-match-plugin.el --- Humane match plug-in for anything
2 ;; $Id: anything-match-plugin.el,v 1.27 2010-03-24 11:11:28 rubikitch Exp $
4 ;; Copyright (C) 2008 rubikitch
6 ;; Author: rubikitch <rubikitch@ruby-lang.org>
7 ;; Keywords: anything, matching
8 ;; URL: http://www.emacswiki.org/cgi-bin/wiki/download/anything-match-plugin.el
10 ;; This file is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
15 ;; This file is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
25 ;;; Commentary:
27 ;; Change anything.el matching algorithm humanely.
28 ;; It gives anything.el search refinement functionality.
29 ;; exact match -> prefix match -> multiple regexp match
31 ;;; Commands:
33 ;; Below are complete command list:
36 ;;; Customizable Options:
38 ;; Below are customizable option list:
40 ;; `anything-grep-candidates-fast-directory-regexp'
41 ;; *Directory regexp where a RAM disk (or tmpfs) is mounted.
42 ;; default = nil
44 ;; A query of multiple regexp match is space-delimited string.
45 ;; Anything displays candidates which matches all the regexps.
46 ;; A regexp with "!" prefix means not matching the regexp.
47 ;; To include spaces to a regexp, prefix "\" before space,
48 ;; it is controlled by `anything-mp-space-regexp' variable.
50 ;; If multiple regexps are specified, first one also tries to match the source name.
51 ;; If you want to disable this feature, evaluate
52 ;; (setq anything-mp-match-source-name nil) .
54 ;; This file highlights patterns like `occur'. Note that patterns
55 ;; longer than `anything-mp-highlight-threshold' are highlighted. And
56 ;; region out of screen is highlighted after
57 ;; `anything-mp-highlight-delay' seconds.
59 ;; Highlight in Emacs is time-consuming process for slow computers. To
60 ;; disable it is to set nil to `anything-mp-highlight-delay'.
62 ;; Just require it to use.
64 ;;; History:
66 ;; $Log: anything-match-plugin.el,v $
67 ;; Revision 1.27 2010-03-24 11:11:28 rubikitch
68 ;; Added :group keyword to `defface anything-match'
70 ;; Revision 1.26 2010/03/24 10:48:55 rubikitch
71 ;; grep-candidates plug-in: document / imply `delayed' attribute
73 ;; Revision 1.25 2010/03/24 10:38:48 rubikitch
74 ;; grep-candidates plugin: grep-candidates attribute can also accept variable/function name.
76 ;; Revision 1.24 2010/03/22 09:01:22 rubikitch
77 ;; grep-candidates plugin released
79 ;; Revision 1.23 2010/03/22 08:02:11 rubikitch
80 ;; grep-candidates plugin prototype
82 ;; Revision 1.22 2009/03/03 10:21:45 rubikitch
83 ;; * Remove highlight.el dependency.
84 ;; * Very faster highlight.
86 ;; Revision 1.21 2009/03/03 08:51:23 rubikitch
87 ;; New variable: `anything-mp-highlight-threshold'
89 ;; Revision 1.20 2009/03/03 07:29:24 rubikitch
90 ;; Highlight matches!
92 ;; Revision 1.19 2008/09/08 06:58:59 rubikitch
93 ;; changed default `anything-mp-space-regexp' to "[\\ ] "
95 ;; Revision 1.18 2008/09/07 12:09:01 rubikitch
96 ;; *** empty log message ***
98 ;; Revision 1.17 2008/09/07 07:48:12 rubikitch
99 ;; Append commentary.
100 ;; Multiple regexp match with regexp negation.
102 ;; Revision 1.16 2008/09/07 06:58:11 rubikitch
103 ;; Added mp-3p match: permutation with prefix match
105 ;; Revision 1.15 2008/09/07 05:23:07 rubikitch
106 ;; New variable: `anything-mp-space-regexp'
108 ;; Revision 1.14 2008/09/03 03:33:09 rubikitch
109 ;; anything-exact-*, anything-prefix-*: memoize
111 ;; Revision 1.13 2008/09/02 10:56:50 rubikitch
112 ;; anything-mp-3-*: MUCH MUCH FASTER
113 ;; changed algorithm
115 ;; Revision 1.12 2008/09/01 13:41:57 rubikitch
116 ;; search functions for search-from-end
118 ;; Revision 1.11 2008/08/24 20:40:27 rubikitch
119 ;; prevent the unit test from being byte-compiled.
121 ;; Revision 1.10 2008/08/24 17:48:53 rubikitch
122 ;; Add commentary
124 ;; Revision 1.9 2008/08/24 08:23:16 rubikitch
125 ;; Rename `anything-candidates-buffer' -> `anything-candidate-buffer'
127 ;; Revision 1.8 2008/08/22 21:25:44 rubikitch
128 ;; *** empty log message ***
130 ;; Revision 1.7 2008/08/22 21:17:58 rubikitch
131 ;; exact, prefix match: faster
133 ;; Revision 1.6 2008/08/22 19:40:22 rubikitch
134 ;; exact -> prefix -> mp-3 by default because of speed
136 ;; Revision 1.5 2008/08/22 19:04:53 rubikitch
137 ;; reimplemented
139 ;; Revision 1.4 2008/08/20 00:10:15 rubikitch
140 ;; *** empty log message ***
142 ;; Revision 1.3 2008/08/19 23:30:39 rubikitch
143 ;; exact match support
145 ;; Revision 1.2 2008/08/19 23:02:29 rubikitch
146 ;; candidates-in-buffer hack
148 ;; Revision 1.1 2008/08/19 19:45:11 rubikitch
149 ;; Initial revision
152 ;;; Code:
154 (require 'anything)
155 (require 'cl)
157 (let ((version "1.283"))
158 (when (and (string= "1." (substring version 0 2))
159 (string-match "1\.\\([0-9]+\\)" anything-version)
160 (< (string-to-number (match-string 1 anything-version))
161 (string-to-number (substring version 2))))
162 (error "Please update anything.el!!
164 http://www.emacswiki.org/cgi-bin/wiki/download/anything.el
166 or M-x install-elisp-from-emacswiki anything.el")))
168 (defcustom anything-grep-candidates-fast-directory-regexp nil
169 "*Directory regexp where a RAM disk (or tmpfs) is mounted.
171 If non-nil, grep-candidates plugin gets faster because it uses
172 grep as synchronous process.
174 ex. (setq anything-grep-candidates-fast-directory-regexp \"^/tmp/\")"
175 :type 'string
176 :group 'anything)
178 ;;;; multiple patterns
179 (defvar anything-use-multiple-patterns t
180 "If non-nil, enable anything-use-multiple-patterns.")
181 (defvar anything-mp-space-regexp "[\\ ] "
182 "Regexp to represent space itself in multiple regexp match.")
183 (defvar anything-mp-match-source-name t
184 "If non-nil, first query in space-delimited pattern try to match the source name.
185 It needs at least two queries.
186 For example, to list candidats of \"foo\" source, input pattern as \"foo .\".")
188 (defun amp-mp-make-regexps (pattern)
189 (if (string= pattern "") '("")
190 (loop for s in (split-string
191 (replace-regexp-in-string anything-mp-space-regexp
192 "\000\000" pattern) " " t)
193 collect (replace-regexp-in-string "\000\000" " " s))))
195 (defun amp-mp-1-make-regexp (pattern)
196 (mapconcat 'identity (amp-mp-make-regexps pattern) ".*"))
198 (defmacro amp-define-memoizer (prefix pattern-expr)
199 (let ((pattern-str (intern (concat prefix "pattern-str")))
200 (pattern-real (intern (concat prefix "pattern-real")))
201 (get-pattern (intern (concat prefix "get-pattern"))))
202 `(progn
203 (defvar ,pattern-str nil)
204 (defvar ,pattern-real nil)
205 (defsubst ,get-pattern (pattern)
206 (unless (equal pattern ,pattern-str)
207 (setq ,pattern-str pattern
208 ,pattern-real ,pattern-expr))
209 ,pattern-real))))
211 (defmacro amp-define (prefix pattern-expr)
212 (let ((get-pattern (intern (concat prefix "get-pattern")))
213 (match (intern (concat prefix "match")))
214 (search (intern (concat prefix "search")))
215 (search-backward (intern (concat prefix "search-backward"))))
216 `(progn
217 (amp-define-memoizer ,prefix ,pattern-expr)
218 (defun* ,match (str &optional (pattern anything-pattern))
219 (string-match (,get-pattern pattern) str))
220 (defun ,search (pattern &rest ignore)
221 (re-search-forward (,get-pattern pattern) nil t))
222 (defun ,search-backward (pattern &rest ignore)
223 (re-search-backward (,get-pattern pattern) nil t)))))
225 ;; exact match
226 ;(amp-define "anything-exact-" (concat (anything-prefix-get-pattern pattern) "$"))
227 (amp-define-memoizer "anything-exact-" (concat "\n" pattern "\n"))
228 (defun anything-exact-match (str &optional pattern)
229 (string= str (or pattern anything-pattern)))
230 (defun anything-exact-search (pattern &rest ignore)
231 (and (search-forward (anything-exact-get-pattern pattern) nil t)
232 (forward-line -1)))
233 (defun anything-exact-search-backward (pattern &rest ignore)
234 (and (search-backward (anything-exact-get-pattern pattern) nil t)
235 (forward-line 1)))
236 ;; prefix match
237 ;;(amp-define "anything-prefix-" (concat "^" (regexp-quote pattern)))
238 (amp-define-memoizer "anything-prefix-" (concat "\n" pattern))
239 (defun anything-prefix-match (str &optional pattern)
240 (setq pattern (or pattern anything-pattern))
241 (let ((len (length pattern)))
242 (and (<= len (length str))
243 (string= (substring str 0 len) pattern ))))
244 (defun anything-prefix-search (pattern &rest ignore)
245 (search-forward (anything-prefix-get-pattern pattern) nil t))
246 (defun anything-prefix-search-backward (pattern &rest ignore)
247 (and (search-backward (anything-prefix-get-pattern pattern) nil t)
248 (forward-line 1)))
249 ;; multiple regexp patterns 1 (order is preserved / prefix)
250 (amp-define "anything-mp-1-" (concat "^" (amp-mp-1-make-regexp pattern)))
251 ;; multiple regexp patterns 2 (order is preserved / partial)
252 (amp-define "anything-mp-2-" (concat "^.+" (amp-mp-1-make-regexp pattern)))
254 ;;;; multiple regexp patterns 3 (permutation)
255 (defvar anything-mp-3-pattern-str nil)
256 (defvar anything-mp-3-pattern-list nil)
257 (defsubst anything-mp-3-get-patterns (pattern)
258 (unless (equal pattern anything-mp-3-pattern-str)
259 (setq anything-mp-3-pattern-str pattern
260 anything-mp-3-pattern-list
261 (anything-mp-3-get-patterns-internal pattern)))
262 anything-mp-3-pattern-list)
263 (defun anything-mp-3-get-patterns-internal (pattern)
264 (loop for pat in (amp-mp-make-regexps pattern)
265 collect (if (string= "!" (substring pat 0 1))
266 (cons 'not (substring pat 1))
267 (cons 'identity pat))))
268 (defun anything-mp-handle-source-name-maybe (pattern self else)
269 (when (stringp pattern)
270 (setq pattern (anything-mp-3-get-patterns pattern)))
271 ;; PATTERN is list of (pred . re) now.
272 (when pattern
273 (destructuring-bind ((first-pred . first-re) . rest) pattern
274 (if (and anything-mp-match-source-name
275 (stringp anything-source-name)
276 (eq 'identity first-pred))
277 (let (anything-mp-match-source-name)
278 (or (and (string-match first-re anything-source-name)
279 (funcall self rest))
280 (funcall self pattern)))
281 (funcall else)))))
283 (defun* anything-mp-3-match (str &optional (pattern anything-pattern))
284 (anything-mp-handle-source-name-maybe
285 pattern (apply-partially 'anything-mp-3-match str)
286 (lambda ()
287 (loop for (pred . re) in pattern
288 always (funcall pred (string-match re str))))))
290 (defmacro anything-mp-3-search-base (searchfn1 searchfn2 b e)
291 `(loop with pat = (if (stringp pattern)
292 (anything-mp-3-get-patterns pattern)
293 pattern)
294 while (,searchfn1 (or (cdar pat) "") nil t)
295 for bol = (point-at-bol)
296 for eol = (point-at-eol)
297 if (loop
298 for (pred . s) in (cdr pat)
299 always (progn (goto-char ,b)
300 (funcall pred (,searchfn2 s ,e t))))
301 do (goto-char ,e) (return t)
302 else do
303 (goto-char ,e)
304 finally (return nil)))
306 (defun anything-mp-3-search (pattern &rest ignore)
307 (anything-mp-handle-source-name-maybe
308 pattern 'anything-mp-3-search
309 (lambda () (anything-mp-3-search-base
310 re-search-forward re-search-forward bol eol))))
311 (defun anything-mp-3-search-backward (pattern &rest ignore)
312 (anything-mp-handle-source-name-maybe
313 pattern 'anything-mp-3-search-backward
314 (lambda () (anything-mp-3-search-base
315 re-search-backward re-search-backward eol bol))))
316 ;; mp-3p- (multiple regexp pattern 3 with prefix search)
317 (defun* anything-mp-3p-match (str &optional (pattern anything-pattern))
318 (anything-mp-handle-source-name-maybe
319 pattern (apply-partially 'anything-mp-3p-match str)
320 (lambda ()
321 (declare (special first-pred first-re))
322 (and (funcall first-pred (anything-prefix-match str first-re))
323 (loop for (pred . re) in rest
324 always (funcall pred (string-match re str)))))))
326 (defun anything-mp-3p-search (pattern &rest ignore)
327 (anything-mp-handle-source-name-maybe
328 pattern 'anything-mp-3p-search
329 (lambda () (anything-mp-3-search-base
330 anything-prefix-search re-search-forward bol eol))))
332 (defun anything-mp-3p-search-backward (pattern &rest ignore)
333 (anything-mp-handle-source-name-maybe
334 pattern 'anything-mp-3p-search-backward
335 (lambda () (anything-mp-3-search-base
336 anything-prefix-search-backward re-search-backward eol bol))))
338 ;;;; Highlight matches
339 (defface anything-match
340 '((t (:inherit match)))
341 "Face used to highlight matches."
342 :group 'anything)
344 (defvar anything-mp-highlight-delay 0.7
345 "Highlight matches with `anything-match' face after this many seconds.
346 If nil, no highlight. ")
348 (defvar anything-mp-highlight-threshold 2
349 "Minimum length of pattern to highlight.
350 The smaller this value is, the slower highlight is.")
352 (defun anything-mp-highlight-match ()
353 "Highlight matches after `anything-mp-highlight-delay' seconds."
354 (when (and anything-mp-highlight-delay
355 (not (string= anything-pattern "")))
356 (anything-mp-highlight-match-internal (window-end (anything-window)))
357 (run-with-idle-timer anything-mp-highlight-delay nil
358 'anything-mp-highlight-match-internal
359 (with-current-buffer anything-buffer (point-max)))))
360 (add-hook 'anything-update-hook 'anything-mp-highlight-match)
362 (defun anything-mp-highlight-region (start end regexp face)
363 (save-excursion
364 (goto-char start)
365 (let (me)
366 (while (and (setq me (re-search-forward regexp nil t))
367 (< (point) end)
368 (< 0 (- (match-end 0) (match-beginning 0))))
369 (put-text-property (match-beginning 0) me 'face face)))))
371 (defun* anything-mp-highlight-match-internal (end)
372 (when (anything-window)
373 (set-buffer anything-buffer)
374 (let ((requote (regexp-quote anything-pattern)))
375 (when (>= (length requote) anything-mp-highlight-threshold)
376 (anything-mp-highlight-region (point-min) end
377 requote 'anything-match)))
378 (loop for (pred . re) in (anything-mp-3-get-patterns anything-pattern)
379 when (and (eq pred 'identity)
380 (>= (length re) anything-mp-highlight-threshold))
382 (anything-mp-highlight-region (point-min) end re 'anything-match))))
384 ;;;; source compier
385 (defvar anything-mp-default-match-functions
386 '(anything-exact-match anything-mp-3p-match anything-mp-3-match))
387 (defvar anything-mp-default-search-functions
388 '(anything-exact-search anything-mp-3p-search anything-mp-3-search))
389 (defvar anything-mp-default-search-backward-functions
390 '(anything-exact-search-backward anything-mp-3p-search-backward
391 anything-mp-3-search-backward))
392 (defun anything-compile-source--match-plugin (source)
393 (let ((searchers (if (assoc 'search-from-end source)
394 anything-mp-default-search-backward-functions
395 anything-mp-default-search-functions)))
396 `(,(if (or (assoc 'candidates-in-buffer source)
397 (equal '(identity) (assoc-default 'match source)))
398 '(match identity)
399 `(match ,@anything-mp-default-match-functions
400 ,@(assoc-default 'match source)))
401 (search ,@searchers
402 ,@(assoc-default 'search source))
403 ,@source)))
405 (add-to-list 'anything-compile-source-functions 'anything-compile-source--match-plugin t)
407 ;;;; grep-candidates plug-in
408 (defun agp-candidates (&optional filter)
409 "Normal version of grep-candidates candidates function.
410 Grep is run by asynchronous process."
411 (start-process-shell-command "anything-grep-candidates" nil
412 (agp-command-line-2 filter)))
413 (defun agp-candidates-synchronous-grep (&optional filter)
414 "Faster version of grep-candidates candidates function.
415 Grep is run by synchronous process.
416 It is faster when candidate files are in ramdisk."
417 (split-string (shell-command-to-string (agp-command-line-2 filter)) "\n"))
418 (defun agp-candidates-synchronous-grep--direct-insert-match (&optional filter)
419 "[EXPERIMENTAL]Fastest version of grep-candidates candidates function at the cost of absense of transformers.
420 Grep is run by synchronous process.
421 It is faster when candidate files are in ramdisk.
423 If (direct-insert-match) is in the source, this function is used."
424 (with-current-buffer (anything-candidate-buffer 'global)
425 (call-process-shell-command (agp-command-line-2 filter) nil t)))
427 (defun agp-command-line (query files &optional limit filter)
428 "Build command line used by grep-candidates from QUERY, FILES, LIMIT, and FILTER."
429 (with-temp-buffer
430 (if (string= query "")
431 (insert "cat "
432 (mapconcat
433 (lambda (f) (shell-quote-argument (expand-file-name f)))
434 files " "))
435 (loop for (flag . re) in (anything-mp-3-get-patterns-internal query)
436 for i from 0
438 (setq re (replace-regexp-in-string "^-" "\\-" re))
439 (unless (zerop i) (insert " | "))
440 (insert "grep -ih "
441 (if (eq flag 'identity) "" "-v ")
442 (shell-quote-argument re))
443 (when (zerop i)
444 (insert " "
445 (mapconcat (lambda (f) (shell-quote-argument
446 (expand-file-name f)))
447 files " ")))))
448 (when limit (insert (format " | head -n %d" limit)))
449 (when filter (insert " | " filter))
450 (buffer-string)))
451 (defun agp-command-line-2 (filter)
452 "Build command line used by grep-candidates from FILTER and current source."
453 (agp-command-line
454 anything-pattern
455 (anything-mklist (anything-interpret-value (anything-attr 'grep-candidates)))
456 (anything-candidate-number-limit (anything-get-current-source))
457 filter))
458 (defun anything-compile-source--grep-candidates (source)
459 (anything-aif (assoc-default 'grep-candidates source)
460 (append
461 source
462 (let ((use-fast-directory
463 (string-match
464 anything-grep-candidates-fast-directory-regexp
465 (car (anything-mklist (anything-interpret-value it))))))
466 (cond ((and use-fast-directory (assq 'direct-insert-match source))
467 (anything-log "fastest version (use-fast-directory and direct-insert-match)")
468 `((candidates . agp-candidates-synchronous-grep--direct-insert-match)
469 (match identity)
470 (volatile)
471 (requires-pattern)))
472 (use-fast-directory
473 (anything-log "faster version (use-fast-directory)")
474 `((candidates . agp-candidates-synchronous-grep)
475 (match identity)
476 (volatile)
477 (requires-pattern)))
479 (anything-log "normal version")
480 '((candidates . agp-candidates)
481 (delayed))))))
482 source))
483 (add-to-list 'anything-compile-source-functions 'anything-compile-source--grep-candidates)
485 (anything-document-attribute 'grep-candidates "grep-candidates plug-in"
486 "grep-candidates plug-in provides anything-match-plugin.el feature with grep and head program.
487 It is MUCH FASTER than normal match-plugin to search from vary large (> 1MB) candidates.
488 Make sure to install these programs.
490 It expands `candidates' and `delayed' attributes.
492 `grep-candidates' attribute accepts a filename or list of filename.
493 It also accepts 0-argument function name or variable name.")
495 ;; (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message))))
496 ;; (let ((a "~/.emacs.el")) (anything '(((name . "grep-test") (grep-candidates . a) (action . message) (delayed)))))
497 ;; (let ((a "~/.emacs.el")) (anything '(((name . "grep-test") (grep-candidates . (lambda () a)) (action . message) (delayed)))))
498 ;; (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed) (candidate-number-limit . 2))))
499 ;; (let ((anything-candidate-number-limit 2)) (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed)))))
501 ;;;; Compatibility
502 (unless (fboundp 'apply-partially)
503 (defun apply-partially (fun &rest args)
504 "Return a function that is a partial application of FUN to ARGS.
505 ARGS is a list of the first N arguments to pass to FUN.
506 The result is a new function which does the same as FUN, except that
507 the first N arguments are fixed at the values with which this function
508 was called."
509 (lexical-let ((fun fun) (args1 args))
510 (lambda (&rest args2) (apply fun (append args1 args2))))))
512 ;;;; unit test
513 ;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-expectations.el")
514 ;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-mock.el")
515 (dont-compile
516 (when (fboundp 'expectations)
517 (expectations
518 (desc "amp-mp-make-regexps")
519 (expect '("")
520 (amp-mp-make-regexps ""))
521 (expect '("foo" "bar")
522 (amp-mp-make-regexps "foo bar"))
523 (expect '("foo" "bar")
524 (amp-mp-make-regexps " foo bar"))
525 (expect '("foo" "bar")
526 (amp-mp-make-regexps " foo bar "))
527 (expect '("foo bar" "baz")
528 (let ((anything-mp-space-regexp "\\\\ "))
529 (amp-mp-make-regexps "foo\\ bar baz")))
530 (desc "anything-mp-3-get-patterns-internal")
531 (expect '((identity . "foo"))
532 (anything-mp-3-get-patterns-internal "foo"))
533 (expect '((identity . "foo") (identity . "bar"))
534 (anything-mp-3-get-patterns-internal "foo bar"))
535 (expect '((identity . "foo") (not . "bar"))
536 (anything-mp-3-get-patterns-internal "foo !bar"))
537 (desc "agp-command-line")
538 (expect "grep -ih foo /f1"
539 (agp-command-line "foo" '("/f1")))
540 (expect "grep -ih foo /f1 | grep -ih bar"
541 (agp-command-line "foo bar" '("/f1")))
542 (expect "grep -ih foo /f1 | grep -ih -v bar"
543 (agp-command-line "foo !bar" '("/f1")))
544 (expect "grep -ih foo /f1 /f\\ 2 | grep -ih -v bar | grep -ih baz"
545 (agp-command-line "foo !bar baz" '("/f1" "/f 2")))
546 (expect (concat "grep -ih foo " (expand-file-name "~/.emacs.el"))
547 (agp-command-line "foo" '("~/.emacs.el")))
548 (expect "grep -ih f\\ o /f\\ 1"
549 (agp-command-line "f o" '("/f 1")))
550 (expect "grep -ih foo /f1 | head -n 5"
551 (agp-command-line "foo" '("/f1") 5))
552 (expect "grep -ih foo /f1 | head -n 5 | nkf -w"
553 (agp-command-line "foo" '("/f1") 5 "nkf -w"))
554 (desc "anything-exact-match")
555 (expect (non-nil)
556 (anything-exact-match "thunder" "thunder"))
557 (expect nil
558 (anything-exact-match "thunder" "fire"))
559 (desc "anything-exact-search")
560 (expect (non-nil)
561 (with-temp-buffer
562 (insert "fire\nthunder\n")
563 (goto-char 1)
564 (anything-exact-search "thunder" nil t)))
565 (expect (non-nil)
566 (with-temp-buffer
567 (insert "\nfire\nthunder\n")
568 (goto-char 1)
569 (anything-exact-search "fire" nil t)))
570 (desc "anything-prefix-search")
571 (expect (non-nil)
572 (with-temp-buffer
573 (insert "fire\nthunder\n")
574 (goto-char (point-min))
575 (anything-prefix-search "thund" nil t)))
576 (expect nil
577 (with-temp-buffer
578 (insert "fire\nthunder\n")
579 (goto-char (point-min))
580 (anything-prefix-search "hund" nil t)))
581 (desc "anything-prefix-search-backward")
582 (expect (non-nil)
583 (with-temp-buffer
584 (insert "fire\nthunder\n")
585 (goto-char (point-max))
586 (anything-prefix-search-backward "thund" nil t)))
587 (expect nil
588 (with-temp-buffer
589 (insert "fire\nthunder\n")
590 (goto-char (point-max))
591 (anything-prefix-search-backward "hund" nil t)))
592 (desc "amp-mp-1-make-regexp")
593 (expect "a.*b"
594 (amp-mp-1-make-regexp "a b"))
595 (expect "a b"
596 (let ((anything-mp-space-regexp "\\\\ "))
597 (amp-mp-1-make-regexp "a\\ b")))
598 (expect "a.*b c"
599 (let ((anything-mp-space-regexp "\\\\ "))
600 (amp-mp-1-make-regexp "a b\\ c")))
601 (expect ""
602 (amp-mp-1-make-regexp ""))
603 (desc "anything-mp-1-search")
604 (expect (non-nil)
605 (with-temp-buffer
606 (insert "fire\nthunder\n")
607 (goto-char 1)
608 (anything-mp-1-search "th+ r" nil t)))
609 (desc "anything-mp-2-search")
610 (expect (non-nil)
611 (with-temp-buffer
612 (insert "fire\nthunder\n")
613 (goto-char 1)
614 (anything-mp-2-search "h+ r" nil t)))
615 (expect nil
616 (with-temp-buffer
617 (insert "fire\nthunder\n")
618 (goto-char 1)
619 (anything-mp-2-search "th+ r" nil t)))
620 (desc "anything-mp-3-search")
621 (expect (non-nil)
622 (with-temp-buffer
623 (insert "fire\nthunder\n")
624 (goto-char 1)
625 (anything-mp-3-search "h+ r" nil t)))
626 (expect (non-nil)
627 (with-temp-buffer
628 (insert "fire\nthunder\n")
629 (goto-char 1)
630 (anything-mp-3-search "th+ r" nil t)))
631 (expect (non-nil)
632 (with-temp-buffer
633 (insert "fire\nthunder\n")
634 (goto-char 1)
635 (anything-mp-3-search "r th+" nil t)))
636 (expect nil
637 (with-temp-buffer
638 (insert "fire\nthunder\n")
639 (goto-char 1)
640 (anything-mp-3-search "under hue" nil t)))
641 (expect (non-nil)
642 (with-temp-buffer
643 (insert "fire\nthunder\n")
644 (goto-char 1)
645 (anything-mp-3-search "r th+ n" nil t)))
646 (desc "anything-mp-3-search")
647 (expect (non-nil)
648 (with-temp-buffer
649 (insert "fire\nthunder\n")
650 (goto-char 1)
651 (anything-mp-3-search "th der" nil t)))
652 (expect nil
653 (with-temp-buffer
654 (insert "fire\nthunder\n")
655 (goto-char 1)
656 (anything-mp-3-search "th ders" nil t)))
657 (desc "anything-mp-3-search not")
658 (expect t
659 (with-temp-buffer
660 (insert "threshold\nthunder\n")
661 (goto-char 1)
662 (anything-mp-3-search "h !der" nil t)))
663 (expect t
664 (with-temp-buffer
665 (insert "threshold\nthunder\n")
666 (goto-char 1)
667 (anything-mp-3-search "th !der" nil t)))
668 (desc "anything-mp-3p-search")
669 (expect (non-nil)
670 (with-temp-buffer
671 (insert "fire\nthunder\n")
672 (goto-char 1)
673 (anything-mp-3p-search "th der" nil t)))
674 (expect nil
675 (with-temp-buffer
676 (insert "fire\nthunder\n")
677 (goto-char 1)
678 (anything-mp-3p-search "h ders" nil t)))
679 (desc "anything-mp-3p-search not")
680 (expect t
681 (with-temp-buffer
682 (insert "\nthreshold\nthunder\n")
683 (goto-char 1)
684 (anything-mp-3p-search "th !der" nil t)))
685 (expect nil
686 (with-temp-buffer
687 (insert "threshold\nthunder\n")
688 (goto-char 1)
689 (anything-mp-3p-search "h !der" nil t)))
690 (desc "anything-mp-3-search-backward")
691 (expect (non-nil)
692 (with-temp-buffer
693 (insert "fire\nthunder\n")
694 (goto-char (point-max))
695 (anything-mp-3-search-backward "h der" nil t)))
696 (expect nil
697 (with-temp-buffer
698 (insert "fire\nthunder\n")
699 (goto-char (point-max))
700 (anything-mp-3-search-backward "th ders" nil t)))
701 (desc "anything-mp-3-search-backward not")
702 (expect t
703 (with-temp-buffer
704 (insert "threshold\nthunder\n")
705 (goto-char (point-max))
706 (anything-mp-3-search-backward "h !der" nil t)))
707 (expect t
708 (with-temp-buffer
709 (insert "threshold\nthunder\n")
710 (goto-char (point-max))
711 (anything-mp-3-search-backward "th !der" nil t)))
712 (desc "anything-mp-3p-search-backward")
713 (expect (non-nil)
714 (with-temp-buffer
715 (insert "fire\nthunder\n")
716 (goto-char (point-max))
717 (anything-mp-3p-search-backward "th der" nil t)))
718 (expect nil
719 (with-temp-buffer
720 (insert "fire\nthunder\n")
721 (goto-char (point-max))
722 (anything-mp-3p-search-backward "h der" nil t)))
723 (desc "anything-mp-3p-search-backward not")
724 (expect t
725 (with-temp-buffer
726 (insert "\nthreshold\nthunder\n")
727 (goto-char (point-max))
728 (anything-mp-3p-search-backward "th !der" nil t)))
729 (expect nil
730 (with-temp-buffer
731 (insert "threshold\nthunder\n")
732 (goto-char (point-max))
733 (anything-mp-3p-search-backward "h !der" nil t)))
734 (desc "anything-mp-1-match")
735 (expect (non-nil)
736 (anything-mp-1-match "thunder" "th+ r"))
737 (desc "anything-mp-2-match")
738 (expect (non-nil)
739 (anything-mp-2-match "thunder" "h+ r"))
740 (expect nil
741 (anything-mp-2-match "thunder" "th+ r"))
742 (desc "anything-mp-3-match")
743 (expect (non-nil)
744 (anything-mp-3-match "thunder" "h+ r"))
745 (expect (non-nil)
746 (anything-mp-3-match "thunder" "th+ r"))
747 (expect (non-nil)
748 (anything-mp-3-match "thunder" "r th+"))
749 (expect nil
750 (anything-mp-3-match "thunder" "under hue"))
751 (expect (non-nil)
752 (anything-mp-3-match "thunder" "r th+ n"))
753 (desc "anything-mp-3-match not")
754 (expect (non-nil)
755 (anything-mp-3-match "threshold" "th !der"))
756 (desc "anything-prefix-match")
757 (expect (non-nil)
758 (anything-prefix-match "fobar" "fo"))
759 (expect nil
760 (anything-prefix-match "xfobar" "fo"))
762 (desc "anything-mp-3-match")
763 (expect (non-nil)
764 (anything-mp-3-match "thunder" "h der"))
765 (expect nil
766 (anything-mp-3-match "thunder" "h ders"))
767 (desc "anything-mp-3p-match")
768 (expect (non-nil)
769 (anything-mp-3p-match "thunder" "th der"))
770 (expect nil
771 (anything-mp-3p-match "thunder" "h der"))
772 (desc "anything-mp-3p-match not")
773 (expect (non-nil)
774 (anything-mp-3p-match "threshold" "th !der"))
775 (expect nil
776 (anything-mp-3p-match "threshold" "h !der"))
777 (desc "with identity match")
778 (expect '(identity)
779 (assoc-default 'match
780 (car (anything-compile-sources
781 '(((name . "FOO")
782 (candidates-in-buffer)))
783 '(anything-compile-source--candidates-in-buffer
784 anything-compile-source--match-plugin)))))
785 (expect '(identity)
786 (assoc-default 'match
787 (car (anything-compile-sources
788 '(((name . "FOO")
789 (match identity)))
790 '(anything-compile-source--match-plugin)))))
791 (desc "functional")
792 (expect '(("FOO" ("thunder")))
793 (anything-test-candidates '(((name . "FOO")
794 (candidates "fire" "thunder")))
795 "th r"
796 '(anything-compile-source--match-plugin)))
797 (expect '(("FOO" ("one two")))
798 (let ((anything-mp-space-regexp "\\\\ "))
799 (anything-test-candidates '(((name . "FOO")
800 (candidates "one two" "three four")))
801 "e\\ t"
802 '(anything-compile-source--match-plugin))))
803 (expect '(("FOO" ("one two")))
804 (let ((anything-mp-space-regexp " "))
805 (anything-test-candidates '(((name . "FOO")
806 (candidates "one two" "three four")))
807 "e t"
808 '(anything-compile-source--match-plugin))))
809 (expect '(("FOO" ("thunder")))
810 (anything-test-candidates '(((name . "FOO")
811 (init
812 . (lambda ()
813 (with-current-buffer (anything-candidate-buffer 'global)
814 (insert "fire\nthunder\nthanks\n"))))
815 (candidates-in-buffer)))
816 "th r"
817 '(anything-compile-source--candidates-in-buffer
818 anything-compile-source--match-plugin)))
819 (expect '(("FOO" ("foo" "foobar")))
820 (anything-test-candidates '(((name . "FOO")
821 (candidates "foobar" "foo")))
822 "foo"
823 '(anything-compile-source--match-plugin)))
824 (expect '(("FOO" ("foo" "foobar")))
825 (anything-test-candidates '(((name . "FOO")
826 (init
827 . (lambda ()
828 (with-current-buffer (anything-candidate-buffer 'global)
829 (insert "foobar\nfoo\n"))))
830 (candidates-in-buffer)))
831 "foo"
832 '(anything-compile-source--candidates-in-buffer
833 anything-compile-source--match-plugin)))
834 (expect '(("FOO" ("foo")))
835 (anything-test-candidates '(((name . "FOO")
836 (init
837 . (lambda ()
838 (with-current-buffer (anything-candidate-buffer 'global)
839 (insert "foo\n"))))
840 (candidates-in-buffer)))
841 "foo"
842 '(anything-compile-source--candidates-in-buffer
843 anything-compile-source--match-plugin)))
844 (expect '(("FOO" ("foo")))
845 (anything-test-candidates '(((name . "FOO")
846 (init
847 . (lambda ()
848 (with-current-buffer (anything-candidate-buffer 'global)
849 (insert "bar\nfoo\ntest\n"))))
850 (candidates-in-buffer)))
851 "foo"
852 '(anything-compile-source--candidates-in-buffer
853 anything-compile-source--match-plugin)))
854 (expect '(("FOO" ("foobar" "foo")))
855 (anything-test-candidates '(((name . "FOO")
856 (init
857 . (lambda ()
858 (with-current-buffer (anything-candidate-buffer 'global)
859 (insert "foobar\nfoo\n"))))
860 (candidates-in-buffer)))
862 '(anything-compile-source--candidates-in-buffer
863 anything-compile-source--match-plugin)))
864 (expect '(("FOO" ("foo" "foobar")))
865 (anything-test-candidates '(((name . "FOO")
866 (init
867 . (lambda ()
868 (with-current-buffer (anything-candidate-buffer 'global)
869 (insert "foobar\nfoo\n"))))
870 (candidates-in-buffer)
871 (search-from-end)))
872 "foo"
873 '(anything-compile-source--candidates-in-buffer
874 anything-compile-source--match-plugin)))
875 (expect '(("FOO" ("elisp" "elp")))
876 (anything-test-candidates '(((name . "FOO")
877 (init
878 . (lambda ()
879 (with-current-buffer (anything-candidate-buffer 'global)
880 (insert "elp\nelisp\n"))))
881 (candidates-in-buffer)
882 (search-from-end)))
883 "el p"
884 '(anything-compile-source--candidates-in-buffer
885 anything-compile-source--match-plugin)))
886 (expect '(("FOO" ("elisp" )))
887 (anything-test-candidates '(((name . "FOO")
888 (init
889 . (lambda ()
890 (with-current-buffer (anything-candidate-buffer 'global)
891 (insert "elp\nelisp\n"))))
892 (candidates-in-buffer)
893 (search-from-end)))
894 "el+ isp"
895 '(anything-compile-source--candidates-in-buffer
896 anything-compile-source--match-plugin)))
897 ;; prefix multi -> multi
898 (expect '(("FOO" ("elisp-info" "info.el")))
899 (anything-test-candidates '(((name . "FOO")
900 (init
901 . (lambda ()
902 (with-current-buffer (anything-candidate-buffer 'global)
903 (insert "info.el\nelisp-info\n"))))
904 (candidates-in-buffer)
906 "el info"
907 '(anything-compile-source--candidates-in-buffer
908 anything-compile-source--match-plugin)))
909 ;; multi not
910 (expect '(("FOO" ("info.el")))
911 (anything-test-candidates '(((name . "FOO")
912 (init
913 . (lambda ()
914 (with-current-buffer (anything-candidate-buffer 'global)
915 (insert "info.el\nelisp-info\n"))))
916 (candidates-in-buffer)
918 "info !elisp"
919 '(anything-compile-source--candidates-in-buffer
920 anything-compile-source--match-plugin)))
921 ;; anything-mp-match-source-name
922 (expect '(("SourceName" ("foo")))
923 (let ((anything-mp-match-source-name t))
924 (anything-test-candidates '(((name . "SourceName")
925 (candidates "foo" "bar")))
926 "source f"
927 '(anything-compile-source--match-plugin))))
928 (expect '(("SourceName cib" ("foo")))
929 (let ((anything-mp-match-source-name t))
930 (anything-test-candidates '(((name . "SourceName cib")
931 (init
932 . (lambda ()
933 (with-current-buffer (anything-candidate-buffer 'global)
934 (insert "foo\nbar\n"))))
935 (candidates-in-buffer)))
936 "source f"
937 '(anything-compile-source--candidates-in-buffer
938 anything-compile-source--match-plugin))))
939 (expect '(("SourceName cib search-from-end" ("bar")))
940 (let ((anything-mp-match-source-name t))
941 (anything-test-candidates '(((name . "SourceName cib search-from-end")
942 (init
943 . (lambda ()
944 (with-current-buffer (anything-candidate-buffer 'global)
945 (insert "foo\nbar\n"))))
946 (search-from-end)
947 (candidates-in-buffer)))
948 "source b"
949 '(anything-compile-source--candidates-in-buffer
950 anything-compile-source--match-plugin))))
951 (expect '(("SourceName" ("foo" "bar")))
952 (let ((anything-mp-match-source-name t))
953 (anything-test-candidates '(((name . "SourceName")
954 (candidates "foo" "bar")))
955 "source ."
956 '(anything-compile-source--match-plugin))))
957 (expect '(("SourceName cib" ("foo" "bar")))
958 (let ((anything-mp-match-source-name t))
959 (anything-test-candidates '(((name . "SourceName cib")
960 (init
961 . (lambda ()
962 (with-current-buffer (anything-candidate-buffer 'global)
963 (insert "foo\nbar\n"))))
964 (candidates-in-buffer)))
965 "source ."
966 '(anything-compile-source--candidates-in-buffer
967 anything-compile-source--match-plugin))))
968 (expect '(("SourceName cib search-from-end" ("bar" "foo")))
969 (let ((anything-mp-match-source-name t))
970 (anything-test-candidates '(((name . "SourceName cib search-from-end")
971 (init
972 . (lambda ()
973 (with-current-buffer (anything-candidate-buffer 'global)
974 (insert "foo\nbar\n"))))
975 (search-from-end)
976 (candidates-in-buffer)))
977 "source ."
978 '(anything-compile-source--candidates-in-buffer
979 anything-compile-source--match-plugin))))
981 ;; (anything-compile-sources '(((name . "test"))) anything-compile-source-functions)
982 (provide 'anything-match-plugin)
984 ;; How to save (DO NOT REMOVE!!)
985 ;; (progn (magit-push) (emacswiki-post "anything-match-plugin.el"))
986 ;;; anything-match-plugin.el ends here