Default action of type:file is `anything-find-many-files'.
[anything-config.git] / anything-match-plugin.el
blobb6d9730fb9af24b1bb81ac8d384d47e19a33f813
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:
41 ;; A query of multiple regexp match is space-delimited string.
42 ;; Anything displays candidates which matches all the regexps.
43 ;; A regexp with "!" prefix means not matching the regexp.
44 ;; To include spaces to a regexp, prefix "\" before space,
45 ;; it is controlled by `anything-mp-space-regexp' variable.
47 ;; This file highlights patterns like `occur'. Note that patterns
48 ;; longer than `anything-mp-highlight-threshold' are highlighted. And
49 ;; region out of screen is highlighted after
50 ;; `anything-mp-highlight-delay' seconds.
52 ;; Highlight in Emacs is time-consuming process for slow computers. To
53 ;; disable it is to set nil to `anything-mp-highlight-delay'.
55 ;; Just require it to use.
57 ;;; History:
59 ;; $Log: anything-match-plugin.el,v $
60 ;; Revision 1.27 2010-03-24 11:11:28 rubikitch
61 ;; Added :group keyword to `defface anything-match'
63 ;; Revision 1.26 2010/03/24 10:48:55 rubikitch
64 ;; grep-candidates plug-in: document / imply `delayed' attribute
66 ;; Revision 1.25 2010/03/24 10:38:48 rubikitch
67 ;; grep-candidates plugin: grep-candidates attribute can also accept variable/function name.
69 ;; Revision 1.24 2010/03/22 09:01:22 rubikitch
70 ;; grep-candidates plugin released
72 ;; Revision 1.23 2010/03/22 08:02:11 rubikitch
73 ;; grep-candidates plugin prototype
75 ;; Revision 1.22 2009/03/03 10:21:45 rubikitch
76 ;; * Remove highlight.el dependency.
77 ;; * Very faster highlight.
79 ;; Revision 1.21 2009/03/03 08:51:23 rubikitch
80 ;; New variable: `anything-mp-highlight-threshold'
82 ;; Revision 1.20 2009/03/03 07:29:24 rubikitch
83 ;; Highlight matches!
85 ;; Revision 1.19 2008/09/08 06:58:59 rubikitch
86 ;; changed default `anything-mp-space-regexp' to "[\\ ] "
88 ;; Revision 1.18 2008/09/07 12:09:01 rubikitch
89 ;; *** empty log message ***
91 ;; Revision 1.17 2008/09/07 07:48:12 rubikitch
92 ;; Append commentary.
93 ;; Multiple regexp match with regexp negation.
95 ;; Revision 1.16 2008/09/07 06:58:11 rubikitch
96 ;; Added mp-3p match: permutation with prefix match
98 ;; Revision 1.15 2008/09/07 05:23:07 rubikitch
99 ;; New variable: `anything-mp-space-regexp'
101 ;; Revision 1.14 2008/09/03 03:33:09 rubikitch
102 ;; anything-exact-*, anything-prefix-*: memoize
104 ;; Revision 1.13 2008/09/02 10:56:50 rubikitch
105 ;; anything-mp-3-*: MUCH MUCH FASTER
106 ;; changed algorithm
108 ;; Revision 1.12 2008/09/01 13:41:57 rubikitch
109 ;; search functions for search-from-end
111 ;; Revision 1.11 2008/08/24 20:40:27 rubikitch
112 ;; prevent the unit test from being byte-compiled.
114 ;; Revision 1.10 2008/08/24 17:48:53 rubikitch
115 ;; Add commentary
117 ;; Revision 1.9 2008/08/24 08:23:16 rubikitch
118 ;; Rename `anything-candidates-buffer' -> `anything-candidate-buffer'
120 ;; Revision 1.8 2008/08/22 21:25:44 rubikitch
121 ;; *** empty log message ***
123 ;; Revision 1.7 2008/08/22 21:17:58 rubikitch
124 ;; exact, prefix match: faster
126 ;; Revision 1.6 2008/08/22 19:40:22 rubikitch
127 ;; exact -> prefix -> mp-3 by default because of speed
129 ;; Revision 1.5 2008/08/22 19:04:53 rubikitch
130 ;; reimplemented
132 ;; Revision 1.4 2008/08/20 00:10:15 rubikitch
133 ;; *** empty log message ***
135 ;; Revision 1.3 2008/08/19 23:30:39 rubikitch
136 ;; exact match support
138 ;; Revision 1.2 2008/08/19 23:02:29 rubikitch
139 ;; candidates-in-buffer hack
141 ;; Revision 1.1 2008/08/19 19:45:11 rubikitch
142 ;; Initial revision
145 ;;; Code:
147 (require 'anything)
148 (require 'cl)
150 (let ((version "1.256"))
151 (when (and (string= "1." (substring version 0 2))
152 (string-match "1\.\\([0-9]+\\)" anything-version)
153 (< (string-to-number (match-string 1 anything-version))
154 (string-to-number (substring version 2))))
155 (error "Please update anything.el!!
157 http://www.emacswiki.org/cgi-bin/wiki/download/anything.el
159 or M-x install-elisp-from-emacswiki anything.el")))
160 ;;;; multiple patterns
161 (defvar anything-use-multiple-patterns t
162 "If non-nil, enable anything-use-multiple-patterns.")
163 (defvar anything-mp-space-regexp "[\\ ] "
164 "Regexp to represent space itself in multiple regexp match.")
166 (defun amp-mp-make-regexps (pattern)
167 (if (string= pattern "") '("")
168 (loop for s in (split-string (replace-regexp-in-string anything-mp-space-regexp "\000\000" pattern) " " t)
169 collect (replace-regexp-in-string "\000\000" " " s))))
171 (defun amp-mp-1-make-regexp (pattern)
172 (mapconcat 'identity (amp-mp-make-regexps pattern) ".*"))
174 (defmacro amp-define-memoizer (prefix pattern-expr)
175 (let ((pattern-str (intern (concat prefix "pattern-str")))
176 (pattern-real (intern (concat prefix "pattern-real")))
177 (get-pattern (intern (concat prefix "get-pattern"))))
178 `(progn
179 (defvar ,pattern-str nil)
180 (defvar ,pattern-real nil)
181 (defsubst ,get-pattern (pattern)
182 (unless (equal pattern ,pattern-str)
183 (setq ,pattern-str pattern
184 ,pattern-real ,pattern-expr))
185 ,pattern-real))))
187 (defmacro amp-define (prefix pattern-expr)
188 (let ((get-pattern (intern (concat prefix "get-pattern")))
189 (match (intern (concat prefix "match")))
190 (search (intern (concat prefix "search")))
191 (search-backward (intern (concat prefix "search-backward"))))
192 `(progn
193 (amp-define-memoizer ,prefix ,pattern-expr)
194 (defun* ,match (str &optional (pattern anything-pattern))
195 (string-match (,get-pattern pattern) str))
196 (defun ,search (pattern &rest ignore)
197 (re-search-forward (,get-pattern pattern) nil t))
198 (defun ,search-backward (pattern &rest ignore)
199 (re-search-backward (,get-pattern pattern) nil t)))))
201 ;; exact match
202 ;(amp-define "anything-exact-" (concat (anything-prefix-get-pattern pattern) "$"))
203 (amp-define-memoizer "anything-exact-" (concat "\n" pattern "\n"))
204 (defun anything-exact-match (str &optional pattern)
205 (string= str (or pattern anything-pattern)))
206 (defun anything-exact-search (pattern &rest ignore)
207 (and (search-forward (anything-exact-get-pattern pattern) nil t)
208 (forward-line -1)))
209 (defun anything-exact-search-backward (pattern &rest ignore)
210 (and (search-backward (anything-exact-get-pattern pattern) nil t)
211 (forward-line 1)))
212 ;; prefix match
213 ;;(amp-define "anything-prefix-" (concat "^" (regexp-quote pattern)))
214 (amp-define-memoizer "anything-prefix-" (concat "\n" pattern))
215 (defun anything-prefix-match (str &optional pattern)
216 (setq pattern (or pattern anything-pattern))
217 (let ((len (length pattern)))
218 (and (<= len (length str))
219 (string= (substring str 0 len) pattern ))))
220 (defun anything-prefix-search (pattern &rest ignore)
221 (search-forward (anything-prefix-get-pattern pattern) nil t))
222 (defun anything-prefix-search-backward (pattern &rest ignore)
223 (and (search-backward (anything-prefix-get-pattern pattern) nil t)
224 (forward-line 1)))
225 ;; multiple regexp patterns 1 (order is preserved / prefix)
226 (amp-define "anything-mp-1-" (concat "^" (amp-mp-1-make-regexp pattern)))
227 ;; multiple regexp patterns 2 (order is preserved / partial)
228 (amp-define "anything-mp-2-" (concat "^.+" (amp-mp-1-make-regexp pattern)))
230 ;;;; multiple regexp patterns 3 (permutation)
231 (defvar anything-mp-3-pattern-str nil)
232 (defvar anything-mp-3-pattern-list nil)
233 (defsubst anything-mp-3-get-patterns (pattern)
234 (unless (equal pattern anything-mp-3-pattern-str)
235 (setq anything-mp-3-pattern-str pattern
236 anything-mp-3-pattern-list
237 (anything-mp-3-get-patterns-internal pattern)))
238 anything-mp-3-pattern-list)
239 (defun anything-mp-3-get-patterns-internal (pattern)
240 (loop for pat in (amp-mp-make-regexps pattern)
241 collect (if (string= "!" (substring pat 0 1))
242 (cons 'not (substring pat 1))
243 (cons 'identity pat))))
244 (defun* anything-mp-3-match (str &optional (pattern anything-pattern))
245 (loop for (pred . re) in (anything-mp-3-get-patterns pattern)
246 always (funcall pred (string-match re str))))
248 (defmacro anything-mp-3-search-base (searchfn1 searchfn2 b e)
249 `(loop with pat = (anything-mp-3-get-patterns pattern)
250 while (,searchfn1 (or (cdar pat) "") nil t)
251 for bol = (point-at-bol)
252 for eol = (point-at-eol)
253 if (loop
254 for (pred . s) in (cdr pat)
255 always (progn (goto-char ,b)
256 (funcall pred (,searchfn2 s ,e t))))
257 do (goto-char ,e) (return t)
258 else do
259 (goto-char ,e)
260 finally (return nil)))
262 (defun anything-mp-3-search (pattern &rest ignore)
263 (anything-mp-3-search-base re-search-forward re-search-forward bol eol))
264 (defun anything-mp-3-search-backward (pattern &rest ignore)
265 (anything-mp-3-search-base re-search-backward re-search-backward eol bol))
267 ;; mp-3p- (multiple regexp pattern 3 with prefix search)
268 (defun* anything-mp-3p-match (str &optional (pattern anything-pattern))
269 (destructuring-bind ((first-pred . first-re) . rest)
270 (anything-mp-3-get-patterns pattern)
271 (and (funcall first-pred (anything-prefix-match str first-re))
272 (loop for (pred . re) in rest
273 always (funcall pred (string-match re str))))))
274 (defun anything-mp-3p-search (pattern &rest ignore)
275 (anything-mp-3-search-base anything-prefix-search re-search-forward bol eol))
277 (defun anything-mp-3p-search-backward (pattern &rest ignore)
278 (anything-mp-3-search-base anything-prefix-search-backward re-search-backward eol bol))
280 ;;;; Highlight matches
281 (defface anything-match
282 '((t (:inherit match)))
283 "Face used to highlight matches."
284 :group 'anything)
286 (defvar anything-mp-highlight-delay 0.7
287 "Highlight matches with `anything-match' face after this many seconds.
288 If nil, no highlight. ")
290 (defvar anything-mp-highlight-threshold 2
291 "Minimum length of pattern to highlight.
292 The smaller this value is, the slower highlight is.")
294 (defun anything-mp-highlight-match ()
295 "Highlight matches after `anything-mp-highlight-delay' seconds."
296 (when (and anything-mp-highlight-delay
297 (not (string= anything-pattern "")))
298 (anything-mp-highlight-match-internal (window-end (anything-window)))
299 (run-with-idle-timer anything-mp-highlight-delay nil
300 'anything-mp-highlight-match-internal
301 (with-current-buffer anything-buffer (point-max)))))
302 (add-hook 'anything-update-hook 'anything-mp-highlight-match)
304 (defun anything-mp-highlight-region (start end regexp face)
305 (save-excursion
306 (goto-char start)
307 (let (me)
308 (while (and (setq me (re-search-forward regexp nil t))
309 (< (point) end)
310 (< 0 (- (match-end 0) (match-beginning 0))))
311 (put-text-property (match-beginning 0) me 'face face)))))
313 (defun* anything-mp-highlight-match-internal (end)
314 (when (anything-window)
315 (set-buffer anything-buffer)
316 (let ((requote (regexp-quote anything-pattern)))
317 (when (>= (length requote) anything-mp-highlight-threshold)
318 (anything-mp-highlight-region (point-min) end
319 requote 'anything-match)))
320 (loop for (pred . re) in (anything-mp-3-get-patterns anything-pattern)
321 when (and (eq pred 'identity) (>= (length re) anything-mp-highlight-threshold))
323 (anything-mp-highlight-region (point-min) end re 'anything-match))))
325 ;;;; source compier
326 (defvar anything-default-match-functions
327 '(anything-exact-match anything-mp-3p-match anything-mp-3-match))
328 (defvar anything-default-search-functions
329 '(anything-exact-search anything-mp-3p-search anything-mp-3-search))
330 (defvar anything-default-search-backward-functions
331 '(anything-exact-search-backward anything-mp-3p-search-backward anything-mp-3-search-backward))
332 (defun anything-compile-source--match-plugin (source)
333 (let ((searchers (if (assoc 'search-from-end source)
334 anything-default-search-backward-functions
335 anything-default-search-functions)))
336 `(,(if (or (assoc 'candidates-in-buffer source)
337 (equal '(identity) (assoc-default 'match source)))
338 '(match identity)
339 `(match ,@anything-default-match-functions
340 ,@(assoc-default 'match source)))
341 (search ,@searchers
342 ,@(assoc-default 'search source))
343 ,@source)))
345 (add-to-list 'anything-compile-source-functions 'anything-compile-source--match-plugin t)
347 ;;;; grep-candidates plug-in
348 (defun agp-candidates ()
349 (start-process-shell-command
350 "anything-grep-candidates" nil
351 (agp-command-line anything-pattern
352 (anything-mklist (anything-interpret-value (anything-attr 'grep-candidates)))
353 (anything-candidate-number-limit (anything-get-current-source)))))
354 (defun agp-command-line (query files &optional limit)
355 (with-temp-buffer
356 (loop for (flag . re) in (anything-mp-3-get-patterns-internal query)
357 for i from 0
359 (setq re (replace-regexp-in-string "^-" "\\-" re))
360 (unless (zerop i) (insert " | "))
361 (insert "grep -ih "
362 (if (eq flag 'identity) "" "-v ")
363 (shell-quote-argument re))
364 (when (zerop i) (insert " "
365 (mapconcat (lambda (f) (shell-quote-argument (expand-file-name f))) files " "))))
366 (when limit (insert (format " | head -%d" limit)))
367 (buffer-string)))
368 (defun anything-compile-source--grep-candidates (source)
369 (if (assq 'grep-candidates source)
370 (append source
371 '((candidates . agp-candidates)
372 (delayed)))
373 source))
374 (add-to-list 'anything-compile-source-functions 'anything-compile-source--grep-candidates)
376 (anything-document-attribute 'grep-candidates "grep-candidates plug-in"
377 "grep-candidates plug-in provides anything-match-plugin.el feature with grep and head program.
378 It is MUCH FASTER than normal match-plugin to search from vary large (> 1MB) candidates.
379 Make sure to install these programs.
381 It expands `candidates' and `delayed' attributes.
383 `grep-candidates' attribute accepts a filename or list of filename.
384 It also accepts 0-argument function name or variable name.")
386 ;; (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message))))
387 ;; (let ((a "~/.emacs.el")) (anything '(((name . "grep-test") (grep-candidates . a) (action . message) (delayed)))))
388 ;; (let ((a "~/.emacs.el")) (anything '(((name . "grep-test") (grep-candidates . (lambda () a)) (action . message) (delayed)))))
389 ;; (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed) (candidate-number-limit . 2))))
390 ;; (let ((anything-candidate-number-limit 2)) (anything '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed)))))
392 ;;;; unit test
393 ;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-expectations.el")
394 ;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-mock.el")
395 (dont-compile
396 (when (fboundp 'expectations)
397 (expectations
398 (desc "amp-mp-make-regexps")
399 (expect '("")
400 (amp-mp-make-regexps ""))
401 (expect '("foo" "bar")
402 (amp-mp-make-regexps "foo bar"))
403 (expect '("foo" "bar")
404 (amp-mp-make-regexps " foo bar"))
405 (expect '("foo" "bar")
406 (amp-mp-make-regexps " foo bar "))
407 (expect '("foo bar" "baz")
408 (let ((anything-mp-space-regexp "\\\\ "))
409 (amp-mp-make-regexps "foo\\ bar baz")))
410 (desc "anything-mp-3-get-patterns-internal")
411 (expect '((identity . "foo"))
412 (anything-mp-3-get-patterns-internal "foo"))
413 (expect '((identity . "foo") (identity . "bar"))
414 (anything-mp-3-get-patterns-internal "foo bar"))
415 (expect '((identity . "foo") (not . "bar"))
416 (anything-mp-3-get-patterns-internal "foo !bar"))
417 (desc "agp-command-line")
418 (expect "grep -ih foo /f1"
419 (agp-command-line "foo" '("/f1")))
420 (expect "grep -ih foo /f1 | grep -ih bar"
421 (agp-command-line "foo bar" '("/f1")))
422 (expect "grep -ih foo /f1 | grep -ih -v bar"
423 (agp-command-line "foo !bar" '("/f1")))
424 (expect "grep -ih foo /f1 /f\\ 2 | grep -ih -v bar | grep -ih baz"
425 (agp-command-line "foo !bar baz" '("/f1" "/f 2")))
426 (expect (concat "grep -ih foo " (expand-file-name "~/.emacs.el"))
427 (agp-command-line "foo" '("~/.emacs.el")))
428 (expect "grep -ih f\\ o /f\\ 1"
429 (agp-command-line "f o" '("/f 1")))
430 (expect "grep -ih foo /f1 | head -5"
431 (agp-command-line "foo" '("/f1") 5))
432 (desc "anything-exact-match")
433 (expect (non-nil)
434 (anything-exact-match "thunder" "thunder"))
435 (expect nil
436 (anything-exact-match "thunder" "fire"))
437 (desc "anything-exact-search")
438 (expect (non-nil)
439 (with-temp-buffer
440 (insert "fire\nthunder\n")
441 (goto-char 1)
442 (anything-exact-search "thunder" nil t)))
443 (expect (non-nil)
444 (with-temp-buffer
445 (insert "\nfire\nthunder\n")
446 (goto-char 1)
447 (anything-exact-search "fire" nil t)))
448 (desc "anything-prefix-search")
449 (expect (non-nil)
450 (with-temp-buffer
451 (insert "fire\nthunder\n")
452 (goto-char (point-min))
453 (anything-prefix-search "thund" nil t)))
454 (expect nil
455 (with-temp-buffer
456 (insert "fire\nthunder\n")
457 (goto-char (point-min))
458 (anything-prefix-search "hund" nil t)))
459 (desc "anything-prefix-search-backward")
460 (expect (non-nil)
461 (with-temp-buffer
462 (insert "fire\nthunder\n")
463 (goto-char (point-max))
464 (anything-prefix-search-backward "thund" nil t)))
465 (expect nil
466 (with-temp-buffer
467 (insert "fire\nthunder\n")
468 (goto-char (point-max))
469 (anything-prefix-search-backward "hund" nil t)))
470 (desc "amp-mp-1-make-regexp")
471 (expect "a.*b"
472 (amp-mp-1-make-regexp "a b"))
473 (expect "a b"
474 (let ((anything-mp-space-regexp "\\\\ "))
475 (amp-mp-1-make-regexp "a\\ b")))
476 (expect "a.*b c"
477 (let ((anything-mp-space-regexp "\\\\ "))
478 (amp-mp-1-make-regexp "a b\\ c")))
479 (expect ""
480 (amp-mp-1-make-regexp ""))
481 (desc "anything-mp-1-search")
482 (expect (non-nil)
483 (with-temp-buffer
484 (insert "fire\nthunder\n")
485 (goto-char 1)
486 (anything-mp-1-search "th+ r" nil t)))
487 (desc "anything-mp-2-search")
488 (expect (non-nil)
489 (with-temp-buffer
490 (insert "fire\nthunder\n")
491 (goto-char 1)
492 (anything-mp-2-search "h+ r" nil t)))
493 (expect nil
494 (with-temp-buffer
495 (insert "fire\nthunder\n")
496 (goto-char 1)
497 (anything-mp-2-search "th+ r" nil t)))
498 (desc "anything-mp-3-search")
499 (expect (non-nil)
500 (with-temp-buffer
501 (insert "fire\nthunder\n")
502 (goto-char 1)
503 (anything-mp-3-search "h+ r" nil t)))
504 (expect (non-nil)
505 (with-temp-buffer
506 (insert "fire\nthunder\n")
507 (goto-char 1)
508 (anything-mp-3-search "th+ r" nil t)))
509 (expect (non-nil)
510 (with-temp-buffer
511 (insert "fire\nthunder\n")
512 (goto-char 1)
513 (anything-mp-3-search "r th+" nil t)))
514 (expect nil
515 (with-temp-buffer
516 (insert "fire\nthunder\n")
517 (goto-char 1)
518 (anything-mp-3-search "under hue" nil t)))
519 (expect (non-nil)
520 (with-temp-buffer
521 (insert "fire\nthunder\n")
522 (goto-char 1)
523 (anything-mp-3-search "r th+ n" nil t)))
524 (desc "anything-mp-3-search")
525 (expect (non-nil)
526 (with-temp-buffer
527 (insert "fire\nthunder\n")
528 (goto-char 1)
529 (anything-mp-3-search "th der" nil t)))
530 (expect nil
531 (with-temp-buffer
532 (insert "fire\nthunder\n")
533 (goto-char 1)
534 (anything-mp-3-search "th ders" nil t)))
535 (desc "anything-mp-3-search not")
536 (expect t
537 (with-temp-buffer
538 (insert "threshold\nthunder\n")
539 (goto-char 1)
540 (anything-mp-3-search "h !der" nil t)))
541 (expect t
542 (with-temp-buffer
543 (insert "threshold\nthunder\n")
544 (goto-char 1)
545 (anything-mp-3-search "th !der" nil t)))
546 (desc "anything-mp-3p-search")
547 (expect (non-nil)
548 (with-temp-buffer
549 (insert "fire\nthunder\n")
550 (goto-char 1)
551 (anything-mp-3p-search "th der" nil t)))
552 (expect nil
553 (with-temp-buffer
554 (insert "fire\nthunder\n")
555 (goto-char 1)
556 (anything-mp-3p-search "h ders" nil t)))
557 (desc "anything-mp-3p-search not")
558 (expect t
559 (with-temp-buffer
560 (insert "\nthreshold\nthunder\n")
561 (goto-char 1)
562 (anything-mp-3p-search "th !der" nil t)))
563 (expect nil
564 (with-temp-buffer
565 (insert "threshold\nthunder\n")
566 (goto-char 1)
567 (anything-mp-3p-search "h !der" nil t)))
568 (desc "anything-mp-3-search-backward")
569 (expect (non-nil)
570 (with-temp-buffer
571 (insert "fire\nthunder\n")
572 (goto-char (point-max))
573 (anything-mp-3-search-backward "h der" nil t)))
574 (expect nil
575 (with-temp-buffer
576 (insert "fire\nthunder\n")
577 (goto-char (point-max))
578 (anything-mp-3-search-backward "th ders" nil t)))
579 (desc "anything-mp-3-search-backward not")
580 (expect t
581 (with-temp-buffer
582 (insert "threshold\nthunder\n")
583 (goto-char (point-max))
584 (anything-mp-3-search-backward "h !der" nil t)))
585 (expect t
586 (with-temp-buffer
587 (insert "threshold\nthunder\n")
588 (goto-char (point-max))
589 (anything-mp-3-search-backward "th !der" nil t)))
590 (desc "anything-mp-3p-search-backward")
591 (expect (non-nil)
592 (with-temp-buffer
593 (insert "fire\nthunder\n")
594 (goto-char (point-max))
595 (anything-mp-3p-search-backward "th der" nil t)))
596 (expect nil
597 (with-temp-buffer
598 (insert "fire\nthunder\n")
599 (goto-char (point-max))
600 (anything-mp-3p-search-backward "h der" nil t)))
601 (desc "anything-mp-3p-search-backward not")
602 (expect t
603 (with-temp-buffer
604 (insert "\nthreshold\nthunder\n")
605 (goto-char (point-max))
606 (anything-mp-3p-search-backward "th !der" nil t)))
607 (expect nil
608 (with-temp-buffer
609 (insert "threshold\nthunder\n")
610 (goto-char (point-max))
611 (anything-mp-3p-search-backward "h !der" nil t)))
612 (desc "anything-mp-1-match")
613 (expect (non-nil)
614 (anything-mp-1-match "thunder" "th+ r"))
615 (desc "anything-mp-2-match")
616 (expect (non-nil)
617 (anything-mp-2-match "thunder" "h+ r"))
618 (expect nil
619 (anything-mp-2-match "thunder" "th+ r"))
620 (desc "anything-mp-3-match")
621 (expect (non-nil)
622 (anything-mp-3-match "thunder" "h+ r"))
623 (expect (non-nil)
624 (anything-mp-3-match "thunder" "th+ r"))
625 (expect (non-nil)
626 (anything-mp-3-match "thunder" "r th+"))
627 (expect nil
628 (anything-mp-3-match "thunder" "under hue"))
629 (expect (non-nil)
630 (anything-mp-3-match "thunder" "r th+ n"))
631 (desc "anything-mp-3-match not")
632 (expect (non-nil)
633 (anything-mp-3-match "threshold" "th !der"))
634 (desc "anything-prefix-match")
635 (expect (non-nil)
636 (anything-prefix-match "fobar" "fo"))
637 (expect nil
638 (anything-prefix-match "xfobar" "fo"))
640 (desc "anything-mp-3-match")
641 (expect (non-nil)
642 (anything-mp-3-match "thunder" "h der"))
643 (expect nil
644 (anything-mp-3-match "thunder" "h ders"))
645 (desc "anything-mp-3p-match")
646 (expect (non-nil)
647 (anything-mp-3p-match "thunder" "th der"))
648 (expect nil
649 (anything-mp-3p-match "thunder" "h der"))
650 (desc "anything-mp-3p-match not")
651 (expect (non-nil)
652 (anything-mp-3p-match "threshold" "th !der"))
653 (expect nil
654 (anything-mp-3p-match "threshold" "h !der"))
655 (desc "with identity match")
656 (expect '(identity)
657 (assoc-default 'match
658 (car (anything-compile-sources
659 '(((name . "FOO")
660 (candidates-in-buffer)))
661 '(anything-compile-source--candidates-in-buffer
662 anything-compile-source--match-plugin)))))
663 (expect '(identity)
664 (assoc-default 'match
665 (car (anything-compile-sources
666 '(((name . "FOO")
667 (match identity)))
668 '(anything-compile-source--match-plugin)))))
669 (desc "functional")
670 (expect '(("FOO" ("thunder")))
671 (anything-test-candidates '(((name . "FOO")
672 (candidates "fire" "thunder")))
673 "th r"
674 '(anything-compile-source--match-plugin)))
675 (expect '(("FOO" ("one two")))
676 (let ((anything-mp-space-regexp "\\\\ "))
677 (anything-test-candidates '(((name . "FOO")
678 (candidates "one two" "three four")))
679 "e\\ t"
680 '(anything-compile-source--match-plugin))))
681 (expect '(("FOO" ("one two")))
682 (let ((anything-mp-space-regexp " "))
683 (anything-test-candidates '(((name . "FOO")
684 (candidates "one two" "three four")))
685 "e t"
686 '(anything-compile-source--match-plugin))))
687 (expect '(("FOO" ("thunder")))
688 (anything-test-candidates '(((name . "FOO")
689 (init
690 . (lambda ()
691 (with-current-buffer (anything-candidate-buffer 'global)
692 (insert "fire\nthunder\nthanks\n"))))
693 (candidates-in-buffer)))
694 "th r"
695 '(anything-compile-source--candidates-in-buffer
696 anything-compile-source--match-plugin)))
697 (expect '(("FOO" ("foo" "foobar")))
698 (anything-test-candidates '(((name . "FOO")
699 (candidates "foobar" "foo")))
700 "foo"
701 '(anything-compile-source--match-plugin)))
702 (expect '(("FOO" ("foo" "foobar")))
703 (anything-test-candidates '(((name . "FOO")
704 (init
705 . (lambda ()
706 (with-current-buffer (anything-candidate-buffer 'global)
707 (insert "foobar\nfoo\n"))))
708 (candidates-in-buffer)))
709 "foo"
710 '(anything-compile-source--candidates-in-buffer
711 anything-compile-source--match-plugin)))
712 (expect '(("FOO" ("foo")))
713 (anything-test-candidates '(((name . "FOO")
714 (init
715 . (lambda ()
716 (with-current-buffer (anything-candidate-buffer 'global)
717 (insert "foo\n"))))
718 (candidates-in-buffer)))
719 "foo"
720 '(anything-compile-source--candidates-in-buffer
721 anything-compile-source--match-plugin)))
722 (expect '(("FOO" ("foo")))
723 (anything-test-candidates '(((name . "FOO")
724 (init
725 . (lambda ()
726 (with-current-buffer (anything-candidate-buffer 'global)
727 (insert "bar\nfoo\ntest\n"))))
728 (candidates-in-buffer)))
729 "foo"
730 '(anything-compile-source--candidates-in-buffer
731 anything-compile-source--match-plugin)))
732 (expect '(("FOO" ("foobar" "foo")))
733 (anything-test-candidates '(((name . "FOO")
734 (init
735 . (lambda ()
736 (with-current-buffer (anything-candidate-buffer 'global)
737 (insert "foobar\nfoo\n"))))
738 (candidates-in-buffer)))
740 '(anything-compile-source--candidates-in-buffer
741 anything-compile-source--match-plugin)))
742 (expect '(("FOO" ("foo" "foobar")))
743 (anything-test-candidates '(((name . "FOO")
744 (init
745 . (lambda ()
746 (with-current-buffer (anything-candidate-buffer 'global)
747 (insert "foobar\nfoo\n"))))
748 (candidates-in-buffer)
749 (search-from-end)))
750 "foo"
751 '(anything-compile-source--candidates-in-buffer
752 anything-compile-source--match-plugin)))
753 (expect '(("FOO" ("elisp" "elp")))
754 (anything-test-candidates '(((name . "FOO")
755 (init
756 . (lambda ()
757 (with-current-buffer (anything-candidate-buffer 'global)
758 (insert "elp\nelisp\n"))))
759 (candidates-in-buffer)
760 (search-from-end)))
761 "el p"
762 '(anything-compile-source--candidates-in-buffer
763 anything-compile-source--match-plugin)))
764 (expect '(("FOO" ("elisp" )))
765 (anything-test-candidates '(((name . "FOO")
766 (init
767 . (lambda ()
768 (with-current-buffer (anything-candidate-buffer 'global)
769 (insert "elp\nelisp\n"))))
770 (candidates-in-buffer)
771 (search-from-end)))
772 "el+ isp"
773 '(anything-compile-source--candidates-in-buffer
774 anything-compile-source--match-plugin)))
775 ;; prefix multi -> multi
776 (expect '(("FOO" ("elisp-info" "info.el")))
777 (anything-test-candidates '(((name . "FOO")
778 (init
779 . (lambda ()
780 (with-current-buffer (anything-candidate-buffer 'global)
781 (insert "info.el\nelisp-info\n"))))
782 (candidates-in-buffer)
784 "el info"
785 '(anything-compile-source--candidates-in-buffer
786 anything-compile-source--match-plugin)))
787 ;; multi not
788 (expect '(("FOO" ("info.el")))
789 (anything-test-candidates '(((name . "FOO")
790 (init
791 . (lambda ()
792 (with-current-buffer (anything-candidate-buffer 'global)
793 (insert "info.el\nelisp-info\n"))))
794 (candidates-in-buffer)
796 "info !elisp"
797 '(anything-compile-source--candidates-in-buffer
798 anything-compile-source--match-plugin)))
800 ;; (anything-compile-sources '(((name . "test"))) anything-compile-source-functions)
801 (provide 'anything-match-plugin)
803 ;; How to save (DO NOT REMOVE!!)
804 ;; (emacswiki-post "anything-match-plugin.el")
805 ;;; anything-match-plugin.el ends here