summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog6
-rw-r--r--helm-command.el2
-rw-r--r--helm-core-pkg.el2
-rw-r--r--helm-elisp.el7
-rw-r--r--helm-eshell.el30
-rw-r--r--helm-files.el77
-rw-r--r--helm-grep.el4
-rw-r--r--helm-help.el14
-rw-r--r--helm-imenu.el4
-rw-r--r--helm-lib.el132
-rw-r--r--helm-locate.el1
-rw-r--r--helm-mode.el97
-rw-r--r--helm-pkg.el4
-rw-r--r--helm-semantic.el2
-rw-r--r--helm-types.el1
-rw-r--r--helm.el74
16 files changed, 345 insertions, 112 deletions
diff --git a/debian/changelog b/debian/changelog
index a35ef18e..734a7dcb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+helm (2.8.0-1) unstable; urgency=medium
+
+ * New upstream release.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Tue, 20 Jun 2017 08:38:39 +0100
+
helm (2.7.1-1) unstable; urgency=medium
* New upstream release.
diff --git a/helm-command.el b/helm-command.el
index 61cd8d86..726fcabf 100644
--- a/helm-command.el
+++ b/helm-command.el
@@ -285,7 +285,7 @@ You can get help on each command by persistent action."
(cl-flet ((save-hist (command)
(setq extended-command-history
(cons command (delete command extended-command-history)))))
- (condition-case err
+ (condition-case-unless-debug err
(progn
(command-execute sym-com 'record)
(save-hist command-name))
diff --git a/helm-core-pkg.el b/helm-core-pkg.el
index 72616ed6..d7623542 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.7.1"
+(define-package "helm-core" "2.8.0"
"Development files for Helm"
'((emacs "24.4")
(async "1.9.2"))
diff --git a/helm-elisp.el b/helm-elisp.el
index db315886..0aa5c62b 100644
--- a/helm-elisp.el
+++ b/helm-elisp.el
@@ -673,9 +673,10 @@ Filename completion happen if string start after or between a double quote."
:input c)))
(defun helm-info-lookup-symbol (candidate)
- ;; Running an idle-timer allow not catching RET
- ;; when exiting with the fallback source.
- (run-with-idle-timer 0.01 nil #'helm-info-lookup-symbol-1 candidate))
+ ;; ???:Running an idle-timer allows not catching RET when exiting
+ ;; with the fallback source.
+ ;; (run-with-idle-timer 0.01 nil #'helm-info-lookup-symbol-1 candidate)
+ (helm-info-lookup-symbol-1 candidate))
;;;###autoload
(defun helm-apropos (default)
diff --git a/helm-eshell.el b/helm-eshell.el
index bb64d8e3..7ef9490e 100644
--- a/helm-eshell.el
+++ b/helm-eshell.el
@@ -74,7 +74,7 @@
;; Remove it for the helm one. (Fixed in Emacs24)
(remove-hook 'minibuffer-setup-hook 'eshell-mode)))
(candidates :initform 'helm-esh-get-candidates)
- (nomark :initform t)
+ ;(nomark :initform t)
(persistent-action :initform 'ignore)
(nohighlight :initform t)
(filtered-candidate-transformer
@@ -95,7 +95,7 @@
;; Internal.
(defvar helm-ec-target "")
-(defun helm-ec-insert (candidate)
+(defun helm-ec-insert (_candidate)
"Replace text at point with CANDIDATE.
The function that call this should set `helm-ec-target' to thing at point."
(let ((pt (point)))
@@ -104,14 +104,19 @@ The function that call this should set `helm-ec-target' to thing at point."
(string= (buffer-substring (point) pt) helm-ec-target))
(delete-region (point) pt)))
(when (string-match "\\`\\*" helm-ec-target) (insert "*"))
- (cond ((string-match "\\`~/?" helm-ec-target)
- (insert (helm-quote-whitespace (abbreviate-file-name candidate))))
- ((string-match "\\`/" helm-ec-target)
- (insert (helm-quote-whitespace candidate)))
- (t
- (insert (concat (and (string-match "\\`[.]/" helm-ec-target) "./")
- (helm-quote-whitespace
- (file-relative-name candidate)))))))
+ (let ((marked (helm-marked-candidates)))
+ (insert
+ (mapconcat
+ (lambda (x)
+ (cond ((string-match "\\`~/?" helm-ec-target)
+ (helm-quote-whitespace (abbreviate-file-name x)))
+ ((string-match "\\`/" helm-ec-target)
+ (helm-quote-whitespace x))
+ (t
+ (concat (and (string-match "\\`[.]/" helm-ec-target) "./")
+ (helm-quote-whitespace
+ (file-relative-name x))))))
+ marked " "))))
(defun helm-esh-get-candidates ()
"Get candidates for eshell completion using `pcomplete'."
@@ -131,7 +136,10 @@ The function that call this should set `helm-ec-target' to thing at point."
(not (string= entry ""))
(file-name-as-directory
(expand-file-name entry default-directory)))
- for i in (all-completions pcomplete-stub table)
+ with comps = (all-completions pcomplete-stub table)
+ unless comps return (prog1 nil
+ (message "No completions of %s" pcomplete-stub))
+ for i in comps
;; Transform the related names to abs names.
for file-cand = (and exp-entry
(if (file-remote-p i) i
diff --git a/helm-files.el b/helm-files.el
index 5fc8c46f..baed04b3 100644
--- a/helm-files.el
+++ b/helm-files.el
@@ -292,6 +292,14 @@ it checks if a file is in one of these directories.
Remote filesystem are generally mounted with sshfs."
:group 'helm-files
:type '(repeat string))
+
+(defcustom helm-browse-project-default-find-files-fn
+ #'helm-browse-project-walk-directory
+ "The default function to retrieve files in a non-vc directory.
+
+A function that takes a directory name as only arg."
+ :group 'helm-files
+ :type 'function)
;;; Faces
;;
@@ -370,6 +378,7 @@ Remote filesystem are generally mounted with sshfs."
(define-key map (kbd "C-x C-d") 'helm-ff-run-browse-project)
(define-key map (kbd "C-x r m") 'helm-ff-bookmark-set)
(define-key map (kbd "C-x r b") 'helm-find-files-toggle-to-bookmark)
+ (define-key map (kbd "C-x C-q") 'helm-ff-run-marked-files-in-dired)
(define-key map (kbd "C-s") 'helm-ff-run-grep)
(define-key map (kbd "M-g s") 'helm-ff-run-grep)
(define-key map (kbd "M-g p") 'helm-ff-run-pdfgrep)
@@ -484,6 +493,7 @@ Don't set it directly, use instead `helm-ff-auto-update-initial-value'.")
"Find file in Dired" 'helm-point-file-in-dired
"View file" 'view-file
"Query replace fnames on marked `M-%'" 'helm-ff-query-replace-on-marked
+ "Marked files in dired" 'helm-marked-files-in-dired
"Query replace contents on marked" 'helm-ff-query-replace
"Query replace regexp contents on marked" 'helm-ff-query-replace-regexp
"Attach file(s) to mail buffer" 'helm-ff-mail-attach-files
@@ -1028,11 +1038,11 @@ This doesn't replace inside the files, only modify filenames."
for new = (concat (helm-basedir old)
(replace-regexp-in-string
(cond ((string= regexp "%.")
- (helm-basename old t))
+ (regexp-quote (helm-basename old t)))
((string= regexp ".%")
- (file-name-extension old))
+ (regexp-quote (file-name-extension old)))
((string= regexp "%")
- (helm-basename old))
+ (regexp-quote (helm-basename old)))
(t regexp))
(save-match-data
(cond ((string-match "\\\\#" str)
@@ -1746,11 +1756,43 @@ and should be used carefully elsewhere, or not at all, using
(dired (file-name-directory target))
(dired-goto-file target))))
+(defun helm-marked-files-in-dired (_candidate)
+ "Open a dired buffer with only marked files.
+
+With a prefix arg toggle dired buffer to wdired mode."
+ (advice-add 'wdired-finish-edit :override #'helm--advice-wdired-finish-edit)
+ (advice-add 'wdired-get-filename :override #'helm--advice-wdired-get-filename)
+ (let* ((marked (helm-marked-candidates))
+ (current (car marked)))
+ (unless (and ffap-url-regexp
+ (string-match-p ffap-url-regexp current))
+ (let ((target (expand-file-name (helm-substitute-in-filename current))))
+ (dired (cons helm-ff-default-directory marked))
+ (dired-goto-file target)
+ (when (or helm-current-prefix-arg current-prefix-arg)
+ (call-interactively 'wdired-change-to-wdired-mode))))))
+
+(defun helm-ff-run-marked-files-in-dired ()
+ "Execute `helm-marked-files-in-dired' interactively."
+ (interactive)
+ (with-helm-alive-p
+ (helm-exit-and-execute-action 'helm-marked-files-in-dired)))
+(put 'helm-ff-run-marked-files-in-dired 'helm-only t)
+
(defun helm-create-tramp-name (fname)
- "Build filename for `helm-pattern' like /su:: or /sudo::."
+ "Build filename from `helm-pattern' like /su:: or /sudo::."
+ ;; `tramp-make-tramp-file-name' takes 7 args on emacs-26 whereas it
+ ;; takes only 5 args in emacs-24/25.
(apply #'tramp-make-tramp-file-name
- (cl-loop with v = (tramp-dissect-file-name fname)
- for i across v collect i)))
+ ;; `tramp-dissect-file-name' returns a list in emacs-26
+ ;; whereas in 24.5 it returns a vector, thus the car is a
+ ;; symbol (`tramp-file-name') which is not needed as argument
+ ;; for `tramp-make-tramp-file-name' so transform the cdr in
+ ;; vector, and for 24.5 use directly the returned value.
+ (cl-loop with v = (pcase (tramp-dissect-file-name fname)
+ (`(,_l . ,ll) (vconcat ll))
+ ((and vec (pred vectorp)) vec))
+ for i across v collect i)))
(defun helm-ff-get-tramp-methods ()
"Returns a list of the car of `tramp-methods'."
@@ -3369,12 +3411,28 @@ Set `recentf-max-saved-items' to a bigger value if default is too small.")
name (abbreviate-file-name directory)))
:buffer-list (lambda () (helm-browse-project-get-buffers directory))))
+(defun helm-browse-project-walk-directory (directory)
+ "Default function for `helm-browse-project-default-find-files-fn'."
+ (helm-walk-directory
+ directory
+ :directories nil :path 'full :skip-subdirs t))
+
+(defun helm-browse-project-ag-find-files (directory)
+ "A suitable function for `helm-browse-project-default-find-files-fn'.
+
+Needs AG as backend."
+ (with-temp-buffer
+ (call-process-shell-command
+ (format "ag --hidden -g '.*' %s" directory)
+ nil t nil)
+ (mapcar (lambda (f) (expand-file-name f directory))
+ (split-string (buffer-string) "\n"))))
+
(defun helm-browse-project-find-files (directory &optional refresh)
(when refresh (remhash directory helm--browse-project-cache))
(unless (gethash directory helm--browse-project-cache)
- (puthash directory (helm-walk-directory
- directory
- :directories nil :path 'full :skip-subdirs t)
+ (puthash directory (funcall helm-browse-project-default-find-files-fn
+ directory)
helm--browse-project-cache))
(helm :sources `(,(helm-browse-project-build-buffers-source directory)
,(helm-build-in-buffer-source "Browse project"
@@ -3828,6 +3886,7 @@ This is the starting point for nearly all actions you can do on files."
(null hist))
(helm-basename it) it))))
(set-text-properties 0 (length input) nil input)
+ (setq current-prefix-arg nil)
(helm-find-files-1 input (and presel (null helm-ff-no-preselect)
(concat "^" (regexp-quote presel))))))
diff --git a/helm-grep.el b/helm-grep.el
index 6a2c64ed..b96170cf 100644
--- a/helm-grep.el
+++ b/helm-grep.el
@@ -1449,12 +1449,12 @@ if available with current AG version."
(propertize helm-grep-last-cmd-line
'face 'helm-grep-cmd-line)))
(setq mode-line-format
- '(" " mode-line-buffer-identification " "
+ `(" " mode-line-buffer-identification " "
(:eval (format "L%s" (helm-candidate-number-at-point))) " "
(:eval (propertize
(format
"[%s process finished - (no results)] "
- (upcase proc-name))
+ ,(upcase proc-name))
'face 'helm-grep-finish))))))
((string= event "finished\n")
(helm-log "%s process finished with %s results in %fs"
diff --git a/helm-help.el b/helm-help.el
index 3ffb7541..f4c00ac4 100644
--- a/helm-help.el
+++ b/helm-help.el
@@ -235,6 +235,15 @@ Behave differently depending of `helm-selection' (current candidate in helm-buff
- candidate is a file => open it.
- marked candidates (1+) => open them with default action.
+Note that when copying, renaming etc... from `helm-find-files' you
+will have a file completion with `helm-read-file-name' to select the
+destination file; To not confuse users of `read-file-name' or
+`read-directory-name' RET behave normally, it exit the minibuffer as
+soon as you press RET, if you want the same behavior as in
+`helm-find-files', bind `helm-ff-RET' to the `helm-read-file-map':
+
+ (define-key helm-read-file-map (kbd \"RET\") 'helm-ff-RET)
+
*** Find file at point
Helm is using `ffap' partially or completely to find file at point
@@ -455,6 +464,11 @@ and are not renamed to current directory, IOW use this (\\#) to rename files ins
In the second prompt (replace regexp with) shortcut for `upcase', `downcase' and `capitalize'
are available, respectively `%u', `%d' and `%c'.
+*** Edit marked files in a dired buffer
+
+You can open a dired buffer with only marked files with `\\<helm-find-files-map>\\[helm-ff-run-marked-files-in-dired]'
+With a prefix arg you can open this same dired buffer in wdired mode for editing files.
+
*** Copying renaming asynchronously
If you use async library (if you have installed helm from MELPA you do) you can enable
diff --git a/helm-imenu.el b/helm-imenu.el
index 52482619..39dfc41b 100644
--- a/helm-imenu.el
+++ b/helm-imenu.el
@@ -305,7 +305,7 @@ Each car is a regexp match pattern of the imenu type string."
(helm-execute-action-at-once-if-one
helm-imenu-execute-action-at-once-if-one))
(helm :sources 'helm-source-imenu
- :default (list (concat "\\_<" str "\\_>") str)
+ :default (list (concat "\\_<" (and str (regexp-quote str)) "\\_>") str)
:preselect str
:buffer "*helm imenu*")))
@@ -338,7 +338,7 @@ or it have an association in `helm-imenu-all-buffer-assoc'."
(helm-imenu-candidates-in-all-buffers 'build-sources)
'(helm-source-imenu-all))))
(helm :sources sources
- :default (list (concat "\\_<" str "\\_>") str)
+ :default (list (concat "\\_<" (and str (regexp-quote str)) "\\_>") str)
:preselect (unless helm--maybe-use-default-as-input str)
:buffer "*helm imenu all*")))
diff --git a/helm-lib.el b/helm-lib.el
index f30c6ae6..a6591aff 100644
--- a/helm-lib.el
+++ b/helm-lib.el
@@ -35,6 +35,8 @@
(declare-function org-content "org.el")
(defvar helm-current-position)
+(eval-when-compile (require 'wdired))
+(defvar wdired-old-marks)
;;; User vars.
;;
@@ -97,6 +99,136 @@ When only `add-text-properties' is available APPEND is ignored."
(if (fboundp 'add-face-text-property)
(add-face-text-property beg end face append object)
(add-text-properties beg end `(face ,face) object)))
+
+;; Override `wdired-finish-edit'.
+;; Fix emacs bug in `wdired-finish-edit' where
+;; Wdired is not handling the case where `dired-directory' is a cons
+;; cell instead of a string.
+(defun helm--advice-wdired-finish-edit ()
+ (interactive)
+ (wdired-change-to-dired-mode)
+ (let ((changes nil)
+ (errors 0)
+ files-deleted
+ files-renamed
+ some-file-names-unchanged
+ file-old file-new tmp-value)
+ (save-excursion
+ (when (and wdired-allow-to-redirect-links
+ (fboundp 'make-symbolic-link))
+ (setq tmp-value (wdired-do-symlink-changes))
+ (setq errors (cdr tmp-value))
+ (setq changes (car tmp-value)))
+ (when (and wdired-allow-to-change-permissions
+ (boundp 'wdired-col-perm)) ; could have been changed
+ (setq tmp-value (wdired-do-perm-changes))
+ (setq errors (+ errors (cdr tmp-value)))
+ (setq changes (or changes (car tmp-value))))
+ (goto-char (point-max))
+ (while (not (bobp))
+ (setq file-old (wdired-get-filename nil t))
+ (when file-old
+ (setq file-new (wdired-get-filename))
+ (if (equal file-new file-old)
+ (setq some-file-names-unchanged t)
+ (setq changes t)
+ (if (not file-new) ;empty filename!
+ (push file-old files-deleted)
+ (when wdired-keep-marker-rename
+ (let ((mark (cond ((integerp wdired-keep-marker-rename)
+ wdired-keep-marker-rename)
+ (wdired-keep-marker-rename
+ (cdr (assoc file-old wdired-old-marks)))
+ (t nil))))
+ (when mark
+ (push (cons (substitute-in-file-name file-new) mark)
+ wdired-old-marks))))
+ (push (cons file-old (substitute-in-file-name file-new))
+ files-renamed))))
+ (forward-line -1)))
+ (when files-renamed
+ (setq errors (+ errors (wdired-do-renames files-renamed))))
+ (if changes
+ (progn
+ ;; If we are displaying a single file (rather than the
+ ;; contents of a directory), change dired-directory if that
+ ;; file was renamed. (This ought to be generalized to
+ ;; handle the multiple files case, but that's less trivial)
+ ;; fixit [1].
+ (cond ((and (stringp dired-directory)
+ (not (file-directory-p dired-directory))
+ (null some-file-names-unchanged)
+ (= (length files-renamed) 1))
+ (setq dired-directory (cdr (car files-renamed))))
+ ;; Fix [1] i.e dired buffers created with
+ ;; (dired '(foo f1 f2 f3)).
+ ((and (consp dired-directory)
+ (cdr dired-directory)
+ files-renamed)
+ (setcdr dired-directory
+ ;; Replace in `dired-directory' files that have
+ ;; been modified with their new name keeping
+ ;; the ones that are unmodified at the same place.
+ (cl-loop with old-to-rename = (mapcar 'car files-renamed)
+ for f in (cdr dired-directory)
+ if (member f old-to-rename)
+ collect (assoc-default f files-renamed)
+ else collect f))))
+ ;; Re-sort the buffer.
+ (revert-buffer)
+ (let ((inhibit-read-only t))
+ (dired-mark-remembered wdired-old-marks)))
+ (let ((inhibit-read-only t))
+ (remove-text-properties (point-min) (point-max)
+ '(old-name nil end-name nil old-link nil
+ end-link nil end-perm nil
+ old-perm nil perm-changed nil))
+ (message "(No changes to be performed)")))
+ (when files-deleted
+ (wdired-flag-for-deletion files-deleted))
+ (when (> errors 0)
+ (dired-log-summary (format "%d rename actions failed" errors) nil)))
+ (set-buffer-modified-p nil)
+ (setq buffer-undo-list nil))
+
+;; Override `wdired-get-filename'.
+;; Fix emacs bug in `wdired-get-filename' which returns the current
+;; directory concatened with the filename i.e
+;; "/home/you//home/you/foo" when filename is absolute in dired
+;; buffer.
+;; In consequence Wdired try to rename files even when buffer have
+;; been modified and corrected, e.g delete one char and replace it so
+;; that no change to file is done.
+;; This also lead to ask confirmation for every files even when not
+;; modified and when `wdired-use-interactive-rename' is nil.
+(defun helm--advice-wdired-get-filename (&optional no-dir old)
+ ;; FIXME: Use dired-get-filename's new properties.
+ (let (beg end file)
+ (save-excursion
+ (setq end (line-end-position))
+ (beginning-of-line)
+ (setq beg (next-single-property-change (point) 'old-name nil end))
+ (unless (eq beg end)
+ (if old
+ (setq file (get-text-property beg 'old-name))
+ ;; In the following form changed `(1+ beg)' to `beg' so that
+ ;; the filename end is found even when the filename is empty.
+ ;; Fixes error and spurious newlines when marking files for
+ ;; deletion.
+ (setq end (next-single-property-change beg 'end-name))
+ (setq file (buffer-substring-no-properties (1+ beg) end)))
+ ;; Don't unquote the old name, it wasn't quoted in the first place
+ (and file (setq file (condition-case _err
+ ;; emacs-25+
+ (apply #'wdired-normalize-filename
+ (list file (not old)))
+ (wrong-number-of-arguments
+ ;; emacs-24
+ (wdired-normalize-filename file))))))
+ (if (or no-dir old (and file (file-name-absolute-p file)))
+ file
+ (and file (> (length file) 0)
+ (expand-file-name file (dired-current-directory)))))))
;;; Macros helper.
;;
diff --git a/helm-locate.el b/helm-locate.el
index 01c7738f..65af7aac 100644
--- a/helm-locate.el
+++ b/helm-locate.el
@@ -152,6 +152,7 @@ help for more infos."
(define-key map (kbd "C-c X") 'helm-ff-run-open-file-with-default-tool)
(define-key map (kbd "M-.") 'helm-ff-run-etags)
(define-key map (kbd "C-c @") 'helm-ff-run-insert-org-link)
+ (define-key map (kbd "C-x C-q") 'helm-ff-run-marked-files-in-dired)
map)
"Generic Keymap for files.")
diff --git a/helm-mode.el b/helm-mode.el
index c2a2a5b9..0a1f4052 100644
--- a/helm-mode.el
+++ b/helm-mode.el
@@ -158,14 +158,6 @@ and all functions belonging in this list from `minibuffer-setup-hook'."
"Keymap use as must-match-map in `helm-comp-read' and `helm-read-file-name'.")
-;;; Internal
-;;
-;;
-;; Flag to know if `helm-pattern' have been added
-;; to candidate list in `helm-comp-read'.
-(defvar helm-cr--unknown-pattern-flag nil)
-
-
;;; helm-comp-read
;;
;;
@@ -265,28 +257,46 @@ If COLLECTION is an `obarray', a TEST should be needed. See `obarray'."
(t (all-completions input collection test)))))
(if sort-fn (sort cands sort-fn) cands))))
-(defun helm-cr-default-transformer (candidates _source)
+(defun helm-cr--pattern-in-candidates-p (candidates)
+ (or (assoc helm-pattern candidates)
+ (assq (intern helm-pattern) candidates)
+ (member helm-pattern candidates)
+ (member (downcase helm-pattern) candidates)
+ (member (upcase helm-pattern) candidates)))
+
+(defun helm-cr-default-transformer (candidates source)
"Default filter candidate function for `helm-comp-read'."
- (when (and (null candidates) (not (string= helm-pattern "")))
- (setq helm-cr--unknown-pattern-flag t
- candidates (list helm-pattern)))
- (cl-loop for c in candidates
- for cand = (if (stringp c) (replace-regexp-in-string "\\s\\" "" c) c)
- for pat = (replace-regexp-in-string "\\s\\" "" helm-pattern)
- if (and (equal cand pat) helm-cr--unknown-pattern-flag)
- collect
- (cons (concat (propertize
- " " 'display
- (propertize "[?]" 'face 'helm-ff-prefix))
- c)
- c)
- into lst
- else collect (if (and (stringp cand)
- (string-match "\n" cand))
- (cons (replace-regexp-in-string "\n" "->" c) c)
- c)
- into lst
- finally return (helm-fast-remove-dups lst :test 'equal)))
+ (let ((must-match (helm-attr 'must-match source))
+ unknown-pattern)
+ (unless (or (eq must-match t)
+ (string= helm-pattern "")
+ (helm-cr--pattern-in-candidates-p candidates))
+ (setq candidates (append (list
+ ;; Unquote helm-pattern
+ ;; when it is added
+ ;; as candidate.
+ (replace-regexp-in-string
+ "\\s\\" "" helm-pattern))
+ candidates))
+ ;; Notify pattern have been added to candidates.
+ (setq unknown-pattern t))
+ (cl-loop for c in candidates
+ for cand = (if (stringp c)
+ (replace-regexp-in-string "\\s\\" "" c) c)
+ for pat = (replace-regexp-in-string "\\s\\" "" helm-pattern)
+ if (and (equal c pat) unknown-pattern) collect
+ (cons (concat (propertize
+ " " 'display
+ (propertize "[?]" 'face 'helm-ff-prefix))
+ c)
+ c)
+ into lst
+ else collect (if (and (stringp cand)
+ (string-match "\n" cand))
+ (cons (replace-regexp-in-string "\n" "->" c) c)
+ c)
+ into lst
+ finally return (helm-fast-remove-dups lst :test 'equal))))
(defun helm-comp-read--move-to-first-real-candidate ()
(helm-aif (helm-get-selection nil 'withprop)
@@ -470,21 +480,6 @@ that use `helm-comp-read' See `helm-M-x' for example."
(lambda ()
(let ((cands (helm-comp-read-get-candidates
collection test sort alistp)))
- (unless (or (eq must-match t)
- (string= helm-pattern "")
- (assoc helm-pattern cands)
- (assoc (intern helm-pattern) cands)
- (member helm-pattern cands)
- (member (downcase helm-pattern) cands)
- (member (upcase helm-pattern) cands))
- (setq cands (append (list
- ;; Unquote helm-pattern
- ;; when it is added
- ;; as candidate.
- (replace-regexp-in-string
- "\\s\\" "" helm-pattern))
- cands))
- (setq helm-cr--unknown-pattern-flag t))
(helm-cr-default default cands))))
(history-get-candidates
(lambda ()
@@ -514,8 +509,6 @@ that use `helm-comp-read' See `helm-M-x' for example."
:help-message help-message
:action action-fn))
(src (helm-build-sync-source name
- :init (lambda ()
- (setq helm-cr--unknown-pattern-flag nil))
:candidates get-candidates
:match-part match-part
:multiline multiline
@@ -531,12 +524,7 @@ that use `helm-comp-read' See `helm-M-x' for example."
:action action-fn
:volatile volatile))
(src-1 (helm-build-in-buffer-source name
- :init (lambda ()
- (setq helm-cr--unknown-pattern-flag nil))
- :data (lambda ()
- (let ((cands (helm-comp-read-get-candidates
- collection test sort alistp)))
- (helm-cr-default default cands)))
+ :data get-candidates
:match-part match-part
:multiline multiline
:header-name header-name
@@ -550,8 +538,9 @@ that use `helm-comp-read' See `helm-M-x' for example."
:help-message help-message
:action action-fn))
(src-list (list src-hist
- (if candidates-in-buffer
- src-1 src)))
+ (cons (cons 'must-match must-match)
+ (if candidates-in-buffer
+ src-1 src))))
(helm-execute-action-at-once-if-one exec-when-only-one)
(helm-quit-if-no-candidate quit-when-no-cand)
result)
diff --git a/helm-pkg.el b/helm-pkg.el
index b650cf5a..663f60af 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.7.1"
+(define-package "helm" "2.8.0"
"Helm is an Emacs incremental and narrowing framework"
'((emacs "24.4")
(async "1.9.2")
(popup "0.5.3")
- (helm-core "2.7.1"))
+ (helm-core "2.8.0"))
:url "https://emacs-helm.github.io/helm/")
;; Local Variables:
diff --git a/helm-semantic.el b/helm-semantic.el
index 1672df25..9f4720cb 100644
--- a/helm-semantic.el
+++ b/helm-semantic.el
@@ -208,7 +208,7 @@ Fill in the symbol at point by default."
(format "\\_<%s\\_>" (car (semantic-current-tag))))))
(helm :sources source
:candidate-number-limit 9999
- :default (and imenu-p (list (concat "\\_<" str "\\_>") str))
+ :default (and imenu-p (list (concat "\\_<" (and str (regexp-quote str)) "\\_>") str))
:preselect (if (or arg imenu-p) str tag)
:buffer "*helm semantic/imenu*")))
diff --git a/helm-types.el b/helm-types.el
index 2002019f..715bb29f 100644
--- a/helm-types.el
+++ b/helm-types.el
@@ -44,6 +44,7 @@
"Find file other window" 'helm-find-files-other-window
"Find file other frame" 'find-file-other-frame
"Open dired in file's directory" 'helm-open-dired
+ "Marked files in dired" 'helm-marked-files-in-dired
"Grep File(s) `C-u recurse'" 'helm-find-files-grep
"Zgrep File(s) `C-u Recurse'" 'helm-ff-zgrep
"Pdfgrep File(s)" 'helm-ff-pdfgrep
diff --git a/helm.el b/helm.el
index 90411344..51f30425 100644
--- a/helm.el
+++ b/helm.el
@@ -1078,11 +1078,17 @@ you don't need the prefix arg when using \\[helm-mark-all] or \\[helm-toggle-all
** Follow candidates
-You can execute automatically an action specified in the source as persistent-action
-while moving up and down in helm-window or while updating the list of candidates by
-turning on `helm-follow-mode' while in helm.
-The follow behavior will be saved and used in next emacs sessions when `helm-follow-mode-persistent'
-is non-nil.
+You can execute automatically an action specified in the source as
+persistent-action while moving up and down in helm-window or while
+updating the list of candidates by turning on `helm-follow-mode' while
+in helm with \\<helm-map>\\[helm-follow-mode]. The follow behavior
+will be saved and used in next emacs sessions when
+`helm-follow-mode-persistent' is non-nil.
+
+If you just want to follow candidates occasionally without enabling
+`helm-follow-mode' you can use instead \\<helm-map>\\[helm-follow-action-forward] or \\[helm-follow-action-backward].
+Note that when `helm-follow-mode' is enabled these commands are just
+going to next/previous line without executing persistent action.
** Frequently Used Commands
@@ -1447,36 +1453,47 @@ Messages are logged to a file named with todays date and time in this directory.
;;
(defun helm-attr (attribute-name &optional source compute)
"Get the value of ATTRIBUTE-NAME of SRC.
+
If SRC is omitted, use current source.
-If COMPUTE is non-`nil' compute value of ATTRIBUTE-NAME
-with `helm-interpret-value'. COMPUTE can have also 'ignorefn as
-value, in this case `helm-interpret-value' will return a function
-as value unchanged, but will eval a symbol which is bound."
+
+If COMPUTE is non-`nil' compute value of ATTRIBUTE-NAME with
+`helm-interpret-value'. COMPUTE can have also 'ignorefn as value, in
+this case `helm-interpret-value' will return a function as 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 ATTRIBUTE-NAME."
+ (declare (gv-setter
+ (lambda (val)
+ `(let* ((src (or ,source (helm-get-current-source)))
+ (attr (assq ,attribute-name src)))
+ (cl-assert (null ,compute) nil
+ "`setf' can't set the computed value of attribute `%s'"
+ ,attribute-name)
+ (if attr
+ (setcdr attr ,val)
+ (and (setcdr src (cons (cons ,attribute-name ,val)
+ (cdr src)))
+ ,val))))))
(let ((src (or source (helm-get-current-source))))
(helm-aif (assq attribute-name src)
(if compute
(helm-interpret-value (cdr it) src compute)
- (cdr it)))))
-
-(cl-defun helm-attr-defined (attribute-name
- &optional (src (helm-get-current-source)))
- "Return non-`nil' if ATTRIBUTE-NAME of SRC is defined.
-if SRC is omitted, use current source."
- (and (helm-attr attribute-name src) t))
+ (cdr it)))))
(cl-defun helm-attrset (attribute-name value
&optional
(src (helm-get-current-source)))
"Set the value of ATTRIBUTE-NAME of source SRC to VALUE.
+
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."
- (let (done)
- (helm-aif (assq attribute-name src)
- (prog1 (setcdr it value) (setq done t))
- (setcdr src (cons (cons attribute-name value) (cdr src)))
- (setq done t))
- (and done value)))
+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))
(defun helm-add-action-to-source (name fn source &optional index)
"Add new action NAME linked to function FN to SOURCE.
@@ -4608,10 +4625,14 @@ first source."
(helm-move-selection-common :where 'source :direction source-or-name))
(defun helm--follow-action (arg)
- (let ((helm--temp-follow-flag t))
+ (let ((helm--temp-follow-flag t) ; Needed in HFF.
+ (in-follow-mode (helm-follow-mode-p)))
+ ;; When follow-mode is already enabled, just go to next or
+ ;; previous line.
(when (or (eq last-command 'helm-follow-action-forward)
(eq last-command 'helm-follow-action-backward)
- (eq last-command 'helm-execute-persistent-action))
+ (eq last-command 'helm-execute-persistent-action)
+ in-follow-mode)
(if (> arg 0)
(helm-move-selection-common :where 'line
:direction 'next
@@ -4619,7 +4640,8 @@ first source."
(helm-move-selection-common :where 'line
:direction 'previous
:follow nil)))
- (helm-execute-persistent-action)))
+ (unless in-follow-mode
+ (helm-execute-persistent-action))))
(defun helm-follow-action-forward ()
"Go to next line and execute persistent action."