summaryrefslogtreecommitdiff
path: root/helm.el
diff options
context:
space:
mode:
Diffstat (limited to 'helm.el')
-rw-r--r--helm.el603
1 files changed, 341 insertions, 262 deletions
diff --git a/helm.el b/helm.el
index 1d4dbf9c..3241ec02 100644
--- a/helm.el
+++ b/helm.el
@@ -5,7 +5,7 @@
;; Copyright (C) 2007 Tamas Patrovics
;; 2008 ~ 2011 rubikitch <rubikitch@ruby-lang.org>
-;; 2011 ~ 2019 Thierry Volpiatto <thierry.volpiatto@gmail.com>
+;; 2011 ~ 2020 Thierry Volpiatto <thierry.volpiatto@gmail.com>
;; This is a fork of anything.el wrote by Tamas Patrovics.
@@ -251,7 +251,7 @@ and vectors, so don't use strings to define them."
(define-key map (kbd "C-c %") 'helm-exchange-minibuffer-and-header-line)
(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)
+ (define-key map (kbd "C-c C-i") 'helm-insert-or-copy)
(define-key map (kbd "C-c C-f") 'helm-follow-mode)
(define-key map (kbd "C-c C-u") 'helm-refresh)
(define-key map (kbd "C-c >") 'helm-toggle-truncate-line)
@@ -306,7 +306,7 @@ and vectors, so don't use strings to define them."
Default to Helm group when group is not defined in source."
(interactive)
- (helm-run-after-exit 'helm-customize-group-1 (helm-attr 'group)))
+ (helm-run-after-exit 'helm-customize-group-1 (helm-get-attr 'group)))
(put 'helm-customize-group 'helm-only t)
(defun helm--action-at-nth-set-fn-1 (value &optional negative)
@@ -887,6 +887,11 @@ You can toggle later `truncate-lines' with
\\<helm-map>\\[helm-toggle-truncate-line]."
:group 'helm
:type 'boolean)
+
+(defcustom helm-visible-mark-prefix "*"
+ "Prefix used in margin for marked candidates."
+ :group 'helm
+ :type 'string)
;;; Faces
;;
@@ -1019,6 +1024,11 @@ You can toggle later `truncate-lines' with
"Face for empty line at end of sources in the Helm buffer.
Allow specifying the height of this line."
:group 'helm-faces)
+
+(defface helm-mark-prefix
+ `((t :inherit default))
+ "Face for string `helm-visible-mark-prefix'."
+ :group 'helm-faces)
;;; Variables.
;;
@@ -1089,7 +1099,8 @@ minibuffer abnormally (e.g. via `helm-keyboard-quit').")
"Runs after pre-selection in `helm-buffer'.")
(defvar helm-window-configuration-hook nil
- "Runs when switching to and from the action buffer.")
+ "Runs when switching to and from the action buffer.
+Should run also at end of `helm-display-function'.")
(defvar helm-execute-action-at-once-if-one nil
"When non-nil execute the default action and then exit if only one candidate.
@@ -1191,8 +1202,8 @@ wiki]] for more infos.
You will find in Helm sources already built and bound to a
variable called generally `helm-source-<something>'. In this case
it is an alist and you can change the attributes (keys) values
-using `helm-attrset' function in your configuration. Of course
-you have to ensure before calling `helm-attrset' that the file
+using `helm-set-attr' function in your configuration. Of course
+you have to ensure before calling `helm-set-attr' that the file
containing source is loaded, e.g. with `with-eval-after-load'. Of
course you can also completely redefine the source but this is
generally not elegant as it duplicate for its most part code
@@ -1205,7 +1216,7 @@ Helm session. In this case you can add a defmethod called
#+begin_src elisp
- (defmethod helm-setup-user-source ((source helm-moccur-class))
+ (cl-defmethod helm-setup-user-source ((source helm-moccur-class))
(setf (slot-value source 'follow) -1))
#+end_src
@@ -1240,6 +1251,13 @@ match everything but this.
*** Completion-styles
+UPDATE: At version 3.8.0 Helm default is now to NOT use
+`completion-styles' i.e. now `helm-completion-style' default to
+'helm and no more to 'emacs.
+
+If you want to use `completion-styles' in Helm customize
+`helm-completion-style' to 'emacs.
+
Helm generally fetches its candidates with the :candidates
function up to `helm-candidate-number-limit' and then applies
match functions to these candidates according to `helm-pattern'.
@@ -1249,11 +1267,12 @@ Helm provides 'helm completion style but also 'helm-flex
completion style for Emacs<27 that don't have 'flex completion
style, otherwise (emacs-27) 'flex completion style is used to
provide fuzzy aka flex completion.
-By default, like in Emacs vanilla, all completion commands \(e.g.,
-`completion-at-point') using `completion-in-region' or
-`completing-read' use `completion-styles'.
-Some Helm native commands like `helm-M-x' do use
-`completion-styles'. Any Helm sources can use `completion-styles'
+
+When using helm-fuzzy as `helm-completion-style' helm use its own
+fuzzy implementation which have nothing to do with emacs `flex'
+style.
+
+Any Helm sources can use `completion-styles'
by using :match-dynamic slot and building their :candidates
function with `helm-dynamic-completion'.
@@ -1280,7 +1299,7 @@ emacs-26. Anyway, 'helm-flex is not provided in
Finally Helm provides two user variables to control
`completion-styles' usage: `helm-completion-style' and
-`helm-completion-syles-alist'. Both variables are customizable.
+`helm-completion-styles-alist'. Both variables are customizable.
The former allows retrieving previous Helm behavior if needed, by
setting it to `helm' or `helm-fuzzy', default being `emacs' which
allows dynamic completion and usage of `completion-styles'. The
@@ -1292,7 +1311,7 @@ helmized commands. File completion in `read-file-name' family
doesn't obey completion-styles and has its own file completion
implementation. Native Helm commands using `completion-styles'
doesn't obey `helm-completion-style' and
-`helm-completion-syles-alist' (e.g., helm-M-x).
+`helm-completion-styles-alist' (e.g., helm-M-x).
Also for a better control of styles in native Helm sources (not
helmized by helm-mode) using :match-dynamic,
@@ -1344,7 +1363,7 @@ matching or fuzzy matching (see [[Matching in Helm][Matching in
Helm]]).
Completion is not done dynamically (against `helm-pattern')
-because backend functions (i.e. `competion-at-point-functions')
+because backend functions (i.e. `completion-at-point-functions')
are not aware of Helm matching methods.
By behaving like this, the benefit is that you can fully use Helm
@@ -1421,13 +1440,26 @@ the `helm' group.
You can display the Helm completion buffer in many different
window configurations, see the custom interface to discover the
-different windows configurations available (See [[Customize
-Helm][Customize Helm]] to jump to custom interface). When using
-Emacs in a graphic display (i.e. not in a terminal) you can as
+different windows configurations available (See [[Customize Helm][Customize Helm]] to jump to custom interface).
+When using Emacs in a graphic display (i.e. not in a terminal) you can as
well display your Helm buffers in separated frames globally for
-all Helm commands or separately for specific Helm commands. See
-[[https://github.com/emacs-helm/helm/wiki/frame][helm wiki]] for
-more infos.
+all Helm commands or separately for specific Helm commands.
+See `helm-display-function' and `helm-commands-using-frame'.
+See also [[https://github.com/emacs-helm/helm/wiki/frame][helm wiki]] for more infos.
+
+There is a variable to allow reusing frame instead of deleting
+and creating a new one at each session, see `helm-display-buffer-reuse-frame'.
+Normally you don't have to use this, it have been made to workaround
+slow frame popup in Emacs-26, to workaround this slowness in Emacs-26 use instead
+
+#+begin_src elisp
+ (when (= emacs-major-version 26)
+ (setq x-wait-for-event-timeout nil))
+#+end_src
+
+WARNING:
+There is a package called posframe and also one called helm-posframe,
+you DO NOT need these packages to display helm buffers in frames.
** Helm's basic operations and default key bindings
@@ -1577,17 +1609,19 @@ line without executing the persistent action.
** Frequently Used Commands
-\\[helm-toggle-resplit-and-swap-windows]\t\tToggle vertical/horizontal split on first hit and swap Helm window on second hit.
-\\[helm-exchange-minibuffer-and-header-line]\t\tExchange minibuffer and header-line.
-\\[helm-quit-and-find-file]\t\tDrop into `helm-find-files'.
-\\[helm-kill-selection-and-quit]\t\tKill display value of candidate and quit (with prefix arg, kill the real value).
-\\[helm-yank-selection]\t\tYank current selection into pattern.
-\\[helm-copy-to-buffer]\t\tCopy selected candidate at point in current buffer.
-\\[helm-follow-mode]\t\tToggle automatic execution of persistent action.
-\\[helm-follow-action-forward]\tRun persistent action then select next line.
-\\[helm-follow-action-backward]\t\tRun persistent action then select previous line.
-\\[helm-refresh]\t\tRecalculate and redisplay candidates.
-\\[helm-toggle-suspend-update]\t\tToggle candidate updates.
+|Keys|Description
+|-----------+----------|
+|\\[helm-toggle-resplit-and-swap-windows]|Toggle vertical/horizontal split on first hit and swap Helm window on second hit.
+|\\[helm-exchange-minibuffer-and-header-line]|Exchange minibuffer and header-line.
+|\\[helm-quit-and-find-file]|Drop into `helm-find-files'.
+|\\[helm-kill-selection-and-quit]|Kill display value of candidate and quit (with prefix arg, kill the real value).
+|\\[helm-yank-selection]|Yank current selection into pattern.
+|\\[helm-insert-or-copy]|Insert or copy marked candidates (C-u) .
+|\\[helm-follow-mode]|Toggle automatic execution of persistent action.
+|\\[helm-follow-action-forward]|Run persistent action then select next line.
+|\\[helm-follow-action-backward]|Run persistent action then select previous line.
+|\\[helm-refresh]|Recalculate and redisplay candidates.
+|\\[helm-toggle-suspend-update]|Toggle candidate updates.
** Special yes, no or yes for all answers
@@ -1764,7 +1798,6 @@ in `helm-initialize'.")
"Internal, store locally `helm-pattern' value for later use in `helm-resume'.")
(defvar helm--source-name nil)
(defvar helm-current-source nil)
-(defvar helm-tick-hash (make-hash-table :test 'equal))
(defvar helm-issued-errors nil)
(defvar helm--last-log-file nil
"The name of the log file of the last Helm session.")
@@ -1788,7 +1821,7 @@ Knowing this exit-status could help restore a window config when
Helm aborts in some special circumstances. See
`helm-exit-minibuffer' and `helm-keyboard-quit'.")
(defvar helm-minibuffer-confirm-state nil)
-(defvar helm-quit nil)
+(defvar helm--quit nil)
(defvar helm-buffers nil
"Helm buffers listed in order of most recently used.")
(defvar helm-current-position nil
@@ -1870,6 +1903,7 @@ session just like resume would do.")
It is generally `helm-current-buffer', but when this one is displayed
in a dedicated buffer, helm can't start in this window and use another
window handling a buffer, it is this one we store.")
+(defvar helm--tramp-archive-maybe-loaded nil)
;; Utility: logging
(defun helm-log (format-string &rest args)
@@ -2039,7 +2073,7 @@ End:")
;;; helm-attributes
;;
-(defun helm-attr (attribute-name &optional source compute)
+(defun helm-get-attr (attribute-name &optional source compute)
"Get the value of ATTRIBUTE-NAME of SRC.
If SRC is omitted, use current source.
@@ -2052,7 +2086,7 @@ value unchanged, but will eval a symbol which is bound.
You can use `setf' to modify value of ATTRIBUTE-NAME unless
COMPUTE is specified, if attribute ATTRIBUTE-NAME is not found in
SOURCE `setf' will create new attribute ATTRIBUTE-NAME with
-specified value. You can also use `helm-attrset' to modify
+specified value. You can also use `helm-set-attr' to modify
ATTRIBUTE-NAME."
(declare (gv-setter
(lambda (val)
@@ -2072,17 +2106,10 @@ ATTRIBUTE-NAME."
(helm-interpret-value (cdr it) src compute)
(cdr it)))))
-;; (helm-aif (assq attribute-name src)
-;; (let* ((val (cdr it))
-;; When attr exists but have no cdr it is equal to `t'.
-;; (attrval (or val t)))
-;; Attributes with a boolean value have no cdr, so no need
-;; to compute a value == to t.
-;; (if (and compute val)
-;; (helm-interpret-value val src compute)
-;; attrval)))))
-
-(cl-defun helm-attrset (attribute-name value
+(defalias 'helm-attr 'helm-get-attr)
+(make-obsolete 'helm-attr 'helm-get-attr "3.7.0")
+
+(cl-defun helm-set-attr (attribute-name value
&optional
(src (helm-get-current-source)))
"Set the value of ATTRIBUTE-NAME of source SRC to VALUE.
@@ -2091,9 +2118,11 @@ If ATTRIBUTE-NAME doesn't exists in source it is created with
value VALUE. If SRC is omitted, use current source. If operation
succeed, return value, otherwise nil.
-Note that `setf' on `helm-attr' can be used instead of this
-function."
- (setf (helm-attr attribute-name src) value))
+Using this function is same as using `setf' on `helm-get-attr'."
+ (setf (helm-get-attr attribute-name src) value))
+
+(defalias 'helm-attrset 'helm-set-attr)
+(make-obsolete 'helm-attrset 'helm-set-attr "3.7.0")
(defun helm-add-action-to-source (name fn source &optional index)
"Add new action NAME linked to function FN to SOURCE.
@@ -2104,11 +2133,11 @@ If INDEX is specified, action is added to the action list at INDEX,
otherwise added at end.
This allows users to add specific actions to an existing source
without modifying source code."
- (let ((actions (helm-attr 'action source 'ignorefn))
+ (let ((actions (helm-get-attr 'action source 'ignorefn))
(new-action (list (cons name fn))))
(when (functionp actions)
(setq actions (list (cons "Default action" actions))))
- (helm-attrset 'action
+ (helm-set-attr 'action
(if index
(helm-append-at-nth actions new-action index)
(append actions new-action))
@@ -2118,11 +2147,11 @@ without modifying source code."
"Delete ACTION-OR-NAME from SOURCE.
ACTION-OR-NAME can either be the name of action or the symbol
function associated to name."
- (let* ((actions (helm-attr 'action source 'ignorefn))
+ (let* ((actions (helm-get-attr 'action source 'ignorefn))
(del-action (if (symbolp action-or-name)
(rassoc action-or-name actions)
(assoc action-or-name actions))))
- (helm-attrset 'action (delete del-action actions) source)))
+ (helm-set-attr 'action (delete del-action actions) source)))
(cl-defun helm-add-action-to-source-if (name fn source predicate
&optional (index 4) test-only)
@@ -2150,8 +2179,8 @@ when predicate helm-ff-candidates-lisp-p returns non-nil:
'async-byte-compile-file
helm-source-find-files
'helm-ff-candidates-lisp-p\)."
- (let* ((actions (helm-attr 'action source 'ignorefn))
- (action-transformers (helm-attr 'action-transformer source))
+ (let* ((actions (helm-get-attr 'action source 'ignorefn))
+ (action-transformers (helm-get-attr 'action-transformer source))
(new-action (list (cons name fn)))
(transformer (lambda (actions candidate)
(cond ((funcall predicate candidate)
@@ -2159,12 +2188,12 @@ when predicate helm-ff-candidates-lisp-p returns non-nil:
actions new-action index))
(t actions)))))
(when (functionp actions)
- (helm-attrset 'action (list (cons "Default action" actions)) source))
+ (helm-set-attr 'action (list (cons "Default action" actions)) source))
(when (or (symbolp action-transformers) (functionp action-transformers))
(setq action-transformers (list action-transformers)))
(if test-only ; debug
(delq nil (append (list transformer) action-transformers))
- (helm-attrset 'action-transformer
+ (helm-set-attr 'action-transformer
(helm-fast-remove-dups
(delq nil (append (list transformer) action-transformers))
:test 'equal)
@@ -2229,42 +2258,47 @@ If NO-UPDATE is non-nil, skip executing `helm-update'."
(unless no-update (helm-update)))
(defun helm-get-selection (&optional buffer force-display-part source)
- "Return the currently selected item or nil.
+ "Return the currently selected candidate from BUFFER.
If BUFFER is nil or unspecified, use `helm-buffer' as default value.
-If FORCE-DISPLAY-PART is non-nil, return the display string.
-If FORCE-DISPLAY-PART value is `withprop' the display string is returned
-with its properties."
- (setq buffer (or buffer helm-buffer))
- (unless (or (helm-empty-buffer-p buffer)
- (helm-pos-header-line-p))
- (with-current-buffer buffer
- (let* ((disp-fn (if (eq force-display-part 'withprop)
+
+If FORCE-DISPLAY-PART is non-nil, return the display part of candidate.
+
+If FORCE-DISPLAY-PART value is `withprop' the display part of
+candidate is returned with its properties.
+
+When FORCE-DISPLAY-PART is nil the real part of candidate is returned.
+
+SOURCE default to current-source when unspecified but it is better to
+specify SOURCE when it is already available to avoid to call
+`helm-get-current-source' uselessly.
+
+Note that FORCE-DISPLAY-PART when specified takes precedence over
+`display-to-real' attribute, that's mean don't use FORCE-DISPLAY-PART
+when you want the `display-to-real' function(s) to be applied."
+ (with-current-buffer (or buffer helm-buffer)
+ (unless (or (helm-empty-buffer-p (current-buffer))
+ (helm-pos-header-line-p))
+ (let* ((beg (overlay-start helm-selection-overlay))
+ (end (overlay-end helm-selection-overlay))
+ (disp-fn (if (eq force-display-part 'withprop)
'buffer-substring
'buffer-substring-no-properties))
- (selection
- (or (and (not force-display-part)
- (get-text-property (overlay-start
- helm-selection-overlay)
- 'helm-realvalue))
- ;; It is needed to return properties of DISP in some case,
- ;; e.g for `helm-confirm-and-exit-minibuffer',
- ;; so use `buffer-substring' here when 'withprop is specified.
- (let* ((beg (overlay-start helm-selection-overlay))
- (end (overlay-end helm-selection-overlay))
- ;; If there is no selection at point, the
- ;; overlay is at its initial pos, (point-min)
- ;; (point-min), that's mean the helm-buffer
- ;; is not empty but have no selection yet,
- ;; this happen with grep sentinel sending an
- ;; error message in helm-buffer when no matches.
- (disp (unless (= beg end) (funcall disp-fn beg (1- end))))
- (src (or source (helm-get-current-source))))
- (helm-aif (and src disp
- (not force-display-part)
- (assoc-default 'display-to-real src))
- (helm-apply-functions-from-source source it disp)
- disp)))))
+ ;; If there is no selection at point, the
+ ;; overlay is at its initial pos, (point-min)
+ ;; (point-min), that's mean the helm-buffer
+ ;; is not empty but have no selection yet,
+ ;; this happen with grep sentinel sending an
+ ;; error message in helm-buffer when no matches.
+ (disp (unless (= beg end) (funcall disp-fn beg (1- end))))
+ (src (or source (helm-get-current-source)))
+ (selection (helm-acond (force-display-part disp)
+ ;; helm-realvalue always takes precedence
+ ;; over display-to-real.
+ ((get-text-property beg 'helm-realvalue) it)
+ ((assoc-default 'display-to-real src)
+ (helm-apply-functions-from-source source it disp))
+ (t disp))))
(unless (equal selection "")
(helm-log "selection = %S" selection)
selection)))))
@@ -2275,10 +2309,10 @@ It is a function symbol (sole action) or list
of (action-display . function)."
(unless (helm-empty-buffer-p (helm-buffer-get))
(let ((src (helm-get-current-source)))
- (helm-aif (helm-attr 'action-transformer)
+ (helm-aif (helm-get-attr 'action-transformer)
(helm-apply-functions-from-source
(or source src) it
- (helm-attr 'action nil 'ignorefn)
+ (helm-get-attr 'action nil 'ignorefn)
;; Check if the first given transformer
;; returns the same set of actions for each
;; candidate in marked candidates.
@@ -2291,7 +2325,7 @@ of (action-display . function)."
always (equal (funcall act nil c) acts))
(car (helm-marked-candidates))
(helm-get-selection nil nil src)))
- (helm-attr 'action nil 'ignorefn)))))
+ (helm-get-attr 'action nil 'ignorefn)))))
(defun helm-get-current-source ()
"Return the source for the current selection.
@@ -2313,22 +2347,6 @@ Return nil when `helm-buffer' is empty."
(and (equal (assoc-default 'name source) source-name)
source)))))))))
-(defun helm-buffer-is-modified (buffer)
- "Return non-nil when BUFFER is modified since Helm was invoked."
- (let* ((buf (get-buffer buffer))
- (key (concat (buffer-name buf) "/" (helm-attr 'name)))
- (source-tick (or (gethash key helm-tick-hash) 0))
- (buffer-tick (buffer-chars-modified-tick buf))
- (modifiedp (/= source-tick buffer-tick)))
- (puthash key buffer-tick helm-tick-hash)
- (helm-log "buffer = %S" buffer)
- (helm-log "modifiedp = %S" modifiedp)
- modifiedp))
-
-(defun helm-current-buffer-is-modified ()
- "Check if `helm-current-buffer' is modified since Helm was invoked."
- (helm-buffer-is-modified helm-current-buffer))
-
(defun helm-run-after-exit (function &rest args)
"Execute FUNCTION with ARGS after exiting Helm.
The action is to call FUNCTION with arguments ARGS.
@@ -2576,24 +2594,11 @@ of current source only."
while (not (if in-current-source
(or (helm-pos-header-line-p) (eobp))
(eobp)))
- ;; Don't count empty lines maybe added by popup (#1370).
+ ;; Don't count empty lines maybe added by popup (bug#1370).
unless (or (eq (point-at-bol) (point-at-eol))
(helm-pos-header-line-p))
do (cl-incf ln)
do (forward-line 1) finally return ln))))))
-
-(defmacro with-helm-quittable (&rest body)
- "If an error occurs in execution of BODY, safely quit helm."
- (declare (indent 0) (debug t))
- `(condition-case _v
- (let (inhibit-quit)
- ,@body)
- (quit (setq quit-flag t)
- (setq helm-quit t)
- (exit-minibuffer)
- (keyboard-quit)
- ;; See comment about this in `with-local-quit'.
- (eval '(ignore nil)))))
;; Entry point
;; `:allow-nest' is not in this list because it is treated before.
@@ -2796,6 +2801,17 @@ in the source.
unless (memq key helm-argument-keys)
collect (cons sym value)))
+(defun helm--maybe-load-tramp-archive ()
+ ;; Should fix bug#2393 and bug#2394. `while-no-input-ignore-events'
+ ;; is also let-bounded in `helm--maybe-use-while-no-input'.
+ (let ((while-no-input-ignore-events
+ (cons 'dbus-event while-no-input-ignore-events)))
+ (unless helm--tramp-archive-maybe-loaded
+ ;; This for Emacs-27 not requiring tramp-archive.
+ (and (boundp 'tramp-archive-enabled)
+ (require 'tramp-archive nil t))
+ (setq helm--tramp-archive-maybe-loaded t))))
+
;;; Entry point helper
(defun helm-internal (&optional
sources input
@@ -2810,6 +2826,8 @@ HISTORY args see `helm'."
nil "Error in %S buffer: Initial input should be a string or nil"
buffer)
(unless helm--nested (setq helm-initial-frame (selected-frame)))
+ ;; Launch tramp-archive with dbus-event in `while-no-input-ignore-events'.
+ (helm--maybe-load-tramp-archive)
;; Activate the advices.
;; Advices will be available only in >=emacs-24.4, but
;; allow compiling without errors on lower emacs.
@@ -2819,7 +2837,7 @@ HISTORY args see `helm'."
(advice-add 'epa-passphrase-callback-function
:around #'helm--suspend-read-passwd)
;; Ensure linum-mode is disabled in Helm buffers to preserve
- ;; performances (Issue #1894).
+ ;; performances (Bug#1894).
(advice-add 'linum-on :override #'helm--advice-linum-on '((depth . 100))))
(helm-log (concat "[Start session] " (make-string 41 ?+)))
(helm-log "prompt = %S" prompt)
@@ -2831,7 +2849,7 @@ HISTORY args see `helm'."
(setq helm--prompt (or prompt "pattern: "))
(let ((non-essential t)
;; Prevent mouse jumping to the upper-right
- ;; hand corner of the frame (#1538).
+ ;; hand corner of the frame (bug#1538).
mouse-autoselect-window
focus-follows-mouse
mode-line-in-non-selected-windows
@@ -2849,7 +2867,7 @@ HISTORY args see `helm'."
helm--source-name
helm-current-source
helm-in-persistent-action
- helm-quit
+ helm--quit
(helm-buffer (or buffer helm-buffer)))
(helm-initialize
resume input default sources)
@@ -2858,26 +2876,28 @@ HISTORY args see `helm'."
;; only one candidate (this avoid having the helm frame
;; flashing), lets first compute candidates and if more
;; than one display helm-buffer (this is done later in
- ;; helm-read-pattern-maybe).
+ ;; helm-read-from-minibuffer).
(unless helm-execute-action-at-once-if-one
(helm-display-buffer helm-buffer resume)
- (select-window (helm-window)))
+ (select-window (helm-window))
+ (when (and resume helm-visible-mark-overlays)
+ (set-window-margins (selected-window) 1)))
;; We are now in helm-buffer.
(unless helm-allow-mouse
(helm--remap-mouse-mode 1)) ; Disable mouse bindings.
(add-hook 'post-command-hook 'helm--maybe-update-keymap)
;; Add also to update hook otherwise keymap is not updated
- ;; until a key is hitted (Issue #1670).
+ ;; until a key is hitted (Bug#1670).
(add-hook 'helm-after-update-hook 'helm--maybe-update-keymap)
(add-hook 'post-command-hook 'helm--update-header-line)
(helm-log "show prompt")
(unwind-protect
- (helm-read-pattern-maybe
+ (helm-read-from-minibuffer
prompt input preselect
resume keymap default history)
(helm-cleanup))
(prog1
- (unless helm-quit (helm-execute-selection-action))
+ (unless helm--quit (helm-execute-selection-action))
(helm-log (concat "[End session] " (make-string 41 ?-)))))
(quit
(helm-restore-position-on-quit)
@@ -3177,7 +3197,7 @@ frame configuration as per `helm-save-configuration-functions'."
;;
;; Since they don't know about the new timestamp,
;; their keyboard handling can break after a helm
- ;; user quits emacs, as reported in #1641.
+ ;; user quits emacs, as reported in bug#1641.
;;
;; Fortunately for us, we really don't need this
;; XSetInputFocus call, since we already have focus
@@ -3524,47 +3544,6 @@ For RESUME INPUT DEFAULT and SOURCES see `helm'."
(overlay-put helm-selection-overlay 'face 'helm-selection)
(overlay-put helm-selection-overlay 'priority 1)))
-(defun helm-restore-position-on-quit ()
- "Restore position in `helm-current-buffer' when quitting."
- (helm-current-position 'restore))
-
-(defun helm--push-and-remove-dups (elm sym)
- "Move ELM of SYM value on top and set SYM to this new value."
- (set sym (cons elm (delete elm (symbol-value sym)))))
-
-(defun helm--current-buffer ()
- "[INTERNAL] Return `current-buffer' BEFORE `helm-buffer' is initialized.
-Note that it returns the minibuffer in use after Helm has started
-and is intended for `helm-initial-setup'. To get the buffer where
-Helm was started, use `helm-current-buffer' instead."
- (if (minibuffer-window-active-p (minibuffer-window))
- ;; If minibuffer is active be sure to use it's buffer
- ;; as `helm-current-buffer', this allow to use helm
- ;; from an already active minibuffer (M-: etc...)
- (window-buffer (active-minibuffer-window))
- ;; Fix Issue #456
- ;; Use this instead of `current-buffer' to ensure
- ;; helm session started in helm-mode from a completing-read
- ;; Use really the buffer where we started and not the one
- ;; where the completing-read is wrapped. i.e
- ;; (with-current-buffer SOME-OTHER-BUFFER (completing-read [...])
- (window-buffer (with-selected-window (minibuffer-window)
- (minibuffer-selected-window)))))
-
-(defun helm--run-init-hooks (hook sources)
- "Run after and before init hooks local to source.
-See :after-init-hook and :before-init-hook in `helm-source'."
- (cl-loop with sname = (cl-ecase hook
- (before-init-hook "h-before-init-hook")
- (after-init-hook "h-after-init-hook"))
- with h = (cl-gensym sname)
- for s in sources
- for hv = (assoc-default hook s)
- if (and hv (not (symbolp hv)))
- do (set h hv)
- and do (helm-log-run-hook h)
- else do (helm-log-run-hook hv)))
-
(defun helm-initial-setup (default sources)
"Initialize Helm settings and set up the Helm buffer."
;; Run global hook.
@@ -3618,6 +3597,47 @@ See :after-init-hook and :before-init-hook in `helm-source'."
;; Run local source hook.
(helm--run-init-hooks 'after-init-hook sources))
+(defun helm--run-init-hooks (hook sources)
+ "Run after and before init hooks local to source.
+See :after-init-hook and :before-init-hook in `helm-source'."
+ (cl-loop with sname = (cl-ecase hook
+ (before-init-hook "h-before-init-hook")
+ (after-init-hook "h-after-init-hook"))
+ with h = (cl-gensym sname)
+ for s in sources
+ for hv = (assoc-default hook s)
+ if (and hv (not (symbolp hv)))
+ do (set h hv)
+ and do (helm-log-run-hook h)
+ else do (helm-log-run-hook hv)))
+
+(defun helm-restore-position-on-quit ()
+ "Restore position in `helm-current-buffer' when quitting."
+ (helm-current-position 'restore))
+
+(defun helm--push-and-remove-dups (elm sym)
+ "Move ELM of SYM value on top and set SYM to this new value."
+ (set sym (cons elm (delete elm (symbol-value sym)))))
+
+(defun helm--current-buffer ()
+ "[INTERNAL] Return `current-buffer' BEFORE `helm-buffer' is initialized.
+Note that it returns the minibuffer in use after Helm has started
+and is intended for `helm-initial-setup'. To get the buffer where
+Helm was started, use `helm-current-buffer' instead."
+ (if (minibuffer-window-active-p (minibuffer-window))
+ ;; If minibuffer is active be sure to use it's buffer
+ ;; as `helm-current-buffer', this allow to use helm
+ ;; from an already active minibuffer (M-: etc...)
+ (window-buffer (active-minibuffer-window))
+ ;; Fix Bug#456
+ ;; Use this instead of `current-buffer' to ensure
+ ;; helm session started in helm-mode from a completing-read
+ ;; Use really the buffer where we started and not the one
+ ;; where the completing-read is wrapped. i.e
+ ;; (with-current-buffer SOME-OTHER-BUFFER (completing-read [...])
+ (window-buffer (with-selected-window (minibuffer-window)
+ (minibuffer-selected-window)))))
+
(define-derived-mode helm-major-mode
fundamental-mode "Hmm"
"[INTERNAL] Provide major-mode name in Helm buffers.
@@ -3637,7 +3657,10 @@ Unuseful when used outside Helm, don't use it.")
(set (make-local-variable 'buffer-read-only) nil)
(buffer-disable-undo)
(erase-buffer)
- (set (make-local-variable 'helm-map) helm-map)
+ ;; Use this instead of setting helm-map local ensure we have all
+ ;; our keys when helm loose minibuffer focus. And the map is
+ ;; made local as well AFAIU.
+ (use-local-map helm-map)
(set (make-local-variable 'helm-source-filter) nil)
(make-local-variable 'helm-sources)
(set (make-local-variable 'helm-display-function) nil)
@@ -3673,7 +3696,7 @@ please don't use it outside of Helm.
(setq helm-pattern "")
(setq helm-maybe-use-default-as-input nil))
-(defun helm-read-pattern-maybe (prompt
+(defun helm-read-from-minibuffer (prompt
input preselect resume
keymap default history)
"Read pattern with prompt PROMPT and initial input INPUT.
@@ -3696,7 +3719,17 @@ For PRESELECT RESUME KEYMAP DEFAULT HISTORY, see `helm'."
resize-mini-windows))
(first-src (car helm-sources))
(source-process-p (or (assq 'candidates-process src)
- (assq 'candidates-process first-src))))
+ (assq 'candidates-process first-src)))
+ ;; As we are using `helm-keyboard-quit' for `C-g' we have
+ ;; to prevent emacs command loop redefining `C-g' during
+ ;; helm-session. This happen only on async source with
+ ;; large output after a certain delay. The effect is that
+ ;; the minibuffer is exited but the helm async process
+ ;; continue running, and because minibuffer is lost `C-g'
+ ;; have no more effect. By binding `inhibit-quit' here we
+ ;; prevent this and allow `C-g' (the helm one aka
+ ;; `helm-keyboard-quit') to quit immediately.
+ (inhibit-quit source-process-p))
(helm-log "helm-get-candidate-number => %S"
(helm-get-candidate-number))
(helm-log "helm-execute-action-at-once-if-one = %S"
@@ -3737,7 +3770,7 @@ For PRESELECT RESUME KEYMAP DEFAULT HISTORY, see `helm'."
(ignore)) ; Don't enter the minibuffer loop.
((and helm-quit-if-no-candidate
(= (helm-get-candidate-number) 0))
- (setq helm-quit t)
+ (setq helm--quit t)
(and (functionp helm-quit-if-no-candidate)
(funcall helm-quit-if-no-candidate)))
(t ; Enter now minibuffer and wait for input.
@@ -3858,7 +3891,7 @@ map)."
;; e.g C-x C-f M-y C-g
;; => *find-files have now the bindings of *kill-ring.
;; It is no more true now we are using `minor-mode-overriding-map-alist'
- ;; and `helm--minor-mode' thus it fix issue #1076 for emacs-24.3
+ ;; and `helm--minor-mode' thus it fix Bug#1076 for emacs-24.3
;; where concurrent timers are not supported.
;; i.e update keymap+check input.
(with-current-buffer (window-buffer (minibuffer-window))
@@ -3893,11 +3926,17 @@ WARNING: Do not use this mode yourself, it is internal to Helm."
(defun helm-cleanup ()
"Clean up the mess when Helm exit or quit."
(helm-log "start cleanup")
- (with-current-buffer helm-buffer
+ (with-selected-window
+ ;; When exiting with `helm-execute-action-at-once-if-one',
+ ;; `helm-window' may not be created and we endup with an error
+ ;; e.g. in eshell completion when only one candidate to complete
+ ;; so fallback to selected-window in such cases.
+ (or (get-buffer-window helm-buffer)
+ (selected-window))
(let ((frame (selected-frame)))
(setq cursor-type t)
;; Ensure restoring default-value of mode-line to allow user
- ;; using the mouse when helm is inactive (issues #1517,#2377).
+ ;; using the mouse when helm is inactive (Bug#1517,Bug#2377).
(setq mode-line-format (default-value 'mode-line-format))
(remove-hook 'post-command-hook 'helm--maybe-update-keymap)
(remove-hook 'post-command-hook 'helm--update-header-line)
@@ -3956,10 +3995,9 @@ WARNING: Do not use this mode yourself, it is internal to Helm."
;;
(defun helm-check-minibuffer-input ()
"Check minibuffer content."
- (with-helm-quittable
- (with-selected-window (or (active-minibuffer-window)
- (minibuffer-window))
- (helm-check-new-input (minibuffer-contents)))))
+ (with-selected-window (or (active-minibuffer-window)
+ (minibuffer-window))
+ (helm-check-new-input (minibuffer-contents))))
(defun helm-check-new-input (input)
"Check INPUT string and update the helm buffer if necessary."
@@ -3987,7 +4025,7 @@ WARNING: Do not use this mode yourself, it is internal to Helm."
"Retrieve and return the list of candidates from SOURCE."
(let* ((candidate-fn (assoc-default 'candidates source))
(candidate-proc (assoc-default 'candidates-process source))
- ;; See comment in helm-get-cached-candidates (Issue 2113).
+ ;; See comment in helm-get-cached-candidates (Bug#2113).
(inhibit-quit candidate-proc)
cfn-error
(notify-error
@@ -4024,7 +4062,7 @@ WARNING: Do not use this mode yourself, it is internal to Helm."
;; Can happen when the output of a process
;; is empty, and the candidates function call
;; something like (split-string (buffer-string) "\n")
- ;; which result in a list of one empty string (Issue #938).
+ ;; which result in a list of one empty string (Bug#938).
;; e.g (completing-read "test: " '(""))
(equal candidates '("")))
nil)
@@ -4036,23 +4074,16 @@ WARNING: Do not use this mode yourself, it is internal to Helm."
(helm-transform-candidates candidates source))
(t (funcall notify-error)))))
-(defmacro helm-while-no-input (&rest body)
- "Same as `while-no-input' but without the `input-pending-p' test."
- (declare (debug t) (indent 0))
- (let ((catch-sym (make-symbol "input")))
- `(with-local-quit
- (catch ',catch-sym
- (let ((throw-on-input ',catch-sym))
- ,@body)))))
-
(defun helm-get-cached-candidates (source)
"Return the cached value of candidates for SOURCE.
Cache the candidates if there is no cached value yet."
(let* ((name (assoc-default 'name source))
(candidate-cache (gethash name helm-candidate-cache))
;; Bind inhibit-quit to ensure function terminate in case of
- ;; quit from helm-while-no-input and processes are added to
- ;; helm-async-processes for further deletion (Issue 2113).
+ ;; quit from `helm-while-no-input' and processes are added to
+ ;; helm-async-processes for further deletion (Bug#2113).
+ ;; FIXME: Is this still needed now `helm-while-no-input'
+ ;; handles quit-flag?
(inhibit-quit (assoc-default 'candidates-process source)))
(helm-aif candidate-cache
(prog1 it (helm-log "Use cached candidates"))
@@ -4161,7 +4192,7 @@ If \(candidate-number-limit\) is in SOURCE, show all candidates in SOURCE.
If \(candidate-number-limit . 123\) is in SOURCE limit candidate to 123."
(helm-aif (assq 'candidate-number-limit source)
;; When assoc value is nil use by default 99999999 otherwise use
- ;; the assoc value, when it is a symbol interpret its value (#1831).
+ ;; the assoc value, when it is a symbol interpret its value (bug#1831).
(or (helm-aand (cdr it) (helm-interpret-value it)) 99999999)
(or helm-candidate-number-limit 99999999)))
@@ -4394,7 +4425,7 @@ to the matching method in use."
(with-temp-buffer
;; Insert the whole display part and remove non--match-part
;; to keep their original face properties.
- (insert (propertize (or mp display) 'read-only nil)) ; Fix (#1176)
+ (insert (propertize (or mp display) 'read-only nil)) ; Fix (bug#1176)
(goto-char (point-min))
(condition-case nil
(progn
@@ -4517,7 +4548,9 @@ emacs-27 to provide such scoring in emacs<27."
for dup = (gethash c hash)
for disp = (helm-candidate-get-display c)
while (< count limit)
- for target = (if (helm-attr 'match-on-real source)
+ for target = (if (helm-get-attr 'match-on-real source)
+ ;; Let's fails on error in
+ ;; case next block returns nil.
(or (cdr-safe c)
(get-text-property 0 'helm-realvalue disp))
disp)
@@ -4618,6 +4651,23 @@ emacs-27 to provide such scoring in emacs<27."
(put-text-property start (point)
'helm-multiline t)))))
+(defmacro helm-while-no-input (&rest body)
+ "Same as `while-no-input' but returns either BODY or nil.
+Unlike `while-no-input' this macro ensure to not returns `t'."
+ (declare (debug t) (indent 0))
+ (let ((catch-sym (make-symbol "input")))
+ `(with-local-quit
+ (catch ',catch-sym
+ (let ((throw-on-input ',catch-sym)
+ val)
+ (setq val (progn ,@body))
+ ;; See comments in `while-no-input' about resetting
+ ;; quit-flag.
+ (cond ((eq quit-flag throw-on-input)
+ (setq quit-flag nil))
+ (quit-flag nil)
+ (t val)))))))
+
(defmacro helm--maybe-use-while-no-input (&rest body)
"Wrap BODY in `helm-while-no-input' unless initializing a remote connection."
`(progn
@@ -4626,7 +4676,13 @@ emacs-27 to provide such scoring in emacs<27."
;; Tramp will ask for passwd, don't use `helm-while-no-input'.
,@body
(helm-log "Using here `helm-while-no-input'")
- (helm-while-no-input ,@body))))
+ ;; Emacs bug <https://debbugs.gnu.org/47205>, unexpected
+ ;; dbus-event is triggered on dbus init.
+ ;; Ignoring the dbus-event work on emacs28+; for emacs27 or older
+ ;; version, require tramp-archive can workaround the issue.
+ (let ((while-no-input-ignore-events
+ (cons 'dbus-event while-no-input-ignore-events)))
+ (helm-while-no-input ,@body)))))
(defun helm--collect-matches (src-list)
"Return a list of matches for each source in SRC-LIST.
@@ -4718,13 +4774,13 @@ without recomputing them, it should be a list of lists."
(setq matches (or candidates (helm--collect-matches sources))))
;; If computing matches finished and is not interrupted
;; erase the helm-buffer and render results (Fix #1157).
- (when matches ;; nil only when interrupted by helm-while-no-input.
+ (when matches ;; nil only when interrupted by while-no-input.
(erase-buffer) ; [1]
(cl-loop for src in sources
for mtc in matches
do (helm-render-source src mtc))
;; Move to first line only when there is matches
- ;; to avoid cursor moving upside down (issue #1703).
+ ;; to avoid cursor moving upside down (Bug#1703).
(helm--update-move-first-line)))
;; When there is only one async source, update mode-line and run
;; `helm-after-update-hook' in `helm-output-filter--post-process',
@@ -4758,8 +4814,9 @@ without recomputing them, it should be a list of lists."
(helm-aif (assq 'requires-pattern source) (or (cdr it) 1) 0))
;; Entering repeatedly these strings (*, ?) takes 100% CPU
;; and hang emacs on MacOs preventing deleting backward those
- ;; characters (issue #1802).
- (not (string-match-p "\\`[*]+\\'" helm-pattern))
+ ;; characters (Bug#1802). Update: it seems it is no more true,
+ ;; thus this affect bug#2423, so let's remove this for now.
+ ;; (not (string-match-p "\\`[*]+\\'" helm-pattern))
;; These incomplete regexps hang helm forever
;; so defer update. Maybe replace spaces quoted when using
;; multi-match.
@@ -4812,7 +4869,7 @@ passed as argument to `recenter'."
"Reinit SOURCE by calling its update and init functions."
;; When using a specific buffer as cache, don't kill it.
(helm-aif (and (null (bufferp (assoc-default
- (helm-attr 'name source)
+ (helm-get-attr 'name source)
helm--candidate-buffer-alist)))
(helm-apply-functions-from-source
source 'helm-candidate-buffer))
@@ -5041,7 +5098,7 @@ This will work only in Emacs-26+, i.e. Emacs versions that have
;;
(defun helm-output-filter (process output-string)
"The `process-filter' function for Helm async sources."
- (with-helm-quittable
+ (with-local-quit
(helm-output-filter-1 (assoc process helm-async-processes) output-string)))
(defun helm-output-filter-1 (process-assoc output-string)
@@ -5107,7 +5164,7 @@ This will work only in Emacs-26+, i.e. Emacs versions that have
;; incomplete-line-info assumed output was truncated in
;; only two chunks. But output could be large and
;; truncated in more than two chunks. Therefore store
- ;; 'newline' to contain the previous chunks (Issue #1187).
+ ;; 'newline' to contain the previous chunks (Bug#1187).
finally do (setcdr incomplete-line-info newline))))
(defun helm-output-filter--post-process ()
@@ -5250,7 +5307,7 @@ If action buffer is selected, back to the Helm buffer."
(helm-subr-native-elisp-p actions))
"Anonymous" actions))
(helm-show-action-buffer actions)
- ;; Be sure the minibuffer is entirely deleted (#907).
+ ;; Be sure the minibuffer is entirely deleted (bug#907).
(helm--delete-minibuffer-contents-from "")
(helm--set-action-prompt)
(helm-check-minibuffer-input))))
@@ -5444,7 +5501,7 @@ mode and header lines."
(with-selected-window (minibuffer-window)
(when helm-display-header-line
;; Prevent cursor movement over the overlay displaying
- ;; persistent-help in minibuffer (issue #2108).
+ ;; persistent-help in minibuffer (Bug#2108).
(setq-local disable-point-adjustment t))
(let* ((beg (save-excursion (vertical-motion 0 (helm-window)) (point)))
(end (save-excursion (end-of-visual-line) (point)))
@@ -5460,11 +5517,11 @@ mode and header lines."
"->"
'face 'helm-header-line-left-margin))))
(pos (- (point) beg)))
- ;; Increment pos each time we find a "%" up to current-pos (#1648).
+ ;; Increment pos each time we find a "%" up to current-pos (bug#1648).
(cl-loop for c across (buffer-substring-no-properties beg (point))
when (eql c ?%) do (cl-incf pos))
;; Increment pos when cursor is on a "%" to make it visible in header-line
- ;; i.e "%%|" and not "%|%" (#1649).
+ ;; i.e "%%|" and not "%|%" (bug#1649).
(when (eql (char-after) ?%) (setq pos (1+ pos)))
(setq cont (replace-regexp-in-string "%" "%%" cont))
(with-helm-buffer
@@ -5514,7 +5571,7 @@ It has no effect if `helm-echo-input-in-header-line' is nil."
(let ((ov (make-overlay (point-min) (point-max) nil nil t)))
(overlay-put ov 'window (selected-window))
(helm-aif (and helm-display-header-line
- (helm-attr 'persistent-help))
+ (helm-get-attr 'persistent-help))
(progn
(overlay-put ov 'display
(truncate-string-to-width
@@ -5685,7 +5742,7 @@ Key arg DIRECTION can be one of:
(forward-line 1) (eobp)))
;; Empty source at eob are just
;; not displayed unless they are dummy.
- ;; Issue #1117.
+ ;; Bug#1117.
(helm-get-next-header-pos))
(point-min))))
@@ -5791,6 +5848,17 @@ If SOURCE-OR-NAME is empty string or nil go to the first
candidate of first source."
(helm-move-selection-common :where 'source :direction source-or-name))
+(defvar helm-follow-action-white-list-commands
+ '(helm-ff-decrease-image-size-persistent
+ helm-ff-increase-image-size-persistent
+ helm-ff-rotate-left-persistent
+ helm-ff-rotate-right-persistent)
+ "Allow `helm-follow-action-forward/backward' switching to next file
+when one of these commands is the `last-command'.
+
+For example when browsing files with `C-<down>` and rotate the current file,
+hitting `C-<down>` again will not switch to next file but kill its buffer.")
+
(defun helm--follow-action (arg)
(let ((helm--temp-follow-flag t) ; Needed in HFF.
(in-follow-mode (helm-follow-mode-p)))
@@ -5799,6 +5867,7 @@ candidate of first source."
(when (or (eq last-command 'helm-follow-action-forward)
(eq last-command 'helm-follow-action-backward)
(eq last-command 'helm-execute-persistent-action)
+ (memq last-command helm-follow-action-white-list-commands)
in-follow-mode)
(if (> arg 0)
(helm-move-selection-common :where 'line
@@ -5912,7 +5981,7 @@ message 'no match'."
(defun helm--set-minibuffer-completion-confirm (src)
(with-helm-buffer
- (helm-aif (helm-attr 'must-match src)
+ (helm-aif (helm-get-attr 'must-match src)
(setq minibuffer-completion-confirm it))))
(defun helm-read-string (prompt &optional initial-input history
@@ -6037,14 +6106,6 @@ to a list of forms.\n\n")
;; Misc
-(defun helm-kill-buffer-hook ()
- "Remove tick entry from `helm-tick-hash' and remove buffer from
-`helm-buffers' when killing a buffer."
- (cl-loop for key being the hash-keys in helm-tick-hash
- if (string-match (format "^%s/" (regexp-quote (buffer-name))) key)
- do (remhash key helm-tick-hash))
- (setq helm-buffers (remove (buffer-name) helm-buffers)))
-(add-hook 'kill-buffer-hook 'helm-kill-buffer-hook)
(defun helm-preselect (candidate-or-regexp &optional source)
"Move selection to CANDIDATE-OR-REGEXP on Helm start.
@@ -6074,7 +6135,7 @@ Optional argument SOURCE is a Helm source object."
(re-search-forward (cdr candidate-or-regexp) nil t))
(re-search-forward candidate-or-regexp nil t))
;; If search fall on an header line continue loop
- ;; until it match or fail (Issue #1509).
+ ;; until it match or fail (Bug#1509).
(unless (helm-pos-header-line-p) (cl-return (setq mp it))))
(goto-char (or mp start)))))
(forward-line 0) ; Avoid scrolling right on long lines.
@@ -6248,7 +6309,7 @@ To customize `helm-candidates-in-buffer' behaviour, use `search',
(or (assoc-default 'search src)
'(helm-candidates-in-buffer-search-default-fn))
(helm-candidate-number-limit src)
- (helm-attr 'match-part)
+ (helm-get-attr 'match-part)
src)))
(defun helm-candidates-in-buffer-search-default-fn (pattern)
@@ -6478,7 +6539,7 @@ before running again the init function."
(global global-bname)
(local local-bname)))
;; We need a buffer not read-only to perhaps insert later
- ;; text coming from read-only buffers (issue #1176).
+ ;; text coming from read-only buffers (Bug#1176).
(set (make-local-variable 'buffer-read-only) nil)
;; Undo is automatically disabled in buffer names starting
;; with a space, so no need to disable it.
@@ -6818,7 +6879,7 @@ unsuitable window to display persistent action buffer."
((and helm--buffer-in-new-frame-p helm-initial-frame)
(with-selected-frame helm-initial-frame (selected-window)))
((and split (not (eq split 'never))) (split-window))
- ;; Fix Issue #2050 with dedicated window.
+ ;; Fix Bug#2050 with dedicated window.
((and (window-dedicated-p
(setq prev-win (previous-window (selected-window) 1)))
(not (eq split 'never)))
@@ -6915,7 +6976,7 @@ Meaning of prefix ARG is the same as in `reposition-window'."
(defun helm-make-visible-mark (&optional src selection)
(let* ((source (or src (helm-get-current-source)))
(sel (or selection (helm-get-selection
- nil (helm-attr 'marked-with-props source)
+ nil (helm-get-attr 'marked-with-props source)
source)))
(selection-end (if (helm-pos-multiline-p)
;; Stays within source
@@ -6927,10 +6988,16 @@ Meaning of prefix ARG is the same as in `reposition-window'."
(o (make-overlay (point-at-bol) selection-end)))
(overlay-put o 'priority 0)
(overlay-put o 'face 'helm-visible-mark)
- (overlay-put o 'source (assoc-default 'name source))
+ (overlay-put o 'source source)
(overlay-put o 'string (buffer-substring (overlay-start o) (overlay-end o)))
(overlay-put o 'real sel)
+ (overlay-put o 'before-string (propertize " " 'display
+ `((margin left-margin)
+ ,(propertize
+ helm-visible-mark-prefix
+ 'face 'helm-mark-prefix))))
(overlay-put o 'visible-mark t)
+ (overlay-put o 'evaporate t)
(cl-pushnew o helm-visible-mark-overlays)
(push (cons source sel) helm-marked-candidates)))
@@ -6956,7 +7023,9 @@ If ARG is negative toggle backward."
(progn
(helm-display-mode-line (helm-get-current-source))
(cl-return nil))
- (funcall (cdr next-fns))))))))))
+ (funcall (cdr next-fns)))))
+ (set-window-margins (selected-window)
+ (if helm-visible-mark-overlays 1 0)))))))
(put 'helm-toggle-visible-mark 'helm-only t)
(defun helm-toggle-visible-mark-forward ()
@@ -6982,7 +7051,9 @@ With a prefix arg mark all visible unmarked candidates in all
sources."
(interactive "P")
(with-helm-alive-p
- (with-helm-window ; Using `with-helm-buffer' for some unknow reasons infloop.
+ (with-helm-window ; Using `with-helm-buffer' for some unknow
+ ; reasons infloop.
+ (set-window-margins (selected-window) 1)
(if (null all)
(helm-mark-all-1 t)
(let ((pos (point)))
@@ -7033,7 +7104,7 @@ starting it is not needed."
(helm-mark-current-line)
(let* ((prefix (get-text-property (point-at-bol) 'display))
(cand (helm-get-selection
- nil (helm-attr 'marked-with-props src)
+ nil (helm-get-attr 'marked-with-props src)
src))
(bn (and filecomp-p (helm-basename cand))))
;; Don't mark possibles directories ending with . or ..
@@ -7043,7 +7114,7 @@ starting it is not needed."
;; Non existing files in HFF and
;; RFN. Display may be an image. See
;; https://github.com/yyoncho/helm-treemacs-icons/issues/5
- ;; and also issue #2296.
+ ;; and also Bug#2296.
(equal prefix "[?]")
(and filecomp-p
(or
@@ -7069,7 +7140,8 @@ starting it is not needed."
(helm-clear-visible-mark))
(setq helm-marked-candidates nil)
(helm-mark-current-line)
- (helm-display-mode-line (helm-get-current-source)))))
+ (helm-display-mode-line (helm-get-current-source))
+ (set-window-margins (selected-window) 0))))
(put 'helm-unmark-all 'helm-only t)
(defun helm-toggle-all-marks (&optional all)
@@ -7128,7 +7200,7 @@ sources."
sel)
(unless candidates
(setq sel (helm-get-selection
- nil (helm-attr 'marked-with-props
+ nil (helm-get-attr 'marked-with-props
current-src)
current-src))
(setq candidates
@@ -7155,18 +7227,29 @@ sources."
(with-current-buffer helm-buffer
(save-excursion
(cl-dolist (o helm-visible-mark-overlays)
- (let ((o-src-str (overlay-get o 'source))
- (o-str (overlay-get o 'string))
- beg end)
+ (let* ((source (overlay-get o 'source))
+ (ov-src-name (assoc-default 'name source))
+ (ov-str (overlay-get o 'string))
+ (ov-real (overlay-get o 'real))
+ (ov-ml-str (helm-aif (helm-get-attr 'multiline source)
+ (if (numberp it)
+ ;; Assume display have been computed
+ ;; against real e.g. kill-ring.
+ (helm--multiline-get-truncated-candidate
+ ov-real it)
+ ov-str)
+ ov-str))
+ beg end)
;; Move point to end of source header line.
(goto-char (point-min))
- (search-forward o-src-str nil t)
- (while (and (search-forward o-str nil t)
+ (search-forward ov-src-name nil t)
+ (while (and (search-forward ov-ml-str nil t)
(cl-loop for ov in (overlays-at (point-at-bol 0))
never (overlay-get ov 'visible-mark))
- (helm-current-source-name= o-src-str))
+ (helm-current-source-name= ov-src-name))
(setq beg (match-beginning 0)
- end (match-end 0))
+ end (if (string= ov-ml-str ov-str)
+ (match-end 0) (1+ (match-end 0))))
;; Calculate real value of candidate.
;; It can be nil if candidate have only a display value.
(let ((real (get-text-property (point-at-bol 0) 'helm-realvalue)))
@@ -7175,10 +7258,10 @@ sources."
;; than the one stored in overlay.
;; This is needed when some cands have same display names.
;; Using equal allow testing any type of value for real cand.
- ;; Issue (#706).
- (and (equal (overlay-get o 'real) real)
+ ;; bug#706.
+ (and (equal ov-real real)
(move-overlay o beg end))
- (and (equal o-str (buffer-substring beg end))
+ (and (equal ov-str (buffer-substring beg end))
(move-overlay o beg end))))))))))
(add-hook 'helm-after-update-hook 'helm-revive-visible-mark)
@@ -7252,20 +7335,22 @@ perform actions."
(format "%s" (helm-get-selection nil (not arg))))))
(put 'helm-kill-selection-and-quit 'helm-only t)
-(defun helm-copy-to-buffer ()
- "Copy selection or marked candidates to `helm-current-buffer'.
-Note that the real values of candidates are copied and not the
-display values."
- (interactive)
+(defun helm-insert-or-copy (&optional arg)
+ "Insert selection or marked candidates in current buffer.
+
+With a prefix arg copy marked candidates to kill-ring.
+The real value of each candidate is used."
+ (interactive "P")
(with-helm-alive-p
(helm-run-after-exit
(lambda (cands)
(with-helm-current-buffer
- (insert (mapconcat (lambda (c)
- (format "%s" c))
- cands "\n"))))
+ (let ((sels (mapconcat (lambda (c)
+ (format "%s" c))
+ cands "\n")))
+ (if arg (kill-new sels) (insert sels)))))
(helm-marked-candidates))))
-(put 'helm-copy-to-buffer 'helm-only t)
+(put 'helm-insert-or-copy 'helm-only t)
;;; Follow-mode: Automatic execution of persistent-action
@@ -7375,11 +7460,11 @@ source or `helm-follow-input-idle-delay' or
(defun helm-follow-mode-p (&optional source)
(with-helm-buffer
- (eq (helm-attr 'follow (or source (helm-get-current-source))) 1)))
+ (eq (helm-get-attr 'follow (or source (helm-get-current-source))) 1)))
(defun helm-follow-mode-set-source (value &optional source)
(with-helm-buffer
- (helm-attrset 'follow value (or source (helm-get-current-source)))))
+ (helm-set-attr 'follow value (or source (helm-get-current-source)))))
;;; Auto-resize mode
;;
@@ -7455,10 +7540,4 @@ help."
(provide 'helm)
-;; Local Variables:
-;; byte-compile-warnings: (not obsolete)
-;; coding: utf-8
-;; indent-tabs-mode: nil
-;; End:
-
;;; helm.el ends here