root/dotfiles/emacs/oinume/.emacs.d/elisp/anything.el @ 30030

Revision 30030, 172.3 kB (checked in by oinume, 6 years ago)

anything.el updated

  • Property svn:executable set to *
Line 
1;;; anything.el --- open anything / QuickSilver-like candidate-selection framework
2;; $Id: anything.el,v 1.147 2009/02/02 20:51:41 rubikitch Exp $
3
4;; Copyright (C) 2007        Tamas Patrovics
5;;               2008, 2009  rubikitch <rubikitch@ruby-lang.org>
6
7;; Author: Tamas Patrovics
8;; Maintainer: rubikitch <rubikitch@ruby-lang.org>
9;; Keywords: files, frames, help, matching, outlines, processes, tools, convenience, anything
10;; URL: http://www.emacswiki.org/cgi-bin/wiki/download/anything.el
11;; Site: http://www.emacswiki.org/cgi-bin/emacs/Anything
12
13;; This file is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation; either version 2, or (at your option)
16;; any later version.
17
18;; This file is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
22;; GNU General Public License for more details.
23
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 the
26;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27;; Boston, MA 02110-1301, USA.
28
29;;; Commentary:
30
31;;
32;; Start with M-x anything, narrow the list by typing some pattern,
33;; select with up/down/pgup/pgdown, choose with enter, left/right
34;; moves between sources. With TAB actions can be selected if the
35;; selected candidate has more than one possible action.
36;;
37;; Note that anything.el provides only the framework and some example
38;; configurations for demonstration purposes. See anything-config.el
39;; for practical, polished, easy to use configurations which can be
40;; used to assemble a custom personalized configuration. And many
41;; other configurations are in the EmacsWiki.
42;;
43;; http://www.emacswiki.org/cgi-bin/wiki/download/anything-config.el
44;; http://www.emacswiki.org/cgi-bin/emacs/AnythingSources
45;;
46;; Maintainer's configuration is in the EmacsWiki. It would tell you
47;; many tips to write smart sources!
48;;
49;; http://www.emacswiki.org/cgi-bin/emacs/RubikitchAnythingConfiguration
50
51;; You can extend `anything' by writing plug-ins. As soon as
52;; `anything' is invoked, `anything-sources' is compiled into basic
53;; attributes, then compiled one is used during invocation.
54;;
55;; The oldest built-in plug-in is `type' attribute: appends
56;; appropriate element of `anything-type-attributes'. Second built-in
57;; plug-in is `candidates-in-buffer': selecting a line from candidates
58;; buffer.
59;;
60;; To write a plug-in:
61;; 1. Define a compiler: anything-compile-source--*
62;; 2. Add compier function to `anything-compile-source-functions'.
63;; 3. (optional) Write helper functions.
64;;
65;; Anything plug-ins are found in the EmacsWiki.
66;;
67;; http://www.emacswiki.org/cgi-bin/emacs/AnythingPlugins
68
69;; Tested on Emacs 22.
70;;
71;;
72;; Thanks to Vagn Johansen for ideas.
73;; Thanks to Stefan Kamphausen for fixes and XEmacs support.
74;; Thanks to Tassilo Horn for fixes.
75;; Thanks to Drew Adams for various fixes (frame, isearch, customization, etc.)
76;; Thanks to IMAKADO for candidates-in-buffer idea.
77;; Thanks to Tomohiro MATSUYAMA for multiline patch.
78;;
79
80;;; (@* "Index")
81
82;;  If you have library `linkd.el', load
83;;  `linkd.el' and turn on `linkd-mode' now.  It lets you easily
84;;  navigate around the sections  Linkd mode will
85;;  highlight this Index.  You can get `linkd.el' here:
86;;  http://www.emacswiki.org/cgi-bin/wiki/download/linkd.el
87;;
88
89
90;;; (@* "INCOMPATIBLE CHANGES")
91
92;; v1.114
93;;
94;;   `anything-attr' returns nil when the source attribute is defined
95;;   but the value of attribute is nil, eg. (volatile) cell. Use
96;;   `anything-attr-defined' when testing whether the attribute is
97;;   defined.
98
99;;; (@* "Tips")
100
101;;
102;; There are many `anything' applications, using `anything' for
103;; selecting candidate. In this case, if there is one candidate or no
104;; candidate, popping up *anything* buffer is irritating. If one
105;; candidate, you want to select it at once. If no candidate, you want
106;; to quit `anything'. Set `anything-execute-action-at-once-if-one'
107;; and `anything-quit-if-no-candidate' to non-nil to remedy it. Note
108;; that setting these variables GLOBALLY is bad idea because of
109;; delayed sources. These are meant to be let-binded.
110;; See anything-etags.el for example.
111;;
112;; [EVAL IT] (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/anything-etags.el")
113;;
114;; ex.
115;; (let ((anything-execute-action-at-once-if-one t)
116;;       (anything-quit-if-no-candidate (lambda () (message "No candidate"))))
117;;    (anything temporary-sources input))
118
119;;
120;; `set-frame-configuration' arises flickering. If you hate
121;; flickering, eval:
122;; (setq anything-save-configuration-functions
123;;    '(set-window-configuration . current-window-configuration))
124;; at the cost of restoring frame configuration (only window configuration).
125
126;;
127;; `anything-delete-current-selection' deletes the current line.
128;; It is useful when deleting a candidate in persistent action.
129;; eg. `kill-buffer'.
130;;
131;; [EVAL IT] (describe-function 'anything-delete-current-selection)
132
133;;
134;; `anything-attr' gets the attribute. `anything-attrset' sets the
135;; attribute. `anything-attr-defined' tests whether the attribute is
136;; defined. They handles source-local variables.
137;;
138;; [EVAL IT] (describe-function 'anything-attr)
139;; [EVAL IT] (describe-function 'anything-attrset)
140;; [EVAL IT] (describe-function 'anything-attr-defined)
141
142;;
143;; `anything-sources' accepts many attributes to make your life easier.
144;; Now `anything-sources' accepts a list of symbols.
145;;
146;; [EVAL IT] (describe-variable 'anything-sources)
147
148;;
149;; `anything' has optional arguments. Now you do not have to let-bind
150;; `anything-sources'.
151;;
152;; [EVAL IT] (describe-function 'anything)
153
154;;
155;; `anything-resume' resumes last `anything' session. Now you do not
156;; have to retype pattern.
157;;
158;; [EVAL IT] (describe-function 'anything-resume)
159
160;;
161;; `anything-execute-persistent-action' executes action without
162;; quitting `anything'. When popping up a buffer in other window by
163;; persistent action, you can scroll with `anything-scroll-other-window' and
164;; `anything-scroll-other-window-down'. See also `anything-sources' docstring.
165;;
166;; [EVAL IT] (describe-function 'anything-execute-persistent-action)
167;; [EVAL IT] (describe-variable 'anything-sources)
168
169;;
170;; `anything-select-2nd-action', `anything-select-3rd-action' and
171;; `anything-select-4th-action' select other than default action
172;; without pressing Tab.
173
174;;
175;; Using `anything-candidate-buffer' and the candidates-in-buffer
176;; attribute is much faster than traditional "candidates and match"
177;; way. And `anything-current-buffer-is-modified' avoids to
178;; recalculate candidates for unmodified buffer. See docstring of
179;; them.
180;;
181;; [EVAL IT] (describe-function 'anything-candidate-buffer)
182;; [EVAL IT] (describe-function 'anything-candidates-in-buffer)
183;; [EVAL IT] (describe-function 'anything-current-buffer-is-modified)
184
185;;
186;; `anything-current-buffer' and `anything-buffer-file-name' stores
187;; `(current-buffer)' and `buffer-file-name' in the buffer `anything'
188;; is invoked. Use them freely.
189;;
190;; [EVAL IT] (describe-variable 'anything-current-buffer)
191;; [EVAL IT] (describe-variable 'anything-buffer-file-name)
192
193;;
194;; `anything-completing-read' and `anything-read-file-name' are
195;; experimental implementation. If you are curious, type M-x
196;; anything-read-string-mode. It is a minor mode and toggles on/off.
197
198;;
199;; Use `anything-test-candidates' to test your handmade anything
200;; sources. It simulates contents of *anything* buffer with pseudo
201;; `anything-sources' and `anything-pattern', without side-effect. So
202;; you can unit-test your anything sources! Let's TDD!
203;;
204;; [EVAL IT] (describe-function 'anything-test-candidates)
205;;
206;; There are many unit-testing framework in Emacs Lisp. See the EmacsWiki.
207;; http://www.emacswiki.org/cgi-bin/emacs/UnitTesting
208;;
209;; There is an unit-test by Emacs Lisp Expectations at the tail of this file.
210;; http://www.emacswiki.org/cgi-bin/wiki/download/el-expectations.el
211;; http://www.emacswiki.org/cgi-bin/wiki/download/el-mock.el
212
213
214;; (@* "TODO")
215;;
216;;   - process status indication
217;;
218;;   - results from async sources should appear in the order they are
219;;     specified in anything-sources
220;;
221;;   - async sources doesn't honor digit-shortcut-count
222;;
223;;   - anything-candidate-number-limit can't be nil everywhere
224;;
225;;   - support multi line candidates
226
227;; (@* "HISTORY")
228;; $Log: anything.el,v $
229;; Revision 1.147  2009/02/02 20:51:41  rubikitch
230;; New `anything-sources' attribute: real-to-display
231;;
232;; Revision 1.146  2009/02/01 20:01:00  rubikitch
233;; Update Tips
234;;
235;; Revision 1.145  2009/02/01 19:45:53  rubikitch
236;; New variable: `anything-quit-if-no-candidate'
237;;
238;; Revision 1.144  2009/02/01 19:31:47  rubikitch
239;; fixed a typo
240;;
241;; Revision 1.143  2009/02/01 19:23:32  rubikitch
242;; New variable: `anything-execute-action-at-once-if-one'
243;;
244;; Revision 1.142  2009/02/01 19:12:34  rubikitch
245;; `anything-persistent-action-display-buffer': bug fix
246;;
247;; Revision 1.141  2009/02/01 18:25:25  rubikitch
248;; * fix docstring
249;; * New variable: `anything-selection-face'
250;;
251;; Revision 1.140  2009/01/16 16:36:25  rubikitch
252;; New variable: `anything-persistent-action-use-special-display'.
253;;
254;; Revision 1.139  2009/01/05 20:15:53  rubikitch
255;; Fixed a bug of anything action buffer.
256;; The action source should not be cached.
257;;
258;; Revision 1.138  2008/12/21 16:56:05  rubikitch
259;; Fixed an error when action attribute is a function symbol and press TAB,
260;;
261;; Revision 1.137  2008/12/20 19:38:47  rubikitch
262;; `anything-check-minibuffer-input-1': proper quit handling
263;; `anything-process-delayed-sources': ditto
264;;
265;; Revision 1.136  2008/10/27 17:41:27  rubikitch
266;; `anything-process-delayed-sources', `anything-check-minibuffer-input-1': quittable
267;;
268;; Revision 1.135  2008/10/27 17:04:25  rubikitch
269;; arranged source, added more linkd tags (no code change)
270;;
271;; Revision 1.134  2008/10/27 15:02:25  rubikitch
272;; New variable: `anything-save-configuration-functions'
273;; Delete variable: `anything-save-configuration-type'
274;;
275;; Revision 1.133  2008/10/27 11:16:13  rubikitch
276;; New variable: `anything-save-configuration-type'
277;;
278;; Revision 1.132  2008/10/26 22:34:59  rubikitch
279;; `anything-delete-current-selection' with multiline
280;;
281;; Revision 1.131  2008/10/26 21:44:43  rubikitch
282;; New command: `anything-delete-current-selection'
283;;
284;; Revision 1.130  2008/10/22 10:41:09  rubikitch
285;; `anything-insert-match': do not override 'anything-realvalue property
286;;
287;; Revision 1.129  2008/10/21 17:01:37  rubikitch
288;; `anything-resume' per buffer.
289;; `anything-last-sources': obsolete
290;;
291;; Revision 1.128  2008/10/20 06:27:54  rubikitch
292;; `anything-quick-update': new user option
293;;
294;; Revision 1.127  2008/10/20 05:47:49  rubikitch
295;; refactoring
296;;
297;; Revision 1.126  2008/10/20 03:47:58  rubikitch
298;; `anything-update': reversed order of delayed sources
299;;
300;; Revision 1.125  2008/10/19 00:29:54  rubikitch
301;; kill buffer-local candidate buffers when creating global candidate buffers.
302;;
303;; Revision 1.124  2008/10/18 13:04:20  rubikitch
304;; Remove tick entry from `anything-tick-hash' when killing a buffer.
305;;
306;; Revision 1.123  2008/10/18 10:23:36  rubikitch
307;; multiline patch by Tomohiro MATSUYAMA.
308;;
309;; Revision 1.122  2008/10/13 03:10:07  rubikitch
310;; `anything': do `anything-mark-current-line' when resuming
311;;
312;; Revision 1.121  2008/10/13 03:08:08  rubikitch
313;; always set `anything-current-position'
314;;
315;; Revision 1.120  2008/10/07 14:12:02  rubikitch
316;; `anything-execute-persistent-action': optional arg
317;;
318;; Revision 1.119  2008/10/06 06:43:29  rubikitch
319;; `anything-candidate-buffer': return nil when the buffer is dead
320;;
321;; Revision 1.118  2008/09/30 22:21:28  rubikitch
322;; New `anything-sources' attribute: accept-empty
323;; dummy: include accept-empty
324;;
325;; Revision 1.117  2008/09/30 21:59:10  rubikitch
326;; New function: `anything-buffer-is-modified'
327;;
328;; Revision 1.116  2008/09/22 11:27:29  rubikitch
329;; *** empty log message ***
330;;
331;; Revision 1.115  2008/09/20 20:21:11  rubikitch
332;; added linkd index. (no code change)
333;;
334;; Revision 1.114  2008/09/20 20:09:57  rubikitch
335;; INCOMPATIBLE CHANGES: `anything-attr'
336;; New functions: `anything-attrset', `anything-attr-defined'
337;;
338;; Revision 1.113  2008/09/14 15:15:32  rubikitch
339;; bugfix: volatile and match attribute / process and match attribute
340;;
341;; Revision 1.112  2008/09/12 01:57:17  rubikitch
342;; When resuming anything, reinitialize overlays.
343;;
344;; Revision 1.111  2008/09/10 22:53:11  rubikitch
345;; anything: bug fix of `anything-buffer'
346;; New macro: `anything-test-update'
347;;
348;; Revision 1.110  2008/09/10 22:17:11  rubikitch
349;; New `anything-sources' attribute: header-name
350;;
351;; Revision 1.109  2008/09/10 21:12:26  rubikitch
352;; New hook: `anything-after-action-hook'
353;;
354;; Revision 1.108  2008/09/06 06:07:56  rubikitch
355;; Extended `anything-set-sources' optional arguments.
356;;
357;; Revision 1.107  2008/09/05 03:14:35  rubikitch
358;; reimplement `anything-current-buffer-is-modified' in the right way
359;;
360;; Revision 1.106  2008/09/05 00:11:05  rubikitch
361;; Moved `anything-read-string-mode' and read functions to anything-complete.el.
362;;
363;; Revision 1.105  2008/09/04 12:45:06  rubikitch
364;; New hook: `anything-after-persistent-action-hook'
365;;
366;; Revision 1.104  2008/09/04 12:27:05  rubikitch
367;; `anything': prefixed optional arguments
368;;
369;; Revision 1.103  2008/09/04 09:16:28  rubikitch
370;; fixed a bug of `anything-read-file-name'.
371;;
372;; Revision 1.102  2008/09/03 11:25:19  rubikitch
373;; Extended `anything' optional arguments: buffer
374;;
375;; Revision 1.101  2008/09/03 11:15:13  rubikitch
376;; `anything': return nil when keybord-quitted
377;;
378;; Revision 1.100  2008/09/01 23:11:02  rubikitch
379;; bug fix of search-from-end
380;;
381;; Revision 1.99  2008/09/01 13:45:55  rubikitch
382;; bug fix of search-from-end
383;;
384;; Revision 1.98  2008/09/01 11:23:38  rubikitch
385;; New `anything-sources' attribute: search-from-end
386;;
387;; Revision 1.97  2008/09/01 00:44:34  rubikitch
388;; Make sure to display the other window when persistent action.
389;;
390;; Revision 1.96  2008/08/31 20:55:20  rubikitch
391;; define `buffer-modified-tick' for older emacs.
392;;
393;; Revision 1.95  2008/08/30 04:55:51  rubikitch
394;; fixed a bug of `anything-completing-read'
395;;
396;; Revision 1.94  2008/08/28 20:18:03  rubikitch
397;; added some tests
398;;
399;; Revision 1.93  2008/08/25 20:18:46  rubikitch
400;; `anything': set `anything-input' and `anything-pattern' before `anything-update'
401;;
402;; Revision 1.92  2008/08/24 22:38:46  rubikitch
403;; *** empty log message ***
404;;
405;; Revision 1.91  2008/08/24 21:34:35  rubikitch
406;; rewrite `with-anything-restore-variables'
407;;
408;; Revision 1.90  2008/08/24 20:33:02  rubikitch
409;; prevent the unit test from byte-compiled.
410;; macro bug fix.
411;;
412;; Revision 1.89  2008/08/24 08:35:27  rubikitch
413;; *** empty log message ***
414;;
415;; Revision 1.88  2008/08/24 08:22:19  rubikitch
416;; Rename `anything-candidates-buffer' -> `anything-candidate-buffer'
417;;
418;; Revision 1.87  2008/08/23 22:27:04  rubikitch
419;; New hook: `anything-cleanup-hook'
420;;
421;; Revision 1.86  2008/08/23 22:05:42  rubikitch
422;; `anything-original-source-filter' is removed.
423;; Now use `anything-restored-variables' and `with-anything-restore-variables'.
424;;
425;; Revision 1.85  2008/08/23 21:23:21  rubikitch
426;; inhibit-read-only = t in anything-buffer
427;;
428;; Revision 1.84  2008/08/23 21:18:33  rubikitch
429;; *** empty log message ***
430;;
431;; Revision 1.83  2008/08/23 20:44:20  rubikitch
432;; `anything-execute-persistent-action': display-to-real bug fix
433;;
434;; Revision 1.82  2008/08/23 20:19:12  rubikitch
435;; New `anything-sources' attribute: get-line
436;;
437;; Revision 1.81  2008/08/23 19:32:14  rubikitch
438;; `anything-attr': Return t in (attribute-name) case.
439;;
440;; Revision 1.80  2008/08/22 21:25:05  rubikitch
441;; anything-candidates-in-buffer-1:
442;; Open a line at the BOB to make use of `search-forward' for faster exact/prefix match.
443;; Of course, restore the buffer contents after search.
444;;
445;; Revision 1.79  2008/08/22 17:11:00  rubikitch
446;; New hook: `anything-before-initialize-hook', `anything-after-initialize-hook'
447;;
448;; Revision 1.78  2008/08/21 18:37:03  rubikitch
449;; Implemented dummy sources as plug-in.
450;;
451;; Revision 1.77  2008/08/21 17:40:40  rubikitch
452;; New function: `anything-set-sources'
453;;
454;; Revision 1.76  2008/08/21 12:25:02  rubikitch
455;; New variable: `anything-version'
456;;
457;; Revision 1.75  2008/08/21 12:13:46  rubikitch
458;; New variable: `anything-in-persistent-action'
459;;
460;; Revision 1.74  2008/08/21 10:34:22  rubikitch
461;; New function `anything-mklist'
462;;
463;; Revision 1.73  2008/08/21 09:41:38  rubikitch
464;; accept multiple init/cleanup functions so that plug-ins can add new function.
465;;
466;; Revision 1.72  2008/08/20 22:51:53  rubikitch
467;; New `anything-sources' attribute: candidate-number-limit
468;;
469;; Revision 1.71  2008/08/20 21:45:42  rubikitch
470;; added many tests.
471;;
472;; Revision 1.70  2008/08/20 18:51:45  rubikitch
473;; `anything-preselect' bug fix.
474;; refactoring.
475;;
476;; Revision 1.69  2008/08/20 17:57:51  rubikitch
477;; Extended `anything' optional arguments: preselect
478;;
479;; Revision 1.68  2008/08/20 16:39:07  rubikitch
480;; Nested `anything' invocation support, ie. `anything' can be invoked by anything action.
481;;
482;; (anything '(((name . "nested anything invocation test")
483;;              (candidates "anything-c-source-buffers" "anything-c-source-man-pages")
484;;              (display-to-real . intern)
485;;              (action . anything))))
486;;
487;; Revision 1.67  2008/08/20 00:08:28  rubikitch
488;; `anything-candidates-in-buffer-1': add code when pattern == ""
489;;
490;; Revision 1.66  2008/08/19 23:31:52  rubikitch
491;; Removed `anything-show-exact-match-first' because it should be provided as a plug-in.
492;;
493;; Revision 1.65  2008/08/19 23:18:47  rubikitch
494;; *** empty log message ***
495;;
496;; Revision 1.64  2008/08/19 23:15:43  rubikitch
497;; `anything-compute-matches': short-cut when match == '(identity)
498;;
499;; Revision 1.63  2008/08/19 23:06:42  rubikitch
500;; Use hash table to speed uniquify candidates.
501;;
502;; Revision 1.62  2008/08/19 22:40:57  rubikitch
503;; `anything-test-candidates': additional optonal argument
504;;
505;; Revision 1.61  2008/08/19 18:13:39  rubikitch
506;; search attribute: multiple search functions
507;;
508;; Revision 1.60  2008/08/19 15:07:39  rubikitch
509;; New function: `anything-attr'
510;;
511;; Revision 1.59  2008/08/19 15:01:59  rubikitch
512;; arranged code
513;; added unit tests
514;; update doc
515;;
516;; Revision 1.58  2008/08/19 13:40:52  rubikitch
517;; `anything-get-current-source': This function can be used in
518;;  init/candidates/action/candidate-transformer/filtered-candidate-transformer
519;;  display-to-real/cleanup function.
520;;
521;; Revision 1.57  2008/08/19 03:43:57  rubikitch
522;; `anything-process-delayed-sources': delay = anything-idle-delay - anything-input-idle-delay
523;;
524;; Revision 1.56  2008/08/18 06:37:51  rubikitch
525;; Make `anything-input-idle-delay' ineffective when the action list is shown.
526;;
527;; Revision 1.55  2008/08/18 06:35:00  rubikitch
528;; New variable: `anything-show-exact-match-first'
529;;
530;; Revision 1.54  2008/08/17 23:22:24  rubikitch
531;; *** empty log message ***
532;;
533;; Revision 1.53  2008/08/17 23:15:38  rubikitch
534;; bind `anything-source-name' when executing action to enable to use `anything-candidate-buffer' in action.
535;;
536;; Revision 1.52  2008/08/17 15:21:27  rubikitch
537;; `anything-test-candidates': accept a symbol for source
538;; New variable: `anything-input-idle-delay'
539;;
540;; Revision 1.51  2008/08/17 12:45:30  rubikitch
541;; (buffer-disable-undo) in anything-buffer
542;;
543;; Revision 1.50  2008/08/16 22:21:37  rubikitch
544;; `anything-saved-sources': removed
545;; `anything-action-buffer': action selection buffer
546;; `anything-select-action': toggle actions <=> candidates
547;;
548;; Revision 1.49  2008/08/16 19:46:11  rubikitch
549;; New function: `anything-action-list-is-shown'
550;;
551;; Revision 1.48  2008/08/16 17:03:02  rubikitch
552;; bugfix: cleanup
553;;
554;; Revision 1.47  2008/08/16 16:35:24  rubikitch
555;; silence byte compiler
556;;
557;; Revision 1.46  2008/08/16 14:51:27  rubikitch
558;; *** empty log message ***
559;;
560;; Revision 1.45  2008/08/16 11:27:59  rubikitch
561;; refactoring
562;;  `anything-aif': Anaphoric if.
563;;  `anything-compile-source-functions': make `anything-get-sources' customizable.
564;;
565;; Revision 1.44  2008/08/16 09:38:15  rubikitch
566;; *** empty log message ***
567;;
568;; Revision 1.43  2008/08/15 11:44:28  rubikitch
569;; `anything-read-string-mode': minor mode for `anything' version of read functions. (experimental)
570;;
571;; Revision 1.42  2008/08/15 11:03:20  rubikitch
572;; update docs
573;;
574;; Revision 1.41  2008/08/14 20:51:28  rubikitch
575;; New `anything-sources' attribute: cleanup
576;;
577;; Revision 1.40  2008/08/14 10:34:04  rubikitch
578;; `anything': SOURCES: accept symbols
579;;
580;; Revision 1.39  2008/08/10 22:46:01  rubikitch
581;; `anything-move-selection': avoid infinite loop
582;;
583;; Revision 1.38  2008/08/09 21:38:25  rubikitch
584;; `anything-read-file-name': experimental implementation.
585;;
586;; Revision 1.37  2008/08/09 17:54:25  rubikitch
587;; action test
588;;
589;; Revision 1.36  2008/08/09 17:13:00  rubikitch
590;; fixed test
591;;
592;; Revision 1.35  2008/08/09 10:43:08  rubikitch
593;; New `anything-sources' attribute: display-to-real
594;;
595;; Revision 1.34  2008/08/07 13:15:44  rubikitch
596;; New `anything-sources' attribute: search
597;;
598;; Revision 1.33  2008/08/05 23:14:20  rubikitch
599;; `anything-candidate-buffer': bugfix
600;;
601;; Revision 1.32  2008/08/05 21:42:15  rubikitch
602;; *** empty log message ***
603;;
604;; Revision 1.31  2008/08/05 21:06:23  rubikitch
605;; `anything-candidate-buffer': candidates buffer registration
606;;
607;; Revision 1.30  2008/08/05 19:46:36  rubikitch
608;; New `anything-sources' attribute: candidates-in-buffer
609;;
610;; Revision 1.29  2008/08/05 17:58:31  rubikitch
611;; *** empty log message ***
612;;
613;; Revision 1.28  2008/08/05 17:46:04  rubikitch
614;; memoized `anything-get-sources'
615;;
616;; Revision 1.27  2008/08/05 17:29:40  rubikitch
617;; update doc
618;;
619;; Revision 1.26  2008/08/05 08:35:45  rubikitch
620;; `anything-completing-read': accept obarray
621;;
622;; Revision 1.25  2008/08/05 07:26:17  rubikitch
623;; `anything-completing-read': guard from non-string return value
624;;
625;; Revision 1.24  2008/08/04 12:05:41  rubikitch
626;; Wrote Tips and some docstrings.
627;; `anything-candidate-buffer': buffer-local by default
628;;
629;; Revision 1.23  2008/08/04 05:29:46  rubikitch
630;; `anything-buffer-file-name': `buffer-file-name' when `anything' is invoked.
631;;
632;; Revision 1.22  2008/08/04 00:10:13  rubikitch
633;; `anything-candidate-buffer': new API
634;;
635;; Revision 1.21  2008/08/03 22:05:08  rubikitch
636;; `anything-candidate-buffer': Return a buffer containing candidates of current source.
637;;
638;; Revision 1.20  2008/08/03 20:47:56  rubikitch
639;; `anything-current-buffer-is-modified': modify checker
640;;
641;; Revision 1.19  2008/08/03 19:06:18  rubikitch
642;; `anything-candidates-in-buffer': use `with-current-buffer' instead.
643;;
644;; Revision 1.18  2008/08/03 05:55:01  rubikitch
645;; `anything-candidates-in-buffer': extract candidates in a buffer for speed.
646;;
647;; Revision 1.17  2008/08/02 21:31:29  rubikitch
648;; Extended `anything' optional arguments.
649;; `anything-completing-read': experimental implementation.
650;;
651;; Revision 1.16  2008/08/02 20:32:54  rubikitch
652;; Extended `anything' optional arguments.
653;;
654;; Revision 1.15  2008/08/02 16:53:40  rubikitch
655;; Fixed a small bug of `anything-test-candidates'.
656;;
657;; Revision 1.14  2008/08/02 16:48:29  rubikitch
658;; Refactored to testable code.
659;; Added many candidate tests with `anything-test-candidates'.
660;;
661;; Revision 1.13  2008/08/02 15:08:14  rubikitch
662;; *** empty log message ***
663;;
664;; Revision 1.12  2008/08/02 14:29:31  rubikitch
665;; `anything-sources' accepts symbols. (patched by Sugawara)
666;;
667;; Revision 1.11  2008/08/02 10:20:36  rubikitch
668;; `anything-resume' is usable with other (let-binded) `anything-sources'.
669;;
670;; Revision 1.10  2008/08/01 19:44:01  rubikitch
671;; `anything-resume': resurrect previously invoked `anything'.
672;;
673;; Revision 1.9  2008/07/30 15:44:49  rubikitch
674;; *** empty log message ***
675;;
676;; Revision 1.8  2008/07/30 15:38:51  rubikitch
677;; *** empty log message ***
678;;
679;; Revision 1.7  2008/07/30 15:21:48  rubikitch
680;; `anything-scroll-other-window', `anything-scroll-other-window-down':
681;; Scroll other window (for persistent action).
682;;
683;; Revision 1.6  2008/07/30 15:12:36  rubikitch
684;; *** empty log message ***
685;;
686;; Revision 1.5  2008/07/30 15:06:32  rubikitch
687;; `anything-select-2nd-action', `anything-select-3rd-action', `anything-select-4th-action':
688;; Select other than default action without pressing Tab.
689;;
690;; Revision 1.4  2008/07/30 14:58:27  rubikitch
691;; `anything-current-buffer': Store current buffer when `anything' is invoked.
692;; `anything-current-position': Restore position when keyboard-quitted.
693;;
694;; Revision 1.3  2008/07/30 14:38:04  rubikitch
695;; Implemented persistent action.
696;;
697;; Revision 1.2  2008/07/30 13:37:16  rubikitch
698;; Update doc.
699;;
700;; Revision 1.1  2008/07/30 13:22:06  rubikitch
701;; New maintainer.
702;;
703
704(defvar anything-version "$Id: anything.el,v 1.147 2009/02/02 20:51:41 rubikitch Exp $")
705(require 'cl)
706
707;; (@* "User Configuration")
708
709;; This is only an example. Customize it to your own taste!
710(defvar anything-sources `(((name . "Buffers")
711                            (candidates
712                             . (lambda ()
713                                 (remove-if (lambda (name)
714                                              (or (equal name anything-buffer)
715                                                  (eq ?\  (aref name 0))))
716                                            (mapcar 'buffer-name (buffer-list)))))
717                            (type . buffer))
718
719                           ((name . "File Name History")
720                            (candidates . file-name-history)
721                            (match (lambda (candidate)
722                                     ;; list basename matches first
723                                     (string-match
724                                      anything-pattern
725                                      (file-name-nondirectory candidate)))
726
727                                   (lambda (candidate)                                     
728                                     ;; and then directory part matches
729                                     (let ((dir (file-name-directory candidate)))
730                                       (if dir
731                                           (string-match anything-pattern dir)))))
732                            (type . file))
733
734                           ((name . "Files from Current Directory")
735                            (init . (lambda ()
736                                      (setq anything-default-directory
737                                            default-directory)))
738                            (candidates . (lambda ()
739                                            (directory-files
740                                             anything-default-directory)))
741                            (type . file))
742
743                           ((name . "Manual Pages")
744                            (candidates . ,(progn
745                                             ;; XEmacs doesn't have a woman :)
746                                             (declare (special woman-file-name
747                                                               woman-topic-all-completions))
748                                             (condition-case nil
749                                                 (progn
750                                                   (require 'woman)
751                                                   (woman-file-name "")
752                                                   (sort (mapcar 'car
753                                                                 woman-topic-all-completions)
754                                                         'string-lessp))
755                                               (error nil))))
756                            (action . (("Open Manual Page" . woman)))
757                            (requires-pattern . 2))
758
759                           ((name . "Complex Command History")
760                            (candidates . (lambda ()
761                                            (mapcar 'prin1-to-string
762                                                    command-history)))
763                            (action . (("Repeat Complex Command" .
764                                        (lambda (c)
765                                          (eval (read c))))))
766                            (delayed)))
767  "The source of candidates for anything.
768It accepts symbols:
769 (setq anything-sources (list anything-c-foo anything-c-bar))
770can be written as
771 (setq anything-sources '(anything-c-foo anything-c-bar))
772The latter is recommended because if you change anything-c-* variable,
773you do not have to update `anything-sources'.
774
775If you want to change `anything-sources' during `anything' invocation,
776use `anything-set-sources', never use `setq'.
777
778Attributes:
779
780- name (mandatory)
781
782  The name of the source. It is also the heading which appears
783  above the list of matches from the source. Must be unique.
784
785- header-name (optional)
786
787  A function returning the display string of the header. Its
788  argument is the name of the source. This attribute is useful to
789  add an additional information with the source name.
790
791- candidates (mandatory if candidates-in-buffer attribute is not provided)
792
793  Specifies how to retrieve candidates from the source. It can
794  either be a variable name, a function called with no parameters
795  or the actual list of candidates.
796
797  The list must be a list of strings, so it's the responsibility
798  of the source to convert candidates to strings if necessary.
799
800  If the candidates have to be retrieved asynchronously (for
801  example, by an external command which takes a while to run)
802  then the function should start the external command
803  asynchronously and return the associated process object.
804  Anything will take care of managing the process (receiving the
805  output from it, killing it if necessary, etc.). The process
806  should return candidates matching the current pattern (see
807  variable `anything-pattern'.)
808
809  Note that currently results from asynchronous sources appear
810  last in the anything buffer regardless of their position in
811  `anything-sources'.
812
813- action (mandatory if type attribute is not provided)
814
815  It is a list of (DISPLAY . FUNCTION) pairs or FUNCTION.
816  FUNCTION is called with one parameter: the selected candidate.
817
818  An action other than the default can be chosen from this list
819  of actions for the currently selected candidate (by default
820  with TAB). The DISPLAY string is shown in the completions
821  buffer and the FUNCTION is invoked when an action is
822  selected. The first action of the list is the default.
823
824- type (optional if action attribute is provided)
825
826  Indicates the type of the items the source returns.
827
828  Merge attributes not specified in the source itself from
829  `anything-type-attributes'.
830
831  This attribute is implemented by plug-in.
832
833- init (optional)
834
835  Function called with no parameters when anything is started. It
836  is useful for collecting current state information which can be
837  used to create the list of candidates later.
838
839  For example, if a source needs to work with the current
840  directory then it can store its value here, because later
841  anything does its job in the minibuffer and in the
842  `anything-buffer' and the current directory can be different
843  there.
844
845- match (optional)
846
847  List of functions called with one parameter: a candidate. The
848  function should return non-nil if the candidate matches the
849  current pattern (see variable `anything-pattern').
850
851  This attribute allows the source to override the default
852  pattern matching based on `string-match'. It can be used, for
853  example, to implement a source for file names and do the
854  pattern matching on the basename of files, since it's more
855  likely one is typing part of the basename when searching for a
856  file, instead of some string anywhere else in its path.
857
858  If the list contains more than one function then the list of
859  matching candidates from the source is constructed by appending
860  the results after invoking the first function on all the
861  potential candidates, then the next function, and so on. The
862  matching candidates supplied by the first function appear first
863  in the list of results and then results from the other
864  functions, respectively.
865
866  This attribute has no effect for asynchronous sources (see
867  attribute `candidates'), since they perform pattern matching
868  themselves.
869
870- candidate-transformer (optional)
871
872  It's a function called with one argument when the completion
873  list from the source is built. The argument is the list of
874  candidates retrieved from the source. The function should
875  return a transformed list of candidates which will be used for
876  the actual completion.
877
878  This can be used to transform or remove items from the list of
879  candidates.
880
881  The function can also substitute candidates in the returned
882  list with (DISPLAY . REAL) pairs. In this case the DISPLAY
883  string is shown in the Anything buffer, but the REAL one is
884  used as action argument when the candidate is selected. This
885  allows a more readable presentation for candidates which would
886  otherwise be, for example, too long or have a common part
887  shared with other candidates which can be safely replaced with
888  an abbreviated string for display purposes.
889
890  Note that if the (DISPLAY . REAL) form is used then pattern
891  matching is done on the displayed string, not on the real
892  value.
893
894- filtered-candidate-transformer (optional)
895
896  It has the same format as `candidate-transformer', except the
897  function is called with two parameters: the candidate list and
898  the source.
899
900  This transformer is run on the candidate list which is already
901  filtered by the current pattern. While `candidate-transformer'
902  is run only once, it is run every time the input pattern is
903  changed.
904
905  It can be used to transform the candidate list dynamically, for
906  example, based on the current pattern.
907
908  In some cases it may also be more efficent to perform candidate
909  transformation here, instead of with `candidate-transformer'
910  even if this transformation is done every time the pattern is
911  changed.  For example, if a candidate set is very large then
912  `candidate-transformer' transforms every candidate while only
913  some of them will actually be dislpayed due to the limit
914  imposed by `anything-candidate-number-limit'.
915
916  Note that `candidate-transformer' is run already, so the given
917  transformer function should also be able to handle candidates
918  with (DISPLAY . REAL) format.
919
920  This option has no effect for asynchronous sources. (Not yet,
921  at least.
922
923- action-transformer (optional)
924
925  It's a function called with two arguments when the action list
926  from the source is assembled. The first argument is the list of
927  actions, the second is the current selection.
928
929  The function should return a transformed action list.
930
931  This can be used to customize the list of actions based on the
932  currently selected candidate.
933
934- delayed (optional)
935
936  Candidates from the source are shown only if the user stops
937  typing and is idle for `anything-idle-delay' seconds.
938
939- volatile (optional)
940
941  Indicates the source assembles the candidate list dynamically,
942  so it shouldn't be cached within a single Anything
943  invocation. It is only applicable to synchronous sources,
944  because asynchronous sources are not cached.
945
946- requires-pattern (optional)
947
948  If present matches from the source are shown only if the
949  pattern is not empty. Optionally, it can have an integer
950  parameter specifying the required length of input which is
951  useful in case of sources with lots of candidates.
952
953- persistent-action (optional)
954
955  Function called with one parameter; the selected candidate.
956
957  An action performed by `anything-execute-persistent-action'.
958  If none, use the default action.
959
960- candidates-in-buffer (optional)
961
962  Shortcut attribute for making and narrowing candidates using
963  buffers.  This newly-introduced attribute prevents us from
964  forgetting to add volatile and match attributes.
965
966  See docstring of `anything-candidates-in-buffer'.
967
968  (candidates-in-buffer) is equivalent of three attributes:
969    (candidates . anything-candidates-in-buffer)
970    (volatile)
971    (match identity)
972
973  (candidates-in-buffer . candidates-function) is equivalent of:
974    (candidates . candidates-function)
975    (volatile)
976    (match identity)
977
978  This attribute is implemented by plug-in.
979
980- search (optional)
981
982  List of functions like `re-search-forward' or `search-forward'.
983  Buffer search function used by `anything-candidates-in-buffer'.
984  By default, `anything-candidates-in-buffer' uses `re-search-forward'.
985  This attribute is meant to be used with
986  (candidates . anything-candidates-in-buffer) or
987  (candidates-in-buffer) in short.
988
989- search-from-end (optional)
990
991  Make `anything-candidates-in-buffer' search from the end of buffer.
992  If this attribute is specified, `anything-candidates-in-buffer' uses
993  `re-search-backward' instead.
994
995- get-line (optional)
996
997  A function like `buffer-substring-no-properties' or `buffer-substring'.
998  This function converts point of line-beginning and point of line-end,
999  which represents a candidate computed by `anything-candidates-in-buffer'.
1000  By default, `anything-candidates-in-buffer' uses
1001  `buffer-substring-no-properties'.
1002
1003- display-to-real (optional)
1004
1005  Function called with one parameter; the selected candidate.
1006
1007  The function transforms the selected candidate, and the result
1008  is passed to the action function.  The display-to-real
1009  attribute provides another way to pass other string than one
1010  shown in Anything buffer.
1011
1012  Traditionally, it is possible to make candidates,
1013  candidate-transformer or filtered-candidate-transformer
1014  function return a list with (DISPLAY . REAL) pairs. But if REAL
1015  can be generated from DISPLAY, display-to-real is more
1016  convenient and faster.
1017
1018- real-to-display (optional)
1019
1020  Function called with one parameter; the selected candidate.
1021
1022  The inverse of display-to-real attribute.
1023
1024  The function transforms the selected candidate, which is passed
1025  to the action function, for display.  The real-to-display
1026  attribute provides the other way to pass other string than one
1027  shown in Anything buffer.
1028
1029  Traditionally, it is possible to make candidates,
1030  candidate-transformer or filtered-candidate-transformer
1031  function return a list with (DISPLAY . REAL) pairs. But if
1032  DISPLAY can be generated from REAL, real-to-display is more
1033  convenient and faster.
1034
1035- cleanup (optional)
1036
1037  Function called with no parameters when *anything* buffer is closed. It
1038  is useful for killing unneeded candidates buffer.
1039
1040  Note that the function is executed BEFORE performing action.
1041
1042- candidate-number-limit (optional)
1043
1044  Override `anything-candidate-number-limit' only for this source.
1045
1046- accept-empty (optional)
1047
1048  Pass empty string \"\" to action function.
1049
1050- dummy (optional)
1051
1052  Set `anything-pattern' to candidate. If this attribute is
1053  specified, The candidates attribute is ignored.
1054
1055  This attribute is implemented by plug-in.
1056
1057- multiline (optional)
1058
1059  Enable to selection multiline candidates.
1060")
1061
1062
1063;; This value is only provided as an example. Customize it to your own
1064;; taste!
1065(defvar anything-type-attributes
1066  '((file (action . (("Find File" . find-file)
1067                     ("Delete File" . (lambda (file)
1068                                        (if (y-or-n-p (format "Really delete file %s? "
1069                                                              file))
1070                                            (delete-file file)))))))
1071    (buffer (action . (("Switch to Buffer" . switch-to-buffer)
1072                       ("Pop to Buffer"    . pop-to-buffer)
1073                       ("Display Buffer"   . display-buffer)
1074                       ("Kill Buffer"      . kill-buffer)))))
1075  "It's a list of (TYPE ATTRIBUTES ...). ATTRIBUTES are the same
1076  as attributes for `anything-sources'. TYPE connects the value
1077  to the appropriate sources in `anything-sources'.
1078
1079  This allows specifying common attributes for several
1080  sources. For example, sources which provide files can specify
1081  common attributes with a `file' type.")
1082
1083
1084(defvar anything-enable-digit-shortcuts nil
1085  "*If t then the first nine matches can be selected using
1086  Ctrl+<number>.")
1087
1088
1089(defvar anything-candidate-number-limit 50
1090  "*Do not show more candidates than this limit from inidividual
1091  sources. It is usually pointless to show hundreds of matches
1092  when the pattern is empty, because it is much simpler to type a
1093  few characters to narrow down the list of potential candidates.
1094
1095  Set it to nil if you don't want this limit.")
1096
1097
1098(defvar anything-idle-delay 0.5
1099  "*The user has to be idle for this many seconds, before
1100  candidates from delayed sources are collected. This is useful
1101  for sources involving heavy operations (like launching external
1102  programs), so that candidates from the source are not retrieved
1103  unnecessarily if the user keeps typing.
1104
1105  It also can be used to declutter the results anything displays,
1106  so that results from certain sources are not shown with every
1107  character typed, only if the user hesitates a bit.")
1108
1109
1110(defvar anything-input-idle-delay nil
1111  "The user has to be idle for this many seconds, before ALL candidates are collected.
1112Unlink `anything-input-idle', it is also effective for non-delayed sources.
1113If nil, candidates are collected immediately. ")
1114
1115
1116(defvar anything-samewindow nil
1117  "If t then Anything doesn't pop up a new window, it uses the
1118current window to show the candidates.")
1119
1120
1121(defvar anything-source-filter nil
1122  "A list of source names to be displayed. Other sources won't
1123appear in the search results. If nil then there is no filtering.
1124See also `anything-set-source-filter'.")
1125
1126
1127(defvar anything-map
1128  (let ((map (copy-keymap minibuffer-local-map)))
1129    (define-key map (kbd "<down>") 'anything-next-line)
1130    (define-key map (kbd "<up>") 'anything-previous-line)
1131    (define-key map (kbd "<prior>") 'anything-previous-page)
1132    (define-key map (kbd "<next>") 'anything-next-page)
1133    (define-key map (kbd "<right>") 'anything-next-source)
1134    (define-key map (kbd "<left>") 'anything-previous-source)
1135    (define-key map (kbd "<RET>") 'anything-exit-minibuffer)
1136    (define-key map (kbd "C-1") 'anything-select-with-digit-shortcut)
1137    (define-key map (kbd "C-2") 'anything-select-with-digit-shortcut)
1138    (define-key map (kbd "C-3") 'anything-select-with-digit-shortcut)
1139    (define-key map (kbd "C-4") 'anything-select-with-digit-shortcut)
1140    (define-key map (kbd "C-5") 'anything-select-with-digit-shortcut)
1141    (define-key map (kbd "C-6") 'anything-select-with-digit-shortcut)
1142    (define-key map (kbd "C-7") 'anything-select-with-digit-shortcut)
1143    (define-key map (kbd "C-8") 'anything-select-with-digit-shortcut)
1144    (define-key map (kbd "C-9") 'anything-select-with-digit-shortcut)
1145    (define-key map (kbd "C-i") 'anything-select-action)
1146    ;; the defalias is needed because commands are bound by name when
1147    ;; using iswitchb, so only commands having the prefix anything-
1148    ;; get rebound
1149    (defalias 'anything-previous-history-element 'previous-history-element)
1150    ;; C-p is used instead of M-p, because anything uses ESC
1151    ;; (currently hardcoded) for `anything-iswitchb-cancel-anything' and
1152    ;; Emacs handles ESC and Meta as synonyms, so ESC overrides
1153    ;; other commands with Meta prefix.
1154    ;;
1155    ;; Note that iswitchb uses M-p and M-n by default for history
1156    ;; navigation, so you should bind C-p and C-n in
1157    ;; `iswitchb-mode-map' if you use the history keys and don't want
1158    ;; to use different keys for iswitchb while anything is not yet
1159    ;; kicked in. These keys are not bound automatically by anything
1160    ;; in `iswitchb-mode-map' because they (C-n at least) already have
1161    ;; a standard iswitchb binding which you might be accustomed to.
1162    (define-key map (kbd "C-p") 'anything-previous-history-element)
1163    (defalias 'anything-next-history-element 'next-history-element)
1164    (define-key map (kbd "C-n") 'anything-next-history-element)
1165    ;; Binding M-s is used instead of C-s, because C-s has a binding in
1166    ;; iswitchb.  You can rebind it, of course.
1167    (define-key map (kbd "M-s") 'anything-isearch)
1168    ;; unbind C-r to prevent problems during anything-isearch
1169    (define-key map (kbd "C-r") nil)
1170    map)
1171  "Keymap for anything.")
1172
1173
1174(defvar anything-isearch-map
1175  (let ((map (copy-keymap (current-global-map))))
1176    (define-key map (kbd "<return>") 'anything-isearch-default-action)
1177    (define-key map (kbd "C-i") 'anything-isearch-select-action)
1178    (define-key map (kbd "C-g") 'anything-isearch-cancel)
1179    (define-key map (kbd "M-s") 'anything-isearch-again)
1180    (define-key map (kbd "<backspace>") 'anything-isearch-delete)
1181    ;; add printing chars
1182    (let ((i 32))
1183      (while (< i 256)
1184        (define-key map (vector i) 'anything-isearch-printing-char)
1185        (setq i (1+ i))))
1186    map)
1187  "Keymap for anything incremental search.")
1188
1189
1190(defgroup anything nil
1191  "Open anything." :prefix "anything-" :group 'convenience)
1192
1193(if (facep 'header-line)
1194    (copy-face 'header-line 'anything-header)
1195 
1196  (defface anything-header
1197    '((t (:bold t :underline t)))
1198    "Face for header lines in the anything buffer." :group 'anything))
1199
1200(defvar anything-header-face 'anything-header
1201  "Face for header lines in the anything buffer.")
1202
1203(defface anything-isearch-match '((t (:background "Yellow")))
1204  "Face for isearch in the anything buffer." :group 'anything)
1205
1206(defvar anything-isearch-match-face 'anything-isearch-match
1207  "Face for matches during incremental search.")
1208
1209(defvar anything-selection-face 'highlight
1210  "Face for currently selected item.")
1211
1212(defvar anything-iswitchb-idle-delay 1
1213  "Show anything completions if the user is idle that many
1214  seconds after typing.")
1215
1216(defvar anything-iswitchb-dont-touch-iswithcb-keys nil
1217  "If t then those commands are not bound from `anything-map'
1218  under iswitchb which would override standard iswithcb keys.
1219
1220This allows an even more seamless integration with iswitchb for
1221those who prefer using iswitchb bindings even if the anything
1222completions buffer is popped up.
1223
1224Note that you can bind alternative keys for the same command in
1225`anything-map', so that you can use different keys for anything
1226under iswitchb. For example, I bind the character \ to
1227`anything-exit-minibuffer' which key is just above Enter on my
1228keyboard. This way I can switch buffers with Enter and choose
1229anything completions with \.")
1230
1231;;----------------------------------------------------------------------
1232
1233(defvar anything-buffer "*anything*"
1234  "Buffer showing completions.")
1235
1236(defvar anything-action-buffer "*anything action*"
1237  "Buffer showing actions.")
1238
1239(defvar anything-selection-overlay nil
1240  "Overlay used to highlight the currently selected item.")
1241
1242(defvar anything-isearch-overlay nil
1243  "Overlay used to highlight the current match during isearch.")
1244
1245(defvar anything-digit-overlays nil
1246  "Overlays for digit shortcuts. See `anything-enable-digit-shortcuts'.")
1247
1248(defvar anything-candidate-cache nil
1249  "Holds the available candidate withing a single anything invocation.")
1250
1251(defvar anything-pattern
1252  "The input pattern used to update the anything buffer.")
1253
1254(defvar anything-input
1255  "The input typed in the candidates panel.")
1256
1257(defvar anything-async-processes nil
1258  "List of information about asynchronous processes managed by anything.")
1259
1260(defvar anything-digit-shortcut-count 0
1261  "Number of digit shortcuts shown in the anything buffer.")
1262
1263(defvar anything-before-initialize-hook nil
1264  "Run before anything initialization.
1265This hook is run before init functions in `anything-sources'.")
1266
1267(defvar anything-after-initialize-hook nil
1268  "Run after anything initialization.
1269Global variables are initialized and the anything buffer is created.
1270But the anything buffer has no contents. ")
1271
1272(defvar anything-update-hook nil
1273  "Run after the anything buffer was updated according the new
1274  input pattern.")
1275
1276(defvar anything-cleanup-hook nil
1277  "Run after anything minibuffer is closed, IOW this hook is executed BEFORE performing action. ")
1278
1279(defvar anything-after-action-hook nil
1280  "Run after executing action.")
1281
1282(defvar anything-after-persistent-action-hook nil
1283  "Run after executing persistent action.")
1284
1285(defvar anything-restored-variables
1286  '( anything-candidate-number-limit
1287     anything-source-filter)
1288  "Variables which are restored after `anything' invocation.")
1289;; `anything-saved-sources' is removed
1290
1291(defvar anything-saved-selection nil
1292  "Saved value of the currently selected object when the action
1293  list is shown.")
1294
1295;; `anything-original-source-filter' is removed
1296
1297(defvar anything-candidate-separator
1298  "--------------------"
1299  "Candidates separator of `multiline' source.")
1300
1301(defvar anything-current-buffer nil
1302  "Current buffer when `anything' is invoked.")
1303
1304(defvar anything-buffer-file-name nil
1305  "`buffer-file-name' when `anything' is invoked.")
1306
1307(defvar anything-current-position nil
1308  "Cons of (point) and (window-start) when `anything' is invoked.
1309It is needed because restoring position when `anything' is keyboard-quitted.")
1310
1311(defvar anything-saved-action nil
1312  "Saved value of the currently selected action by key.")
1313
1314(defvar anything-last-sources nil
1315  "OBSOLETE!! Sources of previously invoked `anything'.")
1316
1317(defvar anything-saved-current-source nil
1318  "Saved value of the original (anything-get-current-source) when the action
1319  list is shown.")
1320
1321(defvar anything-compiled-sources nil
1322  "Compiled version of `anything-sources'. ")
1323
1324(defvar anything-in-persistent-action nil
1325  "Flag whether in persistent-action or not.")
1326
1327(defvar anything-quick-update nil
1328  "If non-nil, suppress displaying sources which are out of screen at first.
1329They are treated as delayed sources at this input.
1330This flag makes `anything' a bit faster with many sources.")
1331
1332(defvar anything-last-sources-local nil
1333  "Buffer local value of `anything-sources'.")
1334(defvar anything-last-buffer nil
1335  "`anything-buffer' of previously `anything' session.")
1336
1337(defvar anything-save-configuration-functions
1338  '(set-frame-configuration . current-frame-configuration)
1339  "If you hate flickering, set this variable to
1340 '(set-window-configuration . current-window-configuration)
1341")
1342
1343(defvar anything-persistent-action-use-special-display nil
1344  "If non-nil, use `special-display-function' in persistent action.")
1345
1346(defvar anything-execute-action-at-once-if-one nil
1347  "If non-nil and there is one candidate, execute the first action without selection.
1348It is useful for `anything' applications.")
1349
1350(defvar anything-quit-if-no-candidate nil
1351  "if non-nil and there is no candidate, do not display *anything* buffer and quit.
1352This variable accepts a function, which is executed if no candidate.
1353
1354It is useful for `anything' applications.")
1355
1356
1357(put 'anything 'timid-completion 'disabled)
1358
1359;; (@* "Internal Variables")
1360(defvar anything-test-candidate-list nil)
1361(defvar anything-test-mode nil)
1362(defvar anything-source-name nil)
1363(defvar anything-candidate-buffer-alist nil)
1364(defvar anything-check-minibuffer-input-timer nil)
1365(defvar anything-match-hash (make-hash-table :test 'equal))
1366(defvar anything-cib-hash (make-hash-table :test 'equal))
1367(defvar anything-tick-hash (make-hash-table :test 'equal))
1368
1369;; (@* "Programming Tools")
1370(defmacro anything-aif (test-form then-form &rest else-forms)
1371  "Anaphoric if. Temporary variable `it' is the result of test-form."
1372  `(let ((it ,test-form))
1373     (if it ,then-form ,@else-forms))) 
1374(put 'anything-aif 'lisp-indent-function 2)
1375
1376(defun anything-mklist (obj)
1377  "If OBJ is a list, return itself, otherwise make a list with one element."
1378  (if (listp obj) obj (list obj)))
1379
1380;; (@* "Anything API")
1381(defun anything-buffer-get ()
1382  "If *anything action* buffer is shown, return `anything-action-buffer', otherwise `anything-buffer'."
1383  (if (anything-action-window)
1384      anything-action-buffer
1385    anything-buffer))
1386
1387(defun anything-window ()
1388  "Window of `anything-buffer'."
1389  (get-buffer-window (anything-buffer-get) 'visible))
1390
1391(defun anything-action-window ()
1392  "Window of `anything-action-buffer'."
1393  (get-buffer-window anything-action-buffer 'visible))
1394
1395(defmacro with-anything-window (&rest body)
1396  `(let ((--tmpfunc-- (lambda () ,@body)))
1397     (if anything-test-mode
1398         (with-current-buffer (anything-buffer-get)
1399           (funcall --tmpfunc--))
1400       (with-selected-window (anything-window)
1401         (funcall --tmpfunc--)))))
1402(put 'with-anything-window 'lisp-indent-function 0)
1403
1404(defmacro with-anything-restore-variables(&rest body)
1405  "Restore variables specified by `anything-restored-variables' after executing BODY ."
1406  `(let ((--orig-vars (mapcar (lambda (v) (cons v (symbol-value v))) anything-restored-variables)))
1407     (unwind-protect (progn ,@body)
1408       (loop for (var . value) in --orig-vars
1409             do (set var value)))))
1410(put 'with-anything-restore-variables 'lisp-indent-function 0)
1411
1412(defun* anything-attr (attribute-name &optional (src (anything-get-current-source)))
1413  "Get the value of ATTRIBUTE-NAME of SRC (source).
1414if SRC is omitted, use current source.
1415It is useful to write your sources."
1416  (anything-aif (assq attribute-name src)
1417      (cdr it)))
1418
1419(defun* anything-attr-defined (attribute-name &optional (src (anything-get-current-source)))
1420  "Return non-nil if ATTRIBUTE-NAME of SRC (source)  is defined.
1421if SRC is omitted, use current source.
1422It is useful to write your sources."
1423  (and (assq attribute-name src) t))
1424
1425(defun* anything-attrset (attribute-name value &optional (src (anything-get-current-source)))
1426  "Set the value of ATTRIBUTE-NAME of SRC (source) to VALUE.
1427if SRC is omitted, use current source.
1428It is useful to write your sources."
1429  (anything-aif (assq attribute-name src)
1430      (setcdr it value)
1431    (setcdr src (cons (cons attribute-name value) (cdr src))))
1432  value)
1433
1434;; anything-set-source-filter
1435;;
1436;;   This function sets a filter for anything sources and it may be
1437;;   called while anything is running. It can be used to toggle
1438;;   displaying of sources dinamically. For example, additional keys
1439;;   can be bound into `anything-map' to display only the file-related
1440;;   results if there are too many matches from other sources and
1441;;   you're after files only:
1442;;
1443;;   Shift+F shows only file results from some sources:
1444;;
1445;;     (define-key anything-map "F" 'anything-my-show-files-only)
1446;;     
1447;;     (defun anything-my-show-files-only ()
1448;;       (interactive)
1449;;       (anything-set-source-filter '("File Name History"
1450;;                                     "Files from Current Directory")))
1451;;
1452;;   Shift+A shows all results:
1453;;
1454;;     (define-key anything-map "A" 'anything-my-show-all)
1455;;     
1456;;     (defun anything-my-show-all ()
1457;;       (interactive)
1458;;       (anything-set-source-filter nil))
1459;; 
1460;; 
1461;;   Note that you have to prefix the functions with anything- prefix,
1462;;   otherwise they won't be bound when Anything is used under
1463;;   Iswitchb. The -my- part is added to avoid collisions with
1464;;   existing Anything function names.
1465;; 
1466(defun anything-set-source-filter (sources)
1467  "Sets the value of `anything-source-filter' and updates the list of results."
1468  (setq anything-source-filter sources)
1469  (anything-update))
1470
1471(defun anything-set-sources (sources &optional no-init no-update)
1472  "Set `anything-sources' during `anything' invocation.
1473If NO-INIT is non-nil, skip executing init functions of SOURCES.
1474If NO-UPDATE is non-nil, skip executing `anything-update'."
1475  (setq anything-compiled-sources nil
1476        anything-sources sources)
1477  (unless no-init (anything-funcall-foreach 'init))
1478  (unless no-update (anything-update)))
1479
1480(defun anything-get-sources ()
1481  "Return compiled `anything-sources', which is memoized.
1482
1483Attributes:
1484
1485- type
1486  `anything-type-attributes' are merged in.
1487- candidates-buffer
1488  candidates, volatile and match attrubute are created.
1489"
1490  (cond
1491   ;; action
1492   ((anything-action-window)
1493    anything-sources)
1494   ;; memoized
1495   (anything-compiled-sources)
1496   ;; first time
1497   (t
1498    (setq anything-compiled-sources
1499          (anything-compile-sources anything-sources anything-compile-source-functions)))))
1500
1501(defun* anything-get-selection (&optional (buffer anything-buffer))
1502  "Return the currently selected item or nil."
1503  (unless (zerop (buffer-size (get-buffer buffer)))
1504    (with-current-buffer buffer
1505      (let ((selection
1506             (or (get-text-property (overlay-start
1507                                     anything-selection-overlay)
1508                                    'anything-realvalue)
1509                 (buffer-substring-no-properties
1510                  (overlay-start anything-selection-overlay)
1511                  (1- (overlay-end anything-selection-overlay))))))
1512        (unless (equal selection "")
1513          selection)))))
1514
1515(defun anything-get-action ()
1516  "Return the associated action for the selected candidate."
1517  (unless (zerop (buffer-size (get-buffer (anything-buffer-get))))
1518    (let* ((source (anything-get-current-source))
1519           (actions (assoc-default 'action source)))
1520
1521      (anything-aif (assoc-default 'action-transformer source)
1522          (funcall it actions (anything-get-selection))
1523        actions))))
1524
1525(defun anything-get-current-source ()
1526  "Return the source for the current selection / in init/candidates/action/candidate-transformer/filtered-candidate-transformer function."
1527  (declare (special source))
1528  ;; The name `anything-get-current-source' should be used in init function etc.
1529  (if (and (boundp 'anything-source-name) (stringp anything-source-name))
1530      source
1531    (with-current-buffer (anything-buffer-get)
1532      ;; This goto-char shouldn't be necessary, but point is moved to
1533      ;; point-min somewhere else which shouldn't happen.
1534      (goto-char (overlay-start anything-selection-overlay))
1535      (let* ((header-pos (anything-get-previous-header-pos))
1536             (source-name
1537              (save-excursion
1538                (assert header-pos)
1539                (goto-char header-pos)
1540                (buffer-substring-no-properties
1541                 (line-beginning-position) (line-end-position)))))
1542        (some (lambda (source)
1543                (if (equal (assoc-default 'name source)
1544                           source-name)
1545                    source))
1546              (anything-get-sources))))))
1547
1548(defun anything-buffer-is-modified (buffer)
1549  "Return non-nil when BUFFER is modified since `anything' was invoked."
1550  (let* ((b (get-buffer buffer))
1551         (key (concat (buffer-name b)
1552                     "/"
1553                     (anything-attr 'name)))
1554         (source-tick (or (gethash key anything-tick-hash) 0))
1555         (buffer-tick (buffer-chars-modified-tick b)))
1556    (prog1 (/= source-tick buffer-tick)
1557      (puthash key buffer-tick anything-tick-hash))))
1558(defun anything-current-buffer-is-modified ()
1559  "Return non-nil when `anything-current-buffer' is modified since `anything' was invoked."
1560  (anything-buffer-is-modified anything-current-buffer))
1561
1562;; (@* "Core: tools")
1563(defun anything-current-frame/window-configuration ()
1564  (funcall (cdr anything-save-configuration-functions)))
1565
1566(defun anything-set-frame/window-configuration (conf)
1567  (funcall (car anything-save-configuration-functions) conf))
1568
1569(defun anything-funcall-with-source (source func &rest args)
1570  (let ((anything-source-name (assoc-default 'name source)))
1571    (apply func args)))
1572
1573(defun anything-funcall-foreach (sym)
1574  "Call the sym function(s) for each source if any."
1575  (dolist (source (anything-get-sources))
1576    (when (symbolp source)
1577      (setq source (symbol-value source)))
1578    (anything-aif (assoc-default sym source)
1579        (dolist (func (if (functionp it) (list it) it))
1580          (anything-funcall-with-source source func)))))
1581
1582(defun anything-normalize-sources (sources)
1583  (cond ((and sources (symbolp sources)) (list sources))
1584        (sources)
1585        (t anything-sources))) 
1586
1587(defun anything-approximate-candidate-number ()
1588  "Approximate Number of candidates.
1589It is used to check if candidate number is 0 or 1."
1590  (with-current-buffer anything-buffer
1591    (1- (line-number-at-pos (1- (point-max))))))
1592
1593(defvar anything-quit nil)
1594(defmacro with-anything-quittable (&rest body)
1595  `(let (inhibit-quit)
1596     (condition-case v
1597         (progn ,@body)
1598       (quit (setq anything-quit t)
1599             (exit-minibuffer)
1600             (keyboard-quit)))))
1601(put 'with-anything-quittable 'lisp-indent-function 0)
1602
1603;; (@* "Core: entry point")
1604(defun anything (&optional any-sources any-input any-prompt any-resume any-preselect any-buffer)
1605  "Select anything. In Lisp program, some optional arguments can be used.
1606
1607Note that all the optional arguments are prefixed because of
1608dynamic scope problem, IOW argument variables may eat
1609already-bound variables. Yuck!
1610
1611- ANY-SOURCES
1612
1613  Temporary value of `anything-sources'. ANY-SOURCES accepts a
1614  symbol, interpreted as a variable of an anything source.
1615
1616- ANY-INPUT
1617
1618  Temporary value of `anything-pattern', ie. initial input of minibuffer.
1619
1620- ANY-PROMPT
1621
1622  Prompt other than \"pattern: \".
1623
1624- ANY-RESUME
1625
1626  Resurrect previously instance of `anything'. Skip the initialization.
1627
1628- ANY-PRESELECT
1629
1630  Initially selected candidate. Specified by exact candidate or a regexp.
1631
1632- ANY-BUFFER
1633
1634  `anything-buffer' instead of *anything*.
1635"
1636  ;; TODO more document
1637  (interactive)
1638  (condition-case v
1639      (with-anything-restore-variables
1640        (let ((frameconfig (anything-current-frame/window-configuration))
1641              ;; It is needed because `anything-source-name' is non-nil
1642              ;; when `anything' is invoked by action. Awful global scope.
1643              anything-source-name anything-in-persistent-action
1644              anything-quit
1645              (anything-buffer (or any-buffer anything-buffer))
1646              (anything-sources (anything-normalize-sources any-sources)))
1647         
1648          (add-hook 'post-command-hook 'anything-check-minibuffer-input)
1649
1650          (setq anything-current-position (cons (point) (window-start)))
1651          (if any-resume
1652              (anything-initialize-overlays (anything-buffer-get))
1653            (anything-initialize))
1654          (setq anything-last-buffer anything-buffer)
1655          (when any-input (setq anything-input any-input anything-pattern any-input))
1656          (if anything-samewindow
1657              (switch-to-buffer anything-buffer)
1658            (pop-to-buffer anything-buffer))                 
1659
1660          (unwind-protect
1661              (progn
1662                (if any-resume (anything-mark-current-line) (anything-update))
1663               
1664                (select-frame-set-input-focus (window-frame (minibuffer-window)))
1665                (anything-preselect any-preselect)
1666                (let ((ncandidate (anything-approximate-candidate-number))
1667                      (minibuffer-local-map anything-map))
1668                  (cond ((and anything-execute-action-at-once-if-one
1669                              (= ncandidate 1))
1670                         (ignore))
1671                        ((and anything-quit-if-no-candidate (= ncandidate 0))
1672                         (setq anything-quit t)
1673                         (and (functionp anything-quit-if-no-candidate)
1674                              (funcall anything-quit-if-no-candidate)))
1675                        (t
1676                         (read-string (or any-prompt "pattern: ")
1677                                      (if any-resume anything-pattern any-input))))))
1678            (anything-cleanup)
1679            (remove-hook 'post-command-hook 'anything-check-minibuffer-input)
1680            (anything-set-frame/window-configuration frameconfig))
1681          (unless anything-quit
1682            (unwind-protect
1683                (anything-execute-selection-action)
1684              (anything-aif (get-buffer anything-action-buffer)
1685                  (kill-buffer it))
1686              (run-hooks 'anything-after-action-hook)))))
1687    (quit
1688     (goto-char (car anything-current-position))
1689     (set-window-start (selected-window) (cdr anything-current-position))
1690     nil)))
1691
1692(defun* anything-resume (&optional (any-buffer anything-last-buffer))
1693  "Resurrect previously invoked `anything'."
1694  (interactive)
1695  (when current-prefix-arg
1696    (setq any-buffer
1697          (completing-read
1698           "Resume anything buffer: "
1699           (delq nil
1700                 (mapcar (lambda (b)
1701                           (when (buffer-local-value 'anything-last-sources-local b)
1702                             (list (buffer-name b)))) (buffer-list)))
1703           nil t nil nil anything-buffer)))
1704  (setq anything-compiled-sources nil)
1705  (anything
1706   (or (buffer-local-value 'anything-last-sources-local (get-buffer any-buffer))
1707       anything-last-sources anything-sources)
1708   nil nil t nil any-buffer))
1709
1710;; (@* "Core: initialize")
1711(defun anything-initialize ()
1712  "Initialize anything settings and set up the anything buffer."
1713  (run-hooks 'anything-before-initialize-hook)
1714  (setq anything-current-buffer (current-buffer))
1715  (setq anything-buffer-file-name buffer-file-name)
1716  (setq anything-compiled-sources nil)
1717  (setq anything-saved-current-source nil)
1718  ;; Call the init function for sources where appropriate
1719  (anything-funcall-foreach 'init)
1720
1721  (setq anything-pattern "")
1722  (setq anything-input "")
1723  (setq anything-candidate-cache nil)
1724  (setq anything-last-sources anything-sources)
1725
1726  (anything-create-anything-buffer)
1727  (run-hooks 'anything-after-initialize-hook))
1728
1729(defun anything-create-anything-buffer (&optional test-mode)
1730  "Create newly created `anything-buffer'.
1731If TEST-MODE is non-nil, clear `anything-candidate-cache'."
1732  (when test-mode
1733    (setq anything-candidate-cache nil))
1734  (with-current-buffer (get-buffer-create anything-buffer)
1735    (buffer-disable-undo)
1736    (erase-buffer)
1737    (set (make-local-variable  'inhibit-read-only) t)
1738    (set (make-local-variable 'anything-last-sources-local) anything-sources)
1739    (setq cursor-type nil)
1740    (setq mode-name "Anything"))
1741  (anything-initialize-overlays anything-buffer)
1742  (get-buffer anything-buffer))
1743
1744(defun anything-initialize-overlays (buffer)
1745  (if anything-selection-overlay
1746      ;; make sure the overlay belongs to the anything buffer if
1747      ;; it's newly created
1748      (move-overlay anything-selection-overlay (point-min) (point-min)
1749                    (get-buffer buffer))
1750
1751    (setq anything-selection-overlay
1752          (make-overlay (point-min) (point-min) (get-buffer buffer)))
1753    (overlay-put anything-selection-overlay 'face anything-selection-face))
1754
1755  (if anything-enable-digit-shortcuts
1756      (unless anything-digit-overlays
1757        (dotimes (i 9)
1758          (push (make-overlay (point-min) (point-min)
1759                              (get-buffer buffer))
1760                anything-digit-overlays)
1761          (overlay-put (car anything-digit-overlays)
1762                       'before-string (concat (int-to-string (1+ i)) " - ")))
1763        (setq anything-digit-overlays (nreverse anything-digit-overlays)))
1764
1765    (when anything-digit-overlays
1766      (dolist (overlay anything-digit-overlays)
1767        (delete-overlay overlay))
1768      (setq anything-digit-overlays nil))))
1769
1770;; (@* "Core: clean up")
1771(defun anything-cleanup ()
1772  "Clean up the mess."
1773  (with-current-buffer anything-buffer
1774    (setq cursor-type t))
1775  (bury-buffer anything-buffer)
1776  (anything-funcall-foreach 'cleanup)
1777  (anything-kill-async-processes)
1778  (run-hooks 'anything-cleanup-hook))
1779
1780;; (@* "Core: input handling")
1781(defun anything-check-minibuffer-input ()
1782  "Extract input string from the minibuffer and check if it needs
1783to be handled."
1784  (if (or (not anything-input-idle-delay) (anything-action-window))
1785      (anything-check-minibuffer-input-1)
1786    (if anything-check-minibuffer-input-timer
1787        (cancel-timer anything-check-minibuffer-input-timer))
1788    (setq anything-check-minibuffer-input-timer
1789          (run-with-idle-timer anything-input-idle-delay nil
1790                               'anything-check-minibuffer-input-1))))
1791
1792(defun anything-check-minibuffer-input-1 ()
1793  (let (inhibit-quit)
1794    (with-selected-window (minibuffer-window)
1795      (anything-check-new-input (minibuffer-contents)))))
1796
1797
1798(defun anything-check-minibuffer-input-1 ()
1799  (with-anything-quittable
1800    (with-selected-window (minibuffer-window)
1801      (anything-check-new-input (minibuffer-contents)))))
1802
1803(defun anything-check-new-input (input)
1804  "Check input string and update the anything buffer if
1805necessary."
1806  (unless (equal input anything-pattern)
1807    (setq anything-pattern input)
1808    (unless (anything-action-window)
1809      (setq anything-input anything-pattern))
1810    (anything-update)))
1811
1812;; (@* "Core: source compiler")
1813(defvar anything-compile-source-functions
1814  '(anything-compile-source--type anything-compile-source--dummy anything-compile-source--candidates-in-buffer)
1815  "Functions to compile elements of `anything-sources' (plug-in).")
1816(defvar anything-compile-source-functions-default anything-compile-source-functions
1817  "Plug-ins this file provides.")
1818(defun anything-compile-sources (sources funcs)
1819  "Compile sources (`anything-sources') with funcs (`anything-compile-source-functions').
1820Anything plug-ins are realized by this function."
1821  (mapcar
1822   (lambda (source)
1823     (loop with source = (if (listp source) source (symbol-value source))
1824           for f in funcs
1825           do (setq source (funcall f source))
1826           finally (return source)))
1827   sources)) 
1828
1829;; (@* "Core: all candidates")
1830(defun anything-get-candidates (source)
1831  "Retrieve and return the list of candidates from
1832SOURCE."
1833  (let* ((candidate-source (assoc-default 'candidates source))
1834         (candidates
1835          (if (functionp candidate-source)
1836                (anything-funcall-with-source source candidate-source)
1837            (if (listp candidate-source)
1838                candidate-source
1839              (if (and (symbolp candidate-source)
1840                       (boundp candidate-source))
1841                  (symbol-value candidate-source)
1842                (error (concat "Candidates must either be a function, "
1843                               " a variable or a list: %s")
1844                       candidate-source))))))
1845    (if (processp candidates)
1846        candidates
1847      (anything-transform-candidates candidates source))))
1848         
1849
1850(defun anything-transform-candidates (candidates source)
1851  "Transform CANDIDATES according to candidate transformers."
1852  (anything-aif (assoc-default 'candidate-transformer source)
1853      (anything-funcall-with-source source it candidates)
1854    candidates))
1855
1856
1857(defun anything-get-cached-candidates (source)
1858  "Return the cached value of candidates for SOURCE.
1859Cache the candidates if there is not yet a cached value."
1860  (let* ((name (assoc-default 'name source))
1861         (candidate-cache (assoc name anything-candidate-cache))
1862         candidates)
1863
1864    (if candidate-cache
1865        (setq candidates (cdr candidate-cache))
1866
1867      (setq candidates (anything-get-candidates source))
1868
1869      (if (processp candidates)
1870          (progn
1871            (push (cons candidates
1872                        (append source
1873                                (list (cons 'item-count 0)
1874                                      (cons 'incomplete-line ""))))
1875                  anything-async-processes)
1876            (set-process-filter candidates 'anything-output-filter)
1877            (setq candidates nil))
1878
1879        (unless (assoc 'volatile source)
1880          (setq candidate-cache (cons name candidates))
1881          (push candidate-cache anything-candidate-cache))))
1882
1883    candidates))
1884
1885;; (@* "Core: narrowing candidates")
1886(defun anything-candidate-number-limit (source)
1887  "`anything-candidate-number-limit' variable may be overridden by SOURCE."
1888  (or (assoc-default 'candidate-number-limit source)
1889      anything-candidate-number-limit
1890      99999999))
1891
1892(defun anything-compute-matches (source)
1893  "Compute matches from SOURCE according to its settings."
1894  (let ((functions (assoc-default 'match source))
1895        (limit (anything-candidate-number-limit source))
1896        matches)
1897    (cond ((or (equal anything-pattern "") (equal functions '(identity)))
1898           (setq matches (anything-get-cached-candidates source))
1899           (if (> (length matches) limit)
1900               (setq matches
1901                     (subseq matches 0 limit))))
1902          (t
1903           (condition-case nil
1904               (let ((item-count 0)
1905                     (cands (anything-get-cached-candidates source))
1906                     exit)
1907
1908                 (unless functions
1909                   (setq functions
1910                         (list (lambda (candidate)
1911                                 (string-match anything-pattern candidate)))))
1912
1913                 (clrhash anything-match-hash)
1914                 (dolist (function functions)
1915                   (let (newmatches)
1916                     (dolist (candidate cands)
1917                       (when (and (not (gethash candidate anything-match-hash))
1918                                  (funcall function (if (listp candidate)
1919                                                        (car candidate)
1920                                                      candidate)))
1921                         (puthash candidate t anything-match-hash)
1922                         (push candidate newmatches)
1923
1924                         (when limit
1925                           (incf item-count)
1926                           (when (= item-count limit)
1927                             (setq exit t)
1928                             (return)))))
1929
1930                     (setq matches (append matches (reverse newmatches)))
1931
1932                     (if exit
1933                         (return)))))
1934
1935             (invalid-regexp (setq matches nil)))))
1936
1937    (anything-aif (assoc-default 'filtered-candidate-transformer source)
1938        (setq matches
1939              (anything-funcall-with-source source it matches source)))
1940    matches))
1941
1942(defun anything-process-source (source)
1943  "Display matches from SOURCE according to its settings."
1944  (let ((matches (anything-compute-matches source)))
1945    (when matches
1946      (when anything-test-mode
1947          (setq anything-test-candidate-list
1948                `(,@anything-test-candidate-list
1949                  (,(assoc-default 'name source)
1950                   ,matches))))
1951      (let ((multiline (assoc 'multiline source))
1952            (real-to-display (assoc-default 'real-to-display source))
1953            (start (point))
1954            separate)
1955        (anything-insert-header-from-source source)
1956        (dolist (match matches)
1957          (when (and anything-enable-digit-shortcuts
1958                     (not (eq anything-digit-shortcut-count 9)))
1959            (move-overlay (nth anything-digit-shortcut-count
1960                               anything-digit-overlays)
1961                          (line-beginning-position)
1962                          (line-beginning-position))
1963            (incf anything-digit-shortcut-count))
1964
1965          (if (and multiline separate)
1966              (anything-insert-candidate-separator)
1967            (setq separate t))
1968          (anything-insert-match match 'insert real-to-display))
1969       
1970        (if multiline
1971            (put-text-property start (point) 'anything-multiline t))))))
1972
1973(defun anything-process-delayed-sources (delayed-sources)
1974  "Process delayed sources if the user is idle for
1975`anything-idle-delay' seconds."
1976  (with-anything-quittable
1977    (if (sit-for (if anything-input-idle-delay
1978                     (max 0 (- anything-idle-delay anything-input-idle-delay))
1979                   anything-idle-delay))
1980        (with-current-buffer anything-buffer       
1981          (save-excursion
1982            (goto-char (point-max))
1983            (dolist (source delayed-sources)
1984              (anything-process-source source))
1985
1986            (when (and (not (equal (buffer-size) 0))
1987                       ;; no selection yet
1988                       (= (overlay-start anything-selection-overlay)
1989                          (overlay-end anything-selection-overlay)))
1990              (goto-char (point-min))
1991              (run-hooks 'anything-update-hook)
1992              (anything-next-line)))
1993
1994          (anything-maybe-fit-frame)))))
1995
1996;; (@* "Core: *anything* buffer contents")
1997(defun anything-update ()
1998  "Update the list of matches in the anything buffer according to
1999the current pattern."
2000  (setq anything-digit-shortcut-count 0)
2001  (anything-kill-async-processes)
2002  (with-current-buffer (anything-buffer-get)
2003    (erase-buffer)
2004
2005    (if anything-enable-digit-shortcuts
2006        (dolist (overlay anything-digit-overlays)
2007          (delete-overlay overlay)))
2008
2009    (let (delayed-sources)
2010      (dolist (source (anything-get-sources))
2011        (when (and (or (not anything-source-filter)
2012                       (member (assoc-default 'name source) anything-source-filter))
2013                   (>= (length anything-pattern)
2014                       (anything-aif (assoc 'requires-pattern source)
2015                           (or (cdr it) 1)
2016                         0)))
2017          (if (or (assoc 'delayed source)
2018                  (and anything-quick-update
2019                       (< (window-height (get-buffer-window (current-buffer)))
2020                          (line-number-at-pos (point-max)))))
2021              (push source delayed-sources)
2022            (anything-process-source source))))
2023
2024      (goto-char (point-min))
2025      (run-hooks 'anything-update-hook)
2026      (anything-next-line)
2027
2028      (setq delayed-sources (nreverse delayed-sources))
2029      (if anything-test-mode
2030          (dolist (source delayed-sources)
2031            (anything-process-source source))
2032        (anything-maybe-fit-frame)
2033        (run-with-idle-timer (if (featurep 'xemacs)
2034                                 0.1
2035                               0)
2036                             nil
2037                             'anything-process-delayed-sources
2038                             delayed-sources)))))
2039
2040(defun anything-insert-match (match insert-function &optional real-to-display)
2041  "Insert MATCH into the anything buffer. If MATCH is a list then
2042insert the string inteneded to appear on the display and store
2043the real value in a text property."
2044   (let ((start (line-beginning-position (point)))
2045         (string (if (listp match) (car match) match))
2046         (realvalue (if (listp match) (cdr match) match)))
2047     (and (functionp real-to-display)
2048          (setq string (funcall real-to-display realvalue)))
2049     (funcall insert-function string)
2050     ;; Some sources with candidates-in-buffer have already added
2051     ;; 'anything-realvalue property when creating candidate buffer.
2052     (unless (get-text-property start 'anything-realvalue)
2053       (put-text-property start (line-end-position)
2054                          'anything-realvalue realvalue)))
2055  (funcall insert-function "\n"))
2056
2057(defun anything-insert-header-from-source (source)
2058  (let ((name (assoc-default 'name source)))
2059    (anything-insert-header name
2060                            (anything-aif (assoc-default 'header-name source)
2061                                (funcall it name)))))
2062
2063(defun anything-insert-header (name &optional display-string)
2064  "Insert header of source NAME into the anything buffer."
2065  (unless (bobp)
2066    (let ((start (point)))
2067      (insert "\n")
2068      (put-text-property start (point) 'anything-header-separator t)))
2069
2070  (let ((start (point)))
2071    (insert name)
2072    (put-text-property (line-beginning-position)
2073                       (line-end-position) 'anything-header t)
2074    (when display-string
2075      (overlay-put (make-overlay (line-beginning-position) (line-end-position))
2076                   'display display-string))
2077    (insert "\n")
2078    (put-text-property start (point) 'face anything-header-face)))
2079
2080
2081(defun anything-insert-candidate-separator ()
2082  "Insert separator of candidates into the anything buffer."
2083  (insert anything-candidate-separator)
2084  (put-text-property (line-beginning-position)
2085                     (line-end-position) 'anything-candidate-separator t)
2086  (insert "\n"))
2087
2088
2089
2090
2091;; (@* "Core: async process")
2092(defun anything-output-filter (process string)
2093  "Process output from PROCESS."
2094  (let* ((process-assoc (assoc process anything-async-processes))
2095         (process-info (cdr process-assoc))
2096         (insertion-marker (assoc-default 'insertion-marker process-info))
2097         (incomplete-line-info (assoc 'incomplete-line process-info))
2098         (item-count-info (assoc 'item-count process-info))
2099         (real-to-display (assoc-default 'real-to-display process-info)))
2100
2101    (with-current-buffer anything-buffer
2102      (save-excursion
2103        (if insertion-marker
2104            (goto-char insertion-marker)
2105       
2106          (goto-char (point-max))
2107          (anything-insert-header-from-source process-info)
2108          (setcdr process-assoc
2109                  (append process-info `((insertion-marker . ,(point-marker))))))
2110
2111        (let ((lines (split-string string "\n"))
2112              candidates)
2113          (while lines
2114            (if (not (cdr lines))
2115                ;; store last incomplete line until new output arrives
2116                (setcdr incomplete-line-info (car lines))
2117
2118              (if (cdr incomplete-line-info)
2119                  (progn
2120                    (push (concat (cdr incomplete-line-info) (car lines))
2121                          candidates)
2122                    (setcdr incomplete-line-info nil))
2123
2124              (push (car lines) candidates)))
2125                 
2126            (pop lines))
2127
2128          (setq candidates (reverse candidates))
2129          (dolist (candidate (anything-transform-candidates candidates process-info))
2130            (anything-insert-match candidate 'insert-before-markers real-to-display)
2131            (incf (cdr item-count-info))
2132            (when (>= (cdr item-count-info) anything-candidate-number-limit)
2133              (anything-kill-async-process process)
2134              (return)))))
2135
2136      (anything-maybe-fit-frame)
2137
2138      (run-hooks 'anything-update-hook)
2139
2140      (if (bobp)
2141          (anything-next-line)
2142
2143        (save-selected-window
2144          (select-window (get-buffer-window anything-buffer 'visible))
2145          (anything-mark-current-line))))))
2146
2147
2148(defun anything-kill-async-processes ()
2149  "Kill all known asynchronous processes according to
2150`anything-async-processes'."
2151    "Kill locate process."
2152    (dolist (process-info anything-async-processes)
2153      (anything-kill-async-process (car process-info)))
2154    (setq anything-async-processes nil))
2155
2156
2157(defun anything-kill-async-process (process)
2158  "Kill PROCESS and detach the associated functions."
2159  (set-process-filter process nil)
2160  (delete-process process))
2161 
2162
2163;; (@* "Core: action")
2164(defun anything-execute-selection-action (&optional selection action clear-saved-action display-to-real)
2165  "If a candidate was selected then perform the associated
2166action."
2167  (setq selection (or selection (anything-get-selection)))
2168  (setq action (or action
2169                   anything-saved-action
2170                   (if (get-buffer anything-action-buffer)
2171                       (anything-get-selection anything-action-buffer)
2172                     (anything-get-action))))
2173  (let ((source (or anything-saved-current-source (anything-get-current-source))))
2174    (if (and (not selection) (assoc 'accept-empty source))
2175        (setq selection ""))
2176    (setq display-to-real
2177          (or display-to-real (assoc-default 'display-to-real source)
2178              #'identity))
2179    (if (and (listp action)
2180             (not (functionp action)))  ; lambda
2181        ;;select the default action
2182        (setq action (cdar action)))
2183    (unless clear-saved-action (setq anything-saved-action nil))
2184    (if (and selection action)
2185        (anything-funcall-with-source
2186         source  action
2187         (anything-funcall-with-source source display-to-real selection)))))
2188
2189(defun anything-select-action ()
2190  "Select an action for the currently selected candidate.
2191If action buffer is selected, back to the anything buffer."
2192  (interactive)
2193  (cond ((get-buffer-window anything-action-buffer 'visible)
2194         (set-window-buffer (get-buffer-window anything-action-buffer) anything-buffer)
2195         (kill-buffer anything-action-buffer))
2196        (t
2197         (setq anything-saved-selection (anything-get-selection))
2198         (unless anything-saved-selection
2199           (error "Nothing is selected."))
2200         (setq anything-saved-current-source (anything-get-current-source))
2201         (let ((actions (anything-get-action)))
2202           (if (functionp actions)
2203               (message "Sole action: %s" actions)
2204             (with-current-buffer (get-buffer-create anything-action-buffer)
2205               (erase-buffer)
2206               (buffer-disable-undo)
2207               (set-window-buffer (get-buffer-window anything-buffer) anything-action-buffer)
2208               (set (make-local-variable 'anything-sources)
2209                    `(((name . "Actions")
2210                       (volatile)
2211                       (candidates . ,actions))))
2212               (set (make-local-variable 'anything-source-filter) nil)
2213               (set (make-local-variable 'anything-selection-overlay) nil)
2214               (set (make-local-variable 'anything-digit-overlays) nil)
2215               (anything-initialize-overlays anything-action-buffer))
2216             (with-selected-window (minibuffer-window)
2217               (delete-minibuffer-contents))
2218             (setq anything-pattern 'dummy) ; so that it differs from the
2219                                        ; previous one
2220           
2221             (anything-check-minibuffer-input))))))
2222
2223;; (@* "Core: selection")
2224(defun anything-previous-line ()
2225  "Move selection to the previous line."
2226  (interactive)
2227  (anything-move-selection 'line 'previous))
2228
2229(defun anything-next-line ()
2230  "Move selection to the next line."
2231  (interactive)
2232  (anything-move-selection 'line 'next))
2233
2234(defun anything-previous-page ()
2235  "Move selection back with a pageful."
2236  (interactive)
2237  (anything-move-selection 'page 'previous))
2238
2239(defun anything-next-page ()
2240  "Move selection forward with a pageful."
2241  (interactive)
2242  (anything-move-selection 'page 'next))
2243
2244
2245(defun anything-previous-source ()
2246  "Move selection to the previous source."
2247  (interactive)
2248  (anything-move-selection 'source 'previous))
2249
2250
2251(defun anything-next-source ()
2252  "Move selection to the next source."
2253  (interactive)
2254  (anything-move-selection 'source 'next))
2255
2256
2257(defun anything-move-selection (unit direction)
2258  "Move the selection marker to a new position determined by
2259UNIT and DIRECTION."
2260  (unless (or (zerop (buffer-size (get-buffer (anything-buffer-get))))
2261              (not (anything-window)))
2262    (with-anything-window
2263      (case unit
2264        (line (case direction
2265                (next (if (not (anything-pos-multiline-p))
2266                          (forward-line 1)
2267                        (let ((header-pos (anything-get-next-header-pos))
2268                              (candidate-pos (anything-get-next-candidate-separator-pos)))
2269                          (if (and candidate-pos
2270                                   (or (null header-pos)
2271                                       (< candidate-pos header-pos)))
2272                              (goto-char candidate-pos)
2273                            (if header-pos
2274                                (goto-char header-pos)))
2275                          (if candidate-pos
2276                              (forward-line 1)))))
2277               
2278                (previous (progn
2279                            (forward-line -1)
2280                            (when (anything-pos-multiline-p)
2281                              (if (or (anything-pos-header-line-p)
2282                                      (anything-pos-candidate-separator-p))
2283                                  (forward-line -1)
2284                                (forward-line 1))
2285                              (let ((header-pos (anything-get-previous-header-pos))
2286                                    (candidate-pos (anything-get-previous-candidate-separator-pos)))
2287                                (when header-pos
2288                                  (if (or (null candidate-pos) (< candidate-pos header-pos))
2289                                      (goto-char header-pos)
2290                                    (goto-char candidate-pos))
2291                                  (forward-line 1))))))
2292               
2293                (t (error "Invalid direction."))))
2294
2295        (page (case direction
2296                (next (condition-case nil
2297                          (scroll-up)
2298                        (end-of-buffer (goto-char (point-max)))))
2299                (previous (condition-case nil
2300                              (scroll-down)
2301                            (beginning-of-buffer (goto-char (point-min)))))
2302                (t (error "Invalid direction."))))
2303
2304        (source (case direction
2305                   (next (goto-char (or (anything-get-next-header-pos)
2306                                        (point-min))))
2307                   (previous (progn
2308                               (forward-line -1)
2309                               (if (bobp)
2310                                   (goto-char (point-max))
2311                                 (if (anything-pos-header-line-p)
2312                                     (forward-line -1)
2313                                   (forward-line 1)))
2314                               (goto-char (anything-get-previous-header-pos))
2315                               (forward-line 1)))
2316                   (t (error "Invalid direction."))))
2317
2318        (t (error "Invalid unit.")))
2319
2320      (while (and (not (bobp))
2321                  (or (anything-pos-header-line-p)
2322                      (anything-pos-candidate-separator-p)))
2323        (forward-line (if (and (eq direction 'previous)
2324                               (not (eq (line-beginning-position)
2325                                        (point-min))))
2326                          -1
2327                        1)))
2328      (if (bobp)
2329          (forward-line 1))
2330      (if (eobp)
2331          (forward-line -1))
2332
2333      (anything-mark-current-line))))
2334
2335
2336(defun anything-mark-current-line ()
2337  "Move selection overlay to current line."
2338  (move-overlay anything-selection-overlay
2339                (line-beginning-position)
2340                (if (anything-pos-multiline-p)
2341                    (let ((header-pos (anything-get-next-header-pos))
2342                          (candidate-pos (anything-get-next-candidate-separator-pos)))
2343                      (or (and (null header-pos) candidate-pos candidate-pos)
2344                          (and header-pos candidate-pos (< candidate-pos header-pos) candidate-pos)
2345                          header-pos
2346                          (point-max)))
2347                  (1+ (line-end-position)))))
2348
2349
2350(defun anything-select-with-digit-shortcut ()
2351  (interactive)
2352  (if anything-enable-digit-shortcuts
2353      (save-selected-window
2354        (select-window (anything-window))         
2355        (let* ((index (- (event-basic-type (elt (this-command-keys-vector) 0)) ?1))
2356               (overlay (nth index anything-digit-overlays)))
2357          (when (overlay-buffer overlay)
2358            (goto-char (overlay-start overlay))
2359            (anything-mark-current-line)
2360            (anything-exit-minibuffer))))))
2361
2362
2363(defun anything-exit-minibuffer ()
2364  "Select the current candidate by exiting the minibuffer."
2365  (interactive)
2366  (declare (special anything-iswitchb-candidate-selected))
2367  (setq anything-iswitchb-candidate-selected (anything-get-selection))
2368  (exit-minibuffer))
2369
2370
2371(defun anything-get-next-header-pos ()
2372  "Return the position of the next header from point."
2373  (next-single-property-change (point) 'anything-header))
2374
2375
2376(defun anything-get-previous-header-pos ()
2377  "Return the position of the previous header from point"
2378  (previous-single-property-change (point) 'anything-header))
2379
2380
2381(defun anything-pos-multiline-p ()
2382  "Return non-nil if the current position is in the multiline source region."
2383  (get-text-property (point) 'anything-multiline))
2384
2385
2386(defun anything-get-next-candidate-separator-pos ()
2387  "Return the position of the next candidate separator from point."
2388  (next-single-property-change (point) 'anything-candidate-separator))
2389
2390
2391(defun anything-get-previous-candidate-separator-pos ()
2392  "Return the position of the previous candidate separator from point."
2393  (previous-single-property-change (point) 'anything-candidate-separator))
2394
2395
2396(defun anything-pos-header-line-p ()
2397  "Return t if the current line is a header line."
2398  (or (get-text-property (line-beginning-position) 'anything-header)
2399      (get-text-property (line-beginning-position) 'anything-header-separator)))
2400
2401(defun anything-pos-candidate-separator-p ()
2402  "Return t if the current line is a candidate separator."
2403  (get-text-property (line-beginning-position) 'anything-candidate-separator))
2404
2405;; (@* "Core: misc")
2406(defun anything-kill-buffer-hook ()
2407  "Remove tick entry from `anything-tick-hash' when killing a buffer."
2408  (loop for key being the hash-keys in anything-tick-hash
2409        if (string-match (format "^%s/" (regexp-quote (buffer-name))) key)
2410        do (remhash key anything-tick-hash)))
2411(add-hook 'kill-buffer-hook 'anything-kill-buffer-hook)
2412
2413(defun anything-maybe-fit-frame ()
2414  "Fit anything frame to its buffer, and put it at top right of display.
2415 To inhibit fitting, set `fit-frame-inhibit-fitting-flag' to t.
2416 You can set user options `fit-frame-max-width-percent' and
2417 `fit-frame-max-height-percent' to control max frame size."
2418  (declare (warn (unresolved 0)))
2419  (when (and (require 'fit-frame nil t)
2420             (boundp 'fit-frame-inhibit-fitting-flag)
2421             (not fit-frame-inhibit-fitting-flag)
2422             (anything-window))
2423    (with-anything-window
2424      (fit-frame nil nil nil t)
2425      (modify-frame-parameters
2426       (selected-frame)
2427       `((left . ,(- (x-display-pixel-width) (+ (frame-pixel-width) 7)))
2428         (top . 0)))))) ; The (top . 0) shouldn't be necessary (Emacs bug).
2429
2430(defun anything-preselect (candidate-or-regexp)
2431  (when candidate-or-regexp
2432    (with-anything-window
2433      (goto-char (point-min))
2434      ;; go to first candidate of first source
2435      (forward-line 1)
2436      (let ((start (point)))
2437        (unless (or (re-search-forward (concat "^" (regexp-quote candidate-or-regexp) "$") nil t)
2438                (progn (goto-char start)
2439                       (re-search-forward candidate-or-regexp nil t)))
2440          (goto-char start))
2441        (anything-mark-current-line)))))
2442
2443(defun anything-delete-current-selection ()
2444  "Delete the currently selected item."
2445  (interactive)
2446  (with-anything-window
2447    (cond ((anything-pos-multiline-p)
2448           (anything-aif (anything-get-next-candidate-separator-pos)
2449               (delete-region (point-at-bol)
2450                              (1+ (progn (goto-char it) (point-at-eol))))
2451             ;; last candidate
2452             (goto-char (anything-get-previous-candidate-separator-pos))
2453             (delete-region (point-at-bol) (point-max)))
2454           (when (eobp)
2455             (goto-char (or (anything-get-previous-candidate-separator-pos)
2456                            (point-min)))
2457             (forward-line 1)))
2458          (t
2459           (delete-region (point-at-bol) (1+ (point-at-eol)))
2460           (when (eobp) (forward-line -1))))
2461    (anything-mark-current-line)))
2462
2463;; (@* "Built-in plug-in: type")
2464(defun anything-compile-source--type (source)
2465  (anything-aif (assoc-default 'type source)
2466      (append source (assoc-default it anything-type-attributes) nil)
2467    source))
2468
2469;; (@* "Built-in plug-in: dummy")
2470(defun anything-dummy-candidate (candidate source)
2471  ;; `source' is defined in filtered-candidate-transformer
2472  (list anything-pattern)) 
2473
2474(defun anything-compile-source--dummy (source)
2475  (if (assoc 'dummy source)
2476      (append '((candidates "dummy")
2477                (accept-empty)
2478                (match identity)
2479                (filtered-candidate-transformer . anything-dummy-candidate)
2480                (volatile))
2481              source)
2482    source))
2483
2484;; (@* "Built-in plug-in: candidates-in-buffer")
2485(defun anything-candidates-in-buffer ()
2486  "Get candidates from the candidates buffer according to `anything-pattern'.
2487
2488BUFFER is `anything-candidate-buffer' by default.  Each
2489candidate must be placed in one line.  This function is meant to
2490be used in candidates-in-buffer or candidates attribute of an
2491anything source.  Especially fast for many (1000+) candidates.
2492
2493eg.
2494 '((name . \"many files\")
2495   (init . (lambda () (with-current-buffer (anything-candidate-buffer 'local)
2496                        (insert-many-filenames))))
2497   (search re-search-forward)  ; optional
2498   (candidates-in-buffer)
2499   (type . file))
2500
2501+===============================================================+
2502| The new way of making and narrowing candidates: Using buffers |
2503+===============================================================+
2504
2505By default, `anything' makes candidates by evaluating the
2506candidates function, then narrows them by `string-match' for each
2507candidate.
2508
2509But this way is very slow for many candidates. The new way is
2510storing all candidates in a buffer and narrowing them by
2511`re-search-forward'. Search function is customizable by search
2512attribute. The important point is that buffer processing is MUCH
2513FASTER than string list processing and is the Emacs way.
2514
2515The init function writes all candidates to a newly-created
2516candidate buffer.  The candidates buffer is created or specified
2517by `anything-candidate-buffer'.  Candidates are stored in a line.
2518
2519The candidates function narrows all candidates, IOW creates a
2520subset of candidates dynamically. It is the task of
2521`anything-candidates-in-buffer'.  As long as
2522`anything-candidate-buffer' is used,`(candidates-in-buffer)' is
2523sufficient in most cases.
2524
2525Note that `(candidates-in-buffer)' is shortcut of three attributes:
2526  (candidates . anything-candidates-in-buffer)
2527  (volatile)
2528  (match identity)
2529And `(candidates-in-buffer . func)' is shortcut of three attributes:
2530  (candidates . func)
2531  (volatile)
2532  (match identity)
2533The expansion is performed in `anything-get-sources'.
2534
2535The candidates-in-buffer attribute implies the volatile attribute.
2536The volatile attribute is needed because `anything-candidates-in-buffer'
2537creates candidates dynamically and need to be called everytime
2538`anything-pattern' changes.
2539
2540Because `anything-candidates-in-buffer' plays the role of `match' attribute
2541function, specifying `(match identity)' makes the source slightly faster.
2542
2543To customize `anything-candidates-in-buffer' behavior, use search,
2544get-line and search-from-end attributes. See also `anything-sources' docstring.
2545"
2546  (declare (special source))
2547  (anything-candidates-in-buffer-1 (anything-candidate-buffer)
2548                                   anything-pattern
2549                                   (or (assoc-default 'get-line source)
2550                                       #'buffer-substring-no-properties)
2551                                   ;; use external variable `source'.
2552                                   (or (assoc-default 'search source)
2553                                       (if (assoc 'search-from-end source)
2554                                           '(re-search-backward)
2555                                         '(re-search-forward)))
2556                                   (anything-candidate-number-limit source)
2557                                   (assoc 'search-from-end source)))
2558
2559(defun* anything-candidates-in-buffer-1 (buffer &optional (pattern anything-pattern) (get-line-fn 'buffer-substring-no-properties) (search-fns '(re-search-forward)) (limit anything-candidate-number-limit) search-from-end)
2560  ;; buffer == nil when candidates buffer does not exist.
2561  (when buffer
2562    (with-current-buffer buffer
2563      (let ((start-point (if search-from-end (point-max) (point-min)))
2564            (next-line-fn (if search-from-end
2565                              (lambda (x) (goto-char (max (1- (point-at-bol)) 1)))
2566                            #'forward-line))
2567            (endp (if search-from-end #'bobp #'eobp)))
2568        (goto-char (1- start-point))
2569        (if (string= pattern "")
2570            (delq nil (loop until (funcall endp)
2571                                    for i from 1 to limit
2572                                    collecting (funcall get-line-fn (point-at-bol) (point-at-eol))
2573                                    do (funcall next-line-fn 1)))
2574                   
2575          (let ((i 1)
2576                (next-line-fn (if search-from-end
2577                                  (lambda (x) (goto-char (max (point-at-bol) 1)))
2578                                #'forward-line))
2579                buffer-read-only
2580                matches exit newmatches)
2581            (progn
2582              (goto-char (point-min))
2583              (insert "\n")
2584              (goto-char (point-max))
2585              (insert "\n")
2586              (setq start-point (if search-from-end (point-max) (point-min)))
2587              (clrhash anything-cib-hash)
2588              (unwind-protect
2589                  (dolist (searcher search-fns)
2590                    (goto-char start-point)
2591                    (setq newmatches nil)
2592                    (loop while (funcall searcher pattern nil t)
2593                          if (or (funcall endp) (< limit i))
2594                          do (setq exit t) (return)
2595                          else do
2596                          (let ((cand (funcall get-line-fn (point-at-bol) (point-at-eol))))
2597                            (unless (gethash cand anything-cib-hash)
2598                              (puthash cand t anything-cib-hash)
2599                              (incf i)
2600                              (push cand newmatches)))
2601                          (funcall next-line-fn 1))
2602                    (setq matches (append matches (nreverse newmatches)))
2603                    (if exit (return)))
2604                (goto-char (point-min))
2605                (delete-char 1)
2606                (goto-char (1- (point-max)))
2607                (delete-char 1)
2608                           
2609                (set-buffer-modified-p nil)))
2610            (delq nil matches)))))))
2611
2612
2613(defun anything-candidate-buffer (&optional create-or-buffer)
2614  "Register and return a buffer containing candidates of current source.
2615`anything-candidate-buffer' searches buffer-local candidates buffer first,
2616then global candidates buffer.
2617
2618Acceptable values of CREATE-OR-BUFFER:
2619
2620- nil (omit)
2621  Only return the candidates buffer.
2622- a buffer
2623  Register a buffer as a candidates buffer.
2624- 'global
2625  Create a new global candidates buffer,
2626  named \" *anything candidates:SOURCE*\".
2627- other non-nil value
2628  Create a new global candidates buffer,
2629  named \" *anything candidates:SOURCE*ANYTHING-CURRENT-BUFFER\".
2630"
2631  (let* ((gbufname (format " *anything candidates:%s*" anything-source-name))
2632         (lbufname (concat gbufname (buffer-name anything-current-buffer)))
2633         buf)
2634    (when create-or-buffer
2635      (if (bufferp create-or-buffer)
2636          (add-to-list 'anything-candidate-buffer-alist
2637                       (cons anything-source-name create-or-buffer))
2638        (when (eq create-or-buffer 'global)
2639          (loop for b in (buffer-list)
2640                if (string-match (format "^%s" (regexp-quote gbufname)) (buffer-name b))
2641                do (kill-buffer b)))
2642        (with-current-buffer
2643            (get-buffer-create (if (eq create-or-buffer 'global) gbufname lbufname))
2644          (buffer-disable-undo)
2645          (erase-buffer)
2646          (font-lock-mode -1))))
2647    (or (get-buffer lbufname)
2648        (get-buffer gbufname)
2649        (anything-aif (assoc-default anything-source-name anything-candidate-buffer-alist)
2650            (and (buffer-live-p it) it)))))
2651
2652(defun anything-compile-source--candidates-in-buffer (source)
2653  (anything-aif (assoc 'candidates-in-buffer source)
2654      (append source `((candidates . ,(or (cdr it) 'anything-candidates-in-buffer))
2655                       (volatile) (match identity)))
2656    source))
2657
2658;; (@* "Utility: select another action by key")
2659(defun anything-select-nth-action (n)
2660  "Select the nth action for the currently selected candidate."
2661  (setq anything-saved-selection (anything-get-selection))
2662  (unless anything-saved-selection
2663    (error "Nothing is selected."))
2664  (setq anything-saved-action (cdr (elt (anything-get-action) n)))
2665  (anything-exit-minibuffer))
2666
2667(defun anything-select-2nd-action ()
2668  "Select the 2nd action for the currently selected candidate."
2669  (interactive)
2670  (anything-select-nth-action 1))
2671
2672(defun anything-select-3rd-action ()
2673  "Select the 3rd action for the currently selected candidate."
2674  (interactive)
2675  (anything-select-nth-action 2))
2676
2677(defun anything-select-4th-action ()
2678  "Select the 4th action for the currently selected candidate."
2679  (interactive)
2680  (anything-select-nth-action 3))
2681
2682
2683;; (@* "Utility: Persistent Action")
2684(defun* anything-execute-persistent-action (&optional (attr 'persistent-action))
2685  "If a candidate is selected then perform the associated action without quitting anything."
2686  (interactive)
2687  (save-selected-window
2688    (select-window (get-buffer-window (anything-buffer-get)))
2689    (select-window (setq minibuffer-scroll-window
2690                         (if (one-window-p t) (split-window)
2691                           (next-window (selected-window) 1))))
2692    (let ((anything-in-persistent-action t))
2693      (with-anything-display-same-window
2694        (anything-execute-selection-action
2695         nil
2696         (or (assoc-default attr (anything-get-current-source))
2697             (anything-get-action))
2698         t)
2699        (run-hooks 'anything-after-persistent-action-hook)))))
2700
2701(defmacro with-anything-display-same-window (&rest body)
2702  "Make `pop-to-buffer' and `display-buffer' display in the same window."
2703  `(let ((display-buffer-function 'anything-persistent-action-display-buffer))
2704     ,@body))
2705(put 'with-anything-display-same-window 'lisp-indent-function 0)
2706
2707(defun anything-persistent-action-display-buffer (buf &optional not-this-window)
2708  "Make `pop-to-buffer' and `display-buffer' display in the same window in persistent action.
2709If `anything-persistent-action-use-special-display' is non-nil and
2710BUF is to be displayed by `special-display-function', use it.
2711Otherwise ignores `special-display-buffer-names' and `special-display-regexps'."
2712  (let* ((name (buffer-name buf))
2713         display-buffer-function pop-up-windows
2714         (same-window-regexps
2715          (unless (and anything-persistent-action-use-special-display
2716                       (or (member name
2717                                   (mapcar (lambda (x) (or (car-safe x) x)) special-display-buffer-names))
2718                           (remove-if-not
2719                            (lambda (x) (string-match (or (car-safe x) x) name))
2720                            special-display-regexps)))
2721            '("."))))
2722    (display-buffer buf not-this-window)))
2723
2724;; scroll-other-window(-down)? for persistent-action
2725(defun anything-scroll-other-window-base (command)
2726  (save-selected-window
2727    (other-window 2)
2728    (call-interactively command)))
2729
2730(defun anything-scroll-other-window ()
2731  "Scroll other window (not *Anything* window) upward."
2732  (interactive)
2733  (anything-scroll-other-window-base 'scroll-other-window))
2734(defun anything-scroll-other-window-down ()
2735  "Scroll other window (not *Anything* window) downward."
2736  (interactive)
2737  (anything-scroll-other-window-base 'scroll-other-window-down))
2738
2739;; (@* "Utility: Incremental search within results")
2740
2741(defvar anything-isearch-original-global-map nil
2742  "Original global map before Anything isearch is started.")
2743
2744(defvar anything-isearch-original-message-timeout nil
2745  "Original message timeout before Anything isearch is started.")
2746
2747(defvar anything-isearch-pattern nil
2748  "The current isearch pattern.")
2749
2750(defvar anything-isearch-message-suffix ""
2751  "Message suffix indicating the current state of the search.")
2752
2753(defvar anything-isearch-original-point nil
2754  "Original position of point before isearch is started.")
2755
2756(defvar anything-isearch-original-window nil
2757  "Original selected window before isearch is started.")
2758
2759(defvar anything-isearch-original-cursor-in-non-selected-windows nil
2760  "Original value of cursor-in-non-selected-windows before isearch is started.")
2761
2762(defvar anything-isearch-original-post-command-hook nil
2763  "Original value of post-command-hook before isearch is started.")
2764
2765(defvar anything-isearch-match-positions nil
2766  "Stack of positions of matches or non-matches.
2767
2768It's a list of plists with two properties: `event', the last user
2769 event, `start', the start position of the current match, and
2770 `pos', the position of point after that event.
2771
2772The value of `event' can be the following symbols: `char' if a
2773character was typed, `error' if a non-matching character was
2774typed, `search' if a forward search had to be done after a
2775character, and `search-again' if a search was done for the next
2776occurrence of the current pattern.")
2777
2778(defvar anything-isearch-match-start nil
2779  "Start position of the current match.")
2780
2781
2782(defun anything-isearch ()
2783  "Start incremental search within results."
2784  (interactive)
2785  (if (zerop (buffer-size (get-buffer (anything-buffer-get))))
2786      (message "There are no results.")
2787
2788    (setq anything-isearch-original-message-timeout minibuffer-message-timeout)
2789    (setq minibuffer-message-timeout nil)
2790
2791    (setq anything-isearch-original-global-map global-map)
2792
2793    (condition-case nil
2794        (progn
2795          (setq anything-isearch-original-window (selected-window))
2796          (select-window (anything-window))
2797          (setq cursor-type t)
2798
2799          (setq anything-isearch-original-post-command-hook
2800                (default-value 'post-command-hook))
2801          (setq-default post-command-hook nil)
2802          (add-hook 'post-command-hook 'anything-isearch-post-command)
2803
2804          (use-global-map anything-isearch-map)
2805          (setq overriding-terminal-local-map anything-isearch-map)
2806
2807          (setq anything-isearch-pattern "")
2808
2809          (setq anything-isearch-original-cursor-in-non-selected-windows
2810                cursor-in-non-selected-windows)
2811          (setq cursor-in-non-selected-windows nil)
2812
2813          (setq anything-isearch-original-point (point-marker))
2814          (goto-char (point-min))
2815          (forward-line)
2816          (anything-mark-current-line)
2817
2818          (setq anything-isearch-match-positions nil)
2819          (setq anything-isearch-match-start (point-marker))
2820
2821          (if anything-isearch-overlay
2822              ;; make sure the overlay belongs to the anything buffer
2823              (move-overlay anything-isearch-overlay (point-min) (point-min)
2824                            (get-buffer (anything-buffer-get)))
2825
2826            (setq anything-isearch-overlay (make-overlay (point-min) (point-min)))
2827            (overlay-put anything-isearch-overlay 'face anything-isearch-match-face))
2828
2829          (setq anything-isearch-message-suffix
2830                (substitute-command-keys "cancel with \\[anything-isearch-cancel]")))
2831
2832      (error (anything-isearch-cleanup)))))
2833
2834
2835(defun anything-isearch-post-command ()
2836  "Print the current pattern after every command."
2837  (anything-isearch-message)
2838  (when (anything-window)
2839    (with-anything-window
2840      (move-overlay anything-isearch-overlay anything-isearch-match-start (point)
2841                    (get-buffer (anything-buffer-get))))))
2842
2843
2844(defun anything-isearch-printing-char ()
2845  "Add printing char to the pattern."
2846  (interactive)
2847  (let ((char (char-to-string last-command-char)))
2848    (setq anything-isearch-pattern (concat anything-isearch-pattern char))
2849
2850    (with-anything-window
2851      (if (looking-at char)
2852          (progn
2853            (push (list 'event 'char
2854                        'start anything-isearch-match-start
2855                        'pos (point-marker))
2856                  anything-isearch-match-positions)
2857            (forward-char))
2858
2859        (let ((start (point)))
2860          (while (and (re-search-forward anything-isearch-pattern nil t)
2861                      (anything-pos-header-line-p)))
2862          (if (or (anything-pos-header-line-p)
2863                  (eq start (point)))
2864              (progn
2865                (goto-char start)
2866                (push (list 'event 'error
2867                            'start anything-isearch-match-start
2868                            'pos (point-marker))
2869                      anything-isearch-match-positions))
2870
2871            (push (list 'event 'search
2872                        'start anything-isearch-match-start
2873                        'pos (copy-marker start))
2874                  anything-isearch-match-positions)
2875            (setq anything-isearch-match-start (copy-marker (match-beginning 0))))))
2876 
2877      (anything-mark-current-line))))
2878
2879
2880(defun anything-isearch-again ()
2881  "Search again for the current pattern"
2882  (interactive)
2883  (if (equal anything-isearch-pattern "")
2884      (setq anything-isearch-message-suffix "no pattern yet")
2885
2886    (with-anything-window
2887      (let ((start (point)))
2888        (while (and (re-search-forward anything-isearch-pattern nil t)
2889                    (anything-pos-header-line-p)))
2890        (if (or (anything-pos-header-line-p)
2891                (eq start (point)))
2892            (progn
2893              (goto-char start)
2894              (unless (eq 'error (plist-get (car anything-isearch-match-positions)
2895                                            'event))
2896                (setq anything-isearch-message-suffix "no more matches")))
2897
2898          (push (list 'event 'search-again
2899                      'start anything-isearch-match-start
2900                      'pos (copy-marker start))
2901                anything-isearch-match-positions)
2902          (setq anything-isearch-match-start (copy-marker (match-beginning 0)))
2903
2904          (anything-mark-current-line))))))
2905
2906
2907(defun anything-isearch-delete ()
2908  "Undo last event."
2909  (interactive)
2910  (unless (equal anything-isearch-pattern "")
2911    (let ((last (pop anything-isearch-match-positions)))
2912      (unless (eq 'search-again (plist-get last 'event))
2913        (setq anything-isearch-pattern
2914              (substring anything-isearch-pattern 0 -1)))
2915
2916      (with-anything-window     
2917        (goto-char (plist-get last 'pos))
2918        (setq anything-isearch-match-start (plist-get last 'start))
2919        (anything-mark-current-line)))))
2920
2921
2922(defun anything-isearch-default-action ()
2923  "Execute the default action for the selected candidate."
2924  (interactive)
2925  (anything-isearch-cleanup)
2926  (with-current-buffer (anything-buffer-get) (anything-exit-minibuffer)))
2927
2928
2929(defun anything-isearch-select-action ()
2930  "Choose an action for the selected candidate."
2931  (interactive)
2932  (anything-isearch-cleanup)
2933  (with-anything-window
2934    (anything-select-action)))
2935
2936
2937(defun anything-isearch-cancel ()
2938  "Cancel Anything isearch."
2939  (interactive)
2940  (anything-isearch-cleanup)
2941  (when (anything-window)
2942    (with-anything-window
2943      (goto-char anything-isearch-original-point)
2944      (anything-mark-current-line))))
2945
2946
2947(defun anything-isearch-cleanup ()
2948  "Clean up the mess."
2949  (setq minibuffer-message-timeout anything-isearch-original-message-timeout)
2950  (with-current-buffer (anything-buffer-get)
2951    (setq overriding-terminal-local-map nil)
2952    (setq cursor-type nil)
2953    (setq cursor-in-non-selected-windows
2954          anything-isearch-original-cursor-in-non-selected-windows))
2955  (when anything-isearch-original-window
2956    (select-window anything-isearch-original-window))
2957
2958  (use-global-map anything-isearch-original-global-map)
2959  (setq-default post-command-hook anything-isearch-original-post-command-hook)
2960  (when (overlayp anything-isearch-overlay)
2961    (delete-overlay anything-isearch-overlay)))
2962
2963
2964(defun anything-isearch-message ()
2965  "Print prompt."
2966  (if (and (equal anything-isearch-message-suffix "")
2967           (eq (plist-get (car anything-isearch-match-positions) 'event)
2968               'error))
2969      (setq anything-isearch-message-suffix "failing"))
2970
2971  (unless (equal anything-isearch-message-suffix "")
2972    (setq anything-isearch-message-suffix
2973          (concat " [" anything-isearch-message-suffix "]")))
2974
2975  (message (concat "Search within results: "
2976                   anything-isearch-pattern
2977                   anything-isearch-message-suffix))
2978
2979  (setq anything-isearch-message-suffix ""))
2980
2981
2982;; (@* "Utility: Iswitchb integration")
2983
2984(defvar anything-iswitchb-candidate-selected nil
2985  "Indicates whether an anything candidate is selected from iswitchb.")
2986
2987(defvar anything-iswitchb-frame-configuration nil
2988  "Saved frame configuration, before anything buffer was displayed.")
2989
2990(defvar anything-iswitchb-saved-keys nil
2991  "The original in iswitchb before binding anything keys.")
2992
2993
2994(defun anything-iswitchb-setup ()
2995  "Integrate anything completion into iswitchb.
2996
2997If the user is idle for `anything-iswitchb-idle-delay' seconds
2998after typing something into iswitchb then anything candidates are
2999shown for the current iswitchb input.
3000
3001ESC cancels anything completion and returns to normal iswitchb."
3002  (interactive)
3003
3004  (require 'iswitchb)
3005
3006  ;; disable timid completion during iswitchb
3007  (put 'iswitchb-buffer 'timid-completion 'disabled)
3008  (add-hook 'minibuffer-setup-hook  'anything-iswitchb-minibuffer-setup)
3009
3010  (defadvice iswitchb-visit-buffer
3011    (around anything-iswitchb-visit-buffer activate)
3012    (if anything-iswitchb-candidate-selected
3013        (anything-execute-selection-action)
3014      ad-do-it))
3015
3016  (defadvice iswitchb-possible-new-buffer
3017    (around anything-iswitchb-possible-new-buffer activate)
3018    (if anything-iswitchb-candidate-selected
3019        (anything-execute-selection-action)
3020      ad-do-it))
3021
3022  (message "Iswitchb integration is activated."))
3023
3024
3025(defun anything-iswitchb-minibuffer-setup ()
3026  (when (eq this-command 'iswitchb-buffer)
3027    (add-hook 'minibuffer-exit-hook  'anything-iswitchb-minibuffer-exit)
3028
3029    (setq anything-iswitchb-frame-configuration nil)
3030    (setq anything-iswitchb-candidate-selected nil)
3031    (add-hook 'anything-update-hook 'anything-iswitchb-handle-update)
3032
3033    (anything-initialize)
3034   
3035    (add-hook 'post-command-hook 'anything-iswitchb-check-input)))
3036
3037
3038(defun anything-iswitchb-minibuffer-exit ()
3039  (remove-hook 'minibuffer-exit-hook  'anything-iswitchb-minibuffer-exit)
3040  (remove-hook 'post-command-hook 'anything-iswitchb-check-input)
3041  (remove-hook 'anything-update-hook 'anything-iswitchb-handle-update)
3042
3043  (anything-cleanup)
3044
3045  (when anything-iswitchb-frame-configuration
3046    (anything-set-frame/window-configuration anything-iswitchb-frame-configuration)
3047    (setq anything-iswitchb-frame-configuration nil)))
3048
3049
3050(defun anything-iswitchb-check-input ()
3051  "Extract iswitchb input and check if it needs to be handled."
3052  (declare (special iswitchb-text))
3053  (if (or anything-iswitchb-frame-configuration
3054          (sit-for anything-iswitchb-idle-delay))
3055      (anything-check-new-input iswitchb-text)))
3056
3057
3058(defun anything-iswitchb-handle-update ()
3059  "Pop up the anything buffer if it's not empty and it's not
3060shown yet and bind anything commands in iswitchb."
3061  (unless (or (equal (buffer-size (get-buffer anything-buffer)) 0)
3062              anything-iswitchb-frame-configuration)
3063    (setq anything-iswitchb-frame-configuration (anything-current-frame/window-configuration))
3064
3065    (save-selected-window
3066      (if (not anything-samewindow)
3067          (pop-to-buffer anything-buffer)
3068
3069        (select-window (get-lru-window))
3070        (switch-to-buffer anything-buffer)))
3071
3072    (with-current-buffer (window-buffer (active-minibuffer-window))
3073      (let* ((anything-prefix "anything-")
3074             (prefix-length (length anything-prefix))
3075             (commands
3076              (delete-dups
3077               (remove-if 'null
3078                          (mapcar
3079                           (lambda (binding)
3080                             (let ((command (cdr binding)))
3081                               (when (and (symbolp command)
3082                                          (eq (compare-strings
3083                                               anything-prefix
3084                                               0 prefix-length
3085                                               (symbol-name command)
3086                                               0 prefix-length)
3087                                              t))
3088                                 command)))
3089                           (cdr anything-map)))))
3090             (bindings (mapcar (lambda (command)
3091                                 (cons command
3092                                       (where-is-internal command anything-map)))
3093                               commands)))
3094
3095        (push (list 'anything-iswitchb-cancel-anything (kbd "<ESC>"))
3096              bindings)
3097
3098        (setq anything-iswitchb-saved-keys nil)
3099
3100      (let* ((iswitchb-prefix "iswitchb-")
3101             (prefix-length (length iswitchb-prefix)))
3102        (dolist (binding bindings)
3103          (dolist (key (cdr binding))
3104            (let ((old-command (lookup-key (current-local-map) key)))
3105              (unless (and anything-iswitchb-dont-touch-iswithcb-keys
3106                           (symbolp old-command)
3107                           (eq (compare-strings iswitchb-prefix
3108                                                0 prefix-length
3109                                                (symbol-name old-command)
3110                                                0 prefix-length)
3111                               t))
3112                (push (cons key old-command)
3113                      anything-iswitchb-saved-keys)
3114                (define-key (current-local-map) key (car binding)))))))))))
3115
3116
3117(defun anything-iswitchb-cancel-anything ()
3118  "Cancel anything completion and return to standard iswitchb."
3119  (interactive)
3120  (save-excursion
3121    (dolist (binding anything-iswitchb-saved-keys)
3122      (define-key (current-local-map) (car binding) (cdr binding)))
3123    (anything-iswitchb-minibuffer-exit)))
3124
3125;; (@* "Compatibility")
3126
3127;; Copied assoc-default from XEmacs version 21.5.12
3128(unless (fboundp 'assoc-default)
3129  (defun assoc-default (key alist &optional test default)
3130    "Find object KEY in a pseudo-alist ALIST.
3131ALIST is a list of conses or objects.  Each element (or the element's car,
3132if it is a cons) is compared with KEY by evaluating (TEST (car elt) KEY).
3133If that is non-nil, the element matches;
3134then `assoc-default' returns the element's cdr, if it is a cons,
3135or DEFAULT if the element is not a cons.
3136
3137If no element matches, the value is nil.
3138If TEST is omitted or nil, `equal' is used."
3139    (let (found (tail alist) value)
3140      (while (and tail (not found))
3141        (let ((elt (car tail)))
3142          (when (funcall (or test 'equal) (if (consp elt) (car elt) elt) key)
3143            (setq found t value (if (consp elt) (cdr elt) default))))
3144        (setq tail (cdr tail)))
3145      value)))
3146
3147;; Function not available in XEmacs,
3148(unless (fboundp 'minibuffer-contents)
3149  (defun minibuffer-contents ()
3150    "Return the user input in a minbuffer as a string.
3151The current buffer must be a minibuffer."
3152    (field-string (point-max)))
3153
3154  (defun delete-minibuffer-contents  ()
3155    "Delete all user input in a minibuffer.
3156The current buffer must be a minibuffer."
3157    (delete-field (point-max))))
3158
3159;; Function not available in older Emacs (<= 22.1).
3160(unless (fboundp 'buffer-chars-modified-tick)
3161  (defun buffer-chars-modified-tick (&optional buffer)
3162    "Return BUFFER's character-change tick counter.
3163Each buffer has a character-change tick counter, which is set to the
3164value of the buffer's tick counter (see `buffer-modified-tick'), each
3165time text in that buffer is inserted or deleted.  By comparing the
3166values returned by two individual calls of `buffer-chars-modified-tick',
3167you can tell whether a character change occurred in that buffer in
3168between these calls.  No argument or nil as argument means use current
3169buffer as BUFFER."
3170    (with-current-buffer (or buffer (current-buffer))
3171      (if (listp buffer-undo-list)
3172          (length buffer-undo-list)
3173        (buffer-modified-tick)))))
3174
3175
3176;; (@* "Unit Tests")
3177
3178(defun* anything-test-candidates (sources &optional (input "") (compile-source-functions anything-compile-source-functions-default))
3179  "Test helper function for anything.
3180Given pseudo `anything-sources' and `anything-pattern', returns list like
3181  ((\"source name1\" (\"candidate1\" \"candidate2\"))
3182   (\"source name2\" (\"candidate3\" \"candidate4\")))
3183"
3184  (let ((anything-test-mode t)
3185        anything-enable-digit-shortcuts
3186        anything-candidate-cache
3187        (anything-sources (anything-normalize-sources sources))
3188        (anything-compile-source-functions compile-source-functions)
3189        anything-before-initialize-hook
3190        anything-after-initialize-hook
3191        anything-update-hook
3192        anything-test-candidate-list)
3193    (get-buffer-create anything-buffer)
3194
3195    (anything-initialize)
3196    (setq anything-input input anything-pattern input)
3197    (anything-update)
3198    ;; test-mode spec: select 1st candidate!
3199    (with-current-buffer anything-buffer
3200      (forward-line 1)
3201      (anything-mark-current-line))
3202    (prog1
3203        anything-test-candidate-list
3204      (anything-cleanup))))
3205
3206(defmacro anything-test-update (sources pattern)
3207  "Test helper macro for anything. It is meant for testing *anything* buffer contents."
3208  `(progn (stub anything-get-sources => ,sources)
3209          (stub run-hooks => nil)
3210          (stub anything-maybe-fit-frame => nil)
3211          (stub run-with-idle-timer => nil)
3212          (let (anything-test-mode (anything-pattern ,pattern))
3213            (anything-update))))
3214
3215;;;; unit test
3216;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-expectations.el")
3217;; (install-elisp "http://www.emacswiki.org/cgi-bin/wiki/download/el-mock.el")
3218(dont-compile
3219  (when (fboundp 'expectations)
3220    (expectations
3221      (desc "anything-current-buffer")
3222      (expect "__a_buffer"
3223        (with-current-buffer (get-buffer-create "__a_buffer")
3224          (anything-test-candidates '(((name . "FOO"))) "")
3225          (prog1
3226              (buffer-name anything-current-buffer)
3227            (kill-buffer "__a_buffer")
3228            )))
3229      (desc "anything-buffer-file-name")
3230      (expect (regexp "/__a_file__")
3231        (with-current-buffer (get-buffer-create "__a_file__")
3232          (setq buffer-file-name "/__a_file__")
3233          (anything-test-candidates '(((name . "FOO"))) "")
3234          (prog1
3235              anything-buffer-file-name
3236            ;;(kill-buffer "__a_file__")
3237            )))
3238      (desc "anything-compile-sources")
3239      (expect '(((name . "foo")))
3240        (anything-compile-sources '(((name . "foo"))) nil)
3241        )
3242      (expect '(((name . "foo") (type . test) (action . identity)))
3243        (let ((anything-type-attributes '((test (action . identity)))))
3244          (anything-compile-sources '(((name . "foo") (type . test)))
3245                                    '(anything-compile-source--type))))
3246      (desc "anything-sources accepts symbols")
3247      (expect '(((name . "foo")))
3248        (let* ((foo '((name . "foo"))))
3249          (anything-compile-sources '(foo) nil)))
3250      (desc "anything-get-sources action")
3251      (expect '(((name . "Actions") (candidates . actions)))
3252        (stub anything-action-window => t)
3253        (let (anything-compiled-sources
3254              (anything-sources '(((name . "Actions") (candidates . actions)))))
3255          (anything-get-sources)))
3256      (desc "get-buffer-create candidates-buffer")
3257      (expect '(((name . "many") (init . many-init)
3258                 (candidates-in-buffer . anything-candidates-in-buffer)
3259                 (candidates . anything-candidates-in-buffer)
3260                 (volatile) (match identity)))
3261        (anything-compile-sources
3262         '(((name . "many") (init . many-init)
3263            (candidates-in-buffer . anything-candidates-in-buffer)))
3264         '(anything-compile-source--candidates-in-buffer)))
3265      (expect '(((name . "many") (init . many-init)
3266                 (candidates-in-buffer)
3267                 (candidates . anything-candidates-in-buffer)
3268                 (volatile) (match identity)))
3269        (anything-compile-sources
3270         '(((name . "many") (init . many-init)
3271            (candidates-in-buffer)))
3272         '(anything-compile-source--candidates-in-buffer)))
3273      (expect '(((name . "many") (init . many-init)
3274                 (candidates-in-buffer)
3275                 (type . test)
3276                 (action . identity)
3277                 (candidates . anything-candidates-in-buffer)
3278                 (volatile) (match identity)))
3279        (let ((anything-type-attributes '((test (action . identity)))))
3280          (anything-compile-sources
3281           '(((name . "many") (init . many-init)
3282              (candidates-in-buffer)
3283              (type . test)))
3284           '(anything-compile-source--type
3285             anything-compile-source--candidates-in-buffer))))
3286
3287      (desc "anything-get-candidates")
3288      (expect '("foo" "bar")
3289        (anything-get-candidates '((name . "foo") (candidates "foo" "bar"))))
3290      (expect '("FOO" "BAR")
3291        (anything-get-candidates '((name . "foo") (candidates "foo" "bar")
3292                                   (candidate-transformer
3293                                    . (lambda (cands) (mapcar 'upcase cands))))))
3294      (expect '("foo" "bar")
3295        (anything-get-candidates '((name . "foo")
3296                                   (candidates . (lambda () '("foo" "bar"))))))
3297      (desc "anything-compute-matches")
3298      (expect '("foo" "bar")
3299        (let ((anything-pattern ""))
3300          (anything-compute-matches '((name . "FOO") (candidates "foo" "bar") (volatile)))))
3301      (expect '("foo")
3302        (let ((anything-pattern "oo"))
3303          (anything-compute-matches '((name . "FOO") (candidates "foo" "bar") (volatile)))))
3304      (expect '("bar")
3305        (let ((anything-pattern "^b"))
3306          (anything-compute-matches '((name . "FOO") (candidates "foo" "bar") (volatile)))))
3307      (expect '("a" "b")
3308        (let ((anything-pattern "")
3309              (anything-candidate-number-limit 2))
3310          (anything-compute-matches '((name . "FOO") (candidates "a" "b" "c") (volatile)))))
3311      (expect '("a" "b")
3312        (let ((anything-pattern ".")
3313              (anything-candidate-number-limit 2))
3314          (anything-compute-matches '((name . "FOO") (candidates "a" "b" "c") (volatile)))))
3315      (expect '("a" "b" "c")
3316        (let ((anything-pattern "")
3317              anything-candidate-number-limit)
3318          (anything-compute-matches '((name . "FOO") (candidates "a" "b" "c") (volatile)))))
3319      (expect '("a" "b" "c")
3320        (let ((anything-pattern "[abc]")
3321              anything-candidate-number-limit)
3322          (anything-compute-matches '((name . "FOO") (candidates "a" "b" "c") (volatile)))))
3323      ;; using anything-test-candidate-list
3324      (desc "anything-test-candidates")
3325      (expect '(("FOO" ("foo" "bar")))
3326        (anything-test-candidates '(((name . "FOO") (candidates "foo" "bar")))))
3327      (expect '(("FOO" ("bar")))
3328        (anything-test-candidates '(((name . "FOO") (candidates "foo" "bar"))) "ar"))
3329      (expect '(("T1" ("hoge" "aiue"))
3330                ("T2" ("test" "boke")))
3331        (anything-test-candidates '(((name . "T1") (candidates "hoge" "aiue"))
3332                                    ((name . "T2") (candidates "test" "boke")))))
3333      (expect '(("T1" ("hoge"))
3334                ("T2" ("boke")))
3335        (anything-test-candidates '(((name . "T1") (candidates "hoge" "aiue"))
3336                                    ((name . "T2") (candidates "test" "boke"))) "o"))
3337      (desc "requires-pattern attribute")
3338      (expect nil
3339        (anything-test-candidates '(((name . "FOO") (candidates "foo" "bar")
3340                                     (requires-pattern . 1)))))
3341      (expect '(("FOO" ("bar")))
3342        (anything-test-candidates '(((name . "FOO") (candidates "foo" "bar")
3343                                     (requires-pattern . 1))) "b"))
3344      (desc "delayed attribute(for test)")
3345      (expect '(("T2" ("boke"))
3346                ("T1" ("hoge")))
3347        (anything-test-candidates
3348         '(((name . "T1") (candidates "hoge" "aiue") (delayed))
3349           ((name . "T2") (candidates "test" "boke")))
3350         "o"))
3351      (desc "match attribute(prefix search)")
3352      (expect '(("FOO" ("bar")))
3353        (anything-test-candidates
3354         '(((name . "FOO") (candidates "foo" "bar")
3355            (match (lambda (c) (string-match (concat "^" anything-pattern) c)))))
3356         "ba"))
3357      (expect nil
3358        (anything-test-candidates
3359         '(((name . "FOO") (candidates "foo" "bar")
3360            (match (lambda (c) (string-match (concat "^" anything-pattern) c)))))
3361         "ar"))
3362      (desc "init attribute")
3363      (expect '(("FOO" ("bar")))
3364        (let (v)
3365          (anything-test-candidates
3366           '(((name . "FOO") (init . (lambda () (setq v '("foo" "bar"))))
3367              (candidates . v)))
3368           "ar")))
3369      (desc "candidate-transformer attribute")
3370      (expect '(("FOO" ("BAR")))
3371        (anything-test-candidates '(((name . "FOO") (candidates "foo" "bar")
3372                                     (candidate-transformer
3373                                      . (lambda (cands) (mapcar 'upcase cands)))))
3374                                  "ar"))
3375      (desc "filtered-candidate-transformer attribute")
3376      ;; needs more tests
3377      (expect '(("FOO" ("BAR")))
3378        (anything-test-candidates '(((name . "FOO") (candidates "foo" "bar")
3379                                     (filtered-candidate-transformer
3380                                      . (lambda (cands src) (mapcar 'upcase cands)))))
3381                                  "ar"))
3382      (desc "anything-candidates-in-buffer-1")
3383      (expect nil
3384        (anything-candidates-in-buffer-1 nil))
3385      (expect '("foo+" "bar+" "baz+")
3386        (with-temp-buffer
3387          (insert "foo+\nbar+\nbaz+\n")
3388          (let ((anything-candidate-number-limit 5))
3389            (anything-candidates-in-buffer-1 (current-buffer) ""))))
3390      (expect '("foo+" "bar+")
3391        (with-temp-buffer
3392          (insert "foo+\nbar+\nbaz+\n")
3393          (let ((anything-candidate-number-limit 2))
3394            (anything-candidates-in-buffer-1 (current-buffer) ""))))
3395      (expect '("foo+")
3396        (with-temp-buffer
3397          (insert "foo+\nbar+\nbaz+\n")
3398          (anything-candidates-in-buffer-1 (current-buffer) "oo\\+")))
3399      (expect '("foo+")
3400        (with-temp-buffer
3401          (insert "foo+\nbar+\nbaz+\n")
3402          (anything-candidates-in-buffer-1
3403           (current-buffer) "oo+"
3404           #'buffer-substring-no-properties '(search-forward))))
3405      (expect '(("foo+" "FOO+"))
3406        (with-temp-buffer
3407          (insert "foo+\nbar+\nbaz+\n")
3408          (anything-candidates-in-buffer-1
3409           (current-buffer) "oo\\+"
3410           (lambda (s e)
3411             (let ((l (buffer-substring-no-properties s e)))
3412               (list l (upcase l)))))))
3413      (desc "anything-candidates-in-buffer")
3414      (expect '(("TEST" ("foo+" "bar+" "baz+")))
3415        (anything-test-candidates
3416         '(((name . "TEST")
3417            (init
3418             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3419                            (insert "foo+\nbar+\nbaz+\n"))))
3420            (candidates . anything-candidates-in-buffer)
3421            (match identity)
3422            (volatile)))))
3423      (expect '(("TEST" ("foo+" "bar+" "baz+")))
3424        (let (anything-candidate-number-limit)
3425          (anything-test-candidates
3426           '(((name . "TEST")
3427              (init
3428               . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3429                              (insert "foo+\nbar+\nbaz+\n"))))
3430              (candidates . anything-candidates-in-buffer)
3431              (match identity)
3432              (volatile))))))
3433      (expect '(("TEST" ("foo+")))
3434        (anything-test-candidates
3435         '(((name . "TEST")
3436            (init
3437             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3438                            (insert "foo+\nbar+\nbaz+\n"))))
3439            (candidates . anything-candidates-in-buffer)
3440            (match identity)
3441            (volatile)))
3442         "oo\\+"))
3443      (desc "search attribute")
3444      (expect '(("TEST" ("foo+")))
3445        (anything-test-candidates
3446         '(((name . "TEST")
3447            (init
3448             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3449                            (insert "foo+\nbar+\nbaz+\nooo\n"))))
3450            (search search-forward)
3451            (candidates . anything-candidates-in-buffer)
3452            (match identity)
3453            (volatile)))
3454         "oo+"))
3455      (expect '(("TEST" ("foo+" "ooo")))
3456        (anything-test-candidates
3457         '(((name . "TEST")
3458            (init
3459             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3460                            (insert "foo+\nbar+\nbaz+\nooo\n"))))
3461            (search search-forward re-search-forward)
3462            (candidates . anything-candidates-in-buffer)
3463            (match identity)
3464            (volatile)))
3465         "oo+"))
3466      (expect '(("TEST" ("foo+" "ooo")))
3467        (anything-test-candidates
3468         '(((name . "TEST")
3469            (init
3470             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3471                            (insert "foo+\nbar+\nbaz+\nooo\n"))))
3472            (search re-search-forward search-forward)
3473            (candidates . anything-candidates-in-buffer)
3474            (match identity)
3475            (volatile)))
3476         "oo+"))
3477      (expect '(("TEST" ("ooo" "foo+")))
3478        (anything-test-candidates
3479         '(((name . "TEST")
3480            (init
3481             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3482                            (insert "bar+\nbaz+\nooo\nfoo+\n"))))
3483            (search re-search-forward search-forward)
3484            (candidates . anything-candidates-in-buffer)
3485            (match identity)
3486            (volatile)))
3487         "oo+"))
3488      ;; faster exact match
3489      (expect '(("TEST" ("bar+")))
3490        (anything-test-candidates
3491         '(((name . "TEST")
3492            (init
3493             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3494                            (insert "bar+\nbaz+\nooo\nfoo+\n"))))
3495            (search (lambda (pattern &rest _)
3496                      (and (search-forward (concat "\n" pattern "\n") nil t)
3497                           (forward-line -1))))
3498            (candidates . anything-candidates-in-buffer)
3499            (match identity)
3500            (volatile)))
3501         "bar+"))
3502      ;; faster prefix match
3503      (expect '(("TEST" ("bar+")))
3504        (anything-test-candidates
3505         '(((name . "TEST")
3506            (init
3507             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3508                            (insert "bar+\nbaz+\nooo\nfoo+\n"))))
3509            (search (lambda (pattern &rest _)
3510                      (search-forward (concat "\n" pattern) nil t)))
3511            (candidates . anything-candidates-in-buffer)
3512            (match identity)
3513            (volatile)))
3514         "ba"))
3515      (desc "anything-current-buffer-is-modified")
3516      (expect '(("FOO" ("modified")))
3517        (let ((sources '(((name . "FOO")
3518                          (candidates
3519                           . (lambda ()
3520                               (if (anything-current-buffer-is-modified)
3521                                   '("modified")
3522                                 '("unmodified"))))))))
3523          (with-temp-buffer
3524            (clrhash anything-tick-hash)
3525            (insert "1")
3526            (anything-test-candidates sources))))
3527      (expect '(("FOO" ("unmodified")))
3528        (let ((sources '(((name . "FOO")
3529                          (candidates
3530                           . (lambda ()
3531                               (if (anything-current-buffer-is-modified)
3532                                   '("modified")
3533                                 '("unmodified"))))))))
3534          (with-temp-buffer
3535            (clrhash anything-tick-hash)
3536            (insert "1")
3537            (anything-test-candidates sources)
3538            (anything-test-candidates sources))))
3539      (expect '(("FOO" ("modified")))
3540        (let ((sources '(((name . "FOO")
3541                          (candidates
3542                           . (lambda ()
3543                               (if (anything-current-buffer-is-modified)
3544                                   '("modified")
3545                                 '("unmodified"))))))))
3546          (with-temp-buffer
3547            (clrhash anything-tick-hash)
3548            (insert "1")
3549            (anything-test-candidates sources)
3550            (insert "2")
3551            (anything-test-candidates sources))))
3552      (expect '(("BAR" ("modified")))
3553        (let ((sources1 '(((name . "FOO")
3554                          (candidates
3555                           . (lambda ()
3556                               (if (anything-current-buffer-is-modified)
3557                                   '("modified")
3558                                 '("unmodified")))))))
3559              (sources2 '(((name . "BAR")
3560                          (candidates
3561                           . (lambda ()
3562                               (if (anything-current-buffer-is-modified)
3563                                   '("modified")
3564                                 '("unmodified"))))))))
3565          (with-temp-buffer
3566            (clrhash anything-tick-hash)
3567            (insert "1")
3568            (anything-test-candidates sources1)
3569            (anything-test-candidates sources2))))
3570      (expect '(("FOO" ("unmodified")))
3571        (let ((sources1 '(((name . "FOO")
3572                          (candidates
3573                           . (lambda ()
3574                               (if (anything-current-buffer-is-modified)
3575                                   '("modified")
3576                                 '("unmodified")))))))
3577              (sources2 '(((name . "BAR")
3578                          (candidates
3579                           . (lambda ()
3580                               (if (anything-current-buffer-is-modified)
3581                                   '("modified")
3582                                 '("unmodified"))))))))
3583          (with-temp-buffer
3584            (clrhash anything-tick-hash)
3585            (insert "1")
3586            (anything-test-candidates sources1)
3587            (anything-test-candidates sources2)
3588            (anything-test-candidates sources1))))
3589      (expect '(("BAR" ("unmodified")))
3590        (let ((sources1 '(((name . "FOO")
3591                          (candidates
3592                           . (lambda ()
3593                               (if (anything-current-buffer-is-modified)
3594                                   '("modified")
3595                                 '("unmodified")))))))
3596              (sources2 '(((name . "BAR")
3597                          (candidates
3598                           . (lambda ()
3599                               (if (anything-current-buffer-is-modified)
3600                                   '("modified")
3601                                 '("unmodified"))))))))
3602          (with-temp-buffer
3603            (clrhash anything-tick-hash)
3604            (insert "1")
3605            (anything-test-candidates sources1)
3606            (anything-test-candidates sources2)
3607            (anything-test-candidates sources2))))
3608      (expect '(("BAR" ("modified")))
3609        (let ((sources1 '(((name . "FOO")
3610                          (candidates
3611                           . (lambda ()
3612                               (if (anything-current-buffer-is-modified)
3613                                   '("modified")
3614                                 '("unmodified")))))))
3615              (sources2 '(((name . "BAR")
3616                          (candidates
3617                           . (lambda ()
3618                               (if (anything-current-buffer-is-modified)
3619                                   '("modified")
3620                                 '("unmodified"))))))))
3621          (with-temp-buffer
3622            (clrhash anything-tick-hash)
3623            (insert "1")
3624            (anything-test-candidates sources1)
3625            (anything-test-candidates sources2)
3626            (with-temp-buffer
3627              (anything-test-candidates sources2)))))
3628      (desc "anything-source-name")
3629      (expect "FOO"
3630        (let (v)
3631          (anything-test-candidates '(((name . "FOO")
3632                                       (init
3633                                        . (lambda () (setq v anything-source-name)))
3634                                       (candidates "ok"))))
3635          v))
3636      (expect "FOO"
3637        (let (v)
3638          (anything-test-candidates '(((name . "FOO")
3639                                       (candidates
3640                                        . (lambda ()
3641                                            (setq v anything-source-name)
3642                                            '("ok"))))))
3643          v))
3644      (expect "FOO"
3645        (let (v)
3646          (anything-test-candidates '(((name . "FOO")
3647                                       (candidates "ok")
3648                                       (candidate-transformer
3649                                        . (lambda (c)
3650                                            (setq v anything-source-name)
3651                                            c)))))
3652          v))
3653      (expect "FOO"
3654        (let (v)
3655          (anything-test-candidates '(((name . "FOO")
3656                                       (candidates "ok")
3657                                       (filtered-candidate-transformer
3658                                        . (lambda (c s)
3659                                            (setq v anything-source-name)
3660                                            c)))))
3661          v))
3662      (expect "FOO"
3663        (let (v)
3664          (anything-test-candidates '(((name . "FOO")
3665                                       (candidates "ok")
3666                                       (display-to-real
3667                                        . (lambda (c)
3668                                            (setq v anything-source-name)
3669                                            c))
3670                                       (action . identity))))
3671          (anything-execute-selection-action)
3672          v))
3673      (desc "anything-candidate-buffer create")
3674      (expect " *anything candidates:FOO*"
3675        (let* (anything-candidate-buffer-alist
3676               (anything-source-name "FOO")
3677               (buf (anything-candidate-buffer 'global)))
3678          (prog1 (buffer-name buf)
3679            (kill-buffer buf))))
3680      (expect " *anything candidates:FOO*aTestBuffer"
3681        (let* (anything-candidate-buffer-alist
3682               (anything-source-name "FOO")
3683               (anything-current-buffer (get-buffer-create "aTestBuffer"))
3684               (buf (anything-candidate-buffer 'local)))
3685          (prog1 (buffer-name buf)
3686            (kill-buffer anything-current-buffer)
3687            (kill-buffer buf))))
3688      (expect 0
3689        (let (anything-candidate-buffer-alist
3690              (anything-source-name "FOO") buf)
3691          (with-current-buffer  (anything-candidate-buffer 'global)
3692            (insert "1"))
3693          (setq buf  (anything-candidate-buffer 'global))
3694          (prog1 (buffer-size buf)
3695            (kill-buffer buf))))
3696      (desc "anything-candidate-buffer get-buffer")
3697      (expect " *anything candidates:FOO*"
3698        (let* (anything-candidate-buffer-alist
3699               (anything-source-name "FOO")
3700               (buf (anything-candidate-buffer 'global)))
3701          (prog1 (buffer-name (anything-candidate-buffer))
3702            (kill-buffer buf))))
3703      (expect " *anything candidates:FOO*aTestBuffer"
3704        (let* (anything-candidate-buffer-alist
3705               (anything-source-name "FOO")
3706               (anything-current-buffer (get-buffer-create "aTestBuffer"))
3707               (buf (anything-candidate-buffer 'local)))
3708          (prog1 (buffer-name (anything-candidate-buffer))
3709            (kill-buffer anything-current-buffer)
3710            (kill-buffer buf))))
3711      (expect " *anything candidates:FOO*"
3712        (let* (anything-candidate-buffer-alist
3713               (anything-source-name "FOO")
3714               (buf-local (anything-candidate-buffer 'local))
3715               (buf-global (anything-candidate-buffer 'global)))
3716          (prog1 (buffer-name (anything-candidate-buffer))
3717            (kill-buffer buf-local)
3718            (kill-buffer buf-global))))
3719      (expect " *anything candidates:FOO*aTestBuffer"
3720        (let* (anything-candidate-buffer-alist
3721               (anything-source-name "FOO")
3722               (anything-current-buffer (get-buffer-create "aTestBuffer"))
3723               (buf-global (anything-candidate-buffer 'global))
3724               (buf-local (anything-candidate-buffer 'local)))
3725          (prog1 (buffer-name (anything-candidate-buffer))
3726            (kill-buffer buf-local)
3727            (kill-buffer buf-global))))
3728      (expect nil
3729        (let* (anything-candidate-buffer-alist
3730               (anything-source-name "NOP__"))
3731          (anything-candidate-buffer)))
3732      (desc "anything-candidate-buffer register-buffer")
3733      (expect " *anything test candidates*"
3734        (let (anything-candidate-buffer-alist
3735              (buf (get-buffer-create " *anything test candidates*")))
3736          (with-current-buffer buf
3737            (insert "1\n2\n")
3738            (prog1 (buffer-name (anything-candidate-buffer buf))
3739              (kill-buffer (current-buffer))))))
3740      (expect " *anything test candidates*"
3741        (let (anything-candidate-buffer-alist
3742              (buf (get-buffer-create " *anything test candidates*")))
3743          (with-current-buffer buf
3744            (insert "1\n2\n")
3745            (anything-candidate-buffer buf)
3746            (prog1 (buffer-name (anything-candidate-buffer))
3747              (kill-buffer (current-buffer))))))
3748      (expect "1\n2\n"
3749        (let (anything-candidate-buffer-alist
3750              (buf (get-buffer-create " *anything test candidates*")))
3751          (with-current-buffer buf
3752            (insert "1\n2\n")
3753            (anything-candidate-buffer buf)
3754            (prog1 (buffer-string)
3755              (kill-buffer (current-buffer))))))
3756      (desc "action attribute")
3757      (expect "foo"
3758        (anything-test-candidates
3759         '(((name . "TEST")
3760            (candidates "foo")
3761            (action ("identity" . identity)))))
3762        (anything-execute-selection-action))
3763      (expect "foo"
3764        (anything-test-candidates
3765         '(((name . "TEST")
3766            (candidates "foo")
3767            (action ("identity" . (lambda (c) (identity c)))))))
3768        (anything-execute-selection-action))
3769      (desc "anything-execute-selection-action")
3770      (expect "FOO"
3771        (anything-execute-selection-action
3772         "foo" '(("upcase" . upcase))  nil #'identity))
3773      (expect "FOO"
3774        (anything-execute-selection-action
3775         "foo" '(("upcase" . (lambda (c) (upcase c)))) nil #'identity))
3776      (desc "display-to-real attribute")
3777      (expect "FOO"
3778        (anything-execute-selection-action
3779         "foo"
3780         '(("identity" . identity))
3781         nil
3782         #'upcase
3783         ))
3784      (expect "FOO"
3785        (anything-test-candidates
3786         '(((name . "TEST")
3787            (candidates "foo")
3788            (display-to-real . upcase)
3789            (action ("identity" . identity)))))
3790        (anything-execute-selection-action))
3791      (desc "cleanup test")
3792      (expect 'cleaned
3793        (let (v)
3794          (anything-test-candidates
3795           '(((name . "TEST")
3796              (cleanup . (lambda () (setq v 'cleaned))))))
3797          v))
3798      (desc "anything-get-current-source")
3799      ;; in init/candidates/action/candidate-transformer/filtered-candidate-transformer
3800      ;; display-to-real/cleanup function
3801      (expect "FOO"
3802        (assoc-default
3803         'name
3804         (anything-funcall-with-source '((name . "FOO")) 'anything-get-current-source)))
3805      ;; init
3806      (expect "FOO"
3807        (let (v)
3808          (anything-test-candidates
3809           '(((name . "FOO")
3810              (init . (lambda () (setq v (anything-get-current-source)))))))
3811          (assoc-default 'name v)))
3812      ;; candidates
3813      (expect "FOO"
3814        (let (v)
3815          (anything-test-candidates
3816           '(((name . "FOO")
3817              (candidates . (lambda () (setq v (anything-get-current-source)) '("a"))))))
3818          (assoc-default 'name v)))
3819      ;; action
3820      (expect "FOO"
3821        (let (v)
3822          (anything-test-candidates
3823           '(((name . "FOO")
3824              (candidates "a")
3825              (action
3826               . (lambda (c) (setq v (anything-get-current-source)) c)))))
3827          (anything-execute-selection-action)
3828          (assoc-default 'name v)))
3829      ;; candidate-transformer
3830      (expect "FOO"
3831        (let (v)
3832          (anything-test-candidates
3833           '(((name . "FOO")
3834              (candidates "a")
3835              (candidate-transformer
3836               . (lambda (c) (setq v (anything-get-current-source)) c)))))
3837          (assoc-default 'name v)))
3838      ;; filtered-candidate-transformer
3839      (expect "FOO"
3840        (let (v)
3841          (anything-test-candidates
3842           '(((name . "FOO")
3843              (candidates "a")
3844              (filtered-candidate-transformer
3845               . (lambda (c s) (setq v (anything-get-current-source)) c)))))
3846          (assoc-default 'name v)))
3847      ;; action-transformer
3848      (expect "FOO"
3849        (let (v)
3850          (anything-test-candidates
3851           '(((name . "FOO")
3852              (candidates "a")
3853              (action-transformer
3854               . (lambda (a c) (setq v (anything-get-current-source)) a))
3855              (action . identity))))
3856          (anything-execute-selection-action)
3857          (assoc-default 'name v)))
3858      ;; display-to-real
3859      (expect "FOO"
3860        (let (v)
3861          (anything-test-candidates
3862           '(((name . "FOO")
3863              (init . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
3864                                   (insert "a\n"))))
3865              (candidates-in-buffer)
3866              (display-to-real
3867               . (lambda (c) (setq v (anything-get-current-source)) c))
3868              (action . identity))))
3869          (anything-execute-selection-action)
3870          (assoc-default 'name v)))
3871      ;; cleanup
3872      (expect "FOO"
3873        (let (v)
3874          (anything-test-candidates
3875           '(((name . "FOO")
3876              (candidates "a")
3877              (cleanup
3878               . (lambda () (setq v (anything-get-current-source)))))))
3879          (assoc-default 'name v)))
3880      ;; candidates are displayed
3881      (expect "TEST"
3882        (anything-test-candidates
3883         '(((name . "TEST")
3884            (candidates "foo")
3885            (action ("identity" . identity)))))
3886        (assoc-default 'name (anything-get-current-source)))
3887      (desc "anything-attr")
3888      (expect "FOO"
3889        (anything-funcall-with-source
3890         '((name . "FOO"))
3891         (lambda ()
3892           (anything-attr 'name))))
3893      (expect 'fuga
3894        (let (v)
3895          (anything-test-candidates
3896           '(((name . "FOO")
3897              (hoge . fuga)
3898              (init . (lambda () (setq v (anything-attr 'hoge))))
3899              (candidates "a"))))
3900          v))
3901      (expect nil
3902        (let (v)
3903          (anything-test-candidates
3904           '(((name . "FOO")
3905              (init . (lambda () (setq v (anything-attr 'hoge))))
3906              (candidates "a"))))
3907          v))
3908      (expect nil
3909        (let (v)
3910          (anything-test-candidates
3911           '(((name . "FOO")
3912              (hoge)                    ;INCOMPATIBLE!
3913              (init . (lambda () (setq v (anything-attr 'hoge))))
3914              (candidates "a"))))
3915          v))
3916      (desc "anything-attr-defined")
3917      (expect (non-nil)
3918        (let (v)
3919          (anything-test-candidates
3920           '(((name . "FOO")
3921              (hoge)
3922              (init . (lambda () (setq v (anything-attr-defined 'hoge))))
3923              (candidates "a"))))
3924          v))     
3925      (expect nil
3926        (let (v)
3927          (anything-test-candidates
3928           '(((name . "FOO")
3929              (init . (lambda () (setq v (anything-attr-defined 'hoge))))
3930              (candidates "a"))))
3931          v))     
3932      (desc "anything-attrset")
3933      (expect '((name . "FOO") (hoge . 77))
3934        (let ((src '((name . "FOO") (hoge))))
3935          (anything-attrset 'hoge 77 src)
3936          src))
3937      (expect 77
3938        (anything-attrset 'hoge 77 '((name . "FOO") (hoge))))
3939
3940      (expect '((name . "FOO") (hoge . 77))
3941        (let ((src '((name . "FOO") (hoge . 1))))
3942          (anything-attrset 'hoge 77 src)
3943          src))
3944
3945      (expect '((name . "FOO") (hoge . 77) (x))
3946        (let ((src '((name . "FOO") (x))))
3947          (anything-attrset 'hoge 77 src)
3948          src))
3949      (expect 77
3950        (anything-attrset 'hoge 77 '((name . "FOO"))))
3951      (desc "anything-preselect")
3952      ;; entire candidate
3953      (expect "foo"
3954        (with-current-buffer (anything-create-anything-buffer t)
3955          (let ((anything-pattern "")
3956                (anything-test-mode t))
3957            (anything-process-source '((name . "test")
3958                                       (candidates "hoge" "foo" "bar")))
3959            (anything-preselect "foo")
3960            (anything-get-selection))))
3961      ;; regexp
3962      (expect "foo"
3963        (with-current-buffer (anything-create-anything-buffer t)
3964          (let ((anything-pattern "")
3965                (anything-test-mode t))
3966            (anything-process-source '((name . "test")
3967                                       (candidates "hoge" "foo" "bar")))
3968            (anything-preselect "fo+")
3969            (anything-get-selection))))
3970      ;; no match -> first entry
3971      (expect "hoge"
3972        (with-current-buffer (anything-create-anything-buffer t)
3973          (let ((anything-pattern "")
3974                (anything-test-mode t))
3975            (anything-process-source '((name . "test")
3976                                       (candidates "hoge" "foo" "bar")))
3977            (anything-preselect "not found")
3978            (anything-get-selection))))
3979      (desc "anything-check-new-input")
3980      (expect "newpattern"
3981        (stub anything-update)
3982        (stub anything-action-window)
3983        (let ((anything-pattern "pattern"))
3984          (anything-check-new-input "newpattern")
3985          anything-pattern))
3986      ;; anything-input == nil when action window is available
3987      (expect nil
3988        (stub anything-update)
3989        (stub anything-action-window => t)
3990        (let ((anything-pattern "pattern")
3991              anything-input)
3992          (anything-check-new-input "newpattern")
3993          anything-input))
3994      ;; anything-input == anything-pattern unless action window is available
3995      (expect "newpattern"
3996        (stub anything-update)
3997        (stub anything-action-window => nil)
3998        (let ((anything-pattern "pattern")
3999              anything-input)
4000          (anything-check-new-input "newpattern")
4001          anything-input))
4002      (expect (mock (anything-update))
4003        (stub anything-action-window)
4004        (let (anything-pattern)
4005          (anything-check-new-input "foo")))
4006      (desc "anything-update")
4007      (expect (mock (anything-process-source '((name . "1"))))
4008        (anything-test-update '(((name . "1"))) ""))
4009      ;; (find-function 'anything-update)
4010      ;; TODO el-mock.el should express 2nd call of function.
4011      ;;     (expect (mock (anything-process-source '((name . "2"))))
4012      ;;       (stub anything-get-sources => '(((name . "1")) ((name . "2"))))
4013      ;;       (stub run-hooks)
4014      ;;       (stub anything-maybe-fit-frame)
4015      ;;       (stub run-with-idle-timer)
4016      ;;       (anything-update))
4017      (expect (mock (run-with-idle-timer * nil 'anything-process-delayed-sources
4018                                         '(((name . "2") (delayed)))))
4019        (stub anything-get-sources => '(((name . "1"))
4020                                        ((name . "2") (delayed))))
4021        (stub run-hooks)
4022        (stub anything-maybe-fit-frame)
4023        (let ((anything-pattern "") anything-test-mode)
4024          (anything-update)))
4025
4026      (expect (mock (run-with-idle-timer * nil 'anything-process-delayed-sources nil))
4027        (stub anything-get-sources => '(((name . "1"))
4028                                        ((name . "2"))))
4029        (stub run-hooks)
4030        (stub anything-maybe-fit-frame)
4031        (let ((anything-pattern "") anything-test-mode)
4032          (anything-update)))
4033
4034
4035      (desc "requires-pattern attribute")
4036      (expect (not-called anything-process-source)
4037        (anything-test-update '(((name . "1") (requires-pattern))) ""))
4038      (expect (not-called anything-process-source)
4039        (anything-test-update '(((name . "1") (requires-pattern . 3))) "xx"))
4040
4041      (desc "delay")
4042      (expect (mock (sit-for 0.25))
4043        (stub with-current-buffer)
4044        (let ((anything-idle-delay 1.0)
4045              (anything-input-idle-delay 0.75))
4046          (anything-process-delayed-sources t)))
4047      (expect (mock (sit-for 0.0))
4048        (stub with-current-buffer)
4049        (let ((anything-idle-delay 0.2)
4050              (anything-input-idle-delay 0.5))
4051          (anything-process-delayed-sources t)))   
4052      (expect (mock (sit-for 0.5))
4053        (stub with-current-buffer)
4054        (let ((anything-idle-delay 0.5)
4055              (anything-input-idle-delay nil))
4056          (anything-process-delayed-sources t)))
4057      (desc "anything-normalize-sources")
4058      (expect '(anything-c-source-test)
4059        (anything-normalize-sources 'anything-c-source-test))
4060      (expect '(anything-c-source-test)
4061        (anything-normalize-sources '(anything-c-source-test)))
4062      (expect '(anything-c-source-test)
4063        (let ((anything-sources '(anything-c-source-test)))
4064          (anything-normalize-sources nil)))
4065      (desc "anything-get-action")
4066      (expect '(("identity" . identity))
4067        (stub buffer-size => 1)
4068        (stub anything-get-current-source => '((name . "test")
4069                                               (action ("identity" . identity))))
4070        (anything-get-action))
4071      (expect '((("identity" . identity)) "action-transformer is called")
4072        (stub buffer-size => 1)
4073        (stub anything-get-current-source
4074              => '((name . "test")
4075                   (action ("identity" . identity))
4076                   (action-transformer
4077                    . (lambda (actions selection)
4078                        (list actions selection)))))
4079        (stub anything-get-selection => "action-transformer is called")
4080        (anything-get-action))
4081      (desc "anything-select-nth-action")
4082      (expect "selection"
4083        (stub anything-get-selection => "selection")
4084        (stub anything-exit-minibuffer)
4085        (let (anything-saved-selection)
4086          (anything-select-nth-action 1)
4087          anything-saved-selection))
4088      (expect 'cadr
4089        (stub anything-get-action => '(("0" . car) ("1" . cdr) ("2" . cadr)))
4090        (stub anything-exit-minibuffer)
4091        (stub anything-get-selection => "selection")
4092        (let (anything-saved-action)
4093          (anything-select-nth-action 2)
4094          anything-saved-action))
4095      (desc "anything-funcall-foreach")
4096      (expect (mock (upcase "foo"))
4097        (stub anything-get-sources => '(((init . (lambda () (upcase "foo"))))))
4098        (anything-funcall-foreach 'init))
4099      (expect (mock (downcase "bar"))
4100        (stub anything-get-sources => '(((init . (lambda () (upcase "foo"))))
4101                                        ((init . (lambda () (downcase "bar"))))))
4102        (anything-funcall-foreach 'init))
4103      (expect (not-called anything-funcall-with-source)
4104        (stub anything-get-sources => '(((init . (lambda () (upcase "foo"))))))
4105        (anything-funcall-foreach 'not-found))
4106      ;; TODO anything-select-with-digit-shortcut test
4107      (desc "anything-get-cached-candidates")
4108      (expect '("cached" "version")
4109        (let ((anything-candidate-cache '(("test" "cached" "version"))))
4110          (anything-get-cached-candidates '((name . "test")
4111                                            (candidates "new")))))
4112      (expect '("new")
4113        (let ((anything-candidate-cache '(("other" "cached" "version"))))
4114          (anything-get-cached-candidates '((name . "test")
4115                                            (candidates "new")))))
4116      (expect '(("test" "new")
4117                ("other" "cached" "version"))
4118        (let ((anything-candidate-cache '(("other" "cached" "version"))))
4119          (anything-get-cached-candidates '((name . "test")
4120                                            (candidates "new")))
4121          anything-candidate-cache))
4122      (expect '(("other" "cached" "version"))
4123        (let ((anything-candidate-cache '(("other" "cached" "version"))))
4124          (anything-get-cached-candidates '((name . "test")
4125                                            (candidates "new")
4126                                            (volatile)))
4127          anything-candidate-cache))
4128      ;; TODO when candidates == process
4129      ;; TODO anything-output-filter
4130      (desc "candidate-number-limit attribute")
4131      (expect '("a" "b")
4132        (let ((anything-pattern "")
4133              (anything-candidate-number-limit 20))
4134          (anything-compute-matches '((name . "FOO") (candidates "a" "b" "c")
4135                                      (candidate-number-limit . 2) (volatile)))))
4136      (expect '("a" "b")
4137        (let ((anything-pattern "[abc]")
4138              (anything-candidate-number-limit 20))
4139          (anything-compute-matches '((name . "FOO") (candidates "a" "b" "c")
4140                                      (candidate-number-limit . 2) (volatile)))))
4141      (expect '(("TEST" ("a" "b" "c")))
4142        (let ((anything-candidate-number-limit 2))
4143          (anything-test-candidates
4144           '(((name . "TEST")
4145              (init
4146               . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4147                              (insert "a\nb\nc\nd\n"))))
4148              (candidates . anything-candidates-in-buffer)
4149              (match identity)
4150              (candidate-number-limit . 3)
4151              (volatile))))))
4152      (expect '(("TEST" ("a" "b" "c")))
4153        (let ((anything-candidate-number-limit 2))
4154          (anything-test-candidates
4155           '(((name . "TEST")
4156              (init
4157               . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4158                              (insert "a\nb\nc\nd\n"))))
4159              (candidates . anything-candidates-in-buffer)
4160              (match identity)
4161              (candidate-number-limit . 3)
4162              (volatile)))
4163           ".")))
4164      (desc "multiple init")
4165      (expect '(1 . 2)
4166        (let (a b)
4167          (anything-test-candidates
4168           '(((name . "test")
4169              (init (lambda () (setq a 1))
4170                    (lambda () (setq b 2))))))
4171          (cons a b)))
4172      (expect 1
4173        (let (a)
4174          (anything-test-candidates
4175           '(((name . "test")
4176              (init (lambda () (setq a 1))))))
4177          a))
4178      (desc "multiple cleanup")
4179      (expect '(1 . 2)
4180        (let (a b)
4181          (anything-test-candidates
4182           '(((name . "test")
4183              (cleanup (lambda () (setq a 1))
4184                       (lambda () (setq b 2))))))
4185          (cons a b)))
4186      (desc "anything-mklist")
4187      (expect '(1)
4188        (anything-mklist 1))
4189      (expect '(2)
4190        (anything-mklist '(2)))
4191      (desc "anything-before-initialize-hook")
4192      (expect 'called
4193        (let ((anything-before-initialize-hook '((lambda () (setq v 'called))))
4194              v)
4195          (anything-initialize)
4196          v))
4197      (desc "anything-after-initialize-hook")
4198      (expect '(b a)
4199        (let ((anything-before-initialize-hook
4200               '((lambda () (setq v '(a)))))
4201              (anything-after-initialize-hook
4202               '((lambda () (setq v (cons 'b v)))))
4203              v)
4204          (anything-initialize)
4205          v))
4206      (expect 0
4207        (let ((anything-after-initialize-hook
4208               '((lambda () (setq v (buffer-size (get-buffer anything-buffer))))))
4209              v)
4210          (anything-initialize)
4211          v))
4212      (desc "get-line attribute")
4213      (expect '(("TEST" ("FOO+")))
4214        (anything-test-candidates
4215         '(((name . "TEST")
4216            (init
4217             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4218                            (insert "foo+\nbar+\nbaz+\n"))))
4219            (candidates-in-buffer)
4220            (get-line . (lambda (s e) (upcase (buffer-substring-no-properties s e))))))
4221         "oo\\+"))
4222      (desc "with-anything-restore-variables")
4223      (expect '(7 8)
4224        (let ((a 7) (b 8)
4225              (anything-restored-variables '(a b)))
4226          (with-anything-restore-variables
4227            (setq a 0 b 0))
4228          (list a b)))
4229      (desc "anything-cleanup-hook")
4230      (expect 'called
4231        (let ((anything-cleanup-hook
4232               '((lambda () (setq v 'called))))
4233              v)
4234          (anything-cleanup)
4235          v))
4236      (desc "with-anything-display-same-window")
4237      (expect (non-nil)
4238        (save-window-excursion
4239          (delete-other-windows)
4240          (split-window)
4241         
4242          (let ((buf (get-buffer-create " tmp"))
4243                (win (selected-window)))
4244            (with-anything-display-same-window
4245              (display-buffer buf)
4246              (eq win (get-buffer-window buf))))))
4247      (expect (non-nil)
4248        (save-window-excursion
4249          (delete-other-windows)
4250          (split-window)
4251         
4252          (let ((buf (get-buffer-create " tmp"))
4253                (win (selected-window)))
4254            (with-anything-display-same-window
4255              (pop-to-buffer buf)
4256              (eq win (get-buffer-window buf))))))
4257      (expect (non-nil)
4258        (save-window-excursion
4259          (delete-other-windows)
4260          (split-window)
4261         
4262          (let ((buf (get-buffer-create " tmp"))
4263                (win (selected-window)))
4264            (with-anything-display-same-window
4265              (switch-to-buffer buf)
4266              (eq win (get-buffer-window buf))))))
4267      (expect (non-nil)
4268        (save-window-excursion
4269          (delete-other-windows)
4270          (let ((buf (get-buffer-create " tmp"))
4271                (win (selected-window)))
4272            (with-anything-display-same-window
4273              (display-buffer buf)
4274              (eq win (get-buffer-window buf))))))
4275      (expect (non-nil)
4276        (save-window-excursion
4277          (delete-other-windows)
4278          (let ((buf (get-buffer-create " tmp"))
4279                (win (selected-window)))
4280            (with-anything-display-same-window
4281              (pop-to-buffer buf)
4282              (eq win (get-buffer-window buf))))))
4283      (desc "search-from-end attribute")
4284      (expect '(("TEST" ("baz+" "bar+" "foo+")))
4285        (anything-test-candidates
4286         '(((name . "TEST")
4287            (init
4288             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4289                            (insert "foo+\nbar+\nbaz+\n"))))
4290            (candidates-in-buffer)
4291            (search-from-end)))))
4292      (expect '(("TEST" ("baz+" "bar+" "foo+")))
4293        (anything-test-candidates
4294         '(((name . "TEST")
4295            (init
4296             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4297                            (insert "foo+\nbar+\nbaz+\n"))))
4298            (candidates-in-buffer)
4299            (search-from-end)))
4300         "\\+"))
4301      (expect '(("TEST" ("baz+" "bar+")))
4302        (anything-test-candidates
4303         '(((name . "TEST")
4304            (init
4305             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4306                            (insert "foo+\nbar+\nbaz+\n"))))
4307            (candidates-in-buffer)
4308            (search-from-end)
4309            (candidate-number-limit . 2)))))
4310      (expect '(("TEST" ("baz+" "bar+")))
4311        (anything-test-candidates
4312         '(((name . "TEST")
4313            (init
4314             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4315                            (insert "foo+\nbar+\nbaz+\n"))))
4316            (candidates-in-buffer)
4317            (search-from-end)
4318            (candidate-number-limit . 2)))
4319         "\\+"))
4320
4321      (desc "header-name attribute")
4322      (expect "original is transformed"
4323        (anything-test-update '(((name . "original")
4324                                         (candidates "1")
4325                                         (header-name
4326                                          . (lambda (name)
4327                                              (format "%s is transformed" name)))))
4328                              "")
4329        (with-current-buffer (anything-buffer-get)
4330          (buffer-string)
4331          (overlay-get (car (overlays-at (1+(point-min)))) 'display)))
4332      (desc "volatile and match attribute")
4333      ;; candidates function is called once per `anything-process-delayed-sources'
4334      (expect 1
4335        (let ((v 0))
4336          (anything-test-candidates '(((name . "test")
4337                                       (candidates . (lambda () (incf v) '("ok")))
4338                                       (volatile)
4339                                       (match identity identity identity)))
4340                                    "o")
4341          v))
4342      (desc "accept-empty attribute")
4343      (expect nil
4344        (anything-test-candidates
4345         '(((name . "test") (candidates "") (action . identity))))
4346        (anything-execute-selection-action))
4347      (expect ""
4348        (anything-test-candidates
4349         '(((name . "test") (candidates "") (action . identity) (accept-empty))))
4350        (anything-execute-selection-action))
4351      (desc "anything-tick-hash")
4352      (expect nil
4353        (with-current-buffer (get-buffer-create " *00create+*")
4354          (puthash " *00create+*/xxx" 1 anything-tick-hash)
4355          (kill-buffer (current-buffer)))
4356        (gethash " *00create+*/xxx" anything-tick-hash))
4357      (desc "anything-execute-action-at-once-if-once")
4358      (expect "HOGE"
4359        (let ((anything-execute-action-at-once-if-one t))
4360          (anything '(((name . "one test1")
4361                       (candidates "hoge")
4362                       (action . upcase))))))
4363      (expect "ANY"
4364        (let ((anything-execute-action-at-once-if-one t))
4365          (anything '(((name . "one test2")
4366                       (candidates "hoge" "any")
4367                       (action . upcase)))
4368                    "an")))
4369      ;; candidates > 1
4370      (expect (mock (read-string "word: " nil))
4371        (let ((anything-execute-action-at-once-if-one t))
4372          (anything '(((name . "one test3")
4373                       (candidates "hoge" "foo" "bar")
4374                       (action . identity)))
4375                    nil "word: ")))
4376      (desc "anything-quit-if-no-candidate")
4377      (expect nil
4378        (let ((anything-quit-if-no-candidate t))
4379          (anything '(((name . "zero test1") (candidates) (action . upcase))))))
4380      (expect 'called
4381        (let (v (anything-quit-if-no-candidate (lambda () (setq v 'called))))
4382          (anything '(((name . "zero test2") (candidates) (action . upcase))))
4383          v))
4384      (desc "real-to-display attribute")
4385      (expect '(("test" ("ddd")))
4386        (anything-test-candidates '(((name . "test")
4387                                     (candidates "ddd")
4388                                     (real-to-display . upcase)
4389                                     (action . identity)))))
4390      (expect "test\nDDD\n"
4391        (anything-test-update '(((name . "test")
4392                                 (candidates "ddd")
4393                                 (real-to-display . upcase)
4394                                 (action . identity)))
4395                              "")
4396        (with-current-buffer (anything-buffer-get) (buffer-string)))
4397      (desc "real-to-display and candidates-in-buffer")
4398      (expect '(("test" ("a" "b")))
4399        (anything-test-candidates
4400         '(((name . "test")
4401            (init
4402             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4403                            (erase-buffer)
4404                            (insert "a\nb\n"))))
4405            (candidates-in-buffer)
4406            (real-to-display . upcase)
4407            (action . identity)))))
4408      (expect "test\nA\nB\n"
4409        (stub read-string)
4410        (anything
4411         '(((name . "test")
4412            (init
4413             . (lambda () (with-current-buffer (anything-candidate-buffer 'global)
4414                            (erase-buffer)
4415                            (insert "a\nb\n"))))
4416            (candidates-in-buffer)
4417            (real-to-display . upcase)
4418            (action . identity))))
4419        (with-current-buffer (anything-buffer-get) (buffer-string)))
4420      )))
4421
4422
4423(provide 'anything)
4424;; How to save (DO NOT REMOVE!!)
4425;; (emacswiki-post "anything.el")
4426;;; anything.el ends here
Note: See TracBrowser for help on using the browser.