summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2017-12-30 14:39:21 +0000
committerSean Whitton <spwhitton@spwhitton.name>2017-12-30 14:39:21 +0000
commit688d6135cbe7fb06b32aa5d562bcce4ff3d0dc77 (patch)
tree1b3652e29995520c1f98d514df3fa769124a0b51
parent8be4fa3d95dddb096f05cf25fdeee780dd42e274 (diff)
parent5b2057c7755f6ea20e1ea011c6fb992d12650161 (diff)
Merge tag 'v2.8.7'
Version 2.8.7 * New command to toggle helm buffer full-frame. * Allow yanking marked and choosing separator from main action, the third action "append" have been removed. * Possibility to create new kmacro from marked kmacros. * Allow toggling mark on more than one candidate with numeric prefix args. # gpg: Signature made Sat 23 Dec 2017 08:02:48 GMT # gpg: using DSA key 28D17F5359F29997 # gpg: Can't check signature: No public key
-rw-r--r--helm-core-pkg.el2
-rw-r--r--helm-elisp.el53
-rw-r--r--helm-files.el142
-rw-r--r--helm-for-files.el2
-rw-r--r--helm-help.el15
-rw-r--r--helm-mode.el20
-rw-r--r--helm-pkg.el4
-rw-r--r--helm-ring.el204
-rw-r--r--helm-source.el59
-rw-r--r--helm-tags.el9
-rw-r--r--helm-utils.el15
-rw-r--r--helm.el195
12 files changed, 442 insertions, 278 deletions
diff --git a/helm-core-pkg.el b/helm-core-pkg.el
index 0cdd9302..65c39023 100644
--- a/helm-core-pkg.el
+++ b/helm-core-pkg.el
@@ -1,6 +1,6 @@
;;; helm-core-pkg.el --- define helm-core for package.el
-(define-package "helm-core" "2.8.6"
+(define-package "helm-core" "2.8.7"
"Development files for Helm"
'((emacs "24.4")
(async "1.9.2"))
diff --git a/helm-elisp.el b/helm-elisp.el
index e6b9e6b6..6cc3fa78 100644
--- a/helm-elisp.el
+++ b/helm-elisp.el
@@ -150,10 +150,9 @@ fuzzy completion is not available in `completion-at-point'."
(helm-get-selection)))))
(defun helm-show-completion-init-overlay (beg end)
- (when (and helm-turn-on-show-completion beg end)
- (setq helm-show-completion-overlay (make-overlay beg end))
- (overlay-put helm-show-completion-overlay
- 'face 'helm-lisp-show-completion)))
+ (setq helm-show-completion-overlay (make-overlay beg end))
+ (overlay-put helm-show-completion-overlay
+ 'face 'helm-lisp-show-completion))
(defun helm-show-completion-display-function (buffer &rest _args)
"A special resized helm window is used depending on position in BUFFER."
@@ -179,31 +178,29 @@ fuzzy completion is not available in `completion-at-point'."
BEG and END are the beginning and end position of the current completion
in `helm-current-buffer'.
BODY is an helm call where we want to enable show completion.
-If `helm-turn-on-show-completion' is nil just do nothing."
+If `helm-turn-on-show-completion' is nil do nothing."
(declare (indent 2) (debug t))
- `(let ((helm-move-selection-after-hook
- (and helm-turn-on-show-completion
- (append (list 'helm-show-completion)
- helm-move-selection-after-hook)))
- (helm-always-two-windows t)
- (helm-split-window-default-side
- (if (eq helm-split-window-default-side 'same)
- 'below helm-split-window-default-side))
- helm-split-window-inside-p
- helm-reuse-last-window-split-state)
- (helm-set-local-variable
- 'helm-display-function
- (if helm-show-completion-use-special-display
- 'helm-show-completion-display-function
- 'helm-default-display-buffer))
- (unwind-protect
- (progn
- (helm-show-completion-init-overlay ,beg ,end)
- ,@body)
- (when (and helm-turn-on-show-completion
- helm-show-completion-overlay
- (overlayp helm-show-completion-overlay))
- (delete-overlay helm-show-completion-overlay)))))
+ `(unwind-protect
+ (if helm-turn-on-show-completion
+ (let ((helm-move-selection-after-hook
+ (append (list 'helm-show-completion)
+ helm-move-selection-after-hook))
+ (helm-split-window-default-side
+ (if (eq helm-split-window-default-side 'same)
+ 'below helm-split-window-default-side))
+ helm-split-window-inside-p
+ helm-reuse-last-window-split-state)
+ (helm-set-local-variable
+ 'helm-display-function
+ (if helm-show-completion-use-special-display
+ 'helm-show-completion-display-function
+ 'helm-default-display-buffer))
+ (helm-show-completion-init-overlay ,beg ,end)
+ ,@body)
+ ,@body)
+ (when (and helm-show-completion-overlay
+ (overlayp helm-show-completion-overlay))
+ (delete-overlay helm-show-completion-overlay))))
;;; Lisp symbol completion.
diff --git a/helm-files.el b/helm-files.el
index b6c2adc8..0a2d70e2 100644
--- a/helm-files.el
+++ b/helm-files.el
@@ -575,7 +575,7 @@ Should not be used among other sources.")
(cl-loop for f in candidates
for ff = (helm-ff-filter-candidate-one-by-one f)
when ff collect ff))))
- (persistent-action :initform 'helm-find-files-persistent-action)
+ (persistent-action-if :initform 'helm-find-files-persistent-action-if)
(persistent-help :initform "Hit1 Expand Candidate, Hit2 or (C-u) Find file")
(help-message :initform 'helm-ff-help-message)
(mode-line :initform (list "File(s)" helm-mode-line-string))
@@ -2471,7 +2471,7 @@ Never kill `helm-current-buffer'.
Never kill buffer modified.
This is called normally on third hit of \
\\<helm-map>\\[helm-execute-persistent-action]
-in `helm-find-files-persistent-action'."
+in `helm-find-files-persistent-action-if'."
(let* ((buf (get-file-buffer candidate))
(buf-name (buffer-name buf))
(win (get-buffer-window buf))
@@ -2761,7 +2761,7 @@ This affect directly file CANDIDATE."
(format "No program %s found to extract exif"
helm-ff-exif-data-program)))
-(cl-defun helm-find-files-persistent-action (candidate)
+(cl-defun helm-find-files-persistent-action-if (candidate)
"Open subtree CANDIDATE without quitting helm.
If CANDIDATE is not a directory expand CANDIDATE filename.
If CANDIDATE is alone, open file CANDIDATE filename.
@@ -2785,66 +2785,77 @@ If a prefix arg is given or `helm-follow-mode' is on open file."
(unless image-cand
(when follow
(helm-follow-mode -1)
- (cl-return-from helm-find-files-persistent-action
+ (cl-return-from helm-find-files-persistent-action-if
(message "Helm-follow-mode allowed only on images, disabling"))))
(cond ((and (helm-ff--invalid-tramp-name-p)
(string-match helm-tramp-file-name-regexp candidate))
- ;; First hit insert hostname and
- ;; second hit insert ":" and expand.
- (if (string= candidate helm-pattern)
- (funcall insert-in-minibuffer (concat candidate ":"))
- (funcall insert-in-minibuffer candidate)))
+ (cons (lambda (_candidate)
+ ;; First hit insert hostname and
+ ;; second hit insert ":" and expand.
+ (if (string= candidate helm-pattern)
+ (funcall insert-in-minibuffer (concat candidate ":"))
+ (funcall insert-in-minibuffer candidate)))
+ 'never-split))
(;; A symlink directory, expand it but not to its truename
;; unless a prefix arg is given.
(and (file-directory-p candidate) (file-symlink-p candidate))
- (funcall insert-in-minibuffer
- (file-name-as-directory
- (if current-prefix-arg
- (file-truename (expand-file-name candidate))
- (expand-file-name candidate)))))
+ (cons (lambda (_candidate)
+ (funcall insert-in-minibuffer
+ (file-name-as-directory
+ (if current-prefix-arg
+ (file-truename (expand-file-name candidate))
+ (expand-file-name candidate)))))
+ 'never-split))
;; A directory, open it.
((file-directory-p candidate)
- (when (string= (helm-basename candidate) "..")
- (setq helm-ff-last-expanded helm-ff-default-directory))
- (funcall insert-in-minibuffer (file-name-as-directory
- (expand-file-name candidate))))
+ (cons (lambda (_candidate)
+ (when (string= (helm-basename candidate) "..")
+ (setq helm-ff-last-expanded helm-ff-default-directory))
+ (funcall insert-in-minibuffer (file-name-as-directory
+ (expand-file-name candidate))))
+ 'never-split))
;; A symlink file, expand to it's true name. (first hit)
((and (file-symlink-p candidate) (not current-prefix-arg) (not follow))
- (funcall insert-in-minibuffer (file-truename candidate)))
+ (cons (lambda (_candidate)
+ (funcall insert-in-minibuffer (file-truename candidate)))
+ 'never-split))
;; A regular file, expand it, (first hit)
((and (>= num-lines-buf 3) (not current-prefix-arg) (not follow))
- (setq helm-pattern "") ; Force update.
- (funcall insert-in-minibuffer new-pattern))
+ (cons (lambda (_candidate)
+ (setq helm-pattern "") ; Force update.
+ (funcall insert-in-minibuffer new-pattern))
+ 'never-split))
;; An image file and it is the second hit on C-j,
;; show the file in `image-dired'.
(image-cand
- (require 'image-dired)
- (let* ((win (get-buffer-window
- image-dired-display-image-buffer 'visible))
- (remove-buf-only
- (and win
- (with-helm-buffer
- (file-equal-p candidate
- (with-current-buffer
- image-dired-display-image-buffer
- (get-text-property
- (point-min)
- 'original-file-name)))))))
- (when remove-buf-only
- (set-window-buffer win helm-current-buffer))
- (when (buffer-live-p (get-buffer image-dired-display-image-buffer))
- (kill-buffer image-dired-display-image-buffer))
- (unless remove-buf-only
- ;; Fix emacs bug never fixed upstream.
- (unless (file-directory-p image-dired-dir)
- (make-directory image-dired-dir))
- (image-dired-display-image candidate)
- (message nil)
- (switch-to-buffer image-dired-display-image-buffer)
- (with-current-buffer image-dired-display-image-buffer
- (let ((exif-data (helm-ff-exif-data candidate)))
- (setq default-directory helm-ff-default-directory)
- (image-dired-update-property 'help-echo exif-data))))))
+ (lambda (_candidate)
+ (require 'image-dired)
+ (let* ((win (get-buffer-window
+ image-dired-display-image-buffer 'visible))
+ (remove-buf-only
+ (and win
+ (with-helm-buffer
+ (file-equal-p candidate
+ (with-current-buffer
+ image-dired-display-image-buffer
+ (get-text-property
+ (point-min)
+ 'original-file-name)))))))
+ (when remove-buf-only
+ (set-window-buffer win helm-current-buffer))
+ (when (buffer-live-p (get-buffer image-dired-display-image-buffer))
+ (kill-buffer image-dired-display-image-buffer))
+ (unless remove-buf-only
+ ;; Fix emacs bug never fixed upstream.
+ (unless (file-directory-p image-dired-dir)
+ (make-directory image-dired-dir))
+ (image-dired-display-image candidate)
+ (message nil)
+ (switch-to-buffer image-dired-display-image-buffer)
+ (with-current-buffer image-dired-display-image-buffer
+ (let ((exif-data (helm-ff-exif-data candidate)))
+ (setq default-directory helm-ff-default-directory)
+ (image-dired-update-property 'help-echo exif-data)))))))
;; Allow browsing archive on avfs fs.
;; Assume volume is already mounted with mountavfs.
((helm-aand helm-ff-avfs-directory
@@ -2853,7 +2864,9 @@ If a prefix arg is given or `helm-follow-mode' is on open file."
(regexp-quote (expand-file-name helm-ff-avfs-directory))
it)
(helm-ff-file-compressed-p candidate))
- (funcall insert-in-minibuffer (concat candidate "#")))
+ (cons (lambda (_candidate)
+ (funcall insert-in-minibuffer (concat candidate "#")))
+ 'never-split))
;; File doesn't exists and basename starts with ".." or " ",
;; Start a recursive search for directories.
((and (not (file-exists-p candidate))
@@ -2862,19 +2875,24 @@ If a prefix arg is given or `helm-follow-mode' is on open file."
(helm-basename candidate)))
;; As soon as the final "/" is added the job is passed
;; to `helm-ff-auto-expand-to-home-or-root'.
- (funcall insert-in-minibuffer (concat candidate "/")))
+ (cons (lambda (_candidate)
+ (funcall insert-in-minibuffer (concat candidate "/")))
+ 'never-split))
;; File is not existing and have no basedir, typically when
;; user hit C-k (minibuffer is empty) and then write foo and
;; hit C-j. This make clear that when no basedir, helm will
;; create the file in default-directory.
((and (not (file-exists-p candidate))
(not (helm-basedir candidate)))
- (funcall insert-in-minibuffer
- (expand-file-name candidate default-directory)))
+ (cons (lambda (_candidate)
+ (funcall insert-in-minibuffer
+ (expand-file-name candidate default-directory)))
+ 'never-split))
;; On second hit we open file.
;; On Third hit we kill it's buffer maybe.
(t
- (funcall helm-ff-kill-or-find-buffer-fname-fn candidate)))))
+ (lambda (_candidate)
+ (funcall helm-ff-kill-or-find-buffer-fname-fn candidate))))))
;;; Recursive dirs completion
@@ -2923,6 +2941,17 @@ If a prefix arg is given or `helm-follow-mode' is on open file."
(member (file-name-extension candidate)
helm-ff-file-compressed-list))
+(defun helm-ff--fname-at-point ()
+ "Try to guess fname at point."
+ (let ((end (point))
+ (limit (helm-aif (bounds-of-thing-at-point 'filename)
+ (car it)
+ (point))))
+ (save-excursion
+ (while (re-search-backward "\\(~\\|/\\|[[:lower:][:upper:]]:/\\)"
+ limit t))
+ (buffer-substring-no-properties (point) end))))
+
(defun helm-insert-file-name-completion-at-point (_candidate)
"Insert file name completion at point."
(with-helm-current-buffer
@@ -2931,9 +2960,10 @@ If a prefix arg is given or `helm-follow-mode' is on open file."
(let* ((mkds (helm-marked-candidates :with-wildcard t))
(candidate (car mkds))
(end (point))
- (tap (thing-at-point 'filename))
- (guess (and (stringp tap) (substring-no-properties tap)))
- (beg (- (point) (length guess)))
+ (tap (helm-ff--fname-at-point))
+ (guess (and (stringp tap)
+ (substring-no-properties tap)))
+ (beg (if guess (- (point) (length guess)) (point)))
(full-path-p (and (stringp guess)
(or (string-match-p
(concat "^" (getenv "HOME"))
diff --git a/helm-for-files.el b/helm-for-files.el
index 6c3a3550..53714052 100644
--- a/helm-for-files.el
+++ b/helm-for-files.el
@@ -127,7 +127,7 @@ this source is accessible and properly loaded."
'(("Delete file(s) from recentf" .
(lambda (_candidate)
(cl-loop for file in (helm-marked-candidates)
- do (setq recentf-list (delq file recentf-list)))))))))
+ do (setq recentf-list (delete file recentf-list)))))))))
(defvar helm-source-recentf nil
"See (info \"(emacs)File Conveniences\").
diff --git a/helm-help.el b/helm-help.el
index 10298da7..e5c94cbe 100644
--- a/helm-help.el
+++ b/helm-help.el
@@ -1475,10 +1475,16 @@ Helm-kill-ring session you can navigate to next/previous line with `M-y' and
It is possible to delete candidates from the kill ring.
-You can concatenate marked candidates and yank them in the current buffer, thus
-creating a new entry in the kill ring. See the commands below. Candidates are
-concatenated with a newline as separator. Alternatively, use
-`\\<helm-map>\\[helm-copy-to-buffer]' to not push a new entry in the kill ring.
+You can concatenate marked candidates and yank them in the current
+buffer, thus creating a new entry in the kill ring. Candidates are
+concatenated with `helm-kill-ring-separator' as default but you can
+change interactively the separator while yanking by using two prefix
+args. When you have something else than \"\\n\" as default value for
+`helm-kill-ring-separator' and you want to use \"\\n\" from prompt, use
+`C-q C-j' to enter a newline in prompt.
+
+To not push a new entry in the kill ring, use `\\<helm-map>\\[helm-copy-to-buffer]' instead of RET
+\(note that you can't change separator with this).
When inserting candidates with the default action (`RET'), `point' is placed at
the end of the candidate and `mark' at the beginning. You can revert this behavior
@@ -1489,7 +1495,6 @@ by using a prefix argument, i.e. `C-u RET', like the regular `yank' command does
\\[helm-next-line]\t\tNext line.
\\[helm-previous-line]\t\tPrevious line.
\\[helm-kill-ring-delete]\t\tDelete entry.
-\\[helm-kill-ring-run-append]\t\tYank concatenated marked candidates.
\\[helm-kill-ring-toggle-truncated]\t\tToggle truncated view of candidate.
\\[helm-kill-ring-kill-selection]\t\tKill non-truncated of selection.")
diff --git a/helm-mode.el b/helm-mode.el
index 1b79c82b..214d073a 100644
--- a/helm-mode.el
+++ b/helm-mode.el
@@ -261,14 +261,16 @@ If COLLECTION is an `obarray', a TEST should be needed. See `obarray'."
;; Normally file completion should not be handled here,
;; but special cases like `find-file-at-point' do it.
;; Handle here specially such cases.
- ((and (functionp collection) minibuffer-completing-file-name)
+ ((and (functionp collection) (not (string= input ""))
+ minibuffer-completing-file-name)
(cl-loop for f in (funcall collection input test t)
unless (member f '("./" "../"))
if (string-match helm--url-regexp input)
collect f
else
collect (concat (file-name-as-directory
- (helm-basedir input)) f)))
+ (helm-basedir input))
+ f)))
((functionp collection)
(funcall collection input test t))
((and alistp (null test)) collection)
@@ -858,7 +860,7 @@ See documentation of `completing-read' and `all-completions' for details."
(candidate-number-limit helm-ff-candidate-number-limit)
nomark
(alistp t)
- (persistent-action 'helm-find-files-persistent-action)
+ (persistent-action-if 'helm-find-files-persistent-action-if)
(persistent-help "Hit1 Expand Candidate, Hit2 or (C-u) Find file")
(mode-line helm-read-file-name-mode-line-string))
"Read a file name with helm completion.
@@ -892,7 +894,7 @@ Keys description:
- ALISTP: Don't use `all-completions' in history (take effect only on history).
-- PERSISTENT-ACTION: a persistent action function.
+- PERSISTENT-ACTION-IF: a persistent if action function.
- PERSISTENT-HELP: persistent help message.
@@ -918,7 +920,6 @@ Keys description:
(helm-ff-auto-update-initial-value
(and helm-ff-auto-update-initial-value
(not (minibuffer-window-active-p (minibuffer-window)))))
- helm-full-frame
helm-follow-mode-persistent
(helm-ff-fuzzy-matching
(and fuzzy
@@ -956,7 +957,7 @@ Keys description:
:candidates hist
:nohighlight t
:fuzzy-match fuzzy
- :persistent-action persistent-action
+ :persistent-action-if persistent-action-if
:persistent-help persistent-help
:keymap cmap
:nomark nomark
@@ -988,7 +989,7 @@ Keys description:
(helm-find-files-get-candidates must-match))))
:filtered-candidate-transformer 'helm-ff-sort-candidates
:filter-one-by-one 'helm-ff-filter-candidate-one-by-one
- :persistent-action persistent-action
+ :persistent-action-if persistent-action-if
:persistent-help persistent-help
:volatile t
:keymap cmap
@@ -1006,6 +1007,7 @@ Keys description:
:case-fold-search case-fold
:default default
:buffer buffer
+ :full-frame nil
:preselect preselect)))
(or
(cond ((and result (stringp result)
@@ -1017,7 +1019,9 @@ Keys description:
(if (listp default) (car default) default))
((and result (listp result))
(mapcar #'expand-file-name result))
- (t result))
+ ((and result (file-directory-p result))
+ (file-name-as-directory (expand-file-name result)))
+ (result (expand-file-name result)))
(helm-mode--keyboard-quit))))
(defun helm-mode--default-filename (fname dir initial)
diff --git a/helm-pkg.el b/helm-pkg.el
index 650086f7..092a8609 100644
--- a/helm-pkg.el
+++ b/helm-pkg.el
@@ -1,11 +1,11 @@
;;; helm-pkg.el --- define helm for package.el
-(define-package "helm" "2.8.6"
+(define-package "helm" "2.8.7"
"Helm is an Emacs incremental and narrowing framework"
'((emacs "24.4")
(async "1.9.2")
(popup "0.5.3")
- (helm-core "2.8.6"))
+ (helm-core "2.8.7"))
:url "https://emacs-helm.github.io/helm/")
;; Local Variables:
diff --git a/helm-ring.el b/helm-ring.el
index 79d2c017..bb8a9c10 100644
--- a/helm-ring.el
+++ b/helm-ring.el
@@ -46,19 +46,22 @@ will not have anymore separators between candidates."
(integer :tag "Max candidate offset"))
:group 'helm-ring)
-(defcustom helm-register-max-offset 160
- "Max size of string register entries before truncating."
- :group 'helm-ring
- :type 'integer)
-
(defcustom helm-kill-ring-actions
- '(("Yank" . helm-kill-ring-action-yank)
- ("Delete" . helm-kill-ring-action-delete)
- ("Append" . helm-kill-ring-append))
+ '(("Yank marked" . helm-kill-ring-action-yank)
+ ("Delete marked" . helm-kill-ring-action-delete))
"List of actions for kill ring source."
:group 'helm-ring
:type '(alist :key-type string :value-type function))
+(defcustom helm-kill-ring-separator "\n"
+ "The separator used to separate marked candidates when yanking."
+ :group 'helm-ring
+ :type 'string)
+
+(defcustom helm-register-max-offset 160
+ "Max size of string register entries before truncating."
+ :group 'helm-ring
+ :type 'integer)
;;; Kill ring
;;
@@ -69,7 +72,6 @@ will not have anymore separators between candidates."
(define-key map (kbd "M-y") 'helm-next-line)
(define-key map (kbd "M-u") 'helm-previous-line)
(define-key map (kbd "M-D") 'helm-kill-ring-delete)
- (define-key map (kbd "C-M-w") 'helm-kill-ring-run-append)
(define-key map (kbd "C-]") 'helm-kill-ring-toggle-truncated)
(define-key map (kbd "C-c C-k") 'helm-kill-ring-kill-selection)
map)
@@ -140,60 +142,70 @@ Same as `helm-kill-selection-and-quit' called with a prefix arg."
(cl-return)
(helm-next-line))))
-(defun helm-kill-ring-action-yank (str)
+(defun helm-kill-ring-action-yank (_str)
+ "Insert concatenated marked candidates in current-buffer.
+
+When two prefix args are given prompt to choose separator, otherwise
+use `helm-kill-ring-separator' as default."
+ (let ((marked (helm-marked-candidates))
+ (sep (if (equal helm-current-prefix-arg '(16))
+ (read-string "Separator: ")
+ helm-kill-ring-separator)))
+ (helm-kill-ring-action-yank-1
+ (cl-loop for c in (butlast marked)
+ concat (concat c sep) into str
+ finally return (concat str (car (last marked)))))))
+
+(defun helm-kill-ring-action-yank-1 (str)
"Insert STR in `kill-ring' and set STR to the head.
When called with a prefix arg, point and mark are exchanged without
activating region.
If this action is executed just after `yank',
replace with STR as yanked string."
- (with-helm-current-buffer
- (unwind-protect
- (progn
- (setq kill-ring (delete str kill-ring))
- ;; Adding a `delete-selection' property
- ;; to `helm-kill-ring-action' is not working
- ;; because `this-command' will be `helm-maybe-exit-minibuffer',
- ;; so use this workaround (Issue #1520).
- (when (and (region-active-p) delete-selection-mode)
- (delete-region (region-beginning) (region-end)))
- (if (not (eq (helm-attr 'last-command helm-source-kill-ring) 'yank))
- (progn
- ;; Ensure mark is at beginning of inserted text.
- (push-mark)
- ;; When yanking in a helm minibuffer we need a small
- ;; delay to detect the mark in previous minibuffer. [1]
- (run-with-timer
- 0.01 nil
- (lambda ()
- (insert-for-yank str)
- (when helm-current-prefix-arg
- ;; Same as exchange-point-and-mark but without
- ;; activating region.
- (goto-char (prog1 (mark t)
- (set-marker (mark-marker)
- (point)
- helm-current-buffer)))))))
+ (let ((yank-fn (lambda (&optional before yank-pop)
+ (insert-for-yank str)
+ ;; Set the window start back where it was in
+ ;; the yank command, if possible.
+ (when yank-pop
+ (set-window-start (selected-window) yank-window-start t))
+ (when (or (equal helm-current-prefix-arg '(4)) before)
+ ;; Same as exchange-point-and-mark but without
+ ;; activating region.
+ (goto-char (prog1 (mark t)
+ (set-marker (mark-marker)
+ (point)
+ helm-current-buffer)))))))
+ (with-helm-current-buffer
+ (unwind-protect
+ (progn
+ (setq kill-ring (delete str kill-ring))
+ ;; Adding a `delete-selection' property
+ ;; to `helm-kill-ring-action' is not working
+ ;; because `this-command' will be `helm-maybe-exit-minibuffer',
+ ;; so use this workaround (Issue #1520).
+ (when (and (region-active-p) delete-selection-mode)
+ (delete-region (region-beginning) (region-end)))
+ (if (not (eq (helm-attr 'last-command helm-source-kill-ring) 'yank))
+ (progn
+ ;; Ensure mark is at beginning of inserted text.
+ (push-mark)
+ ;; When yanking in a helm minibuffer we need a small
+ ;; delay to detect the mark in previous minibuffer. [1]
+ (run-with-timer 0.01 nil yank-fn))
;; from `yank-pop'
(let ((inhibit-read-only t)
(before (< (point) (mark t))))
(if before
(funcall (or yank-undo-function 'delete-region) (point) (mark t))
- (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
+ (funcall (or yank-undo-function 'delete-region) (mark t) (point)))
(setq yank-undo-function nil)
(set-marker (mark-marker) (point) helm-current-buffer)
- ;; Same as [1]
- (run-with-timer 0.01 nil (lambda () (insert-for-yank str)))
- ;; Set the window start back where it was in the yank command,
- ;; if possible.
- (set-window-start (selected-window) yank-window-start t)
- (when before
- ;; This is like exchange-point-and-mark, but doesn't activate the mark.
- ;; It is cleaner to avoid activation, even though the command
- ;; loop would deactivate the mark because we inserted text.
- (goto-char (prog1 (mark t)
- (set-marker (mark-marker) (point) helm-current-buffer)))))))
- (kill-new str))))
+ ;; Same as [1] but use the same mark and point as in
+ ;; the initial yank according to BEFORE even if no
+ ;; prefix arg is given.
+ (run-with-timer 0.01 nil yank-fn before 'pop))))
+ (kill-new str)))))
(define-obsolete-function-alias 'helm-kill-ring-action 'helm-kill-ring-action-yank "2.4.0")
(defun helm-kill-ring-action-delete (_candidate)
@@ -210,19 +222,6 @@ This is a command for `helm-kill-ring-map'."
(with-helm-alive-p
(helm-exit-and-execute-action 'helm-kill-ring-action-delete)))
-(defun helm-kill-ring-append (_candidate)
- "Yank concatenated marked candidates."
- (let ((marked (helm-marked-candidates)))
- (helm-kill-ring-action-yank
- (cl-loop for cand in marked
- for sep = (if (string-match "\n\\'" cand) "" "\n")
- concat (concat cand sep)))))
-
-(defun helm-kill-ring-run-append ()
- "Yank concatenated marked candidates."
- (interactive)
- (with-helm-alive-p
- (helm-exit-and-execute-action 'helm-kill-ring-append)))
;;;; <Mark ring>
;; DO NOT use these sources with other sources use
@@ -481,34 +480,57 @@ Define your macros with `f3' and `f4'.
See (info \"(emacs) Keyboard Macros\") for detailed infos.
This command is useful when used with persistent action."
(interactive)
- (helm :sources
- (helm-build-sync-source "Kmacro"
- :candidates (lambda ()
- (helm-fast-remove-dups
- (cons (kmacro-ring-head)
- kmacro-ring)
- :test 'equal))
- :multiline t
- :candidate-transformer
- (lambda (candidates)
- (cl-loop for c in candidates collect
- (propertize (help-key-description (car c) nil)
- 'helm-realvalue c)))
- :persistent-help "Execute kmacro"
- :help-message 'helm-kmacro-help-message
- :action
- (helm-make-actions
- "Execute kmacro (`C-u <n>' to execute <n> times)"
- (lambda (candidate)
- (interactive)
- ;; Move candidate on top of list for next use.
- (setq kmacro-ring (delete candidate kmacro-ring))
- (kmacro-push-ring)
- (kmacro-split-ring-element candidate)
- (kmacro-exec-ring-item
- candidate helm-current-prefix-arg)))
- :group 'helm-ring)
- :buffer "*helm kmacro*"))
+ (let ((helm-quit-if-no-candidate
+ (lambda () (message "No kbd macro has been defined"))))
+ (helm :sources
+ (helm-build-sync-source "Kmacro"
+ :candidates (lambda ()
+ (helm-fast-remove-dups
+ (cons (kmacro-ring-head)
+ kmacro-ring)
+ :test 'equal))
+ :multiline t
+ :candidate-transformer
+ (lambda (candidates)
+ (cl-loop for c in candidates collect
+ (propertize (help-key-description (car c) nil)
+ 'helm-realvalue c)))
+ :persistent-help "Execute kmacro"
+ :help-message 'helm-kmacro-help-message
+ :action
+ (helm-make-actions
+ "Execute kmacro (`C-u <n>' to execute <n> times)"
+ 'helm-kbd-macro-execute
+ "Concat marked macros"
+ 'helm-kbd-macro-concat-macros
+ "Delete marked macros"
+ 'helm-kbd-macro-delete-macro)
+ :group 'helm-ring)
+ :buffer "*helm kmacro*")))
+
+(defun helm-kbd-macro-execute (candidate)
+ ;; Move candidate on top of list for next use.
+ (setq kmacro-ring (delete candidate kmacro-ring))
+ (kmacro-push-ring)
+ (kmacro-split-ring-element candidate)
+ (kmacro-exec-ring-item
+ candidate helm-current-prefix-arg))
+
+(defun helm-kbd-macro-concat-macros (_candidate)
+ (let ((mkd (helm-marked-candidates)))
+ (when (cdr mkd)
+ (kmacro-push-ring)
+ (setq last-kbd-macro
+ (mapconcat 'identity
+ (cl-loop for km in mkd
+ collect (car km))
+ "")))))
+
+(defun helm-kbd-macro-delete-macro (_candidate)
+ (let ((mkd (helm-marked-candidates)))
+ (cl-loop for km in mkd
+ do (setq kmacro-ring (delete km kmacro-ring)))
+ (kmacro-pop-ring1)))
(provide 'helm-ring)
diff --git a/helm-source.el b/helm-source.el
index da6a804a..9ceeba6f 100644
--- a/helm-source.el
+++ b/helm-source.el
@@ -157,8 +157,63 @@
" Can be a either a Function called with one parameter (the
selected candidate) or a cons cell where first element is this
same function and second element a symbol (e.g never-split)
- that inform `helm-execute-persistent-action'to not split his
- window to execute this persistent action.")
+ that inform `helm-execute-persistent-action' to not split his
+ window to execute this persistent action.
+ Example:
+
+ (defun foo-persistent-action (candidate)
+ (do-something candidate))
+
+ :persistent-action '(foo-persistent-action . never-split) ; Don't split
+ or
+ :persistent-action 'foo-persistent-action ; Split
+
+ When specifying :persistent-action by slot directly, foo-persistent-action
+ will be executed without quitting helm when hitting `C-j'.
+
+ Note that other persistent actions can be defined using other
+ bindings than `C-j' by simply defining an interactive function bound
+ to a key in the keymap source.
+ The function should create a new attribute in source before calling
+ `helm-execute-persistent-action' on this attribute.
+ Example:
+
+ (defun helm-ff-persistent-delete ()
+ \"Delete current candidate without quitting.\"
+ (interactive)
+ (with-helm-alive-p
+ (helm-attrset 'quick-delete '(helm-ff-quick-delete . never-split))
+ (helm-execute-persistent-action 'quick-delete)))
+
+ This function is then bound in `helm-find-files-map'.")
+
+ (persistent-action-if
+ :initarg :persistent-action-if
+ :initform nil
+ :custom function
+ :documentation
+ " Similar from persistent action but it is a function that should
+ return an object suitable for persistent action when called , i.e. a
+ function or a cons cell.
+ Example:
+
+ (defun foo-persistent-action (candidate)
+ (cond (something
+ ;; Don't split helm-window.
+ (cons (lambda (_ignore)
+ (do-something candidate))
+ 'no-split))
+ ;; Split helm-window.
+ (something-else
+ (lambda (_ignore)
+ (do-something-else candidate)))))
+
+ :persistent-action-if 'foo-persistent-action
+
+ Here when hitting `C-j' one of the lambda's will be executed
+ depending on something or something-else condition, splitting or not
+ splitting as needed.
+ See `helm-find-files-persistent-action-if' definition as another example.")
(persistent-help
:initarg :persistent-help
diff --git a/helm-tags.el b/helm-tags.el
index f374fccc..9111d5b7 100644
--- a/helm-tags.el
+++ b/helm-tags.el
@@ -261,6 +261,7 @@ If no entry in cache, create one."
(defun helm-etags-action-goto (switcher candidate)
"Helm default action to jump to an etags entry in other window."
(require 'etags)
+ (deactivate-mark t)
(helm-log-run-hook 'helm-goto-line-before-hook)
(let* ((split (helm-grep-split-line candidate))
(fname (cl-loop for tagf being the hash-keys of helm-etags-cache
@@ -310,13 +311,7 @@ This function aggregates three sources of tag files:
(str (if (region-active-p)
(buffer-substring-no-properties
(region-beginning) (region-end))
- ;; Use a raw syntax-table to determine tap.
- ;; This may be wrong when calling etags
- ;; with hff from a buffer that use
- ;; a different syntax, but most of the time it
- ;; should be better.
- (with-syntax-table (standard-syntax-table)
- (thing-at-point 'symbol)))))
+ (thing-at-point 'symbol))))
(if (cl-notany 'file-exists-p tag-files)
(message "Error: No tag file found.\
Create with etags shell command, or visit with `find-tag' or `visit-tags-table'.")
diff --git a/helm-utils.el b/helm-utils.el
index ea99cb91..5d202c85 100644
--- a/helm-utils.el
+++ b/helm-utils.el
@@ -404,12 +404,17 @@ Default is `helm-current-buffer'."
(defun helm-goto-char (loc)
"Go to char, revealing if necessary."
+ (require 'org) ; On some old Emacs versions org may not be loaded.
(goto-char loc)
- (when (or (eq major-mode 'org-mode)
- (and (boundp 'outline-minor-mode)
- outline-minor-mode))
- (require 'org) ; On some old Emacs versions org may not be loaded.
- (org-reveal)))
+ (let ((fn (cond ((eq major-mode 'org-mode) #'org-reveal)
+ ((and (boundp 'outline-minor-mode)
+ outline-minor-mode)
+ #'outline-show-subtree))))
+ ;; outline may fail in some conditions e.g. with markdown enabled
+ ;; (issue #1919).
+ (condition-case nil
+ (and fn (funcall fn))
+ (error nil))))
(defun helm-goto-line (lineno &optional noanim)
"Goto LINENO opening only outline headline if needed.
diff --git a/helm.el b/helm.el
index 82f2ae3a..f67be8f5 100644
--- a/helm.el
+++ b/helm.el
@@ -224,6 +224,7 @@ vectors, so don't use strings to define them."
(define-key map (kbd "C-}") 'helm-narrow-window)
(define-key map (kbd "C-{") 'helm-enlarge-window)
(define-key map (kbd "C-c -") 'helm-swap-windows)
+ (define-key map (kbd "C-c _") 'helm-toggle-full-frame)
(define-key map (kbd "C-c C-y") 'helm-yank-selection)
(define-key map (kbd "C-c C-k") 'helm-kill-selection-and-quit)
(define-key map (kbd "C-c C-i") 'helm-copy-to-buffer)
@@ -1060,10 +1061,17 @@ current selected candidate only. (See bindings below.) Most Helm actions
operate on marked candidates unless candidate-marking is explicitely forbidden
for a specific source.
-To mark/unmark a candidate, use \\[helm-toggle-visible-mark]. (See bindings below.)
-To mark all visible unmarked candidates at once in current source use \\[helm-mark-all].
-To mark/unmark all candidates at once use \\[helm-toggle-all-marks].
-With a prefix argument, those bindings let you mark candidates in all sources.
+- To mark/unmark a candidate, use \\[helm-toggle-visible-mark]. (See bindings below.)
+With a numeric prefix arg mark ARG candidates forward, if ARG is negative
+mark ARG candidates backward.
+
+- To mark all visible unmarked candidates at once in current source use \\[helm-mark-all].
+With a prefix argument, mark all candidates in all sources.
+
+- To unmark all visible marked candidates at once use \\[helm-unmark-all].
+
+- To mark/unmark all candidates at once use \\[helm-toggle-all-marks].
+With a prefix argument, mark/unmark all candidates in all sources.
Note: When multiple candidates are selected across different sources, only the
candidates of the current source will be used when executing most actions (as
@@ -1133,7 +1141,7 @@ this command will greatly improve `helm' interactivity, e.g. when quitting Helm
accidentally.
You can call \\<global-map>\\[helm-resume] with a prefix argument to choose
-(with completion!) which session you'd like to resume. You can also cycle in
+\(with completion!) which session you'd like to resume. You can also cycle in
these sources with `helm-cycle-resume' (see above).
** Debugging Helm
@@ -2363,6 +2371,9 @@ Don't use this directly, use instead `helm' with the keyword
(orig-helm-last-frame-or-window-configuration
helm-last-frame-or-window-configuration)
(orig-one-window-p helm-onewindow-p))
+ ;; FIXME Using helm-full-frame here allow showing the new
+ ;; helm-buffer in the same window as old helm-buffer, why?
+ (helm-set-local-variable 'helm-full-frame t)
(unwind-protect
(let (helm-current-position
helm-current-buffer
@@ -2372,12 +2383,12 @@ Don't use this directly, use instead `helm' with the keyword
"*Helm*"))
helm-sources
helm-compiled-sources
- (helm-full-frame t)
(enable-recursive-minibuffers t))
(apply #'helm same-as-helm))
(with-current-buffer orig-helm-buffer
(setq helm-alive-p t) ; Nested session set this to nil on exit.
(setq helm-buffer orig-helm-buffer)
+ (setq helm-full-frame nil)
(setq helm--prompt orig-helm--prompt)
(setq helm--in-fuzzy orig-helm--in-fuzzy)
(helm-initialize-overlays helm-buffer)
@@ -3879,6 +3890,8 @@ respectively `helm-cand-num' and `helm-cur-source'."
(not (zerop (length dispvalue))))
(funcall insert-function dispvalue)
(setq end (point-at-eol))
+ ;; Some strings may handle another keymap prop.
+ (remove-text-properties start end '(keymap nil))
(put-text-property start end 'read-only nil)
;; Some sources with candidates-in-buffer have already added
;; 'helm-realvalue property when creating candidate buffer.
@@ -3886,10 +3899,7 @@ respectively `helm-cand-num' and `helm-cur-source'."
(and realvalue
(put-text-property start end
'helm-realvalue realvalue)))
- (when (and map
- ;; Don't overwrite mouse properties when
- ;; redisplaying.
- (not (get-text-property start 'keymap)))
+ (when map
(define-key map [mouse-1] 'helm-mouse-select-candidate)
(define-key map [mouse-2] 'ignore)
(define-key map [mouse-3] 'helm-select-action)
@@ -3897,9 +3907,10 @@ respectively `helm-cand-num' and `helm-cur-source'."
start end
`(mouse-face highlight
keymap ,map
- help-echo ,(helm-aif (get-text-property start 'help-echo)
- (concat it "\nmouse-1: select candidate\nmouse-3: menu actions")
- "mouse-1: select candidate\nmouse-3: menu actions"))))
+ help-echo ,(pcase (get-text-property start 'help-echo)
+ ((and it (pred stringp))
+ (concat it "\nmouse-1: select candidate\nmouse-3: menu actions"))
+ (_ "mouse-1: select candidate\nmouse-3: menu actions")))))
(when num
(put-text-property start end 'helm-cand-num num))
(when source
@@ -3911,7 +3922,7 @@ respectively `helm-cand-num' and `helm-cur-source'."
(start (overlay-start helm-selection-overlay))
(end (overlay-end helm-selection-overlay))
(help-echo (get-text-property start 'help-echo)))
- (when (and help-echo
+ (when (and (stringp help-echo)
(string-match "mouse-2: execute action" help-echo))
(put-text-property
start end
@@ -3927,9 +3938,10 @@ respectively `helm-cand-num' and `helm-cur-source'."
helm-selection-point
(overlay-end helm-selection-overlay)
'help-echo (helm-aif (get-text-property pos 'help-echo)
- (if (string-match "mouse-1: select candidate" it)
+ (if (and (stringp it)
+ (string-match "mouse-1: select candidate" it))
(replace-match "mouse-2: execute action" t t it)
- "mouse-2: execute action\nmouse-3: menu actions")
+ "mouse-2: execute action\nmouse-3: menu actions")
"mouse-2: execute action\nmouse-3: menu actions")))))
(defun helm-mouse-select-candidate (event)
@@ -5457,6 +5469,26 @@ If N is positive enlarge, if negative narrow."
(helm-enlarge-window-1 1)))
(put 'helm-enlarge-window 'helm-only t)
+(defun helm-toggle-full-frame ()
+ "Toggle helm-buffer full-frame view."
+ (interactive)
+ (cl-assert (null (helm-action-window)) nil "Unable to toggle full frame from action window")
+ (if (or helm-onewindow-p
+ (buffer-local-value 'helm-full-frame (get-buffer helm-buffer)))
+ (with-helm-window
+ (setq-local helm-full-frame nil)
+ (setq helm-onewindow-p nil)
+ (let ((split-window-preferred-function
+ helm-split-window-preferred-function))
+ (switch-to-buffer helm-current-buffer)
+ (helm-display-buffer helm-buffer)
+ (select-window (minibuffer-window))))
+ (with-helm-window
+ (delete-other-windows)
+ (setq-local helm-full-frame t)
+ (setq helm-onewindow-p t))))
+(put 'helm-toggle-full-frame 'helm-only t)
+
(defun helm-swap-windows ()
"Swap window holding `helm-buffer' with other window."
(interactive)
@@ -5562,11 +5594,14 @@ Possible values are 'left 'right 'below or 'above."
(defun helm-initialize-persistent-action ()
(set (make-local-variable 'helm-persistent-action-display-window) nil))
-(cl-defun helm-execute-persistent-action
- (&optional (attr 'persistent-action) split-onewindow)
+(cl-defun helm-execute-persistent-action (&optional attr split-onewindow)
"Perform the associated action ATTR without quitting helm.
-ATTR default is 'persistent-action', but it can be anything else.
+Arg ATTR default will be `persistent-action' or `persistent-action-if'
+if unspecified depending on what's found in source, but it can be
+anything else.
In this case you have to add this new attribute to your source.
+See `persistent-action' and `persistent-action-if' slot documentation
+in `helm-source'.
When `helm-full-frame' or SPLIT-ONEWINDOW are non-`nil', and
`helm-buffer' is displayed in only one window, the helm window is
@@ -5574,51 +5609,58 @@ split to display `helm-select-persistent-action-window' in other
window to maintain visibility."
(interactive)
(with-helm-alive-p
- (helm-log "executing persistent-action")
- (let* ((source (helm-get-current-source))
- (selection (and source (helm-get-selection nil nil source)))
- (attr-val (assoc-default attr source))
- ;; If attr value is a cons, use its car as persistent function
- ;; and its car to decide if helm window should be splitted.
- (fn (if (and (consp attr-val)
- ;; maybe a lambda.
- (not (functionp attr-val)))
- (car attr-val) attr-val))
- (no-split (and (consp attr-val)
- (not (functionp attr-val))
- (cdr attr-val)))
- (cursor-in-echo-area t)
- mode-line-in-non-selected-windows)
- (when (eq fn 'ignore)
- (cl-return-from helm-execute-persistent-action nil))
- (when source
- (with-helm-window
- (save-selected-window
- (if no-split
- (helm-select-persistent-action-window)
+ (let ((source (helm-get-current-source)))
+ (unless attr
+ (setq attr (or (car (assq 'persistent-action source))
+ (car (assq 'persistent-action-if source)))))
+ (helm-log "executing persistent-action")
+ (let* ((selection (and source (helm-get-selection nil nil source)))
+ (attr-val (if (eq attr 'persistent-action-if)
+ (funcall (assoc-default attr source) selection)
+ (assoc-default attr source)))
+ ;; If attr value is a cons, use its car as persistent function
+ ;; and its car to decide if helm window should be splitted.
+ (fn (if (and (consp attr-val)
+ ;; maybe a lambda.
+ (not (functionp attr-val)))
+ (car attr-val) attr-val))
+ (no-split (and (consp attr-val)
+ (not (functionp attr-val))
+ (cdr attr-val)))
+ (cursor-in-echo-area t)
+ mode-line-in-non-selected-windows)
+ (when (and helm-onewindow-p (null no-split))
+ (helm-toggle-full-frame))
+ (when (eq fn 'ignore)
+ (cl-return-from helm-execute-persistent-action nil))
+ (when source
+ (with-helm-window
+ (save-selected-window
+ (if no-split
+ (helm-select-persistent-action-window)
(helm-select-persistent-action-window
(or split-onewindow helm-onewindow-p)))
- (helm-log "current-buffer = %S" (current-buffer))
- (let ((helm-in-persistent-action t)
- (same-window-regexps '("."))
- display-buffer-function pop-up-windows pop-up-frames
- special-display-regexps special-display-buffer-names)
- (helm-execute-selection-action-1
- selection (or fn (helm-get-actions-from-current-source source)) t)
- (unless (helm-action-window)
- (helm-log-run-hook 'helm-after-persistent-action-hook)))
- ;; A typical case is when a persistent action delete
- ;; the buffer already displayed in
- ;; `helm-persistent-action-display-window' and `helm-full-frame'
- ;; is enabled, we end up with the `helm-buffer'
- ;; displayed in two windows.
- (when (and helm-onewindow-p
- (> (length (window-list)) 1)
- (equal (buffer-name
- (window-buffer
- helm-persistent-action-display-window))
- (helm-buffer-get)))
- (delete-other-windows))))))))
+ (helm-log "current-buffer = %S" (current-buffer))
+ (let ((helm-in-persistent-action t)
+ (same-window-regexps '("."))
+ display-buffer-function pop-up-windows pop-up-frames
+ special-display-regexps special-display-buffer-names)
+ (helm-execute-selection-action-1
+ selection (or fn (helm-get-actions-from-current-source source)) t)
+ (unless (helm-action-window)
+ (helm-log-run-hook 'helm-after-persistent-action-hook)))
+ ;; A typical case is when a persistent action delete
+ ;; the buffer already displayed in
+ ;; `helm-persistent-action-display-window' and `helm-full-frame'
+ ;; is enabled, we end up with the `helm-buffer'
+ ;; displayed in two windows.
+ (when (and helm-onewindow-p
+ (> (length (window-list)) 1)
+ (equal (buffer-name
+ (window-buffer
+ helm-persistent-action-display-window))
+ (helm-buffer-get)))
+ (delete-other-windows)))))))))
(put 'helm-execute-persistent-action 'helm-only t)
(defun helm-persistent-action-display-window (&optional split-onewindow)
@@ -5730,20 +5772,29 @@ Meaning of prefix ARG is the same as in `reposition-window'."
(cl-pushnew o helm-visible-mark-overlays)
(push (cons source sel) helm-marked-candidates)))
-(defun helm-toggle-visible-mark ()
- "Toggle helm visible mark at point."
- (interactive)
+(defun helm-toggle-visible-mark (arg)
+ "Toggle helm visible mark at point ARG times.
+If ARG is negative toggle backward."
+ (interactive "p")
(with-helm-alive-p
(with-helm-window
- (let ((nomark (assq 'nomark (helm-get-current-source))))
+ (let ((nomark (assq 'nomark (helm-get-current-source)))
+ (next-fns (if (< arg 0)
+ '(helm-beginning-of-source-p . helm-previous-line)
+ '(helm-end-of-source-p . helm-next-line))))
(if nomark
(message "Marking not allowed in this source")
- (helm-aif (helm-this-visible-mark)
- (helm-delete-visible-mark it)
- (helm-make-visible-mark))
- (if (helm-end-of-source-p)
- (helm-display-mode-line (helm-get-current-source))
- (helm-next-line)))))))
+ (cl-loop with n = (if (< arg 0) (* arg -1) arg)
+ repeat n do
+ (progn
+ (helm-aif (helm-this-visible-mark)
+ (helm-delete-visible-mark it)
+ (helm-make-visible-mark))
+ (if (funcall (car next-fns))
+ (progn
+ (helm-display-mode-line (helm-get-current-source))
+ (cl-return nil))
+ (funcall (cdr next-fns))))))))))
(put 'helm-toggle-visible-mark 'helm-only t)
(defun helm-file-completion-source-p (&optional source)