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

Chizi123
2018-11-18 76bbd07de7add0f9d13c6914f158d19630fe2f62
commit | author | age
76bbd0 1 ;;; helm.el --- Emacs incremental and narrowing framework -*- lexical-binding: t -*-
C 2
3 ;; Copyright (C) 2007         Tamas Patrovics
4 ;;               2008 ~ 2011  rubikitch <rubikitch@ruby-lang.org>
5 ;;               2011 ~ 2018  Thierry Volpiatto <thierry.volpiatto@gmail.com>
6
7 ;; This is a fork of anything.el wrote by Tamas Patrovics.
8
9 ;; Authors of anything.el: Tamas Patrovics
10 ;;                         rubikitch <rubikitch@ruby-lang.org>
11 ;;                         Thierry Volpiatto <thierry.volpiatto@gmail.com>
12
13 ;; Author: Thierry Volpiatto <thierry.volpiatto@gmail.com>
14 ;; URL: http://github.com/emacs-helm/helm
15
16 ;; This program is free software; you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation, either version 3 of the License, or
19 ;; (at your option) any later version.
20
21 ;; This program is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 ;; GNU General Public License for more details.
25
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
28
29 ;;; Code:
30
31 (require 'cl-lib)
32 (require 'async)
33 (require 'advice) ; Shutup byte compiler about ad-deactivate.
34 (require 'helm-lib)
35 (require 'helm-multi-match)
36 (require 'helm-source)
37
38
39 ;;; Multi keys
40 ;;
41 ;;
42 ;;;###autoload
43 (defun helm-define-multi-key (keymap key functions &optional delay)
44   "In KEYMAP, define key sequence KEY for function list FUNCTIONS.
45 Each function runs sequentially for each KEY press.
46 If DELAY is specified, switch back to initial function of FUNCTIONS list
47 after DELAY seconds.
48 The functions in FUNCTIONS list take no args.
49 e.g
50     (defun foo ()
51       (interactive)
52       (message \"Run foo\"))
53     (defun bar ()
54       (interactive)
55       (message \"Run bar\"))
56     (defun baz ()
57       (interactive)
58       (message \"Run baz\"))
59
60 \(helm-define-multi-key global-map (kbd \"<f5> q\") '(foo bar baz) 2)
61
62 Each time \"<f5> q\" is pressed, the next function is executed. Waiting
63 more than 2 seconds between key presses switches back to executing the first
64 function on the next hit."
65   (define-key keymap key (helm-make-multi-command functions delay)))
66
67 ;;;###autoload
68 (defmacro helm-multi-key-defun (name docstring funs &optional delay)
69   "Define NAME as a multi-key command running FUNS.
70 After DELAY seconds, the FUNS list is reinitialized.
71 See `helm-define-multi-key'."
72   (declare (indent 2))
73   (setq docstring (if docstring (concat docstring "\n\n")
74                     "This is a helm-ish multi-key command."))
75   `(defalias (quote ,name) (helm-make-multi-command ,funs ,delay) ,docstring))
76
77 (defun helm-make-multi-command (functions &optional delay)
78   "Return an anonymous multi-key command running FUNCTIONS.
79 Run each function in the FUNCTIONS list in turn when called within DELAY seconds."
80   (declare (indent 1))
81   (let ((funs functions)
82         (iter (cl-gensym "helm-iter-key"))
83         (timeout delay))
84     (eval (list 'defvar iter nil))
85     (lambda ()
86       (interactive)
87       (helm-run-multi-key-command funs iter timeout))))
88
89 (defun helm-run-multi-key-command (functions iterator delay)
90   (let ((fn (lambda ()
91                 (cl-loop for count from 1 to (length functions)
92                       collect count)))
93         next)
94     (unless (and (symbol-value iterator)
95                  ;; Reset iterator when another key is pressed.
96                  (eq this-command real-last-command))
97       (set iterator (helm-iter-list (funcall fn))))
98     (setq next (helm-iter-next (symbol-value iterator)))
99     (unless next
100       (set iterator (helm-iter-list (funcall fn)))
101       (setq next (helm-iter-next (symbol-value iterator))))
102     (and next (symbol-value iterator)
103          (call-interactively (nth (1- next) functions)))
104     (when delay (run-with-idle-timer
105                  delay nil (lambda ()
106                              (set iterator nil))))))
107
108 (helm-multi-key-defun helm-toggle-resplit-and-swap-windows
109     "Multi key command to re-split and swap helm window.
110 First call runs `helm-toggle-resplit-window',
111 and second call within 0.5s runs `helm-swap-windows'."
112   '(helm-toggle-resplit-window helm-swap-windows) 1)
113 (put 'helm-toggle-resplit-and-swap-windows 'helm-only t)
114
115 ;;;###autoload
116 (defun helm-define-key-with-subkeys (map key subkey command
117                                          &optional other-subkeys prompt exit-fn)
118   "Defines in MAP a KEY and SUBKEY to COMMAND.
119
120 This allows typing KEY to call COMMAND the first time and
121 type only SUBKEY on subsequent calls.
122
123 Arg MAP is the keymap to use, SUBKEY is the initial short key-binding to
124 call COMMAND.
125
126 Arg OTHER-SUBKEYS is an alist specifying other short key-bindings
127 to use once started e.g:
128
129     \(helm-define-key-with-subkeys global-map
130        \(kbd \"C-x v n\") ?n 'git-gutter:next-hunk '((?p . git-gutter:previous-hunk))\)
131
132
133 In this example, `C-x v n' will run `git-gutter:next-hunk'
134 subsequent \"n\"'s run this command again
135 and subsequent \"p\"'s run `git-gutter:previous-hunk'.
136
137 If specified PROMPT can be displayed in minibuffer to
138 describe SUBKEY and OTHER-SUBKEYS.
139 Arg EXIT-FN specifies a function to run on exit.
140
141 For any other keys pressed, run their assigned command as defined
142 in MAP and then exit the loop running EXIT-FN, if specified.
143
144 NOTE: SUBKEY and OTHER-SUBKEYS bindings support only char syntax and
145 vectors, so don't use strings to define them."
146   (declare (indent 1))
147   (define-key map key
148     (lambda ()
149       (interactive)
150       (unwind-protect
151           (progn
152             (call-interactively command)
153             (while (let ((input (read-key prompt)) other kb com)
154                      (setq last-command-event input)
155                      (cond
156                       ((eq input subkey)
157                        (call-interactively command)
158                        t)
159                       ((setq other (assoc input other-subkeys))
160                        (call-interactively (cdr other))
161                        t)
162                       (t
163                        (setq kb (vector last-command-event))
164                        (setq com (lookup-key map kb))
165                        (if (commandp com)
166                            (call-interactively com)
167                          (setq unread-command-events
168                                (nconc (mapcar 'identity kb)
169                                       unread-command-events)))
170                        nil)))))
171         (and exit-fn (funcall exit-fn))))))
172
173 ;;; Keymap
174 ;;
175 ;;
176 (defvar helm-map
177   (let ((map (make-sparse-keymap)))
178     (set-keymap-parent map minibuffer-local-map)
179     (define-key map (kbd "<down>")     'helm-next-line)
180     (define-key map (kbd "<up>")       'helm-previous-line)
181     (define-key map (kbd "C-n")        'helm-next-line)
182     (define-key map (kbd "C-p")        'helm-previous-line)
183     (define-key map (kbd "<C-down>")   'helm-follow-action-forward)
184     (define-key map (kbd "<C-up>")     'helm-follow-action-backward)
185     (define-key map (kbd "<prior>")    'helm-previous-page)
186     (define-key map (kbd "<next>")     'helm-next-page)
187     (define-key map (kbd "M-v")        'helm-previous-page)
188     (define-key map (kbd "C-v")        'helm-next-page)
189     (define-key map (kbd "M-<")        'helm-beginning-of-buffer)
190     (define-key map (kbd "M->")        'helm-end-of-buffer)
191     (define-key map (kbd "C-g")        'helm-keyboard-quit)
192     (define-key map (kbd "<right>")    'helm-next-source)
193     (define-key map (kbd "<left>")     'helm-previous-source)
194     (define-key map (kbd "<RET>")      'helm-maybe-exit-minibuffer)
195     (define-key map (kbd "C-i")        'helm-select-action)
196     (define-key map (kbd "C-z")        'helm-execute-persistent-action)
197     (define-key map (kbd "C-j")        'helm-execute-persistent-action)
198     (define-key map (kbd "C-o")        'helm-next-source)
199     (define-key map (kbd "M-o")        'helm-previous-source)
200     (define-key map (kbd "C-l")        'helm-recenter-top-bottom-other-window)
201     (define-key map (kbd "M-C-l")      'helm-reposition-window-other-window)
202     (define-key map (kbd "C-M-v")      'helm-scroll-other-window)
203     (define-key map (kbd "M-<next>")   'helm-scroll-other-window)
204     (define-key map (kbd "C-M-y")      'helm-scroll-other-window-down)
205     (define-key map (kbd "C-M-S-v")    'helm-scroll-other-window-down)
206     (define-key map (kbd "M-<prior>")  'helm-scroll-other-window-down)
207     (define-key map (kbd "<C-M-down>") 'helm-scroll-other-window)
208     (define-key map (kbd "<C-M-up>")   'helm-scroll-other-window-down)
209     (define-key map (kbd "C-@")        'helm-toggle-visible-mark)
210     (define-key map (kbd "C-SPC")      'helm-toggle-visible-mark)
211     (define-key map (kbd "M-SPC")      'helm-toggle-visible-mark)
212     (define-key map (kbd "M-[")        nil)
213     (define-key map (kbd "M-(")        'helm-prev-visible-mark)
214     (define-key map (kbd "M-)")        'helm-next-visible-mark)
215     (define-key map (kbd "C-k")        'helm-delete-minibuffer-contents)
216     (define-key map (kbd "C-x C-f")    'helm-quit-and-find-file)
217     (define-key map (kbd "M-m")        'helm-toggle-all-marks)
218     (define-key map (kbd "M-a")        'helm-mark-all)
219     (define-key map (kbd "M-U")        'helm-unmark-all)
220     (define-key map (kbd "C-M-a")      'helm-show-all-in-this-source-only)
221     (define-key map (kbd "C-M-e")      'helm-display-all-sources)
222     (define-key map (kbd "C-s")        'undefined)
223     (define-key map (kbd "M-s")        'undefined)
224     (define-key map (kbd "C-}")        'helm-narrow-window)
225     (define-key map (kbd "C-{")        'helm-enlarge-window)
226     (define-key map (kbd "C-c -")      'helm-swap-windows)
227     (define-key map (kbd "C-c _")      'helm-toggle-full-frame)
228     (define-key map (kbd "C-c %")      'helm-exchange-minibuffer-and-header-line)
229     (define-key map (kbd "C-c C-y")    'helm-yank-selection)
230     (define-key map (kbd "C-c C-k")    'helm-kill-selection-and-quit)
231     (define-key map (kbd "C-c C-i")    'helm-copy-to-buffer)
232     (define-key map (kbd "C-c C-f")    'helm-follow-mode)
233     (define-key map (kbd "C-c C-u")    'helm-refresh)
234     (define-key map (kbd "C-c >")      'helm-toggle-truncate-line)
235     (define-key map (kbd "M-p")        'previous-history-element)
236     (define-key map (kbd "M-n")        'next-history-element)
237     (define-key map (kbd "C-!")        'helm-toggle-suspend-update)
238     (define-key map (kbd "C-x b")      'helm-resume-previous-session-after-quit)
239     (define-key map (kbd "C-x C-b")    'helm-resume-list-buffers-after-quit)
240     (helm-define-key-with-subkeys map (kbd "C-c n") ?n 'helm-run-cycle-resume)
241     ;; Disable `file-cache-minibuffer-complete'.
242     (define-key map (kbd "<C-tab>")    'undefined)
243     ;; Multi keys
244     (define-key map (kbd "C-t")        'helm-toggle-resplit-and-swap-windows)
245     ;; Debugging command
246     (define-key map (kbd "C-h C-d")    'undefined)
247     (define-key map (kbd "C-h C-d")    'helm-enable-or-switch-to-debug)
248     (define-key map (kbd "C-h c")      'helm-customize-group)
249     ;; Allow to eval keymap without errors.
250     (define-key map [f1] nil)
251     (define-key map (kbd "C-h C-h")    'undefined)
252     (define-key map (kbd "C-h h")      'undefined)
253     (helm-define-key-with-subkeys map
254       (kbd "C-w") ?\C-w 'helm-yank-text-at-point
255       '((?\C-_ . helm-undo-yank-text-at-point)))
256     ;; Use `describe-mode' key in `global-map'.
257     (cl-dolist (k (where-is-internal 'describe-mode global-map))
258       (define-key map k 'helm-help))
259     (define-key map (kbd "C-c ?")    'helm-help)
260     ;; Bind all actions from 1 to 12 to their corresponding nth index+1.
261     (cl-loop for n from 0 to 12 do
262              (define-key map (kbd (format "<f%s>" (1+ n)))
263                `(lambda ()
264                   (interactive)
265                   (helm-select-nth-action ,n))))
266     map)
267   "Keymap for helm.")
268
269 (defun helm-customize-group ()
270   "Jump to customization group of current source.
271
272 Default to `helm' when group is not defined in source."
273   (interactive)
274   (helm-run-after-exit 'customize-group (helm-attr 'group)))
275 (put 'helm-customize-group 'helm-only t)
276
277 (defun helm--action-at-nth-set-fn-1 (value &optional negative)
278   (cl-loop for n from 1 to 9
279         for key = (format value n)
280         for sym = (make-symbol (format "helm-execute-selection-action-at-nth-+%d" n))
281         for fn = `(lambda ()
282                      (interactive)
283                      (helm-execute-selection-action-at-nth ,(if negative (- n) n)))
284         do (progn
285              (defalias sym fn)
286              (define-key helm-map (kbd key) sym))))
287
288 (defun helm--action-at-nth-set-fn- (var val)
289   (set var val)
290   (helm--action-at-nth-set-fn-1 val 'negative))
291
292 (defun helm--action-at-nth-set-fn+ (var val)
293   (set var val)
294   (helm--action-at-nth-set-fn-1 val))
295
296 (defcustom helm-action-at-nth-negative-prefix-key "C-x %d"
297   "The prefix key to execute default action on nth <-n> candidate.
298
299 This is a format spec where %d will be replaced by the candidate
300 number.
301
302 NOTE: `setq' have no effect until you restart emacs, use customize for
303 immediate effect."
304   :group 'helm
305   :type 'string
306   :set #'helm--action-at-nth-set-fn-)
307
308 (defcustom helm-action-at-nth-positive-prefix-key "C-c %d"
309   "The prefix key to execute default action on nth <+n> candidate.
310
311 This is a format spec where %d will be replaced by the candidate
312 number.
313
314 NOTE: `setq' have no effect until you restart emacs, use customize for
315 immediate effect."
316   :group 'helm
317   :type 'string
318   :set #'helm--action-at-nth-set-fn+)
319
320
321 (defgroup helm nil
322   "Open helm."
323   :prefix "helm-" :group 'convenience)
324
325 (defcustom helm-completion-window-scroll-margin 5
326   " `scroll-margin' to use for helm completion window.
327 Set to 0 to disable.
328 NOTE: This has no effect when `helm-display-source-at-screen-top'
329 id is non-`nil'."
330   :group 'helm
331   :type  'integer)
332
333 (defcustom helm-display-source-at-screen-top t
334   "Display candidates at the top of screen.
335 This happens with `helm-next-source' and `helm-previous-source'.
336 NOTE: When non-`nil' (default), disable `helm-completion-window-scroll-margin'."
337   :group 'helm
338   :type 'boolean)
339
340 (defcustom helm-candidate-number-limit 100
341   "Global limit for number of candidates displayed.
342 When the pattern is empty, the number of candidates shown will be
343 as set here instead of the entire list, which may be hundreds or
344 thousands. Since narrowing and filtering rapidly reduces
345 available candidates, having a small list will keep the interface
346 responsive.
347
348 Set this value to nil for no limit."
349   :group 'helm
350   :type '(choice (const :tag "Disabled" nil) integer))
351
352 (defcustom helm-input-idle-delay 0.01
353   "Idle time before updating, specified in seconds."
354   :group 'helm
355   :type 'float)
356
357 (defcustom helm-exit-idle-delay 0
358   "Idle time before exiting minibuffer while helm is updating.
359 Has no affect when helm-buffer is up to date \(i.e exit without
360 delay in this condition\)."
361   :group 'helm
362   :type 'float)
363
364 (defvaralias 'helm-samewindow 'helm-full-frame)
365 (make-obsolete-variable 'helm-samewindow 'helm-full-frame "1.4.8.1")
366 (defcustom helm-full-frame nil
367   "Use current window for showing candidates.
368 If t, then Helm does not pop-up new window."
369   :group 'helm
370   :type 'boolean)
371
372 (defcustom helm-candidate-separator
373   "--------------------"
374   "Candidates separator of `multiline' source."
375   :group 'helm
376   :type 'string)
377
378 (defcustom helm-save-configuration-functions
379   '(set-window-configuration . current-window-configuration)
380   "Functions used to restore or save configurations for frames and windows.
381 Specified as a pair of functions, where car is the restore function and cdr
382 is the save function.
383
384 To save and restore frame configuration, set this variable to
385 '\(set-frame-configuration . current-frame-configuration\)
386
387 NOTE: This may not work properly with own-frame minibuffer
388 settings. Older versions saves/restores frame configuration, but
389 the default has changed now to avoid flickering."
390   :group 'helm
391   :type 'sexp)
392
393 (defcustom helm-display-function 'helm-default-display-buffer
394   "Function used to display `helm-buffer'.
395
396 Local value in `helm-buffer' will take precedence on this default
397 value. Commands that are in `helm-commands-using-frame' will have
398 `helm-buffer' displayed in frame, `helm-display-function' being
399 ignored.
400 If no local value found and current command is not one of
401 `helm-commands-using-frame' use this default value.
402 Function in charge of deciding which value use is
403 `helm-resolve-display-function'.
404  
405 To set it locally to `helm-buffer' in helm sources use
406 `helm-set-local-variable' in init function or use
407 :display-function slot in `helm' call."
408   :group 'helm
409   :type 'symbol)
410
411 (defcustom helm-case-fold-search 'smart
412   "Adds 'smart' option to `case-fold-search'.
413 Smart option ignores case for searches as long as there are no
414 upper case characters in the pattern.
415
416 Use nil or t to turn off smart behavior and use
417 `case-fold-search' behavior.
418
419 Default is smart.
420
421 NOTE: Case fold search has no effect when searching asynchronous
422 sources, which rely on customized features implemented directly
423 into their execution process. See helm-grep.el for an example."
424   :group 'helm
425   :type '(choice (const :tag "Ignore case" t)
426                  (const :tag "Respect case" nil)
427                  (other :tag "Smart" 'smart)))
428
429 (defcustom helm-file-name-case-fold-search
430   (if (memq system-type
431             '(cygwin windows-nt ms-dos darwin))
432       t
433     helm-case-fold-search)
434   "Local setting of `helm-case-fold-search' for reading filenames.
435
436 See `helm-case-fold-search' for more info."
437   :group 'helm
438   :type 'symbol)
439
440 (defcustom helm-reuse-last-window-split-state nil
441   "Use the same state of window split, vertical or horizontal.
442 `helm-toggle-resplit-window' for the next helm session will use
443 the same window scheme as the previous session unless
444 `helm-split-window-default-side' is 'same or 'other."
445   :group 'helm
446   :type 'boolean)
447
448 (defcustom helm-split-window-preferred-function 'helm-split-window-default-fn
449   "Default function used for splitting window."
450   :group 'helm
451   :type 'function)
452
453 (defcustom helm-split-window-default-side 'below
454   "The default side to display `helm-buffer'.
455 Must be one acceptable arg for `split-window' SIDE,
456 that is `below', `above', `left' or `right'.
457
458 Other acceptable values are `same' which always display
459 `helm-buffer' in current window and `other' that display
460 `helm-buffer' below if only one window or in
461 `other-window-for-scrolling' when available.
462
463 A nil value has same effect as `below'.
464 If `helm-full-frame' is non-`nil', it take precedence over this setting.
465
466 See also `helm-split-window-inside-p' and `helm-always-two-windows' that
467 take precedence over this.
468
469 NOTE: this have no effect if `helm-split-window-preferred-function' is not
470 `helm-split-window-default-fn' unless this new function can handle this."
471   :group 'helm
472   :type 'symbol)
473
474 (defcustom helm-display-buffer-default-height nil
475   "Initial height of `helm-buffer', specified as an integer or a function.
476
477 The function should take one arg and the responsibility for
478 re-sizing the window; function's return value is ignored.
479 Note that this have no effect when the split is vertical.
480 See `display-buffer' for more info."
481   :group 'helm
482   :type '(choice integer function))
483
484 (defcustom helm-display-buffer-default-width nil
485   "Initial width of `helm-buffer', specified as an integer or a function.
486
487 The function should take one arg and the responsibility for
488 re-sizing the window; function's return value is ignored.
489 Note that this have no effect when the split is horizontal.
490 See `display-buffer' for more info."
491   :group 'helm
492   :type '(choice integer function))
493
494 (defvaralias 'helm-split-window-in-side-p 'helm-split-window-inside-p)
495 (make-obsolete-variable 'helm-split-window-in-side-p 'helm-split-window-inside-p "2.8.6")
496 (defcustom helm-split-window-inside-p nil
497   "Forces split inside selected window when non-`nil'.
498 See also `helm-split-window-default-side'.
499
500 NOTE: this has no effect if
501 `helm-split-window-preferred-function' is not
502 `helm-split-window-default-fn' unless this new function can
503 handle this."
504   :group 'helm
505   :type 'boolean)
506
507 (defcustom helm-always-two-windows nil
508   "When non-`nil' helm uses two windows in this frame.
509 To display `helm-buffer' in one window and `helm-current-buffer'
510 in the other.
511
512 Note: this has no effect when `helm-split-window-inside-p' is non-`nil',
513 or when `helm-split-window-default-side' is set to 'same.
514
515 When `helm-autoresize-mode' is enabled, setting this to nil
516 will have no effect.
517
518 Also when non-`nil' it overrides the effect of `helm-split-window-default-side'
519 set to `other'."
520   :group 'helm
521   :type 'boolean)
522
523 (defcustom helm-display-buffer-width 72
524   "Frame width when displaying helm-buffer in own frame."
525   :group 'helm
526   :type 'integer)
527
528 (defcustom helm-display-buffer-height 20
529   "Frame height when displaying helm-buffer in own frame."
530   :group 'helm
531   :type 'integer)
532
533 (defcustom helm-default-display-buffer-functions nil
534   "Action functions to pass to `display-buffer'.
535 See (info \"(elisp) Display Action Functions\").
536
537 Have no effect when `helm-always-two-windows' is non-nil and may
538 override other settings like `helm-split-window-inside-p'."
539   :group 'helm
540   :type '(repeat symbol))
541
542 (defcustom helm-default-display-buffer-alist nil
543   "Additional alist to pass to `display-buffer' action.
544 See (info \"(elisp) Display Action Functions\").
545
546 Have no effect when `helm-always-two-windows' is non-nil and may
547 override other settings like `helm-split-window-inside-p'.
548 Note that window-height and window-width have to be configured in
549 `helm-display-buffer-height' and `helm-display-buffer-width'."
550   :group 'helm
551   :type '(alist :key-type symbol :value-type sexp))
552
553 (defcustom helm-sources-using-default-as-input '(helm-source-imenu
554                                                  helm-source-imenu-all
555                                                  helm-source-info-elisp
556                                                  helm-source-etags-select
557                                                  helm-source-man-pages
558                                                  helm-source-occur
559                                                  helm-source-moccur
560                                                  helm-source-grep-ag
561                                                  helm-source-grep-git
562                                                  helm-source-grep)
563   "List of helm sources that need to use `helm--maybe-use-default-as-input'.
564 When a source is a member of this list, default `thing-at-point'
565 will be used as input."
566   :group 'helm
567   :type '(repeat (choice symbol)))
568
569 (defcustom helm-delete-minibuffer-contents-from-point t
570   "When non-`nil', `helm-delete-minibuffer-contents' delete region from `point'.
571 Otherwise delete `minibuffer-contents'.
572 See documentation for  `helm-delete-minibuffer-contents'."
573   :group 'helm
574   :type 'boolean)
575
576 (defcustom helm-follow-mode-persistent nil
577   "When non-`nil', save last state of `helm-follow-mode' for the next emacs sessions.
578
579 Each time you turn on or off `helm-follow-mode', the current source name will be stored
580 or removed from `helm-source-names-using-follow'.
581
582 Note that this may be disabled in some places where it is unsafe to use
583 because persistent action is changing according to context."
584   :group 'helm
585   :type 'boolean)
586
587 (defcustom helm-source-names-using-follow nil
588   "A list of source names to have follow enabled.
589 This list of source names will be used only
590 when `helm-follow-mode-persistent' is non-nil.
591
592 You don't have to customize this yourself unless you really want and
593 know what you are doing, instead just set
594 `helm-follow-mode-persistent' to non-nil and as soon you turn on or
595 off `helm-follow-mode' (C-c C-f) in a source, helm will save or remove
596 source name in this variable."
597   :group 'helm
598   :type '(repeat (choice string)))
599
600 (defcustom helm-prevent-escaping-from-minibuffer t
601   "Prevent escaping from minibuffer with `other-window' during the helm session."
602   :group 'helm
603   :type 'boolean)
604
605 (defcustom helm-allow-mouse nil
606   "Allow mouse usage during the helm session when non-nil.
607
608 Note that this also allow moving out of minibuffer when clicking
609 outside of `helm-buffer', up to you to get back to helm by clicking
610 back in `helm-buffer' of minibuffer."
611   :group 'helm
612   :type 'boolean)
613
614 (defcustom helm-move-to-line-cycle-in-source nil
615   "Cycle to the beginning or end of the list after reaching the bottom or top.
616 This applies when using `helm-next/previous-line'."
617   :group 'helm
618   :type 'boolean)
619
620 (defcustom helm-fuzzy-match-fn 'helm-fuzzy-match
621   "The function for fuzzy matching in `helm-source-sync' based sources."
622   :group 'helm
623   :type 'function)
624
625 (defcustom helm-fuzzy-search-fn 'helm-fuzzy-search
626   "The function for fuzzy matching in `helm-source-in-buffer' based sources."
627   :group 'helm
628   :type 'function)
629
630 (defcustom helm-fuzzy-sort-fn 'helm-fuzzy-matching-default-sort-fn
631   "The sort transformer function used in fuzzy matching.
632 When nil, sorting is not done."
633   :group 'helm
634   :type 'function)
635
636 (defcustom helm-fuzzy-matching-highlight-fn 'helm-fuzzy-default-highlight-match
637   "The function to highlight fuzzy matches.
638 When nil, no highlighting is done."
639   :group 'helm
640   :type 'function)
641
642 (defcustom helm-autoresize-max-height 40
643   "Specifies maximum height and defaults to percent of helm window's frame height.
644
645 See `fit-window-to-buffer' for more infos."
646   :group 'helm
647   :type 'integer)
648
649 (defcustom helm-autoresize-min-height 10
650   "Specifies minimum height and defaults to percent of helm window's frame height.
651
652 If nil, `window-min-height' is used.
653 See `fit-window-to-buffer' for details."
654   :group 'helm
655   :type 'integer)
656
657 (defcustom helm-input-method-verbose-flag nil
658   "The default value for `input-method-verbose-flag' used in helm minibuffer.
659 It is nil by default, which does not turn off input method. Helm
660 updates and exits without interruption -- necessary for complex methods.
661
662 If set to any other value as per `input-method-verbose-flag',
663 then use `C-\\' to disable the `current-input-method' to exit or update helm"
664   :group 'helm
665   :type '(radio :tag "A flag to control extra guidance for input methods in helm."
666                 (const :tag "Never provide guidance" nil)
667                 (const :tag "Always provide guidance" t)
668                 (const :tag "Provide guidance only for complex methods" complex-only)))
669
670 (defcustom helm-display-header-line t
671   "Display header-line when non nil."
672   :group 'helm
673   :type 'boolean)
674
675 (defcustom helm-inherit-input-method t
676   "Inherit `current-input-method' from `current-buffer' when non-`nil'.
677 The default is to enable this by default and then toggle
678 `toggle-input-method'."
679   :group 'helm
680   :type 'boolean)
681
682 (defcustom helm-echo-input-in-header-line nil
683   "Send current input in header-line when non-nil."
684   :group 'helm
685   :type 'boolean)
686
687 (defcustom helm-header-line-space-before-prompt 'left-fringe
688   "Specify the space before prompt in header-line.
689
690 This will be used when `helm-echo-input-in-header-line' is non-nil.
691
692 Value can be one of the symbols 'left-fringe or 'left-margin or an
693 integer specifying the number of spaces before prompt.
694 Note that on input longer that `window-width' the continuation string
695 will be shown on left side of window without taking care of this."
696   :group 'helm
697   :type '(choice
698           (symbol
699            (const :tag "Fringe" 'left-fringe)
700            (const :tag "Margin" 'left-margin))
701           integer))
702
703 (defcustom helm-tramp-connection-min-time-diff 5
704   "Value of `tramp-connection-min-time-diff' for helm remote processes.
705 If set to zero helm remote processes are not delayed.
706 Setting this to a value less than 5 or disabling it with a zero value
707 is risky, however on emacs versions starting at 24.5 it seems
708 it is now possible to disable it.
709 Anyway at any time in helm you can suspend your processes while typing
710 by hitting \\<helm-map> `\\[helm-toggle-suspend-update]'.
711 Only async sources than use a sentinel calling
712 `helm-process-deferred-sentinel-hook' are affected by this."
713   :type 'integer
714   :group 'helm)
715
716 (defcustom helm-debug-root-directory nil
717   "When non-`nil', saves helm log messages to a file in this directory.
718 When `nil' log messages are saved to a buffer instead.
719 Log message are saved only when `helm-debug' is non-nil, so setting this
720 doesn't enable debugging by itself.
721
722 See `helm-log-save-maybe' for more info."
723   :type 'string
724   :group 'helm)
725
726 (defcustom helm-show-action-window-other-window nil
727   "Show action buffer beside `helm-buffer' when non-nil.
728
729 If nil don't split and replace helm-buffer by the action buffer
730 in same window.
731 If left display the action buffer at the left of helm-buffer.
732 If right or any other value, split at right.
733
734 Note that this may not fit well with some helm window configurations,
735 so it have only effect when `helm-always-two-windows' is non-nil."
736   :group 'helm
737   :type '(choice
738           (const :tag "Split at left" left)
739           (const :tag "Don't split" nil)
740           (other :tag "Split at right" right)))
741
742 (defcustom helm-cycle-resume-delay 1.0
743   "Delay used before resuming in `helm-run-cycle-resume'."
744   :type 'float
745   :group 'helm)
746
747 (defcustom helm-display-buffer-reuse-frame nil
748   "When non nil helm frame is not deleted and reused in next sessions.
749
750 This was used to workaround a bug in emacs where frames where
751 popping up slowly, now that the bug have been fixed upstream probably
752 you don't want to use this anymore."
753   :group 'helm
754   :type 'boolean)
755
756 (defcustom helm-commands-using-frame nil
757   "A list of commands where `helm-buffer' is displayed in a frame."
758   :group 'helm
759   :type '(repeat symbol))
760
761 (defcustom helm-actions-inherit-frame-settings t
762   "Actions inherit helm frame settings of initial command when non nil."
763   :group 'helm
764   :type 'boolean)
765
766 (defcustom helm-use-undecorated-frame-option t
767   "Display helm frame undecorated when non nil.
768
769 This option have no effect with emacs versions lower than 26."
770   :group 'helm
771   :type 'boolean)
772
773 (defcustom helm-use-frame-when-more-than-two-windows nil
774   "Display helm buffer in frame when more than two windows."
775   :group 'helm
776   :type 'boolean)
777
778 (defcustom helm-default-prompt-display-function
779   #'helm-set-default-prompt-display
780   "The function to use to set face of fake cursor in header-line."
781   :group 'helm
782   :type 'function)
783
784 ;;; Faces
785 ;;
786 ;;
787 (defgroup helm-faces nil
788   "Customize the appearance of helm."
789   :prefix "helm-"
790   :group 'faces
791   :group 'helm)
792
793 (defface helm-source-header
794   '((((background dark))
795      :background "#22083397778B"
796      :foreground "white"
797      :weight bold :height 1.3 :family "Sans Serif")
798     (((background light))
799      :background "#abd7f0"
800      :foreground "black"
801      :weight bold :height 1.3 :family "Sans Serif"))
802   "Face for source header in the helm buffer."
803   :group 'helm-faces)
804
805 (defface helm-visible-mark
806   '((((min-colors 88) (background dark))
807      (:background "green1" :foreground "black"))
808     (((background dark))
809      (:background "green" :foreground "black"))
810     (((background light)) :background "#d1f5ea")
811     (((min-colors 88))
812      (:background "green1"))
813     (t (:background "green")))
814   "Face for visible mark."
815   :group 'helm-faces)
816
817 (defface helm-header
818   '((t (:inherit header-line)))
819   "Face for header lines in the helm buffer."
820   :group 'helm-faces)
821
822 (defface helm-candidate-number
823   '((((background dark)) :background "Yellow" :foreground "black")
824     (((background light)) :background "#faffb5" :foreground "black"))
825   "Face for candidate number in mode-line."
826   :group 'helm-faces)
827
828 (defface helm-candidate-number-suspended
829   '((t (:inherit helm-candidate-number :inverse-video t)))
830   "Face for candidate number in mode-line when helm is suspended."
831   :group 'helm-faces)
832
833 (defface helm-selection
834   '((((background dark)) :background "ForestGreen"
835      :distant-foreground "black")
836     (((background light)) :background "#b5ffd1"
837      :distant-foreground "black"))
838   "Face for currently selected item in the helm buffer."
839   :group 'helm-faces)
840
841 (defface helm-separator
842   '((((background dark)) :foreground "red")
843     (((background light)) :foreground "#ffbfb5"))
844   "Face for multiline source separator."
845   :group 'helm-faces)
846
847 (defface helm-action
848   '((t (:underline t)))
849   "Face for action lines in the helm action buffer."
850   :group 'helm-faces)
851
852 (defface helm-prefarg
853   '((((background dark)) :foreground "green")
854     (((background light)) :foreground "red"))
855   "Face for showing prefix arg in mode-line."
856   :group 'helm-faces)
857
858 (defface helm-match
859   '((((background light)) :foreground "#b00000")
860     (((background dark))  :foreground "gold1"))
861   "Face used to highlight matches."
862   :group 'helm-faces)
863
864 (defface helm-header-line-left-margin
865   '((t (:foreground "black" :background "yellow")))
866   "Face used to highlight helm-header sign in left-margin."
867   :group 'helm-faces)
868
869 (defface helm-minibuffer-prompt
870   '((t (:inherit minibuffer-prompt)))
871   "Face used for the minibuffer/headline prompt (such as Pattern:) in helm."
872   :group 'helm-faces)
873
874
875 ;;; Variables.
876 ;;
877 ;;
878 (defvar helm-selection-overlay nil
879   "Overlay used to highlight the currently selected item.")
880
881 (defvar helm-async-processes nil
882   "List of information about asynchronous processes managed by helm.")
883
884 (defvar helm-before-initialize-hook nil
885   "Runs before helm initialization.
886 This hook runs before init functions in `helm-sources', which is
887 before creation of `helm-buffer'. Set local variables for
888 `helm-buffer' that need a value from `current-buffer' with
889 `helm-set-local-variable'.")
890
891 (defvar helm-after-initialize-hook nil
892   "Runs after helm initialization.
893 This hook runs after `helm-buffer' is created but not from
894 `helm-buffer'. The hook needs to specify in which buffer to run.")
895
896 (defvaralias 'helm-update-hook 'helm-after-update-hook)
897 (make-obsolete-variable 'helm-update-hook 'helm-after-update-hook "1.9.9")
898
899 (defvar helm-after-update-hook nil
900   "Runs after updating the helm buffer with the new input pattern.")
901
902 (defvar helm-cleanup-hook nil
903   "Runs after exiting the minibuffer and before performing an
904 action.
905
906 This hook runs even if helm exits the minibuffer abnormally (e.g.
907 via `helm-keyboard-quit').")
908
909 (defvar helm-select-action-hook nil
910   "Runs when opening the action buffer.")
911
912 (defvar helm-before-action-hook nil
913   "Runs before executing action.
914 Unlike `helm-cleanup-hook', this hook runs before helm closes the
915 minibuffer and also before performing an action.")
916
917 (defvar helm-after-action-hook nil
918   "Runs after executing action.")
919
920 (defvar helm-exit-minibuffer-hook nil
921   "Runs just before exiting the minibuffer.
922
923 This hook runs when helm exits the minibuffer normally (e.g. via
924 candidate selection), but does NOT run if helm exits the
925 minibuffer abnormally (e.g. via `helm-keyboard-quit').")
926
927 (defvar helm-after-persistent-action-hook nil
928   "Runs after executing persistent action.")
929
930 (defvar helm-move-selection-before-hook nil
931   "Runs before moving selection in `helm-buffer'.")
932
933 (defvar helm-move-selection-after-hook nil
934   "Runs after moving selection in `helm-buffer'.")
935
936 (defvar helm-after-preselection-hook nil
937   "Runs after pre-selection in `helm-buffer'.")
938
939 (defvar helm-window-configuration-hook nil
940   "Runs when switching to and from the action buffer.")
941
942 (defvar helm-execute-action-at-once-if-one nil
943   "When non--nil executes the default action and then exits if only one candidate.
944 If symbol 'current-source is given as value exit if only one candidate
945 in current source.
946 This variable accepts a function with no args that should returns a boolean
947 value or 'current-source.")
948
949 (defvar helm-quit-if-no-candidate nil
950   "When non-`nil', quits if there are no candidates.
951 This variable accepts a function.")
952
953 (defvar helm-debug-variables nil
954   "A list of helm variables that `helm-debug-output' displays.
955 If `nil', `helm-debug-output' includes only variables with
956 `helm-' prefixes.")
957
958 (defvar helm-debug-buffer "*Debug Helm Log*")
959
960 (defvar helm-debug nil
961   "If non-`nil', write log message to `helm-debug-buffer'.
962 Default is `nil', which disables writing log messages because the
963 size of `helm-debug-buffer' grows quickly.")
964
965 (defvar helm-mode-line-string "\
966 \\<helm-map>\
967 \\[helm-help]:Help \
968 \\[helm-select-action]:Act \
969 \\[helm-maybe-exit-minibuffer]/\
970 f1/f2/f-n:NthAct \
971 \\[helm-toggle-suspend-update]:Tog.suspend"
972   "Help string displayed by helm in the mode-line.
973 It is either a string or a list of two string arguments where the
974 first string is the name and the second string is displayed in
975 the mode-line. When `nil', uses default `mode-line-format'.")
976
977 (defvar helm-minibuffer-set-up-hook nil
978   "Hook that runs at minibuffer initialization.
979 A hook useful for modifying minibuffer settings in helm.
980
981 An example that hides the minibuffer when using
982 `helm-echo-input-in-header-line':
983
984       (add-hook 'helm-minibuffer-set-up-hook #'helm-hide-minibuffer-maybe)
985
986 Note that we check `helm-echo-input-in-header-line' value
987 from `helm-buffer' which allow detecting possible local
988 value of this var.")
989
990 (defvar helm-help-message
991   "* Helm Generic Help
992 ** Basics
993
994 Helm narrows down the list of candidates as you type a filter pattern.
995
996 Helm accepts multiple space-separated patterns, each pattern can be negated with \"!\".
997
998 Helm also supports fuzzy matching in some places when specified, you will find
999 several variables to enable fuzzy matching in diverse sources,
1000 see [[https://github.com/emacs-helm/helm/wiki/Fuzzy-matching][fuzzy-matching]] in helm-wiki for more infos.
1001
1002 Helm generally uses familiar Emacs keys to navigate the list.
1003 Here follow some of the less obvious bindings:
1004
1005 - `\\[helm-maybe-exit-minibuffer]' selects the candidate from the list, executes the default action
1006 upon exiting the Helm session.
1007
1008 - `\\[helm-execute-persistent-action]' executes the default action but without exiting the Helm session.
1009 Not all sources support this.
1010
1011 - `\\[helm-select-action]' displays a list of actions available on current candidate or all marked candidates.
1012 The default binding <tab> is ordinarily used for completion, but that would be
1013 redundant since Helm completes upon every character entered in the prompt.
1014 See [[https://github.com/emacs-helm/helm/wiki#helm-completion-vs-emacs-completion][Helm wiki]].
1015
1016 Note: In addition to the default actions list, additional actions appear
1017 depending of the type of the selected candidate(s).  They are called filtered
1018 actions.
1019
1020 ** Helm mode
1021
1022 `helm-mode' toggles Helm completion in native Emacs functions,
1023 so when you turn `helm-mode' on, commands like `switch-to-buffer' will use
1024 Helm completion instead of the usual Emacs completion buffer.
1025
1026 *** What gets or does not get \"helmized\" when `helm-mode' is enabled?
1027
1028 Helm provides generic completion on all Emacs functions using `completing-read',
1029 `completion-in-region' and their derivatives, e.g. `read-file-name'.  Helm
1030 exposes a user variable to control which function to use for a specific Emacs
1031 command: `helm-completing-read-handlers-alist'.  If the function for a specific
1032 command is nil, it turns off Helm completion.  See the variable documentation
1033 for more infos.
1034
1035 *** Helm functions vs helmized Emacs functions
1036
1037 While there are Helm functions that perform the same completion as other
1038 helmized Emacs functions, e.g. `switch-to-buffer' and `helm-buffers-list', the
1039 native Helm functions like `helm-buffers-list' can receive new features, the
1040 allow marking candidates, they have several actions, etc.  Whereas the helmized
1041 Emacs functions only have Helm completion, one action and no more then Emacs can
1042 provide for this function.  This is the intended behavior.
1043
1044 Generally you are better off using the native Helm command
1045 than the helmized Emacs equivalent.
1046
1047 ** Helm help
1048
1049 \\[helm-documentation]: Show all helm documentations concatenated in one org file.
1050
1051 From a Helm session, just hit \\<helm-map>\\[helm-help] to have the
1052 documentation for the current source followed by the global Helm documentation.
1053
1054 While in the help buffer, most of the regular keybindings are available in an
1055 Emacs buffers; the most important ones are shown in minibuffer.  However due to
1056 the implementation restrictions, no regular Emacs keymap is used (it runs in a
1057 loop when reading the help buffer) they are hardcoded and not modifiable.
1058
1059 The hard-coded documentation bindings are:
1060
1061 | Key       | Alternative keys | Command             |
1062 |-----------+------------------+---------------------|
1063 | C-v       | Space next       | Scroll up           |
1064 | M-v       | b prior          | Scroll down         |
1065 | C-s       |                  | Isearch forward     |
1066 | C-r       |                  | Isearch backward    |
1067 | C-a       |                  | Beginning of line   |
1068 | C-e       |                  | End of line         |
1069 | C-f       | right            | Forward char        |
1070 | C-b       | left             | Backward char       |
1071 | C-n       | down             | Next line           |
1072 | C-p       | up               | Previous line       |
1073 | M-a       |                  | Backward sentence   |
1074 | M-e       |                  | Forward sentence    |
1075 | M-f       |                  | Forward word        |
1076 | M-b       |                  | Backward word       |
1077 | M->       |                  | End of buffer       |
1078 | M-<       |                  | Beginning of buffer |
1079 | C-<SPACE> |                  | Toggle mark         |
1080 | RET       |                  | Follow org link     |
1081 | C-%       |                  | Push org mark       |
1082 | C-&       |                  | Goto org mark-ring  |
1083 | TAB       |                  | Org cycle           |
1084 | M-<TAB>   |                  | Toggle visibility   |
1085 | M-w       |                  | Copy region         |
1086 | q         |                  | Quit                |
1087
1088 ** Customize Helm
1089
1090 Helm provides a lot of user variables for extensive customization.
1091 From any Helm session, type \\<helm-map>\\[helm-customize-group] to jump to the current source `custom' group.
1092 Helm also has a special group for faces you can access via `M-x customize-group RET helm-faces'.
1093
1094 Note: Some sources may not have their group set and default to the `helm' group.
1095
1096 ** Helm's basic operations and default key bindings
1097
1098 | Key     | Alternative Keys | Command                                                              |
1099 |---------+------------------+----------------------------------------------------------------------|
1100 | C-p     | Up               | Previous line                                                        |
1101 | C-n     | Down             | Next line                                                            |
1102 | M-v     | prior            | Previous page                                                        |
1103 | C-v     | next             | Next page                                                            |
1104 | Enter   |                  | Execute first (default) action / Select                              |
1105 | M-<     |                  | First line                                                           |
1106 | M->     |                  | Last line                                                            |
1107 | C-M-S-v | M-prior, C-M-y   | Previous page (other-window)                                         |
1108 | C-M-v   | M-next           | Next page (other-window)                                             |
1109 | Tab     | C-i              | Show action list                                                     |
1110 | Left    |                  | Previous source                                                      |
1111 | Right   | C-o              | Next source                                                          |
1112 | C-k     |                  | Delete pattern (with prefix arg delete from point to end or all [1]) |
1113 | C-j     | C-z              | Persistent action (Execute and keep Helm session)                    |
1114
1115 \[1] Delete from point to end or all depending on the value of
1116 `helm-delete-minibuffer-contents-from-point'.
1117
1118 ** Shortcuts for n-th action
1119
1120 f1-f12: Execute n-th action where n is 1 to 12.
1121
1122 ** Shortcuts for executing the default action on the n-th candidate
1123
1124 C-x <n>: Execute default action on the n-th candidate before currently selected candidate.
1125
1126 C-c <n>: Execute default action on the n-th candidate after current selected candidate.
1127
1128 \"n\" is limited to 1-9.  For larger jumps use other navigation keys.  Helm does
1129 not display line numbers by default: enable them with the
1130 \[[https://github.com/coldnew/linum-relative][linum-relative]] package and
1131 `helm-linum-relative-mode'.
1132 If you are using Emacs-26+ version you can use `global-display-line-numbers-mode'
1133 which seems even better (don't forget to customize `display-line-numbers-type' to relative).
1134
1135 ** Mouse control in Helm
1136
1137 A basic support for the mouse is provided when the user sets `helm-allow-mouse' to non-nil.
1138
1139 - mouse-1 selects the candidate.
1140 - mouse-2 executes the default action on selected candidate.
1141 - mouse-3 pops up the action menu.
1142
1143 Note: When mouse control is enabled in Helm, it also lets you click around and lose
1144 the minibuffer focus: you'll have to click on the Helm buffer or the minibuffer
1145 to retrieve control of your Helm session.
1146
1147 ** Marked candidates
1148
1149 You can mark candidates to execute an action on all of them instead of the
1150 current selected candidate only.  (See bindings below.)  Most Helm actions
1151 operate on marked candidates unless candidate-marking is explicitely forbidden
1152 for a specific source.
1153
1154 - To mark/unmark a candidate, use \\[helm-toggle-visible-mark].  (See bindings below.)
1155 With a numeric prefix arg mark ARG candidates forward, if ARG is negative
1156 mark ARG candidates backward.
1157
1158 - To mark all visible unmarked candidates at once in current source use \\[helm-mark-all].
1159 With a prefix argument, mark all candidates in all sources.
1160
1161 - To unmark all visible marked candidates at once use \\[helm-unmark-all].
1162
1163 - To mark/unmark all candidates at once use \\[helm-toggle-all-marks].
1164 With a prefix argument, mark/unmark all candidates in all sources.
1165
1166 Note: When multiple candidates are selected across different sources, only the
1167 candidates of the current source will be used when executing most actions (as
1168 different sources can have different actions).  Some actions support
1169 multi-source marking however.
1170
1171 ** Follow candidates
1172
1173 When `helm-follow-mode' is on (\\<helm-map>\\[helm-follow-mode] to toggle it),
1174 moving up and down the Helm session or updating the list of candidates will
1175 automatically execute the persistent-action as specified for the current source.
1176
1177 If `helm-follow-mode-persistent' is non-nil, the state of the mode will be
1178 restored for the following Helm sessions.
1179
1180 If you just want to follow candidates occasionally without enabling
1181 `helm-follow-mode', you can use \\<helm-map>\\[helm-follow-action-forward] or \\[helm-follow-action-backward] instead.
1182 Conversely, when `helm-follow-mode' is enabled, those commands
1183 go to previous/next line without executing the persistent action.
1184
1185 ** Frequently Used Commands
1186
1187 \\[helm-toggle-resplit-and-swap-windows]\t\tToggle vertical/horizontal split on first hit and swap Helm window on second hit.
1188 \\[helm-quit-and-find-file]\t\tDrop into `helm-find-files'.
1189 \\[helm-kill-selection-and-quit]\t\tKill display value of candidate and quit (with prefix arg, kill the real value).
1190 \\[helm-yank-selection]\t\tYank current selection into pattern.
1191 \\[helm-copy-to-buffer]\t\tCopy selected candidate at point in current buffer.
1192 \\[helm-follow-mode]\t\tToggle automatic execution of persistent action.
1193 \\[helm-follow-action-forward]\tRun persistent action then select next line.
1194 \\[helm-follow-action-backward]\t\tRun persistent action then select previous line.
1195 \\[helm-refresh]\t\tRecalculate and redisplay candidates.
1196 \\[helm-toggle-suspend-update]\t\tToggle candidate updates.
1197
1198 ** Special yes, no or yes for all answers
1199
1200 You may be prompted in the minibuffer to answer by [y,n,!,q] in some places
1201 for confirmation.
1202
1203 - y  mean yes
1204 - no mean no
1205 - !  mean yes for all
1206 - q  mean quit or abort current operation.
1207
1208 When using ! you will not be prompted anymore for the same thing in current operation
1209 e.g. file deletion, file copy etc...
1210
1211 ** Moving in `helm-buffer'
1212
1213 You can move in `helm-buffer' with the usual commands used in Emacs:
1214 \(\\<helm-map>\\[helm-next-line], \\<helm-map>\\[helm-previous-line], etc.  See above basic commands.
1215 When `helm-buffer' contains more than one source, change source with \\<helm-map>\\[helm-next-source].
1216
1217 Note: When reaching the end of a source, \\<helm-map>\\[helm-next-line] will *not* go to the next source unless
1218 variable `helm-move-to-line-cycle-in-source' is non-nil, so you will have to use \\<helm-map>\\[helm-next-source].
1219
1220 ** Resume previous session from current Helm session
1221
1222 You can use `C-c n' (`helm-run-cycle-resume') to cycle in resumables sources.
1223 `C-c n' is a special key set with `helm-define-key-with-subkeys' which, after pressing it, allows you
1224 to keep cycling with further `n'.
1225
1226 Tip: You can bound the same key in `global-map' to `helm-cycle-resume'
1227      with `helm-define-key-with-subkeys' to let you transparently cycle
1228      sessions, Helm fired up or not.
1229      You can also bind the cycling commands to single key presses (e.g. `S-<f1>') this time
1230      with a simple `define-key'.  (Note that `S-<f1>' is not available in terminals.)
1231
1232 Note: `helm-define-key-with-subkeys' is available only once Helm is loaded.
1233
1234 You can also use \\<helm-map>\\[helm-resume-previous-session-after-quit] to resume
1235 the previous session, or \\<helm-map>\\[helm-resume-list-buffers-after-quit]
1236 to have completion on all resumable buffers.
1237
1238 ** Global commands
1239
1240 *** Resume Helm session from outside Helm
1241
1242 \\<global-map>\\[helm-resume] revives the last `helm' session.  Binding a key to
1243 this command will greatly improve `helm' interactivity, e.g. when quitting Helm
1244 accidentally.
1245
1246 You can call \\<global-map>\\[helm-resume] with a prefix argument to choose
1247 \(with completion!) which session you'd like to resume.  You can also cycle in
1248 these sources with `helm-cycle-resume' (see above).
1249
1250 ** Debugging Helm
1251
1252 Helm exposes the special variable `helm-debug': setting it to non-nil
1253 will enable Helm logging in a special outline-mode buffer.
1254 Helm resets the variable to nil at the end of each session.
1255
1256 For convenience, \\<helm-map>\\[helm-enable-or-switch-to-debug]
1257 allows you to turn on debugging for this session only.
1258 To avoid accumulating log entries while you are typing patterns, you can use
1259 \\<helm-map>\\[helm-toggle-suspend-update] to turn off updating.  When you
1260 are ready turn it on again to resume logging.
1261
1262 Once you exit your Helm session you can access the debug buffer with
1263 `helm-debug-open-last-log'.  It is possible to save logs to dated files when
1264 `helm-debug-root-directory' is set to a valid directory.
1265
1266 Note: Be aware that Helm log buffers grow really fast, so use `helm-debug' only
1267 when needed.
1268
1269 ** Writing your own Helm sources
1270
1271 Writing simple sources for your own usage is easy.  When calling the `helm'
1272 function, the sources are added the :sources slot which can be a symbol or a
1273 list of sources.  Sources can be built with different EIEIO classes depending
1274 what you want to do.  To simplify this, several `helm-build-*' macros are
1275 provided.  Below, simple examples to start with.
1276
1277 We will not go further here, see [[https://github.com/emacs-helm/helm/wiki/Developing][Helm wiki]] and the source
1278 code for more information and more complex exapmles.
1279
1280 #+begin_src elisp
1281
1282     ;; Candidates are stored in a list.
1283     (helm :sources (helm-build-sync-source \"test\"
1284                      ;; A function can be used as well
1285                      ;; to provide candidates.
1286                      :candidates '(\"foo\" \"bar\" \"baz\"))
1287           :buffer \"*helm test*\")
1288
1289     ;; Candidates are stored in a buffer.
1290     ;; Generally faster but doesn't allow a dynamic updating
1291     ;; of the candidates list i.e the list is fixed on start.
1292     (helm :sources (helm-build-in-buffer-source \"test\"
1293                      :data '(\"foo\" \"bar\" \"baz\"))
1294           :buffer \"*helm test*\")
1295
1296 #+end_src
1297
1298 ** Helm Map
1299 \\{helm-map}"
1300   "Message string containing detailed help for `helm'.
1301 It also accepts function or variable symbol.")
1302
1303 (defvar helm-autoresize-mode) ;; Undefined in `helm-default-display-buffer'.
1304
1305 (defvar helm-async-outer-limit-hook nil
1306   "A hook that run in async sources when process output comes out of `candidate-number-limit'.
1307 Should be set locally to `helm-buffer' with `helm-set-local-variable'.")
1308
1309 (defvar helm-quit-hook nil
1310   "A hook that run when quitting helm.")
1311
1312 (defvar helm-resume-after-hook nil
1313   "A hook that run after resuming a helm session.
1314 The hook should take one arg SOURCES.")
1315
1316 ;;; Internal Variables
1317 ;;
1318 ;;
1319 (defvar helm-source-filter nil
1320   "A list of source names to be displayed.
1321 Other sources won't appear in the search results.
1322 If nil, no filtering is done.
1323 Don't set this directly, use `helm-set-source-filter' during helm session
1324 to modify it.")
1325 (defvar helm-current-prefix-arg nil
1326   "Record `current-prefix-arg' when exiting minibuffer.")
1327 (defvar helm-saved-action nil
1328   "Saved value of the currently selected action by key.")
1329 (defvar helm-saved-current-source nil
1330   "Value of the current source when the action list is shown.")
1331 (defvar helm-in-persistent-action nil
1332   "Flag whether in persistent-action or not.")
1333 (defvar helm-last-buffer nil
1334   "`helm-buffer' of previously `helm' session.")
1335 (defvar helm-saved-selection nil
1336   "Value of the currently selected object when the action list is shown.")
1337 (defvar helm-sources nil
1338   "[INTERNAL] Value of current sources in use, a list.")
1339 (defvar helm-buffer-file-name nil
1340   "Variable `buffer-file-name' when `helm' is invoked.")
1341 (defvar helm-candidate-cache (make-hash-table :test 'equal)
1342   "Holds the available candidate within a single helm invocation.")
1343 (defvar helm--candidate-buffer-alist nil)
1344 (defvar helm-input ""
1345   "The input typed in the candidates panel.")
1346 (defvar helm-input-local nil
1347   "Internal, store locally `helm-pattern' value for later use in `helm-resume'.")
1348 (defvar helm--source-name nil)
1349 (defvar helm-current-source nil)
1350 (defvar helm-tick-hash (make-hash-table :test 'equal))
1351 (defvar helm-issued-errors nil)
1352 (defvar helm--last-log-file nil
1353   "The name of the log file of the last helm session.")
1354 (defvar helm--local-variables nil)
1355 (defvar helm-split-window-state nil)
1356 (defvar helm--window-side-state nil)
1357 (defvar helm-selection-point nil)
1358 (defvar helm-alive-p nil)
1359 (defvar helm-visible-mark-overlays nil)
1360 (defvar helm-update-blacklist-regexps '("^" "^ *" "$" "!" " " "\\b"
1361                                         "\\<" "\\>" "\\_<" "\\_>" ".*"
1362                                         "??" "?*" "*?" "?"))
1363 (defvar helm--force-updating-p nil
1364   "[INTERNAL] Don't use this in your programs.")
1365 (defvar helm-exit-status 0
1366   "Flag to inform if helm did exit or quit.
1367 0 means helm did exit when executing an action.
1368 1 means helm did quit with \\[keyboard-quit]
1369 Knowing this exit-status could help restore a window config when helm aborts
1370 in some special circumstances.
1371 See `helm-exit-minibuffer' and `helm-keyboard-quit'.")
1372 (defvar helm-minibuffer-confirm-state nil)
1373 (defvar helm-quit nil)
1374 (defvar helm-buffers nil
1375   "Helm buffers listed in order of most recently used.")
1376 (defvar helm-current-position nil
1377   "Cons of \(point . window-start\)  when `helm' is invoked.
1378 `helm-current-buffer' uses this to restore position after
1379 `helm-keyboard-quit'")
1380 (defvar helm-last-frame-or-window-configuration nil
1381   "Used to store window or frame configuration at helm start.")
1382 (defvar helm-onewindow-p nil)
1383 (defvar helm-types nil)
1384 (defvar helm--mode-line-string-real nil) ; The string to display in mode-line.
1385 (defvar helm-persistent-action-display-window nil)
1386 (defvar helm-marked-candidates nil
1387   "Marked candidates.  List of \(source . real\) pair.")
1388 (defvar helm--mode-line-display-prefarg nil)
1389 (defvar helm--temp-follow-flag nil
1390   "[INTERNAL] A simple flag to notify persistent action we are following.")
1391 (defvar helm--reading-passwd-or-string nil)
1392 (defvar helm--in-update nil)
1393 (defvar helm--in-fuzzy nil)
1394 (defvar helm--maybe-use-default-as-input nil
1395   "Flag to notify the use of use-default-as-input.
1396 Use only in let-bindings.
1397 Use :default arg of `helm' as input to update display.
1398 Note that if also :input is specified as `helm' arg, it will take
1399 precedence on :default.")
1400 (defvar helm--temp-hooks nil
1401   "Store temporary hooks added by `with-helm-temp-hook'.")
1402 (defvar helm-truncate-lines nil
1403   "[Internal] Don't set this globally, it is used as a local var.")
1404 (defvar helm--prompt nil)
1405 (defvar helm--file-completion-sources
1406   '("Find Files" "Read File Name")
1407   "Sources that use the *find-files mechanism can be added here.
1408 Sources generated by `helm-mode' don't need to be added here
1409 because they are automatically added.
1410
1411 You should not modify this yourself unless you know what you are doing.")
1412 (defvar helm--completing-file-name nil
1413   "Non nil when `helm-read-file-name' is running.
1414 Used for `helm-file-completion-source-p'.")
1415 ;; Same as `ffap-url-regexp' but keep it here to ensure `ffap-url-regexp' is not nil.
1416 (defvar helm--url-regexp "\\`\\(news\\(post\\)?:\\|mailto:\\|file:\\|\\(ftp\\|https?\\|telnet\\|gopher\\|www\\|wais\\)://\\)")
1417 (defvar helm--ignore-errors nil
1418   "Flag to prevent helm popping up errors in candidates functions.
1419 Should be set in candidates functions if needed, will be restored
1420 at end of session.")
1421 (defvar helm--action-prompt "Select action: ")
1422 (defvar helm--cycle-resume-iterator nil)
1423 (defvar helm--buffer-in-new-frame-p nil)
1424 (defvar helm-initial-frame nil
1425   "[INTERNAL] The selected frame before starting helm.
1426 Helm use this internally to know in which frame it started, don't
1427 modify this yourself.")
1428 (defvar helm-popup-frame nil
1429   "The frame where helm is displayed.
1430
1431 This is only used when helm is using
1432 `helm-display-buffer-in-own-frame' as `helm-display-function' and
1433 `helm-display-buffer-reuse-frame' is non nil.")
1434 (defvar helm--nested nil)
1435 (defconst helm--frame-default-attributes
1436   '(width height tool-bar-lines left top
1437     title undecorated vertical-scroll-bars
1438     visibility fullscreen menu-bar-lines undecorated)
1439   "Frame parameters to save in `helm--last-frame-parameters'.")
1440 (defvar helm--last-frame-parameters nil
1441   "Frame parameters to save for later resuming.
1442 Local to `helm-buffer'.")
1443 (defvar helm--executing-helm-action nil
1444   "Non nil when action is triggering a new helm-session.
1445 This may be let bounded in other places to notify the display function
1446 to reuse the same frame parameters as the previous helm session just
1447 like resume would do.")
1448 (defvar helm--current-buffer-narrowed nil)
1449 (defvar helm--suspend-update-interactive-flag nil)
1450
1451 ;; Utility: logging
1452 (defun helm-log (format-string &rest args)
1453   "Log message `helm-debug' is non-`nil'.
1454 Messages are written to the `helm-debug-buffer' buffer.
1455
1456 Argument FORMAT-STRING is a string to use with `format'.
1457 Use optional arguments ARGS like in `format'."
1458   (when helm-debug
1459     (with-current-buffer (get-buffer-create helm-debug-buffer)
1460       (outline-mode)
1461       (buffer-disable-undo)
1462       (let ((inhibit-read-only t))
1463         (goto-char (point-max))
1464         (insert (let ((tm (current-time)))
1465                   (format (concat (if (string-match "Start session" format-string)
1466                                       "* " "** ")
1467                                   "%s.%06d (%s)\n %s\n")
1468                           (format-time-string "%H:%M:%S" tm)
1469                           (nth 2 tm)
1470                           (helm-log-get-current-function)
1471                           (apply #'format (cons format-string args)))))))))
1472
1473 (defun helm-log-run-hook (hook)
1474   "Run HOOK like `run-hooks' but write these actions to helm log buffer."
1475   (helm-log "Executing %s with value = %S" hook (symbol-value hook))
1476   (helm-log "Executing %s with global value = %S" hook (default-value hook))
1477   (run-hooks hook)
1478   (helm-log "executed %s" hook))
1479
1480 (defun helm-log-get-current-function ()
1481   "Get name of function that is calling `helm-log'.
1482 The original idea is from `tramp-debug-message'."
1483   (cl-loop with exclude-func-re = "^helm-\\(?:interpret\\|log\\|.*funcall\\)"
1484            for btn from 1 to 40
1485            for btf = (cl-second (backtrace-frame btn))
1486            for fn  = (if (symbolp btf) (symbol-name btf) "")
1487            if (and (string-match "^helm" fn)
1488                    (not (string-match exclude-func-re fn)))
1489            return fn))
1490
1491 (defun helm-log-error (&rest args)
1492   "Accumulate error messages into `helm-issued-errors'.
1493 ARGS are args given to `format'.
1494 e.g (helm-log-error \"Error %s: %s\" (car err) (cdr err))."
1495   (apply 'helm-log (concat "ERROR: " (car args)) (cdr args))
1496   (let ((msg (apply 'format args)))
1497     (unless (member msg helm-issued-errors)
1498       (cl-pushnew msg helm-issued-errors :test 'equal))))
1499
1500 (defun helm-log-save-maybe ()
1501   "Save log buffer when `helm-debug-root-directory' is non nil.
1502 Create `helm-debug-root-directory' directory if necessary.
1503 Messages are logged to a file named with todays date and time in this directory."
1504   (when (and (stringp helm-debug-root-directory)
1505              (not (file-directory-p helm-debug-root-directory)))
1506     (make-directory helm-debug-root-directory t))
1507   (when helm-debug
1508     (let ((logdir (expand-file-name (concat "helm-debug-"
1509                                             (format-time-string "%Y%m%d"))
1510                                     helm-debug-root-directory)))
1511       (make-directory logdir t)
1512       (with-current-buffer (get-buffer-create helm-debug-buffer)
1513         (write-region (point-min) (point-max)
1514                       (setq helm--last-log-file
1515                             (expand-file-name
1516                              (format-time-string "%Y%m%d-%H%M%S")
1517                              logdir))
1518                       nil 'silent)
1519         (kill-buffer))))
1520   (setq helm-debug nil))
1521
1522 ;;;###autoload
1523 (defun helm-debug-open-last-log ()
1524   "Open helm log file or buffer of last helm session."
1525   (interactive)
1526   (if helm--last-log-file
1527       (progn
1528         (find-file helm--last-log-file)
1529         (outline-mode) (view-mode 1) (visual-line-mode 1))
1530     (switch-to-buffer helm-debug-buffer)
1531     (view-mode 1) (visual-line-mode 1)))
1532
1533 (defun helm-print-error-messages ()
1534   "Print error messages in `helm-issued-errors'."
1535   (and helm-issued-errors
1536        (message "Helm issued errors: %s"
1537                 (mapconcat 'identity (reverse helm-issued-errors) "\n"))))
1538
1539
1540 ;; Test tools
1541 (defmacro with-helm-time-after-update (&rest body)
1542   (helm-with-gensyms (start-time time-elapsed)
1543     `(let ((,start-time (float-time)) ,time-elapsed)
1544        (add-hook 'helm-after-update-hook
1545                  (lambda ()
1546                    (setq ,time-elapsed (- (float-time) ,start-time))
1547                    (keyboard-quit)))
1548        (unwind-protect ,@body
1549          (remove-hook 'helm-after-update-hook
1550                       (lambda ()
1551                         (setq  ,time-elapsed (- (float-time) ,start-time))
1552                         (keyboard-quit))))
1553        ,time-elapsed)))
1554
1555
1556 ;; Helm API
1557 (defmacro with-helm-default-directory (directory &rest body)
1558   (declare (indent 2) (debug t))
1559   `(let ((default-directory (or (and ,directory
1560                                      (file-name-as-directory ,directory))
1561                                 default-directory)))
1562      ,@body))
1563
1564 (defun helm-default-directory ()
1565   "Return the local value of `default-directory' in `helm-buffer'."
1566   (buffer-local-value 'default-directory (get-buffer helm-buffer)))
1567
1568 (defmacro with-helm-temp-hook (hook &rest body)
1569   "Execute temporarily BODY as a function for HOOK."
1570   (declare (indent 1) (debug t))
1571   (helm-with-gensyms (helm--hook)
1572     `(progn
1573        (defun ,helm--hook ()
1574          (unwind-protect
1575              (progn ,@body)
1576            (remove-hook ,hook (quote ,helm--hook))
1577            (fmakunbound (quote ,helm--hook))))
1578        (push (cons ',helm--hook ,hook) helm--temp-hooks)
1579        (add-hook ,hook (quote ,helm--hook)))))
1580
1581 (defmacro with-helm-after-update-hook (&rest body)
1582   "Execute BODY at end of `helm-update'."
1583   (declare (indent 0) (debug t))
1584   `(with-helm-temp-hook 'helm-after-update-hook ,@body))
1585
1586 (defmacro with-helm-alive-p (&rest body)
1587   "Return error when BODY run outside helm context."
1588   (declare (indent 0) (debug t))
1589   `(progn
1590      (if helm-alive-p
1591          (progn ,@body)
1592        (error "Running helm command outside of context"))))
1593
1594 (defmacro with-helm-in-frame (&rest body)
1595   "Execute helm function in BODY displaying `helm-buffer' in separate frame."
1596   (declare (debug t) (indent 0))
1597   `(progn
1598      (helm-set-local-variable
1599       'helm-display-function 'helm-display-buffer-in-own-frame)
1600      ,@body))
1601
1602 ;;; helm-attributes
1603 ;;
1604 (defun helm-attr (attribute-name &optional source compute)
1605   "Get the value of ATTRIBUTE-NAME of SRC.
1606
1607 If SRC is omitted, use current source.
1608
1609 If COMPUTE is non-`nil' compute value of ATTRIBUTE-NAME with
1610 `helm-interpret-value'.  COMPUTE can have also 'ignorefn as value, in
1611 this case `helm-interpret-value' will return a function as value
1612 unchanged, but will eval a symbol which is bound.
1613
1614 You can use `setf' to modify value of ATTRIBUTE-NAME unless COMPUTE is
1615 specified, if attribute ATTRIBUTE-NAME is not found in SOURCE `setf'
1616 will create new attribute ATTRIBUTE-NAME with specified value.
1617 You can also use `helm-attrset' to modify ATTRIBUTE-NAME."
1618   (declare (gv-setter
1619             (lambda (val)
1620               `(let* ((src (or ,source (helm-get-current-source)))
1621                       (attr (assq ,attribute-name src)))
1622                  (cl-assert (null ,compute) nil
1623                             "`setf' can't set the computed value of attribute `%s'"
1624                             ,attribute-name)
1625                  (if attr
1626                      (setcdr attr ,val)
1627                    (and (setcdr src (cons (cons ,attribute-name ,val)
1628                                           (cdr src)))
1629                         ,val))))))
1630   (let ((src (or source (helm-get-current-source))))
1631     (helm-aif (assq attribute-name src)
1632         (if compute
1633             (helm-interpret-value (cdr it) src compute)
1634           (cdr it)))))
1635
1636 (cl-defun helm-attrset (attribute-name value
1637                                        &optional
1638                                        (src (helm-get-current-source)))
1639   "Set the value of ATTRIBUTE-NAME of source SRC to VALUE.
1640
1641 If ATTRIBUTE-NAME doesn't exists in source it is created with value VALUE..
1642 If SRC is omitted, use current source.
1643 If operation succeed, return value, otherwise nil.
1644
1645 Note that `setf' on `helm-attr' can be used instead of this function."
1646   (setf (helm-attr attribute-name src) value))
1647
1648 (defun helm-add-action-to-source (name fn source &optional index)
1649   "Add new action NAME linked to function FN to SOURCE.
1650 Function FN should be a valid function that takes one arg i.e candidate,
1651 argument NAME is a string that will appear in action menu
1652 and SOURCE should be an existing helm source already loaded.
1653 If INDEX is specified, action is added to the action list at INDEX,
1654 otherwise added at end.
1655 This allows users to add specific actions to an existing source
1656 without modifying source code."
1657   (let ((actions    (helm-attr 'action source 'ignorefn))
1658         (new-action (list (cons name fn))))
1659     (when (functionp actions)
1660       (setq actions (list (cons "Default action" actions))))
1661     (helm-attrset 'action
1662                   (if index
1663                       (helm-append-at-nth actions new-action index)
1664                     (append actions new-action))
1665                   source)))
1666
1667 (defun helm-delete-action-from-source (action-or-name source)
1668   "Delete ACTION-OR-NAME from SOURCE.
1669 ACTION-OR-NAME can either be the name of action or the symbol function
1670 associated to name."
1671   (let* ((actions    (helm-attr 'action source 'ignorefn))
1672          (del-action (if (symbolp action-or-name)
1673                          (rassoc action-or-name actions)
1674                        (assoc action-or-name actions))))
1675     (helm-attrset 'action (delete del-action actions) source)))
1676
1677 (cl-defun helm-add-action-to-source-if (name fn source predicate
1678                                              &optional (index 4) test-only)
1679   "Add new action NAME linked to function FN to SOURCE.
1680 Action NAME will be available when the current candidate matches PREDICATE.
1681 This function adds an entry in the `action-transformer' attribute
1682 of SOURCE (or creates one if not found).
1683 Function PREDICATE must take one candidate as arg.
1684 Function FN should be a valid function that takes one arg i.e. candidate,
1685 argument NAME is a string that will appear in action menu
1686 and SOURCE should be an existing helm source already loaded.
1687 If INDEX is specified, action is added in action list at INDEX.
1688 Value of INDEX should be always >=1, default to 4.
1689 This allow user to add a specific `action-transformer'
1690 to an existing source without modifying source code.
1691 E.g
1692 Add the action \"Byte compile file async\" linked to
1693 function 'async-byte-compile-file to source `helm-source-find-files'
1694 only when predicate helm-ff-candidates-lisp-p return non-`nil':
1695
1696 \(helm-add-action-to-source-if \"Byte compile file async\"
1697                               'async-byte-compile-file
1698                               helm-source-find-files
1699                               'helm-ff-candidates-lisp-p\)."
1700   (let* ((actions     (helm-attr 'action source 'ignorefn))
1701          (action-transformers (helm-attr 'action-transformer source))
1702          (new-action  (list (cons name fn)))
1703          (transformer (lambda (actions candidate)
1704                         (cond ((funcall predicate candidate)
1705                                (helm-append-at-nth
1706                                 actions new-action index))
1707                               (t actions)))))
1708     (when (functionp actions)
1709       (helm-attrset 'action (list (cons "Default action" actions)) source))
1710     (when (or (symbolp action-transformers) (functionp action-transformers))
1711       (setq action-transformers (list action-transformers)))
1712     (if test-only                       ; debug
1713         (delq nil (append (list transformer) action-transformers))
1714       (helm-attrset 'action-transformer
1715                     (helm-fast-remove-dups
1716                      (delq nil (append (list transformer) action-transformers))
1717                      :test 'equal)
1718                     source))))
1719
1720
1721 ;;; Source filter
1722 ;;
1723 (defun helm-set-source-filter (sources)
1724   "Set the value of `helm-source-filter' to SOURCES and update.
1725
1726 This function sets a filter for helm sources and it may be
1727 called while helm is running. It can be used to toggle
1728 displaying of sources dynamically. For example, additional keys
1729 can be bound into `helm-map' to display only the file-related
1730 results if there are too many matches from other sources and
1731 you're after files only:
1732
1733 Shift+F shows only file results from some sources:
1734
1735 \(define-key helm-map \"F\" 'helm-my-show-files-only)
1736
1737 \(defun helm-my-show-files-only ()
1738   (interactive)
1739   (helm-set-source-filter '(\"File Name History\"
1740                                   \"Files from Current Directory\")))
1741
1742 Shift+A shows all results:
1743
1744 \(define-key helm-map \"A\" 'helm-my-show-all)
1745
1746 \(defun helm-my-show-all ()
1747   (interactive)
1748   (helm-set-source-filter nil))
1749
1750 The -my- part is added to avoid collisions with
1751 existing Helm function names."
1752   (with-helm-buffer
1753     (let ((cur-disp-sel (helm-get-selection nil t)))
1754       (set (make-local-variable 'helm-source-filter)
1755            (helm--normalize-filter-sources sources))
1756       (helm-log "helm-source-filter = %S" helm-source-filter)
1757       ;; Use force-update to run init/update functions.
1758       (helm-force-update (and (stringp cur-disp-sel)
1759                               (regexp-quote cur-disp-sel))))))
1760
1761 (defun helm--normalize-filter-sources (sources)
1762   (cl-loop for s in sources collect
1763            (cl-typecase s
1764              (symbol (assoc-default 'name (symbol-value s)))
1765              (list   (assoc-default 'name s))
1766              (string s))))
1767
1768 (defun helm-set-sources (sources &optional no-init no-update)
1769   "Set SOURCES during `helm' invocation.
1770 If NO-INIT is non-`nil', skip executing init functions of SOURCES.
1771 If NO-UPDATE is non-`nil', skip executing `helm-update'."
1772   (with-current-buffer helm-buffer
1773     (setq helm-sources (helm-get-sources sources))
1774     (helm-log "helm-sources = %S" helm-sources))
1775   (unless no-init (helm-compute-attr-in-sources 'init))
1776   (unless no-update (helm-update)))
1777
1778 (defun helm-get-selection (&optional buffer force-display-part source)
1779   "Return the currently selected item or nil.
1780
1781 if BUFFER is nil or unspecified, use helm-buffer as default value.
1782 If FORCE-DISPLAY-PART is non-`nil', return the display string.
1783 If FORCE-DISPLAY-PART value is `withprop' the display string is returned
1784 with its properties."
1785   (setq buffer (or buffer helm-buffer))
1786   (unless (or (helm-empty-buffer-p buffer)
1787               (helm-pos-header-line-p))
1788     (with-current-buffer buffer
1789       (let* ((disp-fn (if (eq force-display-part 'withprop)
1790                           'buffer-substring
1791                         'buffer-substring-no-properties))
1792              (selection
1793               (or (and (not force-display-part)
1794                        (get-text-property (overlay-start
1795                                            helm-selection-overlay)
1796                                           'helm-realvalue))
1797                   ;; It is needed to return properties of DISP in some case,
1798                   ;; e.g for `helm-confirm-and-exit-minibuffer',
1799                   ;; so use `buffer-substring' here when 'withprop is specified.
1800                   (let* ((beg  (overlay-start helm-selection-overlay))
1801                          (end  (overlay-end helm-selection-overlay))
1802                          ;; If there is no selection at point, the
1803                          ;; overlay is at its initial pos, (point-min)
1804                          ;; (point-min), that's mean the helm-buffer
1805                          ;; is not empty but have no selection yet,
1806                          ;; this happen with grep sentinel sending an
1807                          ;; error message in helm-buffer when no matches.
1808                          (disp (unless (= beg end) (funcall disp-fn beg (1- end))))
1809                          (src (or source (helm-get-current-source))))
1810                     (helm-aif (and src disp
1811                                    (not force-display-part)
1812                                    (assoc-default 'display-to-real src))
1813                         (helm-apply-functions-from-source source it disp)
1814                       disp)))))
1815         (unless (equal selection "")
1816           (helm-log "selection = %S" selection)
1817           selection)))))
1818
1819 (defun helm-get-actions-from-current-source (&optional source)
1820   "Return the associated action for the selected candidate.
1821 It is a function symbol (sole action) or list
1822 of (action-display . function)."
1823   (unless (helm-empty-buffer-p (helm-buffer-get))
1824     (let ((src (helm-get-current-source)))
1825       (helm-aif (helm-attr 'action-transformer)
1826           (helm-apply-functions-from-source
1827            (or source src) it
1828            (helm-attr 'action nil 'ignorefn)
1829            ;; Check if the first given transformer
1830            ;; returns the same set of actions for each
1831            ;; candidate in marked candidates.
1832            ;; If so use the car of marked to determine
1833            ;; the set of actions, otherwise use the selection.
1834            (if (cl-loop with marked = (helm-marked-candidates)
1835                         with act = (car (helm-mklist it))
1836                         with acts = (funcall act nil (car marked))
1837                         for c in marked
1838                         always (equal (funcall act nil c) acts))
1839                (car (helm-marked-candidates))
1840                (helm-get-selection nil nil src)))
1841         (helm-attr 'action nil 'ignorefn)))))
1842
1843 (defun helm-get-current-source ()
1844   "Return the source for the current selection.
1845 Return nil when `helm-buffer' is empty."
1846   (or helm-current-source
1847       (with-helm-buffer
1848         (or (get-text-property (point) 'helm-cur-source)
1849             (progn
1850               ;; This is needed to not loose selection.
1851               (goto-char (overlay-start helm-selection-overlay))
1852               (let ((header-pos (or (helm-get-previous-header-pos)
1853                                     (helm-get-next-header-pos))))
1854                 ;; Return nil when no--candidates.
1855                 (when header-pos
1856                   (cl-loop with source-name = (save-excursion
1857                                                 (goto-char header-pos)
1858                                                 (helm-current-line-contents))
1859                            for source in helm-sources thereis
1860                            (and (equal (assoc-default 'name source) source-name)
1861                                 source)))))))))
1862
1863 (defun helm-buffer-is-modified (buffer)
1864   "Return non-`nil' when BUFFER is modified since `helm' was invoked."
1865   (let* ((buf         (get-buffer buffer))
1866          (key         (concat (buffer-name buf) "/" (helm-attr 'name)))
1867          (source-tick (or (gethash key helm-tick-hash) 0))
1868          (buffer-tick (buffer-chars-modified-tick buf))
1869          (modifiedp   (/= source-tick buffer-tick)))
1870     (puthash key buffer-tick helm-tick-hash)
1871     (helm-log "buffer = %S" buffer)
1872     (helm-log "modifiedp = %S" modifiedp)
1873     modifiedp))
1874
1875 (defun helm-current-buffer-is-modified ()
1876   "Check if `helm-current-buffer' is modified since `helm' was invoked."
1877   (helm-buffer-is-modified helm-current-buffer))
1878
1879 (defun helm-run-after-exit (function &rest args)
1880   "Execute FUNCTION with ARGS after exiting `helm'.
1881 The action is to call FUNCTION with arguments ARGS.
1882 Unlike `helm-exit-and-execute-action', this can be used
1883 to call non--actions functions with any ARGS or no ARGS at all.
1884
1885 Use this on commands invoked from key-bindings, but not
1886 on action functions invoked as action from the action menu,
1887 i.e. functions called with RET."
1888   (helm-kill-async-processes)
1889   (helm-log "function = %S" function)
1890   (helm-log "args = %S" args)
1891   (helm-exit-and-execute-action
1892    (lambda (_candidate)
1893      (apply function args))))
1894
1895 (defun helm-exit-and-execute-action (action)
1896   "Exit current helm session and execute ACTION.
1897 Argument ACTION is a function called with one arg (candidate)
1898 and part of the actions of current source.
1899
1900 Use this on commands invoked from key-bindings, but not
1901 on action functions invoked as action from the action menu,
1902 i.e functions called with RET."
1903   ;; If ACTION is not an action available in source 'action attribute,
1904   ;; return an error.  This allow to remove unneeded actions from
1905   ;; source that inherit actions from type, note that ACTION have to
1906   ;; be bound to a symbol and not to be an anonymous action
1907   ;; i.e. lambda or byte-code.
1908   (let ((actions (helm-attr 'action nil t)))
1909     (when actions
1910       (cl-assert (or (eq action actions)
1911                      (rassq action actions)
1912                      ;; Compiled lambda
1913                      (byte-code-function-p action)
1914                      ;; Lambdas
1915                      (and (listp action) (functionp action)))
1916                  nil "No such action `%s' for this source" action)))
1917   (setq helm-saved-action action)
1918   (setq helm-saved-selection (or (helm-get-selection) ""))
1919   (setq helm--executing-helm-action t)
1920   ;; When toggling minibuffer and header-line, we want next action
1921   ;; inherit this setting.
1922   (helm-set-local-variable 'helm-echo-input-in-header-line
1923                            (with-helm-buffer helm-echo-input-in-header-line))
1924   ;; Ensure next action use same display function as initial helm-buffer when
1925   ;; helm-actions-inherit-frame-settings is non nil.
1926   (when (and helm-actions-inherit-frame-settings
1927              helm--buffer-in-new-frame-p)
1928     (helm-set-local-variable 'helm-display-function
1929                              (with-helm-buffer helm-display-function)
1930                              'helm--last-frame-parameters
1931                              (with-helm-buffer
1932                                (helm--get-frame-parameters)))
1933     ;; The helm-buffer keeps `helm-display-function' and
1934     ;; `helm--get-frame-parameters' values during 0.5 seconds, just
1935     ;; the time to execute the possible helm action with those values.
1936     ;; If no helm based action run within 0.5 seconds, the next helm
1937     ;; session will have to resolve again those variable values.
1938     (run-with-idle-timer 0.5 nil
1939       (lambda () (helm-set-local-variable 'helm-display-function nil 
1940                                           'helm--last-frame-parameters nil))))
1941   (helm-exit-minibuffer))
1942
1943 (defun helm--get-frame-parameters (&optional frame)
1944   (cl-loop with params = (frame-parameters frame)
1945            for p in helm--frame-default-attributes
1946            when (assq p params) collect it))
1947
1948 (defalias 'helm-run-after-quit 'helm-run-after-exit)
1949 (make-obsolete 'helm-run-after-quit 'helm-run-after-exit "1.7.7")
1950 (defalias 'helm-quit-and-execute-action 'helm-exit-and-execute-action)
1951 (make-obsolete 'helm-quit-and-execute-action 'helm-exit-and-execute-action "1.7.7")
1952
1953 (defun helm-interpret-value (value &optional source compute)
1954   "Interpret VALUE as variable, function or literal and return it.
1955 If VALUE is a function, call it with no arguments and return the value
1956 unless COMPUTE value is 'ignorefn.
1957 If SOURCE compute VALUE for this source.
1958 If VALUE is a variable, return the value.
1959 If VALUE is a symbol, but it is not a function or a variable, cause an error.
1960 Otherwise, return VALUE itself."
1961   (cond ((and source (functionp value) (not (eq compute 'ignorefn)))
1962          (helm-apply-functions-from-source source value))
1963         ((and (functionp value) (not (eq compute 'ignorefn)))
1964          (funcall value))
1965         ((and (symbolp value) (boundp value))
1966          (symbol-value value))
1967         ((and (symbolp value) (not (functionp value)))
1968          (error
1969           "helm-interpret-value: Symbol must be a function or a variable"))
1970         (t
1971          value)))
1972
1973 (defun helm-set-local-variable (&rest args)
1974   "Bind each pair in ARGS locally to `helm-buffer'.
1975
1976 Use this to set local vars before calling helm.
1977
1978 When used from an init or update function
1979 (i.e when `helm-force-update' is running) the variables are set
1980 using `make-local-variable' within the `helm-buffer'.
1981
1982 Usage: helm-set-local-variable ([VAR VALUE]...)
1983 Just like `setq' except that the vars are not set sequentially.
1984 IOW Don't use VALUE of previous VAR to set the VALUE of next VAR.
1985
1986 \(fn VAR VALUE ...)"
1987   (if helm--force-updating-p
1988       (with-helm-buffer
1989         (cl-loop for i on args by #'cddr
1990                  do (set (make-local-variable (car i)) (cadr i))))
1991       (setq helm--local-variables
1992             (append (cl-loop for i on args by #'cddr
1993                              collect (cons (car i) (cadr i)))
1994                     helm--local-variables))))
1995
1996 (defun helm--set-local-variables-internal ()
1997   (cl-loop for (var . val) in helm--local-variables
1998            ;; If `helm-set-local-variable' is called twice or more
1999            ;; on same variable use the last value entered which is
2000            ;; the first on stack e.g.
2001            ;; (helm-set-local-variable 'helm-foo 1)
2002            ;; (helm-set-local-variable 'helm-foo 2)
2003            ;; helm--local-variables => 
2004            ;; '((helm-foo . 2) (helm-foo. 1))
2005            ;; (helm-foo . 2) is retained and (helm-foo . 1)
2006            ;; ignored.
2007            unless (memq var computed)
2008            do (set (make-local-variable var) val)
2009            collect var into computed
2010            finally (setq helm--local-variables nil)))
2011
2012
2013 ;; API helper
2014 (cl-defun helm-empty-buffer-p (&optional (buffer helm-buffer))
2015   "Check if BUFFER have candidates.
2016 Default value for BUFFER is `helm-buffer'."
2017   (zerop (buffer-size (and buffer (get-buffer buffer)))))
2018
2019 (defun helm-empty-source-p ()
2020   "Check if current source contains candidates.
2021 This could happen when for example the last element of a source
2022 was deleted and the candidates list not updated."
2023   (when (helm-window)
2024     (with-helm-window
2025       (or (helm-empty-buffer-p)
2026           (and (helm-end-of-source-p)
2027                (eq (point-at-bol) (point-at-eol))
2028                (or
2029                 (save-excursion
2030                   (forward-line -1)
2031                   (helm-pos-header-line-p))
2032                 (bobp)))))))
2033
2034
2035 ;; Tools
2036 ;;
2037 (defun helm-apply-functions-from-source (source functions &rest args)
2038   "From SOURCE apply FUNCTIONS on ARGS.
2039
2040 This function is used to process filter functions, when filter is a
2041 \`filtered-candidate-transformer', we pass to ARGS candidates+source
2042 whereas when the filter is `candidate-transformer' we pass to ARGS
2043 candidates only.
2044 This function is used also to process functions called with no args,
2045 e.g. init functions, in this case it is called without ARGS.
2046 See `helm-process-filtered-candidate-transformer'
2047 \`helm-compute-attr-in-sources' and 
2048 \`helm-process-candidate-transformer'.
2049
2050 Arg FUNCTIONS is either a symbol or a list of functions, each function being
2051 applied on ARGS and called on the result of the precedent function.
2052 Return the result of last function call."
2053   (let ((helm--source-name (assoc-default 'name source))
2054         (helm-current-source source)
2055         (funs (if (functionp functions) (list functions) functions)))
2056     (helm-log "helm--source-name = %S" helm--source-name)
2057     (helm-log "functions = %S" functions)
2058     (helm-log "args = %S" args)
2059     (cl-loop with result
2060              for fn in funs
2061              do (setq result (apply fn args))
2062              when (and args (cdr funs))
2063              ;; In filter functions, ARGS is a list of one or two elements where
2064              ;; the first element is the list of candidates and the second
2065              ;; a list containing the source.
2066              ;; When more than one fn, set the candidates list to what returns
2067              ;; this fn to compute the modified candidates with the next fn
2068              ;; and so on.
2069              do (setcar args result)
2070              finally return result)))
2071
2072 (defalias 'helm-funcall-with-source 'helm-apply-functions-from-source)
2073 (make-obsolete 'helm-funcall-with-source 'helm-apply-functions-from-source "2.9.7")
2074
2075 (defun helm-compute-attr-in-sources (attr &optional sources)
2076   "Call the associated function(s) to ATTR for each source if any."
2077   (let ((sources (or (helm-get-sources sources)
2078                      ;; Fix error no buffer named *helm... by checking
2079                      ;; if helm-buffer exists.
2080                      (and (buffer-live-p (get-buffer (helm-buffer-get)))
2081                           ;; `helm-sources' are local to helm-buffer.
2082                           (with-helm-buffer helm-sources)))))
2083     (when sources
2084       (cl-dolist (source sources)
2085         (helm-aif (assoc-default attr source)
2086             (helm-apply-functions-from-source source it))))))
2087
2088 (defalias 'helm-funcall-foreach 'helm-compute-attr-in-sources)
2089 (make-obsolete 'helm-funcall-foreach 'helm-compute-attr-in-sources "2.9.7")
2090
2091 (defun helm-normalize-sources (sources)
2092   "If SOURCES is only one source, make a list of one element."
2093   (if (or (and sources (symbolp sources))
2094           (and (listp sources) (assq 'name sources)))
2095       (list sources)
2096     sources))
2097
2098 (defun helm-get-candidate-number (&optional in-current-source)
2099   "Return candidates number in `helm-buffer'.
2100 If IN-CURRENT-SOURCE is provided return number of candidates of current source
2101 only."
2102   (with-helm-buffer
2103     (if (or (helm-empty-buffer-p)
2104             (helm-empty-source-p))
2105         0
2106         (save-excursion
2107           (helm-aif (and in-current-source (helm-get-previous-header-pos))
2108               (goto-char it)
2109             (goto-char (point-min)))
2110           (forward-line 1)
2111           (if (helm-pos-multiline-p)
2112               (cl-loop with count-multi = 1
2113                        while (and (not (if in-current-source
2114                                            (save-excursion
2115                                              (forward-line 2)
2116                                              (or (helm-pos-header-line-p) (eobp)))
2117                                            (eobp)))
2118                                   (search-forward helm-candidate-separator nil t))
2119                        do (cl-incf count-multi)
2120                        finally return count-multi)
2121               (cl-loop with ln = 0
2122                        while (not (if in-current-source
2123                                       (or (helm-pos-header-line-p) (eobp))
2124                                       (eobp)))
2125                        ;; Don't count empty lines maybe added by popup (#1370).
2126                        unless (or (eq (point-at-bol) (point-at-eol))
2127                                   (helm-pos-header-line-p))
2128                        do (cl-incf ln)
2129                        do (forward-line 1) finally return ln))))))
2130
2131 (defmacro with-helm-quittable (&rest body)
2132   "If an error occurs in execution of BODY, safely quit helm."
2133   (declare (indent 0) (debug t))
2134   `(condition-case _v
2135        (let (inhibit-quit)
2136          ,@body)
2137      (quit (setq quit-flag t)
2138            (setq helm-quit t)
2139            (exit-minibuffer)
2140            (keyboard-quit)
2141            ;; See comment about this in `with-local-quit'.
2142            (eval '(ignore nil)))))
2143
2144 ;; Entry point
2145 ;; `:allow-nest' is not in this list because it is treated before.
2146 (defconst helm-argument-keys
2147   '(:sources :input :prompt :resume
2148     :preselect :buffer :keymap :default :history))
2149
2150 ;;;###autoload
2151 (defun helm (&rest plist)
2152   "Main function to execute helm sources.
2153
2154 PLIST is a list like
2155
2156 \(:key1 val1 :key2 val2 ...\)
2157
2158  or
2159
2160 \(&optional sources input prompt resume preselect
2161             buffer keymap default history allow-nest\).
2162
2163 ** Keywords
2164
2165 Keywords supported:
2166
2167 - :sources
2168 - :input
2169 - :prompt
2170 - :resume
2171 - :preselect
2172 - :buffer
2173 - :keymap
2174 - :default
2175 - :history
2176 - :allow-nest
2177
2178 Extra LOCAL-VARS keywords are supported, see the \"** Other
2179 keywords\" section below.
2180
2181 Basic keywords are the following:
2182
2183 *** :sources
2184
2185 One of the following:
2186
2187 - List of sources
2188 - Symbol whose value is a list of sources
2189 - Alist representing a Helm source.
2190   - In this case the source has no name and is referenced in
2191     `helm-sources' as a whole alist.
2192
2193 *** :input
2194
2195 Initial input of minibuffer (temporary value of `helm-pattern')
2196
2197 *** :prompt
2198
2199 Minibuffer prompt. Default value is `helm--prompt'.
2200
2201 *** :resume
2202
2203 If t, allow resumption of the previous session of this Helm
2204 command, skipping initialization.
2205
2206 If 'noresume, this instance of `helm' cannot be resumed.
2207
2208 *** :preselect
2209
2210 Initially selected candidate (string or regexp).
2211
2212 *** :buffer
2213
2214 Buffer name for this Helm session. `helm-buffer' will take this value.
2215
2216 *** :keymap
2217
2218 \[Obsolete]
2219
2220 Keymap used at the start of this Helm session.
2221
2222 It is overridden by keymaps specified in sources, and is kept
2223 only for backward compatibility.
2224
2225 Keymaps should be specified in sources using the :keymap slot
2226 instead. See `helm-source'.
2227
2228 This keymap is not restored by `helm-resume'.
2229
2230 *** :default
2231
2232 Default value inserted into the minibuffer \ with
2233 \\<minibuffer-local-map>\\[next-history-element].
2234
2235 It can be a string or a list of strings, in this case
2236 \\<minibuffer-local-map>\\[next-history-element] cycles through
2237 the list items, starting with the first.
2238
2239 If nil, `thing-at-point' is used.
2240
2241 If `helm--maybe-use-default-as-input' is non-`nil', display is
2242 updated using this value, unless :input is specified, in which
2243 case that value is used instead.
2244
2245 *** :history
2246
2247 Minibuffer input, by default, is pushed to `minibuffer-history'.
2248
2249 When an argument HISTORY is provided, input is pushed to
2250 HISTORY. HISTORY should be a valid symbol.
2251
2252 *** :allow-nest
2253
2254 Allow running this Helm command in a running Helm session.
2255
2256 ** Other keywords
2257
2258 Other keywords are interpreted as local variables of this Helm
2259 session. The `helm-' prefix can be omitted. For example,
2260
2261 \(helm :sources 'helm-source-buffers-list
2262        :buffer \"*helm buffers*\"
2263        :candidate-number-limit 10\)
2264
2265 starts a Helm session with the variable
2266 `helm-candidate-number-limit' set to 10.
2267
2268 ** Backward compatibility
2269
2270 For backward compatibility, positional parameters are
2271 supported:
2272
2273 \(helm sources input prompt resume preselect
2274        buffer keymap default history allow-nest\)
2275
2276 However, the use of non-keyword args is deprecated.
2277
2278 \(fn &key SOURCES INPUT PROMPT RESUME PRESELECT BUFFER KEYMAP DEFAULT HISTORY ALLOW-NEST OTHER-LOCAL-VARS)"
2279   (let ((fn (cond ((or (and helm-alive-p (plist-get plist :allow-nest))
2280                        (and helm-alive-p (memq 'allow-nest plist)))
2281                    #'helm--nest)
2282                   ((keywordp (car plist))
2283                    #'helm)
2284                   (t #'helm-internal))))
2285     (if (and helm-alive-p (eq fn #'helm))
2286         (if (helm--alive-p)
2287             ;; A helm session is normally running.
2288             (error "Error: Trying to run helm within a running helm session")
2289           ;; A helm session is already running and user jump somewhere else
2290           ;; without deactivating it.
2291           (with-helm-buffer
2292             (prog1
2293                 (message "Aborting an helm session running in background")
2294               ;; `helm-alive-p' will be reset in unwind-protect forms.
2295               (helm-keyboard-quit))))
2296       (if (keywordp (car plist))
2297           ;; Parse `plist' and move not regular `helm-argument-keys'
2298           ;; to `helm--local-variables', then calling helm on itself
2299           ;; with normal arguments (the non--arguments-keys removed)
2300           ;; will end up in [1].
2301           (progn
2302             (setq helm--local-variables
2303                   (append helm--local-variables
2304                           ;; Vars passed by keyword on helm call
2305                           ;; take precedence on same vars
2306                           ;; that may have been passed before helm call.
2307                           (helm-parse-keys plist)))
2308             (apply fn (mapcar (lambda (key) (plist-get plist key))
2309                               helm-argument-keys)))
2310         (apply fn plist))))) ; [1] fn == helm-internal.
2311
2312 (defun helm--alive-p ()
2313   "[Internal] Check if `helm' is alive.
2314 An `helm' session is considered alive if `helm-alive-p' value is
2315 non-`nil', the `helm-buffer' is visible, and cursor is in the
2316 minibuffer."
2317   (and helm-alive-p
2318        (get-buffer-window (helm-buffer-get) 'visible)
2319        (minibuffer-window-active-p (minibuffer-window))
2320        (minibufferp (current-buffer))))
2321
2322 (defun helm-parse-keys (keys)
2323   "Parse the KEYS arguments of `helm'.
2324 Return only those keys not in `helm-argument-keys', prefix them
2325 with \"helm\", and then convert them to an alist. This allows
2326 adding arguments that are not part of `helm-argument-keys', but
2327 are valid helm variables nevertheless. For
2328 example, :candidate-number-limit is bound to
2329 `helm-candidate-number-limit' in the source.
2330
2331   (helm-parse-keys '(:sources ((name . \"test\")
2332                                (candidates . (a b c)))
2333                      :buffer \"toto\"
2334                      :candidate-number-limit 4))
2335   ==> ((helm-candidate-number-limit . 4))."
2336
2337   (cl-loop for (key value) on keys by #'cddr
2338            for symname = (substring (symbol-name key) 1)
2339            for sym = (intern (if (string-match "^helm-" symname)
2340                                  symname
2341                                (concat "helm-" symname)))
2342            unless (memq key helm-argument-keys)
2343            collect (cons sym value)))
2344
2345 ;;; Entry point helper
2346 (defun helm-internal (&optional
2347                         any-sources any-input
2348                         any-prompt any-resume
2349                         any-preselect any-buffer
2350                         any-keymap any-default any-history)
2351   "The internal helm function called by `helm'.
2352 For ANY-SOURCES ANY-INPUT ANY-PROMPT ANY-RESUME ANY-PRESELECT ANY-BUFFER and
2353 ANY-KEYMAP ANY-DEFAULT ANY-HISTORY See `helm'."
2354   (unless helm--nested (setq helm-initial-frame (selected-frame)))
2355   ;; Activate the advices.
2356   ;; Advices will be available only in >=emacs-24.4, but
2357   ;; allow compiling without errors on lower emacs.
2358   (when (fboundp 'advice-add)
2359     (advice-add 'tramp-read-passwd :around #'helm--suspend-read-passwd)
2360     (advice-add 'ange-ftp-get-passwd :around #'helm--suspend-read-passwd)
2361     (advice-add 'epa-passphrase-callback-function
2362                 :around #'helm--suspend-read-passwd)
2363     ;; Ensure linum-mode is disabled in Helm buffers to preserve
2364     ;; performances (Issue #1894).
2365     (advice-add 'linum-on :override #'helm--advice-linum-on))
2366   (helm-log (concat "[Start session] " (make-string 41 ?+)))
2367   (helm-log "any-prompt = %S" any-prompt)
2368   (helm-log "any-preselect = %S" any-preselect)
2369   (helm-log "any-buffer = %S" any-buffer)
2370   (helm-log "any-keymap = %S" any-keymap)
2371   (helm-log "any-default = %S" any-default)
2372   (helm-log "any-history = %S" any-history)
2373   (setq helm--prompt (or any-prompt "pattern: "))
2374   (let ((non-essential t)
2375         ;; Prevent mouse jumping to the upper-right
2376         ;; hand corner of the frame (#1538).
2377         mouse-autoselect-window
2378         focus-follows-mouse
2379         mode-line-in-non-selected-windows
2380         (input-method-verbose-flag helm-input-method-verbose-flag)
2381         (helm--maybe-use-default-as-input
2382          (and (null any-input)
2383               (or helm--maybe-use-default-as-input ; it is let-bounded so use it.
2384                   (cl-loop for s in (helm-normalize-sources any-sources)
2385                            thereis (memq s helm-sources-using-default-as-input))))))
2386     (unwind-protect
2387          (condition-case-unless-debug _v
2388              (let ( ;; `helm--source-name' is non-`nil'
2389                    ;; when `helm' is invoked by action, reset it.
2390                    helm--source-name
2391                    helm-current-source
2392                    helm-in-persistent-action
2393                    helm-quit
2394                    (helm-buffer (or any-buffer helm-buffer)))
2395                (helm-initialize
2396                 any-resume any-input any-default any-sources)
2397                ;; We don't display helm-buffer here to avoid popping
2398                ;; up a window or a frame when exiting immediately when
2399                ;; only one candidate (this avoid having the helm frame
2400                ;; flashing), lets first compute candidates and if more
2401                ;; than one display helm-buffer (this is done later in
2402                ;; helm-read-pattern-maybe).
2403                (unless helm-execute-action-at-once-if-one
2404                  (helm-display-buffer helm-buffer any-resume)
2405                  (select-window (helm-window)))
2406                ;; We are now in helm-buffer.
2407                (unless helm-allow-mouse
2408                  (helm--remap-mouse-mode 1)) ; Disable mouse bindings.
2409                (add-hook 'post-command-hook 'helm--maybe-update-keymap)
2410                ;; Add also to update hook otherwise keymap is not updated
2411                ;; until a key is hitted (Issue #1670).
2412                (add-hook 'helm-after-update-hook 'helm--maybe-update-keymap)
2413                (add-hook 'post-command-hook 'helm--update-header-line)
2414                (helm-log "show prompt")
2415                (unwind-protect
2416                     (helm-read-pattern-maybe
2417                      any-prompt any-input any-preselect
2418                      any-resume any-keymap any-default any-history)
2419                  (helm-cleanup))
2420                (prog1
2421                    (unless helm-quit (helm-execute-selection-action))
2422                  (helm-log (concat "[End session] " (make-string 41 ?-)))))
2423            (quit
2424             (helm-restore-position-on-quit)
2425             (helm-log-run-hook 'helm-quit-hook)
2426             (helm-log (concat "[End session (quit)] " (make-string 34 ?-)))
2427             nil))
2428       (when (fboundp 'advice-remove)
2429         (advice-remove 'tramp-read-passwd #'helm--suspend-read-passwd)
2430         (advice-remove 'ange-ftp-get-passwd #'helm--suspend-read-passwd)
2431         (advice-remove 'epa-passphrase-callback-function #'helm--suspend-read-passwd)
2432         (advice-remove 'linum-on #'helm--advice-linum-on))
2433       (helm-log "helm-alive-p = %S" (setq helm-alive-p nil))
2434       (helm--remap-mouse-mode -1)       ; Reenable mouse bindings.
2435       (setq helm-alive-p nil)
2436       ;; Prevent error "No buffer named *helm*" triggered by
2437       ;; `helm-set-local-variable'.
2438       (setq helm--force-updating-p nil)
2439       (setq helm--buffer-in-new-frame-p nil)
2440       ;; Reset helm-pattern so that lambda's using it
2441       ;; before running helm will not start with its old value.
2442       (setq helm-pattern "")
2443       (setq helm--ignore-errors nil)
2444       (helm-log-save-maybe))))
2445
2446 (defun helm--advice-linum-on ()
2447   (unless (or (minibufferp)
2448               (string-match "\\`\\*helm" (buffer-name))
2449               (and (daemonp) (null (frame-parameter nil 'client))))
2450     (linum-mode 1)))
2451
2452 ;;; Helm resume
2453 ;;
2454 ;;
2455 (defun helm-resume (arg)
2456   "Resume a previous `helm' session.
2457 Call with a prefix arg to choose among existing helm
2458 buffers (sessions). When calling from lisp, specify a buffer-name
2459 as a string with ARG."
2460   (interactive "P")
2461   (let (any-buffer
2462         cur-dir
2463         narrow-pos
2464         (helm-full-frame (default-value 'helm-full-frame))
2465         sources)
2466     (if arg
2467         (if (and (stringp arg) (bufferp (get-buffer arg)))
2468             (setq any-buffer arg)
2469           (setq any-buffer (helm-resume-select-buffer)))
2470       (setq any-buffer helm-last-buffer))
2471     (cl-assert any-buffer nil
2472                "helm-resume: No helm buffers found to resume")
2473     (setq sources (buffer-local-value
2474                    'helm-sources (get-buffer any-buffer)))
2475     ;; Reset `cursor-type' to nil as it have been set to t
2476     ;; when quitting previous session.
2477     (with-current-buffer any-buffer (setq cursor-type nil))
2478     (setq helm-full-frame (buffer-local-value
2479                            'helm-full-frame (get-buffer any-buffer)))
2480     (setq cur-dir (buffer-local-value
2481                    'default-directory (get-buffer any-buffer)))
2482     (setq helm-saved-selection nil
2483           helm-saved-action nil)
2484     (unless (buffer-live-p helm-current-buffer)
2485       ;; `helm-current-buffer' may have been killed.
2486       (setq helm-current-buffer (current-buffer)))
2487     (helm-aif (with-current-buffer any-buffer
2488                 helm--current-buffer-narrowed)
2489           (progn
2490             (set-buffer (car it))
2491             (setq narrow-pos (cdr it))))
2492     (save-restriction
2493       (when narrow-pos (apply #'narrow-to-region narrow-pos))
2494       ;; Restart with same `default-directory' value this session
2495       ;; was initially started with.
2496       (with-helm-default-directory cur-dir
2497           (unwind-protect
2498                (helm
2499                 :sources sources
2500                 :input (buffer-local-value 'helm-input-local (get-buffer any-buffer))
2501                 :prompt (buffer-local-value 'helm--prompt (get-buffer any-buffer))
2502                 :resume t
2503                 :buffer any-buffer)
2504             (run-hook-with-args 'helm-resume-after-hook sources))))))
2505
2506 (defun helm-resume-previous-session-after-quit (arg)
2507   "Resume previous helm session within a running helm."
2508   (interactive "p")
2509   (with-helm-alive-p
2510     (if (> (length helm-buffers) arg)
2511         (helm-run-after-exit (lambda () (helm-resume (nth arg helm-buffers))))
2512       (message "No previous helm sessions available for resuming!"))))
2513 (put 'helm-resume-previous-session-after-quit 'helm-only t)
2514
2515 (defun helm-resume-list-buffers-after-quit ()
2516   "List resumable helm buffers within running helm."
2517   (interactive)
2518   (with-helm-alive-p
2519     (if (> (length helm-buffers) 0)
2520         (helm-run-after-exit (lambda () (helm-resume t)))
2521       (message "No previous helm sessions available for resuming!"))))
2522 (put 'helm-resume-list-buffers-after-quit 'helm-only t)
2523
2524 (defun helm-resume-p (any-resume)
2525   "Whether current helm session is resumed or not."
2526   (eq any-resume t))
2527
2528 (defun helm-resume-select-buffer ()
2529   "Select an `helm-buffer' in `helm-buffers' list to resume a helm session.
2530 Return nil if no `helm-buffer' found."
2531   (when helm-buffers
2532     (or (helm :sources (helm-build-sync-source "Resume helm buffer"
2533                           :candidates helm-buffers)
2534               :resume 'noresume
2535               :buffer "*helm resume*")
2536         (keyboard-quit))))
2537
2538 ;;;###autoload
2539 (defun helm-cycle-resume ()
2540   "Cycle in `helm-buffers' list and resume when waiting more than 1.2s."
2541   (interactive)
2542   (cl-assert (and helm-buffers helm-last-buffer)
2543              nil "No helm buffers to resume")
2544   ;; Setup a new iterator only on first hit on
2545   ;; `helm-run-cycle-resume', subsequents hits should reuse same
2546   ;; iterator.
2547   (unless (and (eq last-command 'helm-cycle-resume)
2548                helm--cycle-resume-iterator)
2549     (setq helm--cycle-resume-iterator
2550           (helm-iter-sub-next-circular
2551            helm-buffers helm-last-buffer :test 'equal)))
2552   (helm--resume-or-iter))
2553
2554 (defun helm--resume-or-iter (&optional from-helm)
2555   (message "Resuming helm buffer `%s'" helm-last-buffer)
2556   (if (sit-for helm-cycle-resume-delay)
2557       ;; Delay expire, run helm-resume.
2558       (if from-helm
2559           (helm-run-after-exit (lambda () (helm-resume helm-last-buffer)))
2560         (helm-resume helm-last-buffer))
2561     ;; key pressed before delay, cycle.
2562     (unless from-helm ; cycling to next item already done.
2563       (message "Resuming helm buffer `%s'"
2564                (setq helm-last-buffer
2565                      (helm-iter-next helm--cycle-resume-iterator))))))
2566
2567 (defun helm-run-cycle-resume ()
2568   "Same as `helm-cycle-resume' but intended to be called only from helm."
2569   (interactive)
2570   (when (cdr helm-buffers) ; only one session registered.
2571     ;; Setup a new iterator only on first hit on
2572     ;; `helm-run-cycle-resume', subsequents hits should reuse same
2573     ;; iterator.
2574     (unless (and (eq last-command 'helm-run-cycle-resume)
2575                  helm--cycle-resume-iterator)
2576       (setq helm--cycle-resume-iterator
2577             (helm-iter-sub-next-circular
2578              helm-buffers helm-last-buffer :test 'equal)))
2579     ;; start at next buffer as we already are at `helm-last-buffer'.
2580     (setq helm-last-buffer
2581           (helm-iter-next helm--cycle-resume-iterator))
2582     (helm--resume-or-iter 'from-helm)))
2583 (put 'helm-run-cycle-resume 'helm-only t)
2584
2585
2586 ;;;###autoload
2587 (defun helm-other-buffer (any-sources any-buffer)
2588   "Simplified `helm' interface with other `helm-buffer'.
2589 Call `helm' only with ANY-SOURCES and ANY-BUFFER as args."
2590   (helm :sources any-sources :buffer any-buffer))
2591
2592 ;;; Nested sessions
2593 ;;
2594 ;;
2595 (defun helm--nest (&rest same-as-helm)
2596   "[internal]Allows calling `helm' within a running helm session.
2597
2598 Arguments SAME-AS-HELM are the same as `helm'.
2599
2600 Don't use this directly, use instead `helm' with the keyword
2601 :allow-nest.
2602
2603 \(fn &key SOURCES INPUT PROMPT RESUME PRESELECT BUFFER KEYMAP DEFAULT HISTORY OTHER-LOCAL-VARS)"
2604   (with-helm-window
2605     (let ((orig-helm-current-buffer helm-current-buffer)
2606           (orig-helm-buffer helm-buffer)
2607           (orig-helm--prompt helm--prompt)
2608           (orig-helm-sources helm-sources)
2609           (orig-helm--in-fuzzy helm--in-fuzzy)
2610           (orig-helm--display-frame helm--buffer-in-new-frame-p)
2611           (orig-helm-last-frame-or-window-configuration
2612            helm-last-frame-or-window-configuration)
2613           (orig-one-window-p helm-onewindow-p)
2614           (helm--nested t))
2615       ;; FIXME Using helm-full-frame here allow showing the new
2616       ;; helm-buffer in the same window as old helm-buffer, why? 
2617       (helm-set-local-variable 'helm-full-frame t)
2618       (unwind-protect
2619           (let (helm-current-position
2620                 helm-current-buffer
2621                 helm-pattern
2622                 (helm-buffer (or (cl-getf same-as-helm :buffer)
2623                                  (nth 5 same-as-helm)
2624                                  "*Helm*"))
2625                 (enable-recursive-minibuffers t))
2626             (setq helm-sources nil)
2627             (apply #'helm same-as-helm))
2628         (with-current-buffer orig-helm-buffer
2629           (setq helm-sources orig-helm-sources)
2630           (setq helm--nested nil)
2631           (setq helm--buffer-in-new-frame-p orig-helm--display-frame)
2632           (setq helm-alive-p t) ; Nested session set this to nil on exit.
2633           (setq helm-buffer orig-helm-buffer)
2634           (setq helm-full-frame nil)
2635           (setq helm--prompt orig-helm--prompt)
2636           (setq helm--in-fuzzy orig-helm--in-fuzzy)
2637           (helm-initialize-overlays helm-buffer)
2638           (unless (helm-empty-buffer-p) (helm-mark-current-line t))
2639           (setq helm-last-frame-or-window-configuration
2640                 orig-helm-last-frame-or-window-configuration)
2641           (setq cursor-type nil)
2642           (setq helm-current-buffer orig-helm-current-buffer)
2643           (setq helm-onewindow-p orig-one-window-p)
2644           ;; Be sure advices, hooks, and local modes keep running.
2645           (if (fboundp 'advice-add)
2646               (progn
2647                 (advice-add 'tramp-read-passwd
2648                             :around #'helm--suspend-read-passwd)
2649                 (advice-add 'ange-ftp-get-passwd
2650                             :around #'helm--suspend-read-passwd)
2651                 (advice-add 'epa-passphrase-callback-function
2652                             :around #'helm--suspend-read-passwd))
2653             (ad-activate 'tramp-read-passwd)
2654             (ad-activate 'ange-ftp-get-passwd))
2655           (unless helm-allow-mouse
2656             (helm--remap-mouse-mode 1))
2657           (unless (cl-loop for h in post-command-hook
2658                            thereis (memq h '(helm--maybe-update-keymap
2659                                              helm--update-header-line)))
2660             (add-hook 'post-command-hook 'helm--maybe-update-keymap)
2661             (add-hook 'post-command-hook 'helm--update-header-line))
2662           (helm-display-mode-line (helm-get-current-source)))))))
2663
2664
2665 ;;; Accessors
2666 ;;
2667 (defun helm-current-position (save-or-restore)
2668   "Save or restore current position in `helm-current-buffer'.
2669 Argument SAVE-OR-RESTORE is either save or restore."
2670   (cl-case save-or-restore
2671     (save
2672      (helm-log "Save position at %S" (cons (point) (window-start)))
2673      (setq helm-current-position (cons (point) (window-start))))
2674     (restore
2675      ;; Maybe `helm-current-buffer' have been deleted
2676      ;; during helm session so check if it is here
2677      ;; otherwise position in underlying buffer will be lost.
2678      (when (get-buffer-window helm-current-buffer 'visible)
2679        (helm-log "Restore position at  %S in buffer %s"
2680                  helm-current-position
2681                  (buffer-name (current-buffer)))
2682        (goto-char (car helm-current-position))
2683        ;; Fix this position with the NOFORCE arg of `set-window-start'
2684        ;; otherwise, if there is some other buffer than `helm-current-buffer'
2685        ;; one, position will be lost.
2686        (set-window-start (selected-window) (cdr helm-current-position) t)))))
2687
2688
2689 (defun helm-frame-or-window-configuration (save-or-restore)
2690   "Save or restore last frame or window configuration.
2691 Argument SAVE-OR-RESTORE is either save or restore of window or
2692 frame configuration as per `helm-save-configuration-functions'."
2693   (helm-log "helm-save-configuration-functions = %S"
2694             helm-save-configuration-functions)
2695   (let ((window-persistent-parameters (append '((no-other-window . t))
2696                                               window-persistent-parameters)))
2697     (cl-case save-or-restore
2698       (save    (setq helm-last-frame-or-window-configuration
2699                      (funcall (cdr helm-save-configuration-functions))))
2700       (restore (funcall (car helm-save-configuration-functions)
2701                         helm-last-frame-or-window-configuration)
2702                ;; Restore frame focus.
2703                ;; This is needed for minibuffer own-frame config
2704                ;; when recursive minibuffers are in use.
2705                ;; e.g M-: + helm-minibuffer-history.
2706                (cl-letf ((frame (if (minibufferp helm-current-buffer)
2707                                     (selected-frame)
2708                                   (last-nonminibuffer-frame)))
2709                          ;; This is a workaround, because the i3 window
2710                          ;; manager developers are refusing to fix their
2711                          ;; broken timestamp and event handling.
2712                          ;;
2713                          ;; We basically just disable the part of
2714                          ;; select-frame-set-input-focus that would call
2715                          ;; XSetInputFocus in Xlib (x-focus-frame), that
2716                          ;; resets a timestamp in the xserver which the i3
2717                          ;; developers fail to notice.
2718                          ;;
2719                          ;; Since they don't know about the new timestamp,
2720                          ;; their keyboard handling can break after a helm
2721                          ;; user quits emacs, as reported in #1641.
2722                          ;;
2723                          ;; Fortunately for us, we really don't need this
2724                          ;; XSetInputFocus call, since we already have focus
2725                          ;; for Emacs, the user is just using helm!  We call
2726                          ;; select-frame-set-input-focus for the other
2727                          ;; side-effects, not for x-focus-frame.
2728                          ((symbol-function 'x-focus-frame) #'ignore))
2729                  (select-frame-set-input-focus frame))))))
2730
2731 (defun helm-split-window-default-fn (window)
2732   "Default function to split windows before displaying `helm-buffer'.
2733
2734 It is used as default value for
2735 `helm-split-window-preferred-function' which is then the let-bounded
2736 value of `split-window-preferred-function' in `helm-display-buffer'.
2737 When `helm-display-function' which default to
2738 `helm-default-display-buffer' is called from `helm-display-buffer' the
2739 value of `split-window-preferred-function' will be used by `display-buffer'."
2740   (let (split-width-threshold)
2741     (if (and (fboundp 'window-in-direction)
2742              ;; Don't try to split when starting in a minibuffer
2743              ;; e.g M-: and try to use helm-show-kill-ring.
2744              (not (minibufferp helm-current-buffer)))
2745         (if (or (one-window-p t)
2746                 helm-split-window-inside-p)
2747             (split-window
2748              (selected-window) nil (if (eq helm-split-window-default-side 'other)
2749                                        'below helm-split-window-default-side))
2750           ;; If more than one window reuse one of them.
2751           (cl-case helm-split-window-default-side
2752             (left  (or (helm-window-in-direction 'left)
2753                        (helm-window-in-direction 'above)
2754                        (selected-window)))
2755             (above (or (helm-window-in-direction 'above)
2756                        (helm-window-in-direction 'left)
2757                        (selected-window)))
2758             (right (or (helm-window-in-direction 'right)
2759                        (helm-window-in-direction 'below)
2760                        (selected-window)))
2761             (below (or (helm-window-in-direction 'below)
2762                        (helm-window-in-direction 'right)
2763                        (selected-window)))
2764             (same  (selected-window))
2765             (other (other-window-for-scrolling))
2766             (t     (or (window-next-sibling) (selected-window)))))
2767       (split-window-sensibly window))))
2768
2769 (defun helm-window-in-direction (direction)
2770   "Same as `window-in-direction' but check if window is dedicated."
2771   (helm-aif (window-in-direction direction)
2772       (and (not (window-dedicated-p it)) it)))
2773
2774
2775 ;;; Display helm buffer
2776 ;;
2777 ;;
2778 (defun helm-resolve-display-function (com)
2779   "Decide which display function use according to `helm-commands-using-frame'.
2780
2781 The `helm-display-function' buffer local value takes precedence on
2782 `helm-commands-using-frame'.
2783 If `helm-initial-frame' has no minibuffer, use
2784 `helm-display-buffer-in-own-frame' function.
2785 Fallback to global value of `helm-display-function' when no local
2786 value found and current command is not in `helm-commands-using-frame'."
2787   (or (with-helm-buffer helm-display-function)
2788       (and (or (memq com helm-commands-using-frame)
2789                (and helm-use-frame-when-more-than-two-windows
2790                     (null helm--nested)
2791                     (> (length (window-list)) 2))
2792                ;; Frame parameter is unreliable for minibuffer on emacs-26.
2793                (null (member helm-initial-frame (minibuffer-frame-list))))
2794            #'helm-display-buffer-in-own-frame)
2795       (default-value 'helm-display-function)))
2796
2797 (defun helm-display-buffer (buffer &optional resume)
2798   "Display BUFFER.
2799
2800 The function used to display `helm-buffer' by calling
2801 `helm-display-function' which split window with
2802 `helm-split-window-preferred-function'."
2803   (let ((split-window-preferred-function
2804          helm-split-window-preferred-function)
2805         (helm-split-window-default-side
2806          (if (and (not helm-full-frame)
2807                   helm-reuse-last-window-split-state)
2808              (cond ((eq helm-split-window-default-side 'same) 'same)
2809                    ((eq helm-split-window-default-side 'other) 'other)
2810                    (helm--window-side-state)
2811                    (t helm-split-window-default-side))
2812            helm-split-window-default-side))
2813         (disp-fn (with-current-buffer buffer
2814                    (helm-resolve-display-function
2815                     (if helm-actions-inherit-frame-settings
2816                         (helm-this-command) this-command)))))
2817     (prog1
2818         (funcall disp-fn buffer (or (helm-resume-p resume)
2819                                     (and helm-actions-inherit-frame-settings
2820                                          helm--executing-helm-action)))
2821       (with-helm-buffer (setq-local helm-display-function disp-fn))
2822       (setq helm-onewindow-p (one-window-p t))
2823       ;; Don't allow other-window and friends switching out of minibuffer.
2824       (when helm-prevent-escaping-from-minibuffer
2825         (helm-prevent-switching-other-window)))))
2826
2827 (cl-defun helm-prevent-switching-other-window (&key (enabled t))
2828   "Allow setting `no-other-window' parameter for all windows.
2829 Arg ENABLE is the value of `no-other-window' window property."
2830   (walk-windows
2831    (lambda (w)
2832      (unless (window-dedicated-p w)
2833        (set-window-parameter w 'no-other-window enabled)))
2834    0))
2835
2836 (defun helm-default-display-buffer (buffer &optional _resume)
2837   "Default function to display `helm-buffer' BUFFER.
2838
2839 It is the default value of `helm-display-function'
2840 It uses `switch-to-buffer' or `display-buffer' depending on the
2841 value of `helm-full-frame' or `helm-split-window-default-side'."
2842   (let (pop-up-frames)
2843     (if (or (buffer-local-value 'helm-full-frame (get-buffer buffer))
2844             (and (eq helm-split-window-default-side 'same)
2845                  (one-window-p t)))
2846         (progn (and (not (minibufferp helm-current-buffer))
2847                     (delete-other-windows))
2848                (switch-to-buffer buffer))
2849       (when (and (or helm-always-two-windows helm-autoresize-mode)
2850                  (not (eq helm-split-window-default-side 'same))
2851                  (not (minibufferp helm-current-buffer))
2852                  (not helm-split-window-inside-p))
2853         (delete-other-windows))
2854       (display-buffer
2855        buffer `(,helm-default-display-buffer-functions
2856                 . ,(append helm-default-display-buffer-alist
2857                            `((window-height . ,helm-display-buffer-default-height)
2858                              (window-width  . ,helm-display-buffer-default-width)))))
2859       (helm-log-run-hook 'helm-window-configuration-hook))))
2860
2861 (defun helm-display-buffer-in-own-frame (buffer &optional resume)
2862   "Display helm buffer BUFFER in a separate frame.
2863
2864 Function suitable for `helm-display-function',
2865 `helm-completion-in-region-display-function'
2866 and/or `helm-show-completion-default-display-function'.
2867
2868 See `helm-display-buffer-height' and `helm-display-buffer-width' to
2869 configure frame size.
2870
2871 Note that this feature is available only with emacs-25+."
2872   (cl-assert (and (fboundp 'window-absolute-pixel-edges)
2873                   (fboundp 'frame-geometry))
2874              nil "Helm buffer in own frame is only available starting at emacs-25+")
2875   (if (not (display-graphic-p))
2876       ;; Fallback to default when frames are not usable.
2877       (helm-default-display-buffer buffer)
2878     (setq helm--buffer-in-new-frame-p t)
2879     (let* ((pos (window-absolute-pixel-position))
2880            (half-screen-size (/ (display-pixel-height x-display-name) 2))
2881            (frame-info (frame-geometry))
2882            (prmt-size (length helm--prompt))
2883            (line-height (frame-char-height))
2884            (default-frame-alist
2885             (if resume
2886                 (buffer-local-value 'helm--last-frame-parameters
2887                                     (get-buffer buffer))
2888               `((width . ,helm-display-buffer-width)
2889                 (height . ,helm-display-buffer-height)
2890                 (tool-bar-lines . 0)
2891                 (left . ,(- (car pos)
2892                             (* (frame-char-width)
2893                                (if (< (- (point) (point-at-bol)) prmt-size)
2894                                    (- (point) (point-at-bol))
2895                                  prmt-size))))
2896                 ;; Try to put frame at the best possible place.
2897                 ;; Frame should be below point if enough
2898                 ;; place, otherwise above point and
2899                 ;; current line should not be hidden
2900                 ;; by helm frame.
2901                 (top . ,(if (> (cdr pos) half-screen-size)
2902                             ;; Above point
2903                             (- (cdr pos)
2904                                ;; add 2 lines to make sure there is always a gap
2905                                (* (+ helm-display-buffer-height 2) line-height)
2906                                ;; account for title bar height too
2907                                (cddr (assq 'title-bar-size frame-info)))
2908                           ;; Below point
2909                           (+ (cdr pos) line-height)))
2910                 (title . "Helm")
2911                 (undecorated . ,helm-use-undecorated-frame-option)
2912                 (vertical-scroll-bars . nil)
2913                 (menu-bar-lines . 0)
2914                 (fullscreen . nil)
2915                 (visibility . ,(null helm-display-buffer-reuse-frame))
2916                 (minibuffer . t))))
2917            display-buffer-alist)
2918       ;; Display minibuffer above or below only in initial session,
2919       ;; not on a session triggered by action, this way if user have
2920       ;; toggled minibuffer and header-line manually she keeps this
2921       ;; setting in next action.
2922       (unless (or helm--executing-helm-action resume)
2923         ;; Add the hook inconditionally, if
2924         ;; helm-echo-input-in-header-line is nil helm-hide-minibuffer-maybe
2925         ;; will have anyway no effect so no need to remove the hook.
2926         (add-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe)
2927         (with-helm-buffer
2928           (setq-local helm-echo-input-in-header-line
2929                       (not (> (cdr pos) half-screen-size)))))
2930       (helm-display-buffer-popup-frame buffer default-frame-alist)
2931       ;; When frame size have been modified manually by user restore
2932       ;; it to default value unless resuming or not using
2933       ;; `helm-display-buffer-reuse-frame'.
2934       ;; This have to be done AFTER raising the frame otherwise
2935       ;; minibuffer visibility is lost until next session.
2936       (unless (or resume (not helm-display-buffer-reuse-frame))
2937         (set-frame-size helm-popup-frame
2938                         helm-display-buffer-width
2939                         helm-display-buffer-height)))
2940     (helm-log-run-hook 'helm-window-configuration-hook)))
2941
2942 (defun helm-display-buffer-popup-frame (buffer frame-alist)
2943   (if helm-display-buffer-reuse-frame
2944       (let* ((x (cdr (assoc 'left frame-alist)))
2945              (y (cdr (assoc 'top frame-alist))))
2946         (unless (and helm-popup-frame
2947                      (frame-live-p helm-popup-frame))
2948           (setq helm-popup-frame (make-frame frame-alist)))
2949         (select-frame helm-popup-frame)
2950         (set-frame-position helm-popup-frame x y)
2951         (switch-to-buffer buffer)
2952         (select-frame-set-input-focus helm-popup-frame t))
2953     ;; If user have changed `helm-display-buffer-reuse-frame' to nil
2954     ;; maybe kill the frame.
2955     (when (and helm-popup-frame
2956                (frame-live-p helm-popup-frame))
2957       (delete-frame helm-popup-frame))
2958     (display-buffer
2959      buffer '(display-buffer-pop-up-frame . nil))))
2960
2961 ;; Ensure to quit helm when user delete helm frame manually.
2962 ;; If user deletes another frame keep session running.
2963 (defun helm--delete-frame-function (frame)
2964   (when (and helm-alive-p
2965              ;; FRAME is handling helm-buffer
2966              (get-buffer-window helm-buffer frame))
2967     (helm-keyboard-quit)))
2968 (add-hook 'delete-frame-functions 'helm--delete-frame-function)
2969
2970 ;;; Initialize
2971 ;;
2972 (defun helm-get-sources (sources)
2973   "Transform each element of SOURCES in alist.
2974 Returns the resulting list."
2975   (when sources
2976     (mapcar (lambda (source)
2977               (if (listp source)
2978                   source (symbol-value source)))
2979             (helm-normalize-sources sources))))
2980
2981 (defun helm-initialize (any-resume any-input any-default any-sources)
2982   "Start initialization of `helm' session.
2983 For ANY-RESUME ANY-INPUT ANY-DEFAULT and ANY-SOURCES See `helm'."
2984   (helm-log "start initialization: any-resume=%S any-input=%S"
2985             any-resume any-input)
2986   (helm-frame-or-window-configuration 'save)
2987   (let ((sources (helm-get-sources any-sources)))
2988     (setq helm--in-fuzzy
2989           (cl-loop for s in sources
2990                    for matchfns = (helm-match-functions s)
2991                    for searchfns = (helm-search-functions s)
2992                    when (or (memq 'helm-fuzzy-match matchfns)
2993                             (memq 'helm-fuzzy-search searchfns))
2994                    return t))
2995     (helm-log "sources = %S" sources)
2996     (helm-set-local-variable 'helm-sources sources)
2997     ;; Once `helm-buffer' is created `helm-sources' will be a local
2998     ;; variable which value is a list of alists.
2999     (helm-current-position 'save)
3000     (if (helm-resume-p any-resume)
3001         (helm-initialize-overlays (helm-buffer-get))
3002       (helm-initial-setup any-default sources))
3003     (setq helm-alive-p t)
3004     (unless (eq any-resume 'noresume)
3005       (helm--push-and-remove-dups helm-buffer 'helm-buffers)
3006       (setq helm-last-buffer helm-buffer))
3007     (when any-input
3008       (setq helm-input any-input
3009             helm-pattern any-input)
3010       (helm--fuzzy-match-maybe-set-pattern))
3011     ;; If a `resume' attribute is present `helm-compute-attr-in-sources'
3012     ;; will run its function.
3013     (when (helm-resume-p any-resume)
3014       (helm-compute-attr-in-sources 'resume))
3015     (helm-log "end initialization")))
3016
3017 (defun helm-initialize-overlays (buffer)
3018   "Initialize helm overlays in BUFFER."
3019   (helm-log "overlay setup")
3020   (if helm-selection-overlay
3021       ;; make sure the overlay belongs to the helm buffer if
3022       ;; it's newly created
3023       (move-overlay helm-selection-overlay (point-min) (point-min)
3024                     (get-buffer buffer))
3025
3026     (setq helm-selection-overlay
3027           (make-overlay (point-min) (point-min) (get-buffer buffer)))
3028     (overlay-put helm-selection-overlay 'face 'helm-selection)
3029     (overlay-put helm-selection-overlay 'priority 1)))
3030
3031 (defun helm-restore-position-on-quit ()
3032   "Restore position in `helm-current-buffer' when quitting."
3033   (helm-current-position 'restore))
3034
3035 (defun helm--push-and-remove-dups (elm sym)
3036   "Move ELM of SYM value on top and set SYM to this new value."
3037   (set sym (cons elm (delete elm (symbol-value sym)))))
3038
3039 (defun helm--current-buffer ()
3040   "[internal] Return `current-buffer' BEFORE `helm-buffer' is initialized.
3041 Note that it returns the minibuffer in use after helm has started
3042 and is intended for `helm-initial-setup'. To get the buffer where
3043 helm was started, use `helm-current-buffer' instead."
3044   (if (minibuffer-window-active-p (minibuffer-window))
3045       ;; If minibuffer is active be sure to use it's buffer
3046       ;; as `helm-current-buffer', this allow to use helm
3047       ;; from an already active minibuffer (M-: etc...)
3048       (window-buffer (active-minibuffer-window))
3049     ;; Fix Issue #456
3050     ;; Use this instead of `current-buffer' to ensure
3051     ;; helm session started in helm-mode from a completing-read
3052     ;; Use really the buffer where we started and not the one
3053     ;; where the completing-read is wrapped. i.e
3054     ;; (with-current-buffer SOME-OTHER-BUFFER (completing-read [...])
3055     (window-buffer (with-selected-window (minibuffer-window)
3056                      (minibuffer-selected-window)))))
3057
3058 (defun helm--run-init-hooks (hook sources)
3059   "Run after and before init hooks local to source.
3060 See :after-init-hook and :before-init-hook in `helm-source'."
3061   (cl-loop with sname = (cl-ecase hook
3062                           (before-init-hook "h-before-init-hook")
3063                           (after-init-hook "h-after-init-hook"))
3064            with h = (cl-gensym sname)
3065            for s in sources
3066            for hv = (assoc-default hook s)
3067            if (and hv (not (symbolp hv)))
3068            do (set h hv)
3069            and do (helm-log-run-hook h)
3070            else do (helm-log-run-hook hv)))
3071
3072 (defun helm-initial-setup (any-default sources)
3073   "Initialize helm settings and set up the helm buffer."
3074   ;; Run global hook.
3075   (helm-log-run-hook 'helm-before-initialize-hook)
3076   ;; Run local source hook.
3077   (helm--run-init-hooks 'before-init-hook sources)
3078   ;; For initialization of helm locals vars that need
3079   ;; a value from current buffer, it is here.
3080   (helm-set-local-variable 'current-input-method current-input-method)
3081   (setq helm-current-prefix-arg nil
3082         helm-saved-action nil
3083         helm-saved-selection nil
3084         helm-suspend-update-flag nil
3085         ;; Ensure this is called BEFORE selecting helm-window.
3086         helm-current-buffer (helm--current-buffer)
3087         helm-buffer-file-name buffer-file-name
3088         helm-issued-errors nil
3089         helm-saved-current-source nil
3090         helm--suspend-update-interactive-flag nil)
3091   (when (and (with-helm-current-buffer
3092                (and (buffer-narrowed-p)
3093                     (use-region-p)))
3094              (not helm--nested))
3095     (helm-set-local-variable 'helm--current-buffer-narrowed
3096                              (list (current-buffer)
3097                                    (region-beginning) (region-end))))
3098   (unless (and (or helm-split-window-state
3099                    helm--window-side-state)
3100                helm-reuse-last-window-split-state)
3101     (setq helm-split-window-state
3102           (if (or (null split-width-threshold)
3103                   (and (integerp split-width-threshold)
3104                        (>= split-width-threshold (+ (frame-width) 4))))
3105               'vertical 'horizontal))
3106     (setq helm--window-side-state
3107           (or helm-split-window-default-side 'below)))
3108   ;; Call the init function for sources where appropriate
3109   (helm-compute-attr-in-sources 'init sources)
3110   (setq helm-pattern (or (and helm--maybe-use-default-as-input
3111                               (or (if (listp any-default)
3112                                       (car any-default) any-default)
3113                                   (with-helm-current-buffer
3114                                     (thing-at-point 'symbol))))
3115                          ""))
3116   (setq helm-input "")
3117   (clrhash helm-candidate-cache)
3118   (helm-create-helm-buffer)
3119   (helm-clear-visible-mark)
3120   ;; Run global hook.
3121   (helm-log-run-hook 'helm-after-initialize-hook)
3122   ;; Run local source hook.
3123   (helm--run-init-hooks 'after-init-hook sources))
3124
3125 (define-derived-mode helm-major-mode
3126     fundamental-mode "Hmm"
3127     "[Internal] Provide major-mode name in helm buffers.
3128 Unuseful when used outside helm, don't use it.")
3129 (put 'helm-major-mode 'mode-class 'special)
3130 (put 'helm-major-mode 'helm-only t)
3131
3132 (defun helm-create-helm-buffer ()
3133   "Create and setup `helm-buffer'."
3134   (let ((root-dir default-directory)
3135         (inhibit-read-only t))
3136     (with-current-buffer (get-buffer-create helm-buffer)
3137       (helm-log "Enabling major-mode %S" major-mode)
3138       (helm-log "kill local variables: %S" (buffer-local-variables))
3139       (kill-all-local-variables)
3140       (helm-major-mode)
3141       (set (make-local-variable 'buffer-read-only) nil)
3142       (buffer-disable-undo)
3143       (erase-buffer)
3144       (set (make-local-variable 'helm-map) helm-map)
3145       (set (make-local-variable 'helm-source-filter) nil)
3146       (make-local-variable 'helm-sources)
3147       (set (make-local-variable 'helm-display-function) nil)
3148       (set (make-local-variable 'helm-selection-point) nil)
3149       (set (make-local-variable 'scroll-margin)
3150            (if helm-display-source-at-screen-top
3151                0 helm-completion-window-scroll-margin))
3152       (set (make-local-variable 'default-directory) root-dir)
3153       (set (make-local-variable 'helm-marked-candidates) nil)
3154       (set (make-local-variable 'helm--prompt) helm--prompt)
3155       (helm-initialize-persistent-action)
3156       (helm-log "helm-display-function = %S" helm-display-function)
3157       (helm-log "helm--local-variables = %S" helm--local-variables)
3158       (helm--set-local-variables-internal)
3159       (setq truncate-lines helm-truncate-lines) ; already local.
3160       (setq cursor-type nil))
3161     (helm-initialize-overlays helm-buffer)
3162     (get-buffer helm-buffer)))
3163
3164 (define-minor-mode helm--minor-mode
3165   "[INTERNAL] Enable keymap in helm minibuffer.
3166 Since this mode has no effect when run outside of helm context,
3167 please don't use it outside helm.
3168
3169 \\{helm-map}"
3170   :group 'helm
3171   :keymap (and helm-alive-p helm-map)
3172   (unless helm-alive-p (setq helm--minor-mode nil)))
3173 (put 'helm--minor-mode 'helm-only t)
3174
3175 (defun helm--reset-default-pattern ()
3176   (setq helm-pattern "")
3177   (setq helm--maybe-use-default-as-input nil))
3178
3179 (defun helm-read-pattern-maybe (any-prompt any-input
3180                                 any-preselect any-resume any-keymap
3181                                 any-default any-history)
3182   "Read pattern with prompt ANY-PROMPT and initial input ANY-INPUT.
3183 For ANY-PRESELECT ANY-RESUME ANY-KEYMAP ANY-DEFAULT ANY-HISTORY, See `helm'."
3184   (with-helm-buffer
3185     (if (and (helm-resume-p any-resume)
3186            ;; When no source, helm-buffer is empty
3187            ;; or contain non--candidate lines (e.g grep exit status)
3188            (helm-get-current-source))
3189       (helm-mark-current-line t)
3190     (helm-update any-preselect))
3191     (let* ((src        (helm-get-current-source))
3192            (src-keymap (assoc-default 'keymap src))
3193            (hist       (or (and any-history (symbolp any-history) any-history)
3194                            ;; Needed for resuming.
3195                            (assoc-default 'history src)))
3196            (timer nil)
3197            blink-matching-paren
3198            (resize-mini-windows (and (null helm-echo-input-in-header-line)
3199                                      resize-mini-windows))
3200            (first-src (car helm-sources))
3201            (source-process-p (or (assq 'candidates-process src)
3202                                  (assq 'candidates-process first-src))))
3203       (helm-log "helm-get-candidate-number => %S"
3204                 (helm-get-candidate-number))
3205       (helm-log "helm-execute-action-at-once-if-one = %S"
3206                 helm-execute-action-at-once-if-one)
3207       (helm-log "helm-quit-if-no-candidate = %S" helm-quit-if-no-candidate)
3208       (when (and src (helm-resume-p any-resume))
3209         (helm-display-mode-line src))
3210       ;; Reset `helm-pattern' and update
3211       ;; display if no result found with precedent value of `helm-pattern'
3212       ;; unless `helm-quit-if-no-candidate' is non-`nil', in this case
3213       ;; Don't force update with an empty pattern.
3214       ;; Reset also `helm--maybe-use-default-as-input' as this checking
3215       ;; happen only on startup.
3216       (when helm--maybe-use-default-as-input
3217         ;; Store value of `default' temporarily here waiting next update
3218         ;; to allow actions like helm-moccur-action matching pattern
3219         ;; at the place it jump to.
3220         (setq helm-input helm-pattern)
3221         (if source-process-p
3222             ;; Reset pattern to next update.
3223             (with-helm-after-update-hook
3224               (helm--reset-default-pattern))
3225           ;; Reset pattern right now.
3226           (helm--reset-default-pattern))
3227         ;; Ensure force-update when no candidates
3228         ;; when we start with an empty pattern.
3229         (and (helm-empty-buffer-p)
3230              (null helm-quit-if-no-candidate)
3231              (helm-force-update)))
3232       ;; Handle `helm-execute-action-at-once-if-one' and
3233       ;; `helm-quit-if-no-candidate' now.
3234       (cond ((and (if (functionp helm-execute-action-at-once-if-one)
3235                       (funcall helm-execute-action-at-once-if-one)
3236                     helm-execute-action-at-once-if-one)
3237                   (= (helm-get-candidate-number
3238                       (eq helm-execute-action-at-once-if-one 'current-source))
3239                      1))
3240              (ignore))              ; Don't enter the minibuffer loop.
3241             ((and helm-quit-if-no-candidate
3242                   (= (helm-get-candidate-number) 0))
3243              (setq helm-quit t)
3244              (and (functionp helm-quit-if-no-candidate)
3245                   (funcall helm-quit-if-no-candidate)))
3246             (t              ; Enter now minibuffer and wait for input.
3247              (let ((tap (or any-default
3248                             (with-helm-current-buffer
3249                               (thing-at-point 'symbol)))))
3250                (when helm-execute-action-at-once-if-one
3251                  (helm-display-buffer helm-buffer any-resume)
3252                  (select-window (helm-window)))
3253                (unwind-protect
3254                    (minibuffer-with-setup-hook
3255                        (lambda ()
3256                          ;; Start minor-mode with global value of helm-map.
3257                          (helm--minor-mode 1)
3258                          ;; Now override the global value of `helm-map' with
3259                          ;; the local one which is in this order:
3260                          ;; - The keymap of current source.
3261                          ;; - The value passed in ANY-KEYMAP
3262                          ;; - Or fallback to the global value of helm-map.
3263                          (helm--maybe-update-keymap
3264                           (or src-keymap any-keymap helm-map))
3265                          (helm-log-run-hook 'helm-minibuffer-set-up-hook)
3266                          (setq timer
3267                                (run-with-idle-timer
3268                                 (max (with-helm-buffer helm-input-idle-delay)
3269                                      0.001)
3270                                 'repeat
3271                                 (lambda ()
3272                                   ;; Stop updating in persistent action
3273                                   ;; or when `helm-suspend-update-flag'
3274                                   ;; is non-`nil'.
3275                                   (unless (or helm-in-persistent-action
3276                                               helm-suspend-update-flag)
3277                                     (save-selected-window
3278                                       (helm-check-minibuffer-input)
3279                                       (helm-print-error-messages))))))
3280                          ;; minibuffer has already been filled here.
3281                          (helm--update-header-line))
3282                      (read-from-minibuffer (propertize (or any-prompt "pattern: ")
3283                                                        'face 'helm-minibuffer-prompt)
3284                                            any-input helm-map
3285                                            nil hist tap
3286                                            helm-inherit-input-method))
3287                  (when timer (cancel-timer timer) (setq timer nil)))))))))
3288
3289 (defun helm-toggle-suspend-update ()
3290   "Enable or disable display update in helm.
3291 This can be useful for example for quietly writing a complex regexp
3292 without helm constantly updating."
3293   (interactive)
3294   (helm-suspend-update (not helm-suspend-update-flag) t)
3295   (setq helm--suspend-update-interactive-flag
3296         (not helm--suspend-update-interactive-flag)))
3297 (put 'helm-toggle-suspend-update 'helm-only t)
3298
3299 (defun helm-suspend-update (arg &optional verbose)
3300   "Enable or disable display update in helm.
3301 If ARG is 1 or non nil suspend update, if it is -1 or nil reenable
3302 updating.  When VERBOSE is specified display a message."
3303   (with-helm-buffer
3304     (when (setq helm-suspend-update-flag
3305                 (helm-acase arg
3306                   (1 t)
3307                   (-1 nil)
3308                   (t it)))
3309       (helm-kill-async-processes)
3310       (setq helm-pattern ""))
3311     (when verbose
3312       (message (if helm-suspend-update-flag
3313                    "Helm update suspended!"
3314                  "Helm update re-enabled!")))
3315     (helm-aif (helm-get-current-source)
3316         (helm-display-mode-line it t))))
3317
3318 (defun helm-delete-backward-no-update (arg)
3319   "Disable update and delete ARG chars backward.
3320 Update is reenabled when idle 1s."
3321   (interactive "p")
3322   (with-helm-alive-p
3323     (unless helm--suspend-update-interactive-flag
3324       (helm-suspend-update 1))
3325     (backward-delete-char arg)
3326     (run-with-idle-timer
3327      1 nil
3328      (lambda ()
3329        (unless helm--suspend-update-interactive-flag
3330          (helm-suspend-update -1)
3331          (helm-check-minibuffer-input)
3332          (helm-force-update))))))
3333 (put 'helm-delete-backward-no-update 'helm-only t)
3334
3335 (defun helm--suspend-read-passwd (old--fn &rest args)
3336   "Suspend helm while reading password.
3337 This is used to advice `tramp-read-passwd', `ange-ftp-get-passwd' and
3338 `epa-passphrase-callback-function'."
3339   ;; Suspend update when prompting for a tramp password.
3340   (setq helm-suspend-update-flag t)
3341   (setq overriding-terminal-local-map nil)
3342   (setq helm--reading-passwd-or-string t)
3343   (unwind-protect
3344        ;; No need to suspend timer in emacs-24.4
3345        ;; it is fixed upstream.
3346        (apply old--fn args)
3347     (setq helm--reading-passwd-or-string nil)
3348     (setq helm-suspend-update-flag nil)))
3349
3350 (defun helm--maybe-update-keymap (&optional map)
3351   "Handle different keymaps in multiples sources.
3352
3353 Overrides `helm-map' with the local map of current source. If no
3354 map is found in current source, does nothing (keeps previous
3355 map)."
3356   (with-helm-buffer
3357     (helm-aif (or map (assoc-default 'keymap (helm-get-current-source)))
3358         ;; We used a timer in the past to leave
3359         ;; enough time to helm to setup its keymap
3360         ;; when changing source from a recursive minibuffer.
3361         ;; e.g C-x C-f M-y C-g
3362         ;; => *find-files have now the bindings of *kill-ring.
3363         ;; It is no more true now we are using `minor-mode-overriding-map-alist'
3364         ;; and `helm--minor-mode' thus it fix issue #1076 for emacs-24.3
3365         ;; where concurrent timers are not supported.
3366         ;; i.e update keymap+check input.
3367         (with-current-buffer (window-buffer (minibuffer-window))
3368           (setq minor-mode-overriding-map-alist `((helm--minor-mode . ,it)))))))
3369
3370 ;;; Prevent loosing focus when using mouse.
3371 ;;
3372 (defvar helm--remap-mouse-mode-map
3373   (let ((map (make-sparse-keymap)))
3374     (cl-loop for k in '([mouse-1] [mouse-2] [mouse-3]
3375                         [down-mouse-1] [down-mouse-2] [down-mouse-3]
3376                         [drag-mouse-1] [drag-mouse-2] [drag-mouse-3]
3377                         [double-mouse-1] [double-mouse-2] [double-mouse-3]
3378                         [triple-mouse-1] [triple-mouse-2] [triple-mouse-3])
3379              do (define-key map k 'ignore))
3380     map))
3381
3382 (define-minor-mode helm--remap-mouse-mode
3383     "[INTERNAL] Prevent escaping helm minibuffer with mouse clicks.
3384 Do nothing when used outside of helm context.
3385
3386 WARNING: Do not use this mode yourself, it is internal to helm."
3387   :group 'helm
3388   :global t
3389   :keymap helm--remap-mouse-mode-map
3390   (unless helm-alive-p
3391     (setq helm--remap-mouse-mode-map nil)))
3392 (put 'helm--remap-mouse-mode 'helm-only t)
3393
3394 ;; Clean up
3395
3396 (defun helm-cleanup ()
3397   "Clean up the mess when helm exit or quit."
3398   (helm-log "start cleanup")
3399   (with-current-buffer helm-buffer
3400     (let ((frame (selected-frame)))
3401       (setq cursor-type t)
3402       (remove-hook 'post-command-hook 'helm--maybe-update-keymap)
3403       (remove-hook 'post-command-hook 'helm--update-header-line)
3404       ;; Be sure we call cleanup functions from helm-buffer.
3405       (helm-compute-attr-in-sources 'cleanup)
3406       ;; Delete or make invisible helm frame.
3407       (if (and helm--buffer-in-new-frame-p (null helm--nested))
3408           (progn
3409             (setq-local helm--last-frame-parameters
3410                         (helm--get-frame-parameters))
3411             (bury-buffer)
3412             (if helm-display-buffer-reuse-frame
3413                 (make-frame-invisible frame) (delete-frame frame)))
3414         ;; bury-buffer from this window [1].
3415         ;; Do it at end to make sure buffer is still current.
3416         (bury-buffer))))
3417   (helm-kill-async-processes)
3418   ;; Remove the temporary hooks added
3419   ;; by `with-helm-temp-hook' that
3420   ;; may not have been consumed.
3421   (when helm--temp-hooks
3422     (cl-loop for (fn . hook) in helm--temp-hooks
3423              do (set hook (delete fn (symbol-value hook)))))
3424   ;; When running helm from a dedicated frame
3425   ;; with no minibuffer, helm will run in the main frame
3426   ;; which have a minibuffer, so be sure to disable
3427   ;; the `no-other-window' prop there.
3428   (helm-prevent-switching-other-window :enabled nil)
3429   (helm-log-run-hook 'helm-cleanup-hook)
3430   (helm-frame-or-window-configuration 'restore)
3431   ;; [1] now bury-buffer from underlying windows otherwise,
3432   ;; if this window is killed the underlying buffer will
3433   ;; be a helm buffer.
3434   (replace-buffer-in-windows helm-buffer)
3435   (setq helm-alive-p nil)
3436   ;; Prevent error "No buffer named *helm*" triggered by
3437   ;; `helm-set-local-variable'.
3438   (setq helm--force-updating-p nil)
3439   (setq helm--buffer-in-new-frame-p nil)
3440   ;; This is needed in some cases where last input
3441   ;; is yielded infinitely in minibuffer after helm session.
3442   (helm-clean-up-minibuffer))
3443
3444 (defun helm-clean-up-minibuffer ()
3445   "Remove contents of minibuffer."
3446   (let ((miniwin (minibuffer-window)))
3447     ;; Clean only current minibuffer used by helm.
3448     ;; i.e The precedent one is active.
3449     (unless (minibuffer-window-active-p miniwin)
3450       (with-current-buffer (window-buffer miniwin)
3451         (delete-minibuffer-contents)))))
3452
3453
3454 ;;; Input handling
3455 ;;
3456 ;;
3457 (defun helm-check-minibuffer-input ()
3458   "Check minibuffer content."
3459   (with-helm-quittable
3460     (with-selected-window (or (active-minibuffer-window)
3461                               (minibuffer-window))
3462       (helm-check-new-input (minibuffer-contents)))))
3463
3464 (defun helm-check-new-input (input)
3465   "Check INPUT string and update the helm buffer if necessary."
3466   (unless (equal input helm-pattern)
3467     (setq helm-pattern input)
3468     (unless (helm-action-window)
3469       (setq helm-input helm-pattern))
3470     (helm-log "helm-pattern = %S" helm-pattern)
3471     (helm-log "helm-input = %S" helm-input)
3472     (setq helm--in-update t)
3473     (helm-update)))
3474
3475 (defun helm--reset-update-flag ()
3476   (run-with-idle-timer
3477    helm-exit-idle-delay nil
3478    (lambda () (setq helm--in-update nil))))
3479
3480 ;; (add-hook 'helm-after-update-hook #'helm--reset-update-flag)
3481
3482
3483 ;; All candidates
3484
3485 (defun helm-get-candidates (source)
3486   "Retrieve and return the list of candidates from SOURCE."
3487   (let* ((candidate-fn (assoc-default 'candidates source))
3488          (candidate-proc (assoc-default 'candidates-process source))
3489          (inhibit-quit candidate-proc)
3490          cfn-error
3491          (notify-error
3492           (lambda (&optional e)
3493             (error
3494              "In `%s' source: `%s' %s %s"
3495              (assoc-default 'name source)
3496              (or candidate-fn candidate-proc)
3497              (if e "\n" "must be a list, a symbol bound to a list, or a function returning a list")
3498              (if e (prin1-to-string e) ""))))
3499          (candidates (condition-case-unless-debug err
3500                          ;; Process candidates-(process) function
3501                          ;; It may return a process or a list of candidates.
3502                          (if candidate-proc
3503                              ;; Calling `helm-interpret-value' with no
3504                              ;; SOURCE arg force the use of `funcall'
3505                              ;; and not `helm-apply-functions-from-source'.
3506                              (helm-interpret-value candidate-proc)
3507                            (helm-interpret-value candidate-fn source))
3508                        (error (helm-log "Error: %S" (setq cfn-error err)) nil))))
3509     (cond ((and (processp candidates) (not candidate-proc))
3510            (warn "Candidates function `%s' should be called in a `candidates-process' attribute"
3511                  candidate-fn))
3512           ((and candidate-proc (not (processp candidates)))
3513            (error "Candidates function `%s' should run a process" candidate-proc)))
3514     (cond ((processp candidates)
3515            ;; Candidates will be filtered later in process filter.
3516            candidates)
3517           ;; An error occured in candidates function.
3518           (cfn-error (unless helm--ignore-errors
3519                        (funcall notify-error cfn-error)))
3520           ;; Candidates function returns no candidates.
3521           ((or (null candidates)
3522                ;; Can happen when the output of a process
3523                ;; is empty, and the candidates function call
3524                ;; something like (split-string (buffer-string) "\n")
3525                ;; which result in a list of one empty string (Issue #938).
3526                ;; e.g (completing-read "test: " '(""))
3527                (equal candidates '("")))
3528            nil)
3529           ((listp candidates)
3530            ;; Transform candidates with `candidate-transformer' functions or
3531            ;; `real-to-display' functions if those are found,
3532            ;; otherwise return candidates unmodified.
3533            ;; `filtered-candidate-transformer' is NOT called here.
3534            (helm-transform-candidates candidates source))
3535           (t (funcall notify-error)))))
3536
3537 (defmacro helm-while-no-input (&rest body)
3538   "Same as `while-no-input' but without the `input-pending-p' test."
3539   (declare (debug t) (indent 0))
3540   (let ((catch-sym (make-symbol "input")))
3541     `(with-local-quit
3542        (catch ',catch-sym
3543          (let ((throw-on-input ',catch-sym))
3544            ,@body)))))
3545
3546 (defun helm-get-cached-candidates (source)
3547   "Return the cached value of candidates for SOURCE.
3548 Cache the candidates if there is no cached value yet."
3549   (let* ((name (assoc-default 'name source))
3550          (candidate-cache (gethash name helm-candidate-cache))
3551          (inhibit-quit (assoc-default 'candidates-process source)))
3552     (helm-aif candidate-cache
3553         (prog1 it (helm-log "Use cached candidates"))
3554       (helm-log "No cached candidates, calculate candidates")
3555       (let ((candidates (helm-get-candidates source)))
3556         (cond ((processp candidates)
3557                (push (cons candidates
3558                            (append source
3559                                    (list (cons 'item-count 0)
3560                                          (cons 'incomplete-line ""))))
3561                      helm-async-processes)
3562                (set-process-filter candidates 'helm-output-filter)
3563                (setq candidates nil))
3564               ((not (assq 'volatile source))
3565                (puthash name candidates helm-candidate-cache)))
3566         candidates))))
3567
3568
3569 ;;; Candidate transformers
3570
3571 (defun helm-process-candidate-transformer (candidates source)
3572   "Execute `candidate-transformer' function(s) on CANDIDATES in SOURCE."
3573   (helm-aif (assoc-default 'candidate-transformer source)
3574       (helm-apply-functions-from-source source it candidates)
3575     candidates))
3576
3577 (defun helm-process-filtered-candidate-transformer (candidates source)
3578   "Execute `filtered-candidate-transformer' function(s) on CANDIDATES in SOURCE."
3579   (helm-aif (assoc-default 'filtered-candidate-transformer source)
3580       (helm-apply-functions-from-source source it candidates source)
3581     candidates))
3582
3583 (defmacro helm--maybe-process-filter-one-by-one-candidate (candidate source)
3584   "Execute `filter-one-by-one' function(s) on real value of CANDIDATE in SOURCE."
3585   `(helm-aif (assoc-default 'filter-one-by-one ,source)
3586        (let ((real (if (consp ,candidate)
3587                        (cdr ,candidate)
3588                        ,candidate)))
3589          (if (and (listp it)
3590                   (not (functionp it))) ;; Don't treat lambda's as list.
3591              (cl-loop for f in it
3592                       do (setq ,candidate (funcall f real))
3593                       finally return ,candidate)
3594              (setq ,candidate (funcall it real))))
3595      ,candidate))
3596
3597 (defun helm--initialize-one-by-one-candidates (candidates source)
3598   "Process the CANDIDATES with the `filter-one-by-one' function in SOURCE.
3599 Return CANDIDATES unchanged when pattern is not empty."
3600   (helm-aif (and (string= helm-pattern "")
3601                  (assoc-default 'filter-one-by-one source))
3602       (cl-loop for cand in candidates collect
3603                (helm--maybe-process-filter-one-by-one-candidate cand source))
3604     candidates))
3605
3606 (defun helm-process-filtered-candidate-transformer-maybe
3607     (candidates source process-p)
3608   "Execute `filtered-candidate-transformer' function(s) on CANDIDATES in SOURCE.
3609 When PROCESS-P is non-`nil' execute `filtered-candidate-transformer'
3610 functions if some, otherwise return CANDIDATES."
3611   (if process-p
3612       ;; When no filter return CANDIDATES unmodified.
3613       (helm-process-filtered-candidate-transformer candidates source)
3614     candidates))
3615
3616 (defun helm-process-real-to-display (candidates source)
3617   "Execute real-to-display function on all CANDIDATES of SOURCE."
3618   (helm-aif (assoc-default 'real-to-display source)
3619       (setq candidates (helm-apply-functions-from-source
3620                         source 'mapcar
3621                         (lambda (cand)
3622                           (if (consp cand)
3623                               ;; override DISPLAY from candidate-transformer
3624                               (cons (funcall it (cdr cand)) (cdr cand))
3625                             (cons (funcall it cand) cand)))
3626                         candidates))
3627     candidates))
3628
3629 (defun helm-transform-candidates (candidates source &optional process-p)
3630   "Transform CANDIDATES from SOURCE according to candidate transformers.
3631
3632 When PROCESS-P is non-`nil' executes the
3633 `filtered-candidate-transformer' functions, otherwise processes
3634 `candidate-transformer' functions only,
3635 `filtered-candidate-transformer' functions being processed later,
3636 after the candidates have been narrowed by
3637 `helm-candidate-number-limit', see `helm-compute-matches'.  When
3638 `real-to-display' attribute is present, execute its functions on all
3639 maybe filtered CANDIDATES."
3640   (helm-process-real-to-display
3641    (helm-process-filtered-candidate-transformer-maybe
3642     (helm-process-candidate-transformer
3643      candidates source)
3644     source process-p)
3645    source))
3646
3647
3648 ;; Narrowing candidates
3649 (defun helm-candidate-number-limit (source)
3650   "Apply candidate-number-limit attribute value.
3651 This overrides `helm-candidate-number-limit' variable.
3652
3653 e.g:
3654 If \(candidate-number-limit\) is in SOURCE, show all candidates in SOURCE.
3655 If \(candidate-number-limit . 123\) is in SOURCE limit candidate to 123."
3656   (helm-aif (assq 'candidate-number-limit source)
3657       ;; When assoc value is nil use by default 99999999 otherwise use
3658       ;; the assoc value, when it is a symbol interpret its value (#1831).
3659       (or (helm-aand (cdr it) (helm-interpret-value it)) 99999999)
3660     (or helm-candidate-number-limit 99999999)))
3661
3662 (defun helm-candidate-get-display (candidate)
3663   "Get searched display part from CANDIDATE.
3664 CANDIDATE is either a string, a symbol, or a \(DISPLAY . REAL\)
3665 cons cell."
3666   (cond ((car-safe candidate))
3667         ((symbolp candidate)
3668          (symbol-name candidate))
3669         ((numberp candidate)
3670          (number-to-string candidate))
3671         (t candidate)))
3672
3673 (defun helm-process-pattern-transformer (pattern source)
3674   "Execute pattern-transformer attribute function(s) on PATTERN in SOURCE."
3675   (helm-aif (assoc-default 'pattern-transformer source)
3676       (helm-apply-functions-from-source source it pattern)
3677     pattern))
3678
3679 (defun helm-default-match-function (candidate)
3680   "Check if `helm-pattern' match CANDIDATE.
3681 Default function to match candidates according to `helm-pattern'."
3682   (string-match helm-pattern candidate))
3683
3684
3685 ;;; Fuzzy matching
3686 ;;
3687 ;;
3688 (defvar helm--fuzzy-regexp-cache (make-hash-table :test 'eq))
3689 (defun helm--fuzzy-match-maybe-set-pattern ()
3690   ;; Computing helm-pattern with helm--mapconcat-pattern
3691   ;; is costly, so cache it once time for all and reuse it
3692   ;; until pattern change.
3693   (when helm--in-fuzzy
3694     (let ((fun (if (string-match "\\`\\^" helm-pattern)
3695                    #'identity
3696                    #'helm--mapconcat-pattern)))
3697       (clrhash helm--fuzzy-regexp-cache)
3698       ;; FIXME: Splitted part are not handled here,
3699       ;; I must compute them in `helm-search-match-part'
3700       ;; when negation and in-buffer are used.
3701       (if (string-match "\\`!" helm-pattern)
3702           (puthash 'helm-pattern
3703                    (if (> (length helm-pattern) 1)
3704                        (list (funcall fun (substring helm-pattern 1 2))
3705                              (funcall fun (substring helm-pattern 1)))
3706                        '("" ""))
3707                    helm--fuzzy-regexp-cache)
3708           (puthash 'helm-pattern
3709                    (if (> (length helm-pattern) 0)
3710                        (list (funcall fun (substring helm-pattern 0 1))
3711                              (funcall fun helm-pattern))
3712                        '("" ""))
3713                    helm--fuzzy-regexp-cache)))))
3714
3715 (defun helm-fuzzy-match (candidate)
3716   "Check if `helm-pattern' fuzzy matches CANDIDATE.
3717 This function is used with sources built with `helm-source-sync'."
3718   (unless (string-match " " helm-pattern)
3719     ;; When pattern have one or more spaces, let
3720     ;; multi-match doing the job with no fuzzy matching.[1]
3721     (let ((regexp (cadr (gethash 'helm-pattern helm--fuzzy-regexp-cache))))
3722       (if (string-match "\\`!" helm-pattern)
3723           (not (string-match regexp candidate))
3724         (string-match regexp candidate)))))
3725
3726 (defun helm-fuzzy-search (pattern)
3727   "Same as `helm-fuzzy-match' but for sources built with
3728 `helm-source-in-buffer'."
3729   (unless (string-match " " helm-pattern)
3730     ;; Same as in `helm-fuzzy-match' ref[1].
3731     (let* ((regexps (gethash 'helm-pattern helm--fuzzy-regexp-cache))
3732            (partial-regexp (car regexps))
3733            (regexp (cadr regexps)))
3734       (if (string-match "\\`!" pattern)
3735           ;; Don't try to search here, just return
3736           ;; the position of line and go ahead,
3737           ;; letting `helm-search-match-part' checking if
3738           ;; pattern match against this line.
3739           (prog1 (list (point-at-bol) (point-at-eol))
3740             (forward-line 1))
3741         ;; We could use here directly `re-search-forward'
3742         ;; on the regexp produced by `helm--mapconcat-pattern',
3743         ;; but it is very slow because emacs have to do an incredible
3744         ;; amount of loops to match e.g "[^f]*f[^o]*o..." in the whole buffer,
3745         ;; more the regexp is long more the amount of loops grow.
3746         ;; (Probably leading to a max-lisp-eval-depth error if both
3747         ;; regexp and buffer are too big)
3748         ;; So just search the first bit of pattern e.g "[^f]*f", and
3749         ;; then search the corresponding line with the whole regexp,
3750         ;; which increase dramatically the speed of the search.
3751         (cl-loop while (re-search-forward partial-regexp nil t)
3752                  for bol = (point-at-bol)
3753                  for eol = (point-at-eol)
3754                  if (progn (goto-char bol)
3755                            (re-search-forward regexp eol t))
3756                  do (goto-char eol) and return t
3757                  else do (goto-char eol)
3758                  finally return nil)))))
3759
3760 (defun helm-score-candidate-for-pattern (candidate pattern)
3761   "Assign score to CANDIDATE according to PATTERN.
3762 Score is calculated for contiguous matches found with PATTERN.
3763 Score is 100 (maximum) if PATTERN is fully matched in CANDIDATE.
3764 One point bonus is added to score when PATTERN prefix matches
3765 CANDIDATE. Contiguous matches get a coefficient of 2."
3766   (let* ((cand (if (stringp candidate)
3767                    candidate (helm-stringify candidate)))
3768          (pat-lookup (helm--collect-pairs-in-string pattern))
3769          (str-lookup (helm--collect-pairs-in-string cand))
3770          (bonus (cond ((equal (car pat-lookup) (car str-lookup))
3771                        1)
3772                       ((and (null pat-lookup) ; length = 1
3773                             (string= pattern (substring cand 0 1)))
3774                        150)
3775                       (t 0)))
3776          (bonus1 (and (string-match (concat "\\<" (regexp-quote pattern) "\\>")
3777                                     cand)
3778                       100)))
3779     (+ bonus (or bonus1
3780                  ;; Give a coefficient of 2 for contiguous matches.
3781                  ;; That's mean that "wiaaaki" will not take precedence
3782                  ;; on "aaawiki" when matching on "wiki" even if "wiaaaki"
3783                  ;; starts by "wi".
3784                  (* (length (cl-nintersection
3785                              pat-lookup str-lookup :test 'equal))
3786                     2)))))
3787
3788 (defun helm-fuzzy-matching-default-sort-fn-1 (candidates &optional use-real basename preserve-tie-order)
3789   "The transformer for sorting candidates in fuzzy matching.
3790 It sorts on the display part by default.
3791
3792 Sorts CANDIDATES by their scores as calculated by
3793 `helm-score-candidate-for-pattern'.  Set USE-REAL to non-`nil' to
3794 sort on the real part.  If BASENAME is non-nil assume we are
3795 completing filenames and sort on basename of candidates.  If
3796 PRESERVE-TIE-ORDER is nil, ties in scores are sorted by length of
3797 the candidates."
3798   (if (string= helm-pattern "")
3799       candidates
3800     (let ((table-scr (make-hash-table :test 'equal)))
3801       (sort candidates
3802             (lambda (s1 s2)
3803               ;; Score and measure the length on real or display part of candidate
3804               ;; according to `use-real'.
3805               (let* ((real-or-disp-fn (if use-real #'cdr #'car))
3806                      (cand1 (cond ((and basename (consp s1))
3807                                    (helm-basename (funcall real-or-disp-fn s1)))
3808                                   ((consp s1) (funcall real-or-disp-fn s1))
3809                                   (basename (helm-basename s1))
3810                                   (t s1)))
3811                      (cand2 (cond ((and basename (consp s2))
3812                                    (helm-basename (funcall real-or-disp-fn s2)))
3813                                   ((consp s2) (funcall real-or-disp-fn s2))
3814                                   (basename (helm-basename s2))
3815                                   (t s2)))
3816                      (data1 (or (gethash cand1 table-scr)
3817                                 (puthash cand1
3818                                          (list (helm-score-candidate-for-pattern
3819                                                 cand1 helm-pattern)
3820                                                (length (helm-stringify cand1)))
3821                                          table-scr)))
3822                      (data2 (or (gethash cand2 table-scr)
3823                                 (puthash cand2
3824                                          (list (helm-score-candidate-for-pattern
3825                                                 cand2 helm-pattern)
3826                                                (length (helm-stringify cand2)))
3827                                          table-scr)))
3828                      (len1 (cadr data1))
3829                      (len2 (cadr data2))
3830                      (scr1 (car data1))
3831                      (scr2 (car data2)))
3832                 (cond ((= scr1 scr2)
3833                        (unless preserve-tie-order
3834                          (< len1 len2)))
3835                       ((> scr1 scr2)))))))))
3836
3837 (defun helm-fuzzy-matching-default-sort-fn (candidates _source)
3838   "Default `filtered-candidate-transformer' to sort candidates in fuzzy matching."
3839   (helm-fuzzy-matching-default-sort-fn-1 candidates))
3840
3841 (defun helm-fuzzy-matching-sort-fn-preserve-ties-order (candidates _source)
3842   "`filtered-candidate-transformer' to sort candidates in fuzzy matching, preserving order of ties.
3843 The default function, `helm-fuzzy-matching-default-sort-fn',
3844 sorts ties by length, shortest first.  This function may be more
3845 useful when the order of the candidates is meaningful, e.g. with
3846 `recentf-list'."
3847   (helm-fuzzy-matching-default-sort-fn-1 candidates nil t))
3848
3849 (defun helm--maybe-get-migemo-pattern (pattern)
3850   (or (and helm-migemo-mode
3851            (assoc-default pattern helm-mm--previous-migemo-info))
3852       pattern))
3853
3854 (defun helm-fuzzy-default-highlight-match (candidate)
3855   "The default function to highlight matches in fuzzy matching.
3856 Highlight elements in CANDIDATE matching `helm-pattern' according
3857 to the matching method in use."
3858   (if (string= helm-pattern "")
3859       ;; Empty pattern, do nothing.
3860       candidate
3861     ;; Else start highlighting.
3862     (let* ((pair    (and (consp candidate) candidate))
3863            (display (helm-stringify (if pair (car pair) candidate)))
3864            (real    (cdr pair))
3865            (regex   (helm--maybe-get-migemo-pattern helm-pattern))
3866            (mp      (pcase (get-text-property 0 'match-part display)
3867                       ((pred (string= display)) nil)
3868                       (str str)))
3869            (count   0)
3870            beg-str end-str)
3871       ;; Extract all parts of display keeping original properties.
3872       (when (and mp (string-match (regexp-quote mp) display))
3873         (setq beg-str (substring display 0 (match-beginning 0))
3874               end-str (substring display (match-end 0) (length display))
3875               mp (substring display (match-beginning 0) (match-end 0))))
3876       (with-temp-buffer
3877         ;; Insert the whole display part and remove non--match-part
3878         ;; to keep their original face properties.
3879         (insert (propertize (or mp display) 'read-only nil)) ; Fix (#1176)
3880         (goto-char (point-min))
3881         (condition-case nil
3882             (progn
3883               ;; Try first matching against whole pattern.
3884               (while (re-search-forward regex nil t)
3885                 (cl-incf count)
3886                 (helm-add-face-text-properties
3887                  (match-beginning 0) (match-end 0) 'helm-match))
3888               ;; If no matches start matching against multiples or fuzzy matches.
3889               (when (zerop count)
3890                 (cl-loop with multi-match = (string-match-p " " helm-pattern)
3891                          with patterns = (if multi-match
3892                                              (mapcar #'helm--maybe-get-migemo-pattern
3893                                                      (helm-mm-split-pattern helm-pattern))
3894                                              (split-string helm-pattern "" t))
3895                          for p in patterns
3896                          ;; Multi matches (regexps patterns).
3897                          if multi-match do
3898                          (progn
3899                            (while (re-search-forward p nil t)
3900                              (helm-add-face-text-properties
3901                               (match-beginning 0) (match-end 0)
3902                               'helm-match))
3903                            (goto-char (point-min)))
3904                          ;; Fuzzy matches (literal patterns).
3905                          else do
3906                          (when (search-forward p nil t)
3907                            (helm-add-face-text-properties
3908                             (match-beginning 0) (match-end 0)
3909                             'helm-match)))))
3910           (invalid-regexp nil))
3911         ;; Now replace the original match-part with the part
3912         ;; with face properties added.
3913         (setq display (if mp (concat beg-str (buffer-string) end-str) (buffer-string))))
3914       (if real (cons display real) display))))
3915
3916 (defun helm-fuzzy-highlight-matches (candidates _source)
3917   "The filtered-candidate-transformer function to highlight fuzzy matches.
3918 See `helm-fuzzy-default-highlight-match'."
3919   (cl-loop for c in candidates
3920            collect (funcall helm-fuzzy-matching-highlight-fn c)))
3921
3922
3923 ;;; Matching candidates
3924 ;;
3925 ;;
3926 (defun helm-match-functions (source)
3927   (let ((matchfns (or (assoc-default 'match source)
3928                       (assoc-default 'match-strict source)
3929                       #'helm-default-match-function)))
3930     (if (and (listp matchfns) (not (functionp matchfns)))
3931         matchfns (list matchfns))))
3932
3933 (defun helm-search-functions (source)
3934   (let ((searchfns (assoc-default 'search source)))
3935     (if (and (listp searchfns) (not (functionp searchfns)))
3936         searchfns (list searchfns))))
3937
3938 (defun helm-take-first-elements (seq n)
3939   "Return the first N elements of SEQ if SEQ is longer than N.
3940 It is used for narrowing list of candidates to the
3941 `helm-candidate-number-limit'."
3942   (if (> (length seq) n) (cl-subseq seq 0 n) seq))
3943
3944 (defun helm-match-from-candidates (cands matchfns match-part-fn limit source)
3945   (condition-case-unless-debug err
3946       (cl-loop with hash = (make-hash-table :test 'equal)
3947                with allow-dups = (assq 'allow-dups source)
3948                with case-fold-search = (helm-set-case-fold-search)
3949                with count = 0
3950                for iter from 1
3951                for fn in matchfns
3952                when (< count limit) nconc
3953                (cl-loop for c in cands
3954                         for dup = (gethash c hash)
3955                         while (< count limit)
3956                         for target = (helm-candidate-get-display c)
3957                         for prop-part = (get-text-property 0 'match-part target)
3958                         for part = (and match-part-fn
3959                                         (or prop-part
3960                                             (funcall match-part-fn target)))
3961                         ;; When allowing dups check if DUP
3962                         ;; have been already found in previous loop
3963                         ;; by comparing its value with ITER.
3964                         when (and (or (and allow-dups dup (= dup iter))
3965                                       (null dup))
3966                                   (condition-case nil
3967                                       (funcall fn (or part target))
3968                                     (invalid-regexp nil)))
3969                         do
3970                         (progn
3971                           ;; Give as value the iteration number of
3972                           ;; inner loop to be able to check if
3973                           ;; the duplicate have not been found in previous loop.
3974                           (puthash c iter hash)
3975                           (helm--maybe-process-filter-one-by-one-candidate c source)
3976                           (cl-incf count))
3977                         ;; Filter out nil candidates maybe returned by
3978                         ;; `helm--maybe-process-filter-one-by-one-candidate'.
3979                         and when c collect
3980                         (if (and part (not prop-part))
3981                             (if (consp c)
3982                                 (cons (propertize target 'match-part part) (cdr c))
3983                               (propertize c 'match-part part))
3984                           c)))
3985     (error (unless (eq (car err) 'invalid-regexp) ; Always ignore regexps errors.
3986              (helm-log-error "helm-match-from-candidates in source `%s': %s %s"
3987                              (assoc-default 'name source) (car err) (cdr err)))
3988            nil)))
3989
3990 (defun helm-compute-matches (source)
3991   "Start computing candidates in SOURCE."
3992   (save-current-buffer
3993     (let ((matchfns (helm-match-functions source))
3994           (matchpartfn (assoc-default 'match-part source))
3995           (helm--source-name (assoc-default 'name source))
3996           (helm-current-source source)
3997           (limit (helm-candidate-number-limit source))
3998           (helm-pattern (helm-process-pattern-transformer
3999                          helm-pattern source)))
4000       (helm--fuzzy-match-maybe-set-pattern)
4001       ;; If source have a `filtered-candidate-transformer' attr
4002       ;; Filter candidates with this func, otherwise just compute
4003       ;; candidates.
4004       ;; NOTE that this next block of code is returning nil on async sources,
4005       ;; the candidates being processed directly in `helm-output-filter'
4006       ;; process-filter. 
4007       (helm-process-filtered-candidate-transformer
4008        ;; Using in-buffer method or helm-pattern is empty
4009        ;; in this case compute all candidates.
4010        (if (or (equal helm-pattern "")
4011                (helm--candidates-in-buffer-p matchfns))
4012            ;; Compute all candidates up to LIMIT.
4013            ;; one-by-one are computed here only for sources that
4014            ;; display a list of  candidates even with an empty
4015            ;; pattern.
4016            (helm--initialize-one-by-one-candidates
4017             (helm-take-first-elements
4018              (helm-get-cached-candidates source) limit)
4019             source)
4020            ;; Compute candidates according to pattern with their match
4021            ;; fns.
4022            ;; one-by-one filtered candidates are computed during the
4023            ;; execution of next loop in `helm-match-from-candidates'.
4024            (helm-match-from-candidates
4025             (helm-get-cached-candidates source) matchfns matchpartfn limit source))
4026        source))))
4027
4028 (defun helm--candidates-in-buffer-p (matchfns)
4029   (equal matchfns '(identity)))
4030
4031 (defun helm-render-source (source matches)
4032   "Display MATCHES from SOURCE according to its settings."
4033   (helm-log "Source name = %S" (assoc-default 'name source))
4034   (when matches
4035     (helm-insert-header-from-source source)
4036     (cl-loop with separate = nil
4037              with start = (point)
4038              with singleline = (null (assq 'multiline source))
4039              for m in matches
4040              for count from 1
4041              if singleline
4042              do (helm-insert-match m 'insert count source)
4043              else
4044              do (progn
4045                   (if separate
4046                       (helm-insert-candidate-separator)
4047                     (setq separate t))
4048                   (helm-insert-match m 'insert count source))
4049              finally (and (null singleline)
4050                           (put-text-property start (point)
4051                                              'helm-multiline t)))))
4052
4053 (defmacro helm--maybe-use-while-no-input (&rest body)
4054   "Wrap BODY in `helm-while-no-input' unless initializing a remote connection."
4055   `(progn
4056      (if (and (file-remote-p helm-pattern)
4057               (not (file-remote-p helm-pattern nil t)))
4058          ;; Tramp will ask for passwd, don't use `helm-while-no-input'.
4059          ,@body
4060        (helm-log "Using here `helm-while-no-input'")
4061        (helm-while-no-input ,@body))))
4062
4063 (defun helm--collect-matches (src-list)
4064   "Returns a list of matches for each source in SRC-LIST.
4065
4066 The resulting value is a list of lists, e.g ((a b c) (c d) (e f)) or
4067 \(nil nil nil) for three sources when no matches found, however this
4068 function can be interrupted by new input and in this case returns a
4069 plain `nil' i.e not (nil), in this case `helm-update' is not rendering
4070 the source, keeping previous candidates in display."
4071   (let ((matches (helm--maybe-use-while-no-input
4072                   (cl-loop for src in src-list
4073                            collect (helm-compute-matches src)))))
4074     (unless (eq matches t) matches)))
4075
4076
4077 ;;; Case fold search
4078 ;;
4079 ;;
4080 (cl-defun helm-set-case-fold-search (&optional (pattern helm-pattern))
4081   "Used to set the value of `case-fold-search' in helm.
4082 Return t or nil depending on the value of `helm-case-fold-search'
4083 and `helm-pattern'."
4084   (let ((helm-case-fold-search
4085          (helm-aif (assq 'case-fold-search (helm-get-current-source))
4086              (cdr it)
4087            helm-case-fold-search))
4088         ;; Only parse basename for filenames
4089         ;; to avoid setting case sensitivity
4090         ;; when expanded directories contains upcase
4091         ;; characters.
4092         (bn-or-pattern (if (string-match "[~/]*" pattern)
4093                            (helm-basename pattern)
4094                          pattern)))
4095     (helm-set-case-fold-search-1 bn-or-pattern)))
4096
4097 (defun helm-set-case-fold-search-1 (pattern)
4098   (cl-case helm-case-fold-search
4099     (smart (let ((case-fold-search nil))
4100              (if (string-match "[[:upper:]]" pattern) nil t)))
4101     (t helm-case-fold-search)))
4102
4103
4104 ;;; Helm update
4105 ;;
4106 (defun helm-update (&optional preselect source candidates)
4107   "Update candidates list in `helm-buffer' based on `helm-pattern'.
4108 Argument PRESELECT is a string or regexp used to move selection
4109 to a particular place after finishing update.
4110 When SOURCE is provided update mode-line for this source, otherwise
4111 the current source will be used.
4112 Argument CANDIDATES when provided is used to redisplay these candidates
4113 without recomputing them, it should be a list of lists."
4114   (helm-log "Start updating")
4115   (helm-kill-async-processes)
4116   ;; When persistent action have been called
4117   ;; we have two windows even with `helm-full-frame'.
4118   ;; So go back to one window when updating if `helm-full-frame'
4119   ;; is non-`nil'.
4120   (when (with-helm-buffer
4121           (and helm-onewindow-p
4122                ;; We are not displaying helm-buffer in a frame and
4123                ;; helm-window is already displayed.
4124                (not helm--buffer-in-new-frame-p)
4125                (helm-window)
4126                (not (helm-action-window))))
4127     (with-helm-window (delete-other-windows)))
4128   (with-current-buffer (helm-buffer-get)
4129     (set (make-local-variable 'helm-input-local) helm-pattern)
4130     (unwind-protect
4131          (let (sources matches)
4132            ;; Collect sources ready to be updated.
4133            (setq sources
4134                  (cl-loop for src in helm-sources
4135                           when (helm-update-source-p src)
4136                           collect src))
4137            ;; When no sources to update erase buffer
4138            ;; to avoid duplication of header and candidates
4139            ;; when next chunk of update will arrive,
4140            ;; otherwise the buffer is erased AFTER [1] the results
4141            ;; are computed.
4142            (unless sources (erase-buffer))
4143            ;; Compute matches without rendering the sources.
4144            ;; This prevent the helm-buffer flickering when constantly
4145            ;; updating.
4146            (helm-log "Matches: %S"
4147                      (setq matches (or candidates (helm--collect-matches sources))))
4148            ;; If computing matches finished and is not interrupted
4149            ;; erase the helm-buffer and render results (Fix #1157).
4150            (when matches ;; nil only when interrupted by helm-while-no-input.
4151              (erase-buffer)             ; [1]
4152              (cl-loop for src in sources
4153                       for mtc in matches
4154                       do (helm-render-source src mtc))
4155              ;; Move to first line only when there is matches
4156              ;; to avoid cursor moving upside down (issue #1703).
4157              (helm--update-move-first-line)
4158              (helm--reset-update-flag)))
4159       ;; When there is only one async source, update mode-line and run
4160       ;; `helm-after-update-hook' in `helm-output-filter--post-process',
4161       ;; when there is more than one source, update mode-line and run
4162       ;; `helm-after-update-hook' now even if an async source is
4163       ;; present and running in BG.
4164       (let ((src (or source (helm-get-current-source))))
4165         (unless (assq 'candidates-process src)
4166           (and src (helm-display-mode-line src 'force))
4167           (helm-log-run-hook 'helm-after-update-hook)))
4168       (when preselect
4169         (helm-log "Update preselect candidate %s" preselect)
4170         (if (helm-window)
4171             (with-helm-window (helm-preselect preselect source))
4172           (helm-preselect preselect source)))
4173       (setq helm--force-updating-p nil))
4174     (helm-log "end update")))
4175
4176 (defun helm-update-source-p (source)
4177   "Whether SOURCE needs updating or not."
4178   (let ((len (string-width
4179               (if (assq 'multimatch source)
4180                   ;; Don't count spaces entered when using
4181                   ;; multi-match.
4182                   (replace-regexp-in-string " " "" helm-pattern)
4183                 helm-pattern))))
4184     (and (or (not helm-source-filter)
4185              (member (assoc-default 'name source) helm-source-filter))
4186          (>= len
4187              (helm-aif (assq 'requires-pattern source) (or (cdr it) 1) 0))
4188          ;; Entering repeatedly these strings (*, ?) takes 100% CPU
4189          ;; and hang emacs on MacOs preventing deleting backward those
4190          ;; characters (issue #1802).
4191          (not (string-match-p "\\`[*]+\\'" helm-pattern))
4192          ;; These incomplete regexps hang helm forever
4193          ;; so defer update. Maybe replace spaces quoted when using
4194          ;; multi-match.
4195          (not (member (replace-regexp-in-string "\\s\\ " " " helm-pattern)
4196                       helm-update-blacklist-regexps)))))
4197
4198 (defun helm--update-move-first-line ()
4199   "Goto first line of `helm-buffer'."
4200   (goto-char (point-min))
4201   (if (helm-window)
4202       (helm-move-selection-common :where 'line
4203                                   :direction 'next
4204                                   :follow t)
4205     (forward-line 1)
4206     (helm-mark-current-line)
4207     (helm-follow-execute-persistent-action-maybe)))
4208
4209 (cl-defun helm-force-update (&optional preselect (recenter t))
4210   "Force recalculation and update of candidates.
4211
4212 Unlike `helm-update', this function re-evaluates `init' and
4213 `update' attributes when present; also `helm-candidate-cache' is
4214 not reinitialized, meaning candidates are not recomputed unless
4215 pattern has changed.
4216
4217 Selection is preserved to current candidate if it still exists after
4218 update or moved to PRESELECT, if specified.
4219 The helm-window is recentered at the end when RECENTER is `t'
4220 which is the default, RECENTER can be also a number in this case it is
4221 passed as argument to `recenter'."
4222   (with-helm-buffer
4223     (let* ((source    (helm-get-current-source))
4224            (selection (helm-aif (helm-get-selection nil t source)
4225                           (regexp-quote it))))
4226       (setq helm--force-updating-p t)
4227       (mapc 'helm-force-update--reinit helm-sources)
4228       (helm-update (or preselect selection) source)
4229       (when (and (helm-window) recenter)
4230         (with-helm-window
4231           (recenter (and (numberp recenter) recenter)))))))
4232
4233 (defun helm-refresh ()
4234   "Force recalculation and update of candidates."
4235   (interactive)
4236   (with-helm-alive-p
4237     (helm-force-update)))
4238 (put 'helm-refresh 'helm-only t)
4239
4240 (defun helm-force-update--reinit (source)
4241   "Reinit SOURCE by calling its update and init functions."
4242   ;; When using a specific buffer as cache, don't kill it.
4243   (helm-aif (and (null (bufferp (assoc-default
4244                                  (helm-attr 'name source)
4245                                  helm--candidate-buffer-alist)))
4246                  (helm-apply-functions-from-source
4247                   source 'helm-candidate-buffer))
4248       (kill-buffer it))
4249   (cl-dolist (attr '(update init))
4250     (helm-aif (assoc-default attr source)
4251         (helm-apply-functions-from-source source it)))
4252   (helm-remove-candidate-cache source))
4253
4254 (defun helm-redisplay-buffer ()
4255   "Redisplay candidates in `helm-buffer'.
4256
4257 Candidates are not recomputed, only redisplayed after modifying the
4258 whole list of candidates in each source with functions found in
4259 `redisplay' attribute of current source.  Note that candidates are
4260 redisplayed with their display part with all properties included only.
4261 This function is used in async sources to transform the whole list of
4262 candidates from the sentinel functions (i.e when all candidates have
4263 been computed) because other filters like `candidate-transformer' are
4264 modifying only each chunk of candidates from process-filter as they
4265 come in and not the whole list.  Use this for e.g sorting the whole
4266 list of async candidates once computed.
4267 Note: To ensure redisplay is done in async sources after helm
4268 reached `candidate-number-limit' you will have also to redisplay your
4269 candidates from `helm-async-outer-limit-hook'."
4270   (with-helm-buffer
4271     (let ((get-cands (lambda (source)
4272                        (let ((fns (assoc-default 'redisplay source))
4273                              candidates
4274                              helm-move-to-line-cycle-in-source
4275                              helm-allow-mouse)
4276                          (helm-goto-source source)
4277                          (helm-next-line)
4278                          (helm-awhile (condition-case-unless-debug nil
4279                                           (and (not (helm-pos-header-line-p))
4280                                                (helm-get-selection
4281                                                 nil 'withprop source))
4282                                         (error nil))
4283                            (push it candidates)
4284                            (when (save-excursion
4285                                    (forward-line 1) (helm-end-of-source-p t))
4286                              (cl-return nil))
4287                            (helm-next-line))
4288                          (helm-apply-functions-from-source
4289                           source fns (nreverse candidates)))))
4290           (get-sources (lambda ()
4291                          (let (sources helm-move-to-line-cycle-in-source)
4292                            (helm-awhile (helm-get-current-source)
4293                              (push it sources)
4294                              (when (save-excursion
4295                                      (helm-move--end-of-source)
4296                                      (forward-line 1) (eobp))
4297                              (cl-return nil))
4298                              (helm-next-source))
4299                            (nreverse sources)))))
4300       (goto-char (point-min))
4301       (helm-update nil (helm-get-current-source)
4302                    (cl-loop with sources = (funcall get-sources)
4303                             for s in helm-sources
4304                             for name =  (assoc-default 'name s) collect
4305                             (when (cl-loop for src in sources thereis
4306                                            (string= name
4307                                                     (assoc-default 'name src)))
4308                                       (funcall get-cands s)))))))
4309
4310 (defun helm-remove-candidate-cache (source)
4311   "Remove SOURCE from `helm-candidate-cache'."
4312   (remhash (assoc-default 'name source) helm-candidate-cache))
4313
4314 (defun helm-insert-match (match insert-function &optional num source)
4315   "Insert MATCH into `helm-buffer' with INSERT-FUNCTION.
4316 If MATCH is a cons cell then insert the car as display with
4317 the cdr stored as real value in a `helm-realvalue' text property.
4318 Args NUM and SOURCE are also stored as text property when specified as
4319 respectively `helm-cand-num' and `helm-cur-source'."
4320   (let ((start     (point-at-bol (point)))
4321         (dispvalue (helm-candidate-get-display match))
4322         (realvalue (cdr-safe match))
4323         (map       (when helm-allow-mouse (make-sparse-keymap)))
4324         (inhibit-read-only t)
4325         end)
4326     (when (and (stringp dispvalue)
4327                (not (zerop (length dispvalue))))
4328       (funcall insert-function dispvalue)
4329       (setq end (point-at-eol))
4330       ;; Some strings may handle another keymap prop.
4331       (remove-text-properties start end '(keymap nil))
4332       (put-text-property start end 'read-only nil)
4333       ;; Some sources with candidates-in-buffer have already added
4334       ;; 'helm-realvalue property when creating candidate buffer.
4335       (unless (get-text-property start 'helm-realvalue)
4336         (and realvalue
4337              (put-text-property start end
4338                                 'helm-realvalue realvalue)))
4339       (when map
4340         (define-key map [mouse-1] 'helm-mouse-select-candidate)
4341         (define-key map [mouse-2] 'ignore)
4342         (define-key map [mouse-3] 'helm-select-action)
4343         (add-text-properties
4344          start end
4345          `(mouse-face highlight
4346            keymap ,map
4347            help-echo ,(pcase (get-text-property start 'help-echo)
4348                         ((and it (pred stringp))
4349                          (concat it "\nmouse-1: select candidate\nmouse-3: menu actions"))
4350                         (_ "mouse-1: select candidate\nmouse-3: menu actions")))))
4351       (when num
4352         (put-text-property start end 'helm-cand-num num))
4353       (when source
4354         (put-text-property start end 'helm-cur-source source))
4355       (funcall insert-function "\n"))))
4356
4357 (defun helm--mouse-reset-selection-help-echo ()
4358   (let* ((inhibit-read-only t)
4359          (start (overlay-start helm-selection-overlay))
4360          (end   (overlay-end helm-selection-overlay))
4361          (help-echo (get-text-property start 'help-echo)))
4362     (when (and (stringp help-echo)
4363                (string-match "mouse-2: execute action" help-echo))
4364       (put-text-property
4365        start end
4366        'help-echo (replace-match "mouse-1: select candidate"
4367                                  t t help-echo)))))
4368
4369 (defun helm--bind-mouse-for-selection (pos)
4370   (let ((inhibit-read-only t)
4371         (map (get-text-property pos 'keymap)))
4372     (when map
4373       (define-key map [mouse-2] 'helm-maybe-exit-minibuffer)
4374       (put-text-property
4375        helm-selection-point
4376        (overlay-end helm-selection-overlay)
4377        'help-echo (helm-aif (get-text-property pos 'help-echo)
4378                       (if (and (stringp it)
4379                                (string-match "mouse-1: select candidate" it))
4380                           (replace-match "mouse-2: execute action" t t it)
4381                         "mouse-2: execute action\nmouse-3: menu actions")
4382                     "mouse-2: execute action\nmouse-3: menu actions")))))
4383
4384 (defun helm-mouse-select-candidate (event)
4385   (interactive "e")
4386   (let* ((window (posn-window (event-end event)))
4387          (pos    (posn-point (event-end event))))
4388     (unwind-protect
4389          (with-current-buffer (window-buffer window)
4390            (if (and (helm-action-window)
4391                     (eql window (get-buffer-window helm-buffer)))
4392                (user-error "selection in helm-window not available while selecting action")
4393                (helm--mouse-reset-selection-help-echo)
4394                (goto-char pos)
4395                (when (helm-pos-multiline-p)
4396                  (goto-char (or (helm-get-previous-candidate-separator-pos)
4397                                 (helm-get-previous-header-pos)))
4398                  (forward-line 1)))
4399            (helm-mark-current-line)
4400            (helm-follow-execute-persistent-action-maybe))
4401       (select-window (minibuffer-window))
4402       (set-buffer (window-buffer window)))))
4403 (put 'helm-mouse-select-candidate 'helm-only t)
4404
4405 (defun helm-insert-header-from-source (source)
4406   "Insert SOURCE name in `helm-buffer' header.
4407 Maybe insert, by overlay, additional info after the source name
4408 if SOURCE has header-name attribute."
4409   (let ((name (assoc-default 'name source)))
4410     (helm-insert-header
4411      name
4412      (helm-aif (assoc-default 'header-name source)
4413          (helm-apply-functions-from-source source it name)))))
4414
4415 (defun helm-insert-header (name &optional display-string)
4416   "Insert header of source NAME into the helm buffer.
4417 If DISPLAY-STRING is non-`nil' and a string value then display
4418 this additional info after the source name by overlay."
4419   (unless (bobp)
4420     (let ((start (point)))
4421       (insert "\n")
4422       (put-text-property start (point) 'helm-header-separator t)))
4423   (let ((start (point)))
4424     (insert name)
4425     (put-text-property (point-at-bol)
4426                        (point-at-eol) 'helm-header t)
4427     (when display-string
4428       (overlay-put (make-overlay (point-at-bol) (point-at-eol))
4429                    'display display-string))
4430     (insert "\n")
4431     (put-text-property start (point) 'face 'helm-source-header)))
4432
4433 (defun helm-insert-candidate-separator ()
4434   "Insert separator of candidates into the helm buffer."
4435   (insert (propertize helm-candidate-separator 'face 'helm-separator))
4436   (put-text-property (point-at-bol)
4437                      (point-at-eol) 'helm-candidate-separator t)
4438   (insert "\n"))
4439
4440
4441 ;;; Async process
4442 ;;
4443 (defun helm-output-filter (process output-string)
4444   "The `process-filter' function for helm async sources."
4445   (with-helm-quittable
4446     (helm-output-filter-1 (assoc process helm-async-processes) output-string)))
4447
4448 (defun helm-output-filter-1 (process-assoc output-string)
4449   (helm-log "output-string = %S" output-string)
4450   (with-current-buffer helm-buffer
4451     (let ((source (cdr process-assoc)))
4452       (save-excursion
4453         (helm-aif (assoc-default 'insertion-marker source)
4454             (goto-char it)
4455           (goto-char (point-max))
4456           (helm-insert-header-from-source source)
4457           (setcdr process-assoc
4458                   (append source `((insertion-marker . ,(point-marker))))))
4459         (helm-output-filter--process-source
4460          (car process-assoc) output-string source
4461          (helm-candidate-number-limit source))))
4462     (helm-output-filter--post-process)))
4463
4464 (defun helm-output-filter--process-source (process output-string source limit)
4465   (cl-dolist (candidate (helm-transform-candidates
4466                          (helm-output-filter--collect-candidates
4467                           (split-string output-string "\n")
4468                           (assq 'incomplete-line source))
4469                          source t))
4470     (setq candidate
4471           (helm--maybe-process-filter-one-by-one-candidate candidate source))
4472     (if (assq 'multiline source)
4473         (let ((start (point)))
4474           (helm-insert-candidate-separator)
4475           (helm-insert-match candidate 'insert-before-markers
4476                              (1+ (cdr (assq 'item-count source)))
4477                              source)
4478           (put-text-property start (point) 'helm-multiline t))
4479         (helm-insert-match candidate 'insert-before-markers
4480                            (1+ (cdr (assq 'item-count source)))
4481                            source))
4482     (cl-incf (cdr (assq 'item-count source)))
4483     (when (>= (assoc-default 'item-count source) limit)
4484       (helm-kill-async-process process)
4485       (helm-log-run-hook 'helm-async-outer-limit-hook)
4486       (cl-return))))
4487
4488 (defun helm-output-filter--collect-candidates (lines incomplete-line-info)
4489   "Collect LINES maybe completing the truncated first and last lines."
4490   ;; The output of process may come in chunks of any size, so the last
4491   ;; line of LINES could be truncated, this truncated line is stored
4492   ;; in INCOMPLETE-LINE-INFO to be concatenated with the first
4493   ;; incomplete line of the next arriving chunk. INCOMPLETE-LINE-INFO
4494   ;; is an attribute of source; it is created with an empty string
4495   ;; when the source is computed => (incomplete-line . "")
4496   (helm-log "incomplete-line-info = %S" (cdr incomplete-line-info))
4497   (butlast
4498    (cl-loop for line in lines
4499             ;; On start `incomplete-line-info' value is empty string.
4500             for newline = (helm-aif (cdr incomplete-line-info)
4501                               (prog1
4502                                   (concat it line)
4503                                 (setcdr incomplete-line-info nil))
4504                             line)
4505             collect newline
4506             ;; Store last incomplete line (last chunk truncated) until
4507             ;; new output arrives. Previously storing 'line' in
4508             ;; incomplete-line-info assumed output was truncated in
4509             ;; only two chunks. But output could be large and
4510             ;; truncated in more than two chunks. Therefore store
4511             ;; 'newline' to contain the previous chunks (Issue #1187).
4512             finally do (setcdr incomplete-line-info newline))))
4513
4514 (defun helm-output-filter--post-process ()
4515   (helm-aif (get-buffer-window helm-buffer 'visible)
4516       (with-selected-window it
4517         (helm-skip-noncandidate-line 'next)
4518         (helm-mark-current-line nil 'nomouse)
4519         ;; FIXME Don't hardcode follow delay.
4520         (helm-follow-execute-persistent-action-maybe 0.5)
4521         (helm-display-mode-line (helm-get-current-source))
4522         (helm-log-run-hook 'helm-after-update-hook)
4523         (helm--reset-update-flag))))
4524
4525 (defun helm-process-deferred-sentinel-hook (process event file)
4526   "Defer remote processes in sentinels.
4527 Meant to be called at the beginning of a sentinel process
4528 function."
4529   (when (and (not (zerop helm-tramp-connection-min-time-diff))
4530              (string= event "finished\n")
4531              (or (file-remote-p file)
4532                  ;; `helm-suspend-update-flag'
4533                  ;; is non-`nil' here only during a
4534                  ;; running process, this will never be called
4535                  ;; when user set it explicitly with `C-!'.
4536                  helm-suspend-update-flag))
4537     (setq helm-suspend-update-flag t)
4538     ;; Kill the process but don't delete entry in
4539     ;; `helm-async-processes'.
4540     (helm-kill-async-process process)
4541     ;; When tramp opens the same connection twice in less than 5
4542     ;; seconds, it throws 'suppress, which calls the real-handler on
4543     ;; the main "Emacs". To avoid this [1] helm waits for 5 seconds
4544     ;; before updates yet allows user input during this delay. [1] In
4545     ;; recent Emacs versions, this has been fixed so tramp returns nil
4546     ;; in such conditions. Note: `tramp-connection-min-time-diff' cannot
4547     ;; have values less than 5 seconds otherwise the process dies.
4548     (run-at-time helm-tramp-connection-min-time-diff
4549                  nil (lambda ()
4550                        (when helm-alive-p ; Don't run timer fn after quit.
4551                          (setq helm-suspend-update-flag nil)
4552                          (helm-check-minibuffer-input))))))
4553
4554 (defun helm-kill-async-processes ()
4555   "Kill all asynchronous processes registered in `helm-async-processes'."
4556   (while helm-async-processes
4557     (helm-kill-async-process (caar helm-async-processes))
4558     (setq helm-async-processes (cdr helm-async-processes))))
4559
4560 (defun helm-kill-async-process (process)
4561   "Stop output from `helm-output-filter' and kill associated PROCESS."
4562   (set-process-filter process nil)
4563   (delete-process process))
4564
4565
4566 ;;; Actions
4567 ;;
4568 (defun helm-execute-selection-action ()
4569   "Execute current action."
4570   (helm-log-run-hook 'helm-before-action-hook)
4571   ;; Position can be change when `helm-current-buffer'
4572   ;; is split, so jump to this position before executing action.
4573   (helm-current-position 'restore)
4574   (unwind-protect
4575        (prog1 (helm-execute-selection-action-1)
4576          (helm-log-run-hook 'helm-after-action-hook))
4577     (setq helm--executing-helm-action nil)))
4578
4579 (defun helm-execute-selection-action-1 (&optional
4580                                         selection action
4581                                         preserve-saved-action)
4582   "Execute ACTION on current SELECTION.
4583 If PRESERVE-SAVED-ACTION is non-`nil', then save the action."
4584   (helm-log "executing action")
4585   (setq action (helm-get-default-action
4586                 (or action
4587                     helm-saved-action
4588                     (if (get-buffer helm-action-buffer)
4589                         (helm-get-selection helm-action-buffer)
4590                       (helm-get-actions-from-current-source)))))
4591   (helm-aif (and (not helm-in-persistent-action)
4592                  (get-buffer helm-action-buffer))
4593       (kill-buffer it))
4594   (let ((source (or helm-saved-current-source
4595                     (helm-get-current-source)))
4596         non-essential)
4597     (setq selection (helm-coerce-selection
4598                      (or selection
4599                          helm-saved-selection
4600                          (helm-get-selection nil nil source)
4601                          (and (assq 'accept-empty source) ""))
4602                      source))
4603     (unless preserve-saved-action (setq helm-saved-action nil))
4604     (when (and selection action) (funcall action selection))))
4605
4606 (defun helm-coerce-selection (selection source)
4607   "Apply coerce attribute function to SELECTION in SOURCE.
4608 Coerce source with coerce function."
4609   (helm-aif (assoc-default 'coerce source)
4610       (helm-apply-functions-from-source source it selection)
4611     selection))
4612
4613 (defun helm-get-default-action (action)
4614   "Get the first ACTION value of action list in source."
4615   (if (and (listp action) (not (functionp action)))
4616       (cdar action)
4617     action))
4618
4619 (defun helm--show-action-window-other-window-p ()
4620   (and helm-show-action-window-other-window
4621        (or helm-always-two-windows
4622            helm--buffer-in-new-frame-p)
4623        (eq helm-split-window-state 'vertical)))
4624
4625 (defun helm-select-action ()
4626   "Select an action for the currently selected candidate.
4627 If action buffer is selected, back to the helm buffer."
4628   (interactive)
4629   (with-helm-alive-p
4630     (let ((src (helm-get-current-source)))
4631       (helm-log-run-hook 'helm-select-action-hook)
4632       (setq helm-saved-selection (helm-get-selection nil nil src))
4633       (with-selected-frame (with-helm-window (selected-frame))
4634         (prog1
4635             (helm-acond ((get-buffer-window helm-action-buffer 'visible)
4636                          (set-window-buffer it helm-buffer)
4637                          (helm--set-action-prompt 'restore)
4638                          (when (helm--show-action-window-other-window-p)
4639                            (delete-window it))
4640                          (kill-buffer helm-action-buffer)
4641                          (setq helm-saved-selection nil)
4642                          (helm-set-pattern helm-input 'noupdate))
4643                         (helm-saved-selection
4644                          (setq helm-saved-current-source src)
4645                          (let ((actions (helm-get-actions-from-current-source src))
4646                                helm-onewindow-p)
4647                            (if (functionp actions)
4648                                (message "Sole action: %s"
4649                                         (if (or (consp actions)
4650                                                 (byte-code-function-p actions))
4651                                             "Anonymous" actions))
4652                                (helm-show-action-buffer actions)
4653                                ;; Be sure the minibuffer is entirely deleted (#907).
4654                                (helm--delete-minibuffer-contents-from "")
4655                                (helm--set-action-prompt)
4656                                (helm-check-minibuffer-input))))
4657                         (t (message "No Actions available")))
4658           (helm-display-mode-line (helm-get-current-source))
4659           (run-hooks 'helm-window-configuration-hook))))))
4660 (put 'helm-select-action 'helm-only t)
4661
4662 (defun helm--set-action-prompt (&optional restore)
4663   (with-selected-window (minibuffer-window)
4664     (let ((inhibit-read-only t)
4665           (props '(face minibuffer-prompt
4666                    field t
4667                    read-only t
4668                    rear-nonsticky t
4669                    front-sticky t))
4670           (prt (if restore helm--prompt helm--action-prompt)))
4671       (erase-buffer)
4672       (insert (apply #'propertize prt props)))))
4673
4674 (defun helm-show-action-buffer (actions)
4675   (with-current-buffer (get-buffer-create helm-action-buffer)
4676     (erase-buffer)
4677     (buffer-disable-undo)
4678     (setq cursor-type nil)
4679     (set-window-buffer (if (helm--show-action-window-other-window-p)
4680                            (split-window (get-buffer-window helm-buffer)
4681                                          nil helm-show-action-window-other-window)
4682                            (get-buffer-window helm-buffer))
4683                        helm-action-buffer)
4684     (set (make-local-variable 'helm-sources)
4685          (list
4686           (helm-build-sync-source "Actions"
4687             :volatile t
4688             :nomark t
4689             :persistent-action #'ignore
4690             :persistent-help "DoNothing"
4691             :keymap 'helm-map
4692             :candidates actions
4693             :mode-line '("Action(s)" "\\<helm-map>\\[helm-select-action]:BackToCands RET/f1/f2/fn:NthAct")
4694             :candidate-transformer
4695              (lambda (candidates)
4696                (cl-loop for (i . j) in candidates
4697                         for count from 1
4698                         collect
4699                         (cons (concat (cond ((> count 12)
4700                                              "      ")
4701                                             ((< count 10)
4702                                              (format "[f%s]  " count))
4703                                             (t (format "[f%s] " count)))
4704                                       (propertize i 'face 'helm-action))
4705                               j)))
4706             :candidate-number-limit nil)))
4707     (set (make-local-variable 'helm-source-filter) nil)
4708     (set (make-local-variable 'helm-selection-overlay) nil)
4709     (helm-initialize-overlays helm-action-buffer)))
4710
4711
4712 ;; Selection of candidates
4713
4714 (defun helm-display-source-at-screen-top-maybe (unit)
4715   "Display source at the top of screen when UNIT value is 'source.
4716 Returns nil for any other value of UNIT."
4717   (when (and helm-display-source-at-screen-top (eq unit 'source))
4718     (set-window-start (selected-window)
4719                       (save-excursion (forward-line -1) (point)))))
4720
4721 (defun helm-skip-noncandidate-line (direction)
4722   "Skip source header or candidates separator when going in DIRECTION.
4723 DIRECTION is either 'next or 'previous.
4724 Same as `helm-skip-header-and-separator-line' but ensure
4725 point is moved to the right place when at bob or eob."
4726   (helm-skip-header-and-separator-line direction)
4727   (and (bobp) (forward-line 1))     ; Skip first header.
4728   (and (eobp) (forward-line -1)))   ; Avoid last empty line.
4729
4730 (defun helm-skip-header-and-separator-line (direction)
4731   "Skip source header or candidate separator when going to next/previous line.
4732 DIRECTION is either 'next or 'previous."
4733   (let ((fn (cl-ecase direction
4734               (next 'eobp)
4735               (previous 'bobp))))
4736     (while (and (not (funcall fn))
4737                 (or (helm-pos-header-line-p)
4738                     (helm-pos-candidate-separator-p)))
4739       (forward-line (if (and (eq direction 'previous)
4740                              (not (eq (point-at-bol) (point-min))))
4741                         -1 1)))))
4742
4743 (defun helm-display-mode-line (source &optional force)
4744   "Set up mode line and header line for `helm-buffer'.
4745
4746 SOURCE is a Helm source object.
4747
4748 Optional argument FORCE forces redisplay of the Helm buffer's
4749 mode and header lines."
4750   (set (make-local-variable 'helm-mode-line-string)
4751        (helm-interpret-value (or (and (listp source) ; Check if source is empty.
4752                                       (assoc-default 'mode-line source))
4753                                  (default-value 'helm-mode-line-string))
4754                              source))
4755   (let ((follow (and (or (helm-follow-mode-p source)
4756                          (and helm-follow-mode-persistent
4757                               (member (assoc-default 'name source)
4758                                       helm-source-names-using-follow)))
4759                      " (HF)"))
4760         (marked (and helm-marked-candidates
4761                      (cl-loop with cur-name = (assoc-default 'name source)
4762                               for c in helm-marked-candidates
4763                               for name = (assoc-default 'name (car c))
4764                               when (string= name cur-name)
4765                               collect c))))
4766     ;; Setup mode-line.
4767     (if helm-mode-line-string
4768         (setq mode-line-format
4769               `(:propertize
4770                 (" " mode-line-buffer-identification " "
4771                      (:eval (format "L%-3d" (helm-candidate-number-at-point)))
4772                      ,follow
4773                      " "
4774                      (:eval ,(and marked
4775                                   (propertize
4776                                    (format "M%d" (length marked))
4777                                    'face 'helm-visible-mark)))
4778                      (:eval (when ,helm--mode-line-display-prefarg
4779                               (let ((arg (prefix-numeric-value
4780                                           (or prefix-arg current-prefix-arg))))
4781                                 (unless (= arg 1)
4782                                   (propertize (format " [prefarg:%s]" arg)
4783                                               'face 'helm-prefarg)))))
4784                      " "
4785                      (:eval (with-helm-buffer
4786                               (helm-show-candidate-number
4787                                (car-safe helm-mode-line-string))))
4788                      " " helm--mode-line-string-real " "
4789                      (:eval (make-string (window-width) ? )))
4790                 keymap (keymap (mode-line keymap
4791                                           (mouse-1 . ignore)
4792                                           (down-mouse-1 . ignore)
4793                                           (drag-mouse-1 . ignore)
4794                                           (mouse-2 . ignore)
4795                                           (down-mouse-2 . ignore)
4796                                           (drag-mouse-2 . ignore)
4797                                           (mouse-3 . ignore)
4798                                           (down-mouse-3 . ignore)
4799                                           (drag-mouse-3 . ignore))))
4800               helm--mode-line-string-real
4801               (substitute-command-keys (if (listp helm-mode-line-string)
4802                                            (cadr helm-mode-line-string)
4803                                            helm-mode-line-string)))
4804         (setq mode-line-format (default-value 'mode-line-format)))
4805     ;; Setup header-line.
4806     (cond (helm-echo-input-in-header-line
4807            (setq force t)
4808            (helm--set-header-line))
4809           (helm-display-header-line
4810            (let ((hlstr (helm-interpret-value
4811                          (and (listp source)
4812                               (assoc-default 'header-line source))
4813                          source))
4814                  (endstr (make-string (window-width) ? )))
4815              (setq header-line-format
4816                    (propertize (concat " " hlstr endstr)
4817                                'face 'helm-header))))))
4818   (when force (force-mode-line-update)))
4819
4820 (defun helm--set-header-line (&optional update)
4821   (with-selected-window (minibuffer-window)
4822     (when helm-display-header-line
4823       ;; Prevent cursor movement over the overlay displaying
4824       ;; persistent-help in minibuffer (issue #2108).
4825       (setq-local disable-point-adjustment t))
4826     (let* ((beg  (save-excursion (vertical-motion 0 (helm-window)) (point)))
4827            (end  (save-excursion (end-of-visual-line) (point)))
4828            ;; The visual line where the cursor is.
4829            (cont (buffer-substring beg end))
4830            (pref (propertize
4831                   " "
4832                   'display (if (string-match-p (regexp-opt `(,helm--prompt
4833                                                              ,helm--action-prompt))
4834                                                cont)
4835                                `(space :width ,helm-header-line-space-before-prompt)
4836                                (propertize
4837                                 "->"
4838                                 'face 'helm-header-line-left-margin))))
4839            (pos  (- (point) beg)))
4840       ;; Increment pos each time we find a "%" up to current-pos (#1648).
4841       (cl-loop for c across (buffer-substring-no-properties beg (point))
4842             when (eql c ?%) do (cl-incf pos))
4843       ;; Increment pos when cursor is on a "%" to make it visible in header-line
4844       ;; i.e "%%|" and not "%|%" (#1649).
4845       (when (eql (char-after) ?%) (setq pos (1+ pos)))
4846       (setq cont (replace-regexp-in-string "%" "%%" cont))
4847       (with-helm-buffer
4848         (setq header-line-format (concat pref cont " "))
4849         (funcall helm-default-prompt-display-function pos)
4850         (when update (force-mode-line-update))))))
4851
4852 (defun helm-set-default-prompt-display (pos)
4853   (put-text-property
4854    ;; Increment pos to handle the space before prompt (i.e `pref').
4855    (+ 1 pos) (+ 2 pos)
4856    'face
4857    ;; Don't just use cursor face, this can hide the current character.
4858    (list :inverse-video t
4859          :foreground (face-background 'cursor)
4860          :background (face-background 'default))
4861    header-line-format))
4862
4863 (defun helm-exchange-minibuffer-and-header-line ()
4864   "Display minibuffer in header-line and vice versa for current helm session.
4865
4866 This is a toggle command."
4867   (interactive)
4868   (with-helm-window
4869     (add-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe)
4870     (setq-local helm-echo-input-in-header-line
4871                 (not helm-echo-input-in-header-line))
4872     (with-selected-window (minibuffer-window)
4873       (if (with-helm-buffer helm-echo-input-in-header-line)
4874           (helm-hide-minibuffer-maybe)
4875         (remove-overlays)
4876         (setq cursor-type t)))
4877     (helm-display-mode-line (helm-get-current-source) t)))
4878 (put 'helm-exchange-minibuffer-and-header-line 'helm-only t)
4879
4880 (defun helm--update-header-line ()
4881   ;; This should be used in `post-command-hook',
4882   ;; nowhere else.
4883   (when (with-helm-buffer helm-echo-input-in-header-line)
4884     (helm--set-header-line t)))
4885
4886 (defun helm-hide-minibuffer-maybe ()
4887   "Hide minibuffer contents in a Helm session.
4888 This function should normally go to `helm-minibuffer-set-up-hook'.
4889 It has no effect if `helm-echo-input-in-header-line' is nil."
4890   (when (with-helm-buffer helm-echo-input-in-header-line)
4891     (let ((ov (make-overlay (point-min) (point-max) nil nil t)))
4892       (overlay-put ov 'window (selected-window))
4893       (helm-aif (and helm-display-header-line
4894                      (helm-attr 'persistent-help))
4895           (progn
4896             (overlay-put ov 'display
4897                          (truncate-string-to-width
4898                           (substitute-command-keys
4899                            (concat "\\<helm-map>\\[helm-execute-persistent-action]: "
4900                                    (format "%s (keeping session)" it)))
4901                           (- (window-width) 1)))
4902             (overlay-put ov 'face 'helm-header))
4903         (overlay-put ov 'face (let ((bg-color (face-background 'default nil)))
4904                                 `(:background ,bg-color :foreground ,bg-color))))
4905
4906       (setq cursor-type nil))))
4907
4908 (defun helm-show-candidate-number (&optional name)
4909   "Used to display candidate number in mode-line.
4910 You can specify NAME of candidates e.g \"Buffers\" otherwise
4911 it is \"Candidate\(s\)\" by default."
4912   (when helm-alive-p
4913     (unless (helm-empty-source-p)
4914       ;; Build a fixed width string when candidate-number < 1000
4915       (let* ((cand-name (or name "Candidate(s)"))
4916              (width (length (format "[999 %s]" cand-name))))
4917         (propertize
4918          (format (concat "%-" (number-to-string width) "s")
4919                  (format "[%s %s]"
4920                          (helm-get-candidate-number 'in-current-source)
4921                          cand-name))
4922          'face (if helm-suspend-update-flag
4923                    'helm-candidate-number-suspended
4924                    'helm-candidate-number))))))
4925
4926 (cl-defun helm-move-selection-common (&key where direction (follow t))
4927   "Move the selection marker to a new position.
4928 Position is determined by WHERE and DIRECTION.
4929 Key arg WHERE can be one of:
4930  - line
4931  - page
4932  - edge
4933  - source
4934 Key arg DIRECTION can be one of:
4935  - previous
4936  - next
4937  - A source or a source name when used with :WHERE 'source."
4938   (let ((move-func (cl-case where
4939                      (line (cl-ecase direction
4940                              (previous 'helm-move--previous-line-fn)
4941                              (next 'helm-move--next-line-fn)))
4942                      (page (cl-ecase direction
4943                              (previous 'helm-move--previous-page-fn)
4944                              (next 'helm-move--next-page-fn)))
4945                      (edge (cl-ecase direction
4946                              (previous 'helm-move--beginning-of-buffer-fn)
4947                              (next 'helm-move--end-of-buffer-fn)))
4948                      (source (cl-case direction
4949                                (previous 'helm-move--previous-source-fn)
4950                                (next 'helm-move--next-source-fn)
4951                                (t (lambda () ; A source is passed as DIRECTION arg.
4952                                     (helm-move--goto-source-fn direction))))))))
4953     (unless (or (helm-empty-buffer-p (helm-buffer-get))
4954                 (not (helm-window)))
4955       (with-helm-window
4956         (when helm-allow-mouse
4957           (helm--mouse-reset-selection-help-echo))
4958         (helm-log-run-hook 'helm-move-selection-before-hook)
4959         (funcall move-func)
4960         (and (memq direction '(next previous))
4961              (helm-skip-noncandidate-line direction))
4962         (when (helm-pos-multiline-p)
4963           (helm-move--beginning-of-multiline-candidate))
4964         (helm-display-source-at-screen-top-maybe where)
4965         (helm-mark-current-line)
4966         (when follow
4967           (helm-follow-execute-persistent-action-maybe))
4968         (helm-display-mode-line (helm-get-current-source))
4969         (helm-log-run-hook 'helm-move-selection-after-hook)))))
4970
4971 (defun helm-move--beginning-of-multiline-candidate ()
4972   (let ((header-pos (helm-get-previous-header-pos))
4973         (separator-pos (helm-get-previous-candidate-separator-pos)))
4974     (when header-pos
4975       (goto-char (if (or (null separator-pos)
4976                          (< separator-pos header-pos))
4977                      header-pos
4978                      separator-pos))
4979       (forward-line 1))))
4980
4981 (defun helm-move--previous-multi-line-fn ()
4982   (forward-line -1)
4983   (unless (helm-pos-header-line-p)
4984     (helm-skip-header-and-separator-line 'previous)
4985     (helm-move--beginning-of-multiline-candidate)))
4986
4987 (defun helm-move--previous-line-fn ()
4988   (if (not (helm-pos-multiline-p))
4989       (forward-line -1)
4990     (helm-move--previous-multi-line-fn))
4991   (when (and helm-move-to-line-cycle-in-source
4992              (helm-pos-header-line-p))
4993     (forward-line 1)
4994     (helm-move--end-of-source)
4995     ;; We are at end of helm-buffer
4996     ;; check if last candidate is a multiline candidate
4997     ;; and jump to it
4998     (when (and (eobp)
4999                (save-excursion (forward-line -1) (helm-pos-multiline-p)))
5000       (helm-move--previous-multi-line-fn))))
5001
5002 (defun helm-move--next-multi-line-fn ()
5003   (let ((header-pos (helm-get-next-header-pos))
5004         (separator-pos (helm-get-next-candidate-separator-pos)))
5005     (cond ((and separator-pos
5006                 (or (null header-pos) (< separator-pos header-pos)))
5007            (goto-char separator-pos))
5008           (header-pos
5009            (goto-char header-pos)))))
5010
5011 (defun helm-move--next-line-fn ()
5012   (if (not (helm-pos-multiline-p))
5013       (forward-line 1)
5014     (helm-move--next-multi-line-fn))
5015   (when (and helm-move-to-line-cycle-in-source
5016              (or (save-excursion (and (helm-pos-multiline-p)
5017                                       (goto-char (overlay-end
5018                                                   helm-selection-overlay))
5019                                       (helm-end-of-source-p t)))
5020                  (helm-end-of-source-p t)))
5021     (helm-move--beginning-of-source)))
5022
5023 (defun helm-move--previous-page-fn ()
5024   (condition-case nil
5025       (scroll-down)
5026     (beginning-of-buffer (goto-char (point-min)))))
5027
5028 (defun helm-move--next-page-fn ()
5029   (condition-case nil
5030       (scroll-up)
5031     (end-of-buffer (goto-char (point-max)))))
5032
5033 (defun helm-move--beginning-of-buffer-fn ()
5034   (goto-char (point-min)))
5035
5036 (defun helm-move--end-of-buffer-fn ()
5037   (goto-char (point-max)))
5038
5039 (defun helm-move--end-of-source ()
5040   (helm-aif (helm-get-next-header-pos)
5041       (progn (goto-char it) (forward-line -2))
5042     (goto-char (point-max))))
5043
5044 (defun helm-move--beginning-of-source ()
5045   (helm-aif (helm-get-previous-header-pos)
5046       (progn (goto-char it)
5047              (forward-line 1))
5048     (goto-char (point-min))))
5049
5050 (defun helm-move--previous-source-fn ()
5051   (forward-line -1)
5052   (if (bobp)
5053       (goto-char (point-max))
5054     (helm-skip-header-and-separator-line 'previous))
5055   (goto-char (helm-get-previous-header-pos))
5056   (forward-line 1))
5057
5058 (defun helm-move--next-source-fn ()
5059   (goto-char (or (and (not (save-excursion
5060                              (forward-line 1) (eobp)))
5061                       ;; Empty source at eob are just
5062                       ;; not displayed unless they are dummy.
5063                       ;; Issue #1117.
5064                       (helm-get-next-header-pos))
5065                  (point-min))))
5066
5067 (defun helm-move--goto-source-fn (source-or-name)
5068   (goto-char (point-min))
5069   (let ((name (if (stringp source-or-name)
5070                   source-or-name
5071                   (assoc-default 'name source-or-name))))
5072     (if (or (null name) (string= name ""))
5073         (forward-line 1)
5074         (condition-case err
5075             (while (not (string= name (helm-current-line-contents)))
5076               (goto-char (helm-get-next-header-pos)))
5077           (error (helm-log "%S" err))))))
5078
5079 (defun helm-candidate-number-at-point ()
5080   (if helm-alive-p
5081       (with-helm-buffer
5082         (or (get-text-property (point) 'helm-cand-num) 1))
5083       (or (get-text-property (point) 'helm-cand-num) 1)))
5084
5085 (defun helm--next-or-previous-line (direction &optional arg)
5086   ;; Be sure to not use this in non--interactives calls.
5087   (let ((helm-move-to-line-cycle-in-source
5088          (and helm-move-to-line-cycle-in-source arg)))
5089     (if (and arg (> arg 1))
5090         (cl-loop with pos = (helm-candidate-number-at-point)
5091                  with cand-num = (helm-get-candidate-number t)
5092                  with iter = (min arg (if (eq direction 'next)
5093                                           (- cand-num pos)
5094                                           (min arg (1- pos))))
5095                  for count from 1
5096                  while (<= count iter)
5097                  do
5098                  (helm-move-selection-common :where 'line :direction direction))
5099         (helm-move-selection-common :where 'line :direction direction))))
5100
5101 (defun helm-previous-line (&optional arg)
5102   "Move selection to the ARG previous line(s).
5103 Same behavior as `helm-next-line' when called with a numeric prefix arg."
5104   (interactive "p")
5105   (with-helm-alive-p
5106     (helm--next-or-previous-line 'previous arg)))
5107 (put 'helm-previous-line 'helm-only t)
5108
5109 (defun helm-next-line (&optional arg)
5110   "Move selection to the next ARG line(s).
5111 When numeric prefix arg is > than the number of candidates, then
5112 move to the last candidate of current source (i.e. don't move to
5113 next source)."
5114   (interactive "p")
5115   (with-helm-alive-p
5116     (helm--next-or-previous-line 'next arg)))
5117 (put 'helm-next-line 'helm-only t)
5118
5119 (defun helm-previous-page ()
5120   "Move selection back with a pageful."
5121   (interactive)
5122   (with-helm-alive-p
5123     (helm-move-selection-common :where 'page :direction 'previous)))
5124 (put 'helm-previous-page 'helm-only t)
5125
5126 (defun helm-next-page ()
5127   "Move selection forward with a pageful."
5128   (interactive)
5129   (with-helm-alive-p
5130     (helm-move-selection-common :where 'page :direction 'next)))
5131 (put 'helm-next-page 'helm-only t)
5132
5133 (defun helm-beginning-of-buffer ()
5134   "Move selection at the top."
5135   (interactive)
5136   (with-helm-alive-p
5137     (helm-move-selection-common :where 'edge :direction 'previous)))
5138 (put 'helm-beginning-of-buffer 'helm-only t)
5139
5140 (defun helm-end-of-buffer ()
5141   "Move selection at the bottom."
5142   (interactive)
5143   (with-helm-alive-p
5144     (helm-move-selection-common :where 'edge :direction 'next)))
5145 (put 'helm-end-of-buffer 'helm-only t)
5146
5147 (defun helm-previous-source ()
5148   "Move selection to the previous source."
5149   (interactive)
5150   (with-helm-alive-p
5151     (helm-move-selection-common :where 'source :direction 'previous)))
5152 (put 'helm-previous-source 'helm-only t)
5153
5154 (defun helm-next-source ()
5155   "Move selection to the next source."
5156   (interactive)
5157   (with-helm-alive-p
5158     (helm-move-selection-common :where 'source :direction 'next)))
5159 (put 'helm-next-source 'helm-only t)
5160
5161 (defun helm-goto-source (&optional source-or-name)
5162   "Move the selection to the source named SOURCE-OR-NAME.
5163
5164 If SOURCE-OR-NAME is empty string or nil go to the first candidate of
5165 first source."
5166   (helm-move-selection-common :where 'source :direction source-or-name))
5167
5168 (defun helm--follow-action (arg)
5169   (let ((helm--temp-follow-flag t) ; Needed in HFF.
5170         (in-follow-mode (helm-follow-mode-p)))
5171     ;; When follow-mode is already enabled, just go to next or
5172     ;; previous line.
5173     (when (or (eq last-command 'helm-follow-action-forward)
5174               (eq last-command 'helm-follow-action-backward)
5175               (eq last-command 'helm-execute-persistent-action)
5176               in-follow-mode)
5177       (if (> arg 0)
5178           (helm-move-selection-common :where 'line
5179                                       :direction 'next
5180                                       :follow nil)
5181           (helm-move-selection-common :where 'line
5182                                       :direction 'previous
5183                                       :follow nil)))
5184     (unless in-follow-mode
5185       (helm-execute-persistent-action))))
5186
5187 (defun helm-follow-action-forward ()
5188   "Go to next line and execute persistent action."
5189   (interactive)
5190   (with-helm-alive-p (helm--follow-action 1)))
5191 (put 'helm-follow-action-forward 'helm-only t)
5192
5193 (defun helm-follow-action-backward ()
5194   "Go to previous line and execute persistent action."
5195   (interactive)
5196   (with-helm-alive-p (helm--follow-action -1)))
5197 (put 'helm-follow-action-backward 'helm-only t)
5198
5199 (defun helm-mark-current-line (&optional resumep nomouse)
5200   "Move `helm-selection-overlay' to current line.
5201 When RESUMEP is non nil move overlay to `helm-selection-point'.
5202 When NOMOUSE is specified do not set mouse bindings.
5203
5204 Note that selection is unrelated to visible marks used for marking
5205 candidates."
5206   (with-helm-buffer
5207     (when resumep
5208       (goto-char helm-selection-point))
5209     (move-overlay
5210      helm-selection-overlay (point-at-bol)
5211      (if (helm-pos-multiline-p)
5212          (let ((header-pos (helm-get-next-header-pos))
5213                (separator-pos (helm-get-next-candidate-separator-pos)))
5214            (or (and (null header-pos) separator-pos)
5215                (and header-pos separator-pos
5216                     (< separator-pos header-pos)
5217                     separator-pos)
5218                header-pos
5219                (point-max)))
5220        (1+ (point-at-eol))))
5221     (setq helm-selection-point (overlay-start helm-selection-overlay))
5222     (when (and helm-allow-mouse (null nomouse))
5223       (helm--bind-mouse-for-selection helm-selection-point))))
5224
5225 (defun helm-confirm-and-exit-minibuffer ()
5226   "Maybe ask for confirmation when exiting helm.
5227 It is similar to `minibuffer-complete-and-exit' adapted to helm.
5228 If `minibuffer-completion-confirm' value is 'confirm,
5229 send minibuffer confirm message and exit on next hit.
5230 If `minibuffer-completion-confirm' value is t,
5231 don't exit and send message 'no match'."
5232   (interactive)
5233   (with-helm-alive-p
5234     (if (and (helm--updating-p)
5235              (null helm--reading-passwd-or-string))
5236         (progn (message "[Display not ready]")
5237                (sit-for 0.5) (message nil))
5238       (let* ((src (helm-get-current-source))
5239              (empty-buffer-p (with-current-buffer helm-buffer
5240                                (eq (point-min) (point-max))))
5241              (sel (helm-get-selection nil nil src))
5242              (unknown (and (not empty-buffer-p)
5243                            (string= (get-text-property
5244                                      0 'display
5245                                      (helm-get-selection nil 'withprop src))
5246                                     "[?]"))))
5247         (cond ((and (or empty-buffer-p unknown)
5248                     (eq minibuffer-completion-confirm 'confirm))
5249                (setq helm-minibuffer-confirm-state
5250                      'confirm)
5251                (setq minibuffer-completion-confirm nil)
5252                (minibuffer-message " [confirm]"))
5253               ((and (or empty-buffer-p
5254                         (unless (if minibuffer-completing-file-name
5255                                     (and minibuffer-completion-predicate
5256                                          (funcall minibuffer-completion-predicate sel))
5257                                   (and (stringp sel)
5258                                        ;; SEL may be a cons cell when helm-comp-read
5259                                        ;; is called directly with a collection composed
5260                                        ;; of (display . real) and real is a cons cell.
5261                                        (try-completion sel minibuffer-completion-table
5262                                                        minibuffer-completion-predicate)))
5263                           unknown))
5264                     (eq minibuffer-completion-confirm t))
5265                (minibuffer-message " [No match]"))
5266               (t
5267                (setq helm-minibuffer-confirm-state nil)
5268                (helm-exit-minibuffer)))))))
5269 (put 'helm-confirm-and-exit-minibuffer 'helm-only t)
5270
5271 (add-hook 'helm-after-update-hook 'helm-confirm-and-exit-hook)
5272
5273 (defun helm-confirm-and-exit-hook ()
5274   "Restore `minibuffer-completion-confirm' when helm update."
5275   (unless (or (eq minibuffer-completion-confirm t)
5276               (not helm-minibuffer-confirm-state))
5277     (setq minibuffer-completion-confirm
5278           helm-minibuffer-confirm-state)))
5279
5280 (defun helm-read-string (prompt &optional initial-input history
5281                                   default-value inherit-input-method)
5282   "Same as `read-string' but for reading string from a helm session."
5283   (let ((helm--reading-passwd-or-string t))
5284     (read-string
5285      prompt initial-input history default-value inherit-input-method)))
5286
5287 (defun helm--updating-p ()
5288   ;; helm timer is between two cycles.
5289   ;; IOW `helm-check-minibuffer-input' haven't yet compared input
5290   ;; and `helm-pattern'.
5291   (or (not (equal (minibuffer-contents) helm-pattern))
5292       ;; `helm-check-minibuffer-input' have launched `helm-update'.
5293       helm--in-update))
5294
5295 (defun helm-maybe-exit-minibuffer ()
5296   (interactive)
5297   (with-helm-alive-p
5298     (if (and (helm--updating-p)
5299              (null helm--reading-passwd-or-string))
5300         (progn
5301           (message "[Display not ready]")
5302           (sit-for 0.5) (message nil)
5303           (helm-update))
5304         (helm-exit-minibuffer))))
5305 (put 'helm-maybe-exit-minibuffer 'helm-only t)
5306
5307 (defun helm-exit-minibuffer ()
5308   "Select the current candidate by exiting the minibuffer."
5309   (unless helm-current-prefix-arg
5310     (setq helm-current-prefix-arg current-prefix-arg))
5311   (setq helm-exit-status 0)
5312   (helm-log-run-hook 'helm-exit-minibuffer-hook)
5313   (exit-minibuffer))
5314
5315 (defun helm-keyboard-quit ()
5316   "Quit minibuffer in helm.
5317 If action buffer is displayed, kill it."
5318   (interactive)
5319   (with-helm-alive-p
5320     (when (get-buffer-window helm-action-buffer 'visible)
5321       (kill-buffer helm-action-buffer))
5322     (setq helm-exit-status 1)
5323     (abort-recursive-edit)))
5324 (put 'helm-keyboard-quit 'helm-only t)
5325
5326 (defun helm-get-next-header-pos ()
5327   "Return the position of the next header from point."
5328   (next-single-property-change (point) 'helm-header))
5329
5330 (defun helm-get-previous-header-pos ()
5331   "Return the position of the previous header from point."
5332   (previous-single-property-change (point) 'helm-header))
5333
5334 (defun helm-pos-multiline-p ()
5335   "Return non-`nil' if the current position is in the multiline source region."
5336   (get-text-property (point) 'helm-multiline))
5337
5338 (defun helm-get-next-candidate-separator-pos ()
5339   "Return the position of the next candidate separator from point."
5340   (let ((hp (helm-get-next-header-pos)))
5341     (helm-aif (next-single-property-change (point) 'helm-candidate-separator)
5342         (or
5343          ;; Be sure we don't catch
5344          ;; the separator of next source.
5345          (and hp (< it hp) it)
5346          ;; The separator found is in next source
5347          ;; we are at last cand, so use the header pos.
5348          (and hp (< hp it) hp)
5349          ;; A single source, just try next separator.
5350          it))))
5351
5352 (defun helm-get-previous-candidate-separator-pos ()
5353   "Return the position of the previous candidate separator from point."
5354   (previous-single-property-change (point) 'helm-candidate-separator))
5355
5356 (defun helm-pos-header-line-p ()
5357   "Return t if the current line is a header line."
5358   (or (get-text-property (point-at-bol) 'helm-header)
5359       (get-text-property (point-at-bol) 'helm-header-separator)))
5360
5361 (defun helm-pos-candidate-separator-p ()
5362   "Return t if the current line is a candidate separator."
5363   (get-text-property (point-at-bol) 'helm-candidate-separator))
5364
5365
5366 ;;; Debugging
5367 ;;
5368 ;;
5369 (defun helm-debug-output ()
5370   "Show all helm-related variables at this time."
5371   (interactive)
5372   (with-helm-alive-p
5373     (helm-help-internal " *Helm Debug*" 'helm-debug-output-function)))
5374 (put 'helm-debug-output 'helm-only t)
5375
5376 (defun helm-debug-output-function (&optional vars)
5377   (message "Calculating all helm-related values...")
5378   (insert "If you debug some variables or forms, set `helm-debug-variables'
5379 to a list of forms.\n\n")
5380   (cl-dolist (v (or vars
5381                     helm-debug-variables
5382                     (apropos-internal "^helm-" 'boundp)))
5383     (insert "** "
5384             (pp-to-string v) "\n"
5385             (pp-to-string (with-current-buffer helm-buffer (eval v))) "\n"))
5386   (message "Calculating all helm-related values...Done"))
5387
5388 (defun helm-enable-or-switch-to-debug ()
5389   "First hit enable helm debugging, second hit switch to debug buffer."
5390   (interactive)
5391   (with-helm-alive-p
5392     (if helm-debug
5393         (helm-run-after-exit
5394          #'helm-debug-open-last-log)
5395         (setq helm-debug t)
5396         (with-helm-buffer (setq truncate-lines nil))
5397         (message "Debugging enabled"))))
5398 (put 'helm-enable-or-switch-to-debug 'helm-only t)
5399
5400
5401 ;; Misc
5402 (defun helm-kill-buffer-hook ()
5403   "Remove tick entry from `helm-tick-hash' and remove buffer from
5404 `helm-buffers' when killing a buffer."
5405   (cl-loop for key being the hash-keys in helm-tick-hash
5406         if (string-match (format "^%s/" (regexp-quote (buffer-name))) key)
5407         do (remhash key helm-tick-hash))
5408   (setq helm-buffers (remove (buffer-name) helm-buffers)))
5409 (add-hook 'kill-buffer-hook 'helm-kill-buffer-hook)
5410
5411 (defun helm-preselect (candidate-or-regexp &optional source)
5412   "Move selection to CANDIDATE-OR-REGEXP on Helm start.
5413
5414 CANDIDATE-OR-REGEXP can be a:
5415
5416 - String
5417 - Cons cell of two strings
5418 - Nullary function, which moves to a candidate
5419
5420 When CANDIDATE-OR-REGEXP is a cons cell, tries moving to first
5421 element of the cons cell, then the second, and so on. This allows
5422 selection of duplicate candidates after the first.
5423
5424 Optional argument SOURCE is a Helm source object."
5425   (with-helm-buffer
5426     (when candidate-or-regexp
5427       (if source
5428           (helm-goto-source source)
5429           (goto-char (point-min))
5430           (forward-line 1))
5431       (if (functionp candidate-or-regexp)
5432           (funcall candidate-or-regexp)
5433           (let ((start (point)) mp)
5434             (helm-awhile (if (consp candidate-or-regexp)
5435                              (and (re-search-forward (car candidate-or-regexp) nil t)
5436                                   (re-search-forward (cdr candidate-or-regexp) nil t))
5437                              (re-search-forward candidate-or-regexp nil t))
5438               ;; If search fall on an header line continue loop
5439               ;; until it match or fail (Issue #1509).
5440               (unless (helm-pos-header-line-p) (cl-return (setq mp it))))
5441             (goto-char (or mp start)))))
5442     (forward-line 0) ; Avoid scrolling right on long lines.
5443     (when (helm-pos-multiline-p)
5444       (helm-move--beginning-of-multiline-candidate))
5445     (when (helm-pos-header-line-p) (forward-line 1))
5446     (when helm-allow-mouse
5447       (helm--mouse-reset-selection-help-echo))
5448     (helm-mark-current-line)
5449     (helm-display-mode-line (or source (helm-get-current-source)))
5450     (helm-log-run-hook 'helm-after-preselection-hook)))
5451
5452 (defun helm-delete-current-selection ()
5453   "Delete the currently selected item."
5454   (with-helm-window
5455     (cond ((helm-pos-multiline-p)
5456            (helm-aif (helm-get-next-candidate-separator-pos)
5457                (delete-region (point-at-bol)
5458                               (1+ (progn (goto-char it) (point-at-eol))))
5459              ;; last candidate
5460              (goto-char (helm-get-previous-candidate-separator-pos))
5461              (delete-region (point-at-bol) (point-max)))
5462            (when (helm-end-of-source-p)
5463              (goto-char (or (helm-get-previous-candidate-separator-pos)
5464                             (point-min)))
5465              (forward-line 1)))
5466           (t
5467            (delete-region (point-at-bol) (1+ (point-at-eol)))
5468            (when (helm-end-of-source-p t)
5469              (let ((headp (save-excursion
5470                             (forward-line -1)
5471                             (not (helm-pos-header-line-p)))))
5472                (and headp (forward-line -1))))))
5473     (unless (helm-end-of-source-p t)
5474       (helm-mark-current-line))))
5475
5476 (defun helm-end-of-source-1 (n at-point)
5477   (save-excursion
5478     (if (and (helm-pos-multiline-p) (null at-point))
5479         (null (helm-get-next-candidate-separator-pos))
5480         (forward-line (if at-point 0 n))
5481         (or (eq (point-at-bol) (point-at-eol))
5482             (helm-pos-header-line-p)
5483             (if (< n 0) (bobp) (eobp))))))
5484
5485 (defun helm-end-of-source-p (&optional at-point)
5486   "Return non-`nil' if we are at eob or end of source."
5487   (helm-end-of-source-1 1 at-point))
5488
5489 (defun helm-beginning-of-source-p (&optional at-point)
5490   "Return non-`nil' if we are at bob or beginning of source."
5491   (helm-end-of-source-1 -1 at-point))
5492
5493 (defun helm--edit-current-selection-internal (func)
5494   (with-helm-window
5495     (forward-line 0)
5496     (let ((realvalue (get-text-property (point) 'helm-realvalue))
5497           (multiline (get-text-property (point) 'helm-multiline)))
5498       (funcall func)
5499       (forward-line 0)
5500       (and realvalue
5501            (put-text-property (point) (point-at-eol)
5502                               'helm-realvalue realvalue))
5503       (and multiline
5504            (put-text-property (point)
5505                               (or (helm-get-next-candidate-separator-pos)
5506                                   (point-max))
5507                               'helm-multiline multiline))
5508       (helm-mark-current-line))))
5509
5510 (defmacro helm-edit-current-selection (&rest forms)
5511   "Evaluate FORMS at current selection in the helm buffer.
5512 Used generally to modify current selection."
5513   (declare (indent 0) (debug t))
5514   `(helm--edit-current-selection-internal
5515     (lambda () ,@forms)))
5516
5517 (defun helm--delete-minibuffer-contents-from (from-str)
5518   ;; Giving an empty string value to FROM-STR delete all.
5519   (let ((input (minibuffer-contents)))
5520     (helm-reset-yank-point)
5521     (if (> (length input) 0)
5522         ;; minibuffer is not empty, delete contents from end
5523         ;; of FROM-STR and update.
5524         (helm-set-pattern from-str)
5525         ;; minibuffer is already empty, force update.
5526         (helm-force-update))))
5527
5528 (defun helm-delete-minibuffer-contents (&optional arg)
5529   "Delete minibuffer contents.
5530 When `helm-delete-minibuffer-contents-from-point' is non-`nil',
5531 delete minibuffer contents from point instead of deleting all.
5532 Giving a prefix arg reverses this behavior.
5533 When at the end of minibuffer, deletes all."
5534   (interactive "P")
5535   (let ((str (if helm-delete-minibuffer-contents-from-point
5536                  (if (or arg (eobp))
5537                      "" (helm-minibuffer-completion-contents))
5538                (if (and arg (not (eobp)))
5539                    (helm-minibuffer-completion-contents) ""))))
5540     (helm--delete-minibuffer-contents-from str)))
5541
5542
5543 ;;; helm-source-in-buffer.
5544 ;;
5545 (defun helm-candidates-in-buffer (&optional source)
5546   "The top level function used to store candidates with `helm-source-in-buffer'.
5547
5548 Candidates are stored in a buffer generated internally
5549 by `helm-candidate-buffer' function.
5550 Each candidate must be placed in one line.
5551
5552 The buffer is created and fed in the init attribute function of helm.
5553
5554 e.g:
5555
5556      (helm-build-in-buffer-source \"test\"
5557        :init (lambda ()
5558                (helm-init-candidates-in-buffer
5559                    'global '(foo foa fob bar baz))))
5560
5561 A shortcut can be used to simplify:
5562
5563      (helm-build-in-buffer-source \"test\"
5564        :data '(foo foa fob bar baz))
5565
5566 By default, `helm' makes candidates by evaluating the
5567 candidates function, then narrows them by `string-match' for each
5568 candidate.
5569
5570 But this is slow for large number of candidates. The new way is
5571 to store all candidates in a buffer and then narrow
5572 with `re-search-forward'. Search function is customizable by search
5573 attribute. The important point is that buffer processing is MUCH
5574 FASTER than string list processing and is the Emacs way.
5575
5576 The init function writes all candidates to a newly-created
5577 candidate buffer.  The candidates buffer is created or specified
5578 by `helm-candidate-buffer'.  Candidates are stored in a line.
5579
5580 The candidates function narrows all candidates, IOW creates a
5581 subset of candidates dynamically.
5582
5583 Class `helm-source-in-buffer' is implemented with three attributes:
5584
5585     (candidates . helm-candidates-in-buffer)
5586     (volatile)
5587     (match identity)
5588
5589 The volatile attribute is needed because `helm-candidates-in-buffer'
5590 creates candidates dynamically and need to be called every
5591 time `helm-pattern' changes.
5592
5593 Because `helm-candidates-in-buffer' plays the role of `match' attribute
5594 function, specifying `(match identity)' makes the source slightly faster.
5595
5596 However if source contains `match-part' attribute, match is computed only
5597 on part of candidate returned by the call of function provided by this attribute.
5598 The function should have one arg, candidate, and return only
5599 a specific part of candidate.
5600
5601 To customize `helm-candidates-in-buffer' behavior,
5602 use `search', `get-line' and `match-part' attributes."
5603   (let ((src (or source (helm-get-current-source))))
5604     (helm-candidates-in-buffer-1
5605      (helm-candidate-buffer)
5606      helm-pattern
5607      (or (assoc-default 'get-line src)
5608          #'buffer-substring-no-properties)
5609      (or (assoc-default 'search src)
5610          '(helm-candidates-in-buffer-search-default-fn))
5611      (helm-candidate-number-limit src)
5612      (helm-attr 'match-part)
5613      src)))
5614
5615 (defun helm-candidates-in-buffer-search-default-fn (pattern)
5616   "Search PATTERN with `re-search-forward' with bound and noerror args."
5617   (condition-case _err
5618       (re-search-forward pattern nil t)
5619     (invalid-regexp nil)))
5620
5621 (defun helm-candidates-in-buffer-1 (buffer pattern get-line-fn
5622                                     search-fns limit
5623                                     match-part-fn source)
5624   "Return the list of candidates inserted in BUFFER matching PATTERN."
5625   ;; buffer == nil when candidates buffer does not exist.
5626   (when buffer
5627     (with-current-buffer buffer
5628       (let ((inhibit-point-motion-hooks t)
5629             (start-point (1- (point-min))))
5630         (goto-char start-point)
5631         (if (string= pattern "")
5632             (helm-initial-candidates-from-candidate-buffer
5633              get-line-fn limit)
5634           (helm-search-from-candidate-buffer
5635            pattern get-line-fn search-fns limit
5636            start-point match-part-fn source))))))
5637
5638
5639 (defun helm-search-from-candidate-buffer (pattern get-line-fn search-fns
5640                                           limit start-point match-part-fn source)
5641   (let ((inhibit-read-only t))
5642     (helm--search-from-candidate-buffer-1
5643      (lambda ()
5644        (cl-loop with hash = (make-hash-table :test 'equal)
5645                 with allow-dups = (assq 'allow-dups source)
5646                 with case-fold-search = (helm-set-case-fold-search)
5647                 with count = 0
5648                 for iter from 1
5649                 for searcher in search-fns
5650                 do (progn
5651                      (goto-char start-point)
5652                      ;; The character at start-point is a newline,
5653                      ;; if pattern match it that's mean we are
5654                      ;; searching for newline in buffer, in this
5655                      ;; case skip this false line.
5656                      ;; See comment >>>[1] in
5657                      ;; `helm--search-from-candidate-buffer-1'.
5658                      (and (condition-case nil
5659                               (looking-at pattern)
5660                             (invalid-regexp nil))
5661                           (forward-line 1)))
5662                 nconc
5663                 (cl-loop with pos-lst
5664                          while (and (setq pos-lst (funcall searcher pattern))
5665                                     (not (eobp))
5666                                     (< count limit))
5667                          for cand = (apply get-line-fn
5668                                            (if (and pos-lst (listp pos-lst))
5669                                                pos-lst
5670                                                (list (point-at-bol) (point-at-eol))))
5671                          when (and match-part-fn
5672                                    (not (get-text-property 0 'match-part cand)))
5673                          do (setq cand
5674                                   (propertize cand 'match-part (funcall match-part-fn cand)))
5675                          for dup = (gethash cand hash)
5676                          when (and (or (and allow-dups dup (= dup iter))
5677                                        (null dup))
5678                                    (or
5679                                     ;; Always collect when cand is matched
5680                                     ;; by searcher funcs and match-part attr
5681                                     ;; is not present.
5682                                     (and (not match-part-fn)
5683                                          (not (consp pos-lst)))
5684                                     ;; If match-part attr is present, or if SEARCHER fn
5685                                     ;; returns a cons cell, collect PATTERN only if it
5686                                     ;; match the part of CAND specified by
5687                                     ;; the match-part func.
5688                                     (helm-search-match-part cand pattern)))
5689                          do (progn
5690                               (puthash cand iter hash)
5691                               (helm--maybe-process-filter-one-by-one-candidate cand source)
5692                               (cl-incf count))
5693                          and collect cand))))))
5694
5695 (defun helm-search-match-part (candidate pattern)
5696   "Match PATTERN only on match-part property value of CANDIDATE.
5697
5698 Because `helm-search-match-part' maybe called even if unspecified
5699 in source (negation or fuzzy), the part to match fallback to the whole
5700 candidate even if match-part haven't been computed by match-part-fn
5701 and stored in the match-part property."
5702   (let ((part (or (get-text-property 0 'match-part candidate)
5703                   candidate))
5704         (fuzzy-regexp (cadr (gethash 'helm-pattern helm--fuzzy-regexp-cache)))
5705         (matchfn (if helm-migemo-mode
5706                      'helm-mm-migemo-string-match 'string-match)))
5707     (if (string-match " " pattern)
5708         (cl-loop for i in (helm-mm-split-pattern pattern) always
5709                  (if (string-match "\\`!" i)
5710                      (not (funcall matchfn (substring i 1) part))
5711                      (funcall matchfn i part)))
5712         (if (string-match "\\`!" pattern)
5713             (if helm--in-fuzzy
5714                 ;; Fuzzy regexp have already been
5715                 ;; computed with substring 1.
5716                 (not (string-match fuzzy-regexp part))
5717                 (not (funcall matchfn (substring pattern 1) part)))
5718             (funcall matchfn (if helm--in-fuzzy fuzzy-regexp pattern) part)))))
5719
5720 (defun helm-initial-candidates-from-candidate-buffer (get-line-fn limit)
5721   (delq nil (cl-loop for i from 1 to limit
5722                      until (eobp)
5723                      collect (funcall get-line-fn
5724                                       (point-at-bol) (point-at-eol))
5725                      do (forward-line 1))))
5726
5727 (defun helm--search-from-candidate-buffer-1 (search-fn)
5728   ;; We are adding a newline at bob and at eol
5729   ;; and removing these newlines afterward.
5730   ;; This is a bad hack that should be removed.
5731   ;; To avoid matching the empty line at first line
5732   ;; when searching with e.g occur and "^$" just
5733   ;; forward-line before searching (See >>>[1] above).
5734   (goto-char (point-min))
5735   (insert "\n")
5736   (goto-char (point-max))
5737   (insert "\n")
5738   (unwind-protect
5739        (funcall search-fn)
5740     (goto-char (point-min))
5741     (delete-char 1)
5742     (goto-char (1- (point-max)))
5743     (delete-char 1)
5744     (set-buffer-modified-p nil)))
5745
5746 (defun helm-candidate-buffer (&optional buffer-spec)
5747   "Register and return a buffer storing candidates of current source.
5748
5749 This is used to initialize a buffer for storing candidates for a
5750 candidates-in-buffer source, candidates will be searched in this
5751 buffer and displayed in `helm-buffer'.
5752 This should be used only in init functions, don't relay on this in
5753 other places unless you know what you are doing.
5754
5755 This function is still in public API only for backward compatibility,
5756 you should use instead `helm-init-candidates-in-buffer' for
5757 initializing your sources.
5758
5759 Internally, this function is called without argument and returns the
5760 buffer corresponding to current source i.e `helm--source-name' which
5761 is available in only some places.
5762
5763 Acceptable values of BUFFER-SPEC:
5764
5765 - global (a symbol)
5766   Create a new global candidates buffer,
5767   named \" *helm candidates:SOURCE*\".
5768   This is used by `helm-init-candidates-in-buffer' and it is
5769   the most common usage of BUFFER-SPEC.
5770   The buffer will be killed and recreated at each new helm-session.
5771
5772 - local (a symbol)
5773   Create a new local candidates buffer,
5774   named \" *helm candidates:SOURCE*HELM-CURRENT-BUFFER\".
5775   You may want to use this when you want to have a different buffer
5776   each time source is used from a different `helm-current-buffer'.
5777   The buffer is erased and refilled at each new session but not killed.
5778   You probably don't want to use this value for BUFFER-SPEC.
5779
5780 - nil (omit)
5781   Only return the candidates buffer of current source if found.
5782   
5783 - A buffer
5784   Register a buffer as a candidates buffer.
5785   The buffer needs to exists, it is not created.
5786   This allow you to use the buffer as a cache, it is faster because
5787   the buffer is already drawn, but be careful when using this as you
5788   may mangle your buffer depending what you write in your init(s)
5789   function, IOW don't modify the contents of the buffer in init(s)
5790   function but in a transformer.
5791   The buffer is not erased nor deleted.
5792   Generally it is safer to use a copy of buffer inserted
5793   in a global or local buffer.
5794   
5795 If for some reasons a global buffer and a local buffer exist and are
5796 belonging to the same source, the local buffer takes precedence on the
5797 global one and is used instead.
5798
5799 When forcing update only the global and local buffers are killed
5800 before running again the init function."
5801   (let ((global-bname (format " *helm candidates:%s*"
5802                               helm--source-name))
5803         (local-bname (format " *helm candidates:%s*%s"
5804                              helm--source-name
5805                              (buffer-name helm-current-buffer))))
5806     (when buffer-spec
5807       ;; Register buffer in `helm--candidate-buffer-alist'.
5808       ;; This is used only to retrieve buffer associated to current source
5809       ;; when using named buffer as value of BUFFER-SPEC.
5810       (setq helm--candidate-buffer-alist
5811             (cons (cons helm--source-name buffer-spec)
5812                   (delete (assoc helm--source-name
5813                                  helm--candidate-buffer-alist)
5814                           helm--candidate-buffer-alist)))
5815       ;; When using global or local as value of CREATE-OR-BUFFER
5816       ;; create the buffer global-bname or local-bname, otherwise
5817       ;; reuse the named buffer.
5818       (unless (bufferp buffer-spec)
5819         ;; Global buffers are killed and recreated.
5820         (and (eq buffer-spec 'global)
5821              (buffer-live-p (get-buffer global-bname))
5822              (kill-buffer global-bname))
5823         ;; Create global or local buffer.
5824         ;; Local buffer, once created are reused and a new one
5825         ;; is created when `helm-current-buffer' change across sessions.
5826         (with-current-buffer (get-buffer-create
5827                               (cl-ecase buffer-spec
5828                                 (global global-bname)
5829                                 (local  local-bname)))
5830           ;; We need a buffer not read-only to perhaps insert later
5831           ;; text coming from read-only buffers (issue #1176).
5832           (set (make-local-variable 'buffer-read-only) nil)
5833           ;; Undo is automatically disabled in buffer names starting
5834           ;; with a space, so no need to disable it.
5835           (erase-buffer)
5836           (font-lock-mode -1))))
5837     ;; Finally return the candidates buffer.
5838     (helm-acond ((get-buffer local-bname))
5839                 ((get-buffer global-bname))
5840                 ((assoc-default helm--source-name helm--candidate-buffer-alist)
5841                  (and (or (stringp it) (bufferp it))
5842                       (buffer-live-p (get-buffer it))
5843                       it)))))
5844
5845 (defun helm-init-candidates-in-buffer (buffer-spec data)
5846   "Register BUFFER-SPEC with DATA for a helm candidates-in-buffer session.
5847
5848 Arg BUFFER-SPEC can be a buffer-name (stringp), a buffer-spec object
5849 \(bufferp), or a symbol, either 'local or 'global which is passed to
5850 `helm-candidate-buffer'.
5851 The most common usage of BUFFER-SPEC is 'global.
5852
5853 Arg DATA can be either a list or a plain string.
5854 Returns the resulting buffer.
5855
5856 Use this in your init function to register a buffer for a
5857 `helm-source-in-buffer' session and feed it with DATA.
5858 You probably don't want to bother with this and use the :data slot
5859 when initializing a source with `helm-source-in-buffer' class."
5860   (declare (indent 1))
5861   (let ((caching (and (or (stringp buffer-spec)
5862                           (bufferp buffer-spec))
5863                       (buffer-live-p (get-buffer buffer-spec))))
5864         (buf (helm-candidate-buffer
5865               (if (or (stringp buffer-spec)
5866                       (bufferp buffer-spec))
5867                   (get-buffer-create buffer-spec)
5868                 buffer-spec)))) ; a symbol 'global or 'local.
5869     (unless caching
5870       (with-current-buffer buf
5871         (erase-buffer)
5872         (cond ((listp data)
5873                (insert (mapconcat (lambda (i)
5874                                     (cond ((symbolp i) (symbol-name i))
5875                                           ((numberp i) (number-to-string i))
5876                                           (t i)))
5877                                   data "\n")))
5878               ((stringp data) (insert data))))
5879       buf)))
5880
5881
5882 ;;; Resplit helm window
5883 ;;
5884 ;;
5885 (defun helm-toggle-resplit-window ()
5886   "Toggle resplit helm window, vertically or horizontally."
5887   (interactive)
5888   (with-helm-alive-p
5889     (if (= (length (window-list nil 1)) 2)
5890         (progn
5891           (when helm-prevent-escaping-from-minibuffer
5892             (helm-prevent-switching-other-window :enabled nil))
5893           (unwind-protect
5894                (with-helm-window
5895                  (cond ((or helm-full-frame (one-window-p t))
5896                         (user-error "Attempt to resplit a single window"))
5897                        ((helm-action-window)
5898                         (user-error "Can't resplit while selecting actions"))
5899                        (t
5900                         (let ((before-height (window-height)))
5901                           (delete-window)
5902                           (set-window-buffer
5903                            (select-window
5904                             (if (= (window-height) before-height) ; initial split was horizontal.
5905                                 ;; Split window vertically with `helm-buffer' placed
5906                                 ;; on the good side according to actual value of
5907                                 ;; `helm-split-window-default-side'.
5908                                 (prog1
5909                                     (cond ((or (eq helm-split-window-default-side 'above)
5910                                                (eq helm-split-window-default-side 'left))
5911                                            (split-window
5912                                             (selected-window) nil 'above))
5913                                           (t (split-window-vertically)))
5914                                   (setq helm-split-window-state 'vertical))
5915                                 ;; Split window vertically, same comment as above.
5916                                 (setq helm-split-window-state 'horizontal)
5917                                 (cond ((or (eq helm-split-window-default-side 'left)
5918                                            (eq helm-split-window-default-side 'above))
5919                                        (split-window (selected-window) nil 'left))
5920                                       (t (split-window-horizontally)))))
5921                            helm-buffer))))
5922                  (setq helm--window-side-state (helm--get-window-side-state)))
5923             (when helm-prevent-escaping-from-minibuffer
5924               (helm-prevent-switching-other-window :enabled t))))
5925         (error "current window configuration not suitable for splitting"))))
5926 (put 'helm-toggle-resplit-window 'helm-only t)
5927
5928 ;; Utility: Resize helm window.
5929 (defun helm-enlarge-window-1 (n)
5930   "Enlarge or narrow helm window.
5931 If N is positive enlarge, if negative narrow."
5932   (unless helm-full-frame
5933     (let ((horizontal-p (eq helm-split-window-state 'horizontal)))
5934       (with-helm-window
5935         (enlarge-window n horizontal-p)))))
5936
5937 (defun helm-narrow-window ()
5938   "Narrow helm window."
5939   (interactive)
5940   (with-helm-alive-p
5941     (helm-enlarge-window-1 -1)))
5942 (put 'helm-narrow-window 'helm-only t)
5943
5944 (defun helm-enlarge-window ()
5945   "Enlarge helm window."
5946   (interactive)
5947   (with-helm-alive-p
5948     (helm-enlarge-window-1 1)))
5949 (put 'helm-enlarge-window 'helm-only t)
5950
5951 (defun helm-toggle-full-frame (&optional arg)
5952   "Toggle helm-buffer full-frame view."
5953   (interactive "p")
5954   (cl-assert (null (helm-action-window))
5955              nil "Unable to toggle full frame from action window")
5956   (when arg ; Called interactively
5957     (cl-assert (null helm--buffer-in-new-frame-p)
5958                nil "Can't toggle full frame when using helm own frame"))
5959   (if (or helm-onewindow-p
5960           (buffer-local-value 'helm-full-frame (get-buffer helm-buffer)))
5961       (with-helm-window
5962         (setq-local helm-full-frame nil)
5963         (setq helm-onewindow-p nil)
5964         (let ((split-window-preferred-function
5965                helm-split-window-preferred-function))
5966           (switch-to-buffer helm-current-buffer)
5967           (helm-display-buffer helm-buffer)
5968           (select-window (minibuffer-window))))
5969     (with-helm-window
5970       (delete-other-windows)
5971       (setq-local helm-full-frame t)
5972       (setq helm-onewindow-p t))))
5973 (put 'helm-toggle-full-frame 'helm-only t)
5974
5975 (defun helm-swap-windows ()
5976   "Swap window holding `helm-buffer' with other window."
5977   (interactive)
5978   (with-helm-alive-p
5979     (if (= (length (window-list nil 1)) 2)
5980         (cond ((and helm-full-frame (one-window-p t))
5981                (user-error "Can't swap windows in a single window"))
5982               ((helm-action-window)
5983                (user-error "Can't resplit while selecting actions"))
5984               (t
5985                (let* ((w1          (helm-window))
5986                       (split-state (eq helm-split-window-state 'horizontal))
5987                       (w1size      (window-total-size w1 split-state))
5988                       (b1          (window-buffer w1)) ; helm-buffer
5989                       (s1          (window-start w1))
5990                       (cur-frame   (window-frame w1))
5991                       (w2          (with-selected-window (helm-window)
5992                                      ;; Don't try to display helm-buffer
5993                                      ;; in a dedicated window.
5994                                      (get-window-with-predicate
5995                                       (lambda (w) (not (window-dedicated-p w)))
5996                                       1 cur-frame)))
5997                       (w2size      (window-total-size w2 split-state))
5998                       (b2          (window-buffer w2)) ; probably helm-current-buffer
5999                       (s2          (window-start w2))
6000                       resize)
6001                  (with-selected-frame (window-frame w1)
6002                    (helm-replace-buffer-in-window w1 b1 b2)
6003                    (helm-replace-buffer-in-window w2 b2 b1)
6004                    (setq resize
6005                          (cond ( ;; helm-window is smaller than other window.
6006                                 (< w1size w2size)
6007                                 (- (- (max w2size w1size)
6008                                       (min w2size w1size))))
6009                                ( ;; helm-window is larger than other window.
6010                                 (> w1size w2size)
6011                                 (- (max w2size w1size)
6012                                    (min w2size w1size)))
6013                                ( ;; windows have probably same size.
6014                                 t nil)))
6015                    ;; Maybe resize the window holding helm-buffer.
6016                    (and resize (window-resize w2 resize split-state))
6017                    (set-window-start w1 s2 t)
6018                    (set-window-start w2 s1 t))
6019                  (setq helm--window-side-state (helm--get-window-side-state)))))
6020         (error "current window configuration not suitable for splitting"))))
6021 (put 'helm-swap-windows 'helm-only t)
6022
6023 (defun helm--get-window-side-state ()
6024   "Return the position of `helm-window' from `helm-current-buffer'.
6025 Possible values are 'left 'right 'below or 'above."
6026   (let ((side-list '(left right below above)))
6027     (cl-loop for side in side-list
6028           thereis (and (equal (helm-window)
6029                               (window-in-direction
6030                                side (get-buffer-window helm-current-buffer t)
6031                                t))
6032                        side))))
6033
6034 (defun helm-replace-buffer-in-window (window buffer1 buffer2)
6035   "Replace BUFFER1 by BUFFER2 in WINDOW registering BUFFER1."
6036   (when (get-buffer-window buffer1)
6037     (unrecord-window-buffer window buffer1)
6038     (set-window-buffer window buffer2)))
6039
6040 ;; Utility: select another action by key
6041 (defun helm-select-nth-action (n)
6042   "Select the N nth action for the currently selected candidate."
6043   (let ((src (helm-get-current-source)))
6044     (setq helm-saved-selection (helm-get-selection nil nil src))
6045     (unless helm-saved-selection
6046       (error "Nothing is selected"))
6047     (setq helm-saved-action
6048           (helm-get-nth-action
6049            n
6050            (if (get-buffer-window helm-action-buffer 'visible)
6051                (assoc-default 'candidates src)
6052                (helm-get-actions-from-current-source src))))
6053     (helm-maybe-exit-minibuffer)))
6054
6055 (defun helm-get-nth-action (n action)
6056   (cond ((and (zerop n) (functionp action))
6057          action)
6058         ((listp action)
6059          (or (cdr (elt action n))
6060              (error "No such action")))
6061         ((and (functionp action) (< 0 n))
6062          (error "Sole action"))
6063         (t
6064          (error "Error in `helm-select-nth-action'"))))
6065
6066 (defun helm-execute-selection-action-at-nth (linum)
6067   "Execute default action on candidate at LINUM lines from selection."
6068   (let ((prefarg current-prefix-arg))
6069     (if (>= linum 0)
6070         (helm-next-line linum)
6071         (helm-previous-line (lognot (1- linum))))
6072     (setq current-prefix-arg prefarg)
6073     (helm-exit-minibuffer)))
6074
6075 ;;; Persistent Action
6076 ;;
6077 (defun helm-initialize-persistent-action ()
6078   (set (make-local-variable 'helm-persistent-action-display-window) nil))
6079
6080 (cl-defun helm-execute-persistent-action (&optional attr split-onewindow)
6081   "Perform the associated action ATTR without quitting helm.
6082 Arg ATTR default will be `persistent-action' or `persistent-action-if'
6083 if unspecified depending on what's found in source, but it can be
6084 anything else.
6085 In this case you have to add this new attribute to your source.
6086 See `persistent-action' and `persistent-action-if' slot documentation
6087 in `helm-source'.
6088
6089 When `helm-full-frame' or SPLIT-ONEWINDOW are non-`nil', and
6090 `helm-buffer' is displayed in only one window, the helm window is
6091 split to display `helm-select-persistent-action-window' in other
6092 window to maintain visibility."
6093   (interactive)
6094   (with-helm-alive-p
6095     (let ((source (helm-get-current-source)))
6096       (unless attr
6097         (setq attr (or (car (assq 'persistent-action source))
6098                        (car (assq 'persistent-action-if source)))))
6099       (helm-log "executing persistent-action")
6100       (let* ((selection (and source (helm-get-selection nil nil source)))
6101              (attr-val (if (eq attr 'persistent-action-if)
6102                            (funcall (assoc-default attr source) selection)
6103                          (assoc-default attr source)))
6104              ;; If attr value is a cons, use its car as persistent function
6105              ;; and its car to decide if helm window should be splitted.
6106              (fn       (if (and (consp attr-val)
6107                                 ;; maybe a lambda.
6108                                 (not (functionp attr-val)))
6109                            (car attr-val) attr-val))
6110              (no-split (and (consp attr-val)
6111                             (not (functionp attr-val))
6112                             (cdr attr-val)))
6113              (cursor-in-echo-area t)
6114              mode-line-in-non-selected-windows)
6115         (progn
6116           (when (and helm-onewindow-p (null no-split)
6117                      (null helm--buffer-in-new-frame-p))
6118             (helm-toggle-full-frame))
6119           (when (eq fn 'ignore)
6120             (cl-return-from helm-execute-persistent-action nil))
6121           (when source
6122             (with-helm-window
6123               (save-selected-window
6124                 (if no-split
6125                     (helm-select-persistent-action-window)
6126                   (helm-select-persistent-action-window
6127                    (or split-onewindow helm-onewindow-p)))
6128                 (helm-log "current-buffer = %S" (current-buffer))
6129                 (let ((helm-in-persistent-action t)
6130                       (same-window-regexps '("."))
6131                       display-buffer-function pop-up-windows pop-up-frames
6132                       special-display-regexps special-display-buffer-names)
6133                   (helm-execute-selection-action-1
6134                    selection (or fn (helm-get-actions-from-current-source source)) t)
6135                   (unless (helm-action-window)
6136                     (helm-log-run-hook 'helm-after-persistent-action-hook)))
6137                 ;; A typical case is when a persistent action delete
6138                 ;; the buffer already displayed in
6139                 ;; `helm-persistent-action-display-window' and `helm-full-frame'
6140                 ;; is enabled, we end up with the `helm-buffer'
6141                 ;; displayed in two windows.
6142                 (when (and helm-onewindow-p
6143                            (> (length (window-list)) 1)
6144                            (equal (buffer-name
6145                                    (window-buffer
6146                                     helm-persistent-action-display-window))
6147                                   (helm-buffer-get)))
6148                   (delete-other-windows))))))))))
6149 (put 'helm-execute-persistent-action 'helm-only t)
6150
6151 (defun helm-persistent-action-display-window (&optional split-onewindow)
6152   "Return the window that will be used for persistent action.
6153 If SPLIT-ONEWINDOW is non-`nil' window is split in persistent action."
6154   (with-helm-window
6155     (let (next-win cur-win)
6156       (setq helm-persistent-action-display-window
6157             (cond ((and (window-live-p helm-persistent-action-display-window)
6158                         (not (member helm-persistent-action-display-window
6159                                      (get-buffer-window-list helm-buffer))))
6160                    helm-persistent-action-display-window)
6161                   ((and helm--buffer-in-new-frame-p helm-initial-frame)
6162                    (with-selected-frame helm-initial-frame (selected-window)))
6163                   (split-onewindow (split-window))
6164                   ;; Fix Issue #2050 with dedicated window.
6165                   ((window-dedicated-p
6166                     (setq next-win (next-window (selected-window) 1)))
6167                    (with-helm-after-update-hook
6168                      (and (window-live-p helm-persistent-action-display-window)
6169                           (delete-window helm-persistent-action-display-window)))
6170                    (split-window))
6171                   ((window-dedicated-p
6172                     (setq cur-win (get-buffer-window helm-current-buffer)))
6173                    (split-window))
6174                   (cur-win)
6175                   (t next-win))))))
6176
6177 (defun helm-select-persistent-action-window (&optional split-onewindow)
6178   "Select the window that will be used for persistent action.
6179 See `helm-persistent-action-display-window' for how to use SPLIT-ONEWINDOW."
6180   (select-window (get-buffer-window (helm-buffer-get)))
6181   (prog1
6182       (select-window
6183        (setq minibuffer-scroll-window
6184              (helm-persistent-action-display-window split-onewindow)))
6185     (helm-log "Selected window is %S" minibuffer-scroll-window)))
6186
6187 ;;; Scrolling - recentering
6188 ;;
6189 ;;
6190 (defun helm-other-window-base (command &optional arg)
6191   (let ((minibuffer-scroll-window
6192          (helm-persistent-action-display-window)))
6193     (funcall command (or arg helm-scroll-amount))))
6194
6195 (defun helm-scroll-other-window (&optional arg)
6196   "Scroll other window upward ARG many lines.
6197 When arg is not provided scroll `helm-scroll-amount' lines.
6198 See `scroll-other-window'."
6199   (interactive "P")
6200   (with-helm-alive-p (helm-other-window-base 'scroll-other-window arg)))
6201 (put 'helm-scroll-other-window 'helm-only t)
6202
6203 (defun helm-scroll-other-window-down (&optional arg)
6204   "Scroll other window downward ARG many lines.
6205 When arg is not provided scroll `helm-scroll-amount' lines.
6206 See `scroll-other-window-down'."
6207   (interactive "P")
6208   (with-helm-alive-p (helm-other-window-base 'scroll-other-window-down arg)))
6209 (put 'helm-scroll-other-window-down 'helm-only t)
6210
6211 (defun helm-recenter-top-bottom-other-window (&optional arg)
6212   "Run `recenter-top-bottom' in other window.
6213 Meaning of prefix ARG is the same as in `recenter-top-bottom'."
6214   (interactive "P")
6215   (with-helm-alive-p
6216     (with-helm-window
6217       (with-selected-window (helm-persistent-action-display-window)
6218         (recenter-top-bottom arg)))))
6219 (put 'helm-recenter-top-bottom-other-window 'helm-only t)
6220
6221 (defun helm-reposition-window-other-window (&optional arg)
6222   "Run `reposition-window' in other window.
6223 Meaning of prefix ARG is the same as in `reposition-window'."
6224   (interactive "P")
6225   (with-helm-alive-p
6226     (with-helm-window
6227       (with-selected-window (helm-persistent-action-display-window)
6228         (reposition-window arg)))))
6229 (put 'helm-reposition-window-other-window 'helm-only t)
6230
6231
6232 ;; Utility: Visible Mark
6233
6234 (defun helm-clear-visible-mark ()
6235   (with-current-buffer (helm-buffer-get)
6236     (mapc 'delete-overlay helm-visible-mark-overlays)
6237     (set (make-local-variable 'helm-visible-mark-overlays) nil)))
6238
6239 (defun helm-this-visible-mark ()
6240   (cl-loop for o in (overlays-at (point))
6241            when (overlay-get o 'visible-mark)
6242            return o))
6243
6244 (defun helm-delete-visible-mark (overlay)
6245   (let ((src (helm-get-current-source)))
6246     (setq helm-marked-candidates
6247           (remove
6248            (cons src (helm-get-selection nil nil src))
6249            helm-marked-candidates))
6250     (delete-overlay overlay)
6251     (setq helm-visible-mark-overlays
6252           (delq overlay helm-visible-mark-overlays))))
6253
6254 (defun helm-make-visible-mark (&optional src selection)
6255   (let* ((source (or src  (helm-get-current-source)))
6256          (sel    (or selection (helm-get-selection
6257                                 nil (helm-attr 'marked-with-props source)
6258                                 source)))
6259          (selection-end (if (helm-pos-multiline-p)
6260                             ;; Stays within source
6261                             (or (helm-get-next-candidate-separator-pos)
6262                                 (helm-get-next-header-pos)
6263                                 (point-max))
6264                           ;; Not multiline
6265                           (1+ (point-at-eol))))
6266          (o (make-overlay (point-at-bol) selection-end)))
6267     (overlay-put o 'priority 0)
6268     (overlay-put o 'face   'helm-visible-mark)
6269     (overlay-put o 'source (assoc-default 'name source))
6270     (overlay-put o 'string (buffer-substring (overlay-start o) (overlay-end o)))
6271     (overlay-put o 'real sel)
6272     (overlay-put o 'visible-mark t)
6273     (cl-pushnew o helm-visible-mark-overlays)
6274     (push (cons source sel) helm-marked-candidates)))
6275
6276 (defun helm-toggle-visible-mark (arg)
6277   "Toggle helm visible mark at point ARG times.
6278 If ARG is negative toggle backward."
6279   (interactive "p")
6280   (with-helm-alive-p
6281     (with-helm-window
6282       (let ((nomark (assq 'nomark (helm-get-current-source)))
6283             (next-fns (if (< arg 0)
6284                           '(helm-beginning-of-source-p . helm-previous-line)
6285                         '(helm-end-of-source-p . helm-next-line))))
6286         (if nomark
6287             (message "Marking not allowed in this source")
6288           (cl-loop with n = (if (< arg 0) (* arg -1) arg)
6289                    repeat n do
6290                    (progn
6291                      (helm-aif (helm-this-visible-mark)
6292                          (helm-delete-visible-mark it)
6293                        (helm-make-visible-mark))
6294                      (if (funcall (car next-fns))
6295                          (progn
6296                            (helm-display-mode-line (helm-get-current-source))
6297                            (cl-return nil))
6298                        (funcall (cdr next-fns))))))))))
6299 (put 'helm-toggle-visible-mark 'helm-only t)
6300
6301 (defun helm-file-completion-source-p (&optional source)
6302   "Return non-`nil' if current source is a file completion source."
6303   (or helm--completing-file-name ; helm-read-file-name
6304       (let ((cur-source (cdr (assq 'name
6305                                     (or source (helm-get-current-source))))))
6306         (cl-loop for i in helm--file-completion-sources
6307                  thereis (string= cur-source i)))))
6308
6309 (defun helm-mark-all (&optional all)
6310   "Mark all visible unmarked candidates in current source.
6311
6312 With a prefix arg mark all visible unmarked candidates in all sources."
6313   (interactive "P")
6314   (with-helm-alive-p
6315     (with-helm-window ; Using `with-helm-buffer' for some unknow reasons infloop.
6316       (if (null all)
6317           (helm-mark-all-1 t)
6318           (let ((pos (point)))
6319             (goto-char (point-min))
6320             (helm-awhile (helm-get-next-header-pos)
6321               (goto-char it)
6322               (forward-line 1)
6323               (helm-mark-current-line)
6324               (helm-mark-all-1))
6325             ;; `save-excursion' seems confused if used in addition of
6326             ;; the one used in `helm-mark-all-1', so save POS and back
6327             ;; to it when loop is finished.
6328             (goto-char pos)
6329             (helm-mark-current-line)
6330             (helm-display-mode-line (helm-get-current-source) t))))))
6331 (put 'helm-mark-all 'helm-only t)
6332
6333 (defun helm-mark-all-1 (&optional ensure-beg-of-source)
6334   "Mark all visible unmarked candidates in current source.
6335 Need to be wrapped in `with-helm-window'.
6336 Arg ENSURE-BEG-OF-SOURCE ensure we are at beginning of source when
6337 starting to mark candidates, if handled elsewhere before starting it
6338 is not needed."
6339   (let* ((src        (helm-get-current-source))
6340          (follow     (if (helm-follow-mode-p src) 1 -1))
6341          (nomark     (assq 'nomark src))
6342          (src-name   (assoc-default 'name src))
6343          (filecomp-p (or (helm-file-completion-source-p src)
6344                          (string= src-name "Files from Current Directory")))
6345          (remote-p (and filecomp-p (file-remote-p helm-pattern))))
6346     ;; Note that `cl-letf' prevents edebug working properly.
6347     (cl-letf (((symbol-function 'message) #'ignore))
6348       (helm-follow-mode -1)
6349       (unwind-protect
6350            (if nomark
6351                (message "Marking not allowed in this source")
6352                (save-excursion
6353                  (when ensure-beg-of-source
6354                    (goto-char (helm-get-previous-header-pos))
6355                    (forward-line 1))
6356                  (let* ((next-head (helm-get-next-header-pos))
6357                         (end       (and next-head
6358                                         (save-excursion
6359                                           (goto-char next-head)
6360                                           (forward-line -1)
6361                                           (point))))
6362                         (maxpoint  (or end (point-max))))
6363                    (while (< (point) maxpoint)
6364                      (helm-mark-current-line)
6365                      (let* ((prefix (get-text-property (point-at-bol) 'display))
6366                             (cand   (helm-get-selection nil nil src))
6367                             (bn     (and filecomp-p (helm-basename cand))))
6368                        ;; Don't mark possibles directories ending with . or ..
6369                        ;; autosave files/links and non--existent files.
6370                        (unless
6371                            (or (helm-this-visible-mark)
6372                                (string= prefix "[?]") ; doesn't match
6373                                (and filecomp-p
6374                                     (or
6375                                      ;; autosave files
6376                                      (string-match-p "^[.]?#.*#?$" bn)
6377                                      ;; dot files
6378                                      (member bn '("." ".."))
6379                                      ;; We need to test here when not using
6380                                      ;; a transformer that put a prefix tag
6381                                      ;; before candidate.
6382                                      ;; (i.e no [?] prefix on tramp).
6383                                      (and remote-p (not (file-exists-p cand))))))
6384                          (helm-make-visible-mark src cand)))
6385                      (when (helm-pos-multiline-p)
6386                        (goto-char
6387                         (or (helm-get-next-candidate-separator-pos)
6388                             (point-max))))
6389                      (forward-line 1))))
6390                (helm-mark-current-line))
6391         (helm-follow-mode follow)))))
6392
6393 (defun helm-unmark-all ()
6394   "Unmark all candidates in all sources of current helm session."
6395   (interactive)
6396   (with-helm-alive-p
6397     (with-helm-window
6398       (save-excursion
6399         (helm-clear-visible-mark))
6400       (setq helm-marked-candidates nil)
6401       (helm-mark-current-line)
6402       (helm-display-mode-line (helm-get-current-source)))))
6403 (put 'helm-unmark-all 'helm-only t)
6404
6405 (defun helm-toggle-all-marks (&optional all)
6406   "Toggle all marks.
6407
6408 Mark all visible candidates of current source or unmark all candidates
6409 visible or invisible in all sources of current helm session.
6410
6411 With a prefix argument mark all candidates in all sources."
6412   (interactive "P")
6413   (with-helm-alive-p
6414     (let ((marked (helm-marked-candidates)))
6415       (if (and (>= (length marked) 1)
6416                (with-helm-window helm-visible-mark-overlays))
6417           (helm-unmark-all)
6418           (helm-mark-all all)))))
6419 (put 'helm-toggle-all-marks 'helm-only t)
6420
6421 (defun helm--compute-marked (real source &optional wildcard)
6422   (let* ((coerced (helm-coerce-selection real source))
6423          (wilds   (and wildcard
6424                        (condition-case nil
6425                            (helm-file-expand-wildcards
6426                             coerced t)
6427                          (error nil)))))
6428     ;; Avoid returning a not expanded wilcard fname.
6429     ;; e.g assuming "/tmp" doesn't contain "*.el"
6430     ;; return nil when coerced is "/tmp/*.el".
6431     (unless (or wilds (null wildcard)
6432                 (string-match-p helm--url-regexp coerced)
6433                 (file-exists-p coerced)
6434                 (and (stringp coerced)
6435                      (null (string-match-p "[[*?]" coerced))))
6436       (setq coerced nil))
6437     (or wilds (and coerced (list coerced)))))
6438
6439 (cl-defun helm-marked-candidates (&key with-wildcard all-sources)
6440   "Return marked candidates of current source, if any.
6441
6442 Otherwise return one element list consisting of the current
6443 selection. When key WITH-WILDCARD is specified, expand it.
6444 When ALL-SOURCES key value is non-nil returns marked candidates of all
6445 sources."
6446   (with-current-buffer helm-buffer
6447     (let* ((current-src (helm-get-current-source))
6448            (candidates
6449             (cl-loop for (source . real) in (reverse helm-marked-candidates)
6450                      for use-wc = (and with-wildcard
6451                                        (string-match-p "\\*" real)
6452                                        (null (file-exists-p real)))
6453                      when (or all-sources
6454                               (equal (assq 'name source)
6455                                      (assq 'name current-src)))
6456                      append (helm--compute-marked real source use-wc)))
6457            sel)
6458       (unless candidates
6459         (setq sel (helm-get-selection
6460                    nil (helm-attr 'marked-with-props
6461                                   current-src)
6462                    current-src))
6463         (setq candidates
6464               (helm--compute-marked
6465                sel current-src
6466                (and with-wildcard (null (file-exists-p sel))))))
6467       (helm-log "Marked candidates = %S" candidates)
6468       candidates)))
6469
6470 (defun helm--remove-marked-and-update-mode-line (elm)
6471   (with-helm-buffer
6472     (setq helm-marked-candidates
6473           (delete (rassoc elm helm-marked-candidates)
6474                   helm-marked-candidates))
6475     (helm-display-mode-line (helm-get-current-source))))
6476
6477 (defun helm-current-source-name= (name)
6478   (save-excursion
6479     (goto-char (helm-get-previous-header-pos))
6480     (equal name (helm-current-line-contents))))
6481
6482 (defun helm-revive-visible-mark ()
6483   "Restore marked candidates when helm updates display."
6484   (with-current-buffer helm-buffer
6485     (save-excursion
6486       (cl-dolist (o helm-visible-mark-overlays)
6487         (let ((o-src-str (overlay-get o 'source))
6488               (o-str (overlay-get o 'string))
6489               beg end)
6490           ;; Move point to end of source header line.
6491           (goto-char (point-min))
6492           (search-forward o-src-str nil t)
6493           (while (and (search-forward o-str nil t)
6494                       (cl-loop for ov in (overlays-at (point-at-bol 0))
6495                                never (overlay-get ov 'visible-mark))
6496                       (helm-current-source-name= o-src-str))
6497             (setq beg (match-beginning 0)
6498                   end (match-end 0))
6499             ;; Calculate real value of candidate.
6500             ;; It can be nil if candidate have only a display value.
6501             (let ((real (get-text-property (point-at-bol 0) 'helm-realvalue)))
6502               (if real
6503                   ;; Check if real value of current candidate is the same
6504                   ;; than the one stored in overlay.
6505                   ;; This is needed when some cands have same display names.
6506                   ;; Using equal allow testing any type of value for real cand.
6507                   ;; Issue (#706).
6508                   (and (equal (overlay-get o 'real) real)
6509                        (move-overlay o beg end))
6510                   (and (equal o-str (buffer-substring beg end))
6511                        (move-overlay o beg end))))))))))
6512 (add-hook 'helm-after-update-hook 'helm-revive-visible-mark)
6513
6514 (defun helm-next-point-in-list (curpos points &optional prev)
6515   (cond
6516     ;; rule out special cases.
6517     ((null points) curpos)
6518     ((and prev (<= curpos (car points)))
6519      (nth (1- (length points)) points))
6520     ((< (car (last points)) curpos)
6521      (if prev (car (last points)) (nth 0 points)))
6522     ((and (not prev) (>= curpos (car (last points))))
6523      (nth 0 points))
6524     (t
6525      (nth (if prev
6526               (cl-loop for pt in points
6527                     for i from 0
6528                     if (<= curpos pt) return (1- i))
6529             (cl-loop for pt in points
6530                   for i from 0
6531                   if (< curpos pt) return i))
6532           points))))
6533
6534 (defun helm-next-visible-mark (&optional prev)
6535   "Move next helm visible mark.
6536 If PREV is non-`nil' move to precedent."
6537   (interactive)
6538   (with-helm-alive-p
6539     (with-helm-window
6540       (ignore-errors
6541         (goto-char (helm-next-point-in-list
6542                     (point)
6543                     (sort (mapcar 'overlay-start helm-visible-mark-overlays) '<)
6544                     prev)))
6545       (helm-mark-current-line))))
6546 (put 'helm-next-visible-mark 'helm-only t)
6547
6548 (defun helm-prev-visible-mark ()
6549   "Move previous helm visible mark."
6550   (interactive)
6551   (with-helm-alive-p
6552     (helm-next-visible-mark t)))
6553 (put 'helm-prev-visible-mark 'helm-only t)
6554
6555 ;;; Utility: Selection Paste
6556 ;;
6557 (defun helm-yank-selection (arg)
6558   "Set minibuffer contents to current display selection.
6559 With a prefix arg set to real value of current selection."
6560   (interactive "P")
6561   (with-helm-alive-p
6562     (let ((str (format "%s" (helm-get-selection nil (not arg)))))
6563       (kill-new str)
6564       (helm-set-pattern str))))
6565 (put 'helm-yank-selection 'helm-only t)
6566
6567 (defun helm-kill-selection-and-quit (arg)
6568   "Store display value of current selection to kill ring.
6569 With a prefix arg use real value of current selection.
6570 Display value is shown in `helm-buffer' and real value
6571 is used to perform actions."
6572   (interactive "P")
6573   (with-helm-alive-p
6574     (helm-run-after-exit
6575      (lambda (sel)
6576        (kill-new sel)
6577        ;; Return nil to force `helm-mode--keyboard-quit'
6578        ;; in `helm-comp-read' otherwise the value "Saved to kill-ring: foo"
6579        ;; is used as exit value for `helm-comp-read'.
6580        (prog1 nil (message "Saved to kill-ring: %s" sel) (sit-for 1)))
6581      (format "%s" (helm-get-selection nil (not arg))))))
6582 (put 'helm-kill-selection-and-quit 'helm-only t)
6583
6584 (defun helm-copy-to-buffer ()
6585   "Copy selection or marked candidates to `helm-current-buffer'.
6586 Note that the real values of candidates are copied and not the
6587 display values."
6588   (interactive)
6589   (with-helm-alive-p
6590     (helm-run-after-exit
6591      (lambda (cands)
6592        (with-helm-current-buffer
6593          (insert (mapconcat (lambda (c)
6594                               (format "%s" c))
6595                             cands "\n"))))
6596      (helm-marked-candidates))))
6597 (put 'helm-copy-to-buffer 'helm-only t)
6598
6599
6600 ;;; Follow-mode: Automatic execution of persistent-action
6601 ;;
6602 ;;
6603 (defvar helm-follow-input-idle-delay nil
6604   "`helm-follow-mode' will execute its persistent action after this delay.
6605 Note that if the `follow-delay' attr is present in source,
6606 it will take precedence over this.")
6607
6608 (defun helm-follow-mode (&optional arg)
6609   "Execute persistent action every time the cursor is moved.
6610
6611 This mode is source local, i.e It apply on current source only.
6612 \\<helm-map>
6613 This mode can be enabled or disabled interactively at anytime during
6614 a helm session with \\[helm-follow-mode].
6615
6616 When enabling interactively `helm-follow-mode' in a source, you can keep it enabled
6617 for next emacs sessions by setting `helm-follow-mode-persistent' to a non-nil value.
6618
6619 When `helm-follow-mode' is called with a prefix arg and `helm-follow-mode-persistent'
6620 is non-nil `helm-follow-mode' will be persistent only for this emacs session,
6621 but not for next emacs sessions, i.e the current source will not be saved
6622 to `helm-source-names-using-follow'.
6623 A prefix arg with `helm-follow-mode' already enabled will have no effect.
6624
6625 Note that you can use instead of this mode the commands `helm-follow-action-forward'
6626 and `helm-follow-action-backward' at anytime in all helm sessions.
6627
6628 They are bound by default to \\[helm-follow-action-forward] and \\[helm-follow-action-backward]."
6629   (interactive (list (helm-aif (and current-prefix-arg
6630                                     (prefix-numeric-value current-prefix-arg))
6631                          (unless (helm-follow-mode-p) it))))
6632   (with-helm-alive-p
6633     (with-current-buffer helm-buffer
6634       (let* ((src      (helm-get-current-source))
6635              (name     (assoc-default 'name src))
6636              (fol-attr (assq 'follow src))
6637              (enabled  (or (helm-follow-mode-p src)
6638                            (and helm-follow-mode-persistent
6639                                 (member (assoc-default 'name src)
6640                                         helm-source-names-using-follow)))))
6641         (if src
6642             (progn
6643               (if (eq (cdr fol-attr) 'never)
6644                   (message "helm-follow-mode not allowed in this source")
6645                   ;; Make follow attr persistent for this emacs session.
6646                   (helm-follow-mode-set-source
6647                    (if (or enabled (and (numberp arg) (< arg 0))) -1 1)
6648                    src)
6649                   ;; When arg is nil assume the call is interactive.
6650                   ;; However if user call helm-follow-mode with a prefix arg,
6651                   ;; the call will be considered non--interactive and
6652                   ;; src-name will NOT be saved to helm-source-names-using-follow.
6653                   ;; When called from lisp (non--interactive) src-name
6654                   ;; will never be saved.
6655                   (when (and helm-follow-mode-persistent (null arg))
6656                     (if (null enabled)
6657                         (unless (member name helm-source-names-using-follow)
6658                           (push name helm-source-names-using-follow)
6659                           (customize-save-variable 'helm-source-names-using-follow
6660                                                    helm-source-names-using-follow))
6661                         (when (member name helm-source-names-using-follow)
6662                           (setq helm-source-names-using-follow
6663                                 (delete name helm-source-names-using-follow))
6664                           (customize-save-variable 'helm-source-names-using-follow
6665                                                    helm-source-names-using-follow))))
6666                   (message "helm-follow-mode is %s"
6667                            (if (helm-follow-mode-p src)
6668                                "enabled" "disabled"))
6669                   (helm-display-mode-line src t)))
6670             (message "Not enough candidates for helm-follow-mode"))))))
6671 (put 'helm-follow-mode 'helm-only t)
6672
6673 (defun helm-follow-execute-persistent-action-maybe (&optional delay)
6674   "Execute persistent action in mode `helm-follow-mode'.
6675
6676 This happen after: DELAY or the 'follow-attr value of current source
6677 or `helm-follow-input-idle-delay' or `helm-input-idle-delay' secs."
6678   (let* ((src (helm-get-current-source))
6679          (at (or delay
6680                  (assoc-default 'follow-delay src)
6681                  helm-follow-input-idle-delay
6682                  (or (and helm-input-idle-delay
6683                           (max helm-input-idle-delay 0.01))
6684                      0.01))))
6685     (when (and (not (get-buffer-window helm-action-buffer 'visible))
6686                (not (helm-pos-header-line-p))
6687                (or (helm-follow-mode-p src)
6688                    (and helm-follow-mode-persistent
6689                         (member (assoc-default 'name src)
6690                                 helm-source-names-using-follow)))
6691                (null (eq (assoc-default 'follow src) 'never))
6692                (helm-get-selection nil nil src))
6693       (helm-follow-mode-set-source 1 src)
6694       (run-with-idle-timer at nil (lambda ()
6695                                     (when helm-alive-p
6696                                       (helm-execute-persistent-action)))))))
6697
6698 (defun helm-follow-mode-p (&optional source)
6699   (with-helm-buffer
6700     (eq (helm-attr 'follow (or source (helm-get-current-source))) 1)))
6701
6702 (defun helm-follow-mode-set-source (value &optional source)
6703   (with-helm-buffer
6704     (helm-attrset 'follow value (or source (helm-get-current-source)))))
6705
6706 ;;; Auto-resize mode
6707 ;;
6708 (defun helm--autoresize-hook (&optional max-height min-height)
6709   (when (helm-window)
6710     (with-helm-window
6711       (fit-window-to-buffer nil
6712                             (/ (* (frame-height)
6713                                   (or max-height helm-autoresize-max-height))
6714                                100)
6715                             (/ (* (frame-height)
6716                                   (or min-height helm-autoresize-min-height))
6717                                100)))))
6718
6719 (define-minor-mode helm-autoresize-mode
6720     "Auto resize helm window when enabled.
6721 Helm window is re-sized according to `helm-autoresize-max-height'
6722 and `helm-autoresize-min-height'. Note that when this mode is
6723 enabled, helm behaves as if `helm-always-two-windows' is
6724 enabled.
6725
6726 See `fit-window-to-buffer' for more infos."
6727   :group 'helm
6728   :global t
6729   (if helm-autoresize-mode
6730       (progn (add-hook 'helm-after-update-hook 'helm--autoresize-hook)
6731              (add-hook 'helm-window-configuration-hook 'helm--autoresize-hook))
6732       (remove-hook 'helm-after-update-hook 'helm--autoresize-hook)
6733       (remove-hook 'helm-window-configuration-hook 'helm--autoresize-hook)))
6734
6735 (defun helm-help ()
6736   "Generate helm's help according to `help-message' attribute.
6737
6738 If `helm-buffer' is empty, provide completions on `helm-sources' to
6739 choose its local documentation.
6740 If source doesn't have any `help-message' attribute, a generic message
6741 explaining this is added instead.
6742 The global `helm-help-message' is always added after this local help."
6743   (interactive)
6744   (with-helm-alive-p
6745     (let ((source (or (helm-get-current-source)
6746                       (helm-comp-read
6747                        "Help for: "
6748                        (cl-loop for src in (with-helm-buffer helm-sources)
6749                                 for src-val =  (if (symbolp src)
6750                                                    (symbol-value src)
6751                                                  src)
6752                                 collect `(,(assoc-default 'name src-val) .
6753                                            ,src))
6754                        :allow-nest t
6755                        :exec-when-only-one t))))
6756       (save-selected-window
6757         (helm-help-internal
6758          "*Helm Help*"
6759          (lambda ()
6760            (helm-aif (assoc-default 'help-message source)
6761                (insert (substitute-command-keys
6762                         (helm-interpret-value it)))
6763              (insert "* No specific help for this source available."))
6764            (insert "\n\n"
6765                    (substitute-command-keys
6766                     (helm-interpret-value helm-help-message)))))))))
6767 (put 'helm-help 'helm-only t)
6768
6769 (defun helm-toggle-truncate-line ()
6770   "Toggle `truncate-lines' value in `helm-buffer'"
6771   (interactive)
6772   (with-helm-alive-p
6773     (with-helm-buffer
6774       (setq truncate-lines (not truncate-lines))
6775       (when (helm-get-previous-header-pos)
6776         (helm-update (regexp-quote (helm-get-selection nil t)))))))
6777 (put 'helm-toggle-truncate-line 'helm-only t)
6778
6779 (provide 'helm)
6780
6781 ;; Local Variables:
6782 ;; byte-compile-warnings: (not obsolete)
6783 ;; coding: utf-8
6784 ;; indent-tabs-mode: nil
6785 ;; End:
6786
6787 ;;; helm.el ends here