diff options
author | Thierry Volpiatto <thierry.volpiatto@gmail.com> | 2012-03-15 11:41:21 +0100 |
---|---|---|
committer | Thierry Volpiatto <thierry.volpiatto@gmail.com> | 2012-03-15 11:41:21 +0100 |
commit | b016418949e60bc5e9cb4f135a17d129b2b2f28a (patch) | |
tree | d72b2348a2e4c897bae07c58540562cb29c7fb46 /helm-match-plugin.el | |
parent | 9f2a372ad30a377398645aae773848a6de58bd83 (diff) |
Forking to emacs-helm
Diffstat (limited to 'helm-match-plugin.el')
-rw-r--r-- | helm-match-plugin.el | 677 |
1 files changed, 677 insertions, 0 deletions
diff --git a/helm-match-plugin.el b/helm-match-plugin.el new file mode 100644 index 00000000..befc425b --- /dev/null +++ b/helm-match-plugin.el @@ -0,0 +1,677 @@ +;;; helm-match-plugin.el --- Multiple regexp matching methods for helm + +;; Author: rubikitch <rubikitch@ruby-lang.org> + +;; Maintainers: rubikitch <rubikitch@ruby-lang.org> +;; Thierry Volpiatto <thierry.volpiatto@gmail.com> + +;; Copyright (C) 2008~2012, rubikitch, all rights reserved. +;; Copyright (C) 2011~2012, Thierry Volpiatto, all rights reserved. + +;; Keywords: helm, matching +;; X-URL: <http://repo.or.cz/w/helm-config.git> + +;; This file is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 2, or (at your option) +;; any later version. + +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs; see the file COPYING. If not, write to +;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Auto documentation +;; ------------------ +;; +;; * User variables +;; [EVAL] (autodoc-document-lisp-buffer :type 'user-variable :prefix "helm-mp" :var-value t) +;; `helm-mp-matching-method' +;; Default Value: multi3 +;; `helm-mp-highlight-delay' +;; Default Value: 0.7 +;; `helm-mp-highlight-threshold' +;; Default Value: 2 +;; +;; * Internal variables +;; [EVAL] (autodoc-document-lisp-buffer :type 'internal-variable :prefix "helm-mp" :var-value t) +;; `helm-mp-default-match-functions' +;; Default Value: (helm-mp-exact-match helm-mp-3-match) +;; `helm-mp-default-search-functions' +;; Default Value: (helm-mp-exact-search helm-mp-3-search) +;; `helm-mp-default-search-backward-functions' +;; Default Value: (helm-mp-exact-search-backward helm-mp-3-search-backward) +;; `helm-mp-space-regexp' +;; Default Value: "[\\ ] " +;; `helm-mp-exact-pattern-str' +;; Default Value: "autod" +;; `helm-mp-exact-pattern-real' +;; Default Value: "\nautod\n" +;; `helm-mp-prefix-pattern-str' +;; Default Value: nil +;; `helm-mp-prefix-pattern-real' +;; Default Value: nil +;; `helm-mp-1-pattern-str' +;; Default Value: nil +;; `helm-mp-1-pattern-real' +;; Default Value: nil +;; `helm-mp-2-pattern-str' +;; Default Value: nil +;; `helm-mp-2-pattern-real' +;; Default Value: nil +;; `helm-mp-3-pattern-str' +;; Default Value: "autod" +;; `helm-mp-3-pattern-list' +;; Default Value: ((identity . "autod")) +;; `helm-mp-initial-highlight-delay' +;; Default Value: nil +;; +;; * Helm match plugin Functions +;; [EVAL] (autodoc-document-lisp-buffer :type 'function :prefix "helm-mp") +;; `helm-mp-set-matching-method' +;; `helm-mp-make-regexps' +;; `helm-mp-1-make-regexp' +;; `helm-mp-exact-get-pattern' +;; `helm-mp-exact-match' +;; `helm-mp-exact-search' +;; `helm-mp-exact-search-backward' +;; `helm-mp-prefix-get-pattern' +;; `helm-mp-prefix-match' +;; `helm-mp-prefix-search' +;; `helm-mp-prefix-search-backward' +;; `helm-mp-1-get-pattern' +;; `helm-mp-1-match' +;; `helm-mp-1-search' +;; `helm-mp-1-search-backward' +;; `helm-mp-2-get-pattern' +;; `helm-mp-2-match' +;; `helm-mp-2-search' +;; `helm-mp-2-search-backward' +;; `helm-mp-3-get-patterns' +;; `helm-mp-3-get-patterns-internal' +;; `helm-mp-3-match' +;; `helm-mp-3-search-base' +;; `helm-mp-3-search' +;; `helm-mp-3-search-backward' +;; `helm-mp-3p-match' +;; `helm-mp-3p-search' +;; `helm-mp-3p-search-backward' +;; `helm-mp-highlight-match' +;; `helm-mp-highlight-region' +;; `helm-mp-highlight-match-internal' + +;; *** END auto-documentation + +;;; Commentary: + +;; Change helm.el matching algorithm humanely. +;; It gives helm.el search refinement functionality. +;; exact match -> prefix match -> multiple regexp match + +;;; Commands: +;; +;; Below are complete command list: +;; +;; +;;; Customizable Options: +;; +;; Below are customizable option list: +;; +;; `helm-grep-candidates-fast-directory-regexp' +;; *Directory regexp where a RAM disk (or tmpfs) is mounted. +;; default = nil + +;; A query of multiple regexp match is space-delimited string. +;; Helm displays candidates which matches all the regexps. +;; A regexp with "!" prefix means not matching the regexp. +;; To include spaces to a regexp, prefix "\" before space, +;; it is controlled by `helm-mp-space-regexp' variable. + +;; If multiple regexps are specified, first one also tries to match the source name. +;; If you want to disable this feature, evaluate +;; (setq helm-mp-match-source-name nil) . +;; NOTE: This is obsolete and disabled in helm versions >= 1.3.7 + +;; This file highlights patterns like `occur'. Note that patterns +;; longer than `helm-mp-highlight-threshold' are highlighted. And +;; region out of screen is highlighted after +;; `helm-mp-highlight-delay' seconds. +;; +;; Highlight in Emacs is time-consuming process for slow computers. To +;; disable it is to set nil to `helm-mp-highlight-delay'. + +;; helm-match-plugin is enable by default in helm. +;; To disable/enable it use M-x helm-c-toggle-match-plugin. + +;;; Code: + +(require 'helm) +(require 'cl) + + +;;;; Match-plugin + +;; Internal +(defvar helm-mp-default-match-functions nil) +(defvar helm-mp-default-search-functions nil) +(defvar helm-mp-default-search-backward-functions nil) + +(defun helm-mp-set-matching-method (var key) + "Default function to set matching methods in helm match plugin." + (set-default var key) + (case (symbol-value var) + (multi1 (setq helm-mp-default-match-functions + '(helm-mp-exact-match helm-mp-1-match) + helm-mp-default-search-functions + '(helm-mp-exact-search helm-mp-1-search) + helm-mp-default-search-backward-functions + '(helm-mp-exact-search-backward + helm-mp-1-search-backward))) + (multi2 (setq helm-mp-default-match-functions + '(helm-mp-exact-match helm-mp-2-match) + helm-mp-default-search-functions + '(helm-mp-exact-search helm-mp-2-search) + helm-mp-default-search-backward-functions + '(helm-mp-exact-search-backward + helm-mp-2-search-backward))) + (multi3 (setq helm-mp-default-match-functions + '(helm-mp-exact-match helm-mp-3-match) + helm-mp-default-search-functions + '(helm-mp-exact-search helm-mp-3-search) + helm-mp-default-search-backward-functions + '(helm-mp-exact-search-backward + helm-mp-3-search-backward))) + (multi3p (setq helm-mp-default-match-functions + '(helm-mp-exact-match helm-mp-3p-match) + helm-mp-default-search-functions + '(helm-mp-exact-search helm-mp-3p-search) + helm-mp-default-search-backward-functions + '(helm-mp-exact-search-backward + helm-mp-3p-search-backward))) + (t (error "Unknow value: %s" helm-mp-matching-method)))) + +(defgroup helm-match-plugin nil + "Helm match plugin." + :group 'helm) + +(defcustom helm-mp-matching-method 'multi3 + "Matching method for helm match plugin. +You can set here different methods to match candidates in helm. +Here are the possible value of this symbol and their meaning: +- multi1: Respect order, prefix of pattern must match. +- multi2: Same but with partial match. +- multi3: The best, multiple regexp match, allow negation. +- multi3p: Same but prefix must match. +Default is multi3." + :type '(radio :tag "Matching methods for helm" + (const :tag "Multiple regexp 1 ordered with prefix match" multi1) + (const :tag "Multiple regexp 2 ordered with partial match" multi2) + (const :tag "Multiple regexp 3 matching no order, partial, best." multi3) + (const :tag "Multiple regexp 3p matching with prefix match" multi3p)) + :set 'helm-mp-set-matching-method + :group 'helm-match-plugin) + +(defface helm-match + '((t (:inherit match))) + "Face used to highlight matches." + :group 'helm-match-plugin) + +(defcustom helm-mp-highlight-delay 0.7 + "Highlight matches with `helm-match' face after this many seconds. + If nil, no highlight. " + :type 'integer + :group 'helm-match-plugin) + +(defcustom helm-mp-highlight-threshold 2 + "Minimum length of pattern to highlight. +The smaller this value is, the slower highlight is." + :type 'integer + :group 'helm-match-plugin) + + + +;;; Build regexps +;; +;; +(defvar helm-mp-space-regexp "[\\ ] " + "Regexp to represent space itself in multiple regexp match.") + +(defun helm-mp-make-regexps (pattern) + "Split PATTERN if it contain spaces and return resulting list. +If spaces in PATTERN are escaped, don't split at this place. +i.e \"foo bar\"=> (\"foo\" \"bar\") +but \"foo\ bar\"=> (\"foobar\")." + (if (string= pattern "") + '("") + (loop for s in (split-string + (replace-regexp-in-string helm-mp-space-regexp + "\000\000" pattern) + " " t) + collect (replace-regexp-in-string "\000\000" " " s)))) + +(defun helm-mp-1-make-regexp (pattern) + "Replace spaces in PATTERN with \"\.*\"." + (mapconcat 'identity (helm-mp-make-regexps pattern) ".*")) + + +;;; Exact match. +;; +;; +;; Internal. +(defvar helm-mp-exact-pattern-str nil) +(defvar helm-mp-exact-pattern-real nil) + +(defun helm-mp-exact-get-pattern (pattern) + (unless (equal pattern helm-mp-exact-pattern-str) + (setq helm-mp-exact-pattern-str pattern + helm-mp-exact-pattern-real (concat "\n" pattern "\n"))) + helm-mp-exact-pattern-real) + + +(defun helm-mp-exact-match (str &optional pattern) + (string= str (or pattern helm-pattern))) + +(defun helm-mp-exact-search (pattern &rest ignore) + (and (search-forward (helm-mp-exact-get-pattern pattern) nil t) + (forward-line -1))) + +(defun helm-mp-exact-search-backward (pattern &rest ignore) + (and (search-backward (helm-mp-exact-get-pattern pattern) nil t) + (forward-line 1))) + + +;;; Prefix match +;; +;; +;; Internal +(defvar helm-mp-prefix-pattern-str nil) +(defvar helm-mp-prefix-pattern-real nil) + +(defun helm-mp-prefix-get-pattern (pattern) + (unless (equal pattern helm-mp-prefix-pattern-str) + (setq helm-mp-prefix-pattern-str pattern + helm-mp-prefix-pattern-real (concat "\n" pattern))) + helm-mp-prefix-pattern-real) + +(defun helm-mp-prefix-match (str &optional pattern) + (setq pattern (or pattern helm-pattern)) + (let ((len (length pattern))) + (and (<= len (length str)) + (string= (substring str 0 len) pattern )))) + +(defun helm-mp-prefix-search (pattern &rest ignore) + (search-forward (helm-mp-prefix-get-pattern pattern) nil t)) + +(defun helm-mp-prefix-search-backward (pattern &rest ignore) + (and (search-backward (helm-mp-prefix-get-pattern pattern) nil t) + (forward-line 1))) + + +;;; Multiple regexp patterns 1 (order is preserved / prefix). +;; +;; +;; Internal +(defvar helm-mp-1-pattern-str nil) +(defvar helm-mp-1-pattern-real nil) + +(defun helm-mp-1-get-pattern (pattern) + (unless (equal pattern helm-mp-1-pattern-str) + (setq helm-mp-1-pattern-str pattern + helm-mp-1-pattern-real + (concat "^" (helm-mp-1-make-regexp pattern)))) + helm-mp-1-pattern-real) + +(defun* helm-mp-1-match (str &optional (pattern helm-pattern)) + (string-match (helm-mp-1-get-pattern pattern) str)) + +(defun helm-mp-1-search (pattern &rest ignore) + (re-search-forward (helm-mp-1-get-pattern pattern) nil t)) + +(defun helm-mp-1-search-backward (pattern &rest ignore) + (re-search-backward (helm-mp-1-get-pattern pattern) nil t)) + + +;;; Multiple regexp patterns 2 (order is preserved / partial). +;; +;; +;; Internal +(defvar helm-mp-2-pattern-str nil) +(defvar helm-mp-2-pattern-real nil) + +(defun helm-mp-2-get-pattern (pattern) + (unless (equal pattern helm-mp-2-pattern-str) + (setq helm-mp-2-pattern-str pattern + helm-mp-2-pattern-real + (concat "^.*" (helm-mp-1-make-regexp pattern)))) + helm-mp-2-pattern-real) + +(defun* helm-mp-2-match (str &optional (pattern helm-pattern)) + (string-match (helm-mp-2-get-pattern pattern) str)) + +(defun helm-mp-2-search (pattern &rest ignore) + (re-search-forward (helm-mp-2-get-pattern pattern) nil t)) + +(defun helm-mp-2-search-backward (pattern &rest ignore) + (re-search-backward (helm-mp-2-get-pattern pattern) nil t)) + + +;;; Multiple regexp patterns 3 (permutation). +;; +;; +;; Internal +(defvar helm-mp-3-pattern-str nil) +(defvar helm-mp-3-pattern-list nil) + +(defun helm-mp-3-get-patterns (pattern) + "Return `helm-mp-3-pattern-list', a list of predicate/regexp cons cells. +e.g ((identity . \"foo\") (identity . \"bar\")). +This is done only if `helm-mp-3-pattern-str' is same as PATTERN." + (unless (equal pattern helm-mp-3-pattern-str) + (setq helm-mp-3-pattern-str pattern + helm-mp-3-pattern-list + (helm-mp-3-get-patterns-internal pattern))) + helm-mp-3-pattern-list) + +(defun helm-mp-3-get-patterns-internal (pattern) + "Return a list of predicate/regexp cons cells. +e.g ((identity . \"foo\") (identity . \"bar\"))." + (unless (string= pattern "") + (loop for pat in (helm-mp-make-regexps pattern) + collect (if (string= "!" (substring pat 0 1)) + (cons 'not (substring pat 1)) + (cons 'identity pat))))) + +(defun helm-mp-3-match (str &optional pattern) + "Check if PATTERN match STR. +When PATTERN contain a space, it is splitted and matching is done +with the several resulting regexps against STR. +e.g \"bar foo\" will match \"foobar\" and \"barfoo\". +Argument PATTERN, a string, is transformed in a list of +cons cell with `helm-mp-3-get-patterns' if it contain a space. +e.g \"foo bar\"=>((identity . \"foo\") (identity . \"bar\")). +Then each predicate of cons cell(s) is called with regexp of same +cons cell against STR (a candidate). +i.e (identity (string-match \"foo\" \"foo bar\")) => t." + (let ((pat (helm-mp-3-get-patterns (or pattern helm-pattern)))) + (loop for (predicate . regexp) in pat + always (funcall predicate (string-match regexp str))))) + +(defun helm-mp-3-search-base (pattern searchfn1 searchfn2) + (loop with pat = (if (stringp pattern) + (helm-mp-3-get-patterns pattern) + pattern) + while (funcall searchfn1 (or (cdar pat) "") nil t) + for bol = (point-at-bol) + for eol = (point-at-eol) + if (loop for (pred . str) in (cdr pat) always + (progn (goto-char bol) + (funcall pred (funcall searchfn2 str eol t)))) + do (goto-char eol) and return t + else do (goto-char eol) + finally return nil)) + +(defun helm-mp-3-search (pattern &rest ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 're-search-forward 're-search-forward)) + +(defun helm-mp-3-search-backward (pattern &rest ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 're-search-backward 're-search-backward)) + + +;;; mp-3p- (multiple regexp pattern 3 with prefix search) +;; +;; +(defun helm-mp-3p-match (str &optional pattern) + "Check if PATTERN match STR. +Same as `helm-mp-3-match' but more strict, matching against prefix also. +e.g \"bar foo\" will match \"barfoo\" but not \"foobar\" contrarily to +`helm-mp-3-match'." + (let* ((pat (helm-mp-3-get-patterns (or pattern helm-pattern))) + (first (car pat))) + (and (funcall (car first) (helm-mp-prefix-match str (cdr first))) + (loop for (predicate . regexp) in (cdr pat) + always (funcall predicate (string-match regexp str)))))) + +(defun helm-mp-3p-search (pattern &rest ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 'helm-mp-prefix-search 're-search-forward)) + +(defun helm-mp-3p-search-backward (pattern &rest ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 'helm-mp-prefix-search-backward 're-search-backward)) + + +;;; source compiler +;; +;; +(defun helm-compile-source--match-plugin (source) + (let ((searchers (if (assoc 'search-from-end source) + helm-mp-default-search-backward-functions + helm-mp-default-search-functions))) + `(,(if (or (assoc 'candidates-in-buffer source) + (equal '(identity) (assoc-default 'match source))) + '(match identity) + `(match ,@helm-mp-default-match-functions + ,@(assoc-default 'match source))) + (search ,@searchers + ,@(assoc-default 'search source)) + ,@source))) +(add-to-list 'helm-compile-source-functions 'helm-compile-source--match-plugin t) + + +;;; Highlight matches. +;; +;; +(defun helm-mp-highlight-match () + "Highlight matches after `helm-mp-highlight-delay' seconds." + (when (and helm-mp-highlight-delay + (not (string= helm-pattern ""))) + (helm-mp-highlight-match-internal (window-end (helm-window))) + (run-with-idle-timer helm-mp-highlight-delay nil + 'helm-mp-highlight-match-internal + (with-current-buffer helm-buffer (point-max))))) +(add-hook 'helm-update-hook 'helm-mp-highlight-match) + +(defun helm-mp-highlight-region (start end regexp face) + (save-excursion + (goto-char start) + (let (me) + (while (and (setq me (re-search-forward regexp nil t)) + (< (point) end) + (< 0 (- (match-end 0) (match-beginning 0)))) + (unless (helm-pos-header-line-p) + (put-text-property (match-beginning 0) me 'face face)))))) + +(defun helm-mp-highlight-match-internal (end) + (when (helm-window) + (set-buffer helm-buffer) + (let ((requote (loop for (pred . re) in + (helm-mp-3-get-patterns helm-pattern) + when (and (eq pred 'identity) + (>= (length re) + helm-mp-highlight-threshold)) + collect re into re-list + finally return + (if (and re-list (>= (length re-list) 1)) + (mapconcat 'identity re-list "\\|") + (regexp-quote helm-pattern))))) + (when (>= (length requote) helm-mp-highlight-threshold) + (helm-mp-highlight-region + (point-min) end requote 'helm-match))))) + + +;;; Toggle helm-match-plugin +;; +;; +(defvar helm-mp-initial-highlight-delay nil) + +;;;###autoload +(defun helm-mp-toggle-match-plugin () + "Turn on/off multiple regexp matching in helm. +i.e helm-match-plugin." + (interactive) + (let ((helm-match-plugin-enabled + (member 'helm-compile-source--match-plugin + helm-compile-source-functions))) + (flet ((disable-match-plugin () + (setq helm-compile-source-functions + (delq 'helm-compile-source--match-plugin + helm-compile-source-functions)) + (setq helm-mp-initial-highlight-delay + helm-mp-highlight-delay) + (setq helm-mp-highlight-delay nil)) + (enable-match-plugin () + (unless helm-mp-initial-highlight-delay + (setq helm-mp-initial-highlight-delay + helm-mp-highlight-delay)) + (setq helm-compile-source-functions + (cons 'helm-compile-source--match-plugin + helm-compile-source-functions)) + (unless helm-mp-highlight-delay + (setq helm-mp-highlight-delay + helm-mp-initial-highlight-delay)))) + (if helm-match-plugin-enabled + (when (y-or-n-p "Really disable match-plugin? ") + (disable-match-plugin) + (message "Helm-match-plugin disabled")) + (when (y-or-n-p "Really enable match-plugin? ") + (enable-match-plugin) + (message "Helm-match-plugin enabled")))))) + + +;;;; Grep-candidates plug-in + +(defcustom helm-grep-candidates-fast-directory-regexp nil + "*Directory regexp where a RAM disk (or tmpfs) is mounted. + +If non-nil, grep-candidates plugin gets faster because it uses +grep as synchronous process. + +ex. (setq helm-grep-candidates-fast-directory-regexp \"^/tmp/\")" + :type 'string + :group 'helm) + +(defun agp-candidates (&optional filter) + "Normal version of grep-candidates candidates function. +Grep is run by asynchronous process." + (start-process-shell-command + "helm-grep-candidates" nil + (agp-command-line-2 filter (helm-attr-defined 'search-from-end)))) + +(defun agp-candidates-synchronous-grep (&optional filter) + "Faster version of grep-candidates candidates function. +Grep is run by synchronous process. +It is faster when candidate files are in ramdisk." + (split-string + (shell-command-to-string + (agp-command-line-2 filter (helm-attr-defined 'search-from-end))) + "\n")) + +(defun agp-candidates-synchronous-grep--direct-insert-match (&optional filter) + "[EXPERIMENTAL]Fastest version of grep-candidates candidates function at the cost of absense of transformers. +Grep is run by synchronous process. +It is faster when candidate files are in ramdisk. + +If (direct-insert-match) is in the source, this function is used." + (with-current-buffer (helm-candidate-buffer 'global) + (call-process-shell-command + (agp-command-line-2 filter (helm-attr-defined 'search-from-end)) + nil t))) + +(defun agp-command-line (query files &optional limit filter search-from-end) + "Build command line used by grep-candidates from QUERY, FILES, LIMIT, and FILTER." + (let ((allfiles (mapconcat (lambda (f) (shell-quote-argument (expand-file-name f))) + files " "))) + (with-temp-buffer + (when search-from-end + (insert "tac " allfiles)) + (if (string= query "") + (unless search-from-end + (insert "cat " allfiles)) + (when search-from-end (insert " | ")) + (loop for (flag . re) in (helm-mp-3-get-patterns-internal query) + for i from 0 + do + (setq re (replace-regexp-in-string "^-" "\\-" re)) + (unless (zerop i) (insert " | ")) + (insert "grep -ih " + (if (eq flag 'identity) "" "-v ") + (shell-quote-argument re)) + (when (and (not search-from-end) (zerop i)) + (insert " " allfiles)))) + + (when limit (insert (format " | head -n %d" limit))) + (when filter (insert " | " filter)) + (buffer-string)))) + +(defun agp-command-line-2 (filter &optional search-from-end) + "Build command line used by grep-candidates from FILTER and current source." + (agp-command-line + helm-pattern + (helm-mklist (helm-interpret-value (helm-attr 'grep-candidates))) + (helm-candidate-number-limit (helm-get-current-source)) + filter search-from-end)) + +(defun helm-compile-source--grep-candidates (source) + (helm-aif (assoc-default 'grep-candidates source) + (append + source + (let ((use-fast-directory + (and helm-grep-candidates-fast-directory-regexp + (string-match + helm-grep-candidates-fast-directory-regexp + (or (car (helm-mklist (helm-interpret-value it))) ""))))) + (cond ((not (helm-interpret-value it)) nil) + ((and use-fast-directory (assq 'direct-insert-match source)) + (helm-log "fastest version (use-fast-directory and direct-insert-match)") + `((candidates . agp-candidates-synchronous-grep--direct-insert-match) + (match identity) + (volatile))) + (use-fast-directory + (helm-log "faster version (use-fast-directory)") + `((candidates . agp-candidates-synchronous-grep) + (match identity) + (volatile))) + (t + (helm-log "normal version") + '((candidates . agp-candidates) + (delayed)))))) + source)) +(add-to-list 'helm-compile-source-functions 'helm-compile-source--grep-candidates) + +(helm-document-attribute 'grep-candidates "grep-candidates plug-in" + "grep-candidates plug-in provides helm-match-plugin.el feature with grep and head program. +It is MUCH FASTER than normal match-plugin to search from vary large (> 1MB) candidates. +Make sure to install these programs. + +It expands `candidates' and `delayed' attributes. + +`grep-candidates' attribute accepts a filename or list of filename. +It also accepts 0-argument function name or variable name.") + +;; (helm '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message)))) +;; (let ((a "~/.emacs.el")) (helm '(((name . "grep-test") (grep-candidates . a) (action . message) (delayed))))) +;; (let ((a "~/.emacs.el")) (helm '(((name . "grep-test") (grep-candidates . (lambda () a)) (action . message) (delayed))))) +;; (helm '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed) (candidate-number-limit . 2)))) +;; (let ((helm-candidate-number-limit 2)) (helm '(((name . "grep-test") (grep-candidates . "~/.emacs.el") (action . message) (delayed))))) + +;;;; unit test +;; unit test for match plugin are now in developper-tools/unit-test-match-plugin.el + +(provide 'helm-match-plugin) + +;;; helm-match-plugin.el ends here |