mirror of https://github.com/Chizi123/.emacs.d.git

Chizi123
2018-11-18 76bbd07de7add0f9d13c6914f158d19630fe2f62
commit | author | age
5cb5f7 1 ;;; helm-mode.el --- Enable helm completion everywhere. -*- lexical-binding: t -*-
C 2
3 ;; Copyright (C) 2012 ~ 2018 Thierry Volpiatto <thierry.volpiatto@gmail.com>
4
5 ;; This program is free software; you can redistribute it and/or modify
6 ;; it under the terms of the GNU General Public License as published by
7 ;; the Free Software Foundation, either version 3 of the License, or
8 ;; (at your option) any later version.
9
10 ;; This program is distributed in the hope that it will be useful,
11 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 ;; GNU General Public License for more details.
14
15 ;; You should have received a copy of the GNU General Public License
16 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 ;;; Code:
19
20 (require 'cl-lib)
21 (require 'helm)
22 (require 'helm-lib)
23 (require 'helm-files)
24
25 (defvar crm-separator)
26
27
28 (defgroup helm-mode nil
29   "Enable helm completion."
30   :group 'helm)
31
32 (defcustom helm-completing-read-handlers-alist
33   '((describe-function . helm-completing-read-symbols)
34     (describe-variable . helm-completing-read-symbols)
35     (describe-symbol . helm-completing-read-symbols)
36     (debug-on-entry . helm-completing-read-symbols)
37     (find-function . helm-completing-read-symbols)
38     (disassemble . helm-completing-read-symbols)
39     (trace-function . helm-completing-read-symbols)
40     (trace-function-foreground . helm-completing-read-symbols)
41     (trace-function-background . helm-completing-read-symbols)
42     (find-tag . helm-completing-read-default-find-tag)
43     (org-capture . helm-org-completing-read-tags)
44     (org-set-tags . helm-org-completing-read-tags)
45     (ffap-alternate-file . nil)
46     (tmm-menubar . nil)
47     (find-file . nil)
48     (find-file-at-point . helm-completing-read-sync-default-handler)
49     (ffap . helm-completing-read-sync-default-handler)
50     (execute-extended-command . nil)
51     (dired-do-rename . helm-read-file-name-handler-1)
52     (dired-do-copy . helm-read-file-name-handler-1)
53     (dired-do-symlink . helm-read-file-name-handler-1)
54     (dired-do-relsymlink . helm-read-file-name-handler-1)
55     (dired-do-hardlink . helm-read-file-name-handler-1)
56     (basic-save-buffer . helm-read-file-name-handler-1)
57     (write-file . helm-read-file-name-handler-1)
58     (write-region . helm-read-file-name-handler-1))
59   "Completing read functions for specific Emacs commands.
60
61 By default `helm-mode' use `helm-completing-read-default-handler' to
62 provide helm completion in each `completing-read' or `read-file-name'
63 found, but other functions can be specified here for specific
64 commands. This also allow disabling helm completion for some commands
65 when needed.
66  
67 Each entry is a cons cell like (EMACS_COMMAND . COMPLETING-READ_HANDLER)
68 where key and value are symbols.
69
70 Each key is an Emacs command that use originaly `completing-read'.
71
72 Each value maybe a helm function that takes same arguments as
73 `completing-read' plus NAME and BUFFER, where NAME is the name of the new
74 helm source and BUFFER the name of the buffer we will use, but it can
75 be also a function not using helm, in this case the function should
76 take same args as `completing-read' and not be prefixed by \"helm-\".
77
78 `helm' will use the name of the command calling `completing-read' as
79 NAME and BUFFER will be computed as well with NAME but prefixed with
80 \"*helm-mode-\".
81
82 This function prefix name must start by \"helm-\" when it uses helm,
83 otherwise `helm' assumes the function is not a helm function and
84 expects same args as `completing-read', this allow you to define a
85 handler not using helm completion.
86
87 Example:
88
89     (defun foo/test ()
90       (interactive)
91       (message \"%S\" (completing-read \"test: \" '(a b c d e))))
92
93     (defun helm-foo/test-completing-read-handler (prompt collection
94                                                   predicate require-match
95                                                   initial-input hist def
96                                                   inherit-input-method
97                                                   name buffer)
98       (helm-comp-read prompt collection :marked-candidates t
99                                         :name name
100                                         :buffer buffer))
101
102     (add-to-list 'helm-completing-read-handlers-alist
103                  '(foo/test . helm-foo/test-completing-read-handler))
104
105
106 We want here to make the regular `completing-read' in `foo/test'
107 returns a list of candidate(s) instead of a single candidate.
108  
109 Note that this function will be reused for ALL the `completing-read'
110 of this command, so it should handle all cases, e.g
111 If first `completing-read' complete against symbols and
112 second `completing-read' should handle only buffer,
113 your specialized function should handle the both.
114
115 If the value of an entry is nil completion will fall back to
116 emacs vanilla behavior.
117 Example:
118
119 If you want to disable helm completion for `describe-function', use:
120
121     (describe-function . nil)
122
123 Ido is also supported, you can use `ido-completing-read' and
124 `ido-read-file-name' as value of an entry or just 'ido.
125 Example:
126 Enable ido completion for `find-file':
127
128     (find-file . ido)
129
130 same as
131
132     (find-file . ido-read-file-name)
133
134 Note that you don't need to enable `ido-mode' for this to work, see
135 `helm-mode' documentation."
136   :group 'helm-mode
137   :type '(alist :key-type symbol :value-type symbol))
138
139 (defcustom helm-comp-read-case-fold-search helm-case-fold-search
140   "Default Local setting of `helm-case-fold-search' for `helm-comp-read'.
141 See `helm-case-fold-search' for more info."
142   :group 'helm-mode
143   :type 'symbol)
144
145 (defcustom helm-mode-handle-completion-in-region t
146   "Whether to replace or not `completion-in-region-function'.
147 This enable support for `completing-read-multiple' and `completion-at-point'
148 when non--nil."
149   :group 'helm-mode
150   :type 'boolean)
151
152 (defcustom helm-mode-reverse-history t
153   "Display history source after current source in `helm-mode' handled commands."
154   :group 'helm-mode
155   :type 'boolean)
156
157 (defcustom helm-mode-no-completion-in-region-in-modes nil
158   "A list of modes that do not want helm for `completion-in-region'."
159   :group 'helm-mode
160   :type 'boolean)
161
162 (defcustom helm-completion-in-region-fuzzy-match nil
163   "Whether `helm-completion-in-region' use fuzzy matching or not.
164 Affect among others `completion-at-point', `completing-read-multiple'."
165   :group 'helm-mode
166   :type 'boolean)
167
168 (defcustom helm-completion-in-region-default-sort-fn
169   'helm-completion-in-region-sort-fn
170   "The default sort function to sort candidates in completion-in-region.
171
172 When nil no sorting is done.
173 The function is a `filtered-candidate-transformer' function which takes
174 two args CANDIDATES and SOURCE.
175 It will be used only when `helm-completion-in-region-fuzzy-match' is
176 nil otherwise fuzzy use its own sort function."
177   :group 'helm-mode
178   :type 'function)
179
180 (defcustom helm-mode-fuzzy-match nil
181   "Enable fuzzy matching in `helm-mode' globally.
182 Note that this will slow down completion and modify sorting
183 which is unwanted in many places.
184 This affect only the functions with completing-read helmized by helm-mode.
185 To fuzzy match `completion-at-point' and friends see
186 `helm-completion-in-region-fuzzy-match'."
187   :group 'helm-mode
188   :type 'boolean)
189
190 (defcustom helm-mode-minibuffer-setup-hook-black-list '(minibuffer-completion-help)
191   "Incompatible `minibuffer-setup-hook' functions go here.
192 A list of symbols.
193 Helm-mode is rejecting all lambda's, byte-code fns
194 and all functions belonging in this list from `minibuffer-setup-hook'."
195   :group 'helm-mode
196   :type '(repeat (choice symbol)))
197
198 (defcustom helm-completing-read-dynamic-complete nil
199   "Use dynamic completion in `completing-read' when non-nil.
200
201 The default is to not use this because it is most of the time unneeded
202 in `completing-read' and thus it is much more slower.
203 If you feel one emacs function need this you have better time to tell
204 `helm-mode' to use a dynamic completion for this function only by using
205 `helm-completing-read-handlers-alist' with an entry like this:
206
207     (my-function . helm-completing-read-sync-default-handler)
208
209 So you should not change the default setting of this variable unless you
210 know what you are doing."
211   :group 'helm-mode
212   :type 'boolean)
213
214
215 (defvar helm-comp-read-map
216   (let ((map (make-sparse-keymap)))
217     (set-keymap-parent map helm-map)
218     (define-key map (kbd "<C-return>") 'helm-cr-empty-string)
219     (define-key map (kbd "M-RET")      'helm-cr-empty-string)
220     map)
221   "Keymap for `helm-comp-read'.")
222
223 ;;; helm-comp-read
224 ;;
225 ;;
226 (defun helm-cr-empty-string ()
227   "Return empty string."
228   (interactive)
229   (with-helm-alive-p
230     (helm-exit-and-execute-action
231      (lambda (_candidate)
232          (identity "")))))
233 (put 'helm-cr-empty-string 'helm-only t)
234
235 (defun helm-mode--keyboard-quit ()
236   ;; Use this instead of `keyboard-quit'
237   ;; to avoid deactivating mark in current-buffer.
238   (let ((debug-on-quit nil))
239     (signal 'quit nil)))
240
241 (cl-defun helm-comp-read-get-candidates (collection &optional
242                                                     test sort-fn alistp
243                                                     (input helm-pattern))
244   "Convert COLLECTION to list removing elements that don't match TEST.
245 See `helm-comp-read' about supported COLLECTION arguments.
246
247 SORT-FN is a predicate to sort COLLECTION.
248
249 ALISTP when non--nil will not use `all-completions' to collect
250 candidates because it doesn't handle alists correctly for helm.
251 i.e In `all-completions' the car of each pair is used as value.
252 In helm we want to use the cdr instead like \(display . real\),
253 so we return the alist as it is with no transformation by
254 `all-completions'.
255
256 e.g
257
258 \(setq A '((a . 1) (b . 2) (c . 3)))
259 ==>((a . 1) (b . 2) (c . 3))
260 \(helm-comp-read \"test: \" A :alistp nil
261                               :exec-when-only-one t
262                               :initial-input \"a\")
263 ==>\"a\" Which is not what we expect.
264
265 \(helm-comp-read \"test: \" A :alistp t
266                               :exec-when-only-one t
267                               :initial-input \"1\")
268 ==>\"1\"
269
270 See docstring of `all-completions' for more info.
271
272 INPUT is the string you want to complete against, defaulting to
273 `helm-pattern' which is the value of what you enter in minibuffer.
274 Note that when using a function as COLLECTION this value will be
275 available with the input argument of the function only when using a
276 sync source from `helm-comp-read', i.e not using
277 `:candidates-in-buffer', otherwise the function is called only once
278 with an empty string as value for `helm-pattern' because
279 `helm-pattern' is not yet computed, which is what we want otherwise
280 data would not be fully collected at init time.
281
282 If COLLECTION is an `obarray', a TEST should be needed. See `obarray'."
283   ;; Ensure COLLECTION is computed from `helm-current-buffer'
284   ;; because some functions used as COLLECTION work
285   ;; only in the context of current-buffer (Issue #1030) .
286   (with-helm-current-buffer
287     (let ((cands
288            (cond ((vectorp collection)
289                   (all-completions input collection test))
290                  ((and (symbolp collection) (boundp collection)
291                        ;; Issue #324 history is let-bounded and given
292                        ;; quoted as hist argument of completing-read.
293                        ;; See example in `rcirc-browse-url'.
294                        (symbolp (symbol-value collection)))
295                   nil)
296                  ;; When collection is a symbol, most of the time
297                  ;; it should be a symbol used as a minibuffer-history.
298                  ;; The value of this symbol in this case return a list
299                  ;; of string which maybe are converted later as symbol
300                  ;; in special cases.
301                  ;; we treat here commandp as a special case as it return t
302                  ;; also with a string unless its last arg is provided.
303                  ;; Also, the history collections generally collect their
304                  ;; elements as string, so intern them to call predicate.
305                  ((and (symbolp collection) (boundp collection) test)
306                   (let ((predicate (lambda (elm)
307                                      (condition-case _err
308                                          (if (eq test 'commandp)
309                                              (funcall test (intern elm))
310                                              (funcall test elm))
311                                        (wrong-type-argument
312                                         (funcall test (intern elm)))))))
313                     (all-completions input (symbol-value collection) predicate)))
314                  ((and (symbolp collection) (boundp collection))
315                   (all-completions input (symbol-value collection)))
316                  ;; Normally file completion should not be handled here,
317                  ;; but special cases like `find-file-at-point' do it.
318                  ;; Handle here specially such cases.
319                  ((and (functionp collection) (not (string= input ""))
320                        minibuffer-completing-file-name)
321                   (cl-loop for f in (funcall collection input test t)
322                            unless (member f '("./" "../"))
323                            if (string-match helm--url-regexp input)
324                            collect f
325                            else
326                            collect (concat (file-name-as-directory
327                                             (helm-basedir input))
328                                            f)))
329                  ((functionp collection)
330                   (funcall collection input test t))
331                  ((and alistp (null test)) collection)
332                  ;; Next test ensure circular objects are removed
333                  ;; with `all-completions' (Issue #1530).
334                  (t (all-completions input collection test)))))
335       (if sort-fn (sort cands sort-fn) cands))))
336
337 (defun helm-cr--pattern-in-candidates-p (candidates)
338   (or (assoc helm-pattern candidates)
339       (assq (intern helm-pattern) candidates)
340       (member helm-pattern candidates)
341       (member (downcase helm-pattern) candidates)
342       (member (upcase helm-pattern) candidates)))
343
344 (defun helm-cr-default-transformer (candidates source)
345   "Default filter candidate function for `helm-comp-read'."
346   (let ((must-match (helm-attr 'must-match source))
347         unknown-pattern)
348     (unless (or (eq must-match t)
349                 (string= helm-pattern "")
350                 (helm-cr--pattern-in-candidates-p candidates))
351       (setq candidates (append (list
352                                 ;; Unquote helm-pattern
353                                 ;; when it is added
354                                 ;; as candidate: Why? #2015
355                                 ;; (replace-regexp-in-string
356                                 ;;  "\\s\\" "" helm-pattern)
357                                 helm-pattern)
358                                candidates))
359       ;; Notify pattern have been added to candidates.
360       (setq unknown-pattern t))
361     (cl-loop for c in candidates
362              for cand = (if (stringp c)
363                             (replace-regexp-in-string "\\s\\" "" c)
364                           c)
365              for pat = (replace-regexp-in-string "\\s\\" "" helm-pattern)
366              if (and (or (equal c pat) (equal c helm-pattern))
367                      unknown-pattern)
368              collect
369              (cons (concat (propertize
370                             " " 'display
371                             (propertize "[?]" 'face 'helm-ff-prefix))
372                            c)
373                    c)
374              into lst
375              else collect (if (and (stringp cand)
376                                    (string-match "\n" cand))
377                               (cons (replace-regexp-in-string "\n" "->" c) c)
378                             c)
379              into lst
380              finally return (helm-fast-remove-dups lst :test 'equal))))
381
382 (defun helm-comp-read--move-to-first-real-candidate ()
383   (helm-aif (helm-get-selection nil 'withprop)
384       (when (string= (get-text-property 0 'display it) "[?]")
385         (helm-next-line))))
386
387 (defun helm-cr-default (default cands)
388   (delq nil
389         (cond ((and (stringp default) (not (string= default "")))
390                (cons default (delete default cands)))
391               ((consp default)
392                (append (cl-loop for d in default
393                                 ;; Don't convert
394                                 ;; nil to "nil" (i.e the string)
395                                 ;; it will be delq'ed on top.
396                                 collect (if (null d) d (helm-stringify d)))
397                        cands))
398               (t cands))))
399
400 ;;;###autoload
401 (cl-defun helm-comp-read (prompt collection
402                           &key
403                             test
404                             initial-input
405                             default
406                             preselect
407                             (buffer "*Helm Completions*")
408                             must-match
409                             fuzzy
410                             reverse-history
411                             (requires-pattern 0)
412                             history
413                             input-history
414                             (case-fold helm-comp-read-case-fold-search)
415                             (del-input t)
416                             (persistent-action nil)
417                             (persistent-help "DoNothing")
418                             (mode-line helm-comp-read-mode-line)
419                             help-message
420                             (keymap helm-comp-read-map)
421                             (name "Helm Completions")
422                             header-name
423                             candidates-in-buffer
424                             match-part
425                             exec-when-only-one
426                             quit-when-no-cand
427                             (volatile t)
428                             sort
429                             fc-transformer
430                             hist-fc-transformer
431                             marked-candidates
432                             nomark
433                             (alistp t)
434                             (candidate-number-limit helm-candidate-number-limit)
435                             multiline
436                             allow-nest)
437   "Read a string in the minibuffer, with helm completion.
438
439 It is helm `completing-read' equivalent.
440
441 - PROMPT is the prompt name to use.
442
443 - COLLECTION can be a list, vector, obarray or hash-table.
444   It can be also a function that receives three arguments:
445   the values string, predicate and t. See `all-completions' for more details.
446
447 Keys description:
448
449 - TEST: A predicate called with one arg i.e candidate.
450
451 - INITIAL-INPUT: Same as input arg in `helm'.
452
453 - PRESELECT: See preselect arg of `helm'.
454
455 - DEFAULT: This option is used only for compatibility with regular
456   Emacs `completing-read' (Same as DEFAULT arg of `completing-read').
457
458 - BUFFER: Name of helm-buffer.
459
460 - MUST-MATCH: Candidate selected must be one of COLLECTION.
461
462 - FUZZY: Enable fuzzy matching.
463
464 - REVERSE-HISTORY: When non--nil display history source after current
465   source completion.
466
467 - REQUIRES-PATTERN: Same as helm attribute, default is 0.
468
469 - HISTORY: A list containing specific history, default is nil.
470   When it is non--nil, all elements of HISTORY are displayed in
471   a special source before COLLECTION.
472
473 - INPUT-HISTORY: A symbol. the minibuffer input history will be
474   stored there, if nil or not provided, `minibuffer-history'
475   will be used instead.
476
477 - CASE-FOLD: Same as `helm-case-fold-search'.
478
479 - DEL-INPUT: Boolean, when non--nil (default) remove the partial
480   minibuffer input from HISTORY is present.
481
482 - PERSISTENT-ACTION: A function called with one arg i.e candidate.
483
484 - PERSISTENT-HELP: A string to document PERSISTENT-ACTION.
485
486 - MODE-LINE: A string or list to display in mode line.
487   Default is `helm-comp-read-mode-line'.
488
489 - KEYMAP: A keymap to use in this `helm-comp-read'.
490   (the keymap will be shared with history source)
491
492 - NAME: The name related to this local source.
493
494 - HEADER-NAME: A function to alter NAME, see `helm'.
495
496 - EXEC-WHEN-ONLY-ONE: Bound `helm-execute-action-at-once-if-one'
497   to non--nil. (possibles values are t or nil).
498
499 - VOLATILE: Use volatile attribute.
500
501 - SORT: A predicate to give to `sort' e.g `string-lessp'
502   Use this only on small data as it is ineficient.
503   If you want to sort faster add a sort function to
504   FC-TRANSFORMER.
505   Note that FUZZY when enabled is already providing a sort function.
506
507 - FC-TRANSFORMER: A `filtered-candidate-transformer' function
508   or a list of functions.
509
510 - HIST-FC-TRANSFORMER: A `filtered-candidate-transformer'
511   function for the history source.
512
513 - MARKED-CANDIDATES: If non--nil return candidate or marked candidates as a list.
514
515 - NOMARK: When non--nil don't allow marking candidates.
516
517 - ALISTP: \(default is non--nil\) See `helm-comp-read-get-candidates'.
518
519 - CANDIDATES-IN-BUFFER: when non--nil use a source build with
520   `helm-source-in-buffer' which is much faster.
521   Argument VOLATILE have no effect when CANDIDATES-IN-BUFFER is non--nil.
522
523 - MATCH-PART: Allow matching only one part of candidate.
524   See match-part documentation in `helm-source'.
525
526 - ALLOW-NEST: Allow nesting this `helm-comp-read' in a helm session.
527   See `helm'.
528
529 - MULTILINE: See multiline in `helm-source'.
530
531 Any prefix args passed during `helm-comp-read' invocation will be recorded
532 in `helm-current-prefix-arg', otherwise if prefix args were given before
533 `helm-comp-read' invocation, the value of `current-prefix-arg' will be used.
534 That's mean you can pass prefix args before or after calling a command
535 that use `helm-comp-read' See `helm-M-x' for example."
536
537   (when (get-buffer helm-action-buffer)
538     (kill-buffer helm-action-buffer))
539   (let ((action-fn `(("Sole action (Identity)"
540                       . (lambda (candidate)
541                           (if ,marked-candidates
542                               (helm-marked-candidates)
543                               (identity candidate)))))))
544     ;; Assume completion have been already required,
545     ;; so always use 'confirm.
546     (when (eq must-match 'confirm-after-completion)
547       (setq must-match 'confirm))
548     (let* ((minibuffer-completion-confirm must-match)
549            (must-match-map (when must-match
550                              (let ((map (make-sparse-keymap)))
551                                (define-key map (kbd "RET")
552                                  'helm-confirm-and-exit-minibuffer)
553                                map)))
554            (loc-map (if must-match-map
555                         (make-composed-keymap
556                          must-match-map (or keymap helm-map))
557                       (or keymap helm-map)))
558            (minibuffer-completion-predicate test)
559            (minibuffer-completion-table collection)
560            (helm-read-file-name-mode-line-string
561             (replace-regexp-in-string "helm-maybe-exit-minibuffer"
562                                       "helm-confirm-and-exit-minibuffer"
563                                       helm-read-file-name-mode-line-string))
564            (get-candidates
565             (lambda ()
566               (let ((cands (helm-comp-read-get-candidates
567                             collection test sort alistp
568                             ;; This should not be needed as
569                             ;; `helm-pattern' is not yet computed when
570                             ;; calling this from :init when
571                             ;; candidates-in-buffer is in use.
572                             (if candidates-in-buffer "" helm-pattern))))
573                 (helm-cr-default default cands))))
574            (history-get-candidates
575             (lambda ()
576               (let ((cands (helm-comp-read-get-candidates
577                             history test nil alistp)))
578                 (when cands
579                   (delete "" (helm-cr-default default cands))))))
580            (src-hist (helm-build-sync-source (format "%s History" name)
581                        :candidates history-get-candidates
582                        :fuzzy-match fuzzy
583                        :multiline multiline
584                        :match-part match-part
585                        :filtered-candidate-transformer
586                        (append '((lambda (candidates sources)
587                                    (cl-loop for i in candidates
588                                             ;; Input is added to history in completing-read's
589                                             ;; and may be regexp-quoted, so unquote it
590                                             ;; but check if cand is a string (it may be at this stage
591                                             ;; a symbol or nil) Issue #1553.
592                                             when (stringp i)
593                                             collect (replace-regexp-in-string "\\s\\" "" i))))
594                                (and hist-fc-transformer (helm-mklist hist-fc-transformer)))
595                        :persistent-action persistent-action
596                        :persistent-help persistent-help
597                        :keymap loc-map
598                        :mode-line mode-line
599                        :help-message help-message
600                        :action action-fn))
601            (src (helm-build-sync-source name
602                   :candidates get-candidates
603                   :match-part match-part
604                   :multiline multiline
605                   :header-name header-name
606                   :filtered-candidate-transformer
607                   (append (helm-mklist fc-transformer)
608                           '(helm-cr-default-transformer))
609                   :requires-pattern requires-pattern
610                   :persistent-action persistent-action
611                   :persistent-help persistent-help
612                   :fuzzy-match fuzzy
613                   :keymap loc-map
614                   :mode-line mode-line
615                   :help-message help-message
616                   :action action-fn
617                   :volatile volatile))
618            (src-1 (helm-build-in-buffer-source name
619                     :data get-candidates
620                     :match-part match-part
621                     :multiline multiline
622                     :header-name header-name
623                     :filtered-candidate-transformer
624                     (append (helm-mklist fc-transformer)
625                             '(helm-cr-default-transformer))
626                     :requires-pattern requires-pattern
627                     :persistent-action persistent-action
628                     :fuzzy-match fuzzy
629                     :keymap loc-map
630                     :persistent-help persistent-help
631                     :mode-line mode-line
632                     :help-message help-message
633                     :action action-fn))
634            (src-list (list src-hist
635                            (cons (cons 'must-match must-match)
636                                  (if candidates-in-buffer
637                                      src-1 src))))
638            (helm-execute-action-at-once-if-one exec-when-only-one)
639            (helm-quit-if-no-candidate quit-when-no-cand)
640            result)
641       (when nomark
642         (setq src-list (cl-loop for src in src-list
643                              collect (cons '(nomark) src))))
644       (when reverse-history (setq src-list (nreverse src-list)))
645       (add-hook 'helm-after-update-hook 'helm-comp-read--move-to-first-real-candidate)
646       (unwind-protect
647            (setq result (helm
648                          :sources src-list
649                          :input initial-input
650                          :default default
651                          :preselect preselect
652                          :prompt prompt
653                          :resume 'noresume
654                          :keymap loc-map ;; Needed with empty collection.
655                          :allow-nest allow-nest
656                          :candidate-number-limit candidate-number-limit
657                          :case-fold-search case-fold
658                          :history (and (symbolp input-history) input-history)
659                          :buffer buffer))
660         (remove-hook 'helm-after-update-hook 'helm-comp-read--move-to-first-real-candidate))
661       ;; Avoid adding an incomplete input to history.
662       (when (and result history del-input)
663         (cond ((and (symbolp history) ; History is a symbol.
664                     (not (symbolp (symbol-value history)))) ; Fix Issue #324.
665                ;; Be sure history is not a symbol with a nil value.
666                (helm-aif (symbol-value history) (setcar it result)))
667               ((consp history) ; A list with a non--nil value.
668                (setcar history result))
669               (t ; Possibly a symbol with a nil value.
670                (set history (list result)))))
671       (or result (helm-mode--keyboard-quit)))))
672
673
674 ;; Generic completing-read
675 ;;
676 ;; Support also function as collection.
677 ;; e.g M-x man is supported.
678 ;; Support hash-table and vectors as collection.
679 ;; NOTE:
680 ;; Some crap emacs functions may not be supported
681 ;; like ffap-alternate-file (bad use of completing-read)
682 ;; and maybe others.
683 ;; Provide a mode `helm-mode' which turn on
684 ;; helm in all `completing-read' and `read-file-name' in Emacs.
685 ;;
686 (defvar helm-completion-mode-string " Helm")
687
688 (defvar helm-completion-mode-quit-message
689   "Helm completion disabled")
690
691 (defvar helm-completion-mode-start-message
692   "Helm completion enabled")
693
694 ;;; Specialized handlers
695 ;;
696 ;;
697 (defun helm-completing-read-symbols
698     (prompt _collection test _require-match init
699      hist default _inherit-input-method name buffer)
700   "Specialized function for fast symbols completion in `helm-mode'."
701   (require 'helm-elisp)
702   (or
703    (helm
704     :sources (helm-build-in-buffer-source name
705                :init (lambda ()
706                        (helm-apropos-init (lambda (x)
707                                             (and (funcall test x)
708                                                  (not (keywordp x))))
709                                           (or (car-safe default) default)))
710                :filtered-candidate-transformer 'helm-apropos-default-sort-fn
711                :help-message #'helm-comp-read-help-message
712                :fuzzy-match helm-mode-fuzzy-match
713                :persistent-action
714                (lambda (candidate)
715                  (helm-lisp-completion-persistent-action
716                   candidate name))
717                :persistent-help (helm-lisp-completion-persistent-help))
718     :prompt prompt
719     :buffer buffer
720     :input init
721     :history hist
722     :resume 'noresume
723     :default (or default ""))
724      (helm-mode--keyboard-quit)))
725
726
727 ;;; Generic completing read
728 ;;
729 ;;
730 (defun helm-completing-read-default-1
731     (prompt collection test require-match
732      init hist default _inherit-input-method
733      name buffer &optional cands-in-buffer exec-when-only-one)
734   "Call `helm-comp-read' with same args as `completing-read'.
735 Extra optional arg CANDS-IN-BUFFER mean use `candidates-in-buffer'
736 method which is faster.
737 It should be used when candidate list don't need to rebuild dynamically."
738   (let ((history (or (car-safe hist) hist))
739         (initial-input (helm-aif (pcase init
740                                    ((pred (stringp)) init)
741                                    ;; INIT is a cons cell.
742                                    (`(,l . ,_ll) l))
743                            (if minibuffer-completing-file-name it
744                                (regexp-quote it)))))
745     (helm-comp-read
746      prompt collection
747      :test test
748      :history history
749      :reverse-history helm-mode-reverse-history
750      :input-history history
751      :must-match require-match
752      :alistp nil
753      :help-message #'helm-comp-read-help-message
754      :name name
755      :requires-pattern (if (and (stringp default)
756                                 (string= default "")
757                                 (or (eq require-match 'confirm)
758                                     (eq require-match
759                                         'confirm-after-completion)))
760                            1 0)
761      :candidates-in-buffer cands-in-buffer
762      :exec-when-only-one exec-when-only-one
763      :fuzzy helm-mode-fuzzy-match
764      :buffer buffer
765      ;; If DEF is not provided, fallback to empty string
766      ;; to avoid `thing-at-point' to be appended on top of list
767      :default (or default "")
768      ;; Fail with special characters (e.g in gnus "nnimap+gmail:")
769      ;; if regexp-quote is not used.
770      ;; when init is added to history, it will be unquoted by
771      ;; helm-comp-read.
772      :initial-input initial-input)))
773
774 (defun helm-completing-read-default-find-tag
775     (prompt collection test require-match
776      init hist default inherit-input-method
777      name buffer)
778   "Specialized `helm-mode' handler for `find-tag'."
779   ;; Some commands like find-tag may use `read-file-name' from inside
780   ;; the calculation of collection. in this case it clash with
781   ;; candidates-in-buffer that reuse precedent data (files) which is wrong.
782   ;; So (re)calculate collection outside of main helm-session.
783   (let* ((cands (helm-comp-read-get-candidates
784                  collection test nil nil)))
785     (helm-completing-read-default-1 prompt cands test require-match
786                                     init hist default inherit-input-method
787                                     name buffer t)))
788
789 (defun helm-completing-read-sync-default-handler
790     (prompt collection test require-match
791      init hist default inherit-input-method
792      name buffer)
793   "`helm-mode' handler using sync source as backend."
794   (helm-completing-read-default-1 prompt collection test require-match
795                                   init hist default inherit-input-method
796                                   name buffer))
797
798 (defun helm-completing-read-default-handler
799     (prompt collection test require-match
800      init hist default inherit-input-method
801      name buffer)
802   "Default `helm-mode' handler for all `completing-read'."
803   (helm-completing-read-default-1 prompt collection test require-match
804                                   init hist default inherit-input-method
805                                   name buffer
806                                   (null helm-completing-read-dynamic-complete)))
807
808 (defun helm--generic-read-buffer (prompt &optional default require-match predicate)
809   "The `read-buffer-function' for `helm-mode'.
810 Affects `switch-to-buffer' and related."
811   (let ((collection (helm-buffer-list)))
812     (helm--completing-read-default
813      prompt collection predicate require-match nil nil default)))
814
815 (cl-defun helm--completing-read-default
816     (prompt collection &optional
817                          predicate require-match
818                          initial-input hist def
819                          inherit-input-method)
820   "An helm replacement of `completing-read'.
821 This function should be used only as a `completing-read-function'.
822
823 Don't use it directly, use instead `helm-comp-read' in your programs.
824
825 See documentation of `completing-read' and `all-completions' for details."
826   (let* ((current-command (or (helm-this-command) this-command))
827          (str-command     (helm-symbol-name current-command))
828          (buf-name        (format "*helm-mode-%s*" str-command))
829          (entry           (assq current-command
830                                 helm-completing-read-handlers-alist))
831          (def-com         (cdr-safe entry))
832          (str-defcom      (and def-com (helm-symbol-name def-com)))
833          (def-args        (list prompt collection predicate require-match
834                                 initial-input hist def inherit-input-method))
835          ;; Append the two extra args needed to set the buffer and source name
836          ;; in helm specialized functions.
837          (any-args        (append def-args (list str-command buf-name)))
838          helm-completion-mode-start-message ; Be quiet
839          helm-completion-mode-quit-message
840          ;; Be sure this pesty *completion* buffer doesn't popup.
841          ;; Note: `minibuffer-with-setup-hook' may setup a lambda
842          ;; calling `minibuffer-completion-help' or other minibuffer
843          ;; functions we DONT WANT here, in these cases removing the hook
844          ;; (a symbol) have no effect. Issue #448.
845          ;; Because `minibuffer-completion-table' and
846          ;; `minibuffer-completion-predicate' are not bound
847          ;; anymore here, these functions should have no effect now,
848          ;; except in some rare cases like in `woman-file-name',
849          ;; so remove all incompatible functions
850          ;; from `minibuffer-setup-hook' (Issue #1205, #1240).
851          ;; otherwise helm have not the time to close its initial session.
852          (minibuffer-setup-hook
853           (cl-loop for h in minibuffer-setup-hook
854                    unless (or (consp h) ; a lambda.
855                               (byte-code-function-p h)
856                               (memq h helm-mode-minibuffer-setup-hook-black-list))
857                    collect h))
858          ;; Disable hack that could be used before `completing-read'.
859          ;; i.e (push ?\t unread-command-events).
860          unread-command-events
861          (default-handler
862           ;; Typically when COLLECTION is a function, we can assume
863           ;; the intention is completing dynamically according to
864           ;; input; If one want to use in-buffer handler for specific
865           ;; usage with a function as collection he can specify it in
866           ;; helm-completing-read-handlers-alist.
867           (if (functionp collection)
868               #'helm-completing-read-sync-default-handler
869             #'helm-completing-read-default-handler)))
870     (when (eq def-com 'ido) (setq def-com 'ido-completing-read))
871     (unless (or (not entry) def-com)
872       ;; An entry in *read-handlers-alist exists but have
873       ;; a nil value, so we exit from here, disable `helm-mode'
874       ;; and run the command again with it original behavior.
875       ;; `helm-mode' will be restored on exit.
876       (cl-return-from helm--completing-read-default
877         (unwind-protect
878              (progn
879                (helm-mode -1)
880                (apply completing-read-function def-args))
881           (helm-mode 1))))
882     ;; If we use now `completing-read' we MUST turn off `helm-mode'
883     ;; to avoid infinite recursion and CRASH. It will be reenabled on exit.
884     (when (or (eq def-com 'completing-read)
885               ;; All specialized functions are prefixed by "helm"
886               (and (stringp str-defcom)
887                    (not (string-match "^helm" str-defcom))))
888       (helm-mode -1))
889     (unwind-protect
890          (cond (;; An helm specialized function exists, run it.
891                 (and def-com helm-mode)
892                 (apply def-com any-args))
893                (;; Try to handle `ido-completing-read' everywhere.
894                 (and def-com (eq def-com 'ido-completing-read))
895                 (setcar (memq collection def-args)
896                         (all-completions "" collection predicate))
897                 (apply def-com def-args))
898                (;; User set explicitely `completing-read' or something similar
899                 ;; in *read-handlers-alist, use this with exactly the same
900                 ;; args as in `completing-read'.
901                 ;; If we are here `helm-mode' is now disabled.
902                 def-com
903                 (apply def-com def-args))
904                (;; Use by default a in-buffer handler unless
905                 ;; COLLECTION is a function. 
906                 t
907                 (funcall default-handler
908                          prompt collection predicate require-match
909                          initial-input hist def inherit-input-method
910                          str-command buf-name)))
911       (helm-mode 1)
912       ;; When exiting minibuffer, `this-command' is set to
913       ;; `helm-exit-minibuffer', which is unwanted when starting
914       ;; on another `completing-read', so restore `this-command' to
915       ;; initial value when exiting.
916       (setq this-command current-command))))
917
918 ;;; Generic read-file-name
919 ;;
920 ;;
921 ;;;###autoload
922 (cl-defun helm-read-file-name
923     (prompt
924      &key
925        (name "Read File Name")
926        (initial-input default-directory)
927        (buffer "*Helm file completions*")
928        test
929        (case-fold helm-file-name-case-fold-search)
930        preselect
931        history
932        must-match
933        (fuzzy t)
934        default
935        marked-candidates
936        (candidate-number-limit helm-ff-candidate-number-limit)
937        nomark
938        (alistp t)
939        (persistent-action-if 'helm-find-files-persistent-action-if)
940        (persistent-help "Hit1 Expand Candidate, Hit2 or (C-u) Find file")
941        (mode-line helm-read-file-name-mode-line-string))
942   "Read a file name with helm completion.
943 It is helm `read-file-name' emulation.
944
945 Argument PROMPT is the default prompt to use.
946
947 Keys description:
948
949 - NAME: Source name, default to \"Read File Name\".
950
951 - INITIAL-INPUT: Where to start read file name, default to `default-directory'.
952
953 - BUFFER: `helm-buffer' name default to \"*Helm Completions*\".
954
955 - TEST: A predicate called with one arg 'candidate'.
956
957 - CASE-FOLD: Same as `helm-case-fold-search'.
958
959 - PRESELECT: helm preselection.
960
961 - HISTORY: Display HISTORY in a special source.
962
963 - MUST-MATCH: Can be 'confirm, nil, or t.
964
965 - FUZZY: Enable fuzzy matching when non-nil (Enabled by default).
966
967 - MARKED-CANDIDATES: When non--nil return a list of marked candidates.
968
969 - NOMARK: When non--nil don't allow marking candidates.
970
971 - ALISTP: Don't use `all-completions' in history (take effect only on history).
972
973 - PERSISTENT-ACTION-IF: a persistent if action function.
974
975 - PERSISTENT-HELP: persistent help message.
976
977 - MODE-LINE: A mode line message, default is `helm-read-file-name-mode-line-string'."
978   (require 'tramp)
979   (when (get-buffer helm-action-buffer)
980     (kill-buffer helm-action-buffer))
981   ;; Assume completion have been already required,
982   ;; so always use 'confirm.
983   (when (eq must-match 'confirm-after-completion)
984     (setq must-match 'confirm))
985   (mapc (lambda (hook)
986           (add-hook 'helm-after-update-hook hook))
987         '(helm-ff-move-to-first-real-candidate
988           helm-ff-update-when-only-one-matched
989           helm-ff-auto-expand-to-home-or-root))
990   (let* ((action-fn `(("Sole action (Identity)"
991                        . (lambda (candidate)
992                            (if ,marked-candidates
993                                (helm-marked-candidates :with-wildcard t)
994                              (identity candidate))))))
995          ;; Be sure we don't erase the underlying minibuffer if some.
996          (helm-ff-auto-update-initial-value
997           (and helm-ff-auto-update-initial-value
998                (not (minibuffer-window-active-p (minibuffer-window)))))
999          helm-follow-mode-persistent
1000          (helm-ff-fuzzy-matching
1001           (and fuzzy
1002                (not (memq helm-mm-matching-method '(multi1 multi3p)))))
1003          (hist (and history (helm-comp-read-get-candidates
1004                              history nil nil alistp)))
1005          (minibuffer-completion-confirm must-match)
1006          (must-match-map (when must-match
1007                            (let ((map (make-sparse-keymap)))
1008                              (define-key map (kbd "RET")
1009                                (let ((fn (lookup-key helm-read-file-map (kbd "RET"))))
1010                                  (if (eq fn 'helm-ff-RET)
1011                                      #'helm-ff-RET-must-match
1012                                    #'helm-confirm-and-exit-minibuffer)))
1013                              map)))
1014          (cmap (if must-match-map
1015                    (make-composed-keymap
1016                     must-match-map helm-read-file-map)
1017                  helm-read-file-map))
1018          (minibuffer-completion-predicate test)
1019          (minibuffer-completing-file-name t)
1020          (helm--completing-file-name t)
1021          (helm-read-file-name-mode-line-string
1022           (replace-regexp-in-string "helm-maybe-exit-minibuffer"
1023                                     "helm-confirm-and-exit-minibuffer"
1024                                     helm-read-file-name-mode-line-string))
1025          (src-list
1026           (list
1027            ;; History source.
1028            (helm-build-sync-source (format "%s History" name)
1029              :header-name (lambda (name)
1030                             (concat name (substitute-command-keys
1031                                           helm-find-files-doc-header)))
1032              :mode-line mode-line
1033              :candidates hist
1034              :nohighlight t
1035              :fuzzy-match fuzzy
1036              :persistent-action-if persistent-action-if
1037              :persistent-help persistent-help
1038              :keymap cmap
1039              :nomark nomark
1040              :action action-fn)
1041            ;; Other source.
1042            (helm-build-sync-source name
1043              :header-name (lambda (name)
1044                             (concat name (substitute-command-keys
1045                                           helm-find-files-doc-header)))
1046              :init (lambda ()
1047                      (setq helm-ff-auto-update-flag
1048                            helm-ff-auto-update-initial-value)
1049                      (setq helm-ff--auto-update-state
1050                            helm-ff-auto-update-flag))
1051              :mode-line mode-line
1052              :help-message 'helm-read-file-name-help-message
1053              :nohighlight t
1054              :candidates
1055              (lambda ()
1056                (append (and (not (file-exists-p helm-pattern))
1057                             (not (helm-ff--invalid-tramp-name-p helm-pattern))
1058                             (list helm-pattern))
1059                        (if test
1060                            (cl-loop with hn = (helm-ff--tramp-hostnames)
1061                                     for i in (helm-find-files-get-candidates
1062                                               must-match)
1063                                     when (or (member i hn) ; A tramp host
1064                                              (funcall test i)) ; Test ok
1065                                     collect i)
1066                            (helm-find-files-get-candidates must-match))))
1067              :filtered-candidate-transformer 'helm-ff-sort-candidates
1068              :filter-one-by-one 'helm-ff-filter-candidate-one-by-one
1069              :persistent-action-if persistent-action-if
1070              :persistent-help persistent-help
1071              :volatile t
1072              :keymap cmap
1073              :cleanup 'helm-find-files-cleanup
1074              :nomark nomark
1075              :action action-fn)))
1076          ;; Helm result.
1077          (result (helm
1078                   :sources (if helm-mode-reverse-history
1079                                (reverse src-list) src-list)
1080                   :input (expand-file-name initial-input)
1081                   :prompt prompt
1082                   :candidate-number-limit candidate-number-limit
1083                   :resume 'noresume
1084                   :case-fold-search case-fold
1085                   :default default
1086                   :buffer buffer
1087                   :full-frame nil
1088                   :preselect preselect)))
1089     (or
1090      (cond ((and result (stringp result)
1091                  (string= result "") ""))
1092            ((and result
1093                  (stringp result)
1094                  (file-equal-p result initial-input)
1095                  default)
1096             (if (listp default) (car default) default))
1097            ((and result (listp result))
1098             (mapcar #'expand-file-name result))
1099            ((and result (file-directory-p result))
1100             (file-name-as-directory (expand-file-name result)))
1101            (result (expand-file-name result)))
1102      (helm-mode--keyboard-quit))))
1103
1104 (defun helm-mode--default-filename (fname dir initial)
1105   (unless dir (setq dir default-directory))
1106   (unless (file-name-absolute-p dir)
1107     (setq dir (expand-file-name dir)))
1108   (unless (or fname (consp fname))
1109     (setq fname (expand-file-name
1110                  (or initial buffer-file-name dir)
1111                  dir)))
1112   (if (and fname (consp fname))
1113       (setq fname (cl-loop for f in fname
1114                            collect (expand-file-name f dir)))
1115       (if (file-name-absolute-p fname)
1116           fname (expand-file-name fname dir))))
1117
1118 (cl-defun helm--generic-read-file-name
1119     (prompt &optional dir default-filename mustmatch initial predicate)
1120   "Generic helm replacement of `read-file-name'.
1121 Don't use it directly, use instead `helm-read-file-name' in your programs."
1122   (let* ((init (or initial dir default-directory))
1123          (current-command (or (helm-this-command) this-command))
1124          (str-command (helm-symbol-name current-command))
1125          (helm--file-completion-sources
1126           (cons str-command
1127                 (remove str-command helm--file-completion-sources)))
1128          (buf-name (format "*helm-mode-%s*" str-command))
1129          (entry (assq current-command
1130                       helm-completing-read-handlers-alist))
1131          (def-com  (cdr-safe entry))
1132          (str-defcom (and def-com (helm-symbol-name def-com)))
1133          ;; Don't modify the original args list for emacs generic functions.
1134          (def-args (list prompt dir default-filename mustmatch initial predicate))
1135          ;; Append the two extra args needed to set the buffer and source name
1136          ;; in helm specialized functions.
1137          (any-args (append def-args (list str-command buf-name)))
1138          (ido-state ido-mode)
1139          helm-completion-mode-start-message ; Be quiet
1140          helm-completion-mode-quit-message  ; Same here
1141          fname)
1142     ;; Build `default-filename' with `dir'+`initial' when
1143     ;; `default-filename' is not specified.
1144     ;; See `read-file-name' docstring for more infos.
1145     (setq default-filename (helm-mode--default-filename
1146                             default-filename dir initial))
1147     ;; Some functions that normally call `completing-read' can switch
1148     ;; brutally to `read-file-name' (e.g find-tag), in this case
1149     ;; the helm specialized function will fail because it is build
1150     ;; for `completing-read', so set it to 'incompatible to be sure
1151     ;; we switch to `helm-read-file-name' and don't try to call it
1152     ;; with wrong number of args.
1153     (when (eq def-com 'ido)
1154       (setq def-com 'ido-read-file-name) (ido-mode 1))
1155     (when (and def-com (> (length (help-function-arglist def-com)) 8))
1156       (setq def-com 'incompatible))
1157     (unless (or (not entry) def-com)
1158       (cl-return-from helm--generic-read-file-name
1159         (unwind-protect
1160              (progn
1161                (helm-mode -1)
1162                (apply read-file-name-function def-args))
1163           (helm-mode 1))))
1164     ;; If we use now `read-file-name' we MUST turn off `helm-mode'
1165     ;; to avoid infinite recursion and CRASH. It will be reenabled on exit.
1166     (when (or (eq def-com 'read-file-name)
1167               (eq def-com 'ido-read-file-name)
1168               (and (stringp str-defcom)
1169                    (not (string-match "^helm" str-defcom))))
1170       (helm-mode -1))
1171     (unwind-protect
1172          (setq fname
1173                (cond (;; A specialized function exists, run it
1174                       ;; with the two extra args specific to helm.
1175                       ;; Note that the helm handler should ensure
1176                       ;; :initial-input is not nil i.e. Use init
1177                       ;; which fallback to default-directory instead
1178                       ;; of INITIAL.
1179                       (and def-com helm-mode
1180                            (not (eq def-com 'ido-read-file-name))
1181                            (not (eq def-com 'incompatible)))
1182                       (apply def-com any-args))
1183                      (;; Def-com value is `ido-read-file-name'
1184                       ;; run it with default args.
1185                       (and def-com (eq def-com 'ido-read-file-name))
1186                       (ido-mode 1)
1187                       (apply def-com def-args))
1188                      (;; Def-com value is `read-file-name'
1189                       ;; run it with default args.
1190                       (eq def-com 'read-file-name)
1191                       (apply def-com def-args))
1192                      (t ; Fall back to classic `helm-read-file-name'.
1193                       (helm-read-file-name
1194                        prompt
1195                        :name str-command
1196                        :buffer buf-name
1197                        :default default-filename
1198                        ;; Helm handlers should always have a non nil INITIAL arg.
1199                        :initial-input (expand-file-name init dir)
1200                        :alistp nil
1201                        :must-match mustmatch
1202                        :test predicate))))
1203       (helm-mode 1)
1204       (ido-mode (if ido-state 1 -1))
1205       ;; Same comment as in `helm--completing-read-default'.
1206       (setq this-command current-command))
1207     (if (and
1208          ;; Using `read-directory-name'.
1209          (eq predicate 'file-directory-p)
1210          ;; `file-name-as-directory' return "./" when FNAME is
1211          ;; empty string.
1212          (not (string= fname "")))
1213         (file-name-as-directory fname) fname)))
1214
1215 ;; Read file name handler with history (issue #1652)
1216 (defun helm-read-file-name-handler-1 (prompt dir default-filename
1217                                       mustmatch initial predicate
1218                                       name buffer)
1219   "A `read-file-name' handler with history.
1220 Can be added to `helm-completing-read-handlers-alist' for functions
1221 that need a `read-file-name' function with directory history.
1222 The `helm-find-files' history `helm-ff-history' is used here."
1223   (let ((helm-always-two-windows t)
1224         (helm-split-window-default-side
1225          (if (eq helm-split-window-default-side 'same)
1226              'below helm-split-window-default-side))
1227         helm-split-window-inside-p
1228         helm-reuse-last-window-split-state
1229         ;; Helm handlers should always have a non nil INITIAL arg.
1230         (init (or initial dir default-directory)))
1231     (helm-read-file-name
1232      prompt
1233      :name name
1234      :history helm-ff-history
1235      :buffer buffer
1236      :default default-filename
1237      :initial-input (expand-file-name init dir)
1238      :alistp nil
1239      :must-match mustmatch
1240      :test predicate)))
1241
1242
1243 ;;; Completion in region
1244 ;;
1245 (defun helm-mode--advice-lisp--local-variables (old--fn &rest args)
1246   (ignore-errors
1247     (apply old--fn args)))
1248
1249 (defun helm-completion-in-region-sort-fn (candidates _source)
1250   "Default sort function for completion-in-region."
1251   (sort candidates 'helm-generic-sort-fn))
1252
1253 (defun helm--completion-in-region (start end collection &optional predicate)
1254   "Helm replacement of `completion--in-region'.
1255 Can be used as value for `completion-in-region-function'."
1256   (cl-declare (special require-match prompt))
1257   (if (memq major-mode helm-mode-no-completion-in-region-in-modes)
1258       (funcall helm--old-completion-in-region-function
1259                start end collection predicate)
1260     (advice-add
1261      'lisp--local-variables
1262      :around #'helm-mode--advice-lisp--local-variables)
1263     (unwind-protect
1264         (let* ((enable-recursive-minibuffers t)
1265                (input (buffer-substring-no-properties start end))
1266                (current-command (or (helm-this-command) this-command))
1267                (crm (eq current-command 'crm-complete))
1268                (str-command (helm-symbol-name current-command))
1269                (buf-name (format "*helm-mode-%s*" str-command))
1270                (require-match (or (and (boundp 'require-match) require-match)
1271                                   minibuffer-completion-confirm
1272                                   ;; If prompt have not been propagated here, that's
1273                                   ;; probably mean we have no prompt and we are in
1274                                   ;; completion-at-point or friend, so use a non--nil
1275                                   ;; value for require-match.
1276                                   (not (boundp 'prompt))))
1277                ;; `completion-extra-properties' is let-bounded in `completion-at-point'.
1278                ;; `afun' is a closure to call against each string in `data'.
1279                ;; it provide the annotation info for each string.
1280                ;; e.g "foo" => "foo <f>" where foo is a function.
1281                ;; See Issue #407.
1282                (afun (plist-get completion-extra-properties :annotation-function))
1283                (metadata (completion-metadata
1284                           (buffer-substring-no-properties start (point))
1285                           collection predicate))
1286                (data (completion-all-completions
1287                       (buffer-substring start end)
1288                       collection
1289                       predicate
1290                       (- (point) start)
1291                       metadata))
1292                ;; `completion-all-completions' store the base-size in the last `cdr',
1293                ;; so data looks like this: '(a b c d . 0) and (last data) == (d . 0).
1294                (last-data (last data))
1295                (base-size (helm-aif (cdr (last data))
1296                               (prog1 it
1297                                 (setcdr last-data nil))
1298                             0))
1299                (init-space-suffix (unless (or helm-completion-in-region-fuzzy-match
1300                                               (string-suffix-p " " input)
1301                                               (string= input ""))
1302                                     " "))
1303                (file-comp-p (or (eq (completion-metadata-get metadata 'category) 'file)
1304                                 (helm-mode--in-file-completion-p)
1305                                 ;; Assume that when `afun' and `predicate' are null
1306                                 ;; we are in filename completion.
1307                                 (and (null afun) (null predicate))))
1308                ;; Completion-at-point and friends have no prompt.
1309                (result (if (stringp data)
1310                            data
1311                          (helm-comp-read
1312                           (or (and (boundp 'prompt) prompt) "Pattern: ")
1313                           (if file-comp-p
1314                               (cl-loop for f in data unless
1315                                        (string-match "\\`\\.\\{1,2\\}/\\'" f)
1316                                        collect f)
1317                             (if afun
1318                                 (mapcar (lambda (s)
1319                                           (let ((ann (funcall afun s)))
1320                                             (if ann
1321                                                 (cons
1322                                                  (concat
1323                                                   s
1324                                                   (propertize
1325                                                    " " 'display
1326                                                    (propertize
1327                                                     ann
1328                                                     'face 'completions-annotations)))
1329                                                  s)
1330                                               s)))
1331                                         data)
1332                               data))
1333                           :name str-command
1334                           :fuzzy helm-completion-in-region-fuzzy-match
1335                           :nomark (null crm)
1336                           :marked-candidates crm
1337                           :initial-input
1338                           (cond ((and file-comp-p
1339                                       (not (string-match "/\\'" input)))
1340                                  (concat (helm-basename input)
1341                                          init-space-suffix))
1342                                 ((string-match "/\\'" input) nil)
1343                                 ((or (null require-match)
1344                                      (stringp require-match))
1345                                  input)
1346                                 (t (concat input init-space-suffix)))
1347                           :buffer buf-name
1348                           :fc-transformer (append '(helm-cr-default-transformer)
1349                                                   (unless (or helm-completion-in-region-fuzzy-match
1350                                                               (null helm-completion-in-region-default-sort-fn))
1351                                                     (list helm-completion-in-region-default-sort-fn)))
1352                           :exec-when-only-one t
1353                           :quit-when-no-cand
1354                           (lambda ()
1355                             ;; Delay message to overwrite "Quit".
1356                             (run-with-timer
1357                              0.01 nil
1358                              (lambda ()
1359                                (message "[No matches]")))
1360                             t) ; exit minibuffer immediately.
1361                           :must-match require-match))))
1362           (cond ((stringp result)
1363                  (choose-completion-string
1364                   result (current-buffer)
1365                   (list (+ start base-size) end)
1366                   completion-list-insert-choice-function))
1367                 ((consp result) ; crm.
1368                  (let ((beg (+ start base-size))
1369                        (sep ","))
1370                    ;; Try to find a default separator.
1371                    (save-excursion
1372                      (goto-char beg)
1373                      (when (looking-back crm-separator (1- (point)))
1374                        (setq sep (match-string 0))))
1375                    (funcall completion-list-insert-choice-function
1376                             beg end (mapconcat 'identity result sep))))
1377                 (t nil)))
1378       (advice-remove 'lisp--local-variables
1379                      #'helm-mode--advice-lisp--local-variables))))
1380
1381 (defun helm-mode--in-file-completion-p ()
1382   (with-helm-current-buffer
1383     (run-hook-with-args-until-success 'file-name-at-point-functions)))
1384
1385 (when (boundp 'completion-in-region-function)
1386   (defconst helm--old-completion-in-region-function completion-in-region-function))
1387
1388 ;;;###autoload
1389 (define-minor-mode helm-mode
1390     "Toggle generic helm completion.
1391
1392 All functions in Emacs that use `completing-read'
1393 or `read-file-name' and friends will use helm interface
1394 when this mode is turned on.
1395
1396 However you can modify this behavior for functions of your choice
1397 with `helm-completing-read-handlers-alist'.
1398
1399 Also commands using `completion-in-region' will be helmized when
1400 `helm-mode-handle-completion-in-region' is non nil, you can modify
1401 this behavior with `helm-mode-no-completion-in-region-in-modes'.
1402
1403 Called with a positive arg, turn on unconditionally, with a
1404 negative arg turn off.
1405 You can turn it on with `helm-mode'.
1406
1407 Some crap emacs functions may not be supported,
1408 e.g `ffap-alternate-file' and maybe others
1409 You can add such functions to `helm-completing-read-handlers-alist'
1410 with a nil value.
1411
1412 About `ido-mode':
1413 When you are using `helm-mode', DO NOT use `ido-mode', instead if you
1414 want some commands use `ido', add these commands to
1415 `helm-completing-read-handlers-alist' with `ido' as value.
1416
1417 Note: This mode is incompatible with Emacs23."
1418   :group 'helm-mode
1419   :global t
1420   :lighter helm-completion-mode-string
1421   (cl-assert (boundp 'completing-read-function) nil
1422              "`helm-mode' not available, upgrade to Emacs-24")
1423   (if helm-mode
1424       (if (fboundp 'add-function)
1425           (progn
1426             (add-function :override completing-read-function
1427                           #'helm--completing-read-default)
1428             (add-function :override read-file-name-function
1429                           #'helm--generic-read-file-name)
1430             (add-function :override read-buffer-function
1431                           #'helm--generic-read-buffer)
1432             (when helm-mode-handle-completion-in-region
1433               (add-function :override completion-in-region-function
1434                             #'helm--completion-in-region)))
1435           (setq completing-read-function 'helm--completing-read-default
1436                 read-file-name-function  'helm--generic-read-file-name
1437                 read-buffer-function     'helm--generic-read-buffer)
1438           (when (and (boundp 'completion-in-region-function)
1439                      helm-mode-handle-completion-in-region)
1440             (setq completion-in-region-function #'helm--completion-in-region))
1441           (message helm-completion-mode-start-message))
1442       (if (fboundp 'remove-function)
1443           (progn
1444             (remove-function completing-read-function #'helm--completing-read-default)
1445             (remove-function read-file-name-function #'helm--generic-read-file-name)
1446             (remove-function read-buffer-function #'helm--generic-read-buffer)
1447             (remove-function completion-in-region-function #'helm--completion-in-region))
1448           (setq completing-read-function (and (fboundp 'completing-read-default)
1449                                         'completing-read-default)
1450                 read-file-name-function  (and (fboundp 'read-file-name-default)
1451                                               'read-file-name-default)
1452                 read-buffer-function     (and (fboundp 'read-buffer) 'read-buffer))
1453           (when (and (boundp 'completion-in-region-function)
1454                      (boundp 'helm--old-completion-in-region-function))
1455             (setq completion-in-region-function helm--old-completion-in-region-function))
1456           (message helm-completion-mode-quit-message))))
1457
1458 (provide 'helm-mode)
1459
1460 ;; Local Variables:
1461 ;; byte-compile-warnings: (not obsolete)
1462 ;; coding: utf-8
1463 ;; indent-tabs-mode: nil
1464 ;; End:
1465
1466 ;;; helm-mode.el ends here