summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--debian/changelog10
-rw-r--r--debian/patches/0003-decruft-README.patch11
-rw-r--r--helm-buffers.el130
-rw-r--r--helm-core-pkg.el2
-rw-r--r--helm-elisp.el76
-rw-r--r--helm-eshell.el114
-rw-r--r--helm-files.el79
-rw-r--r--helm-grep.el13
-rw-r--r--helm-lib.el83
-rw-r--r--helm-net.el5
-rw-r--r--helm-org.el8
-rw-r--r--helm-pkg.el4
-rw-r--r--helm-regexp.el20
-rw-r--r--helm-ring.el24
-rw-r--r--helm-sys.el24
-rw-r--r--helm-types.el7
-rw-r--r--helm-utils.el227
-rw-r--r--helm.el360
19 files changed, 764 insertions, 435 deletions
diff --git a/README.md b/README.md
index 4cfaf1eb..5ffabff3 100644
--- a/README.md
+++ b/README.md
@@ -39,8 +39,6 @@
<a href="https://patreon.com/preview/30231724baf440fabe80d44d0ee77067">
Donate monthly using Patreon</a>
&nbsp;&nbsp;
- <a href="https://gratipay.com/emacs-helm/">
- Donate weekly using Gratipay</a>
</div>
***
diff --git a/debian/changelog b/debian/changelog
index b5d44084..d2ded8b0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,11 @@
+helm (2.8.6-1) unstable; urgency=medium
+
+ * New upstream release.
+ * Refresh 0003-decruft-README.patch
+ * Clean trailing white space in Debian changelog entry for 2.5.0-2.
+
+ -- Sean Whitton <spwhitton@spwhitton.name> Wed, 29 Nov 2017 15:55:18 -0700
+
helm (2.8.5-1) unstable; urgency=medium
* New upstream release.
@@ -56,7 +64,7 @@ helm (2.5.0-2) experimental; urgency=medium
* Team upload.
* debian/control: Make dependencies comply with Debian Emacs Policy.
- Depend on emacsen-common (>= 2.0.8) instead of emacs.
-
+
-- Nicholas D Steeves <nsteeves@gmail.com> Thu, 27 Apr 2017 16:53:19 -0400
helm (2.5.0-1) unstable; urgency=medium
diff --git a/debian/patches/0003-decruft-README.patch b/debian/patches/0003-decruft-README.patch
index b475e4d5..586bb7c5 100644
--- a/debian/patches/0003-decruft-README.patch
+++ b/debian/patches/0003-decruft-README.patch
@@ -33,7 +33,7 @@ Subject: decruft-README
<a href="https://github.com/emacs-helm/helm/wiki"><b>Helm wiki</b></a> |
<a href="https://github.com/emacs-helm/helm/wiki/FAQ"><b>FAQ</b></a>
</p>
-@@ -46,22 +34,13 @@
+@@ -46,16 +34,10 @@
<div align="center">
<a href="https://www.paypal.me/thierryvolpiatto/20">
@@ -50,16 +50,9 @@ Subject: decruft-README
- src="https://github.com/emacs-helm/helm/blob/master/images/patreon-25x.png?raw=true"></a>
+ Donate monthly using Patreon</a>
&nbsp;&nbsp;
- <a href="https://gratipay.com/emacs-helm/">
-- <img title="Donate weekly using Gratipay"
-- alt="Donate monthly using Patreon"
-- style="height: 50px; width: auto;"
-- src="https://cdn.rawgit.com/gratipay/gratipay-badge/2.3.0/dist/gratipay.png"></a>
-+ Donate weekly using Gratipay</a>
</div>
- ***
-@@ -70,8 +49,4 @@
+@@ -65,8 +47,4 @@
Helm in action searching with <a href="https://github.com/ggreer/the_silver_searcher"<b>Grep Ag</b></a>
</p>
diff --git a/helm-buffers.el b/helm-buffers.el
index b6d89a84..c16d4966 100644
--- a/helm-buffers.el
+++ b/helm-buffers.el
@@ -154,6 +154,18 @@ this source is accessible and properly loaded."
"Face used for non-file buffers in `helm-buffers-list'."
:group 'helm-buffers-faces)
+(defvar helm-buffers-tick-counter nil
+ "Allows recording local changes to a non-file buffer.
+Typical usage of this var is for modes that want to see if
+their buffers have changed since last visit.
+Such programs may want to record tick counter after visiting their
+buffers like this:
+
+ (setq helm-buffers-tick-counter (buffer-modified-tick))
+
+Note that this variable is buffer-local.")
+(make-variable-buffer-local 'helm-buffers-tick-counter)
+
;;; Buffers keymap
;;
@@ -197,15 +209,19 @@ this source is accessible and properly loaded."
map))
-(defvar helm-buffers-list-cache nil)
(defvar helm-buffer-max-len-mode nil)
(defvar helm-buffers-in-project-p nil)
(defun helm-buffers-list--init ()
(require 'dired)
;; Issue #51 Create the list before `helm-buffer' creation.
- (setq helm-buffers-list-cache (funcall (helm-attr 'buffer-list)))
- (let ((result (cl-loop for b in helm-buffers-list-cache
+ ;; We were using a global cache in the past and 'candidates was
+ ;; bound to this cache, this was a problem when using more than one
+ ;; source with a different 'buffer-list fn as the same cache was
+ ;; reused in each source (issue #1907), now 'candidates attr is set
+ ;; directly so that each list of candidates is local to source.
+ (helm-attrset 'candidates (funcall (helm-attr 'buffer-list)))
+ (let ((result (cl-loop for b in (helm-attr 'candidates)
maximize (length b) into len-buf
maximize (length (with-current-buffer b
(format-mode-line mode-name)))
@@ -224,15 +240,9 @@ this source is accessible and properly loaded."
:documentation
" A function with no arguments to create buffer list.")
(init :initform 'helm-buffers-list--init)
- (candidates :initform helm-buffers-list-cache)
(multimatch :initform nil)
(match :initform 'helm-buffers-match-function)
(persistent-action :initform 'helm-buffers-list-persistent-action)
- (resume :initform (lambda ()
- (run-with-idle-timer
- 0.1 nil (lambda ()
- (with-helm-buffer
- (helm-force-update))))))
(keymap :initform helm-buffer-map)
(migemo :initform 'nomultimatch)
(volatile :initform t)
@@ -333,6 +343,7 @@ See `ido-make-buffer-list' for more infos."
'face face2)))))
(defun helm-buffer--details (buffer &optional details)
+ (require 'dired)
(let* ((mode (with-current-buffer buffer (format-mode-line mode-name)))
(buf (get-buffer buffer))
(size (propertize (helm-buffer-size buf)
@@ -376,6 +387,13 @@ See `ido-make-buffer-list' for more infos."
(helm-buffer--show-details
name name-prefix file-name size mode dir
'helm-buffer-file 'helm-buffer-process nil details 'filebuf))
+ ;; A non-file, modified buffer
+ ((with-current-buffer name
+ (and helm-buffers-tick-counter
+ (/= helm-buffers-tick-counter (buffer-modified-tick))))
+ (helm-buffer--show-details
+ name (and proc name-prefix) dir size mode dir
+ 'helm-buffer-modified 'helm-buffer-process proc details 'nofile-mod))
;; Any non--file buffer.=>italic
(t
(helm-buffer--show-details
@@ -386,36 +404,39 @@ See `ido-make-buffer-list' for more infos."
"Transformer function to highlight BUFFERS list.
Should be called after others transformers i.e (boring buffers)."
(cl-loop for i in buffers
- for (name size mode meta) = (if helm-buffer-details-flag
- (helm-buffer--details i 'details)
- (helm-buffer--details i))
- for truncbuf = (if (> (string-width name) helm-buffer-max-length)
- (helm-substring-by-width
- name helm-buffer-max-length
- helm-buffers-end-truncated-string)
- (concat name
- (make-string
- (- (+ helm-buffer-max-length
- (length helm-buffers-end-truncated-string))
- (string-width name)) ? )))
- for len = (length mode)
- when (> len helm-buffer-max-len-mode)
- do (setq helm-buffer-max-len-mode len)
- for fmode = (concat (make-string
- (- (max helm-buffer-max-len-mode len) len) ? )
- mode)
- ;; The max length of a number should be 1023.9X where X is the
- ;; units, this is 7 characters.
- for formatted-size = (and size (format "%7s" size))
- collect (let ((helm-pattern (helm-buffers--pattern-sans-filters
- (and helm-buffers-fuzzy-matching ""))))
- (cons (if helm-buffer-details-flag
- (concat
- (funcall helm-fuzzy-matching-highlight-fn truncbuf)
- "\t" formatted-size
- " " fmode " " meta)
- (funcall helm-fuzzy-matching-highlight-fn name))
- (get-buffer i)))))
+ for (name size mode meta) = (if helm-buffer-details-flag
+ (helm-buffer--details i 'details)
+ (helm-buffer--details i))
+ for truncbuf = (if (> (string-width name) helm-buffer-max-length)
+ (helm-substring-by-width
+ name helm-buffer-max-length
+ helm-buffers-end-truncated-string)
+ (concat name
+ (make-string
+ (- (+ helm-buffer-max-length
+ (length
+ helm-buffers-end-truncated-string))
+ (string-width name))
+ ? )))
+ for len = (length mode)
+ when (> len helm-buffer-max-len-mode)
+ do (setq helm-buffer-max-len-mode len)
+ for fmode = (concat (make-string
+ (- (max helm-buffer-max-len-mode len) len) ? )
+ mode)
+ ;; The max length of a number should be 1023.9X where X is the
+ ;; units, this is 7 characters.
+ for formatted-size = (and size (format "%7s" size))
+ collect (let ((helm-pattern (helm-buffers--pattern-sans-filters
+ (and helm-buffers-fuzzy-matching ""))))
+ (cons (if helm-buffer-details-flag
+ (concat
+ (funcall helm-fuzzy-matching-highlight-fn
+ truncbuf)
+ "\t" formatted-size
+ " " fmode " " meta)
+ (funcall helm-fuzzy-matching-highlight-fn name))
+ (get-buffer i)))))
(defun helm-buffer--get-preselection (buffer)
(let ((bufname (buffer-name buffer)))
@@ -428,17 +449,21 @@ Should be called after others transformers i.e (boring buffers)."
(helm-substring-by-width
bufname helm-buffer-max-length
helm-buffers-end-truncated-string))
- (concat (regexp-quote bufname)
- (if helm-buffer-details-flag
- "$" "[[:blank:]]+"))))))
+ (concat (regexp-quote bufname)
+ (if helm-buffer-details-flag
+ "$" "[[:blank:]]+"))))))
(defun helm-toggle-buffers-details ()
(interactive)
(with-helm-alive-p
- (let ((preselect (helm-buffer--get-preselection
- (helm-get-selection))))
+ (let* ((buf (helm-get-selection))
+ (preselect (helm-buffer--get-preselection buf)))
(setq helm-buffer-details-flag (not helm-buffer-details-flag))
- (helm-update preselect))))
+ (helm-update (lambda ()
+ (helm-awhile (re-search-forward preselect nil t)
+ (helm-mark-current-line)
+ (when (equal buf (helm-get-selection))
+ (cl-return t))))))))
(put 'helm-toggle-buffers-details 'helm-only t)
(defun helm-buffers--pattern-sans-filters (&optional separator)
@@ -740,7 +765,7 @@ If REGEXP-FLAG is given use `query-replace-regexp'."
"Run switch to other window action from `helm-source-buffers-list'."
(interactive)
(with-helm-alive-p
- (helm-exit-and-execute-action 'helm-display-buffers-other-windows)))
+ (helm-exit-and-execute-action 'helm-buffer-switch-buffers-other-window)))
(put 'helm-buffer-switch-other-window 'helm-only t)
(defun helm-buffer-switch-other-frame ()
@@ -750,6 +775,19 @@ If REGEXP-FLAG is given use `query-replace-regexp'."
(helm-exit-and-execute-action 'switch-to-buffer-other-frame)))
(put 'helm-buffer-switch-other-frame 'helm-only t)
+(defun helm-buffer-switch-buffers (_candidate)
+ "Switch to buffer candidates and replace current buffer.
+
+If more than one buffer marked switch to these buffers in separate windows.
+If a prefix arg is given split windows vertically."
+ (let ((buffers (helm-marked-candidates)))
+ (helm-window-show-buffers buffers)))
+
+(defun helm-buffer-switch-buffers-other-window (_candidate)
+ "Switch to marked buffers in other windows."
+ (let ((buffers (helm-marked-candidates)))
+ (helm-window-show-buffers buffers t)))
+
(defun helm-buffer-run-ediff ()
"Run ediff action from `helm-source-buffers-list'."
(interactive)
diff --git a/helm-core-pkg.el b/helm-core-pkg.el
index 1a7434b2..0cdd9302 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.5"
+(define-package "helm-core" "2.8.6"
"Development files for Helm"
'((emacs "24.4")
(async "1.9.2"))
diff --git a/helm-elisp.el b/helm-elisp.el
index 0f487206..e6b9e6b6 100644
--- a/helm-elisp.el
+++ b/helm-elisp.el
@@ -189,7 +189,7 @@ If `helm-turn-on-show-completion' is nil just do nothing."
(helm-split-window-default-side
(if (eq helm-split-window-default-side 'same)
'below helm-split-window-default-side))
- helm-split-window-in-side-p
+ helm-split-window-inside-p
helm-reuse-last-window-split-state)
(helm-set-local-variable
'helm-display-function
@@ -507,6 +507,63 @@ Filename completion happen if string start after or between a double quote."
candidates
(sort candidates #'helm-generic-sort-fn)))
+(defun helm-apropos-clean-history-variable (candidate)
+ (with-helm-current-buffer ; var is maybe local
+ (let* ((sym (intern-soft candidate))
+ (cands (symbol-value sym))
+ (mkds (and (listp cands)
+ (helm-comp-read "Delete entry: "
+ cands :marked-candidates t))))
+ (cl-assert (listp mkds) nil "Variable value is not a list")
+ (cl-loop for elm in mkds do
+ (if (local-variable-p sym)
+ (set (make-local-variable sym)
+ (setq cands (delete elm cands)))
+ (set sym (setq cands (delete elm cands))))))))
+
+(defun helm-apropos-clean-ring (candidate)
+ (with-helm-current-buffer ; var is maybe local
+ (let* ((sym (intern-soft candidate))
+ (val (symbol-value sym))
+ (cands (and (ring-p val) (ring-elements val)))
+ (mkds (and cands (helm-comp-read
+ "Delete entry: "
+ cands :marked-candidates t))))
+ (when mkds
+ (cl-loop for elm in mkds do
+ (ring-remove
+ val (helm-position
+ elm
+ (ring-elements val)
+ :test 'equal))
+ and do (if (local-variable-p sym)
+ (set (make-local-variable sym) val)
+ (set sym val)))))))
+
+(defun helm-apropos-action-transformer (actions candidate)
+ (let* ((sym (helm-symbolify candidate))
+ (val (with-helm-current-buffer (symbol-value sym))))
+ (cond ((custom-variable-p sym)
+ (append
+ actions
+ (let ((standard-value (eval (car (get sym 'standard-value)))))
+ (unless (equal standard-value (symbol-value sym))
+ `(("Reset Variable to default value"
+ . ,(lambda (candidate)
+ (let ((sym (helm-symbolify candidate)))
+ (set sym standard-value)))))))
+ '(("Customize variable" .
+ (lambda (candidate)
+ (customize-option (helm-symbolify candidate)))))))
+ ((and val (with-helm-current-buffer (ring-p (symbol-value sym))))
+ (append actions
+ '(("Clean ring" . helm-apropos-clean-ring))))
+ ((and (string-match-p "history" candidate) (listp val))
+ (append actions
+ '(("Clean variable" .
+ helm-apropos-clean-history-variable))))
+ (t actions))))
+
(defun helm-def-source--emacs-variables (&optional default)
(helm-build-in-buffer-source "Variables"
:init (lambda ()
@@ -524,22 +581,7 @@ Filename completion happen if string start after or between a double quote."
("Find variable" . helm-find-variable)
("Info lookup" . helm-info-lookup-symbol)
("Set variable" . helm-set-variable))
- :action-transformer
- (lambda (actions candidate)
- (let ((sym (helm-symbolify candidate)))
- (if (custom-variable-p sym)
- (append
- actions
- (let ((standard-value (eval (car (get sym 'standard-value)))))
- (unless (equal standard-value (symbol-value sym))
- `(("Reset Variable to default value" .
- ,(lambda (candidate)
- (let ((sym (helm-symbolify candidate)))
- (set sym standard-value)))))))
- '(("Customize variable" .
- (lambda (candidate)
- (customize-option (helm-symbolify candidate))))))
- actions)))))
+ :action-transformer 'helm-apropos-action-transformer))
(defun helm-def-source--emacs-faces (&optional default)
"Create `helm' source for faces to be displayed with
diff --git a/helm-eshell.el b/helm-eshell.el
index c01e3c04..4da4cb7c 100644
--- a/helm-eshell.el
+++ b/helm-eshell.el
@@ -22,6 +22,7 @@
;; (lambda ()
;; (eshell-cmpl-initialize)
;; (define-key eshell-mode-map [remap eshell-pcomplete] 'helm-esh-pcomplete)
+;; (define-key eshell-mode-map (kbd "M-s f") 'helm-eshell-prompts-all)))
;; (define-key eshell-mode-map (kbd "M-r") 'helm-eshell-history)))
@@ -38,6 +39,7 @@
(declare-function eshell-parse-arguments "esh-arg" (beg end))
(declare-function eshell-backward-argument "esh-mode" (&optional arg))
(declare-function helm-quote-whitespace "helm-lib")
+(declare-function eshell-next-prompt "em-prompt")
(defvar eshell-special-chars-outside-quoting)
@@ -81,7 +83,7 @@
(filtered-candidate-transformer
:initform
(lambda (candidates _sources)
- (cl-loop
+ (cl-loop
for i in candidates
collect
(cond ((string-match "\\`~/?" helm-ec-target)
@@ -334,6 +336,116 @@ The function that call this should set `helm-ec-target' to thing at point."
(looking-back " " (1- (point))))
(delete-char -1)))))
+
+;;; Eshell prompts
+;;
+(defface helm-eshell-prompts-promptidx
+ '((t (:foreground "cyan")))
+ "Face used to highlight Eshell prompt index."
+ :group 'helm-eshell-faces)
+
+(defface helm-eshell-prompts-buffer-name
+ '((t (:foreground "green")))
+ "Face used to highlight Eshell buffer name."
+ :group 'helm-eshell-faces)
+
+(defcustom helm-eshell-prompts-promptidx-p t
+ "Show prompt number."
+ :group 'helm-eshell
+ :type 'boolean)
+
+(defun helm-eshell-prompts-list (&optional buffer)
+ "List the prompts in Eshell BUFFER.
+
+Return a list of (\"prompt\" (point) (buffer-name) prompt-index)).
+If BUFFER is nil, use current buffer."
+ (with-current-buffer (or buffer (current-buffer))
+ (when (eq major-mode 'eshell-mode)
+ (save-excursion
+ (goto-char (point-min))
+ (cl-loop while (not (eobp))
+ for promptno from 1
+ do (eshell-next-prompt 1)
+ collect (list (buffer-substring-no-properties
+ (point) (line-end-position))
+ (point)
+ (buffer-name)
+ (and helm-eshell-prompts-promptidx-p
+ promptno)))))))
+
+(defun helm-eshell-prompts-list-all ()
+ "List the prompts of all Eshell buffers.
+See `helm-eshell-prompts-list'."
+ (let (list)
+ (dolist (b (buffer-list))
+ (setq list (append (helm-eshell-prompts-list b) list)))
+ list))
+
+(defun helm-eshell-prompts-transformer (candidates &optional all)
+ (dolist (c candidates)
+ (setcar c
+ (concat
+ (when all
+ (concat (propertize (nth 2 c)
+ 'face 'helm-eshell-prompts-buffer-name) ":"))
+ (when helm-eshell-prompts-promptidx-p
+ (concat (propertize (number-to-string (nth 3 c))
+ 'face 'helm-eshell-prompts-promptidx) ":"))
+ (car c))))
+ candidates)
+
+(defun helm-eshell-prompts-all-transformer (candidates)
+ (helm-eshell-prompts-transformer candidates t))
+
+(defun helm-eshell-prompts-goto (candidate)
+ (when (nth 1 candidate)
+ (switch-to-buffer (nth 1 candidate)))
+ (goto-char (car candidate)))
+
+(defun helm-eshell-prompts-goto-other-window (candidate)
+ (switch-to-buffer-other-window (cdr candidate))
+ (goto-char (car candidate)))
+
+(defun helm-eshell-prompts-goto-other-frame (candidate)
+ (switch-to-buffer-other-frame (cdr candidate))
+ (goto-char (car candidate)))
+
+(defvar helm-eshell-prompts-keymap
+ (let ((map (make-sparse-keymap)))
+ (set-keymap-parent map helm-map)
+ (define-key map (kbd "C-c o") 'helm-eshell-prompts-goto-other-window)
+ (define-key map (kbd "C-c C-o") 'helm-eshell-prompts-goto-other-frame)
+ map)
+ "Keymap for `helm-eshell-prompt-all'.")
+
+;;;###autoload
+(defun helm-eshell-prompts ()
+ "Pre-configured `helm' to browse the prompts of the current Eshell."
+ (interactive)
+ (if (eq major-mode 'eshell-mode)
+ (helm :sources
+ (helm-build-sync-source "Eshell prompts"
+ :candidates (helm-eshell-prompts-list)
+ :candidate-transformer 'helm-eshell-prompts-transformer
+ :action '(("Go to prompt" . helm-eshell-prompts-goto)))
+ :buffer "*helm Eshell prompts*")
+ (message "Current buffer is not an Eshell buffer")))
+
+;;;###autoload
+(defun helm-eshell-prompts-all ()
+ "Pre-configured `helm' to browse the prompts of all Eshell sessions."
+ (interactive)
+ (helm :sources
+ (helm-build-sync-source "All Eshell prompts"
+ :candidates (helm-eshell-prompts-list-all)
+ :candidate-transformer 'helm-eshell-prompts-all-transformer
+ :action '(("Go to prompt" . helm-eshell-prompts-goto)
+ ("Go to prompt in other window `C-c o`" .
+ helm-eshell-prompts-goto-other-window)
+ ("Go to prompt in other frame `C-c C-o`" .
+ helm-eshell-prompts-goto-other-frame)))
+ :buffer "*helm Eshell all prompts*"))
+
(provide 'helm-eshell)
;; Local Variables:
diff --git a/helm-files.el b/helm-files.el
index 9474bc28..b6c2adc8 100644
--- a/helm-files.el
+++ b/helm-files.el
@@ -63,7 +63,7 @@
(defcustom helm-boring-file-regexp-list
(mapcar (lambda (f)
- (let ((rgx (regexp-quote f)))
+ (let ((rgx (regexp-quote f)))
(if (string-match-p "[^/]$" f)
;; files: e.g .o => \\.o$
(concat rgx "$")
@@ -694,7 +694,7 @@ ACTION must be an action supported by `helm-dired-action'."
(if (and (and (fboundp 'dired-async-mode)
dired-async-mode)
(null prefarg))
- (concat "Async " (symbol-name action))
+ (concat "Async " (symbol-name action))
(capitalize (symbol-name action)))
(length ifiles)))
helm-ff--move-to-first-real-candidate
@@ -707,8 +707,11 @@ ACTION must be an action supported by `helm-dired-action'."
(helm-read-file-name
prompt
:preselect (unless (cdr ifiles)
- (if helm-ff-transformer-show-only-basename
- (helm-basename cand) cand))
+ (concat
+ "^"
+ (regexp-quote
+ (if helm-ff-transformer-show-only-basename
+ (helm-basename cand) cand))))
:initial-input (helm-dwim-target-directory)
:history (helm-find-files-history :comp-read nil)))))
(dest-dir-p (file-directory-p dest))
@@ -750,12 +753,9 @@ This reproduce the behavior of \"cp --backup=numbered from to\"."
"Keep current-buffer and open files in separate windows.
When a prefix arg is detected files are opened in a vertical windows
layout."
- (let* ((files (helm-marked-candidates))
- (initial-ow-fn (if (cdr (window-list))
- #'switch-to-buffer-other-window
- #'helm-switch-to-buffer-other-window)))
- (funcall initial-ow-fn (find-file-noselect (car files)))
- (helm-simultaneous-find-file files t)))
+ (let* ((files (helm-marked-candidates))
+ (buffers (mapcar 'find-file-noselect files)))
+ (helm-window-show-buffers buffers t)))
(defun helm-find-files-byte-compile (_candidate)
"Byte compile elisp files from `helm-find-files'."
@@ -772,7 +772,7 @@ layout."
(defun helm-find-files-ediff-files-1 (candidate &optional merge)
"Generic function to ediff/merge files in `helm-find-files'."
- (let* ((helm-dwim-target 'next-window)
+ (let* ((helm-dwim-target 'next-window)
(bname (helm-basename candidate))
(marked (helm-marked-candidates :with-wildcard t))
(prompt (if merge "Ediff Merge `%s' With File: "
@@ -2012,7 +2012,7 @@ Return nil on valid file name remote or not."
(let* ((str (helm-basename fname))
(split (split-string str ":" t))
(meth (car (member (car split)
- (helm-ff--get-tramp-methods)))))
+ (helm-ff--get-tramp-methods)))))
(when meth (car (last split)))))
(cl-defun helm-ff--tramp-hostnames (&optional (pattern helm-pattern))
@@ -2923,12 +2923,14 @@ 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-insert-file-name-completion-at-point (candidate)
+(defun helm-insert-file-name-completion-at-point (_candidate)
"Insert file name completion at point."
(with-helm-current-buffer
(if buffer-read-only
(error "Error: Buffer `%s' is read-only" (buffer-name))
- (let* ((end (point))
+ (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)))
@@ -2943,26 +2945,35 @@ If a prefix arg is given or `helm-follow-mode' is on open file."
(if (memq major-mode
helm-modes-using-escaped-strings)
#'shell-quote-argument #'identity))))
- (set-text-properties 0 (length candidate) nil candidate)
(insert
- (funcall escape-fn
- (if (and guess (not (string= guess ""))
- (or (string-match
- "^\\(~/\\|/\\|[[:lower:][:upper:]]:/\\)"
- guess)
- (file-exists-p candidate)))
- (prog1
- (cond (full-path-p
- (expand-file-name candidate))
- ((string= (match-string 1 guess) "~/")
- (abbreviate-file-name candidate))
- (t (file-relative-name candidate)))
- (delete-region beg end))
- (cond ((equal helm-current-prefix-arg '(4))
- (abbreviate-file-name candidate))
- ((equal helm-current-prefix-arg '(16))
- (file-relative-name candidate))
- (t candidate)))))))))
+ (funcall escape-fn (helm-ff--insert-fname
+ beg end full-path-p guess candidate))
+ (if (cdr mkds) " " "")
+ (mapconcat escape-fn
+ (cl-loop for f in (cdr mkds)
+ collect (helm-ff--insert-fname
+ nil nil nil nil f))
+ " "))))))
+
+(defun helm-ff--insert-fname (beg end full-path guess candidate)
+ (set-text-properties 0 (length candidate) nil candidate)
+ (if (and guess (not (string= guess ""))
+ (or (string-match
+ "^\\(~/\\|/\\|[[:lower:][:upper:]]:/\\)"
+ guess)
+ (file-exists-p candidate)))
+ (prog1
+ (cond (full-path
+ (expand-file-name candidate))
+ ((string= (match-string 1 guess) "~/")
+ (abbreviate-file-name candidate))
+ (t (file-relative-name candidate)))
+ (delete-region beg end))
+ (cond ((equal helm-current-prefix-arg '(4))
+ (abbreviate-file-name candidate))
+ ((equal helm-current-prefix-arg '(16))
+ (file-relative-name candidate))
+ (t candidate))))
(cl-defun helm-find-files-history (&key (comp-read t))
"The `helm-find-files' history.
@@ -3347,7 +3358,7 @@ Called with a prefix arg open files in background without selecting them."
(if (cdr marked)
;; If helm-current-prefix-arg is detected split is done
;; vertically.
- (helm-simultaneous-find-file marked)
+ (helm-window-show-buffers (mapcar 'find-file-noselect marked))
(let ((dir (and (not url-p) (helm-basedir candidate))))
(cond ((and dir (file-directory-p dir))
(find-file (substitute-in-file-name candidate)))
diff --git a/helm-grep.el b/helm-grep.el
index c2552916..966ca285 100644
--- a/helm-grep.el
+++ b/helm-grep.el
@@ -585,7 +585,7 @@ It is intended to use as a let-bound variable, DON'T set this globaly.")
;;; Actions
;;
;;
-(defun helm-grep-action (candidate &optional where mark)
+(defun helm-grep-action (candidate &optional where)
"Define a default action for `helm-do-grep-1' on CANDIDATE.
WHERE can be one of other-window, other-frame."
(let* ((split (helm-grep-split-line candidate))
@@ -605,8 +605,8 @@ WHERE can be one of other-window, other-frame."
(fname (if tramp-host
(concat tramp-prefix loc-fname) loc-fname)))
(cl-case where
- (other-window (helm-switch-to-buffer-other-window
- (find-file-noselect fname)))
+ (other-window (helm-window-show-buffers
+ (list (find-file-noselect fname)) t))
(other-frame (find-file-other-frame fname))
(grep (helm-grep-save-results-1))
(pdf (if helm-pdfgrep-default-read-command
@@ -625,9 +625,6 @@ WHERE can be one of other-window, other-frame."
(invalid-regexp nil)))
collect (match-beginning 0) into pos-ls
finally (when pos-ls (goto-char (apply #'min pos-ls))))
- (when mark
- (set-marker (mark-marker) (point))
- (push-mark (point) 'nomsg))
;; Save history
(unless (or helm-in-persistent-action
(eq major-mode 'helm-grep-mode)
@@ -644,9 +641,7 @@ WHERE can be one of other-window, other-frame."
(defun helm-grep-persistent-action (candidate)
"Persistent action for `helm-do-grep-1'.
With a prefix arg record CANDIDATE in `mark-ring'."
- (if current-prefix-arg
- (helm-grep-action candidate nil 'mark)
- (helm-grep-action candidate))
+ (helm-grep-action candidate)
(helm-highlight-current-line))
(defun helm-grep-other-window (candidate)
diff --git a/helm-lib.el b/helm-lib.el
index 2bcb2134..c6eeb3ec 100644
--- a/helm-lib.el
+++ b/helm-lib.el
@@ -227,6 +227,47 @@ When only `add-text-properties' is available APPEND is ignored."
file
(and file (> (length file) 0)
(expand-file-name file (dired-current-directory)))))))
+
+;;; Override `push-mark'
+;;
+;; Fix duplicates in `mark-ring' and `global-mark-ring' and update
+;; buffers in `global-mark-ring' to recentest mark.
+(defun helm--advice-push-mark (&optional location nomsg activate)
+ (unless (null (mark t))
+ (let ((marker (copy-marker (mark-marker))))
+ (setq mark-ring (cons marker (delete marker mark-ring))))
+ (when (> (length mark-ring) mark-ring-max)
+ ;; Move marker to nowhere.
+ (set-marker (car (nthcdr mark-ring-max mark-ring)) nil)
+ (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil)))
+ (set-marker (mark-marker) (or location (point)) (current-buffer))
+ ;; Now push the mark on the global mark ring.
+ (setq global-mark-ring (cons (copy-marker (mark-marker))
+ ;; Avoid having multiple entries
+ ;; for same buffer in `global-mark-ring'.
+ (cl-loop with mb = (current-buffer)
+ for m in global-mark-ring
+ for nmb = (marker-buffer m)
+ unless (eq mb nmb)
+ collect m)))
+ (when (> (length global-mark-ring) global-mark-ring-max)
+ (set-marker (car (nthcdr global-mark-ring-max global-mark-ring)) nil)
+ (setcdr (nthcdr (1- global-mark-ring-max) global-mark-ring) nil))
+ (or nomsg executing-kbd-macro (> (minibuffer-depth) 0)
+ (message "Mark set"))
+ (when (or activate (not transient-mark-mode))
+ (set-mark (mark t)))
+ nil)
+
+(defcustom helm-advice-push-mark t
+ "Override `push-mark' with a version avoiding duplicates when non nil."
+ :group 'helm
+ :type 'boolean
+ :set (lambda (var val)
+ (set var val)
+ (if val
+ (advice-add 'push-mark :override #'helm--advice-push-mark)
+ (advice-remove 'push-mark #'helm--advice-push-mark))))
;;; Macros helper.
;;
@@ -272,6 +313,23 @@ and not `exit-minibuffer' or other unwanted functions."
;;; Iterators
;;
+(cl-defmacro helm-position (item seq &key test all)
+ "A simple and faster replacement of CL `position'.
+
+Returns ITEM first occurence position found in SEQ.
+When SEQ is a string, ITEM have to be specified as a char.
+Argument TEST when unspecified default to `eq'.
+When argument ALL is non--nil return a list of all ITEM positions
+found in SEQ."
+ (let ((key (if (stringp seq) 'across 'in)))
+ `(cl-loop with deftest = 'eq
+ for c ,key ,seq
+ for index from 0
+ when (funcall (or ,test deftest) c ,item)
+ if ,all collect index into ls
+ else return index
+ finally return ls)))
+
(defun helm-iter-list (seq)
"Return an iterator object from SEQ."
(let ((lis seq))
@@ -525,30 +583,19 @@ Otherwise make a list with one element."
obj
(list obj)))
-(cl-defmacro helm-position (item seq &key (test 'eq) all)
- "A simple and faster replacement of CL `position'.
-Return position of first occurence of ITEM found in SEQ.
-Argument SEQ can be a string, in this case ITEM have to be a char.
-Argument ALL, if non--nil specify to return a list of positions of
-all ITEM found in SEQ."
- (let ((key (if (stringp seq) 'across 'in)))
- `(cl-loop for c ,key ,seq
- for index from 0
- when (funcall ,test c ,item)
- if ,all collect index into ls
- else return index
- finally return ls)))
-
(cl-defun helm-fast-remove-dups (seq &key (test 'eq))
"Remove duplicates elements in list SEQ.
+
This is same as `remove-duplicates' but with memoisation.
It is much faster, especially in large lists.
A test function can be provided with TEST argument key.
-Default is `eq'."
+Default is `eq'.
+NOTE: Comparison of special elisp objects fails because their printed
+representation which is stored in hash-tables can't be compared."
(cl-loop with cont = (make-hash-table :test test)
- for elm in seq
- unless (gethash elm cont)
- collect (puthash elm elm cont)))
+ for elm in seq
+ unless (gethash elm cont)
+ collect (puthash elm elm cont)))
(defsubst helm--string-join (strings &optional separator)
"Join all STRINGS using SEPARATOR."
diff --git a/helm-net.el b/helm-net.el
index eee591e0..55147bf7 100644
--- a/helm-net.el
+++ b/helm-net.el
@@ -434,6 +434,7 @@ Follows any redirections from Wikipedia, and stores results in
(when (string= event "finished\n")
(message "%s process %s" process event))))))
+;;;###autoload
(defun helm-browse-url-firefox (url &optional _ignore)
"Same as `browse-url-firefox' but detach from emacs.
@@ -451,6 +452,7 @@ NOTE: Probably not supported on some systems (e.g Windows)."
helm-browse-url-firefox-new-window
(shell-quote-argument url)))))
+;;;###autoload
(defun helm-browse-url-opera (url &optional _ignore)
"Browse URL with opera browser and detach from emacs.
@@ -466,17 +468,20 @@ NOTE: Probably not supported on some systems (e.g Windows)."
(format "(%s %s &)"
helm-browse-url-opera-program (shell-quote-argument url)))))
+;;;###autoload
(defun helm-browse-url-chromium (url &optional _ignore)
"Browse URL with google chrome browser."
(interactive "sURL: ")
(helm-generic-browser
url helm-browse-url-chromium-program))
+;;;###autoload
(defun helm-browse-url-uzbl (url &optional _ignore)
"Browse URL with uzbl browser."
(interactive "sURL: ")
(helm-generic-browser url helm-browse-url-uzbl-program "-u"))
+;;;###autoload
(defun helm-browse-url-conkeror (url &optional _ignore)
"Browse URL with conkeror browser."
(interactive "sURL: ")
diff --git a/helm-org.el b/helm-org.el
index b86e7bc6..0032b785 100644
--- a/helm-org.el
+++ b/helm-org.el
@@ -382,6 +382,14 @@ current heading."
;;;###autoload
(defun helm-org-completing-read-tags (prompt collection pred req initial
hist def inherit-input-method _name _buffer)
+ "Completing read function for Org tags.
+
+This function is used as a `completing-read' function in
+`helm-completing-read-handlers-alist' by `org-set-tags' and
+`org-capture'.
+
+NOTE: Org tag completion will work only if you disable org fast tag
+selection, see (info \"(org) setting tags\")."
(if (not (string= "Tags: " prompt))
;; Not a tags prompt. Use normal completion by calling
;; `org-icompleting-read' again without this function in
diff --git a/helm-pkg.el b/helm-pkg.el
index 254d45b7..650086f7 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.5"
+(define-package "helm" "2.8.6"
"Helm is an Emacs incremental and narrowing framework"
'((emacs "24.4")
(async "1.9.2")
(popup "0.5.3")
- (helm-core "2.8.5"))
+ (helm-core "2.8.6"))
:url "https://emacs-helm.github.io/helm/")
;; Local Variables:
diff --git a/helm-regexp.el b/helm-regexp.el
index f0251b33..39a30431 100644
--- a/helm-regexp.el
+++ b/helm-regexp.el
@@ -277,7 +277,7 @@ Should be a local var to helm-buffer to allow resuming.")
(when (= beg end) (forward-char 1))))
(cl-defun helm-moccur-action (candidate
- &optional (method (quote buffer)) mark)
+ &optional (method (quote buffer)))
"Jump to CANDIDATE with METHOD.
arg METHOD can be one of buffer, buffer-other-window, buffer-other-frame."
(require 'helm-grep)
@@ -287,7 +287,7 @@ arg METHOD can be one of buffer, buffer-other-window, buffer-other-frame."
(split-pat (helm-mm-split-pattern helm-input)))
(cl-case method
(buffer (switch-to-buffer buf))
- (buffer-other-window (helm-display-buffers-other-windows buf))
+ (buffer-other-window (helm-window-show-buffers (list buf) t))
(buffer-other-frame (switch-to-buffer-other-frame buf)))
(with-current-buffer buf
(helm-goto-line lineno)
@@ -300,10 +300,7 @@ arg METHOD can be one of buffer, buffer-other-window, buffer-other-frame."
(re-search-forward reg (point-at-eol) t))
(invalid-regexp nil)))
collect (match-beginning 0) into pos-ls
- finally (when pos-ls (goto-char (apply #'min pos-ls))))
- (when mark
- (set-marker (mark-marker) (point))
- (push-mark (point) 'nomsg)))))
+ finally (when pos-ls (goto-char (apply #'min pos-ls)))))))
(defun helm-moccur-persistent-action (candidate)
(helm-moccur-goto-line candidate)
@@ -312,24 +309,19 @@ arg METHOD can be one of buffer, buffer-other-window, buffer-other-frame."
(defun helm-moccur-goto-line (candidate)
"From multi occur, switch to buffer and go to nth 1 CANDIDATE line."
(helm-moccur-action
- candidate 'buffer (or current-prefix-arg ; persistent.
- helm-current-prefix-arg))) ; exit.
+ candidate 'buffer))
(defun helm-moccur-goto-line-ow (candidate)
"Go to CANDIDATE line in other window.
Same as `helm-moccur-goto-line' but go in other window."
(helm-moccur-action
- candidate 'buffer-other-window
- (or current-prefix-arg ; persistent.
- helm-current-prefix-arg))) ; exit.
+ candidate 'buffer-other-window))
(defun helm-moccur-goto-line-of (candidate)
"Go to CANDIDATE line in new frame.
Same as `helm-moccur-goto-line' but go in new frame."
(helm-moccur-action
- candidate 'buffer-other-frame
- (or current-prefix-arg ; persistent.
- helm-current-prefix-arg))) ; exit.
+ candidate 'buffer-other-frame))
(defun helm-moccur-run-goto-line-ow ()
"Run goto line other window action from `helm-source-moccur'."
diff --git a/helm-ring.el b/helm-ring.el
index 556b4258..79d2c017 100644
--- a/helm-ring.el
+++ b/helm-ring.el
@@ -242,7 +242,9 @@ This is a command for `helm-kill-ring-map'."
(defun helm-mark-ring-get-candidates ()
(with-helm-current-buffer
- (cl-loop with marks = (if (mark t) (cons (mark-marker) mark-ring) mark-ring)
+ (cl-loop with marks = (if (mark t)
+ (cons (mark-marker) mark-ring)
+ mark-ring)
for marker in marks
with max-line-number = (line-number-at-pos (point-max))
with width = (length (number-to-string max-line-number))
@@ -255,13 +257,19 @@ This is a command for `helm-kill-ring-map'."
(defun helm-mark-ring-default-action (candidate)
(let ((target (copy-marker candidate)))
- (switch-to-buffer (marker-buffer candidate))
- (helm-log-run-hook 'helm-goto-line-before-hook)
- (helm-match-line-cleanup)
- (with-helm-current-buffer
- (unless helm-yank-point (setq helm-yank-point (point))))
- (helm-goto-char target)
- (helm-highlight-current-line)))
+ (helm-aif (marker-buffer candidate)
+ (progn
+ (switch-to-buffer it)
+ (helm-log-run-hook 'helm-goto-line-before-hook)
+ (helm-match-line-cleanup)
+ (with-helm-current-buffer
+ (unless helm-yank-point (setq helm-yank-point (point))))
+ (helm-goto-char target)
+ (helm-highlight-current-line))
+ ;; marker points to no buffer, no need to dereference it, just
+ ;; delete it.
+ (setq mark-ring (delete target mark-ring))
+ (error "Marker points to no buffer"))))
(defvar helm-source-mark-ring
(helm-build-sync-source "mark-ring"
diff --git a/helm-sys.el b/helm-sys.el
index 745d3eb4..60bf9709 100644
--- a/helm-sys.el
+++ b/helm-sys.el
@@ -46,18 +46,18 @@ is used instead by default.
Normally 'top' command output have 12 columns, but in some versions you may
have less than this, so you can either customize top to use 12 columns with the
interactives 'f' and 'W' commands of top, or modify
-`helm-top-sort-colums-alist' to fit with the number of columns
+`helm-top-sort-columns-alist' to fit with the number of columns
your 'top' command is using.
If you modify 'ps' command be sure that 'pid' comes in first
and \"env COLUMNS=%s\" is specified at beginning of command.
Ensure also that no elements contain spaces (e.g use start_time and not start).
-Same as for 'top' you can customize `helm-top-sort-colums-alist' to make sort commands
+Same as for 'top' you can customize `helm-top-sort-columns-alist' to make sort commands
working properly according to your settings."
:group 'helm-sys
:type 'string)
-(defcustom helm-top-sort-colums-alist '((com . 11)
+(defcustom helm-top-sort-columns-alist '((com . 11)
(mem . 9)
(cpu . 8)
(user . 1))
@@ -290,7 +290,7 @@ Show actions only on line starting by a PID."
(defun helm-top-sort-by-com (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
- (col (cdr (assq 'com helm-top-sort-colums-alist)))
+ (col (cdr (assq 'com helm-top-sort-columns-alist)))
(com-1 (nth col split-1))
(com-2 (nth col split-2)))
(string< com-1 com-2)))
@@ -298,7 +298,7 @@ Show actions only on line starting by a PID."
(defun helm-top-sort-by-mem (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
- (col (cdr (assq 'mem helm-top-sort-colums-alist)))
+ (col (cdr (assq 'mem helm-top-sort-columns-alist)))
(mem-1 (string-to-number (nth col split-1)))
(mem-2 (string-to-number (nth col split-2))))
(> mem-1 mem-2)))
@@ -306,7 +306,7 @@ Show actions only on line starting by a PID."
(defun helm-top-sort-by-cpu (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
- (col (cdr (assq 'cpu helm-top-sort-colums-alist)))
+ (col (cdr (assq 'cpu helm-top-sort-columns-alist)))
(cpu-1 (string-to-number (nth col split-1)))
(cpu-2 (string-to-number (nth col split-2))))
(> cpu-1 cpu-2)))
@@ -314,7 +314,7 @@ Show actions only on line starting by a PID."
(defun helm-top-sort-by-user (s1 s2)
(let* ((split-1 (split-string s1))
(split-2 (split-string s2))
- (col (cdr (assq 'user helm-top-sort-colums-alist)))
+ (col (cdr (assq 'user helm-top-sort-columns-alist)))
(user-1 (nth col split-1))
(user-2 (nth col split-2)))
(string< user-1 user-2)))
@@ -336,11 +336,11 @@ Show actions only on line starting by a PID."
(defun helm-top-run-sort-by-cpu ()
(interactive)
- (let ((com (nth 2 (split-string helm-top-command))))
- (helm-top-set-mode-line "CPU")
- (setq helm-top-sort-fn (and (null (string= com "top"))
- 'helm-top-sort-by-cpu))
- (helm-update (helm-top--preselect-fn))))
+ (helm-top-set-mode-line "CPU")
+ ;; Force sorting by CPU even if some versions of top are using by
+ ;; default CPU sorting (Issue #1908).
+ (setq helm-top-sort-fn 'helm-top-sort-by-cpu)
+ (helm-update (helm-top--preselect-fn)))
(defun helm-top-run-sort-by-mem ()
(interactive)
diff --git a/helm-types.el b/helm-types.el
index 258f69b5..b36c12b7 100644
--- a/helm-types.el
+++ b/helm-types.el
@@ -129,12 +129,9 @@
(defcustom helm-type-buffer-actions
(helm-make-actions
- "Switch to buffer(s)" 'helm-switch-to-buffers
- (lambda () (and (locate-library "popwin")
- "Switch to buffer in popup window"))
- 'popwin:popup-buffer
+ "Switch to buffer(s)" 'helm-buffer-switch-buffers
"Switch to buffer(s) other window `C-c o'"
- 'helm-display-buffers-other-windows
+ 'helm-buffer-switch-buffers-other-window
"Switch to buffer other frame `C-c C-o'"
'switch-to-buffer-other-frame
"Browse project from buffer"
diff --git a/helm-utils.el b/helm-utils.el
index fd39381d..ea99cb91 100644
--- a/helm-utils.el
+++ b/helm-utils.el
@@ -107,7 +107,7 @@ In this case last position is added to the register
("&yen" . 165) ;; ¥
("&brvbar;" . 166) ;; ¦
("&sect;" . 167) ;; §
- ("&uml;" . 32) ;; SPC
+ ("&uml;" . 32) ;; SPC
("&copy;" . 169) ;; ©
("&ordf;" . 97) ;; a
("&laquo;" . 171) ;; «
@@ -121,7 +121,7 @@ In this case last position is added to the register
("&micro;" . 956) ;; μ
("&para;" . 182) ;; ¶
("&middot;" . 183) ;; ·
- ("&cedil;" . 32) ;; SPC
+ ("&cedil;" . 32) ;; SPC
("&sup1;" . 49) ;; 1
("&ordm;" . 111) ;; o
("&raquo;" . 187) ;; »
@@ -217,12 +217,12 @@ In this case last position is added to the register
;;; Utils functions
;;
;;
-(defcustom helm-switch-to-buffer-ow-vertically nil
+(defcustom helm-window-prefer-horizontal-split nil
"Maybe switch to other window vertically when non nil.
-Possible values are `t', `nil' and `decide'.
+Possible values are t, nil and `decide'.
-When `t' switch vertically.
+When t switch vertically.
When nil switch horizontally.
When `decide' try to guess if it is possible to switch vertically
according to the setting of `split-width-threshold' and the size of
@@ -236,91 +236,164 @@ behavior is the same that with a nil value."
(const :tag "Split window horizontally" nil)
(symbol :tag "Guess how to split window" 'decide)))
-(defun helm-switch-to-buffers (buffer-or-name &optional other-window)
- "Switch to buffer BUFFER-OR-NAME.
+(defcustom helm-window-show-buffers-function #'helm-window-default-split-fn
+ "The default function to use when opening several buffers at once.
+It is typically used to rearrange windows."
+ :group 'helm-utils
+ :type '(choice
+ (function :tag "Split windows vertically or horizontally"
+ helm-window-default-split-fn)
+ (function :tag "Split in alternate windows"
+ helm-window-alternate-split-fn)
+ (function :tag "Split windows in mosaic"
+ helm-window-mosaic-fn)))
+
+(defun helm-window-show-buffers (buffers &optional other-window)
+ "Show BUFFERS.
If more than one buffer marked switch to these buffers in separate windows.
-If OTHER-WINDOW is specified keep current-buffer and switch to others buffers
+If OTHER-WINDOW is non-nil, keep current buffer and switch to others buffers
in separate windows.
If a prefix arg is given split windows vertically."
- (let ((mkds (helm-marked-candidates))
- (initial-ow-fn (if (cdr (window-list))
+ (let ((initial-ow-fn (if (cdr (window-list))
#'switch-to-buffer-other-window
- #'helm-switch-to-buffer-other-window)))
- (helm-aif (cdr mkds)
- (progn
- (if other-window
- (funcall initial-ow-fn (car mkds))
- (switch-to-buffer (car mkds)))
- (save-selected-window
- (cl-loop with nosplit
- for b in it
- when nosplit return
- (message "Too many buffers to visit simultaneously")
- do (condition-case _err
- (helm-switch-to-buffer-other-window b 'balance)
- (error (setq nosplit t) nil)))))
+ #'helm-window-other-window)))
+ (if (cdr buffers)
+ (funcall helm-window-show-buffers-function buffers
+ (and other-window initial-ow-fn))
(if other-window
- (funcall initial-ow-fn buffer-or-name)
- (switch-to-buffer buffer-or-name)))))
-
-(defun helm-simultaneous-find-file (files &optional other-window)
- "Find files in FILES list in separate windows.
-If frame is too small to display all windows, continue finding files
-in background.
-When called with a prefix arg split is done vertically."
- (helm-aif (cdr files)
- (progn
- (unless other-window
- (switch-to-buffer (find-file-noselect (car files))))
- (save-selected-window
- (cl-loop with nosplit
- with len = (length it)
- with remaining = 0
- with displayed = 0
- for f in it
- for count from 1
- for buf = (find-file-noselect f)
- unless nosplit do
- (condition-case-unless-debug _err
- (helm-switch-to-buffer-other-window buf 'balance)
- (error
- (setq nosplit t)
- (message
- "%d files displayed, %d files opening in background..."
- (setq displayed count)
- (setq remaining (- len count)))
- nil))
- finally
- (when nosplit
- (message
- "%d files displayed, %d files opened in background"
- displayed remaining)))))))
-
-(defun helm-switch-to-buffer-other-window (buffer-or-name &optional balance)
- "Switch to buffer-or-name in other window.
-If a prefix arg is detected split vertically.
-When argument balance is provided `balance-windows'."
- (let* ((helm-switch-to-buffer-ow-vertically
- (if (eq helm-switch-to-buffer-ow-vertically 'decide)
+ (funcall initial-ow-fn (car buffers))
+ (switch-to-buffer (car buffers))))))
+
+(defun helm-window-default-split-fn (candidates &optional other-window-fn)
+ "Split windows in one direction and balance them.
+
+Direction can be controlled via `helm-window-prefer-horizontal-split'.
+If a prefix arg is given split windows the other direction.
+This function is suitable for `helm-window-show-buffers-function'."
+ (if other-window-fn
+ (funcall other-window-fn (car candidates))
+ (switch-to-buffer (car candidates)))
+ (save-selected-window
+ (cl-loop with nosplit
+ for b in (cdr candidates)
+ when nosplit return
+ (message "Too many buffers to visit simultaneously")
+ do (condition-case _err
+ (helm-window-other-window b 'balance)
+ (error (setq nosplit t) nil)))))
+
+(defun helm-window-alternate-split-fn (candidates &optional other-window-fn)
+ "Split windows horizontally and vertically in alternate fashion.
+
+Direction can be controlled via `helm-window-prefer-horizontal-split'.
+If a prefix arg is given split windows the other direction.
+This function is suitable for `helm-window-show-buffers-function'."
+ (if other-window-fn
+ (funcall other-window-fn (car candidates))
+ (switch-to-buffer (car candidates)))
+ (let (right-side)
+ (save-selected-window
+ (cl-loop with nosplit
+ for b in (cdr candidates)
+ when nosplit return
+ (message "Too many buffers to visit simultaneously")
+ do (condition-case _err
+ (let ((helm-current-prefix-arg right-side))
+ (helm-window-other-window b)
+ (setq right-side (not right-side)))
+ (error (setq nosplit t) nil))))))
+
+(defun helm-window-mosaic-fn (candidates &optional other-window-fn)
+ "Make an as-square-as-possible window mosaic of the CANDIDATES buffers.
+
+If rectangular, the long side is in the direction given by
+`helm-window-prefer-horizontal-split': if non-nil, it is horizontal, vertical
+otherwise.
+If OTHER-WINDOW-FN is non-nil, current windows are included in the mosaic.
+This function is suitable for `helm-window-show-buffers-function'."
+ (when other-window-fn
+ (setq candidates (append (mapcar 'window-buffer (window-list)) candidates)))
+ (delete-other-windows)
+ (let* ((helm-window-prefer-horizontal-split
+ (if (eq helm-window-prefer-horizontal-split 'decide)
(and (numberp split-width-threshold)
(>= (window-width (selected-window))
split-width-threshold))
- helm-switch-to-buffer-ow-vertically))
- (right-side (if helm-switch-to-buffer-ow-vertically
- (not helm-current-prefix-arg)
- helm-current-prefix-arg)))
+ helm-window-prefer-horizontal-split))
+ mosaic-length-tile-count
+ mosaic-width-tile-count
+ mosaic-length-tile-size
+ mosaic-width-tile-size
+ next-window)
+ ;; If 4 tiles, make 2x2 mosaic.
+ ;; If 5-6 tiles, make 2x3 mosaic with direction depending on `helm-window-prefer-horizontal-split'.
+ ;; If 7-9 tiles, make 3x3 mosaic. And so on.
+ (setq mosaic-length-tile-count (ceiling (sqrt (length candidates))))
+ (setq mosaic-width-tile-count
+ (if (<= (length candidates) (* mosaic-length-tile-count (1- mosaic-length-tile-count)))
+ (1- mosaic-length-tile-count)
+ mosaic-length-tile-count))
+ ;; We lower-bound the tile size, otherwise the function would
+ ;; fail during the first inner split.
+ ;; There is consequently no need to check for errors when
+ ;; splitting.
+ (let ((frame-mosaic-length-direction-size (frame-height))
+ (frame-mosaic-width-direction-size (frame-width))
+ (window-mosaic-length-direction-min-size window-min-height)
+ (window-mosaic-width-direction-min-size window-min-width))
+ (if helm-window-prefer-horizontal-split
+ (setq frame-mosaic-length-direction-size (frame-width)
+ frame-mosaic-width-direction-size (frame-height)
+ window-mosaic-length-direction-min-size window-min-width
+ window-mosaic-width-direction-min-size window-min-height))
+ (setq mosaic-length-tile-size (max
+ (/ frame-mosaic-length-direction-size mosaic-length-tile-count)
+ window-mosaic-length-direction-min-size)
+ mosaic-width-tile-size (max
+ (/ frame-mosaic-width-direction-size mosaic-width-tile-count)
+ window-mosaic-width-direction-min-size))
+ ;; Shorten `candidates' to `max-tiles' elements.
+ (let ((max-tiles (* (/ frame-mosaic-length-direction-size mosaic-length-tile-size)
+ (/ frame-mosaic-width-direction-size mosaic-width-tile-size))))
+ (when (> (length candidates) max-tiles)
+ (message "Too many buffers to visit simultaneously")
+ (setcdr (nthcdr (- max-tiles 1) candidates) nil))))
+ ;; Make the mosaic.
+ (while candidates
+ (when (> (length candidates) mosaic-length-tile-count)
+ (setq next-window (split-window nil
+ mosaic-width-tile-size
+ (not helm-window-prefer-horizontal-split))))
+ (switch-to-buffer (pop candidates))
+ (dotimes (_ (min (1- mosaic-length-tile-count) (length candidates)))
+ (select-window (split-window nil
+ mosaic-length-tile-size
+ helm-window-prefer-horizontal-split))
+ (switch-to-buffer (pop candidates)))
+ (when next-window
+ (select-window next-window)))))
+
+(defun helm-window-other-window (buffer-or-name &optional balance)
+ "Switch to BUFFER-OR-NAME in other window.
+Direction can be controlled via `helm-window-prefer-horizontal-split'.
+If a prefix arg is given split windows the other direction.
+When argument BALANCE is provided `balance-windows'."
+ (let* ((helm-window-prefer-horizontal-split
+ (if (eq helm-window-prefer-horizontal-split 'decide)
+ (and (numberp split-width-threshold)
+ (>= (window-width (selected-window))
+ split-width-threshold))
+ helm-window-prefer-horizontal-split))
+ (right-side (if helm-window-prefer-horizontal-split
+ (not helm-current-prefix-arg)
+ helm-current-prefix-arg)))
(select-window (split-window nil nil right-side))
(and balance (balance-windows))
(switch-to-buffer buffer-or-name)))
-(defun helm-display-buffers-other-windows (buffer-or-name)
- "switch to buffer BUFFER-OR-NAME in other window.
-See `helm-switch-to-buffers' for switching to marked buffers."
- (helm-switch-to-buffers buffer-or-name t))
-
(cl-defun helm-current-buffer-narrowed-p (&optional
- (buffer helm-current-buffer))
+ (buffer helm-current-buffer))
"Check if BUFFER is narrowed.
Default is `helm-current-buffer'."
(with-current-buffer buffer
@@ -640,7 +713,7 @@ Inlined here for compatibility."
(helm-split-window-default-side
(if (eq helm-split-window-default-side 'same)
'below helm-split-window-default-side))
- helm-split-window-in-side-p
+ helm-split-window-inside-p
helm-reuse-last-window-split-state
,window)
(with-current-buffer ,buffer
diff --git a/helm.el b/helm.el
index 4d117d30..82f2ae3a 100644
--- a/helm.el
+++ b/helm.el
@@ -392,7 +392,7 @@ the default has changed now to avoid flickering."
(defcustom helm-display-function 'helm-default-display-buffer
"Function to display *helm* buffer.
By default, it is `helm-default-display-buffer', which affects
-`helm-full-frame'."
+`helm-full-frame' among others."
:group 'helm
:type 'symbol)
@@ -451,7 +451,7 @@ Other acceptable values are `same' which always display
A nil value has same effect as `below'.
If `helm-full-frame' is non-`nil', it take precedence over this setting.
-See also `helm-split-window-in-side-p' and `helm-always-two-windows' that
+See also `helm-split-window-inside-p' and `helm-always-two-windows' that
take precedence over this.
NOTE: this have no effect if `helm-split-window-preferred-function' is not
@@ -479,7 +479,7 @@ See `display-buffer' for more info."
:group 'helm
:type '(choice integer function))
-(defcustom helm-split-window-in-side-p nil
+(defcustom helm-split-window-inside-p nil
"Forces split inside selected window when non-`nil'.
See also `helm-split-window-default-side'.
@@ -489,13 +489,15 @@ NOTE: this has no effect if
handle this."
:group 'helm
:type 'boolean)
+(defvaralias 'helm-split-window-in-side-p 'helm-split-window-inside-p)
+(make-obsolete-variable 'helm-split-window-in-side-p 'helm-split-window-inside-p "2.8.6")
(defcustom helm-always-two-windows nil
"When non-`nil' helm uses two windows in this frame.
To display `helm-buffer' in one window and `helm-current-buffer'
in the other.
-Note: this has no effect when `helm-split-window-in-side-p' is non-`nil',
+Note: this has no effect when `helm-split-window-inside-p' is non-`nil',
or when `helm-split-window-default-side' is set to 'same.
When `helm-autoresize-mode' is enabled, setting this to nil
@@ -906,75 +908,69 @@ value of this var.")
"* Helm Generic Help
** Basics
-Helm allow you narrowing the list of candidates as the pattern is typed and
-updates the list in a live feedback.
+Helm narrows down the list of candidates as you type a filter pattern.
-Helm accepts multiple patterns (entered with a space between patterns).
-Helm support also fuzzy matching in some places when specified.
+Helm accepts multiple space-separated patterns.
+Helm also supports fuzzy matching in some places when specified.
-Helm uses familiar Emacs navigation keys to move up and down the list,
-however some keybindings are maybe confusing for new users, here are some:
+Helm generally uses familiar Emacs keys to navigate the list.
+Here follow some of the less obvious bindings:
-`\\[helm-maybe-exit-minibuffer]' selects the candidate from the list and execute default action
-on it, exiting helm session.
+- `\\[helm-maybe-exit-minibuffer]' selects the candidate from the list, executes the default action
+upon exiting the Helm session.
-`\\[helm-execute-persistent-action]' execute the default action but without exiting helm session,
-it may be not available in some places.
+- `\\[helm-execute-persistent-action]' executes the default action but without exiting the Helm session.
+Not all sources support this.
-`\\[helm-select-action]' show you a list of actions available on current candidate or all marked candidates,
-this maybe surprising for new helm users that expect `\\[helm-select-action]' for completions and have not
-realized they are already completing something as soon as helm is started!
-See [[https://github.com/emacs-helm/helm/wiki#helm-completion-vs-emacs-completion][Helm wiki]]
+- `\\[helm-select-action]' displays a list of actions available on current candidate or all marked candidates.
+The default binding <tab> is ordinarily used for completion, but that would be
+redundant since Helm completes upon every character entered in the prompt.
+See [[https://github.com/emacs-helm/helm/wiki#helm-completion-vs-emacs-completion][Helm wiki]].
-NOTE: In addition to this fixed actions list, you will notice that depending
-of the type of candidate selected you may have additional actions
-appearing and disapearing when you select another type of candidate, they are called
-filtered actions.
+Note: In addition to the default actions list, additional actions appear
+depending of the type of the selected candidate(s). They are called filtered
+actions.
** Helm mode
-`helm-mode' allows you enabling helm completion in native emacs functions,
-so when you turn on `helm-mode' commands like e.g `switch-to-buffer' will use
-helm completion instead of the usual emacs completion buffer.
+`helm-mode' toggles Helm completion in native Emacs functions,
+so when you turn `helm-mode' on, commands like `switch-to-buffer' will use
+Helm completion instead of the usual Emacs completion buffer.
-*** What is helmized and not when `helm-mode' is enabled ?
+*** What gets or does not get \"helmized\" when `helm-mode' is enabled?
-Helm is providing completion on all functions in emacs using `completing-read'
-and derived and `completion-in-region', it uses generic functions for this.
+Helm provides generic completion on all Emacs functions using `completing-read',
+`completion-in-region' and their derivatives, e.g. `read-file-name'. Helm
+exposes a user variable to control which function to use for a specific Emacs
+command: `helm-completing-read-handlers-alist'. If the function for a specific
+command is nil, it turns off Helm completion. See the variable documentation
+for more infos.
-For the functions using `completing-read' and derived e.g `read-file-name' helm
-have a user variable that allows controlling which function to use for a specific
-emacs command, it is `helm-completing-read-handlers-alist', it allows also
-disabling helm completion for a specific command when the specified
-function is nil.
-See its documentation for more infos.
+*** Helm functions vs helmized Emacs functions
-*** Helm functions vs helmized emacs functions
+While there are Helm functions that perform the same completion as other
+helmized Emacs functions, e.g. `switch-to-buffer' and `helm-buffers-list', the
+native Helm functions like `helm-buffers-list' can receive new features, the
+allow marking candidates, they have several actions, etc. Whereas the helmized
+Emacs functions only have Helm completion, one action and no more then Emacs can
+provide for this function. This is the intended behavior.
-Sometimes you have helm functions that do the same completion as other
-emacs vanilla helmized functions, e.g `switch-to-buffer' and
-`helm-buffers-list', you have to understand that the native helm
-functions like `helm-buffers-list' can receive new features, allow
-marking candidates, have several actions and much more whereas the
-emacs vanilla helmized functions have only a helm completion, one
-action and no more what emacs provide for this function, it is the
-intended behavior.
+Generally you are better off using the native Helm command
+than the helmized Emacs equivalent.
-So generally you have better time using the native helm command generally
-much more featured than the emacs function helmized than `helm-mode'.
+** Helm help
-** Helm Help
+\\[helm-documentation]: Show all helm documentations concatenated in one org file.
-\\[helm-documentation] Shows all helm documentations concatenated in one org file.
+From a Helm session, just hit \\<helm-map>\\[helm-help] to have the
+documentation for the current source followed by the global Helm documentation.
-When you are in an helm session, just hit \\<helm-map>\\[helm-help] to have the documentation
-for the current source followed for conveniences by the global helm documentation.
+While in the help buffer, most of the regular keybindings are available in an
+Emacs buffers; the most important ones are shown in minibuffer. However due to
+the implementation restrictions, no regular Emacs keymap is used (it runs in a
+loop when reading the help buffer) they are hardcoded and not modifiable.
-While in the help buffer, you have most of the regular keybindings
-available in emacs buffers, the most important are shown in
-minibuffer; However due to the implementation that do not use regular
-emacs keymap (you are in a loop when reading help buffer) they are
-hardcoded and not modifiable, here they are:
+The hard-coded documentation bindings are:
| Key | Alternative keys | Command |
|-----------+------------------+---------------------|
@@ -1000,174 +996,175 @@ hardcoded and not modifiable, here they are:
| M-w | | Copy region |
| q | | Quit |
-** Customize helm
+** Customize Helm
-Helm have a lot of user variables to configure it as you want,
-you can use from any helm session \\<helm-map>\\[helm-customize-group] to jump to the current source group.
-Helm have also a special group for faces you can access via M-x customize-group => helm-faces.
+Helm provides a lot of user variables for extensive customization.
+From any Helm session, type \\<helm-map>\\[helm-customize-group] to jump to the current source `custom' group.
+Helm also has a special group for faces you can access via `M-x customize-group RET helm-faces'.
-NOTE: Some sources may not have their group set and default to `helm' group.
+Note: Some sources may not have their group set and default to the `helm' group.
-** Helm's Basic Operations and Default Key Bindings
+** Helm's basic operations and default key bindings
| Key | Alternative Keys | Command |
|---------+------------------+----------------------------------------------------------------------|
-| C-p | Up | Previous Line |
-| C-n | Down | Next Line |
-| M-v | PageUp | Previous Page |
-| C-v | PageDown | Next Page |
+| C-p | Up | Previous line |
+| C-n | Down | Next line |
+| M-v | prior | Previous page |
+| C-v | next | Next page |
| Enter | | Execute first (default) action / Select |
-| M-< | | First Line |
-| M-> | | Last Line |
-| C-M-S-v | M-PageUp, C-M-y | Previous Page (other-window) |
-| C-M-v | M-PageDown | Next Page (other-window) |
+| M-< | | First line |
+| M-> | | Last line |
+| C-M-S-v | M-prior, C-M-y | Previous page (other-window) |
+| C-M-v | M-next | Next page (other-window) |
| Tab | C-i | Show action list |
-| Left | | Previous Source |
-| Right | C-o | Next Source |
+| Left | | Previous source |
+| Right | C-o | Next source |
| C-k | | Delete pattern (with prefix arg delete from point to end or all [1]) |
-| C-j | C-z | Persistent Action (Execute and keep helm session) |
+| C-j | C-z | Persistent action (Execute and keep Helm session) |
-\[1] Delete from point to end or all depending of
-`helm-delete-minibuffer-contents-from-point' value.
+\[1] Delete from point to end or all depending on the value of
+`helm-delete-minibuffer-contents-from-point'.
-** Shortcuts For nth Action
+** Shortcuts for n-th action
-f1-12: Execute nth Action where n is 1 to 12.
+f1-f12: Execute n-th action where n is 1 to 12.
-** Shortcuts for executing Default Action on the nth candidate
+** Shortcuts for executing the default action on the n-th candidate
-C-x <n> => executes default action on number <n> candidate before currently selected candidate.
+C-x <n>: Execute default action on the n-th candidate before currently selected candidate.
-C-c <n> => executes default action on number <n> candidate after current selected candidate.
+C-c <n>: Execute default action on the n-th candidate after current selected candidate.
-n is limited only to 1 through 9. For larger jumps use other
-navigation keys. Also note that Helm candidates list by default
-do not display line numbers. Line numbers can be enabled with the
-\[[https://github.com/coldnew/linum-relative][linum-relative]] package and `helm-linum-relative-mode'.
+\"n\" is limited to 1-9. For larger jumps use other navigation keys. Helm does
+not display line numbers by default: enable them with the
+\[[https://github.com/coldnew/linum-relative][linum-relative]] package and
+`helm-linum-relative-mode'.
-** Using the mouse in helm
+** Mouse control in Helm
-A basic usage of mouse is provided when user set `helm-allow-mouse' to non-nil.
+A basic support for the mouse is provided when the user sets `helm-allow-mouse' to non-nil.
-- mouse-1 allows selecting candidate.
-- mouse-2 execute default action on selected candidate.
-- mouse-3 pops up menu action.
+- mouse-1 selects the candidate.
+- mouse-2 executes the default action on selected candidate.
+- mouse-3 pops up the action menu.
-NOTE: When mouse usage is enabled in helm, it allow also clicking around and quit
-the minibuffer focus, it will be up to you to click back to helm buffer or minibuffer
-to retrieve control of your helm session.
+Note: When mouse control is enabled in Helm, it also lets you click around and lose
+the minibuffer focus: you'll have to click on the Helm buffer or the minibuffer
+to retrieve control of your Helm session.
** Marked candidates
-You can mark candidates to execute an action on them instead
-of the current selected candidate only (See binding below).
-Most Helm actions operate on marked candidates unless marking candidates
-is prevented explicitely for a specific source.
+You can mark candidates to execute an action on all of them instead of the
+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/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.
-NOTE: These two functions allow marking candidates in all sources with a prefix argument,
-but even if you mark all candidates of all sources, only those of current source will be used
-when executing your action unless this action specify to use candidates of all sources, which
-is not the case in most sources for evident reasons
-\(i.e Each action handle only a specific type of candidate).
-IOW Unless you use specific sources that have actions handling candidates of all other sources
-you don't need the prefix arg when using \\[helm-mark-all] or \\[helm-toggle-all-marks].
+Note: When multiple candidates are selected across different sources, only the
+candidates of the current source will be used when executing most actions (as
+different sources can have different actions). Some actions support
+multi-source marking however.
** 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 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.
+When `helm-follow-mode' is on (\\<helm-map>\\[helm-follow-mode] to toggle it),
+moving up and down the Helm session or updating the list of candidates will
+automatically execute the persistent-action as specified for the current source.
+
+If `helm-follow-mode-persistent' is non-nil, the state of the mode will be
+restored for the following Helm sessions.
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.
+`helm-follow-mode', you can use \\<helm-map>\\[helm-follow-action-forward] or \\[helm-follow-action-backward] instead.
+Conversely, when `helm-follow-mode' is enabled, those commands
+go to previous/next 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-toggle-resplit-and-swap-windows]\t\tToggle vertical/horizontal split on first hit and swap Helm window on second hit.
\\[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-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 and then select next line.
-\\[helm-follow-action-backward]\t\tRun persistent action and then select previous line.
+\\[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\tSuspend/reenable updates to candidates list.
+\\[helm-toggle-suspend-update]\t\tToggle candidate updates.
** Moving in `helm-buffer'
-You can move in `helm-buffer' with usual commands used in emacs
-\(\\<helm-map>\\[helm-next-line], \\<helm-map>\\[helm-previous-line] etc... see above basic commands).
-When `helm-buffer' contains more than one source change source with \\<helm-map>\\[helm-next-source].
+You can move in `helm-buffer' with the usual commands used in Emacs:
+\(\\<helm-map>\\[helm-next-line], \\<helm-map>\\[helm-previous-line], etc. See above basic commands.
+When `helm-buffer' contains more than one source, change source with \\<helm-map>\\[helm-next-source].
+
+Note: When reaching the end of a source, \\<helm-map>\\[helm-next-line] will *not* go to the next source unless
+variable `helm-move-to-line-cycle-in-source' is non-nil, so you will have to use \\<helm-map>\\[helm-next-source].
-NOTE: When at end of source \\<helm-map>\\[helm-next-line] will NOT go to next source if
-variable `helm-move-to-line-cycle-in-source' is non--nil, so you will have to use \\<helm-map>\\[helm-next-source].
+** Resume previous session from current Helm session
-** Resume previous session from current helm session
+You can use `C-c n' (`helm-run-cycle-resume') to cycle in resumables sources.
+`C-c n' is a special key set with `helm-define-key-with-subkeys' which, after pressing it, allows you
+to keep cycling with further `n'.
-You can use `C-c n' which is bound to `helm-run-cycle-resume' to cycle in resumables sources.
-`C-c n' is a special key bound with `helm-define-key-with-subkeys' which allow you
-to hit `C-c n' at first and then continue cycling with only `n'.
Tip: You can bound the same key in `global-map' to `helm-cycle-resume'
- with `helm-define-key-with-subkeys' to allow you cycling transparently
- from outside and inside helm session.
- You can also bind the cycling commands to single key pressed (e.g S-f1) this time
- with a simple `define-key' (note that S-f1 is not available in terminals).
+ with `helm-define-key-with-subkeys' to let you transparently cycle
+ sessions, Helm fired up or not.
+ You can also bind the cycling commands to single key presses (e.g. `S-<f1>') this time
+ with a simple `define-key'. (Note that `S-<f1>' is not available in terminals.)
+
+Note: `helm-define-key-with-subkeys' is available only once Helm is loaded.
-NOTE: `helm-define-key-with-subkeys' is available only once helm is loaded.
+You can also use \\<helm-map>\\[helm-resume-previous-session-after-quit] to resume
+the previous session, or \\<helm-map>\\[helm-resume-list-buffers-after-quit]
+to have completion on all resumable buffers.
-You can also use \\<helm-map>\\[helm-resume-previous-session-after-quit] to resume
-the previous session before this one, or \\<helm-map>\\[helm-resume-list-buffers-after-quit]
-to have completion on all resumables buffers.
+** Global commands
-** Global Commands
+*** Resume Helm session from outside Helm
-*** Resume helm session from outside helm
+\\<global-map>\\[helm-resume] revives the last `helm' session. Binding a key to
+this command will greatly improve `helm' interactivity, e.g. when quitting Helm
+accidentally.
-\\<global-map>\\[helm-resume] revives the last `helm' session.
-Very useful for resuming previous Helm. Binding a key to this
-command will greatly improve `helm' interactivity especially
-after an accidental exit.
-You can call \\<global-map>\\[helm-resume] with a prefix arg to have completion on previous
-sources used and resumables.
-You can also cycle in these source with `helm-cycle-resume' (see above).
+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
+these sources with `helm-cycle-resume' (see above).
-** Debugging helm
+** Debugging Helm
-helm have a special variable called `helm-debug', setting it to non-nil
-will allow helm logging in a special outline-mode buffer.
-Helm is resetting the variable to nil at end of each session.
+Helm exposes the special variable `helm-debug': setting it to non-nil
+will enable Helm logging in a special outline-mode buffer.
+Helm resets the variable to nil at the end of each session.
-A convenient command is bound to \\<helm-map>\\[helm-enable-or-switch-to-debug]
-and allow turning debugging to this session only.
-To avoid accumulating log while you are typing your pattern, you can use
-\\<helm-map>\\[helm-toggle-suspend-update] to turn off updating, then when you
-are ready turn it on again to start updating.
+For convenience, \\<helm-map>\\[helm-enable-or-switch-to-debug]
+allows you to turn on debugging for this session only.
+To avoid accumulating log entries while you are typing patterns, you can use
+\\<helm-map>\\[helm-toggle-suspend-update] to turn off updating. When you
+are ready turn it on again to resume logging.
-Once you exit your helm session you can access the debug buffer with `helm-debug-open-last-log'.
-It is possible to save logs to dated files when `helm-debug-root-directory'
-is set to a valid directory.
+Once you exit your Helm session you can access the debug buffer with
+`helm-debug-open-last-log'. It is possible to save logs to dated files when
+`helm-debug-root-directory' is set to a valid directory.
-NOTE: Be aware that helm log buffers grow really fast, so use `helm-debug' only when needed.
+Note: Be aware that Helm log buffers grow really fast, so use `helm-debug' only
+when needed.
-** Writing your own helm sources
+** Writing your own Helm sources
-It is easy writing simple sources for your own usage.
-Basically in a call to `helm' function, the sources are added as a
-single source which can be a symbol or a list of sources in the :sources slot.
-Sources can be builded with different eieio classes depending
-what you want to do, for simplifying this several `helm-build-*' macros are provided.
-We will not go further here, see [[https://github.com/emacs-helm/helm/wiki/Developing][Helm wiki]] for more infos.
-Below simple examples to start with.
+Writing simple sources for your own usage is easy. When calling the `helm'
+function, the sources are added the :sources slot which can be a symbol or a
+list of sources. Sources can be built with different EIEIO classes depending
+what you want to do. To simplify this, several `helm-build-*' macros are
+provided. Below, simple examples to start with.
+
+We will not go further here, see [[https://github.com/emacs-helm/helm/wiki/Developing][Helm wiki]] and the source
+code for more information and more complex exapmles.
#+begin_src elisp
@@ -1187,9 +1184,6 @@ Below simple examples to start with.
#+end_src
-For more complex sources, See [[https://github.com/emacs-helm/helm/wiki/Developing][Helm wiki]]
-and the many examples you will find in helm source code.
-
** Helm Map
\\{helm-map}"
"Message string containing detailed help for `helm'.
@@ -2479,13 +2473,21 @@ frame configuration as per `helm-save-configuration-functions'."
(select-frame-set-input-focus frame))))))
(defun helm-split-window-default-fn (window)
+ "Default function to split windows before displaying `helm-buffer'.
+
+It is used as default value for
+`helm-split-window-preferred-function' which is then the let-bounded
+value of `split-window-preferred-function' in `helm-display-buffer'.
+When `helm-display-function' which default to
+`helm-default-display-buffer' is called from `helm-display-buffer' the
+value of `split-window-preferred-function' will be used by `display-buffer'."
(let (split-width-threshold)
(if (and (fboundp 'window-in-direction)
;; Don't try to split when starting in a minibuffer
;; e.g M-: and try to use helm-show-kill-ring.
(not (minibufferp helm-current-buffer)))
(if (or (one-window-p t)
- helm-split-window-in-side-p)
+ helm-split-window-inside-p)
(split-window
(selected-window) nil (if (eq helm-split-window-default-side 'other)
'below helm-split-window-default-side))
@@ -2519,7 +2521,10 @@ frame configuration as per `helm-save-configuration-functions'."
;;
(defun helm-display-buffer (buffer)
"Display BUFFER.
-The function to display `helm-buffer'."
+
+The function used to display `helm-buffer' by calling
+`helm-display-function' which split window with
+`helm-split-window-preferred-function'."
(let (pop-up-frames
(split-window-preferred-function
helm-split-window-preferred-function)
@@ -2557,15 +2562,10 @@ value of `helm-full-frame' or `helm-split-window-default-side'."
(progn (and (not (minibufferp helm-current-buffer))
(delete-other-windows))
(switch-to-buffer buffer))
- (when (and (or helm-always-two-windows helm-autoresize-mode
- (and (not helm-split-window-in-side-p)
- (eq (save-selected-window
- (funcall helm-split-window-preferred-function
- (selected-window)))
- (get-buffer-window helm-current-buffer))))
+ (when (and (or helm-always-two-windows helm-autoresize-mode)
(not (eq helm-split-window-default-side 'same))
(not (minibufferp helm-current-buffer))
- (not helm-split-window-in-side-p))
+ (not helm-split-window-inside-p))
(delete-other-windows))
(display-buffer
buffer `(nil . ((window-height . ,helm-display-buffer-default-height)
@@ -3071,9 +3071,11 @@ WARNING: Do not use this mode yourself, it is internal to helm."
(helm-interpret-value candidate-proc)
(helm-interpret-value candidate-fn source))
(error (helm-log "Error: %S" (setq cfn-error err)) nil))))
- (when (and (processp candidates) (not candidate-proc))
- (warn "Candidates function `%s' should be called in a `candidates-process' attribute"
- candidate-fn))
+ (cond ((and (processp candidates) (not candidate-proc))
+ (warn "Candidates function `%s' should be called in a `candidates-process' attribute"
+ candidate-fn))
+ ((and candidate-proc (not (processp candidates)))
+ (error "Candidates function `%s' should run a process" candidate-proc)))
(cond ((processp candidates)
;; Candidates will be filtered later in process filter.
candidates)
@@ -5711,7 +5713,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 nil src)))
+ (sel (or selection (helm-get-selection nil nil source)))
(selection-end (if (helm-pos-multiline-p)
(or (helm-get-next-candidate-separator-pos) ; Stays within source
(helm-get-next-header-pos)