From 1653b5d7eb5381624058cb5e7979e064b1f154c8 Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Wed, 7 Sep 2022 18:58:27 +0200 Subject: [PATCH] update helm Signed-off-by: Andreas Gerler --- bba.org | 2 +- elpa/helm-20210729.1510/helm-pkg.el | 13 - .../.dir-locals.el | 2 +- .../emacs-helm.sh | 4 +- .../helm-adaptive.el | 23 +- .../helm-autoloads.el | 290 ++- .../helm-bookmark.el | 79 +- .../helm-buffers.el | 61 +- .../helm-color.el | 2 +- .../helm-comint.el | 0 .../helm-command.el | 131 +- .../helm-config.el | 10 +- .../helm-dabbrev.el | 10 +- .../helm-easymenu.el | 2 +- .../helm-elisp-package.el | 12 +- .../helm-elisp.el | 197 +- .../helm-epa.el | 6 +- .../helm-eshell.el | 4 +- .../helm-eval.el | 2 +- .../helm-external.el | 161 +- .../helm-fd.el | 8 +- .../helm-files.el | 1632 ++++++++++++----- .../helm-find.el | 2 +- .../helm-font.el | 5 +- .../helm-for-files.el | 19 +- .../helm-global-bindings.el | 34 +- .../helm-grep.el | 174 +- .../helm-help.el | 185 +- .../helm-id-utils.el | 2 +- .../helm-imenu.el | 192 +- .../helm-info.el | 90 +- .../helm-locate.el | 26 +- .../helm-man.el | 2 +- .../helm-misc.el | 68 +- .../helm-mode.el | 445 +++-- .../helm-net.el | 57 +- .../helm-occur.el | 72 +- elpa/helm-20220616.1004/helm-pkg.el | 11 + .../helm-regexp.el | 2 +- .../helm-ring.el | 5 +- .../helm-semantic.el | 2 +- .../helm-shell.el | 0 .../helm-sys.el | 25 +- .../helm-tags.el | 16 +- .../helm-types.el | 16 +- .../helm-utils.el | 116 +- .../helm-x-files.el | 9 +- elpa/helm-20220616.1004/helm.el | 43 + elpa/helm-core-20210128.1814/helm-core-pkg.el | 7 - .../helm-core-autoloads.el | 44 +- elpa/helm-core-20220607.1243/helm-core-pkg.el | 11 + .../helm-core.el} | 1075 ++++++----- .../helm-lib.el | 282 ++- .../helm-multi-match.el | 68 +- .../helm-source.el | 262 ++- 55 files changed, 4042 insertions(+), 1976 deletions(-) delete mode 100644 elpa/helm-20210729.1510/helm-pkg.el rename elpa/{helm-20210729.1510 => helm-20220616.1004}/.dir-locals.el (69%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/emacs-helm.sh (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-adaptive.el (91%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-autoloads.el (73%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-bookmark.el (90%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-buffers.el (95%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-color.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-comint.el (100%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-command.el (75%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-config.el (77%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-dabbrev.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-easymenu.el (97%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-elisp-package.el (97%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-elisp.el (84%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-epa.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-eshell.el (99%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-eval.el (99%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-external.el (55%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-fd.el (96%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-files.el (81%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-find.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-font.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-for-files.el (93%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-global-bindings.el (74%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-grep.el (92%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-help.el (93%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-id-utils.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-imenu.el (56%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-info.el (75%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-locate.el (95%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-man.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-misc.el (77%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-mode.el (86%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-net.el (89%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-occur.el (92%) create mode 100644 elpa/helm-20220616.1004/helm-pkg.el rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-regexp.el (98%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-ring.el (99%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-semantic.el (99%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-shell.el (100%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-sys.el (96%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-tags.el (97%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-types.el (96%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-utils.el (92%) rename elpa/{helm-20210729.1510 => helm-20220616.1004}/helm-x-files.el (94%) create mode 100644 elpa/helm-20220616.1004/helm.el delete mode 100644 elpa/helm-core-20210128.1814/helm-core-pkg.el rename elpa/{helm-core-20210128.1814 => helm-core-20220607.1243}/helm-core-autoloads.el (84%) create mode 100644 elpa/helm-core-20220607.1243/helm-core-pkg.el rename elpa/{helm-core-20210128.1814/helm.el => helm-core-20220607.1243/helm-core.el} (90%) rename elpa/{helm-core-20210128.1814 => helm-core-20220607.1243}/helm-lib.el (87%) rename elpa/{helm-core-20210128.1814 => helm-core-20220607.1243}/helm-multi-match.el (86%) rename elpa/{helm-core-20210128.1814 => helm-core-20220607.1243}/helm-source.el (84%) diff --git a/bba.org b/bba.org index 3fc8fef4..79526935 100644 --- a/bba.org +++ b/bba.org @@ -4337,7 +4337,7 @@ Some links you might check out: (if (>= emacs-major-version 24) (progn (add-to-list 'load-path - "~/.emacs.d/elpa/helm-20210729.1510") + "~/.emacs.d/elpa/helm-20220616.1004") (require 'helm) (helm-mode 1) (global-set-key (kbd "M-y") 'helm-show-kill-ring) diff --git a/elpa/helm-20210729.1510/helm-pkg.el b/elpa/helm-20210729.1510/helm-pkg.el deleted file mode 100644 index d2771b7e..00000000 --- a/elpa/helm-20210729.1510/helm-pkg.el +++ /dev/null @@ -1,13 +0,0 @@ -(define-package "helm" "20210729.1510" "Helm is an Emacs incremental and narrowing framework" - '((emacs "25.1") - (async "1.9.4") - (popup "0.5.3") - (helm-core "3.8.0")) - :commit "1b6ffb10b8cabf177664a34827961520fba88ebe" :authors - '(("Thierry Volpiatto" . "thierry.volpiatto@gmail.com")) - :maintainer - '("Thierry Volpiatto" . "thierry.volpiatto@gmail.com") - :url "https://github.com/emacs-helm/helm") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/helm-20210729.1510/.dir-locals.el b/elpa/helm-20220616.1004/.dir-locals.el similarity index 69% rename from elpa/helm-20210729.1510/.dir-locals.el rename to elpa/helm-20220616.1004/.dir-locals.el index d5693d6f..5ed84320 100644 --- a/elpa/helm-20210729.1510/.dir-locals.el +++ b/elpa/helm-20220616.1004/.dir-locals.el @@ -1,7 +1,7 @@ ;;; Directory Local Variables ;;; For more information see (info "(emacs) Directory Variables") -((nil . ((bug-reference-bug-regexp . "\\([Ii]ssue ?#?\\|[Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z+-]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)") +((nil . ((bug-reference-bug-regexp . "\\(\\b\\(?:[Ii]ssue ?#?\\|[Bb]ug ?#?\\|[Pp]atch ?#\\|RFE ?#\\|PR [a-z+-]+/\\)\\([0-9]+\\(?:#[0-9]+\\)?\\)\\)") (bug-reference-url-format . "https://github.com/emacs-helm/helm/issues/%s") (byte-compile-warnings . (not obsolete not docstrings)))) (emacs-lisp-mode . ((mode . bug-reference-prog) diff --git a/elpa/helm-20210729.1510/emacs-helm.sh b/elpa/helm-20220616.1004/emacs-helm.sh similarity index 98% rename from elpa/helm-20210729.1510/emacs-helm.sh rename to elpa/helm-20220616.1004/emacs-helm.sh index 9c41716d..c3020ea8 100755 --- a/elpa/helm-20210729.1510/emacs-helm.sh +++ b/elpa/helm-20220616.1004/emacs-helm.sh @@ -1,7 +1,7 @@ #!/usr/bin/env sh -## Copyright (C) 2012 ~ 2020 Thierry Volpiatto +## Copyright (C) 2012 ~ 2021 Thierry Volpiatto ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -234,6 +234,8 @@ cat > $CONF_FILE < +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -65,7 +65,8 @@ selection.") (defvar helm-adaptive-history nil "Contains the stored history information. -Format: ((SOURCE-NAME (SELECTED-CANDIDATE (PATTERN . NUMBER-OF-USE) ...) ...) ...)") +Format: ((SOURCE-NAME + (SELECTED-CANDIDATE (PATTERN . NUMBER-OF-USE) ...) ...) ...)") (defconst helm-adaptive-freq-coefficient 5) (defconst helm-adaptive-recent-coefficient 2) @@ -234,7 +235,19 @@ This is a filtered candidate transformer you can use with the for info = (or (and (assq 'multiline source) (replace-regexp-in-string "\n\\'" "" cand)) - cand) + ;; Some transformers like in + ;; bookmarks may add a leading + ;; space to provide additional + ;; infos like an icon as a + ;; display prop, strip out this + ;; leading space for + ;; comparison. Same for a + ;; trailing space (helm + ;; boookmark add bmk location as + ;; a display prop when + ;; displaying it). + (helm-aand (replace-regexp-in-string "\\` " "" cand) + (replace-regexp-in-string " \\'" "" it))) when (cl-member info candidates :test 'helm-adaptive-compare) collect (car it) into sorted @@ -258,7 +271,9 @@ Useful when you have a old or corrupted (interactive) (when (y-or-n-p "Really delete all your `helm-adaptive-history'? ") (setq helm-adaptive-history nil) - (delete-file helm-adaptive-history-file))) + (when (and helm-adaptive-history-file + (file-exists-p helm-adaptive-history-file)) + (delete-file helm-adaptive-history-file)))) (defun helm-adaptive-compare (x y) "Compare display parts if some of candidates X and Y. diff --git a/elpa/helm-20210729.1510/helm-autoloads.el b/elpa/helm-20220616.1004/helm-autoloads.el similarity index 73% rename from elpa/helm-20210729.1510/helm-autoloads.el rename to elpa/helm-20220616.1004/helm-autoloads.el index 3bede507..4ddafa20 100644 --- a/elpa/helm-20210729.1510/helm-autoloads.el +++ b/elpa/helm-20220616.1004/helm-autoloads.el @@ -1,4 +1,4 @@ -;;; helm-autoloads.el --- automatically extracted autoloads +;;; helm-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*- ;; ;;; Code: @@ -22,10 +22,19 @@ or call the function `helm-adaptive-mode'.") (autoload 'helm-adaptive-mode "helm-adaptive" "\ Toggle adaptive sorting in all sources. -If called interactively, enable Helm-Adaptive mode if ARG is -positive, and disable it if ARG is zero or negative. If called -from Lisp, also enable the mode if ARG is omitted or nil, and -toggle it if ARG is `toggle'; disable the mode otherwise. +This is a minor mode. If called interactively, toggle the +`Helm-Adaptive mode' mode. If the prefix argument is positive, +enable the mode, and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `(default-value \\='helm-adaptive-mode)'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. \(fn &optional ARG)" t nil) @@ -34,7 +43,7 @@ Delete all `helm-adaptive-history' and his file. Useful when you have a old or corrupted `helm-adaptive-history-file'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-adaptive" '("helm-adapt"))) +(register-definition-prefixes "helm-adaptive" '("helm-adapt")) ;;;*** @@ -49,7 +58,7 @@ Preconfigured `helm' for bookmarks (filtered by category). Optional source `helm-source-bookmark-addressbook' is loaded only if external addressbook-bookmark package is installed." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-bookmark" '("bmkext-jump-" "bookmark" "helm-"))) +(register-definition-prefixes "helm-bookmark" '("bmkext-jump-" "bookmark" "helm-")) ;;;*** @@ -62,7 +71,7 @@ Preconfigured `helm' to list buffers." t nil) (autoload 'helm-mini "helm-buffers" "\ Preconfigured `helm' displaying `helm-mini-default-sources'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-buffers" '("helm-"))) +(register-definition-prefixes "helm-buffers" '("helm-")) ;;;*** @@ -72,7 +81,7 @@ Preconfigured `helm' displaying `helm-mini-default-sources'." t nil) (autoload 'helm-colors "helm-color" "\ Preconfigured `helm' for color." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-color" '("helm-"))) +(register-definition-prefixes "helm-color" '("helm-")) ;;;*** @@ -88,7 +97,7 @@ Pre-configured `helm' to browse the prompts of all comint sessions." t nil) (autoload 'helm-comint-input-ring "helm-comint" "\ Preconfigured `helm' that provide completion of `comint' history." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-comint" '("helm-"))) +(register-definition-prefixes "helm-comint" '("helm-")) ;;;*** @@ -110,7 +119,7 @@ You can get help on each command by persistent action. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-command" '("helm-"))) +(register-definition-prefixes "helm-command" '("helm-")) ;;;*** @@ -120,7 +129,7 @@ You can get help on each command by persistent action. (autoload 'helm-dabbrev "helm-dabbrev" "\ Preconfigured helm for dynamic abbreviations." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-dabbrev" '("helm-dabbrev-"))) +(register-definition-prefixes "helm-dabbrev" '("helm-dabbrev-")) ;;;*** @@ -161,7 +170,7 @@ Preconfigured `helm' for timers." t nil) (autoload 'helm-complex-command-history "helm-elisp" "\ Preconfigured `helm' for complex command history." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-elisp" '("helm-" "with-helm-show-completion"))) +(register-definition-prefixes "helm-elisp" '("helm-" "with-helm-show-completion")) ;;;*** @@ -183,7 +192,7 @@ remote. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-elisp-package" '("helm-"))) +(register-definition-prefixes "helm-elisp-package" '("helm-")) ;;;*** @@ -203,10 +212,19 @@ or call the function `helm-epa-mode'.") (autoload 'helm-epa-mode "helm-epa" "\ Enable helm completion on gpg keys in epa functions. -If called interactively, enable Helm-Epa mode if ARG is positive, -and disable it if ARG is zero or negative. If called from Lisp, -also enable the mode if ARG is omitted or nil, and toggle it if -ARG is `toggle'; disable the mode otherwise. +This is a minor mode. If called interactively, toggle the +`Helm-Epa mode' mode. If the prefix argument is positive, enable +the mode, and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `(default-value \\='helm-epa-mode)'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. \(fn &optional ARG)" t nil) @@ -214,7 +232,7 @@ ARG is `toggle'; disable the mode otherwise. List all gpg keys. This is the helm interface for `epa-list-keys'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-epa" '("helm-epa"))) +(register-definition-prefixes "helm-epa" '("helm-epa")) ;;;*** @@ -233,7 +251,7 @@ Pre-configured `helm' to browse the prompts of the current Eshell." t nil) (autoload 'helm-eshell-prompts-all "helm-eshell" "\ Pre-configured `helm' to browse the prompts of all Eshell sessions." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-eshell" '("helm-e"))) +(register-definition-prefixes "helm-eshell" '("helm-e")) ;;;*** @@ -251,7 +269,7 @@ Preconfigured `helm' for `helm-source-evaluation-result' with `eldoc' support." (autoload 'helm-calcul-expression "helm-eval" "\ Preconfigured `helm' for `helm-source-calculation-result'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-eval" '("helm-"))) +(register-definition-prefixes "helm-eval" '("helm-")) ;;;*** @@ -260,26 +278,62 @@ Preconfigured `helm' for `helm-source-calculation-result'." t nil) (autoload 'helm-run-external-command "helm-external" "\ Preconfigured `helm' to run External PROGRAM asyncronously from Emacs. -If program is already running exit with error. -You can set your own list of commands with -`helm-external-commands-list'. +If program is already running try to run `helm-raise-command' if +defined otherwise exit with error. You can set your own list of +commands with `helm-external-commands-list'." t nil) -\(fn PROGRAM)" t nil) - -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-external" '("helm-"))) +(register-definition-prefixes "helm-external" '("helm-")) ;;;*** ;;;### (autoloads nil "helm-fd" "helm-fd.el" (0 0 0 0)) ;;; Generated autoloads from helm-fd.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-fd" '("helm-fd-"))) +(register-definition-prefixes "helm-fd" '("helm-fd-")) ;;;*** ;;;### (autoloads nil "helm-files" "helm-files.el" (0 0 0 0)) ;;; Generated autoloads from helm-files.el +(defvar helm-ff-icon-mode nil "\ +Non-nil if Helm-Ff-Icon mode is enabled. +See the `helm-ff-icon-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `helm-ff-icon-mode'.") + +(custom-autoload 'helm-ff-icon-mode "helm-files" nil) + +(autoload 'helm-ff-icon-mode "helm-files" "\ +Display icons from `all-the-icons' package in HFF when enabled. + +This is a minor mode. If called interactively, toggle the +`Helm-Ff-Icon mode' mode. If the prefix argument is positive, +enable the mode, and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `(default-value \\='helm-ff-icon-mode)'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. + +NOTE: This mode is building `helm-source-find-files', so if you enable +it from your init file, ensure to call it _after_ your defmethod's +`helm-setup-user-source' definitions (if some) to ensure they are called. + +\(fn &optional ARG)" t nil) + +(autoload 'helm-ff-cleanup-image-dired-dir-and-cache "helm-files" "\ +Cleanup `image-dired-dir' directory. +Delete all thumb files that are no more associated with an existing +image file in `helm-ff-image-dired-thumbnails-cache'." t nil) + (autoload 'helm-projects-history "helm-files" "\ @@ -323,7 +377,7 @@ in Emacs < to 25.1.50.1 (See Emacs bug http://debbugs.gnu.org/cgi/bugreport.cgi? It allows additionally to delete more than one connection at once." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-files" '("eshell-command-aliases-list" "helm-"))) +(register-definition-prefixes "helm-files" '("eshell-command-aliases-list" "helm-")) ;;;*** @@ -350,7 +404,7 @@ are passed to \"find\" literally. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-find" '("helm-"))) +(register-definition-prefixes "helm-find" '("helm-")) ;;;*** @@ -367,7 +421,7 @@ Called with a prefix arg force reloading cache. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-font" '("helm-"))) +(register-definition-prefixes "helm-font" '("helm-")) ;;;*** @@ -390,7 +444,7 @@ searching for is already found." t nil) (autoload 'helm-recentf "helm-for-files" "\ Preconfigured `helm' for `recentf'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-for-files" '("helm-"))) +(register-definition-prefixes "helm-for-files" '("helm-")) ;;;*** @@ -398,7 +452,7 @@ Preconfigured `helm' for `recentf'." t nil) ;;;;;; (0 0 0 0)) ;;; Generated autoloads from helm-global-bindings.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-global-bindings" '("helm-"))) +(register-definition-prefixes "helm-global-bindings" '("helm-command-")) ;;;*** @@ -411,6 +465,13 @@ Go to previous file in Helm grep/etags buffers." t nil) (autoload 'helm-goto-next-file "helm-grep" "\ Go to previous file in Helm grep/etags buffers." t nil) +(autoload 'helm-revert-next-error-last-buffer "helm-grep" "\ +Revert last `next-error' buffer from `current-buffer'. + +Accept to revert only `helm-grep-mode' or `helm-occur-mode' buffers. +Use this when you want to revert the `next-error' buffer after +modifications in `current-buffer'." t nil) + (autoload 'helm-do-grep-ag "helm-grep" "\ Preconfigured `helm' for grepping with AG in `default-directory'. With prefix arg prompt for type if available with your AG @@ -424,7 +485,7 @@ With a prefix arg ARG git-grep the whole repository. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-grep" '("helm-"))) +(register-definition-prefixes "helm-grep" '("helm-")) ;;;*** @@ -444,7 +505,7 @@ String displayed in mode-line in `helm-source-find-files'.") (defvar helm-top-mode-line "\\\\[helm-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend \\[helm-customize-group]:Conf") -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-help" '("helm-"))) +(register-definition-prefixes "helm-help" '("helm-")) ;;;*** @@ -458,7 +519,7 @@ Need A database created with the command `mkid' above Need id-utils as dependency which provide `mkid', `gid' etc.. See ." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-id-utils" '("helm-gid-"))) +(register-definition-prefixes "helm-id-utils" '("helm-gid-")) ;;;*** @@ -469,12 +530,12 @@ See ." t nil) Preconfigured `helm' for `imenu'." t nil) (autoload 'helm-imenu-in-all-buffers "helm-imenu" "\ -Preconfigured `helm' for fetching imenu entries in all buffers with similar mode as current. +Fetch Imenu entries in all buffers with similar mode as current. A mode is similar as current if it is the same, it is derived i.e. `derived-mode-p' or it have an association in `helm-imenu-all-buffer-assoc'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-imenu" '("helm-"))) +(register-definition-prefixes "helm-imenu" '("helm-")) ;;;*** @@ -501,7 +562,7 @@ Info files are made available. (autoload 'helm-info-at-point "helm-info" "\ Preconfigured `helm' for searching info at point." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-info" '("helm-"))) +(register-definition-prefixes "helm-info" '("helm-")) ;;;*** @@ -517,7 +578,7 @@ With a prefix arg refresh the database in each project. (autoload 'helm-locate "helm-locate" "\ Preconfigured `helm' for Locate. Note: you can add locate options after entering pattern. -See 'man locate' for valid options and also `helm-locate-command'. +See \\='man locate' for valid options and also `helm-locate-command'. You can specify a local database with prefix argument ARG. With two prefix arg, refresh the current local db or create it if @@ -530,7 +591,7 @@ Where db_path is a filename matched by \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-locate" '("helm-"))) +(register-definition-prefixes "helm-locate" '("helm-")) ;;;*** @@ -543,13 +604,44 @@ With a prefix arg reinitialize the cache. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-man" '("helm-"))) +(register-definition-prefixes "helm-man" '("helm-")) ;;;*** ;;;### (autoloads nil "helm-misc" "helm-misc.el" (0 0 0 0)) ;;; Generated autoloads from helm-misc.el +(defvar helm-minibuffer-history-mode nil "\ +Non-nil if Helm-Minibuffer-History mode is enabled. +See the `helm-minibuffer-history-mode' command +for a description of this minor mode. +Setting this variable directly does not take effect; +either customize it (see the info node `Easy Customization') +or call the function `helm-minibuffer-history-mode'.") + +(custom-autoload 'helm-minibuffer-history-mode "helm-misc" nil) + +(autoload 'helm-minibuffer-history-mode "helm-misc" "\ +Bind `helm-minibuffer-history-key' in al minibuffer maps. +This mode is enabled by `helm-mode', so there is no need to enable it directly. + +This is a minor mode. If called interactively, toggle the +`Helm-Minibuffer-History mode' mode. If the prefix argument is +positive, enable the mode, and if it is zero or negative, disable +the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `(default-value \\='helm-minibuffer-history-mode)'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. + +\(fn &optional ARG)" t nil) + (autoload 'helm-world-time "helm-misc" "\ Preconfigured `helm' to show world time. Default action change TZ environment variable locally to emacs." t nil) @@ -566,7 +658,7 @@ Preconfigured helm for stumpwm commands." t nil) (autoload 'helm-minibuffer-history "helm-misc" "\ Preconfigured `helm' for `minibuffer-history'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-misc" '("helm-"))) +(register-definition-prefixes "helm-misc" '("helm-")) ;;;*** @@ -608,19 +700,31 @@ Keys description: - REQUIRES-PATTERN: Same as helm attribute, default is 0. -- HISTORY: A list containing specific history, default is nil. - When it is non--nil, all elements of HISTORY are displayed in - a special source before COLLECTION. +- HISTORY: A symbol where each result will be saved. + If not specified as a symbol an error will popup. + When specified, all elements of HISTORY are displayed in + a special source before or after COLLECTION according to REVERSE-HISTORY. + The main difference with INPUT-HISTORY is that the result of the + completion is saved whereas in INPUT-HISTORY it is the minibuffer + contents which is saved when you exit. + Don't use the same symbol for INPUT-HISTORY and HISTORY. + NOTE: As mentionned above this has nothing to do with + `minibuffer-history-variable', therefore if you want to save this + history persistently, you will have to add this variable to the + relevant variable of your favorite tool for persistent emacs session + i.e. psession, desktop etc... + +- RAW-HISTORY: When non-nil do not remove backslashs if some in + HISTORY candidates. - INPUT-HISTORY: A symbol. The minibuffer input history will be stored there, if nil or not provided, `minibuffer-history' - will be used instead. + will be used instead. You can navigate in this history with + `M-p' and `M-n'. + Don't use the same symbol for INPUT-HISTORY and HISTORY. - CASE-FOLD: Same as `helm-case-fold-search'. -- DEL-INPUT: Boolean, when non--nil (default) remove the partial - minibuffer input from HISTORY is present. - - PERSISTENT-ACTION: A function called with one arg i.e candidate. - PERSISTENT-HELP: A string to document PERSISTENT-ACTION. @@ -652,7 +756,7 @@ Keys description: - HIST-FC-TRANSFORMER: A `filtered-candidate-transformer' function for the history source. -- MARKED-CANDIDATES: If non--nil return candidate or marked candidates as a list. +- MARKED-CANDIDATES: If non-nil return candidate or marked candidates as a list. - NOMARK: When non--nil don't allow marking candidates. @@ -688,10 +792,11 @@ in `helm-current-prefix-arg', otherwise if prefix args were given before That means you can pass prefix args before or after calling a command that use `helm-comp-read'. See `helm-M-x' for example. -\(fn PROMPT COLLECTION &key TEST INITIAL-INPUT DEFAULT PRESELECT (BUFFER \"*Helm Completions*\") MUST-MATCH FUZZY REVERSE-HISTORY (REQUIRES-PATTERN 0) HISTORY INPUT-HISTORY (CASE-FOLD helm-comp-read-case-fold-search) (DEL-INPUT t) (PERSISTENT-ACTION nil) (PERSISTENT-HELP \"DoNothing\") (MODE-LINE helm-comp-read-mode-line) HELP-MESSAGE (KEYMAP helm-comp-read-map) (NAME \"Helm Completions\") HEADER-NAME CANDIDATES-IN-BUFFER MATCH-PART MATCH-DYNAMIC EXEC-WHEN-ONLY-ONE QUIT-WHEN-NO-CAND (VOLATILE t) SORT FC-TRANSFORMER HIST-FC-TRANSFORMER (MARKED-CANDIDATES helm-comp-read-use-marked) NOMARK (ALISTP t) (CANDIDATE-NUMBER-LIMIT helm-candidate-number-limit) MULTILINE ALLOW-NEST COERCE (GROUP \\='helm))" nil nil) +\(fn PROMPT COLLECTION &key TEST INITIAL-INPUT DEFAULT PRESELECT (BUFFER \"*Helm Completions*\") MUST-MATCH FUZZY REVERSE-HISTORY (REQUIRES-PATTERN 0) (HISTORY nil SHISTORY) RAW-HISTORY INPUT-HISTORY (CASE-FOLD helm-comp-read-case-fold-search) (PERSISTENT-ACTION nil) (PERSISTENT-HELP \"DoNothing\") (MODE-LINE helm-comp-read-mode-line) HELP-MESSAGE (KEYMAP helm-comp-read-map) (NAME \"Helm Completions\") HEADER-NAME CANDIDATES-IN-BUFFER DIACRITICS MATCH-PART MATCH-DYNAMIC EXEC-WHEN-ONLY-ONE QUIT-WHEN-NO-CAND (VOLATILE t) SORT FC-TRANSFORMER HIST-FC-TRANSFORMER (MARKED-CANDIDATES helm-comp-read-use-marked) NOMARK (ALISTP t) (CANDIDATE-NUMBER-LIMIT helm-candidate-number-limit) MULTILINE ALLOW-NEST COERCE (GROUP \\='helm))" nil nil) (autoload 'helm-read-file-name "helm-mode" "\ Read a file name with helm completion. + It is helm `read-file-name' emulation. Argument PROMPT is the default prompt to use. @@ -700,11 +805,12 @@ Keys description: - NAME: Source name, default to \"Read File Name\". -- INITIAL-INPUT: Where to start reading file name, default to `default-directory'. +- INITIAL-INPUT: Where to start reading file name, + default to `default-directory' or $HOME. - BUFFER: `helm-buffer' name, defaults to \"*Helm Completions*\". -- TEST: A predicate called with one arg 'candidate'. +- TEST: A predicate called with one arg \\='candidate'. - NORET: Allow disabling helm-ff-RET (have no effect if helm-ff-RET isn't bound to RET). @@ -715,7 +821,7 @@ Keys description: - HISTORY: Display HISTORY in a special source. -- MUST-MATCH: Can be 'confirm, nil, or t. +- MUST-MATCH: Can be \\='confirm, nil, or t. - FUZZY: Enable fuzzy matching when non-nil (Enabled by default). @@ -723,15 +829,17 @@ Keys description: - NOMARK: When non--nil don't allow marking candidates. -- ALISTP: Don't use `all-completions' in history (take effect only on history). +- ALISTP: Don't use `all-completions' in history + (take effect only on history). - PERSISTENT-ACTION-IF: a persistent if action function. - PERSISTENT-HELP: persistent help message. -- MODE-LINE: A mode line message, default is `helm-read-file-name-mode-line-string'. +- MODE-LINE: A mode line message, default is + `helm-read-file-name-mode-line-string'. -\(fn PROMPT &key (NAME \"Read File Name\") (INITIAL-INPUT default-directory) (BUFFER \"*Helm file completions*\") TEST NORET (CASE-FOLD helm-file-name-case-fold-search) PRESELECT HISTORY MUST-MATCH (FUZZY t) DEFAULT MARKED-CANDIDATES (CANDIDATE-NUMBER-LIMIT helm-ff-candidate-number-limit) NOMARK (ALISTP t) (PERSISTENT-ACTION-IF \\='helm-find-files-persistent-action-if) (PERSISTENT-HELP \"Hit1 Expand Candidate, Hit2 or (C-u) Find file\") (MODE-LINE helm-read-file-name-mode-line-string))" nil nil) +\(fn PROMPT &key (NAME \"Read File Name\") INITIAL-INPUT (BUFFER \"*Helm file completions*\") TEST NORET (CASE-FOLD helm-file-name-case-fold-search) PRESELECT HISTORY MUST-MATCH (FUZZY t) DEFAULT MARKED-CANDIDATES (CANDIDATE-NUMBER-LIMIT helm-ff-candidate-number-limit) NOMARK (ALISTP t) (PERSISTENT-ACTION-IF \\='helm-find-files-persistent-action-if) (PERSISTENT-HELP \"Hit1 Expand Candidate, Hit2 or (C-u) Find file\") (MODE-LINE helm-read-file-name-mode-line-string))" nil nil) (defvar helm-mode nil "\ Non-nil if Helm mode is enabled. @@ -766,7 +874,7 @@ Note: This mode is incompatible with Emacs23. \(fn &optional ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-mode" '("helm-"))) +(register-definition-prefixes "helm-mode" '("helm-")) ;;;*** @@ -809,7 +917,7 @@ Browse URL with conkeror browser. \(fn URL &optional IGNORE)" t nil) (autoload 'helm-browse-url-nyxt "helm-net" "\ -Browse URL with next browser. +Browse URL with nyxt browser. \(fn URL &optional IGNORE)" t nil) @@ -821,7 +929,7 @@ Preconfigured `helm' to search PATTERN with search ENGINE. (autoload 'helm-google-suggest "helm-net" "\ Preconfigured `helm' for Google search with Google suggest." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-net" '("helm-"))) +(register-definition-prefixes "helm-net" '("helm-")) ;;;*** @@ -863,7 +971,7 @@ The prefix arg can be set before calling To use this bind it to a key in `isearch-mode-map'." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-occur" '("helm-"))) +(register-definition-prefixes "helm-occur" '("helm-")) ;;;*** @@ -874,7 +982,7 @@ To use this bind it to a key in `isearch-mode-map'." t nil) Preconfigured helm to build regexps. `query-replace-regexp' can be run from there against found regexp." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-regexp" '("helm-"))) +(register-definition-prefixes "helm-regexp" '("helm-")) ;;;*** @@ -888,7 +996,9 @@ Preconfigured `helm' for `helm-source-mark-ring'." t nil) Preconfigured `helm' for `helm-source-global-mark-ring'." t nil) (autoload 'helm-all-mark-rings "helm-ring" "\ -Preconfigured `helm' for `helm-source-global-mark-ring' and `helm-source-mark-ring'." t nil) +Preconfigured `helm' for mark rings. +Source used are `helm-source-global-mark-ring' and +`helm-source-mark-ring'." t nil) (autoload 'helm-register "helm-ring" "\ Preconfigured `helm' for Emacs registers." t nil) @@ -905,7 +1015,7 @@ Define your macros with `f3' and `f4'. See (info \"(emacs) Keyboard Macros\") for detailed infos. This command is useful when used with persistent action." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-ring" '("helm-"))) +(register-definition-prefixes "helm-ring" '("helm-")) ;;;*** @@ -929,7 +1039,7 @@ Fill in the symbol at point by default. \(fn ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-semantic" '("helm-s"))) +(register-definition-prefixes "helm-semantic" '("helm-s")) ;;;*** @@ -958,10 +1068,19 @@ or call the function `helm-top-poll-mode'.") (autoload 'helm-top-poll-mode "helm-sys" "\ Refresh automatically helm top buffer once enabled. -If called interactively, enable Helm-Top-Poll mode if ARG is -positive, and disable it if ARG is zero or negative. If called -from Lisp, also enable the mode if ARG is omitted or nil, and -toggle it if ARG is `toggle'; disable the mode otherwise. +This is a minor mode. If called interactively, toggle the +`Helm-Top-Poll mode' mode. If the prefix argument is positive, +enable the mode, and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `(default-value \\='helm-top-poll-mode)'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. \(fn &optional ARG)" t nil) @@ -974,7 +1093,7 @@ Preconfigured `helm' for Emacs process." t nil) (autoload 'helm-xrandr-set "helm-sys" "\ Preconfigured helm for xrandr." t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-sys" '("helm-"))) +(register-definition-prefixes "helm-sys" '("helm-")) ;;;*** @@ -995,14 +1114,14 @@ This function aggregates three sources of tag files: \(fn REINIT)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-tags" '("helm-"))) +(register-definition-prefixes "helm-tags" '("helm-")) ;;;*** ;;;### (autoloads nil "helm-types" "helm-types.el" (0 0 0 0)) ;;; Generated autoloads from helm-types.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-types" '("helm-"))) +(register-definition-prefixes "helm-types" '("helm-")) ;;;*** @@ -1022,26 +1141,35 @@ or call the function `helm-popup-tip-mode'.") (autoload 'helm-popup-tip-mode "helm-utils" "\ Show help-echo informations in a popup tip at end of line. -If called interactively, enable Helm-Popup-Tip mode if ARG is -positive, and disable it if ARG is zero or negative. If called -from Lisp, also enable the mode if ARG is omitted or nil, and -toggle it if ARG is `toggle'; disable the mode otherwise. +This is a minor mode. If called interactively, toggle the +`Helm-Popup-Tip mode' mode. If the prefix argument is positive, +enable the mode, and if it is zero or negative, disable the mode. + +If called from Lisp, toggle the mode if ARG is `toggle'. Enable +the mode if ARG is nil, omitted, or is a positive number. +Disable the mode if ARG is a negative number. + +To check whether the minor mode is enabled in the current buffer, +evaluate `(default-value \\='helm-popup-tip-mode)'. + +The mode's hook is called both when the mode is enabled and when +it is disabled. \(fn &optional ARG)" t nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-utils" '("helm-" "with-helm-display-marked-candidates"))) +(register-definition-prefixes "helm-utils" '("helm-" "with-helm-display-marked-candidates")) ;;;*** ;;;### (autoloads nil "helm-x-files" "helm-x-files.el" (0 0 0 0)) ;;; Generated autoloads from helm-x-files.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-x-files" '("helm-"))) +(register-definition-prefixes "helm-x-files" '("helm-")) ;;;*** -;;;### (autoloads nil nil ("helm-config.el" "helm-easymenu.el" "helm-pkg.el") -;;;;;; (0 0 0 0)) +;;;### (autoloads nil nil ("helm-config.el" "helm-easymenu.el" "helm-pkg.el" +;;;;;; "helm.el") (0 0 0 0)) ;;;*** diff --git a/elpa/helm-20210729.1510/helm-bookmark.el b/elpa/helm-20220616.1004/helm-bookmark.el similarity index 90% rename from elpa/helm-20210729.1510/helm-bookmark.el rename to elpa/helm-20220616.1004/helm-bookmark.el index aae92d22..1fad3a51 100644 --- a/elpa/helm-20210729.1510/helm-bookmark.el +++ b/elpa/helm-20220616.1004/helm-bookmark.el @@ -1,6 +1,6 @@ ;;; helm-bookmark.el --- Helm for Emacs regular Bookmarks. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -29,6 +29,10 @@ (declare-function helm-browse-project "helm-files" (arg)) (declare-function addressbook-bookmark-edit "ext:addressbook-bookmark.el" (bookmark)) +(declare-function all-the-icons-fileicon "ext:all-the-icons.el") +(declare-function all-the-icons-icon-for-file"ext:all-the-icons.el") +(declare-function all-the-icons-octicon "ext:all-the-icons.el") + (defgroup helm-bookmark nil "Predefined configurations for `helm.el'." @@ -45,6 +49,7 @@ helm-source-bookmark-helm-find-files helm-source-bookmark-info helm-source-bookmark-gnus + helm-source-bookmark-mu4e helm-source-bookmark-man helm-source-bookmark-images helm-source-bookmark-w3m) @@ -54,6 +59,11 @@ :group 'helm-bookmark :type '(repeat (choice symbol))) +(defcustom helm-bookmark-use-icon nil + "Display candidates with an icon with `all-the-icons' when non nil." + :type 'boolean + :group 'helm-bookmark) + (defface helm-bookmark-info `((t ,@(and (>= emacs-major-version 27) '(:extend t)) @@ -121,7 +131,8 @@ (helm-init-candidates-in-buffer 'global (bookmark-all-names)))) - (filtered-candidate-transformer :initform 'helm-bookmark-transformer))) + (filtered-candidate-transformer :initform 'helm-bookmark-transformer) + (find-file-target :initform #'helm-bookmarks-quit-an-find-file-fn))) (defvar helm-source-bookmarks (helm-make-source "Bookmarks" 'helm-source-basic-bookmarks) @@ -145,15 +156,11 @@ (let* ((real (helm-get-selection helm-buffer)) (trunc (if (> (string-width real) bookmark-bmenu-file-column) (helm-substring real bookmark-bmenu-file-column) - real)) - (loc (bookmark-location real))) + real))) (setq helm-bookmark-show-location (not helm-bookmark-show-location)) (helm-update (if helm-bookmark-show-location - (concat (regexp-quote trunc) - " +" - (regexp-quote - (if (listp loc) (car loc) loc))) - (regexp-quote real))))) + (regexp-quote trunc) + (regexp-quote real))))) (defun helm-bookmark-toggle-filename () "Toggle bookmark location visibility." @@ -210,6 +217,11 @@ BOOKMARK is a bookmark name or a bookmark record." (eq (bookmark-get-handler bookmark) 'gnus-summary-bookmark-jump) (eq (bookmark-get-handler bookmark) 'bookmarkp-jump-gnus))) +(defun helm-bookmark-mu4e-bookmark-p (bookmark) + "Return non nil if BOOKMARK is a mu4e bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'mu4e-bookmark-jump)) + (defun helm-bookmark-w3m-bookmark-p (bookmark) "Return non-nil if BOOKMARK is a W3m bookmark. BOOKMARK is a bookmark name or a bookmark record." @@ -279,6 +291,7 @@ BOOKMARK is a bookmark name or a bookmark record." (cl-loop for pred in '(helm-bookmark-org-file-p helm-bookmark-addressbook-p helm-bookmark-gnus-bookmark-p + helm-bookmark-mu4e-bookmark-p helm-bookmark-w3m-bookmark-p helm-bookmark-woman-man-bookmark-p helm-bookmark-info-bookmark-p @@ -344,7 +357,18 @@ If `browse-url-browser-function' is set to something else than (defclass helm-source-filtered-bookmarks (helm-source-in-buffer helm-type-bookmark) ((filtered-candidate-transformer :initform '(helm-adaptive-sort - helm-highlight-bookmark)))) + helm-highlight-bookmark)) + (find-file-target :initform #'helm-bookmarks-quit-an-find-file-fn))) + +(defun helm-bookmarks-quit-an-find-file-fn (source) + (let* ((sel (helm-get-selection nil nil source)) + (bmk (assoc (replace-regexp-in-string "\\`\\*" "" sel) + bookmark-alist))) + (helm-aif (bookmark-get-filename bmk) + (if (and helm--url-regexp + (string-match helm--url-regexp it)) + it (expand-file-name it)) + (expand-file-name default-directory)))) ;;; W3m bookmarks. ;; @@ -411,6 +435,18 @@ If `browse-url-browser-function' is set to something else than (helm-init-candidates-in-buffer 'global (helm-bookmark-gnus-setup-alist))))) +;;; Mu4e +;; +(defun helm-bookmark-mu4e-setup-alist () + (helm-bookmark-filter-setup-alist 'helm-bookmark-mu4e-bookmark-p)) + +(defvar helm-source-bookmark-mu4e + (helm-make-source "Bookmark Mu4e" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-mu4e-setup-alist))))) + ;;; Info ;; (defun helm-bookmark-info-setup-alist () @@ -517,6 +553,8 @@ If `browse-url-browser-function' is set to something else than (helm-bookmark-w3m-bookmark-p i)) for isgnus = (and (fboundp 'helm-bookmark-gnus-bookmark-p) (helm-bookmark-gnus-bookmark-p i)) + for ismu4e = (and (fboundp 'helm-bookmark-mu4e-bookmark-p) + (helm-bookmark-mu4e-bookmark-p i)) for isman = (and (fboundp 'helm-bookmark-man-bookmark-p) ; Man (helm-bookmark-man-bookmark-p i)) for iswoman = (and (fboundp 'helm-bookmark-woman-bookmark-p) ; Woman @@ -532,6 +570,15 @@ If `browse-url-browser-function' is set to something else than (helm-substring i bookmark-bmenu-file-column) i) + for icon = (when helm-bookmark-use-icon + (cond ((and isfile hff) + (all-the-icons-octicon "file-directory")) + ((and isfile isinfo) (all-the-icons-octicon "info")) + (isfile (all-the-icons-icon-for-file isfile)) + ((or iswoman isman) + (all-the-icons-fileicon "man-page")) + ((or isgnus ismu4e) + (all-the-icons-octicon "mail-read")))) ;; Add a * if bookmark have annotation if (and isannotation (not (string-equal isannotation ""))) do (setq trunc (concat "*" (if helm-bookmark-show-location trunc i))) @@ -594,9 +641,15 @@ If `browse-url-browser-function' is set to something else than (propertize trunc 'face 'helm-bookmark-file 'help-echo isfile))) collect (if helm-bookmark-show-location - (cons (concat bmk sep (if (listp loc) (car loc) loc)) + (cons (concat (and icon (propertize " " 'display (concat icon " "))) + bmk + (propertize + " " 'display + (concat sep (if (listp loc) (car loc) loc)))) i) - (cons bmk i))))) + (cons (concat (and icon (propertize " " 'display (concat icon " "))) + bmk) + i))))) ;;; Edit/rename/save bookmarks. @@ -729,6 +782,8 @@ E.g. prepended with *." Optional source `helm-source-bookmark-addressbook' is loaded only if external addressbook-bookmark package is installed." (interactive) + (when helm-bookmark-use-icon + (require 'all-the-icons)) (helm :sources helm-bookmark-default-filtered-sources :prompt "Search Bookmark: " :buffer "*helm filtered bookmarks*" diff --git a/elpa/helm-20210729.1510/helm-buffers.el b/elpa/helm-20220616.1004/helm-buffers.el similarity index 95% rename from elpa/helm-20210729.1510/helm-buffers.el rename to elpa/helm-20220616.1004/helm-buffers.el index ad5443a8..ce91161f 100644 --- a/elpa/helm-20210729.1510/helm-buffers.el +++ b/elpa/helm-20220616.1004/helm-buffers.el @@ -1,6 +1,6 @@ ;;; helm-buffers.el --- helm support for buffers. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -30,6 +30,7 @@ (declare-function helm-browse-project "helm-files") (defvar dired-buffers) +(defvar org-directory) (defgroup helm-buffers nil @@ -291,7 +292,7 @@ Note that this variable is buffer-local.") ;; directly so that each list of candidates is local to source. (helm-set-attr 'candidates (funcall (helm-get-attr 'buffer-list))) (let ((result (cl-loop with allbufs = (memq 'helm-shadow-boring-buffers - (helm-attr + (helm-get-attr 'filtered-candidate-transformer helm-source-buffers-list)) for b in (if allbufs @@ -319,7 +320,8 @@ Note that this variable is buffer-local.") (multimatch :initform nil) (match :initform 'helm-buffers-match-function) (persistent-action :initform 'helm-buffers-list-persistent-action) - (keymap :initform helm-buffer-map) + (keymap :initform 'helm-buffer-map) + (find-file-target :initform #'helm-buffers-quit-and-find-file-fn) (migemo :initform 'nomultimatch) (volatile :initform t) (nohighlight :initform t) @@ -429,9 +431,18 @@ The list is reordered with `helm-buffer-list-reorder-fn'." (append (list (concat prefix - (propertize buf-name 'face face1 - 'help-echo help-echo - 'type type))) + (let* ((buf-fname (buffer-file-name (get-buffer buf-name))) + (ext (if buf-fname (helm-file-name-extension buf-fname) "")) + (buf-name (propertize buf-name 'face face1 + 'help-echo help-echo + 'type type))) + (when (condition-case _err + (string-match (format "\\.\\(%s\\)" ext) buf-name) + (invalid-regexp nil)) + (add-face-text-property + (match-beginning 1) (match-end 1) + 'helm-ff-file-extension nil buf-name)) + buf-name))) (and details (list size mode (propertize @@ -448,7 +459,7 @@ The list is reordered with `helm-buffer-list-reorder-fn'." (helm-acond ((assq major-mode helm-buffer--pretty-names) (cdr it)) ((stringp mode-name) mode-name) - (t (format-mode-line mode-name))))) + (t (format-mode-line mode-name nil nil (get-buffer buf)))))) (defun helm-buffer--details (buffer &optional details) (require 'dired) @@ -949,11 +960,25 @@ If REGEXP-FLAG is given use `query-replace-regexp'." (helm-exit-and-execute-action 'helm-buffer-switch-buffers-other-window))) (put 'helm-buffer-switch-other-window 'helm-only t) +(defun helm-buffer-switch-to-buffer-other-frame (_candidate) + "Display marked buffers in other frame." + (let ((bufs (helm-marked-candidates))) + (select-frame (make-frame)) + (helm-window-show-buffers bufs))) + +(defun helm-buffers-maybe-raise-buffer-frame (candidate) + "Raise buffer frame handling buffer CANDIDATE and switch to it." + (let ((oframe (window-frame (get-buffer-window candidate 0)))) + (unless (eql oframe (selected-frame)) + (raise-frame oframe)) + (with-selected-frame oframe + (switch-to-buffer candidate)))) + (defun helm-buffer-switch-other-frame () "Run switch to other frame action from `helm-source-buffers-list'." (interactive) (with-helm-alive-p - (helm-exit-and-execute-action 'switch-to-buffer-other-frame))) + (helm-exit-and-execute-action 'helm-buffer-switch-to-buffer-other-frame))) (put 'helm-buffer-switch-other-frame 'helm-only t) (defun helm-buffers-switch-to-buffer-other-tab (_candidate) @@ -1113,7 +1138,8 @@ Can be used by any source that list buffers." (interactive) (with-helm-alive-p (let ((filter-attrs (helm-get-attr 'filtered-candidate-transformer - helm-source-buffers-list))) + helm-source-buffers-list)) + (sel (helm-get-selection))) (if (memq 'helm-shadow-boring-buffers filter-attrs) (helm-set-attr 'filtered-candidate-transformer (cons 'helm-skip-boring-buffers @@ -1125,7 +1151,7 @@ Can be used by any source that list buffers." (remove 'helm-skip-boring-buffers filter-attrs)) helm-source-buffers-list)) - (helm-force-update)))) + (helm-force-update (helm-buffers--quote-truncated-buffer sel))))) (put 'helm-buffers-toggle-show-hidden-buffers 'helm-only t) (defun helm-buffers-browse-project (buf) @@ -1140,6 +1166,21 @@ Can be used by any source that list buffers." (if helm-buffers-in-project-p (user-error "You are already browsing this project") (helm-exit-and-execute-action 'helm-buffers-browse-project)))) + +(defun helm-buffers-quit-and-find-file-fn (source) + (let* ((sel (helm-get-selection nil nil source)) + (buf (helm-aand (bufferp sel) + (get-buffer sel) + (buffer-name it)))) + (when buf + (or (buffer-file-name sel) + (car (rassoc buf dired-buffers)) + (and (with-current-buffer buf + (eq major-mode 'org-agenda-mode)) + org-directory + (expand-file-name org-directory)) + (with-current-buffer buf + (expand-file-name default-directory)))))) ;;; Candidate Transformers ;; diff --git a/elpa/helm-20210729.1510/helm-color.el b/elpa/helm-20220616.1004/helm-color.el similarity index 98% rename from elpa/helm-20210729.1510/helm-color.el rename to elpa/helm-20220616.1004/helm-color.el index 5e91e64d..639c3ec7 100644 --- a/elpa/helm-20210729.1510/helm-color.el +++ b/elpa/helm-20220616.1004/helm-color.el @@ -1,6 +1,6 @@ ;;; helm-color.el --- colors and faces -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-comint.el b/elpa/helm-20220616.1004/helm-comint.el similarity index 100% rename from elpa/helm-20210729.1510/helm-comint.el rename to elpa/helm-20220616.1004/helm-comint.el diff --git a/elpa/helm-20210729.1510/helm-command.el b/elpa/helm-20220616.1004/helm-command.el similarity index 75% rename from elpa/helm-20210729.1510/helm-command.el rename to elpa/helm-20220616.1004/helm-command.el index c500779f..ef0c0643 100644 --- a/elpa/helm-20210729.1510/helm-command.el +++ b/elpa/helm-20220616.1004/helm-command.el @@ -1,6 +1,6 @@ ;;; helm-command.el --- Helm execute-exended-command. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -42,6 +42,22 @@ "Helm-M-x fuzzy matching when non nil." :group 'helm-command :type 'boolean) + +(defvar helm-M-x-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-comp-read-map) + (define-key map (kbd "C-u") nil) + (define-key map (kbd "C-u") 'helm-M-x-universal-argument) + (define-key map (kbd "C-]") 'helm-M-x-toggle-short-doc) + map)) + +(defcustom helm-M-x-show-short-doc nil + "Show short docstring of command when non nil. +This value can be toggled with +\\\\[helm-M-x-toggle-short-doc] while in helm-M-x session." + :group 'helm-command + :type 'boolean) + ;;; Faces ;; @@ -54,7 +70,7 @@ (defface helm-M-x-key `((t ,@(and (>= emacs-major-version 27) '(:extend t)) - :foreground "orange" :underline t)) + :foreground "orange" :box (:line-width -1))) "Face used in helm-M-x to show keybinding." :group 'helm-command-faces) @@ -63,6 +79,10 @@ "Face used by `helm-M-x' for activated modes." :group 'helm-command-faces) +(defface helm-M-x-short-doc + '((t :box (:line-width -1) :foreground "DimGray")) + "Face used by `helm-M-x' for short docstring." + :group 'helm-command-faces) (defvar helm-M-x-input-history nil) (defvar helm-M-x-prefix-argument nil @@ -101,8 +121,14 @@ Return nil if no mode-map found." (when (and map-sym (boundp map-sym)) (helm-M-x-get-major-mode-command-alist (symbol-value map-sym))))) +(defun helm-M-x-toggle-short-doc () + "Toggle short doc display in helm-M-x." + (interactive) + (setq helm-M-x-show-short-doc (not helm-M-x-show-short-doc)) + (helm-update (concat "^" (helm-get-selection)) (helm-get-current-source))) +(put 'helm-M-x-toggle-short-doc 'no-helm-mx t) -(defun helm-M-x-transformer-1 (candidates &optional sort) +(defun helm-M-x-transformer-1 (candidates &optional sort ignore-props) "Transformer function to show bindings in emacs commands. Show global bindings and local bindings according to current `major-mode'. @@ -111,33 +137,48 @@ Note that SORT should not be used when fuzzy matching because fuzzy matching is running its own sort function with a different algorithm." (with-helm-current-buffer - (cl-loop with local-map = (helm-M-x-current-mode-map-alist) - for cand in candidates - for local-key = (car (rassq cand local-map)) - for key = (substitute-command-keys (format "\\[%s]" cand)) - for sym = (intern (if (consp cand) (car cand) cand)) - for disp = (if (or (eq sym major-mode) - (and (memq sym minor-mode-list) - (boundp sym) - (buffer-local-value sym helm-current-buffer))) - (propertize cand 'face 'helm-command-active-mode) - cand) - unless (or (get sym 'helm-only) (get sym 'no-helm-mx)) - collect - (cons (cond ((and (string-match "^M-x" key) local-key) - (format "%s %s" - disp (propertize + (cl-loop with max-len = (when helm-M-x-show-short-doc + (buffer-local-value 'helm-candidate-buffer-longest-len + (get-buffer (helm-candidate-buffer)))) + with local-map = (helm-M-x-current-mode-map-alist) + for cand in candidates + for local-key = (car (rassq cand local-map)) + for key = (substitute-command-keys (format "\\[%s]" cand)) + for sym = (intern (if (consp cand) (car cand) cand)) + for doc = (when max-len + (helm-get-first-line-documentation (intern-soft cand))) + for disp = (if (or (eq sym major-mode) + (and (memq sym minor-mode-list) + (boundp sym) + (buffer-local-value sym helm-current-buffer))) + (propertize cand 'face 'helm-command-active-mode) + cand) + unless (and (null ignore-props) (or (get sym 'helm-only) (get sym 'no-helm-mx))) + collect + (cons (cond ((and (string-match "^M-x" key) local-key) + (format "%s%s%s %s" + disp + (if doc (make-string (+ 4 (- max-len (length cand))) ? ) "") + (if doc (propertize doc 'face 'helm-M-x-short-doc) "") + (propertize + " " 'display + (propertize local-key 'face 'helm-M-x-key)))) + ((string-match "^M-x" key) + (format "%s%s%s" + disp + (if doc (make-string (+ 4 (- max-len (length cand))) ? ) "") + (if doc (propertize doc 'face 'helm-M-x-short-doc) ""))) + (t (format "%s%s%s %s" + disp + (if doc (make-string (+ 4 (- max-len (length cand))) ? ) "") + (if doc (propertize doc 'face 'helm-M-x-short-doc) "") + (propertize " " 'display - (propertize local-key 'face 'helm-M-x-key)))) - ((string-match "^M-x" key) disp) - (t (format "%s %s" - disp (propertize - " " 'display - (propertize key 'face 'helm-M-x-key))))) - cand) - into ls - finally return - (if sort (sort ls #'helm-generic-sort-fn) ls)))) + (propertize key 'face 'helm-M-x-key))))) + cand) + into ls + finally return + (if sort (sort ls #'helm-generic-sort-fn) ls)))) (defun helm-M-x-transformer (candidates _source) "Transformer function for `helm-M-x' candidates." @@ -148,6 +189,10 @@ algorithm." "Transformer function for `helm-M-x' candidates." (helm-M-x-transformer-1 candidates)) +(defun helm-M-x-transformer-no-sort-no-props (candidates _source) + "Transformer function for `helm-M-x' candidates." + (helm-M-x-transformer-1 candidates nil t)) + (defun helm-M-x--notify-prefix-arg () ;; Notify a prefix-arg set AFTER calling M-x. (when prefix-arg @@ -171,13 +216,6 @@ algorithm." (push (substring (helm-cmd--get-current-function-name) 1) results)))) results)) -(defvar helm-M-x-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map helm-comp-read-map) - (define-key map (kbd "C-u") nil) - (define-key map (kbd "C-u") 'helm-M-x-universal-argument) - map)) - (defun helm-M-x-universal-argument () "Same as `universal-argument' but for `helm-M-x'." (interactive) @@ -211,7 +249,19 @@ algorithm." (persistent-help :initform "Describe this command") (help-message :initform 'helm-M-x-help-message) (nomark :initform t) - (keymap :initform helm-M-x-map))) + (cleanup :initform #'helm-M-x--unwind-forms) + (keymap :initform 'helm-M-x-map) + (resume :initform 'helm-M-x-resume-fn))) + +(defun helm-M-x-resume-fn () + (when (and helm-M-x--timer (timerp helm-M-x--timer)) + (cancel-timer helm-M-x--timer) + (setq helm-M-x--timer nil)) + (setq helm-M-x--timer (run-at-time 1 0.1 'helm-M-x--notify-prefix-arg)) + (setq helm--mode-line-display-prefarg t) + ;; Prevent displaying a wrong prefix arg when helm-resume is called + ;; from prefix arg. + (setq current-prefix-arg nil)) (defun helm-M-x-read-extended-command (collection &optional predicate history) "Read or execute action on command name in COLLECTION or HISTORY. @@ -227,8 +277,8 @@ Arg COLLECTION should be an `obarray' but can be any object suitable for `try-completion'. Arg PREDICATE is a function that default to `commandp' see also `try-completion'. Arg HISTORY default to `extended-command-history'." - (let* ((helm--mode-line-display-prefarg t) - (pred (or predicate #'commandp)) + (setq helm--mode-line-display-prefarg t) + (let* ((pred (or predicate #'commandp)) (helm-fuzzy-sort-fn (lambda (candidates _source) ;; Sort on real candidate otherwise ;; "symbol ()" is used when sorting. @@ -292,7 +342,8 @@ default to `extended-command-history'." (when (timerp helm-M-x--timer) (cancel-timer helm-M-x--timer) (setq helm-M-x--timer nil)) - (setq helm--mode-line-display-prefarg nil) + (setq helm--mode-line-display-prefarg nil + helm-fuzzy-sort-fn (default-toplevel-value 'helm-fuzzy-sort-fn)) ;; Be sure to remove it here as well in case of quit. (remove-hook 'helm-move-selection-after-hook 'helm-M-x--move-selection-after-hook) diff --git a/elpa/helm-20210729.1510/helm-config.el b/elpa/helm-20220616.1004/helm-config.el similarity index 77% rename from elpa/helm-20210729.1510/helm-config.el rename to elpa/helm-20220616.1004/helm-config.el index d9343b6b..9a83a30b 100644 --- a/elpa/helm-20210729.1510/helm-config.el +++ b/elpa/helm-20220616.1004/helm-config.el @@ -1,6 +1,6 @@ ;;; helm-config.el --- Applications library for `helm.el' -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -18,14 +18,12 @@ ;;; Commentary: ;; ;; Requiring this file is not needed when using a package manager to -;; install helm as this one will take care of loading the autoload -;; file. +;; install helm as this one will take care of creating and loading the +;; autoload file. ;;; Code: -;;; Load the autoload file -;; It should have been generated either by -;; the package manager or the make file. +;;; Load the autoload file generated by the make file. (load "helm-autoloads" nil t) diff --git a/elpa/helm-20210729.1510/helm-dabbrev.el b/elpa/helm-20220616.1004/helm-dabbrev.el similarity index 98% rename from elpa/helm-20210729.1510/helm-dabbrev.el rename to elpa/helm-20220616.1004/helm-dabbrev.el index 4cd36c89..f214c50f 100644 --- a/elpa/helm-20210729.1510/helm-dabbrev.el +++ b/elpa/helm-20220616.1004/helm-dabbrev.el @@ -1,6 +1,6 @@ ;;; helm-dabbrev.el --- Helm implementation of dabbrev. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -72,12 +72,12 @@ When nil all buffers are considered related to `current-buffer'." This allow helm-dabbrev searching in buffers with the associated `major-mode'. -E.g. \(emacs-lisp-mode . lisp-interaction-mode\) +E.g. (emacs-lisp-mode . lisp-interaction-mode) will allow searching in the lisp-interaction-mode buffer when `current-buffer' is an `emacs-lisp-mode' buffer and vice versa -i.e. no need to provide \(lisp-interaction-mode . -emacs-lisp-mode\) association. +i.e. no need to provide (lisp-interaction-mode . +emacs-lisp-mode) association. When nil check is the searched buffer has same `major-mode' than the `current-buffer'. @@ -106,7 +106,7 @@ initial search for all candidates in buffer(s)." :group 'helm-dabbrev :type '(choice (const :tag "Ignore case" t) (const :tag "Respect case" nil) - (other :tag "Smart" 'smart))) + (other :tag "Smart" smart))) (defvaralias 'helm-dabbrev--regexp 'helm-dabbrev-separator-regexp) (make-obsolete-variable 'helm-dabbrev--regexp diff --git a/elpa/helm-20210729.1510/helm-easymenu.el b/elpa/helm-20220616.1004/helm-easymenu.el similarity index 97% rename from elpa/helm-20210729.1510/helm-easymenu.el rename to elpa/helm-20220616.1004/helm-easymenu.el index c30bc05c..690c1c1d 100644 --- a/elpa/helm-20210729.1510/helm-easymenu.el +++ b/elpa/helm-20220616.1004/helm-easymenu.el @@ -1,6 +1,6 @@ ;;; helm-easymenu.el --- Helm easymenu definitions. -*- lexical-binding: t -*- -;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-elisp-package.el b/elpa/helm-20220616.1004/helm-elisp-package.el similarity index 97% rename from elpa/helm-20210729.1510/helm-elisp-package.el rename to elpa/helm-20220616.1004/helm-elisp-package.el index c1237461..258253a7 100644 --- a/elpa/helm-20210729.1510/helm-elisp-package.el +++ b/elpa/helm-20220616.1004/helm-elisp-package.el @@ -1,6 +1,6 @@ ;;; helm-elisp-package.el --- helm interface for package.el -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -385,13 +385,21 @@ See `package-autoremove'." (filtered-candidate-transformer :initform 'helm-el-package--transformer) (action-transformer :initform 'helm-el-package--action-transformer) (help-message :initform 'helm-el-package-help-message) - (keymap :initform helm-el-package-map) + (keymap :initform 'helm-el-package-map) (update :initform 'helm-el-package--update) (candidate-number-limit :initform 9999) (action :initform '(("Describe package" . helm-el-package-describe) ("Visit homepage" . helm-el-package-visit-homepage))) + (find-file-target :initform #'helm-el-package-quit-an-find-file-fn) (group :initform 'helm-el-package))) +(defun helm-el-package-quit-an-find-file-fn (source) + (let* ((sel (helm-get-selection nil nil source)) + (pkg (and (stringp sel) + (get-text-property 0 'tabulated-list-id sel)))) + (when (and pkg (package-installed-p pkg)) + (expand-file-name (package-desc-dir pkg))))) + (defun helm-el-package--action-transformer (actions candidate) (let* ((pkg-desc (get-text-property 0 'tabulated-list-id candidate)) (status (package-desc-status pkg-desc)) diff --git a/elpa/helm-20210729.1510/helm-elisp.el b/elpa/helm-20220616.1004/helm-elisp.el similarity index 84% rename from elpa/helm-20210729.1510/helm-elisp.el rename to elpa/helm-20220616.1004/helm-elisp.el index 7bcf5f77..03a0d77e 100644 --- a/elpa/helm-20210729.1510/helm-elisp.el +++ b/elpa/helm-20220616.1004/helm-elisp.el @@ -1,6 +1,6 @@ ;;; helm-elisp.el --- Elisp symbols completion for helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -31,7 +31,8 @@ (declare-function helm-describe-face "helm-lib") (declare-function helm-read-file-name "helm-mode") (declare-function helm-comp-read "helm-mode") - +(declare-function helm-M-x-transformer-no-sort-no-props "helm-command") +(defvar helm-M-x-show-short-doc) ;;; Customizable values @@ -55,14 +56,14 @@ This is used in macro `with-helm-show-completion'." callf callf2 cl-callf cl-callf2 fset fboundp fmakunbound symbol-function) "List of function where quoted function completion happen. -E.g. give only function names after \(funcall '." +E.g. give only function names after (funcall \\='." :group 'helm-elisp :type '(repeat (choice symbol))) (defcustom helm-lisp-unquoted-function-list '(function defadvice) "List of function where unquoted function completion happen. -E.g. give only function names after \(function ." +E.g. give only function names after (function ." :group 'helm-elisp :type '(repeat (choice symbol))) @@ -273,7 +274,7 @@ of symbol before point." (defun helm-bounds-of-thing-before-point (&optional regexp) "Get the beginning and end position of `helm-thing-before-point'. -Return a cons \(beg . end\)." +Return a cons (beg . end)." (helm-thing-before-point 'limits regexp)) (defun helm-insert-completion-at-point (beg end str) @@ -360,16 +361,16 @@ other window according to the value of (defun helm-elisp--show-help-1 (candidate &optional name) (let ((sym (intern-soft candidate))) - (cl-typecase sym - ((and fboundp boundp) + (pcase sym + ((and (pred fboundp) (pred boundp)) (if (member name `(,helm-describe-function-function ,helm-describe-variable-function)) (funcall (intern (format "helm-%s" name)) sym) ;; When there is no way to know what to describe ;; prefer describe-function. (helm-describe-function sym))) - (fbound (helm-describe-function sym)) - (bound (helm-describe-variable sym)) - (face (helm-describe-face sym))))) + ((pred fboundp) (helm-describe-function sym)) + ((pred boundp) (helm-describe-variable sym)) + ((pred facep) (helm-describe-face sym))))) (defun helm-elisp-show-help (candidate &optional name) "Show full help for the function CANDIDATE. @@ -394,35 +395,44 @@ the same time to variable and a function." "Helm candidates transformer for Lisp completion." (cl-loop for c in candidates for sym = (intern c) - for annot = (cl-typecase sym - (command " (Com)") - (class " (Class)") - (cl-generic " (Gen)") - (fbound " (Fun)") - (bound " (Var)") - (face " (Face)")) + for annot = (pcase sym + ((pred commandp) " (Com)") + ((pred class-p) " (Class)") + ((pred cl-generic-p) " (Gen)") + ((pred fboundp) " (Fun)") + ((pred boundp) " (Var)") + ((pred facep) " (Face)")) for spaces = (make-string (- helm-lgst-len (length c)) ? ) collect (cons (concat c spaces annot) c) into lst finally return (sort lst #'helm-generic-sort-fn))) -(defun helm-get-first-line-documentation (sym &optional name) - "Return first line documentation of symbol SYM. -If SYM is not documented, return \"Not documented\"." - (let ((doc (cl-typecase sym - ((and fboundp boundp) - (cond ((string= name "describe-function") - (documentation sym t)) - ((string= name "describe-variable") - (documentation-property sym 'variable-documentation t)) - (t (documentation sym t)))) - (fbound (documentation sym t)) - (bound (documentation-property sym 'variable-documentation t)) - (face (face-documentation sym))))) +(cl-defun helm-get-first-line-documentation (sym &optional + (name "describe-function") + (end-column 72)) + "Return first line documentation of symbol SYM truncated at END-COLUMN. +If SYM is not documented, return \"Not documented\". +Argument NAME allows specifiying what function to use to display +documentation when SYM name is the same for function and variable." + (let ((doc (pcase sym + ((and (pred fboundp) (pred boundp)) + (pcase name + ("describe-function" + (documentation sym t)) + ("describe-variable" + (documentation-property sym 'variable-documentation t)) + (_ (documentation sym t)))) + ((pred fboundp) (documentation sym t)) + ((pred boundp) (documentation-property + sym 'variable-documentation t)) + ((pred facep) (face-documentation sym))))) (if (and doc (not (string= doc "")) ;; `documentation' return "\n\n(args...)" ;; for CL-style functions. (not (string-match-p "^\n\n" doc))) - (car (split-string doc "\n")) + ;; Some commands specify key bindings in their first line. + (truncate-string-to-width + (substitute-command-keys (car (split-string doc "\n"))) + end-column nil nil t) "Not documented"))) ;;; File completion. @@ -434,7 +444,7 @@ If SYM is not documented, return \"Not documented\"." "Preconfigured Helm to complete file name at point." (interactive) (require 'helm-mode) - (let* ((tap (thing-at-point 'filename)) + (let* ((tap (or (thing-at-point 'filename) "")) beg (init (and tap (or force @@ -487,33 +497,46 @@ double quote." ;; (defvar helm-apropos-history nil) -(defun helm-apropos-init (test default) - "Init candidates buffer for `helm-apropos' sources." +(defcustom helm-apropos-show-short-doc nil + "Show short docstring of symbols when non nil. + +NOTE: When displaying helm-apropos in a frame, i.e. when +`helm-apropos' is member of `helm-commands-using-frame' setting this +to non nil have no effect, you have first to remove `helm-apropos' +from `helm-commands-using-frame'." + :group 'helm-elisp + :type 'boolean) + +(defun helm-apropos-init (test default &optional fn) + "Setup `helm-candidate-buffer' for `helm-apropos' sources. +A list of symbols fetched with FN is inserted in +`helm-candidate-buffer', if FN is not provided symbols are fetched +against obarray with predicate TEST. When FN is provided predicate TEST +is only used to test DEFAULT." (require 'helm-help) (helm-init-candidates-in-buffer 'global (let ((default-symbol (and (stringp default) (intern-soft default))) - (symbols (all-completions "" obarray test))) + (symbols (if fn (funcall fn) (all-completions "" obarray test)))) (if (and default-symbol (funcall test default-symbol)) (cons default-symbol symbols) symbols)))) -(defun helm-apropos-init-faces (default) - "Init candidates buffer for faces for `helm-apropos'." - (require 'helm-help) - (with-current-buffer (helm-candidate-buffer 'global) - (goto-char (point-min)) - (let ((default-symbol (and (stringp default) - (intern-soft default))) - (faces (face-list))) - (when (and default-symbol (facep default-symbol)) - (insert (concat default "\n"))) - (insert - (mapconcat #'prin1-to-string - (if default - (cl-remove-if (lambda (sym) (string= sym default)) faces) - faces) - "\n"))))) +(defun helm-apropos-short-doc-transformer (candidates _source) + (cl-loop with max-len = (buffer-local-value 'helm-candidate-buffer-longest-len + (get-buffer (helm-candidate-buffer))) + for cand in candidates + for doc = (helm-get-first-line-documentation (intern-soft cand)) + collect (cons (format "%s%s%s" + cand + (if doc + (make-string (+ 4 (if (zerop max-len) + max-len + (- max-len (string-width cand)))) + ? ) + "") + (if doc (propertize doc 'face 'helm-M-x-short-doc) "")) + cand))) (defun helm-apropos-default-sort-fn (candidates _source) (if (string= helm-pattern "") @@ -583,8 +606,12 @@ double quote." (helm-apropos-init (lambda (x) (and (boundp x) (not (keywordp x)))) default)) :fuzzy-match helm-apropos-fuzzy-match - :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) - 'helm-apropos-default-sort-fn) + :filtered-candidate-transformer + (delq nil (list (and (null helm-apropos-fuzzy-match) + 'helm-apropos-default-sort-fn) + (and (null (memq 'helm-apropos helm-commands-using-frame)) + helm-apropos-show-short-doc + #'helm-apropos-short-doc-transformer))) :nomark t :persistent-action (lambda (candidate) (helm-elisp--persistent-help @@ -600,15 +627,18 @@ double quote." "Create `helm' source for faces to be displayed with `helm-apropos'." (helm-build-in-buffer-source "Faces" - :init (lambda () (helm-apropos-init-faces default)) + :init (lambda () (helm-apropos-init 'facep default #'face-list)) :fuzzy-match helm-apropos-fuzzy-match :filtered-candidate-transformer - (append (and (null helm-apropos-fuzzy-match) - '(helm-apropos-default-sort-fn)) - (list - (lambda (candidates _source) - (cl-loop for c in candidates - collect (propertize c 'face (intern c)))))) + (delq nil (list + (and (null helm-apropos-fuzzy-match) + #'helm-apropos-default-sort-fn) + (lambda (candidates _source) + (cl-loop for c in candidates + collect (propertize c 'face (intern c)))) + (and (null (memq 'helm-apropos helm-commands-using-frame)) + helm-apropos-show-short-doc + #'helm-apropos-short-doc-transformer))) :persistent-action (lambda (candidate) (helm-elisp--persistent-help candidate 'helm-describe-face)) @@ -619,12 +649,15 @@ double quote." (customize-face (helm-symbolify candidate))))))) (defun helm-def-source--emacs-commands (&optional default) + (require 'helm-command) (helm-build-in-buffer-source "Commands" :init (lambda () (helm-apropos-init 'commandp default)) :fuzzy-match helm-apropos-fuzzy-match - :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) - 'helm-apropos-default-sort-fn) + :filtered-candidate-transformer + (append (list #'helm-M-x-transformer-no-sort-no-props) + (and (null helm-apropos-fuzzy-match) + '(helm-apropos-default-sort-fn))) :display-to-real 'helm-symbolify :nomark t :persistent-action (lambda (candidate) @@ -643,8 +676,12 @@ double quote." (not (class-p x)))) default)) :fuzzy-match helm-apropos-fuzzy-match - :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) - 'helm-apropos-default-sort-fn) + :filtered-candidate-transformer + (delq nil (list (and (null helm-apropos-fuzzy-match) + 'helm-apropos-default-sort-fn) + (and (null (memq 'helm-apropos helm-commands-using-frame)) + helm-apropos-show-short-doc + #'helm-apropos-short-doc-transformer))) :display-to-real 'helm-symbolify :persistent-action (lambda (candidate) (helm-elisp--persistent-help @@ -660,8 +697,12 @@ double quote." (class-p x)) default)) :fuzzy-match helm-apropos-fuzzy-match - :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) - 'helm-apropos-default-sort-fn) + :filtered-candidate-transformer + (delq nil (list (and (null helm-apropos-fuzzy-match) + 'helm-apropos-default-sort-fn) + (and (null (memq 'helm-apropos helm-commands-using-frame)) + helm-apropos-show-short-doc + #'helm-apropos-short-doc-transformer))) :nomark t :persistent-action (lambda (candidate) (helm-elisp--persistent-help @@ -678,8 +719,12 @@ double quote." (cl-generic-p x)) default)) :fuzzy-match helm-apropos-fuzzy-match - :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) - 'helm-apropos-default-sort-fn) + :filtered-candidate-transformer + (delq nil (list (and (null helm-apropos-fuzzy-match) + 'helm-apropos-default-sort-fn) + (and (null (memq 'helm-apropos helm-commands-using-frame)) + helm-apropos-show-short-doc + #'helm-apropos-short-doc-transformer))) :nomark t :persistent-action (lambda (candidate) (helm-elisp--persistent-help @@ -735,14 +780,18 @@ double quote." "Preconfigured Helm to describe commands, functions, variables and faces. In non interactives calls DEFAULT argument should be provided as a string, i.e. the `symbol-name' of any existing symbol." - (interactive (list (thing-at-point 'symbol))) + (interactive (list (with-syntax-table emacs-lisp-mode-syntax-table + (thing-at-point 'symbol)))) + (let ((helm-M-x-show-short-doc + (and helm-apropos-show-short-doc + (null (memq 'helm-apropos helm-commands-using-frame))))) (helm :sources (mapcar (lambda (func) (funcall func default)) helm-apropos-function-list) :history 'helm-apropos-history :buffer "*helm apropos*" - :preselect (and default (concat "\\_<" (regexp-quote default) "\\_>")))) + :preselect (and default (concat "\\_<" (regexp-quote default) "\\_>"))))) ;;; Advices @@ -869,7 +918,7 @@ a string, i.e. the `symbol-name' of any existing symbol." ;; ;; (defclass helm-absolute-time-timers-class (helm-source-sync helm-type-timers) - ((candidates :initform timer-list) + ((candidates :initform 'timer-list) (allow-dups :initform t) (candidate-transformer :initform @@ -881,7 +930,7 @@ a string, i.e. the `symbol-name' of any existing symbol." (helm-make-source "Absolute Time Timers" 'helm-absolute-time-timers-class)) (defclass helm-idle-time-timers-class (helm-source-sync helm-type-timers) - ((candidates :initform timer-idle-list) + ((candidates :initform 'timer-idle-list) (allow-dups :initform t) (candidate-transformer :initform @@ -896,7 +945,9 @@ a string, i.e. the `symbol-name' of any existing symbol." (format "%s repeat=%s %s(%s)" (let ((time (timer--time timer))) (if (timer--idle-delay timer) - (format-time-string "idle-for=%5s" time) + (format "idle-for=[%s]" + (format-seconds "%dd %hh %mmin %z%,3ss" + (time-convert time t))) (format-time-string "%m/%d %T" time))) (or (timer--repeat-delay timer) "nil") (mapconcat 'identity (split-string diff --git a/elpa/helm-20210729.1510/helm-epa.el b/elpa/helm-20220616.1004/helm-epa.el similarity index 98% rename from elpa/helm-20210729.1510/helm-epa.el rename to elpa/helm-20220616.1004/helm-epa.el index 69ec62dd..073b188a 100644 --- a/elpa/helm-20210729.1510/helm-epa.el +++ b/elpa/helm-20220616.1004/helm-epa.el @@ -1,6 +1,6 @@ ;;; helm-epa.el --- helm interface for epa/epg -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -57,8 +57,8 @@ (require 'epg) (require 'epa))) (candidates :initform 'helm-epa-get-key-list) - (keymap :initform helm-comp-read-map) - (mode-line :initform helm-comp-read-mode-line)) + (keymap :initform 'helm-comp-read-map) + (mode-line :initform 'helm-comp-read-mode-line)) "Allow building helm sources for GPG keys.") (defun helm-epa-get-key-list (&optional keys) diff --git a/elpa/helm-20210729.1510/helm-eshell.el b/elpa/helm-20220616.1004/helm-eshell.el similarity index 99% rename from elpa/helm-20210729.1510/helm-eshell.el rename to elpa/helm-20220616.1004/helm-eshell.el index 359f5f50..1b666796 100644 --- a/elpa/helm-20210729.1510/helm-eshell.el +++ b/elpa/helm-20220616.1004/helm-eshell.el @@ -1,6 +1,6 @@ ;;; helm-eshell.el --- pcomplete and eshell completion for helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -214,7 +214,7 @@ at point." finally return lst)))) (nomark :initform t) (multiline :initform t) - (keymap :initform helm-eshell-history-map) + (keymap :initform 'helm-eshell-history-map) (candidate-number-limit :initform 9999) (action :initform (lambda (candidate) (eshell-kill-input) diff --git a/elpa/helm-20210729.1510/helm-eval.el b/elpa/helm-20220616.1004/helm-eval.el similarity index 99% rename from elpa/helm-20210729.1510/helm-eval.el rename to elpa/helm-20220616.1004/helm-eval.el index 8b07d65f..9d261438 100644 --- a/elpa/helm-20210729.1510/helm-eval.el +++ b/elpa/helm-20220616.1004/helm-eval.el @@ -1,6 +1,6 @@ ;;; helm-eval.el --- eval expressions from helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-external.el b/elpa/helm-20220616.1004/helm-external.el similarity index 55% rename from elpa/helm-20210729.1510/helm-external.el rename to elpa/helm-20220616.1004/helm-external.el index 7dad6f41..b7808361 100644 --- a/elpa/helm-20210729.1510/helm-external.el +++ b/elpa/helm-20220616.1004/helm-external.el @@ -1,6 +1,6 @@ ;;; helm-external.el --- Run Externals commands within Emacs with helm completion. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -39,7 +39,7 @@ This will be use with `format', so use something like \"wmctrl -xa %s\"." (defcustom helm-external-programs-associations nil "Alist to store externals programs associated with file extension. This variable overhide setting in .mailcap file. -E.g.: '\(\(\"jpg\" . \"gqview\"\) (\"pdf\" . \"xpdf\"\)\) " +E.g.: \\='((\"jpg\" . \"gqview\") (\"pdf\" . \"xpdf\")) " :type '(alist :key-type string :value-type string) :group 'helm-external) @@ -82,40 +82,66 @@ contents. Else it calculates all external commands and sets finally return (if sort (sort completions 'string-lessp) completions))))) -(defun helm-run-or-raise (exe &optional file) +(defun helm-run-or-raise (exe &optional files detached) "Run asynchronously EXE or jump to the application window. If EXE is already running just jump to his window if `helm-raise-command' is non-nil. -When FILE argument is provided run EXE with FILE." - (let* ((real-com (car (split-string exe))) - (proc (if file (concat real-com " " file) real-com)) - process-connection-type) - (if (get-process proc) - (if helm-raise-command - (shell-command (format helm-raise-command real-com)) - (error "Error: %s is already running" real-com)) - (when (member real-com helm-external-commands-list) - (message "Starting %s..." real-com) - (if file - (start-process-shell-command - proc nil (format "%s %s" - real-com - (shell-quote-argument - (if (eq system-type 'windows-nt) - (helm-w32-prepare-filename file) - (expand-file-name file))))) - (start-process-shell-command proc nil real-com)) +When FILES argument is provided run EXE with FILES. +When argument DETACHED is non nil, detach process from Emacs." + (let* ((proc-name (replace-regexp-in-string + "(" "" (car (split-string exe)))) + (fmt-file (lambda (file) + (shell-quote-argument + (if (eq system-type 'windows-nt) + (helm-w32-prepare-filename file) + (expand-file-name file))))) + (file-arg (and files (mapconcat fmt-file files " "))) + process-connection-type proc) + (when (and files detached (not (string-match "%s &)\\'" exe))) + (setq exe (format "(%s &)" exe))) + (when (member proc-name helm-external-commands-list) + ;; Allow adding more files to the current process if it is + ;; already running (i.e. Don't just raise it without sending + ;; files) we assume program doesn't start a new + ;; process (like firefox, transmission etc...). + (if files + (cond ((string-match "%s &)\\'" exe) + (message "Starting and detaching `%s' from Emacs" proc-name) + (call-process-shell-command (format exe file-arg))) + (t + (message "Starting %s..." proc-name) + (setq proc + (start-process-shell-command + proc-name nil (if (string-match "%s" exe) + (format exe file-arg) + (format "%s %s" exe file-arg)))))) + ;; Just jump to the already running program instance or start + ;; a new process. + (if (get-process proc-name) + (if helm-raise-command + (run-at-time 0.1 nil #'shell-command + (format helm-raise-command proc-name)) + (error "Error: %s is already running" proc-name)) + (if (and detached (not (memq system-type '(windows-nt ms-dos)))) + (progn + (message "Starting and detaching `%s' from Emacs" proc-name) + (call-process-shell-command (format "(%s &)" exe))) + (when detached + (user-error "Detaching programs not supported on `%s'" system-type)) + (setq proc (start-process-shell-command proc-name nil exe))))) + (when proc (set-process-sentinel - (get-process proc) + proc (lambda (process event) - (when (and (string= event "finished\n") - helm-raise-command - (not (helm-get-pid-from-process-name real-com))) - (shell-command (format helm-raise-command "emacs"))) - (message "%s process...Finished." process)))) + (when (and (string= event "finished\n") + helm-raise-command + (not (helm-get-pid-from-process-name proc-name))) + (shell-command (format helm-raise-command "emacs"))) + (message "%s process...Finished." process)))) + ;; Move command on top list. (setq helm-external-commands-list - (cons real-com - (delete real-com helm-external-commands-list)))))) + (cons proc-name + (delete proc-name helm-external-commands-list)))))) (defun helm-get-mailcap-for-file (filename) "Get the command to use for FILENAME from mailcap files." @@ -138,13 +164,14 @@ mailcap file. If nothing found return nil." helm-default-external-file-browser) (t (helm-get-mailcap-for-file filename))))) -(defun helm-open-file-externally (file) +(defun helm-open-file-externally (_file) "Open FILE with an external program. Try to guess which program to use with `helm-get-default-program-for-file'. If not found or a prefix arg is given query the user which tool to use." - (let* ((fname (expand-file-name file)) + (let* ((files (helm-marked-candidates :with-wildcard t)) + (fname (expand-file-name (car files))) (collection (helm-external-commands-list-1 'sort)) (def-prog (helm-get-default-program-for-file fname)) (program (if (or helm-current-prefix-arg (not def-prog)) @@ -154,12 +181,11 @@ to use." "Program: " collection :must-match t :name "Open file Externally" - :del-input nil - :history helm-external-command-history) + :history 'helm-external-command-history) ;; Always prompt to set this program as default. (setq def-prog nil)) - ;; No prefix arg or default program exists. - def-prog))) + ;; No prefix arg or default program exists. + def-prog))) (unless (or def-prog ; Association exists, no need to record it. ;; Don't try to record non--filenames associations (e.g urls). (not (file-exists-p fname))) @@ -178,32 +204,53 @@ to use." helm-external-programs-associations) (customize-save-variable 'helm-external-programs-associations helm-external-programs-associations))) - (helm-run-or-raise program file) + (helm-run-or-raise program files) (setq helm-external-command-history - (cons program - (delete program - (cl-loop for i in helm-external-command-history - when (executable-find i) collect i)))))) + (cl-loop for i in helm-external-command-history + when (executable-find i) collect i)))) + +(defun helm-run-external-command-action (candidate &optional detached) + (helm-run-or-raise candidate nil detached) + (setq helm-external-command-history + (cons candidate + (delete candidate + helm-external-command-history)))) + +(defclass helm-external-commands (helm-source-in-buffer) + ((filtered-candidate-transformer + :initform (lambda (candidates _source) + (cl-loop for c in candidates + if (get-process c) + collect (propertize c 'face 'font-lock-type-face) + else collect c))) + (must-match :initform t) + (nomark :initform t) + (action :initform + (helm-make-actions + "Run program" 'helm-run-external-command-action + (lambda () + (unless (memq system-type '(windows-nt ms-dos)) + "Run program detached")) + (lambda (candidate) + (helm-run-external-command-action candidate 'detached)))))) ;;;###autoload -(defun helm-run-external-command (program) +(defun helm-run-external-command () "Preconfigured `helm' to run External PROGRAM asyncronously from Emacs. -If program is already running exit with error. -You can set your own list of commands with -`helm-external-commands-list'." - (interactive (list - (helm-comp-read - "RunProgram: " - (helm-external-commands-list-1 'sort) - :must-match t - :del-input nil - :name "External Commands" - :history helm-external-command-history))) - (helm-run-or-raise program) +If program is already running try to run `helm-raise-command' if +defined otherwise exit with error. You can set your own list of +commands with `helm-external-commands-list'." + (interactive) + (helm :sources `(,(helm-make-source "External Commands history" 'helm-external-commands + :data helm-external-command-history) + ,(helm-make-source "External Commands" 'helm-external-commands + :data (helm-external-commands-list-1 'sort))) + :buffer "*helm externals commands*" + :prompt "RunProgram: ") + ;; Remove from history no more valid executables. (setq helm-external-command-history - (cons program (delete program - (cl-loop for i in helm-external-command-history - when (executable-find i) collect i))))) + (cl-loop for i in helm-external-command-history + when (executable-find i) collect i))) (provide 'helm-external) diff --git a/elpa/helm-20210729.1510/helm-fd.el b/elpa/helm-20220616.1004/helm-fd.el similarity index 96% rename from elpa/helm-20210729.1510/helm-fd.el rename to elpa/helm-20220616.1004/helm-fd.el index 3d620efd..69d1116a 100644 --- a/elpa/helm-20210729.1510/helm-fd.el +++ b/elpa/helm-20220616.1004/helm-fd.el @@ -1,6 +1,6 @@ ;;; helm-fd.el --- helm interface for fd command line tool. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -20,6 +20,8 @@ (require 'helm) (require 'helm-types) +(declare-function ansi-color-apply "ansi-color.el") + (defvar helm-fd-executable "fd" "The fd shell command executable.") @@ -71,7 +73,7 @@ (help-message :initform 'helm-fd-help-message) (filtered-candidate-transformer :initform 'helm-fd-fct) (action :initform 'helm-type-file-actions) - (keymap :initform helm-fd-map))) + (keymap :initform 'helm-fd-map))) (defun helm-fd-process () "Initialize fd process in an helm async source." @@ -107,7 +109,7 @@ (defun helm-fd-fct (candidates _source) "The filtered-candidate-transformer function for helm-fd." (cl-loop for i in candidates - collect (helm--ansi-color-apply i))) + collect (ansi-color-apply i))) (defun helm-fd-1 (directory) "Run fd shell command on DIRECTORY with helm interface." diff --git a/elpa/helm-20210729.1510/helm-files.el b/elpa/helm-20220616.1004/helm-files.el similarity index 81% rename from elpa/helm-20210729.1510/helm-files.el rename to elpa/helm-20220616.1004/helm-files.el index 44cba9b2..d61ccce5 100644 --- a/elpa/helm-20210729.1510/helm-files.el +++ b/elpa/helm-20220616.1004/helm-files.el @@ -1,6 +1,6 @@ ;;; helm-files.el --- helm file browser and related. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -31,15 +31,14 @@ (require 'thingatpt) (require 'ffap) (require 'dired-aux) - (require 'dired-x) - (require 'image-dired)) + (require 'dired-x)) (require 'filenotify) +(require 'image-mode) +(require 'image-dired) (declare-function find-library-name "find-func.el" (library)) (declare-function w32-shell-execute "ext:w32fns.c" (operation document &optional parameters show-flag)) (declare-function gnus-dired-attach "ext:gnus-dired.el" (files-to-attach)) -(declare-function image-dired-display-image "image-dired.el" (file &optional original-size)) -(declare-function image-dired-update-property "image-dired.el" (prop value)) (declare-function eshell-read-aliases-list "em-alias") (declare-function eshell-send-input "esh-mode" (&optional use-region queue-p no-newline)) (declare-function eshell-kill-input "esh-mode") @@ -48,7 +47,7 @@ (declare-function eshell/cd "em-dirs.el") (declare-function eshell-next-prompt "em-prompt.el") (declare-function eshell-resume-eval "esh-cmd") -(declare-function helm-ls-git-ls "ext:helm-ls-git") +(declare-function helm-ls-git "ext:helm-ls-git") (declare-function helm-hg-find-files-in-project "ext:helm-ls-hg") (declare-function helm-gid "helm-id-utils.el") (declare-function helm-find-1 "helm-find") @@ -85,7 +84,12 @@ (declare-function tramp-make-tramp-file-name "tramp") (declare-function tramp-cleanup-connection "tramp-cmds") (declare-function dired-async-processes "ext:dired-async.el") +(declare-function all-the-icons-icon-for-file "ext:all-the-icons.el") +(declare-function all-the-icons-octicon "ext:all-the-icons.el") +(declare-function all-the-icons-match-to-alist "ext:all-the-icons.el") +(declare-function helm-adaptive-sort "ext:helm-adaptive.el") +(defvar all-the-icons-dir-icon-alist) (defvar term-char-mode-point-at-process-mark) (defvar term-char-mode-buffer-read-only) (defvar recentf-list) @@ -96,7 +100,7 @@ (defvar eshell-debug-command) (defvar eshell-current-command) (defvar tramp-archive-enabled) - +(defvar password-cache) (defgroup helm-files nil "Files applications and libraries for Helm." @@ -146,7 +150,7 @@ This set `ffap-newfile-prompt'." :group 'helm-files) (defcustom helm-ff-avfs-directory "~/.avfs" - "The default avfs directory, usually '~/.avfs'. + "The default avfs directory, usually \\='~/.avfs'. When this is set you will be able to expand archive filenames with `C-j' inside an avfs directory mounted with mountavfs. See ." @@ -258,7 +262,7 @@ very large directories." :group 'helm-files :type 'hook) -(defcustom helm-find-files-bookmark-prefix "Helm-find-files: " +(defcustom helm-find-files-bookmark-prefix nil "bookmark name prefix of `helm-find-files' sessions." :group 'helm-files :type 'string) @@ -361,7 +365,7 @@ else." :type '(repeat symbol)) (defcustom helm-ff-allow-recursive-deletes nil - "When 'always don't prompt for recursive deletion of directories. + "When \\='always don't prompt for recursive deletion of directories. When nil, will ask for recursive deletion. Note that when deleting multiple directories you can answer ! when prompted to avoid being asked for next directories, so it @@ -394,17 +398,17 @@ It is the function that will be used when using "Allow trashing remote files when non-nil. Trashing remote files with tramp doesn't work out of the box -unless the 'trash-cli' package is installed. This is why trashing +unless the \\='trash-cli' package is installed. This is why trashing remote files from Helm is disabled by default. -Tramp is using external 'trash' command in its `delete-file' and +Tramp is using external \\='trash' command in its `delete-file' and `delete-directory' handlers when using `delete-by-moving-to-trash', which is documented nowhere in Emacs. -If you want to enable this you will have to install the 'trash' +If you want to enable this you will have to install the \\='trash' command on remote (and/or locally if you want to trash as root). -On Ubuntu-based distributions it is 'trash-cli'." +On Ubuntu-based distributions it is \\='trash-cli'." :group 'helm-files :type 'boolean) @@ -437,13 +441,19 @@ slower and less featured (only directories colorized)." (defcustom helm-ff-initial-sort-method nil "Sort method to use when initially listing a directory. -Note that this doesn't affect the listing when matching inside -the directory (i.e. filenames)." + +It is better to keep this nil globally and turn it on only when needed +otherwise it may be slightly slower specially with `ext' method which +BTW is not provided on remote files (helm will fallback on nil in such +case). +Note that this have no effect as soon as you start narrowing directory +i.e. filtering filenames inside directory." :group 'helm-files :type '(choice (const :tag "alphabetically" nil) (const :tag "newest" newest) - (const :tag "size" size))) + (const :tag "size" size) + (const :tag "extensions" ext))) (defcustom helm-ff-rotate-image-program "exiftran" "External program used to rotate images. @@ -575,6 +585,12 @@ It is generally \"~/.local/share/Trash\"." "Face used for file names in `helm-find-files'." :group 'helm-files-faces) +(defface helm-ff-nofile + `((t ,@(and (>= emacs-major-version 27) '(:extend t)) + :inherit helm-ff-file)) + "Face used for file names in `helm-find-files'." + :group 'helm-files-faces) + (defface helm-ff-truename `((t ,@(and (>= emacs-major-version 27) '(:extend t)) :inherit font-lock-string-face)) @@ -677,6 +693,7 @@ It is generally \"~/.local/share/Trash\"." (define-key map (kbd "C-c C-x") 'helm-ff-run-open-file-externally) (define-key map (kbd "C-c C-v") 'helm-ff-run-preview-file-externally) (define-key map (kbd "C-c X") 'helm-ff-run-open-file-with-default-tool) + (define-key map (kbd "C-c t") 'helm-ff-toggle-thumbnails) (define-key map (kbd "M-!") 'helm-ff-run-eshell-command-on-file) (define-key map (kbd "M-@") 'helm-ff-run-query-replace-fnames-on-marked) (define-key map (kbd "M-%") 'helm-ff-run-query-replace) @@ -700,6 +717,7 @@ It is generally \"~/.local/share/Trash\"." (define-key map (kbd "M-+") 'helm-ff-increase-image-size-persistent) (define-key map (kbd "M--") 'helm-ff-decrease-image-size-persistent) (define-key map (kbd "C-l") 'helm-find-files-up-one-level) + (define-key map (kbd "C-:") 'helm-ff-complete-tramp-methods) (define-key map (kbd "C-_") 'helm-ff-undo) (define-key map (kbd "C-r") 'helm-find-files-down-last-level) (define-key map (kbd "C-c r") 'helm-ff-run-find-file-as-root) @@ -710,6 +728,7 @@ It is generally \"~/.local/share/Trash\"." (define-key map (kbd "S-") 'helm-ff-sort-by-size) (define-key map (kbd "S-") 'helm-ff-toggle-dirs-only) (define-key map (kbd "S-") 'helm-ff-toggle-files-only) + (define-key map (kbd "S-") 'helm-ff-sort-by-ext) (helm-define-key-with-subkeys map (kbd "DEL") ?\d 'helm-ff-delete-char-backward '((C-backspace . helm-ff-run-toggle-auto-update) ([C-c DEL] . helm-ff-run-toggle-auto-update)) @@ -727,6 +746,7 @@ It is generally \"~/.local/share/Trash\"." (define-key map (kbd "C-]") 'helm-ff-run-toggle-basename) (define-key map (kbd "C-.") 'helm-find-files-up-one-level) (define-key map (kbd "C-l") 'helm-find-files-up-one-level) + (define-key map (kbd "C-:") 'helm-ff-complete-tramp-methods) (define-key map (kbd "C-_") 'helm-ff-undo) (define-key map (kbd "C-r") 'helm-find-files-down-last-level) (define-key map (kbd "C-c h") 'helm-ff-file-name-history) @@ -769,7 +789,7 @@ When nil always delete char backward." :group 'helm-files :type 'boolean) -(defcustom helm-ff-display-image-native nil +(defcustom helm-ff-display-image-native t "Use native `image-mode' when non nil. You should use this only with Emacs>= 27 and `image-auto-resize' @@ -777,8 +797,9 @@ enabled to have images resized properly. When this is enabled, you have new commands to zoom in/out images. See `image-transform-resize' and `image-auto-resize'. Otherwise, when nil `image-dired' is used, using imagemagick as backend. -NOTE: If you see image-mode is eating too much memory, you better have -to set this to nil (default)." +NOTE: On Emacs-29 `image-dired' is no more using external program +image-magick to display image, so this is used inconditionally even +when value is nil." :group 'helm-files :type 'boolean) @@ -788,6 +809,17 @@ When filtering directories/files only, switch back to a \"show all\" view when moving out of directory when non nil." :type 'boolean :group 'helm-files) + +(defcustom helm-ff-eshell-unwanted-aliases nil + "A list of eshell aliases to not display." + :type '(repeat string) + :group 'helm-files) + +(defvar helm-ff-last-expanded-candidate-regexp "^[[:multibyte:] ]*%s$" + "Regexp that retrieve previous candidate when going up one level. +The default value matching a multibyte char at bol allows prefixing +candidate with an icon. The format part will be replaced by the +display part of the candidate regexp quoted.") ;; Internal. (defvar helm-find-files-doc-header " (\\\\[helm-find-files-up-one-level]: Go up one level)" @@ -799,7 +831,6 @@ Don't set it directly, use instead `helm-ff-auto-update-initial-value'.") "Store last expanded directory or file.") (defvar helm-ff-default-directory nil) (defvar helm-ff-history nil) -(defvar helm-ff-cand-to-mark nil) (defvar helm-ff-url-regexp "\\`\\(news\\(post\\)?:\\|nntp:\\|mailto:\\|file:\\|\\(ftp\\|https?\\|telnet\\|gopher\\|www\\|wais\\):/?/?\\).*" "Same as `ffap-url-regexp' but match earlier possible url.") @@ -808,6 +839,7 @@ Don't set it directly, use instead `helm-ff-auto-update-initial-value'.") ;; seems it is wrong and a simpler regexp is enough, let's try it and ;; watch out! (defvar helm-tramp-file-name-regexp "\\`/\\([^/:|]+\\):") +(defvar helm-ff-tramp-method-regexp "[/|]:\\([^:]*\\)") (defvar helm-marked-buffer-name "*helm marked*") (defvar helm-ff--auto-update-state nil) (defvar helm-ff--deleting-char-backward nil) @@ -835,6 +867,8 @@ than `helm-candidate-number-limit'.") (defvar helm-ff--trashed-files nil "[INTERNAL] Files already trashed are stored here during file deletion. This is used only as a let binding.") +(defvar helm-ff--show-thumbnails nil) +(defvar helm-ff--thumbnailed-directories nil) ;;; Helm-find-files ;; @@ -859,6 +893,7 @@ This is used only as a let binding.") "Insert as org link `C-c @'" 'helm-files-insert-as-org-link "Find shell command `C-c /'" 'helm-ff-find-sh-command "Fd shell command (C-/)" 'helm-ff-fd + "Find files in file" 'helm-find-files-in-file "Add marked files to file-cache" 'helm-ff-cache-add-file "Open file externally `C-c C-x, C-u to choose'" 'helm-open-file-externally "Grep File(s) `C-s, C-u Recurse'" 'helm-find-files-grep @@ -927,6 +962,7 @@ Should not be used among other sources.") (match-on-real :initform t) (filtered-candidate-transformer :initform '(helm-ff-fct + helm-ff-maybe-show-thumbnails ;; These next two have to be called after ;; `helm-ff-fct' as they use only cons cell candidates. helm-ff-directories-only @@ -940,7 +976,7 @@ Should not be used among other sources.") (cleanup :initform 'helm-find-files-cleanup) (migemo :initform t) (nohighlight :initform t) - (keymap :initform helm-find-files-map) + (keymap :initform 'helm-find-files-map) (candidate-number-limit :initform 'helm-ff-candidate-number-limit) (action-transformer :initform 'helm-find-files-action-transformer) @@ -967,9 +1003,11 @@ Should not be used among other sources.") ;; tramp starts and display candidates. FNAME is here always a ;; directory. (when (file-directory-p fname) - (helm-find-files-1 fname (if helm-ff-transformer-show-only-basename - (concat "^" (regexp-quote (helm-basename presel))) - (regexp-quote presel)))))) + (helm-find-files-1 fname + (format helm-ff-last-expanded-candidate-regexp + (if helm-ff-transformer-show-only-basename + (regexp-quote (helm-basename presel)) + (regexp-quote presel))))))) (defun helm-ff-bookmark-set () "Record `helm-find-files' session in bookmarks." @@ -1003,7 +1041,11 @@ directories belonging to each visible windows." (defun helm-dwim-target-directory () "Try to return a suitable directory according to `helm-dwim-target'." - (with-selected-window (get-buffer-window helm-current-buffer) + (with-selected-window (or + ;; Try next-window if current-buffer has been + ;; killed during this session probably by C-d. + (get-buffer-window helm-current-buffer) + (next-window (helm-window) 1)) (let ((wins (remove (get-buffer-window helm-marked-buffer-name) (window-list)))) (expand-file-name @@ -1035,10 +1077,15 @@ directories belonging to each visible windows." ;; current. (or (car-safe helm-ff-history) default-directory))))))) +(defsubst helm-ff--file-directory-p (file) + (if (file-remote-p file) + (get-text-property 1 'helm-ff-dir file) + (file-directory-p file))) + (defun helm-ff--count-and-collect-dups (files) (cl-loop with dups = (make-hash-table :test 'equal) for f in files - for file = (if (file-directory-p f) + for file = (if (helm-ff--file-directory-p f) (concat (helm-basename f) "/") (helm-basename f)) for count = (gethash file dups) @@ -1068,7 +1115,7 @@ ACTION can be `rsync' or any action supported by `helm-dired-action'." 'helm-rsync-command-history))))) (ifiles (mapcar 'expand-file-name ; Allow modify '/foo/.' -> '/foo' (helm-marked-candidates :with-wildcard t))) - (cand (helm-get-selection)) ; Target + (cand (unless (cdr ifiles) (helm-get-selection))) ; preselection. (prefarg helm-current-prefix-arg) (prompt (format "%s %s file(s) %s: " (if (and (and (fboundp 'dired-async-mode) @@ -1096,12 +1143,11 @@ ACTION can be `rsync' or any action supported by `helm-dired-action'." (with-helm-current-buffer (helm-read-file-name prompt - :preselect (unless (cdr ifiles) - (concat - "^" - (regexp-quote - (if helm-ff-transformer-show-only-basename - (helm-basename cand) cand)))) + :preselect (when cand + (format helm-ff-last-expanded-candidate-regexp + (regexp-quote + (if helm-ff-transformer-show-only-basename + (helm-basename cand) cand)))) :initial-input (helm-dwim-target-directory) :history (helm-find-files-history nil :comp-read nil)))))) (dest-dir-p (file-directory-p dest)) @@ -1413,9 +1459,12 @@ windows layout." helm-ff-default-directory (file-name-directory candidate)))) (helm-etags-select helm-current-prefix-arg))) - + +;;; Eshell command on file +;; (defvar eshell-command-aliases-list nil) (defvar helm-eshell-command-on-file-input-history nil) +(defvar helm-eshell-command-on-file-history nil) (cl-defun helm-find-files-eshell-command-on-file-1 (&optional map) "Run `eshell-command' on CANDIDATE or marked candidates. This is done possibly with an Eshell alias. If no alias found, @@ -1448,8 +1497,11 @@ Note: You have to setup some aliases in Eshell with the `alias' command or by editing yourself the file `eshell-aliases-file' to make this working." + (require 'helm-adaptive) (require 'em-alias) (eshell-read-aliases-list) - (advice-add 'eshell-eval-command :override #'helm--advice-eshell-eval-command) + (unless (> emacs-major-version 27) + ;; This advice have been merged in emacs-28. + (advice-add 'eshell-eval-command :override #'helm--advice-eshell-eval-command)) (when (or eshell-command-aliases-list (y-or-n-p "No eshell aliases found, run eshell-command without alias anyway? ")) (let* ((cand-list (helm-marked-candidates :with-wildcard t)) @@ -1460,27 +1512,43 @@ this working." helm-display-source-at-screen-top (helm-actions-inherit-frame-settings t) helm-use-frame-when-more-than-two-windows - (command (with-helm-display-marked-candidates - helm-marked-buffer-name - (helm-ff--count-and-collect-dups - (mapcar 'helm-basename cand-list)) - (with-helm-current-buffer - (helm-comp-read - "Command: " - (cl-loop for (a c) in (eshell-read-aliases-list) - ;; Positional arguments may be double - ;; quoted (Bug#1881). - when (string-match "[\"]?.*\\(\\$1\\|\\$\\*\\)[\"]?\\s-*&?\\'" c) - collect (propertize a 'help-echo c) into ls - finally return (sort ls 'string<)) - :buffer "*helm eshell on file*" - :name "Eshell command" - :mode-line - '("Eshell alias" - "C-h m: Help, \\[universal-argument]: Insert output at point") - :help-message 'helm-esh-help-message - :input-history - 'helm-eshell-command-on-file-input-history)))) + (command + (with-helm-display-marked-candidates + helm-marked-buffer-name + (helm-ff--count-and-collect-dups + (mapcar 'helm-basename cand-list)) + (with-helm-current-buffer + (helm-comp-read + "Command: " + (cl-loop with len = 0 + with aliases = + (cl-loop for (a c) in (eshell-read-aliases-list) + for len-key = (length a) + when + (and (string-match + "\\(\\$1\\|\\$\\*\\)" + c) + (not (member a helm-ff-eshell-unwanted-aliases))) + do (when (> len-key len) (setq len len-key)) + and collect (list a c)) + for (a c) in aliases + collect (cons + (concat (propertize + a 'face 'font-lock-keyword-face) + (make-string (1+ (- len (length a))) ? ) + c) + a)) + :fc-transformer #'helm-adaptive-sort + :buffer "*helm eshell on file*" + :name "Eshell command" + :mode-line + '("Eshell alias" + "C-h m: Help, \\[universal-argument]: Insert output at point") + :help-message 'helm-esh-help-message + :history 'helm-eshell-command-on-file-history + :raw-history t + :input-history + 'helm-eshell-command-on-file-input-history)))) (alias-value (car (assoc-default command eshell-command-aliases-list))) cmd-line) (if (or (equal helm-current-prefix-arg '(16)) @@ -1502,50 +1570,62 @@ this working." (and alias-value ;; If command is an alias be sure it accept ;; more than one arg i.e $*. - (string-match "\\$\\*$" alias-value))) - (cdr cand-list)) - - ;; Run eshell-command with ALL marked files as arguments. - ;; This wont work on remote files, because tramp handlers depends + (string-match "\\$\\*" alias-value))) + (cdr cand-list) + (and alias-value + ;; Command is an alias and accept only one arg. + (not (string-match "\\$1" alias-value)))) + + ;; Run eshell-command with ALL marked files as argument. + ;; This wont work on remote files, because tramp handlers depend ;; on `default-directory' (limitation). (let ((mapfiles (mapconcat 'shell-quote-argument cand-list " "))) (if (string-match "%s" command) (setq cmd-line (format command mapfiles)) ; See [1] (setq cmd-line (format "%s %s" command mapfiles))) (eshell-command cmd-line)) + + ;; Run eshell-command sequencially on EACH marked files. + ;; To work with tramp handler we have to call + ;; COMMAND on basename of each file, using + ;; its basedir as `default-directory'. (unwind-protect (progn - ;; Run eshell-command on EACH marked files. - ;; To work with tramp handler we have to call - ;; COMMAND on basename of each file, using - ;; its basedir as `default-directory'. (cl-loop for f in cand-list for n from 1 for dir = (and (not (string-match helm--url-regexp f)) (helm-basedir f)) ;; We can use basename here as the command will run ;; under default-directory. - ;; This allow running e.g. "tar czvf test.tar.gz - ;; %s/*" without creating an archive expanding from /home. - for file = (shell-quote-argument (helm-basename f)) + ;; This allows running e.g. + ;; "tar czvf test.tar.gz %s/*" without creating + ;; an archive expanding from /home. + for file = (shell-quote-argument + (if (string-match helm--url-regexp f) + f (helm-basename f))) ;; \@ => placeholder for file without extension. ;; \# => placeholder for incremental number. - for fcmd = (replace-regexp-in-string - "\\\\@" (regexp-quote (file-name-sans-extension file)) - (replace-regexp-in-string - "\\\\#" (format "%03d" n) command t t) - t t) + for fcmd = (helm-aand command + (replace-regexp-in-string + "\\\\#" (format "%03d" n) + it t t) + (replace-regexp-in-string + "\\\\@" + (regexp-quote + (file-name-sans-extension file)) + it t t)) for com = (if (string-match "%s" fcmd) - ;; [1] This allow to enter other args AFTER filename + ;; [1] This allows to enter other args AFTER filename ;; i.e (format fcmd file) (format "%s %s" fcmd file)) do (let ((default-directory (or dir default-directory))) (eshell-command com)))) - ;; Async process continue running but don't need anymore + ;; Async process continues running but doesn't need anymore ;; the advice at this point (see the `eshell-eval-command' - ;; call in `eshell-command'.) . - (advice-remove 'eshell-eval-command #'helm--advice-eshell-eval-command)))))) + ;; call in `eshell-command'). + (unless (> emacs-major-version 27) + (advice-remove 'eshell-eval-command #'helm--advice-eshell-eval-command))))))) (defun helm--advice-eshell-eval-command (command &optional input) "Fix return value when command ends with \"&\"." @@ -1554,6 +1634,10 @@ this working." ;; always match specifier) whereas it should return either a ;; single element (CAR DELIM) or DELIM itself if the car of ;; DELIM is a process. + ;; This prevent running eshell-command async when needed i.e. when + ;; command ends with "&". + ;; + ;; UPDATE: This have now been merged in Emacs-28. ;; ;; 6b6f91b357f6fe2f1e0d72f046a1b8d8a2d6d8c3 ;; Author: John Wiegley @@ -1577,7 +1661,7 @@ this working." (setq eshell-current-command command) (let* ((delim (catch 'eshell-incomplete (eshell-resume-eval))) - (val (car delim))) + (val (car-safe delim))) ;; If the return value of `eshell-resume-eval' is wrapped in a ;; list, it indicates that the command was run asynchronously. ;; In that case, unwrap the value before checking the delimiter @@ -1738,26 +1822,42 @@ prefix arg shell buffer doesn't exists, create it and switch to it." (defun helm-ff-sort-by-size () (interactive) - (unless (eq helm-ff-initial-sort-method 'size) - (setq helm-ff-initial-sort-method 'size) - (helm-force-update (helm-get-selection nil helm-ff-transformer-show-only-basename))) - (message "Sorting by size")) + (let ((helm-ff-initial-sort-method 'size)) + (helm-force-update + (concat (regexp-quote (helm-get-selection + nil helm-ff-transformer-show-only-basename)) + "$")) + (message "Sorting by size"))) (put 'helm-ff-sort-by-size 'helm-only t) (defun helm-ff-sort-by-newest () (interactive) - (unless (eq helm-ff-initial-sort-method 'newest) - (setq helm-ff-initial-sort-method 'newest) - (helm-force-update (helm-get-selection nil helm-ff-transformer-show-only-basename))) - (message "Sorting by newest")) + (let ((helm-ff-initial-sort-method 'newest)) + (helm-force-update + (concat (regexp-quote (helm-get-selection + nil helm-ff-transformer-show-only-basename)) + "$")) + (message "Sorting by newest"))) (put 'helm-ff-sort-by-newest 'helm-only t) +(defun helm-ff-sort-by-ext () + (interactive) + (let ((helm-ff-initial-sort-method 'ext)) + (helm-force-update + (concat (regexp-quote (helm-get-selection + nil helm-ff-transformer-show-only-basename)) + "$")) + (message "Sorting by extensions"))) +(put 'helm-ff-sort-by-ext 'no-helm-mx t) + (defun helm-ff-sort-alpha () (interactive) - (unless (eq helm-ff-initial-sort-method nil) - (setq helm-ff-initial-sort-method nil) - (helm-force-update (helm-get-selection nil helm-ff-transformer-show-only-basename))) - (message "Sorting alphabetically")) + (let ((helm-ff-initial-sort-method nil)) + (helm-force-update + (concat (regexp-quote (helm-get-selection + nil helm-ff-transformer-show-only-basename)) + "$")) + (message "Sorting alphabetically"))) (put 'helm-ff-sort-alpha 'helm-only t) (defun helm-ff-directories-only (candidates _source) @@ -1927,94 +2027,12 @@ This doesn't replace inside the files, only modify filenames." nil 'helm-ff-query-replace-history-from (helm-basename (car candidates)))) (rep (read-string (format "Replace regexp `%s' with: " regexp) - nil 'helm-ff-query-replace-history-to)) - subexp) + nil 'helm-ff-query-replace-history-to))) (cl-loop with query = "y" with count = 0 - with target = nil for old in candidates - for new = (concat (helm-basedir old) - (helm--replace-regexp-in-buffer-string - (save-match-data - (cond ((string= regexp "%.") - (setq subexp 1) - (helm-ff--prepare-str-with-regexp - (setq target (helm-basename old t)))) - ((string= regexp ".%") - (setq subexp 1) - (helm-ff--prepare-str-with-regexp - (setq target (file-name-extension old)))) - ((string= regexp "%") - (regexp-quote - (setq target (helm-basename old)))) - ((string-match "%:\\([0-9]+\\):\\([0-9]+\\)" regexp) - (setq subexp 1) - (let ((beg (match-string 1 regexp)) - (end (match-string 2 regexp)) - (str (helm-basename old))) - (setq target (substring str - (string-to-number beg) - (string-to-number end))) - (helm-ff--prepare-str-with-regexp str beg end))) - (t regexp))) - (save-match-data - (cond (;; Handle incremental - ;; replacement with \# in - ;; search and replace - ;; feature in placeholder \@. - (string-match - "\\\\@/\\(.*\\)/\\(\\(?99:.*\\)\\\\#\\)/" - rep) - (replace-regexp-in-string - (match-string 1 rep) - (concat (match-string 99 rep) - (format "%03d" (1+ count))) - target)) - ;; Incremental replacement - ;; before or after \@. - ((and (string-match-p "\\\\#" rep) - (string-match "\\\\@" rep)) - (replace-regexp-in-string - "\\\\#" (format "%03d" (1+ count)) - (replace-match target t t rep))) - ;; Simple incremental replacement. - ((string-match "\\\\#" rep) - (replace-match - (format "%03d" (1+ count)) t t rep)) - ;; Substring replacement in placeholder. - ((string-match - "\\\\@:\\([0-9]*\\):\\([0-9]*\\)" rep) - (replace-match (substring - target - (string-to-number - (match-string 1 rep)) - (pcase (match-string 2 rep) - ((pred (string= "")) - (length target)) - (res (string-to-number res)))) - t t rep)) - ;; Search and replace in - ;; placeholder. Doesn't - ;; handle incremental here. - ((string-match "\\\\@/\\(.*\\)/\\(.*\\)/" rep) - (replace-match (replace-regexp-in-string - (match-string 1 rep) - (match-string 2 rep) - target t) - t t rep)) - ;; Simple replacement by placeholder. - ((string-match "\\\\@" rep) - (replace-match target t t rep)) - ;; Replacement with - ;; upcase, downcase or - ;; capitalized text. - ((string= rep "%u") #'upcase) - ((string= rep "%d") #'downcase) - ((string= rep "%c") #'capitalize) - ;; Simple replacement with - ;; whole replacement regexp. - (t rep))) - (helm-basename old) t nil subexp)) + for new = (helm-ff--query-replace-in-fname-set-new-name + old regexp rep count) ;; If `regexp' is not matched in `old' ;; `replace-regexp-in-string' will ;; return `old' unmodified. @@ -2042,6 +2060,93 @@ This doesn't replace inside the files, only modify filenames." (with-current-buffer (window-buffer (minibuffer-window)) (delete-minibuffer-contents))) +(defun helm-ff--query-replace-in-fname-set-new-name (old regexp rep count) + "Setup a new name for OLD replacing part matching REGEXP with REP. +COUNT is used for incrementing new name if needed." + (let (subexp target) + (concat (helm-basedir old) + (helm--replace-regexp-in-buffer-string + (save-match-data + (cond ((string= regexp "%.") + (setq subexp 1) + (helm-ff--prepare-str-with-regexp + (setq target (helm-basename old t)))) + ((string= regexp ".%") + (setq subexp 1) + (helm-ff--prepare-str-with-regexp + (setq target (file-name-extension old)))) + ((string= regexp "%") + (regexp-quote + (setq target (helm-basename old)))) + ((string-match "%:\\([0-9]+\\):\\([0-9]+\\)" regexp) + (setq subexp 1) + (let ((beg (match-string 1 regexp)) + (end (match-string 2 regexp)) + (str (helm-basename old))) + (setq target (substring str + (string-to-number beg) + (string-to-number end))) + (helm-ff--prepare-str-with-regexp str beg end))) + (t regexp))) + (save-match-data + (cond (;; Handle incremental + ;; replacement with \# in + ;; search and replace + ;; feature in placeholder \@. + (string-match + "\\\\@/\\(.*\\)/\\(\\(?99:.*\\)\\\\#\\)/" + rep) + (replace-regexp-in-string + (match-string 1 rep) + (concat (match-string 99 rep) + (format "%03d" (1+ count))) + target)) + ;; Incremental replacement + ;; before or after \@. + ((and (string-match-p "\\\\#" rep) + (string-match "\\\\@" rep)) + (replace-regexp-in-string + "\\\\#" (format "%03d" (1+ count)) + (replace-match target t t rep))) + ;; Simple incremental replacement. + ((string-match "\\\\#" rep) + (replace-match + (format "%03d" (1+ count)) t t rep)) + ;; Substring replacement in placeholder. + ((string-match + "\\\\@:\\([0-9]*\\):\\([0-9]*\\)" rep) + (replace-match (substring + target + (string-to-number + (match-string 1 rep)) + (pcase (match-string 2 rep) + ((pred (string= "")) + (length target)) + (res (string-to-number res)))) + t t rep)) + ;; Search and replace in + ;; placeholder. Doesn't + ;; handle incremental here. + ((string-match "\\\\@/\\(.*\\)/\\(.*\\)/" rep) + (replace-match (replace-regexp-in-string + (match-string 1 rep) + (match-string 2 rep) + target t) + t t rep)) + ;; Simple replacement by placeholder. + ((string-match "\\\\@" rep) + (replace-match target t t rep)) + ;; Replacement with + ;; upcase, downcase or + ;; capitalized text. + ((string= rep "%u") #'upcase) + ((string= rep "%d") #'downcase) + ((string= rep "%c") #'capitalize) + ;; Simple replacement with + ;; whole replacement regexp. + (t rep))) + (helm-basename old) t nil subexp)))) + (defun helm-ff--prepare-str-with-regexp (str &optional rep1 rep2) ;; This is used in `helm-ff-query-replace-on-filenames' to prepare ;; STR when REGEXP is specified as substring e.g %:1:3 in this case @@ -2462,7 +2567,7 @@ Same as `dired-do-print' but for Helm." (lpr-switches (if (and (stringp printer-name) (string< "" printer-name)) - (cons (concat lpr-printer-switch printer-name) + (cons (concat lpr-printer-switch " " printer-name) lpr-switches) lpr-switches)) (command (helm-read-string @@ -2478,8 +2583,7 @@ Same as `dired-do-print' but for Helm." (list lpr-switches) lpr-switches)) " ")))) - (file-args (mapconcat (lambda (x) - (format "'%s'" x)) + (file-args (mapconcat #'shell-quote-argument file-list " ")) (cmd-line (concat command " " file-args))) (if command @@ -2622,6 +2726,8 @@ If prefix numeric arg is given go ARG level up." helm-find-files--level-tree))) (setq helm-find-files--level-tree-iterator nil) (push new-pattern helm-find-files--level-tree) + (setq helm-ff--show-thumbnails + (member new-pattern helm-ff--thumbnailed-directories)) (helm-set-pattern new-pattern helm-suspend-update-flag) (with-helm-after-update-hook (helm-ff-retrieve-last-expanded))))))) (put 'helm-find-files-up-one-level 'helm-only t) @@ -2637,7 +2743,10 @@ If prefix numeric arg is given go ARG level up." (helm-iter-list (cdr helm-find-files--level-tree)))) (setq helm-find-files--level-tree nil) (helm-aif (helm-iter-next helm-find-files--level-tree-iterator) - (helm-set-pattern it) + (progn + (setq helm-ff--show-thumbnails + (member it helm-ff--thumbnailed-directories)) + (helm-set-pattern it)) (setq helm-find-files--level-tree-iterator nil))))) (put 'helm-find-files-down-last-level 'helm-only t) @@ -2659,7 +2768,10 @@ hitting C-j on \"..\"." (directory-file-name helm-ff-last-expanded)) (directory-file-name helm-ff-last-expanded)))) (with-helm-window - (when (re-search-forward (concat "^" (regexp-quote presel) "$") nil t) + (when (re-search-forward + (format helm-ff-last-expanded-candidate-regexp + (regexp-quote presel)) + nil t) (forward-line 0) (helm-mark-current-line))) (setq helm-ff-last-expanded nil)))) @@ -2683,6 +2795,7 @@ hitting C-j on \"..\"." (unless (or (not (stringp it)) (and (string-match helm-tramp-file-name-regexp it) (not (file-remote-p it nil t))) + (string-match helm-ff-tramp-method-regexp it) (file-exists-p it)) (helm-next-line))))) @@ -2699,7 +2812,7 @@ Ensure disabling `helm-ff-auto-update-flag' before undoing." (helm-check-minibuffer-input)) (setq helm-ff-auto-update-flag old--flag) (setq helm-ff--auto-update-state helm-ff-auto-update-flag)))) - + ;;; Auto-update - helm-find-files auto expansion of directories. ;; ;; @@ -2737,7 +2850,8 @@ when `helm-pattern' is equal to \"~/\"." ;; `helm-ff-move-to-first-real-candidate' ;; instead of `helm-next-line' (Bug#910). (helm-ff-move-to-first-real-candidate)) - (helm-get-selection nil nil src)))) + (helm-get-selection nil nil src))) + expand-to) (when (and (or (and helm-ff-auto-update-flag (null helm-ff--deleting-char-backward) ;; Bug#295 @@ -2773,19 +2887,24 @@ when `helm-pattern' is equal to \"~/\"." ;; and only one candidate is remaining [2], ;; assume candidate is a new directory to expand, and do it. (progn - (helm-set-pattern (file-name-as-directory - (substring-no-properties cur-cand))) - ;; Reset flags to show all when changing dir. - (helm-ff-after-persistent-show-all)) + (setq expand-to (file-name-as-directory + (substring-no-properties cur-cand))) + (setq helm-ff--show-thumbnails + (member expand-to helm-ff--thumbnailed-directories)) + (helm-set-pattern expand-to) + ;; Reset flags to show all when changing dir. + (helm-ff-after-persistent-show-all)) ;; The candidate is one of "." or ".." ;; that mean we have entered the last letter of the directory name ;; in prompt, so expansion is already done, just add the "/" at end ;; of name unless helm-pattern ends with "." ;; (i.e we are writing something starting with ".") (unless (string-match "\\`.*[.]\\{1\\}\\'" helm-pattern) - (helm-set-pattern - ;; Need to expand-file-name to avoid e.g /ssh:host:./ in prompt. - (expand-file-name (file-name-as-directory helm-pattern))))) + ;; Need to expand-file-name to avoid e.g /ssh:host:./ in prompt. + (setq expand-to (expand-file-name (file-name-as-directory helm-pattern))) + (setq helm-ff--show-thumbnails + (member expand-to helm-ff--thumbnailed-directories)) + (helm-set-pattern expand-to))) ;; When typing pattern in minibuffer, helm ;; expand very fast to a directory matching pattern and ;; don't let undo the time to set a boundary, the result @@ -2999,29 +3118,22 @@ Return nil on valid file name remote or not." Argument PATTERN default to `helm-pattern'. It is here only for debugging purpose." (when (string-match helm-tramp-file-name-regexp pattern) - (let* ((mh-method (helm-ff--previous-mh-tramp-method pattern)) - (method (or (cadr mh-method) (match-string 1 pattern))) - (current-mh-host (helm-aif (and mh-method - (helm-ff--get-host-from-tramp-invalid-fname pattern)) - (concat (car mh-method) method ":" - (car (split-string it "|" t))))) - (all-methods (helm-ff--get-tramp-methods)) - (comps (cl-loop for (f . h) in (tramp-get-completion-function method) - append (cl-loop for e in (funcall f (car h)) - for host = (and (consp e) (cadr e)) - ;; On emacs-27 host may be - ;; ("root" t) in sudo method. - when (and (stringp host) - (not (member host all-methods))) - collect (helm-ff-filter-candidate-one-by-one - (concat (or (car mh-method) "/") - method ":" host)))))) - (helm-fast-remove-dups - (append (and current-mh-host - (list (helm-ff-filter-candidate-one-by-one - current-mh-host))) - comps) - :test 'equal)))) + (let* ((mh-method (helm-ff--previous-mh-tramp-method pattern)) + (method (or (cadr mh-method) (match-string 1 pattern)))) + (cl-loop with all-methods = (helm-ff--get-tramp-methods) + for (f . h) in (tramp-get-completion-function method) + append (cl-loop for e in (funcall f (car h)) + for host = (and (consp e) (cadr e)) + ;; On emacs-27 host may be + ;; ("root" t) in sudo method. + when (and (stringp host) + (not (member host all-methods))) + collect (helm-ff-filter-candidate-one-by-one + (concat (or (car mh-method) "/") + method ":" host))) + into comps + finally return + (helm-fast-remove-dups comps :test 'equal))))) (defun helm-ff-before-action-hook-fn () "Exit Helm when user try to execute action on an invalid tramp fname." @@ -3036,10 +3148,22 @@ debugging purpose." (cl-defun helm-ff--invalid-tramp-name-p (&optional (pattern helm-pattern)) "Return non-nil when PATTERN is an invalid tramp filename." - (string= (helm-ff-set-pattern pattern) - "@@TRAMP@@")) + (or (string= (helm-ff-set-pattern pattern) + "@@TRAMP@@") + ;; Tramp methods completion. + (string-match helm-ff-tramp-method-regexp pattern))) (defun helm-ff--tramp-postfixed-p (str) + "Return non nil when tramp path STR is complete." + ;; E.g.: + ;; (helm-ff--tramp-postfixed-p "/ssh:foo") + ;; => nil + ;; (helm-ff--tramp-postfixed-p "/ssh:foo:") + ;; => 10 + ;; (helm-ff--tramp-postfixed-p "/ssh:foo|sudo:") + ;; => nil + ;; (helm-ff--tramp-postfixed-p "/ssh:foo|sudo::") + ;; => 16 (let ((methods (helm-ff--get-tramp-methods)) result) (save-match-data @@ -3048,13 +3172,48 @@ debugging purpose." (helm-awhile (search-forward ":" nil t) (if (save-excursion (forward-char -1) - (looking-back - (mapconcat (lambda (m) (format "[/|]%s" m)) methods "\\|") - (point-at-bol))) + (or (looking-back "[/|]" (1- (point))) + (looking-back + (mapconcat (lambda (m) (format "[/|]%s" m)) methods "\\|") + (point-at-bol)))) (setq result nil) (setq result it))))) result)) +(defun helm-ff--tramp-multihops-p (name) + (cl-loop for m in (helm-ff--get-tramp-methods) + thereis (string-match (format "\\`\\(/%s:.*[|]\\).*" m) name))) + +(defun helm-ff-complete-tramp-methods () + "Completion on tramp methods in a nested helm session." + (interactive) + (with-helm-alive-p + (let* (initial-input + (str helm-pattern) + (pattern (with-temp-buffer + (insert str) + (let ((end (point)) beg) + (when (re-search-backward "[/|]" nil t) + (setq beg (1+ (point))) + (unless (= beg end) + (setq initial-input + (buffer-substring beg end)) + (delete-region beg end)) + (buffer-string))))) + (collection (helm-ff--get-tramp-methods)) + (method (helm-comp-read + "Tramp methods: " + (sort collection #'string<) + :initial-input initial-input + :fc-transformer + (lambda (candidates _source) + (cl-loop for c in candidates + collect (propertize c 'face 'helm-ff-file))) + :allow-nest t + :must-match t))) + (helm-set-pattern (concat pattern method ":"))))) +(put 'helm-ff-complete-tramp-methods 'no-helm-mx t) + (defun helm-ff-set-pattern (pattern) "Handle tramp filenames in `helm-pattern'." (let* ((methods (helm-ff--get-tramp-methods)) @@ -3084,6 +3243,8 @@ debugging purpose." (expand-file-name "~/")) ((string-match "\\`~/" pattern) (expand-file-name pattern)) + ((string-match helm-ff-tramp-method-regexp pattern) + pattern) ;; Match "/method:maybe_hostname:~" ((and (string-match (concat reg "~") pattern) postfixed @@ -3164,7 +3325,10 @@ debugging purpose." ;; At this point the tramp connection is triggered. (helm-log "Pattern=%S" - (setq helm-pattern (helm-ff--transform-pattern-for-completion path))) + (setq helm-pattern (if (string-match helm-ff-tramp-method-regexp path) + ;; A tramp method, don't modify pattern. + helm-pattern + (helm-ff--transform-pattern-for-completion path)))) ;; This have to be set after [1] to allow deleting char backward. (setq basedir (or (helm-aand (if (and dir-p helm-ff-auto-update-flag) @@ -3186,7 +3350,12 @@ debugging purpose." (when (and (string-match ":\\'" path) (file-remote-p basedir nil t)) (setq helm-pattern basedir)) - (cond ((string= path "@@TRAMP@@") + (cond ((string-match helm-ff-tramp-method-regexp path) ; Tramp methods + (mapcar (lambda (method) + (helm-ff-filter-candidate-one-by-one + (concat "/" ":" method))) + (helm-ff--get-tramp-methods))) + ((string= path "@@TRAMP@@") (helm-ff--tramp-hostnames)) ; Hostnames completion. ((or (and (file-regular-p path) (eq last-repeatable-command 'helm-execute-persistent-action)) @@ -3233,16 +3402,20 @@ debugging purpose." (list (helm-ff-filter-candidate-one-by-one path nil t))) (helm-ff-directory-files basedir)))))) -(defun helm-list-directory (directory) +(defun helm-list-directory (directory &optional sel) "List directory DIRECTORY. If DIRECTORY is remote use `helm-list-directory-function', -otherwise use `directory-files'." +otherwise use `directory-files'. +SEL argument is only here for debugging purpose, it default to +`helm-get-selection'." (let* ((remote (file-remote-p directory 'method)) (helm-list-directory-function - (if (and remote (not (string= remote "ftp"))) - helm-list-directory-function - #'helm-list-dir-lisp)) + (cond ((and remote (string= remote "ftp")) + #'helm-list-dir-lisp) + ((and remote (string= remote "adb")) + #'helm-list-dir-adb) + (t helm-list-directory-function))) (remote-fn-p (eq helm-list-directory-function 'helm-list-dir-external)) (sort-method (cl-case helm-ff-initial-sort-method @@ -3250,13 +3423,24 @@ otherwise use `directory-files'." "-t" #'file-newer-than-file-p)) (size (if (and remote remote-fn-p) "-S" #'helm-ff-file-larger-that-file-p)) + (ext (unless (and remote remote-fn-p) + #'helm-group-candidates-by)) (t nil)))) - (if remote - (funcall helm-list-directory-function directory sort-method) - (if sort-method - (sort (directory-files directory t directory-files-no-dot-files-regexp) - sort-method) - (directory-files directory t directory-files-no-dot-files-regexp))))) + (cond (remote + (ignore-errors + (funcall helm-list-directory-function directory sort-method))) + ((memq helm-ff-initial-sort-method '(newest size)) + (sort (directory-files + directory t directory-files-no-dot-files-regexp) + sort-method)) + ((eq helm-ff-initial-sort-method 'ext) + (funcall sort-method + (directory-files + directory t directory-files-no-dot-files-regexp) + #'file-name-extension + (or sel (helm-get-selection) ""))) + (t (directory-files + directory t directory-files-no-dot-files-regexp))))) (defsubst helm-ff-file-larger-that-file-p (f1 f2) (let ((attr1 (file-attributes f1)) @@ -3274,16 +3458,45 @@ Add a `helm-ff-dir' property on each fname ending with \"/\"." (cl-loop for f in (sort (file-name-all-completions "" directory) (or sort-method 'string-lessp)) unless (or (string= f "") - (member f '("./" "../")) - ;; Ignore the tramp names from / - ;; completion, e.g. ssh: scp: etc... - (char-equal (aref f (1- (length f))) ?:)) + (member f '("./" "../" "." ".."))) if (and (helm--dir-name-p f) (helm--dir-file-name f directory)) collect (propertize it 'helm-ff-dir t) else collect (propertize (expand-file-name f directory) 'helm-ff-file t))) +(defun helm-file-name-all-completions-internal (directory) + (let ((switches "-1F")) + (with-temp-buffer + (insert-directory (format "%s*" + (file-name-as-directory directory)) + switches t) + (split-string + (buffer-substring-no-properties (point-min) (point-max)) + "\n" t)))) + +(defun helm-list-dir-adb (directory &optional sort-method) + "List DIRECTORY with `helm-file-name-all-completions-internal' as backend. + +This is used for tramp adb backend. + +Add a `helm-ff-dir' property on each fname ending with \"/\"." + (cl-loop with files = (helm-file-name-all-completions-internal directory) + for f in (sort files (or sort-method 'string-lessp)) + for split = (split-string f "->" t) + for fname = (replace-regexp-in-string " $" "" (car split)) + for truename = (cadr split) + collect (cond ((string-match "/\\'" fname) + (propertize (helm--dir-file-name fname directory) + 'helm-ff-dir t)) + (truename + (propertize (expand-file-name + (substring fname 0 (1- (length fname))) + directory) + 'helm-ff-sym truename)) + (t (propertize (expand-file-name fname directory) + 'helm-ff-file t))))) + (defun helm-list-dir-external (dir &optional sort-method) "List directory DIR with external shell command as backend. @@ -3340,56 +3553,63 @@ to nil to avoid error messages when using `helm-find-files'." (cl-loop for dir being the hash-keys of helm-ff--file-notify-watchers do (remhash dir helm-ff--list-directory-cache))))) +(defcustom helm-ff-inotify-unsupported-methods '("adb") + "Tramp methods unsupported by file-notify." + :type '(repeat string) + :group 'helm-files) + (defun helm-ff-directory-files (directory &optional force-update) "List contents of DIRECTORY. Argument FULL mean absolute path. It is same as `directory-files' but always returns the dotted -filename '.' and '..' even on root directories in Windows +filename \\='.' and \\='..' even on root directories in Windows systems. When FORCE-UPDATE is non nil recompute candidates even if DIRECTORY is in cache." - (setq directory (file-name-as-directory - (expand-file-name directory))) - (or (and (not force-update) - (gethash directory helm-ff--list-directory-cache)) - (let* (file-error - (ls (condition-case err - (helm-list-directory directory) - ;; Handle file-error from here for Windows - ;; because predicates like `file-readable-p' and friends - ;; seem broken on emacs for Windows systems (always returns t). - ;; This should never be called on GNU/Linux/Unix - ;; as the error is properly intercepted in - ;; `helm-find-files-get-candidates' by `file-readable-p'. - (file-error - (prog1 - ;; Prefix error message with @@@@ for safety - ;; (some files may match file-error See bug#2400) - (list (format "@@@@%s:%s" - (car err) - (mapconcat 'identity (cdr err) " "))) - (setq file-error t))))) - (dot (concat directory ".")) - (dot2 (concat directory "..")) - (candidates (append (and (not file-error) (list dot dot2)) ls))) - (puthash directory (+ (length ls) 2) helm-ff--directory-files-length) - (prog1 - (puthash directory - (cl-loop for f in candidates - when (helm-ff-filter-candidate-one-by-one f) - collect it) - helm-ff--list-directory-cache) - ;; Put an inotify watcher to check directory modifications. - (unless (or (null helm-ff-use-notify) - (gethash directory helm-ff--file-notify-watchers)) - (condition-case-unless-debug err - (puthash directory - (file-notify-add-watch - directory - '(change attribute-change) - (helm-ff--inotify-make-callback directory)) - helm-ff--file-notify-watchers) - (file-notify-error (user-error "Error: %S %S" (car err) (cdr err))))))))) + (let ((method (file-remote-p directory 'method))) + (setq directory (file-name-as-directory + (expand-file-name directory))) + (or (and (not force-update) + (gethash directory helm-ff--list-directory-cache)) + (let* (file-error + (ls (condition-case err + (helm-list-directory directory) + ;; Handle file-error from here for Windows + ;; because predicates like `file-readable-p' and friends + ;; seem broken on emacs for Windows systems (always returns t). + ;; This should never be called on GNU/Linux/Unix + ;; as the error is properly intercepted in + ;; `helm-find-files-get-candidates' by `file-readable-p'. + (file-error + (prog1 + ;; Prefix error message with @@@@ for safety + ;; (some files may match file-error See bug#2400) + (list (format "@@@@%s:%s" + (car err) + (mapconcat 'identity (cdr err) " "))) + (setq file-error t))))) + (dot (concat directory ".")) + (dot2 (concat directory "..")) + (candidates (append (and (not file-error) (list dot dot2)) ls))) + (puthash directory (+ (length ls) 2) helm-ff--directory-files-length) + (prog1 + (puthash directory + (cl-loop for f in candidates + when (helm-ff-filter-candidate-one-by-one f) + collect it) + helm-ff--list-directory-cache) + ;; Put an inotify watcher to check directory modifications. + (unless (or (null helm-ff-use-notify) + (member method helm-ff-inotify-unsupported-methods) + (gethash directory helm-ff--file-notify-watchers)) + (condition-case-unless-debug err + (puthash directory + (file-notify-add-watch + directory + '(change attribute-change) + (helm-ff--inotify-make-callback directory)) + helm-ff--file-notify-watchers) + (file-notify-error (user-error "Error: %S %S" (car err) (cdr err)))))))))) (defun helm-ff--inotify-make-callback (directory) "Return a callback for `file-notify-add-watch'." @@ -3452,10 +3672,10 @@ If PATTERN is a valid directory name, return PATTERN unchanged." ;; FIXME: some multi-match methods may not work here. (dir-p (concat (regexp-quote bd) " " (regexp-quote bn))) ((or (not (helm-ff-fuzzy-matching-p)) - (string-match "\\s-" bn)) ; Fall back to multi-match. - (concat (regexp-quote bd) bn)) + (string-match "[ !]" bn)) ; Fall back to multi-match. + (concat (regexp-quote bd) " " bn)) ((or (string-match "[*][.]?.*" bn) ; Allow entering wildcard. - (string-match "/$" pattern) ; Allow mkdir. + (string-match "/\\'" pattern) ; Allow mkdir. (string-match helm-ff-url-regexp pattern) (and (string= helm-ff-default-directory "/") tramp-p)) ;; Don't treat wildcards ("*") as regexp char. @@ -3486,34 +3706,16 @@ Note that only existing directories are saved here." (push helm-ff-default-directory helm-ff-history))) (add-hook 'helm-cleanup-hook 'helm-ff-save-history) -(defun helm-files-save-file-name-history (&optional force) - "Save marked files to `file-name-history'." - (let* ((src (helm-get-current-source)) - (src-name (assoc-default 'name src))) - (when (or force (helm-file-completion-source-p src) - (member src-name helm-files-save-history-extra-sources)) - (let ((mkd (helm-marked-candidates :with-wildcard t)) - (history-delete-duplicates t)) - (cl-loop for sel in mkd - when (and sel - (stringp sel) - (file-exists-p sel) - (not (file-directory-p sel))) - do - ;; we use `abbreviate-file-name' here because - ;; other parts of Emacs seems to, - ;; and we don't want to introduce duplicates. - (add-to-history 'file-name-history - (abbreviate-file-name sel))))))) -(add-hook 'helm-exit-minibuffer-hook 'helm-files-save-file-name-history) - -(defun helm-ff-valid-symlink-p (file) +(defun helm-ff-valid-symlink-p (file &optional link) + "Returns the truename of FILE if it exists. +If we already know the truename of FILE we can pass it with LINK arg +to avoid an unnecessary call to `file-truename'." (helm-aif (condition-case-unless-debug nil ;; `file-truename' send error ;; on cyclic symlinks (Bug#692). - (file-truename file) + (or link (file-truename file)) (error nil)) - (file-exists-p it))) + (and (file-exists-p it) it))) (defun helm-get-default-mode-for-file (filename) "Return the default mode to open FILENAME." @@ -3558,8 +3760,7 @@ Note that only existing directories are saved here." (format "True name: '%s'\n" (cond ((string-match "^\\.#" (helm-basename candidate)) "Autosave symlink") - ((helm-ff-valid-symlink-p candidate) - (file-truename candidate)) + ((helm-ff-valid-symlink-p candidate)) (t "Invalid Symlink")))) (format "Owner: %s: %s\n" owner owner-right) (format "Group: %s: %s\n" group group-right) @@ -3747,13 +3948,6 @@ return directly CANDIDATES." when fc collect fc) candidates)) -(defsubst helm-ff-file-extension (file) - "Returns FILE extension if it is not a number." - (helm-aif (file-name-extension file) - (and (not (string-match "\\`0+\\'" it)) - (zerop (string-to-number it)) - it))) - (defun helm-ff-filter-candidate-one-by-one (file &optional reverse skip-boring-check) "Transform file in a cons cell like (DISPLAY . REAL). DISPLAY is shown as basename of FILE and REAL as full path of FILE. @@ -3769,6 +3963,9 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." (if (or reverse urlp) file basename)))) (len (length disp)) (backup (backup-file-name-p disp))) + (when (string-match "/\\'" file) + (setq disp (concat disp "/") + len (1+ len))) ;; We want to filter boring files only on the files coming ;; from the output of helm-ff-directory-files not on single ;; candidate (Bug#2330). @@ -3778,7 +3975,7 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." ;; Highlight extensions. (helm-aif (and (not backup) (not urlp) - (helm-ff-file-extension disp)) + (helm-file-name-extension disp)) (when (condition-case _err (string-match (format "\\.\\(%s\\)\\'" it) disp) (invalid-regexp nil)) @@ -3789,34 +3986,46 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." (if (and (or (string-match-p helm-tramp-file-name-regexp helm-pattern) (helm-file-on-mounted-network-p helm-pattern))) (let* ((hostp (helm-ff--get-host-from-tramp-invalid-fname file))) - (cond (;; Dot directories . and .. - dot - (cons (propertize file 'face 'helm-ff-dotted-directory) file)) - ;; Directories. - ((get-text-property 1 'helm-ff-dir file) - (cons (propertize disp 'face 'helm-ff-directory) file)) - ;; Backup files. - (backup - (cons (propertize disp 'face 'helm-ff-backup-file) file)) - ;; Executable files. - ((get-text-property 1 'helm-ff-exe file) - (add-face-text-property 0 len 'helm-ff-executable t disp) - (cons disp file)) - ;; Symlinks. - ((get-text-property 1 'helm-ff-sym file) - (add-face-text-property 0 len 'helm-ff-symlink t disp) - (cons disp file)) - ;; Regular files. - ((get-text-property 1 'helm-ff-file file) - (add-face-text-property 0 len 'helm-ff-file t disp) - (cons disp file)) - ;; non existing files. - (t - (add-face-text-property 0 len 'helm-ff-file t disp) - (cons (helm-ff-prefix-filename - disp - hostp (unless hostp 'new-file)) - file)))) + (helm-acond (;; Dot directories . and .. + dot + (cons (propertize file 'face 'helm-ff-dotted-directory) file)) + ;; Directories. + ((get-text-property 1 'helm-ff-dir file) + (cons (propertize disp 'face 'helm-ff-directory) file)) + ;; Backup files. + (backup + (cons (propertize disp 'face 'helm-ff-backup-file) file)) + ;; Executable files. + ((get-text-property 1 'helm-ff-exe file) + (add-face-text-property 0 len 'helm-ff-executable t disp) + (cons disp file)) + ;; Symlinks. + ((get-text-property 1 'helm-ff-sym file) + (add-face-text-property 0 len 'helm-ff-symlink t disp) + (if (stringp it) ; adb method. + (progn + (add-face-text-property 0 (length it) 'helm-ff-truename nil it) + (cons (propertize disp 'display (concat disp " ->" it)) file)) + (cons disp file))) + ;; Regular files. + ((get-text-property 1 'helm-ff-file file) + (add-face-text-property 0 len 'helm-ff-file t disp) + (cons disp file)) + ;; Tramp methods. + ((string-match helm-ff-tramp-method-regexp file) + (let ((method (match-string 1 file)) + (mh (helm-ff--tramp-multihops-p helm-pattern))) + (cons (propertize (concat (if mh "" "/") method) 'face 'helm-ff-file) + (if mh + (concat (match-string 1 helm-pattern) ":" method) + (concat "/:" method))))) + ;; non existing files. + (t + (add-face-text-property 0 len 'helm-ff-file t disp) + (cons (helm-ff-prefix-filename + disp + hostp (unless hostp 'new-file)) + file)))) ;; Highlight local files showing everything, symlinks, exe, ;; dirs etc... @@ -3854,7 +4063,7 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." ((stringp type) (let* ((abbrev (abbreviate-file-name type)) (len-abbrev (length abbrev))) - (helm-aif (helm-ff-file-extension abbrev) + (helm-aif (helm-file-name-extension abbrev) (when (string-match (format "\\.\\(%s\\)\\'" it) abbrev) (add-face-text-property (match-beginning 1) (match-end 1) @@ -3888,13 +4097,99 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." ((and attr (null type)) (add-face-text-property 0 len 'helm-ff-file t disp) (cons disp file)) + ;; A tramp method + ;; At this point no need to handle multi hops syntax + ;; which is considered remote and handled in first + ;; cond before. + ((string-match helm-ff-tramp-method-regexp file) + (cons (propertize (concat "/" (match-string 1 file)) + 'face 'helm-ff-nofile) + (concat "/:" (match-string 1 file)))) ;; A non--existing file. (t - (add-face-text-property 0 len 'helm-ff-file t disp) + (add-face-text-property 0 len 'helm-ff-nofile t disp) (cons (helm-ff-prefix-filename disp nil 'new-file) file)))))))) +(defun helm-ff-icons-transformer (candidates _source) + "Transformer for HFF that prefix candidates with icons." + (cl-loop for (disp . fname) in candidates + for icon = (helm-ff-get-icon disp fname) + collect (cons (concat icon disp) fname))) + +(defun helm-ff-get-icon (disp file) + "Get icon from all-the-icons for FILE. +Arg DISP is the display part of the candidate." + (let ((icon (helm-acond (;; Non symlink directories. + (helm-ff--is-dir-from-disp disp) + (all-the-icons-octicon "file-directory")) + (;; All files, symlinks may be symlink directories. + (helm-ff--is-file-from-disp disp) + ;; Detect symlink directories. We must call + ;; `file-directory-p' here but it is + ;; limited to symlinks, so it should not + ;; degrade too much performances. + (if (and (memq it '(helm-ff-symlink + helm-ff-dotted-symlink-directory)) + (file-directory-p file)) + (let* ((icon (all-the-icons-match-to-alist + (helm-basename file) + all-the-icons-dir-icon-alist)) + (args (cdr icon))) + (apply #'all-the-icons-octicon + "file-symlink-directory" (cdr args))) + (all-the-icons-icon-for-file file)))))) + (when icon (concat icon " ")))) + +(defun helm-ff--is-dir-from-disp (disp) + "Return the face used for candidate when candidate is a directory." + (cl-loop for face in '(helm-ff-directory helm-ff-dotted-directory) + thereis (text-property-any 0 (length disp) 'face face disp))) + +(defun helm-ff--is-file-from-disp (disp) + "Return the face used for file's candidate or dotted-symlink dirs." + (cl-loop with len = (length disp) + for face in '(helm-ff-file + helm-ff-suid + helm-ff-executable + helm-ff-socket + helm-ff-pipe + helm-ff-symlink + helm-ff-dotted-symlink-directory + helm-ff-backup-file) + when (text-property-any 0 len 'face face disp) + return face)) + +;;;###autoload +(define-minor-mode helm-ff-icon-mode + "Display icons from `all-the-icons' package in HFF when enabled. + +NOTE: This mode is building `helm-source-find-files', so if you enable +it from your init file, ensure to call it _after_ your defmethod's +`helm-setup-user-source' definitions (if some) to ensure they are called." + :global t + (require 'all-the-icons) + (if helm-ff-icon-mode + (progn + (unless helm-source-find-files + (setq helm-source-find-files + (helm-make-source + "Find Files" 'helm-source-ffiles))) + (let ((fct (helm-get-attr + 'filtered-candidate-transformer + helm-source-find-files))) + (unless (memq 'helm-ff-icons-transformer fct) + (helm-set-attr 'filtered-candidate-transformer + (append fct '(helm-ff-icons-transformer)) + helm-source-find-files)))) + (helm-set-attr 'filtered-candidate-transformer + (remove 'helm-ff-icons-transformer + (helm-get-attr + 'filtered-candidate-transformer + helm-source-find-files)) + helm-source-find-files))) + (defun helm-find-files-action-transformer (actions candidate) "Action transformer for `helm-source-find-files'." (let ((str-at-point (with-helm-current-buffer @@ -3923,19 +4218,17 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." (helm-append-at-nth actions '(("Rotate image right `M-r'" . helm-ff-rotate-image-right) - ("Rotate image left `M-l'" . helm-ff-rotate-image-left)) + ("Rotate image left `M-l'" . helm-ff-rotate-image-left) + ("Start slideshow with marked" . helm-ff-start-slideshow-on-marked)) 3)) - ((string-match "\\.el\\'" (helm-aif (helm-marked-candidates) - (car it) candidate)) + ((string-match "\\.el\\'" candidate) (helm-append-at-nth actions '(("Byte compile lisp file(s) `M-B, C-u to load'" . helm-find-files-byte-compile) ("Load File(s) `M-L'" . helm-find-files-load-files)) 2)) - ((string-match (concat (regexp-opt load-suffixes) "\\'") - (helm-aif (helm-marked-candidates) - (car it) candidate)) + ((string-match (concat (regexp-opt load-suffixes) "\\'") candidate) (helm-append-at-nth actions '(("Load File(s) `M-L'" . helm-find-files-load-files)) @@ -3945,14 +4238,14 @@ If SKIP-BORING-CHECK is non nil don't filter boring files." (helm-append-at-nth actions '(("Browse url file" . browse-url-of-file)) 2)) (t actions)))) - + ;;; Trashing files ;; (defun helm-ff-trash-action (fn names &rest args) "Execute a trash action FN on marked files. Arg NAMES is a list of strings to pass to messages. -E.g. '(\"delete\" \"deleting\") +E.g. \\='(\"delete\" \"deleting\") ARGS are other arguments to be passed to FN." (let ((mkd (helm-marked-candidates)) @@ -4008,7 +4301,7 @@ ARGS are other arguments to be passed to FN." The Trash directory should be a directory compliant with and each -file should have its '*.trashinfo' correspondent file in +file should have its \\='*.trashinfo' correspondent file in Trash/info directory." (helm-ff-trash-action 'helm-ff-trash-rm-1 '("delete" "deleting"))) @@ -4032,7 +4325,7 @@ Trash/info directory." The Trash directory should be a directory compliant with and each -file should have its '*.trashinfo' corresponding file in +file should have its \\='*.trashinfo' corresponding file in Trash/info directory." (let* ((default-directory (file-name-as-directory helm-ff-default-directory)) @@ -4174,7 +4467,7 @@ E.g. \"foo:12\"." (list num-arg basename))) (setq rotation-failed t)) ;; Display image in image-mode. - (if helm-ff-display-image-native + (if (helm-ff-display-image-native-p) (if rotation-failed ;; When rotation fails fallback to `image-rotate' with no ;; transformation of file. @@ -4224,7 +4517,7 @@ This affects directly file CANDIDATE." ;; because they run directly `image--change-size' in a timer without ;; taking care of the selected-window. (cl-assert (and (fboundp 'image--change-size) - helm-ff-display-image-native) + (helm-ff-display-image-native-p)) nil "Resizing image not available") (if (> arg 0) (run-with-idle-timer @@ -4305,7 +4598,16 @@ file." (prog1 #'ignore (message "Helm-follow-mode allowed only on images, disabling"))))) - (cond ((and (helm-ff--invalid-tramp-name-p) + (cond (;; Tramp methods completion. + (string-match helm-ff-tramp-method-regexp candidate) + (let ((method (match-string 1 candidate))) + (cons (lambda (candidate) + (funcall insert-in-minibuffer + (if (helm-ff--tramp-multihops-p candidate) + (concat (match-string 1 candidate) method ":") + (concat "/" method ":")))) + 'never-split))) + ((and (helm-ff--invalid-tramp-name-p) (string-match helm-tramp-file-name-regexp candidate)) (cons (lambda (_candidate) ;; First hit insert hostname and @@ -4319,11 +4621,13 @@ file." (and (file-directory-p candidate) (file-symlink-p candidate)) (cons (lambda (_candidate) (helm-ff-after-persistent-show-all) - (funcall insert-in-minibuffer - (file-name-as-directory - (if current-prefix-arg - (file-truename (expand-file-name candidate)) - (expand-file-name candidate))))) + (let ((new-dir (file-name-as-directory + (if current-prefix-arg + (file-truename (expand-file-name candidate)) + (expand-file-name candidate))))) + (setq helm-ff--show-thumbnails + (member new-dir helm-ff--thumbnailed-directories)) + (funcall insert-in-minibuffer new-dir))) 'never-split)) ;; A directory, open it. ((file-directory-p candidate) @@ -4331,8 +4635,11 @@ file." (helm-ff-after-persistent-show-all) (when (string= (helm-basename candidate) "..") (setq helm-ff-last-expanded helm-ff-default-directory)) - (funcall insert-in-minibuffer (file-name-as-directory - (expand-file-name candidate))) + (let ((new-dir (file-name-as-directory + (expand-file-name candidate)))) + (setq helm-ff--show-thumbnails + (member new-dir helm-ff--thumbnailed-directories)) + (funcall insert-in-minibuffer new-dir)) (with-helm-after-update-hook (helm-ff-retrieve-last-expanded))) 'never-split)) ;; A symlink file, expand to it's true name. (first hit) @@ -4351,7 +4658,7 @@ file." (sound-cand (lambda (candidate) (play-sound-file candidate))) ;; An image file and it is the second hit on C-j, display it. (image-cand - (if helm-ff-display-image-native + (if (helm-ff-display-image-native-p) #'helm-ff--display-or-kill-image-native (lambda (_candidate) (require 'image-dired) @@ -4423,6 +4730,24 @@ file." (t (lambda (candidate) (funcall helm-ff-kill-or-find-buffer-fname-fn candidate)))))) + +;; Native image display (with image-mode). +;; +(defvar helm-ff--image-cache nil) + +(defcustom helm-ff-image-cache-max-len 5 + "The last seen image number to keep in cache." + :group 'helm-files + :type 'integer) + +(defun helm-ff-display-image-native-p () + "Use `helm-ff-display-image-native' when returns `t'." + (or helm-ff-display-image-native + ;; Image-dired in emacs-29 uses image-mode but + ;; display is no more working with our old + ;; image-dired code, so force usage of + ;; helm-ff-display-image-native. + (fboundp 'image-dired-display-image-mode))) (defun helm-ff--display-or-kill-image-native (candidate) ;; Display images in same buffer @@ -4441,13 +4766,231 @@ file." (kill-buffer helm-ff-image-native-buffer)) (helm-ff--display-image-native candidate))) +(defun helm-ff-clean-image-cache () + (when helm-ff--image-cache + (cl-loop for img in helm-ff--image-cache + do (clear-image-cache img) + finally do (setq helm-ff--image-cache nil)))) + (defun helm-ff--display-image-native (candidate) - (and (buffer-live-p (get-buffer helm-ff-image-native-buffer)) - (kill-buffer helm-ff-image-native-buffer)) + (when (buffer-live-p (get-buffer helm-ff-image-native-buffer)) + (kill-buffer helm-ff-image-native-buffer)) + ;; Avoid hight memory consumption see + ;; https://lists.gnu.org/archive/html/bug-gnu-emacs/2021-11/msg00879.html. + (when (> (length helm-ff--image-cache) + (* helm-ff-image-cache-max-len 2)) + ;; Only keep the last `helm-ff-image-cache-max-len' images in cache. + (cl-loop for img in (butlast helm-ff--image-cache + (1+ helm-ff-image-cache-max-len)) + do (clear-image-cache img) + (setq helm-ff--image-cache + (delete img helm-ff--image-cache)))) + (cl-letf* (((symbol-function 'message) #'ignore) + (buf (find-file-noselect candidate t))) + ;; When going back reuse the cached images. + (unless (member candidate helm-ff--image-cache) + (setq helm-ff--image-cache + (append helm-ff--image-cache + (list (expand-file-name candidate))))) + (with-current-buffer buf + (rename-buffer helm-ff-image-native-buffer) + (display-buffer buf)))) + +;;; Slideshow action +;; +(defvar helm-ff--slideshow-iterator nil) +(defvar helm-ff--slideshow-sequence nil) +(defvar helm-ff--slideshow-in-pause nil) +(defvar helm-ff-slideshow-helper + "Type `\\[helm-ff-slideshow-pause-or-restart]' to %s, \ +`\\[helm-ff-slideshow-next]' for next, `\\[helm-ff-slideshow-previous]' for previous, \ +`\\[helm-ff-slideshow-quit]' to quit") + +(defcustom helm-ff-slideshow-default-delay 3 + "Delay in seconds between each image in slideshow." + :group 'helm-files + :type 'integer) + +(defvar helm-slideshow-mode-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map image-mode-map) + (define-key map (kbd "SPC") 'helm-ff-slideshow-pause-or-restart) + (define-key map (kbd "q") 'helm-ff-slideshow-quit) + (define-key map (kbd "n") 'helm-ff-slideshow-next) + (define-key map (kbd "p") 'helm-ff-slideshow-previous) + map)) + +(define-derived-mode helm-slideshow-mode + image-mode "helm-image-mode" + "Mode to display images from helm-find-files. + +Special commands: +\\{helm-slideshow-mode-map} +") +(put 'helm-slideshow-mode 'no-helm-mx t) + +(defun helm-ff-start-slideshow-on-marked (_candidate) + "Start a slideshow on marked files." + (let ((marked (helm-marked-candidates :with-wildcard t))) + (cl-assert (cdr marked) nil "Can't start a slideshow on a single file") + (setq helm-ff--slideshow-sequence marked) + (setq helm-ff--slideshow-iterator (helm-iter-circular marked)) + (helm-ff--display-image-native (helm-iter-next helm-ff--slideshow-iterator)) + (delete-other-windows (get-buffer-window helm-ff-image-native-buffer)) + (cl-letf (((symbol-function 'message) #'ignore)) + (helm-slideshow-mode)) + (message (concat (format "(1/%s) " (length marked)) + (substitute-command-keys + (format helm-ff-slideshow-helper "pause")))) + (helm-ff-slideshow-loop helm-ff--slideshow-iterator))) + +(defun helm-ff-slideshow-state () + (format "(%s/%s) " + (1+ (cl-position + (buffer-file-name) helm-ff--slideshow-sequence + :test 'equal)) + (length helm-ff--slideshow-sequence))) + +(defun helm-ff-slideshow-sequence-from-current (&optional reverse) + (helm-reorganize-sequence-from-elm + helm-ff--slideshow-sequence (buffer-file-name) reverse)) + +(defun helm-ff-slideshow-loop (iterator) + (while (sit-for helm-ff-slideshow-default-delay) + (helm-ff--display-image-native (helm-iter-next iterator)) + (delete-other-windows (get-buffer-window helm-ff-image-native-buffer)) + (cl-letf (((symbol-function 'message) #'ignore)) + (helm-slideshow-mode)) + (message (concat (helm-ff-slideshow-state) + (substitute-command-keys + (format helm-ff-slideshow-helper "pause")))))) + +(defun helm-ff-slideshow-pause-or-restart () + (interactive) + (setq helm-ff--slideshow-in-pause (not helm-ff--slideshow-in-pause)) + (if helm-ff--slideshow-in-pause + (message (substitute-command-keys + (format helm-ff-slideshow-helper "restart"))) + (message "Helm Slideshow restarting...") + (setq helm-ff--slideshow-iterator + (helm-iter-circular (helm-ff-slideshow-sequence-from-current))) + (helm-ff-slideshow-loop helm-ff--slideshow-iterator))) +(put 'helm-ff-slideshow-pause-or-restart 'no-helm-mx t) + +(defun helm-ff-slideshow-next () + (interactive) + (setq helm-ff--slideshow-in-pause t) + (setq helm-ff--slideshow-iterator nil) + (helm-ff--display-image-native + (car (helm-ff-slideshow-sequence-from-current))) + (delete-other-windows (get-buffer-window helm-ff-image-native-buffer)) (cl-letf (((symbol-function 'message) #'ignore)) - (find-file candidate)) - (with-current-buffer (get-file-buffer candidate) - (rename-buffer helm-ff-image-native-buffer))) + (helm-slideshow-mode)) + (message (concat (helm-ff-slideshow-state) + (substitute-command-keys + (format helm-ff-slideshow-helper "restart"))))) +(put 'helm-ff-slideshow-next 'no-helm-mx t) + +(defun helm-ff-slideshow-previous () + (interactive) + (setq helm-ff--slideshow-in-pause t) + (setq helm-ff--slideshow-iterator nil) + (helm-ff--display-image-native + (car (helm-ff-slideshow-sequence-from-current 'reverse))) + (delete-other-windows (get-buffer-window helm-ff-image-native-buffer)) + (cl-letf (((symbol-function 'message) #'ignore)) + (helm-slideshow-mode)) + (message (concat (helm-ff-slideshow-state) + (substitute-command-keys + (format helm-ff-slideshow-helper "restart"))))) +(put 'helm-ff-slideshow-previous 'no-helm-mx t) + +(defun helm-ff-slideshow-quit () + (interactive) + (setq helm-ff--slideshow-iterator nil) + (setq helm-ff--slideshow-in-pause nil) + (helm-ff-clean-image-cache) + (quit-window)) +(put 'helm-ff-slideshow-quit 'no-helm-mx t) + +;;; Thumbnails view +;; +(defun helm-ff-maybe-show-thumbnails (candidates _source) + (require 'image-dired) + (if (and helm-ff--show-thumbnails + (null (file-remote-p helm-ff-default-directory))) + (progn + (cl-pushnew helm-ff-default-directory + helm-ff--thumbnailed-directories :test 'equal) + (cl-loop for (disp . img) in candidates + for type = (helm-acase (file-name-extension img) + ("png" 'png) + (("jpg" "jpeg") 'jpeg)) + if type collect + (let ((thumbnail (plist-get + (cdr (helm-ff--image-dired-get-thumbnail-image img)) + :file))) + (cons (concat (propertize " " + 'display `(image + :type ,type + :margin 5 + :file ,thumbnail) + 'rear-nonsticky '(display)) + disp) + img)) + else collect (cons disp img))) + candidates)) + +;; Same as `image-dired-get-thumbnail-image' but use +;; `helm-ff--image-dired-thumb-name' which cache thumbnails for further use. +(defun helm-ff--image-dired-get-thumbnail-image (file) + "Return the image descriptor for a thumbnail of image file FILE." + (unless (string-match-p (image-file-name-regexp) file) + (error "%s is not a valid image file" file)) + (let* ((thumb-file (helm-ff--image-dired-thumb-name file)) + (thumb-attr (file-attributes thumb-file))) + (when (or (not thumb-attr) + (time-less-p (file-attribute-modification-time thumb-attr) + (file-attribute-modification-time + (file-attributes file)))) + (image-dired-create-thumb file thumb-file)) + (create-image thumb-file))) + +(defvar helm-ff-image-dired-thumbnails-cache (make-hash-table :test 'equal) + "Store associations of image_file/thumbnail_file.") +(defun helm-ff--image-dired-thumb-name (file) + (or (gethash file helm-ff-image-dired-thumbnails-cache) + (let ((thumb-name (image-dired-thumb-name file))) + (puthash file thumb-name helm-ff-image-dired-thumbnails-cache) + thumb-name))) + +(defun helm-ff-toggle-thumbnails () + (interactive) + (cl-assert (null (file-remote-p helm-ff-default-directory)) + nil "Thumbnails show not supported on remote files") + (setq helm-ff--show-thumbnails (not helm-ff--show-thumbnails)) + (when (and (null helm-ff--show-thumbnails) + (member helm-ff-default-directory + helm-ff--thumbnailed-directories)) + (setq helm-ff--thumbnailed-directories + (delete helm-ff-default-directory helm-ff--thumbnailed-directories))) + (helm-update (regexp-quote (replace-regexp-in-string + "\\` *" "" (helm-get-selection nil t))))) +(put 'helm-ff-toggle-thumbnails 'no-helm-mx t) + +;;;###autoload +(defun helm-ff-cleanup-image-dired-dir-and-cache () + "Cleanup `image-dired-dir' directory. +Delete all thumb files that are no more associated with an existing +image file in `helm-ff-image-dired-thumbnails-cache'." + (interactive) + (cl-loop for key being the hash-keys in helm-ff-image-dired-thumbnails-cache + using (hash-value val) + unless (file-exists-p key) do + (progn + (message "Deleting %s" val) + (delete-file val) + (remhash key helm-ff-image-dired-thumbnails-cache)))) ;;; Recursive dirs completion ;; @@ -4617,29 +5160,53 @@ Show the first `helm-ff-history-max-length' elements of "Default action when dragging files. Possible values are `copy', `rsync' or `rename'.") +(defvar helm-ff-drag-and-drop-default-directory nil + "Default directory where to drop files on a drag-and-drop action. +It is used when no suitable directory is found at drop place, +generally when dropping outside of an emacs frame. +You want generally to set this to your home desktop directory.") + (defun helm-ff-drag-mouse-1-fn (event) + "Drag-and-drop function for `helm-find-files'. +Allows dropping marked files to another frame or window. +When dropping to another frame (i.e. not the selected one where helm +is running), you are asked for which directory you want to drop to when frame +displays more than one window. +When no suitable place to drop is found ask to drop to +`helm-ff-drag-and-drop-default-directory' if set." (interactive "e") (cl-assert (memq helm-ff-drag-mouse-1-default-action '(copy rsync rename))) (let* ((win-or-frame (posn-window (event-end event))) (target-frame (when (framep win-or-frame) - helm-initial-frame)) - (target (with-selected-window - (if target-frame - (frame-selected-window target-frame) - win-or-frame) - default-directory)) - win-list - (ask (and target-frame - (cdr (setq win-list (window-list target-frame 1)))))) - (when ask - (setq target (x-popup-menu - t (list "Choose target" - (cons "" - (cl-loop for win in win-list - for dir = (with-selected-window - win default-directory) - collect (cons dir dir))))))) + (car (mouse-pixel-position)))) + (target (with-selected-window + (if target-frame + (frame-selected-window target-frame) + win-or-frame) + default-directory)) + (windows (and target-frame + (remove (helm-window) + (window-list target-frame 1))))) + (when windows + (setq target + (helm-acond ((cdr windows) + (x-popup-menu + t (list "Choose target" + (cons "" + (cl-loop for win in windows + for dir = (with-selected-window + win default-directory) + collect (cons dir dir)))))) + ((and (eql (window-buffer (car windows)) + helm-current-buffer) + helm-ff-drag-and-drop-default-directory) + (x-popup-menu + t (list "Choose target" + (cons "" + (list (cons it it)))))) + ((car windows) + (with-selected-window it default-directory))))) (if (memq helm-ff-drag-mouse-1-default-action '(copy rsync)) (helm-find-files-do-action helm-ff-drag-mouse-1-default-action target) @@ -4669,7 +5236,10 @@ Use it for non-interactive calls of `helm-find-files'." (not (minibuffer-window-active-p (minibuffer-window))))) (tap (thing-at-point 'filename)) (def (and tap (or (file-remote-p tap) - (expand-file-name tap))))) + (expand-file-name tap)))) + ;; Ensure not being prompted for password each time we + ;; navigate to a directory. + (password-cache t)) (helm-set-local-variable 'helm-follow-mode-persistent nil 'helm-drag-mouse-1-fn 'helm-ff-drag-mouse-1-fn) (unless helm-source-find-files @@ -4727,7 +5297,10 @@ source is `helm-source-find-files'." helm-ff-move-to-first-real-candidate helm-ff-clean-initial-input)) (setq helm-ff--show-directories-only nil - helm-ff--show-files-only nil)) + helm-ff--show-files-only nil + helm-ff--show-thumbnails nil + helm-ff--thumbnailed-directories nil) + (helm-ff-clean-image-cache)) (defun helm-ff-bookmark () (helm :sources 'helm-source-bookmark-helm-find-files @@ -4860,23 +5433,23 @@ source is `helm-source-find-files'." Find inside `require' and `declare-function' sexp." (require 'find-func) (let* ((beg-sexp (save-excursion (search-backward "(" (point-at-bol) t))) - (end-sexp (save-excursion (search-forward ")" (point-at-eol) t))) + (end-sexp (save-excursion (ignore-errors (end-of-defun)) (point))) (sexp (and beg-sexp end-sexp (buffer-substring-no-properties (1+ beg-sexp) (1- end-sexp))))) (ignore-errors - (cond ((and sexp (string-match "require ['].+[^)]" sexp)) - (find-library-name - (replace-regexp-in-string - "'\\|)\\|(" "" - ;; If require use third arg, ignore it, - ;; always use library path found in `load-path'. - (cl-second (split-string (match-string 0 sexp)))))) - ((and sexp (string-match-p "^declare-function" sexp)) - (find-library-name - (replace-regexp-in-string - "\"\\|ext:" "" - (cl-third (split-string sexp))))) + (cond (;; Should work only when point is on the use-package line + ;; i.e. first line of sexp otherwise it prevents matching + ;; urls with helm-find-files (bug #2469). + (and sexp (string-match "use-package +\\([^ )\n]+\\)" sexp)) + (find-library-name (match-string 1 sexp))) + ((and sexp (string-match "require +[']\\([^ )]+\\)" sexp)) + ;; If require use third arg, ignore it, + ;; always use library path found in `load-path'. + (find-library-name (match-string 1 sexp))) + ;; Assume declare-function sexps are on one line. + ((and sexp (string-match "declare-function .+? \"\\(?:ext:\\)?\\([^ )]+\\)\"" sexp)) + (find-library-name (match-string 1 sexp))) (t nil))))) @@ -4894,7 +5467,7 @@ Find inside `require' and `declare-function' sexp." &key action follow (files (dired-get-marked-files))) "Execute ACTION on FILES to DESTINATION. Where ACTION is a symbol that can be one of: -'copy, 'rename, 'symlink,'relsymlink, 'hardlink or 'backup. +'copy, \\='rename, \\='symlink,'relsymlink, \\='hardlink or \\='backup. Argument FOLLOW when non-nil specifies to follow FILES to DESTINATION for the actions copy and rename." (require 'dired-async) @@ -4947,28 +5520,26 @@ DESTINATION for the actions copy and rename." (when (and follow (not (memq action '(symlink relsymlink hardlink))) (not (get-buffer dired-log-buffer))) - (let ((target (directory-file-name destination))) - (unwind-protect - (progn - (setq helm-ff-cand-to-mark - (helm-get-dest-fnames-from-list files destination dirflag)) - (with-helm-after-update-hook (helm-ff-maybe-mark-candidates)) - ;; Wait for the notify callback ends before calling HFF. - (run-at-time - 0.1 nil - (lambda () - (if (and dirflag (eq action 'rename)) - (helm-find-files-1 (file-name-directory target) - (if helm-ff-transformer-show-only-basename - (helm-basename target) target)) - (helm-find-files-1 (if (file-directory-p destination) - (file-name-as-directory - (expand-file-name destination)) - (expand-file-name (helm-basedir destination))) - (if helm-ff-transformer-show-only-basename - (helm-basename (car files)) - (car files))))))) - (setq helm-ff-cand-to-mark nil)))))) + (let ((target (directory-file-name destination)) + (cands-to-mark (helm-get-dest-fnames-from-list files destination dirflag))) + (with-helm-after-update-hook (helm-ff-maybe-mark-candidates cands-to-mark)) + ;; Wait for the notify callback ends before calling HFF. + (run-at-time + 0.1 nil + (lambda () + (if (and dirflag (eq action 'rename)) + (helm-find-files-1 (file-name-directory target) + (format helm-ff-last-expanded-candidate-regexp + (if helm-ff-transformer-show-only-basename + (helm-basename target) target))) + (helm-find-files-1 (if (file-directory-p destination) + (file-name-as-directory + (expand-file-name destination)) + (expand-file-name (helm-basedir destination))) + (format helm-ff-last-expanded-candidate-regexp + (if helm-ff-transformer-show-only-basename + (helm-basename (car files)) + (car files))))))))))) (defun helm-get-dest-fnames-from-list (flist dest-cand rename-dir-flag) "Transform filenames of FLIST to abs of DEST-CAND. @@ -4988,26 +5559,26 @@ of transformed members of FLIST." collect fname into tmp-list finally return (sort tmp-list 'string<))) -(defun helm-ff-maybe-mark-candidates () - "Mark all candidates of list `helm-ff-cand-to-mark'. +(defun helm-ff-maybe-mark-candidates (seq) + "Add visible mark to all candidates in SEQ. This is used when copying/renaming/symlinking etc. and following files to destination." (when (and (string= (assoc-default 'name (helm-get-current-source)) (assoc-default 'name helm-source-find-files)) - helm-ff-cand-to-mark) + seq) (with-helm-window - (while helm-ff-cand-to-mark - (if (string= (car helm-ff-cand-to-mark) (helm-get-selection)) + (while seq + (if (string= (car seq) (helm-get-selection)) (progn (helm-make-visible-mark) (helm-next-line) - (setq helm-ff-cand-to-mark (cdr helm-ff-cand-to-mark))) + (setq seq (cdr seq))) (helm-next-line))) (unless (helm-this-visible-mark) (helm-prev-visible-mark))))) -;;; Routines for files +;;; Delete and trash files ;; ;; (defun helm-file-buffers (filename) @@ -5070,10 +5641,11 @@ When a prefix arg is given, meaning of (unwind-protect (cl-loop for c in marked do (progn (helm-preselect - (concat "^" (regexp-quote - (if (and helm-ff-transformer-show-only-basename - (not (helm-ff-dot-file-p c))) - (helm-basename c) c)))) + (format helm-ff-last-expanded-candidate-regexp + (regexp-quote + (if (and helm-ff-transformer-show-only-basename + (not (helm-ff-dot-file-p c))) + (helm-basename c) c)))) (when (y-or-n-p (format "Really %s file `%s'? " (if trash "Trash" "Delete") @@ -5095,9 +5667,10 @@ When a prefix arg is given, meaning of (helm-force-update (let ((presel (helm-get-selection))) (when presel - (concat "^" (regexp-quote (if (and helm-ff-transformer-show-only-basename - (not (helm-ff-dot-file-p presel))) - (helm-basename presel) presel)))))))))) + (format helm-ff-last-expanded-candidate-regexp + (regexp-quote (if (and helm-ff-transformer-show-only-basename + (not (helm-ff-dot-file-p presel))) + (helm-basename presel) presel)))))))))) (defun helm-delete-file (file &optional error-if-dot-file-p synchro trash) "Delete FILE after querying the user. @@ -5200,7 +5773,7 @@ When a prefix arg is given, meaning of (cl-incf len)))) (setq helm-ff-allow-recursive-deletes old--allow-recursive-deletes))) (message "%s File(s) %s" len (if trash "trashed" "deleted")))))) - + ;;; Delete files async ;; ;; @@ -5460,10 +6033,71 @@ list." (let ((mkd (helm-marked-candidates))) (mapc 'helm-ff-file-cache-remove-file-1 mkd))) +;;; Find files in file +;; +;; +(defclass helm-find-files-in-file-class (helm-source-in-file helm-type-file) ()) +(cl-defmethod helm--setup-source ((source helm-find-files-in-file-class)) + (helm-aif (slot-value source 'candidate-transformer) + (setf (slot-value source 'candidate-transformer) + (append (helm-mklist it) + (list (lambda (candidates) + (cl-loop for c in candidates + when (and (not (string= c "")) + (file-exists-p c)) + collect c))))))) + +(defun helm-find-files-in-file-build-source (file) + (helm-make-source + (format "Find files in `%s'" (helm-basename file)) + 'helm-find-files-in-file-class + :candidates-file file)) + +(defun helm-find-files-in-file (_file) + "Helm action for listing filenames listed in marked files." + (require 'helm-for-files) + (let ((sources (cl-loop for f in (helm-marked-candidates) + collect (helm-find-files-in-file-build-source f)))) + (helm :sources sources + :quit-if-no-candidate (lambda () + (message "No files found in file(s)")) + :buffer "*helm find files in files*"))) + ;;; File name history ;; ;; +(defvar helm--file-name-history-hide-deleted nil) + +(defun helm-files-save-file-name-history (&optional force) + "Save marked files to `file-name-history'." + (let* ((src (helm-get-current-source)) + (src-name (assoc-default 'name src))) + (when (or force (helm-file-completion-source-p src) + (member src-name helm-files-save-history-extra-sources)) + (let ((mkd (helm-marked-candidates :with-wildcard t)) + (history-delete-duplicates t)) + (cl-loop for sel in mkd + when (and sel + (stringp sel) + ;; If file was one of HFF candidates assume it + ;; is an existing file, so no need to call + ;; file-exists-p which is costly on remote candidates. + ;; (file-exists-p sel) + (not (helm-ff--file-directory-p sel)) + ;; When creating a new directory previous test + ;; check for file-directory-p BEFORE its + ;; creation, so check for ending slash as + ;; well to know if it is a future directory. + (not (string-match "/\\'" sel))) + do + ;; we use `abbreviate-file-name' here because + ;; other parts of Emacs seems to, + ;; and we don't want to introduce duplicates. + (add-to-history 'file-name-history + (abbreviate-file-name sel))))))) +(add-hook 'helm-exit-minibuffer-hook 'helm-files-save-file-name-history) + (defvar helm-source-file-name-history (helm-build-sync-source "File Name History" :candidates 'file-name-history @@ -5471,13 +6105,6 @@ list." :filtered-candidate-transformer #'helm-file-name-history-transformer :action 'helm-type-file-actions)) -(defvar helm-source--ff-file-name-history nil - "[INTERNAL] This source is build to be used with `helm-find-files'. -Don't use it in your own code unless you know what you are -doing.") - -(defvar helm--file-name-history-hide-deleted nil) - (defun helm-file-name-history-show-or-hide-deleted () (interactive) (setq helm--file-name-history-hide-deleted @@ -5493,16 +6120,27 @@ doing.") map)) (defun helm-file-name-history-transformer (candidates _source) - (cl-loop for c in candidates - when (cond ((or (file-remote-p c) - (and (fboundp 'tramp-archive-file-name-p) - (tramp-archive-file-name-p c))) - (cons (propertize c 'face 'helm-history-remote) c)) - ((file-exists-p c) - (cons (propertize c 'face 'helm-ff-file) c)) - (t (unless helm--file-name-history-hide-deleted - (cons (propertize c 'face 'helm-history-deleted) c)))) - collect it)) + (cl-loop with lgst = (cl-loop for c in candidates maximize (length c)) + for c in candidates + for last-access = (format-time-string "%d/%m/%Y %X" + (nth 4 (file-attributes c))) + for disp = (cond ((or (file-remote-p c) + (and (fboundp 'tramp-archive-file-name-p) + (tramp-archive-file-name-p c))) + (propertize c 'face 'helm-history-remote)) + ((file-exists-p c) + (propertize + c 'display + (concat (propertize c 'face 'helm-ff-file) + (make-string (1+ (- lgst (length c))) ? ) + last-access))) + (t (unless helm--file-name-history-hide-deleted + (propertize c 'face 'helm-history-deleted)))) + when disp + collect (cons (if helm-ff-icon-mode + (concat (all-the-icons-icon-for-file c) " " disp) + disp) + c))) (defun helm-ff-file-name-history-ff (candidate) (helm-set-pattern @@ -5514,39 +6152,47 @@ doing.") (with-helm-alive-p (helm-exit-and-execute-action 'helm-ff-file-name-history-ff))) +(defun helm-ff-file-name-history-delete-item (_candidate) + (let ((files (helm-marked-candidates))) + (with-helm-display-marked-candidates + helm-marked-buffer-name + (helm-ff--count-and-collect-dups files) + (when (y-or-n-p "Delete file(s) from history? ") + (cl-loop for f in files do + (setq file-name-history (delete f file-name-history)))) + (message nil)))) + (defun helm-ff-file-name-history () "Switch to `file-name-history' without quitting `helm-find-files'." (interactive) - (unless helm-source--ff-file-name-history - (setq helm-source--ff-file-name-history - (helm-build-sync-source "File name history" - :init (lambda () - (with-helm-alive-p - (require 'tramp-archive nil t) - (when helm-ff-file-name-history-use-recentf - (require 'recentf) - (or recentf-mode (recentf-mode 1))))) - :candidates (lambda () - (if helm-ff-file-name-history-use-recentf - recentf-list - file-name-history)) - :help-message 'helm-file-name-history-help-message - :fuzzy-match t - :persistent-action 'ignore - :migemo t - :filtered-candidate-transformer 'helm-file-name-history-transformer - :action (helm-make-actions - "Find file" (lambda (candidate) - (helm-set-pattern - (expand-file-name candidate)) - (with-helm-after-update-hook (helm-exit-minibuffer))) - "Find file in helm" 'helm-ff-file-name-history-ff) - :keymap helm-file-name-history-map))) - (with-helm-alive-p - (helm :sources 'helm-source--ff-file-name-history - :buffer "*helm-file-name-history*" - :allow-nest t - :resume 'noresume))) + (let ((src (helm-build-sync-source "File name history" + :init (lambda () + (with-helm-alive-p + (when helm-ff-file-name-history-use-recentf + (require 'recentf) + (or recentf-mode (recentf-mode 1))))) + :candidates (lambda () + (if helm-ff-file-name-history-use-recentf + recentf-list + file-name-history)) + :help-message 'helm-file-name-history-help-message + :fuzzy-match t + :persistent-action 'ignore + :migemo t + :filtered-candidate-transformer 'helm-file-name-history-transformer + :action (helm-make-actions + "Find file" (lambda (candidate) + (helm-set-pattern + (expand-file-name candidate)) + (with-helm-after-update-hook (helm-exit-minibuffer))) + "Find file in helm" 'helm-ff-file-name-history-ff + "Delete candidate(s)" 'helm-ff-file-name-history-delete-item) + :keymap helm-file-name-history-map))) + (with-helm-alive-p + (helm :sources src + :buffer "*helm-file-name-history*" + :allow-nest t + :resume 'noresume)))) (put 'helm-ff-file-name-history 'helm-only t) ;;; Browse project @@ -5727,7 +6373,7 @@ and (fboundp 'helm-ls-git-root-dir) (helm-ls-git-root-dir)) (push-to-hist it) - (helm-ls-git-ls)) + (helm-ls-git)) ((and (require 'helm-ls-hg nil t) (fboundp 'helm-hg-root) (helm-hg-root)) @@ -5760,7 +6406,10 @@ See `helm-browse-project'." (with-helm-alive-p (helm-exit-and-execute-action 'helm-ff-browse-project))) (put 'helm-ff-run-browse-project 'helm-only t) - + +;;; Actions calling helm and main interactive functions. +;; +;; (defun helm-ff-gid (_candidate) (with-helm-default-directory helm-ff-default-directory (helm-gid))) @@ -5849,7 +6498,8 @@ files." ;; resume would do. (let ((helm--executing-helm-action (not (null hist)))) (helm-find-files-1 input (and presel (null helm-ff-no-preselect) - (concat "^" (regexp-quote presel))))))) + (format helm-ff-last-expanded-candidate-regexp + (regexp-quote presel))))))) ;;;###autoload (defun helm-delete-tramp-connection () diff --git a/elpa/helm-20210729.1510/helm-find.el b/elpa/helm-20220616.1004/helm-find.el similarity index 98% rename from elpa/helm-20210729.1510/helm-find.el rename to elpa/helm-20220616.1004/helm-find.el index 748d7021..7626639b 100644 --- a/elpa/helm-20210729.1510/helm-find.el +++ b/elpa/helm-20220616.1004/helm-find.el @@ -1,6 +1,6 @@ ;;; helm-find.el --- helm interface for find command. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-font.el b/elpa/helm-20220616.1004/helm-font.el similarity index 98% rename from elpa/helm-20210729.1510/helm-font.el rename to elpa/helm-20220616.1004/helm-font.el index 76e0154a..f3d45114 100644 --- a/elpa/helm-20210729.1510/helm-font.el +++ b/elpa/helm-20220616.1004/helm-font.el @@ -1,6 +1,6 @@ ;;; helm-font --- Font and ucs selection for Helm -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -21,6 +21,9 @@ (require 'helm) (require 'helm-help) +;; No warnings in Emacs built --without-x +(declare-function x-list-fonts "xfaces.c") + (declare-function helm-generic-sort-fn "helm-utils") (defgroup helm-font nil diff --git a/elpa/helm-20210729.1510/helm-for-files.el b/elpa/helm-20220616.1004/helm-for-files.el similarity index 93% rename from elpa/helm-20210729.1510/helm-for-files.el rename to elpa/helm-20220616.1004/helm-for-files.el index a0c0f61e..6b36fb8e 100644 --- a/elpa/helm-20210729.1510/helm-for-files.el +++ b/elpa/helm-20220616.1004/helm-for-files.el @@ -1,6 +1,6 @@ ;;; helm-for-files.el --- helm-for-files and related. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -193,11 +193,18 @@ Colorize only symlinks, directories and files." 'match-part (funcall mp-fn disp) 'help-echo (expand-file-name i)) i)) - (t (cons (propertize disp - 'face 'helm-ff-file - 'match-part (funcall mp-fn disp) - 'help-echo (expand-file-name i)) - i))))) + (t (let* ((ext (helm-file-name-extension disp)) + (disp (propertize disp + 'face 'helm-ff-file + 'match-part (funcall mp-fn disp) + 'help-echo (expand-file-name i)))) + (when (condition-case _err + (string-match (format "\\.\\(%s\\)$" ext) disp) + (invalid-regexp nil)) + (add-face-text-property + (match-beginning 1) (match-end 1) + 'helm-ff-file-extension nil disp)) + (cons disp i)))))) (defclass helm-files-in-current-dir-source (helm-source-sync helm-type-file) ((candidates :initform (lambda () diff --git a/elpa/helm-20210729.1510/helm-global-bindings.el b/elpa/helm-20220616.1004/helm-global-bindings.el similarity index 74% rename from elpa/helm-20210729.1510/helm-global-bindings.el rename to elpa/helm-20220616.1004/helm-global-bindings.el index 1f4dd044..896df8b6 100644 --- a/elpa/helm-20210729.1510/helm-global-bindings.el +++ b/elpa/helm-20220616.1004/helm-global-bindings.el @@ -1,6 +1,6 @@ ;;; helm-global-bindings.el --- Bind global helm commands -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -17,37 +17,15 @@ ;;; Code: -(defcustom helm-minibuffer-history-key "C-r" - "The key `helm-minibuffer-history' is bound to in minibuffer local maps." - :type '(choice (string :tag "Key") (const :tag "no binding")) - :group 'helm-misc - :set - (lambda (var key) - (cl-dolist (map '(minibuffer-local-completion-map - minibuffer-local-filename-completion-map - minibuffer-local-filename-must-match-map ; Emacs 23.1.+ - minibuffer-local-isearch-map - minibuffer-local-map - minibuffer-local-must-match-filename-map ; Older Emacsen - minibuffer-local-must-match-map - minibuffer-local-ns-map)) - (let ((vmap (and (boundp map) (symbol-value map)))) - (when (keymapp vmap) - (let ((val (and (boundp var) (symbol-value var)))) - (when val - (define-key vmap - (if (stringp val) (read-kbd-macro val) val) - nil))) - (when key - (define-key (symbol-value map) - (if (stringp key) (read-kbd-macro key) key) - 'helm-minibuffer-history))))) - (set var key))) +(require 'helm-lib) ; For helm-aif (bug #2520). + ;;; Command Keymap ;; ;; -(defcustom helm-command-prefix-key "C-x c" +(defcustom helm-command-prefix-key + (helm-aif (car (where-is-internal 'Control-X-prefix (list global-map))) + (concat it [?c])) "The key `helm-command-prefix' is bound to in the global map." :type '(choice (string :tag "Key") (const :tag "no binding")) :group 'helm-config diff --git a/elpa/helm-20210729.1510/helm-grep.el b/elpa/helm-20220616.1004/helm-grep.el similarity index 92% rename from elpa/helm-20210729.1510/helm-grep.el rename to elpa/helm-20220616.1004/helm-grep.el index 3547ee35..135f8017 100644 --- a/elpa/helm-20210729.1510/helm-grep.el +++ b/elpa/helm-20220616.1004/helm-grep.el @@ -1,6 +1,6 @@ ;;; helm-grep.el --- Helm Incremental Grep. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -16,6 +16,7 @@ ;; along with this program. If not, see . ;;; Code: +(require 'ansi-color) (require 'cl-lib) (require 'format-spec) (require 'helm) @@ -30,7 +31,6 @@ (declare-function doc-view-goto-page "doc-view" (page)) (declare-function pdf-view-goto-page "pdf-view" (page &optional window)) (declare-function helm-mm-split-pattern "helm-multi-match") -(declare-function helm--ansi-color-apply "helm-lib") (declare-function helm-comp-read "helm-mode") (declare-function helm-occur "helm-occur") @@ -58,25 +58,27 @@ Where: whether to use the -i option of grep. (Not mandatory) When you specify this spec, helm grep will use smartcase that is when a upcase character is found in pattern case will - be respected and no '-i' option will be used, otherwise, when - no upcase character is found in pattern always use '-i'. + be respected and no \\='-i' option will be used, otherwise, when + no upcase character is found in pattern always use \\='-i'. If you don't want this behavior, don't use this spec and - specify or not the '-i' option. + specify or not the \\='-i' option. Note that with ack-grep this is not needed, just specify - the '--smart-case' option. + the \\='--smart-case' option. '%p' format spec is for pattern. (Mandatory) '%f' format spec is for filenames. (Mandatory) If your grep version doesn't support the --exclude/include args -don't specify the '%e' format spec. +don't specify the \\='%e' format spec. Helm also support ack-grep and git-grep. The following is a default command example for ack-grep: -\(setq helm-grep-default-command \"ack-grep -Hn --color --smart-case --no-group %e %p %f\" - helm-grep-default-recurse-command \"ack-grep -H --color --smart-case --no-group %e %p %f\") +\(setq helm-grep-default-command + \"ack-grep -Hn --color --smart-case --no-group %e -- %p %f\" + helm-grep-default-recurse-command + \"ack-grep -H --color --smart-case --no-group %e -- %p %f\") You can ommit the %e spec if you don't want to be prompted for types. @@ -88,7 +90,8 @@ because ack disable it when output is piped. Same for grep you can use safely the option \"--color=always\" (default). You can customize the color of matches using GREP_COLORS env var. -e.g: \(setenv \"GREP_COLORS\" \"ms=30;43:mc=30;43:sl=01;37:cx=:fn=35:ln=32:bn=32:se=36\") +e.g: (setenv \"GREP_COLORS\" + \"ms=30;43:mc=30;43:sl=01;37:cx=:fn=35:ln=32:bn=32:se=36\") To enable ANSI color in git-grep just add \"--color=always\". To customize the ANSI color in git-grep, GREP_COLORS have no effect, @@ -150,10 +153,10 @@ GREP_COLORS env var." (defcustom helm-pdfgrep-default-read-command nil "Default command to read pdf files from pdfgrep. -Where '%f' format spec is filename and '%p' is page number. +Where \\='%f' format spec is filename and \\='%p' is page number. E.g. In Ubuntu you can set it to: - \"evince --page-label=%p '%f'\" + \"evince --page-label=%p \\='%f'\" If set to nil either `doc-view-mode' or `pdf-view-mode' will be used instead of an external command." @@ -242,7 +245,17 @@ doing." "A list of additional parameters to pass to grep-ag pipe command. Use parameters compatibles with the backend you are using \(i.e. AG for AG, PT for PT or RG for RG) +Here are the commands where you may want to add switches: + + ag -S --color + rg -N -S --color=? + +For RG the value of --color= is computed according to the --color= +value used in `helm-grep-ag-command'. +Note also that by default the \"--\" option is always used, you don't +need to add it here. + You probably don't need to use this unless you know what you are doing." :group 'helm-grep @@ -497,10 +510,13 @@ It is intended to use as a let-bound variable, DON'T set this globaly.") (shell-quote-argument x))) helm-grep-ignored-directories " "))) (exclude (unless (helm-grep-use-ack-p) - (if helm-grep-in-recurse - (concat (or include ignored-files) - " " ignored-dirs) - ignored-files))) + (let ((inc (and include + (concat include " "))) + (igfiles (and ignored-files + (concat ignored-files " "))) + (igdirs (and helm-grep-in-recurse + ignored-dirs))) + (concat inc igfiles igdirs)))) (types (and (helm-grep-use-ack-p) ;; When %e format spec is not specified ;; in `helm-grep-default-command' @@ -787,6 +803,13 @@ If N is positive go forward otherwise go backward." (helm-exit-and-execute-action 'helm-grep-save-results))) (put 'helm-grep-run-save-buffer 'helm-only t) +(defun helm-grep-quit-an-find-file-fn (source) + (let* ((sel (helm-get-selection nil nil source)) + (grep-line (and (stringp sel) + (helm-grep-split-line sel)))) + (if (and grep-line (file-exists-p (car grep-line))) + (expand-file-name (car grep-line)) + default-directory))) ;;; helm-grep-mode ;; @@ -856,6 +879,46 @@ If N is positive go forward otherwise go backward." (helm-grep-mode-jump))))) (put 'helm-grep-mode-mouse-jump 'helm-only t) +(defun helm-grep-next-error (&optional argp reset) + "Goto ARGP position from a `helm-grep-mode' buffer. +RESET non-nil means rewind to the first match. +This is the `next-error-function' for `helm-grep-mode'." + (interactive "p") + (goto-char (cond (reset (point-min)) + ((< argp 0) (line-beginning-position)) + ((> argp 0) (line-end-position)) + ((point)))) + (let ((fun (if (> argp 0) + #'next-single-property-change + #'previous-single-property-change))) + (helm-aif (funcall fun (point) 'helm-grep-fname) + (progn (goto-char it) (helm-grep-mode-jump)) + (user-error "No more matches")))) +(put 'helm-grep-next-error 'helm-only t) + +;;;###autoload +(defun helm-revert-next-error-last-buffer () + "Revert last `next-error' buffer from `current-buffer'. + +Accept to revert only `helm-grep-mode' or `helm-occur-mode' buffers. +Use this when you want to revert the `next-error' buffer after +modifications in `current-buffer'." + (interactive) + (let ((buffer (next-error-find-buffer)) + (linum (line-number-at-pos)) + (bufname (buffer-name))) + (if buffer + (with-current-buffer buffer + (helm-aif (memq major-mode '(helm-grep-mode helm-occur-mode)) + (progn (revert-buffer) + ;; helm-occur-mode revert fn is synchronous so + ;; reajust from here (it is done with + ;; helm-grep-mode in its sentinel). + (when (eq (car it) 'helm-occur-mode) + (helm-grep-goto-closest-from-linum linum bufname))) + (error "No suitable buffer to revert found"))) + (error "No suitable buffer to revert found")))) + (define-derived-mode helm-grep-mode special-mode "helm-grep" "Major mode to provide actions in helm grep saved buffer. @@ -865,7 +928,9 @@ Special commands: (set (make-local-variable 'helm-grep-last-cmd-line) (with-helm-buffer helm-grep-last-cmd-line)) (set (make-local-variable 'revert-buffer-function) - #'helm-grep-mode--revert-buffer-function)) + #'helm-grep-mode--revert-buffer-function) + (set (make-local-variable 'next-error-function) + #'helm-grep-next-error)) (put 'helm-grep-mode 'helm-only t) (defun helm-grep-mode--revert-buffer-function (&optional _ignore-auto _noconfirm) @@ -884,14 +949,16 @@ Special commands: (defun helm-grep-mode--sentinel (process event) (when (string= event "finished\n") - (with-current-buffer (current-buffer) + (with-current-buffer (if (eq major-mode 'helm-grep-mode) + (current-buffer) + (next-error-find-buffer)) (let ((inhibit-read-only t)) (save-excursion (cl-loop for l in (with-current-buffer (process-buffer process) (prog1 (split-string (buffer-string) "\n") (kill-buffer))) for line = (if (string-match-p helm--ansi-color-regexp l) - (helm--ansi-color-apply l) l) + (ansi-color-apply l) l) when (string-match helm-grep-split-line-regexp line) do (insert (propertize (car (helm-grep-filter-one-by-one @@ -900,8 +967,22 @@ Special commands: 'helm-realvalue line) "\n")))) (when (fboundp 'wgrep-cleanup-overlays) - (wgrep-cleanup-overlays (point-min) (point-max))) - (message "Reverting buffer done")))) + (wgrep-cleanup-overlays (point-min) (point-max)))) + (unless (eq major-mode 'helm-grep-mode) + (let ((bufname (buffer-name)) + (linum (line-number-at-pos))) + (with-current-buffer (next-error-find-buffer) + (helm-grep-goto-closest-from-linum linum bufname)))) + (message "Reverting buffer done"))) + +(defun helm-grep-goto-closest-from-linum (linum bufname) + (goto-char (point-min)) + (catch 'break + (while (re-search-forward (format "^%s:\\([0-9]+\\):" (regexp-quote bufname)) nil t) + (let ((numline (string-to-number (match-string 1)))) + (when (< (- linum numline) 0) + (forward-line -1) + (throw 'break nil)))))) (defun helm-gm-next-file () (interactive) @@ -961,14 +1042,13 @@ Special commands: ;; `helm-grep-use-ack-p'. (call-process (helm-grep-command t) nil t nil "--help-types") (goto-char (point-min)) - (cl-loop while (re-search-forward - "^ *--\\(\\[no\\]\\)\\([^. ]+\\) *\\(.*\\)" nil t) - collect (cons (concat (match-string 2) - " [" (match-string 3) "]") - (match-string 2)) - collect (cons (concat "no" (match-string 2) - " [" (match-string 3) "]") - (concat "no" (match-string 2)))))) + (cl-loop while (re-search-forward "^ +\\([^. ]+\\) +\\(.*\\)" nil t) + collect (cons (concat (match-string 1) + " [" (match-string 2) "]") + (match-string 1)) + collect (cons (concat "no" (match-string 1) + " [" (match-string 2) "]") + (concat "no" (match-string 1)))))) (defun helm-grep-ack-types-transformer (candidates _source) (cl-loop for i in candidates @@ -979,7 +1059,7 @@ Special commands: (defvar helm-grep-ack-types-cache nil) (defun helm-grep-read-ack-type () - "Select types for the '--type' argument of ack-grep." + "Select types for the \\='--type' argument of ack-grep." (require 'helm-mode) (require 'helm-adaptive) (setq helm-grep-ack-types-cache (helm-grep-hack-types)) @@ -1019,7 +1099,7 @@ of grep." finally return (delq nil (append ext-list glob-list)))) (defun helm-grep-get-file-extensions (files) - "Try to return a list of file extensions to pass to '--include' arg of grep." + "Try to return a list of file extensions to pass to \\='--include' arg of grep." (require 'helm-adaptive) (let* ((all-exts (helm-grep-guess-extensions (mapcar 'expand-file-name files))) @@ -1049,7 +1129,7 @@ of grep." (defclass helm-grep-class (helm-source-async) ((candidates-process :initform 'helm-grep-collect-candidates) (filtered-candidate-transformer :initform #'helm-grep-fc-transformer) - (keymap :initform helm-grep-map) + (keymap :initform 'helm-grep-map) (pcre :initarg :pcre :initform nil :documentation " Backend is using pcre regexp engine when non-nil.") @@ -1071,6 +1151,7 @@ of grep." (requires-pattern :initform 2) (before-init-hook :initform 'helm-grep-before-init-hook) (after-init-hook :initform 'helm-grep-after-init-hook) + (find-file-target :initform #'helm-grep-quit-an-find-file-fn) (group :initform 'helm-grep))) (defvar helm-source-grep nil) @@ -1088,7 +1169,7 @@ of grep." default-input input (source 'helm-source-grep)) "Launch helm using backend BACKEND on a list of TARGETS files. -When RECURSE is given and BACKEND is 'grep' use -r option of +When RECURSE is given and BACKEND is \\='grep' use -r option of BACKEND and prompt user for EXTS to set the --include args of BACKEND. Interactively you can give more than one arg separated by space @@ -1105,8 +1186,8 @@ Argument DEFAULT-INPUT is use as `default' arg of `helm' and INPUT is used as `input' arg of `helm'. See `helm' docstring. Arg BACKEND when non-nil specifies which backend to use. -It is used actually to specify 'zgrep' or 'git'. -When BACKEND 'zgrep' is used don't prompt for a choice in +It is used actually to specify \\='zgrep' or \\='git'. +When BACKEND \\='zgrep' is used don't prompt for a choice in recurse, and ignore EXTS, search being made recursively on files matching `helm-zgrep-file-extension-regexp' only." (let* (non-essential @@ -1214,7 +1295,7 @@ matching `helm-zgrep-file-extension-regexp' only." (let* ((root (or dir (and helm-grep-default-directory-fn (funcall helm-grep-default-directory-fn)))) (ansi-p (string-match-p helm--ansi-color-regexp candidate)) - (line (if ansi-p (helm--ansi-color-apply candidate) candidate)) + (line (if ansi-p (ansi-color-apply candidate) candidate)) (split (helm-grep-split-line line)) (fname (if (and root split) ;; Filename should always be provided as a local @@ -1249,7 +1330,7 @@ matching `helm-zgrep-file-extension-regexp' only." (let ((helm-grep-default-directory-fn (or helm-grep-default-directory-fn (lambda () (or helm-ff-default-directory - (and (null (eq major-mode 'helm-grep-mode)) + (and helm-alive-p (helm-default-directory)) default-directory))))) (if (consp candidate) @@ -1446,7 +1527,7 @@ non-file buffers." ;; https://github.com/BurntSushi/ripgrep (defcustom helm-grep-ag-command - "ag --line-numbers -S --color --nogroup %s %s %s" + "ag --line-numbers -S --color --nogroup %s -- %s %s" "The default command for AG, PT or RG. Takes three format specs, the first for type(s), the second for @@ -1461,12 +1542,12 @@ colorization of backend, however it is still supported. For ripgrep here is the command line to use: - rg --color=always --smart-case --no-heading --line-number %s %s %s + rg --color=always --smart-case --no-heading --line-number %s -- %s %s And to customize colors (always for ripgrep) use something like this: - rg --color=always --colors 'match:bg:yellow' --colors 'match:fg:black' -\--smart-case --no-heading --line-number %s %s %s + rg --color=always --colors \\='match:bg:yellow' --colors \\='match:fg:black' +\--smart-case --no-heading --line-number %s -- %s %s This will change color for matched items from foreground red (the default) to a yellow background with a black foreground. Note @@ -1538,7 +1619,7 @@ returns if available with current AG version." (shell-quote-argument directory)))) (helm-aif (cdr patterns) (concat cmd (cl-loop for p in it concat - (format " | %s %s" + (format " | %s -- %s" pipe-cmd (shell-quote-argument p)))) cmd))) @@ -1610,7 +1691,7 @@ returns if available with current AG version." (pcre :initarg :pcre :initform t :documentation " Backend is using pcre regexp engine when non--nil.") - (keymap :initform helm-grep-map) + (keymap :initform 'helm-grep-map) (history :initform 'helm-grep-ag-history) (help-message :initform 'helm-grep-help-message) (filtered-candidate-transformer :initform #'helm-grep-fc-transformer) @@ -1620,6 +1701,7 @@ returns if available with current AG version." (requires-pattern :initform 2) (nomark :initform t) (action :initform 'helm-grep-actions) + (find-file-target :initform #'helm-grep-quit-an-find-file-fn) (group :initform 'helm-grep))) (defvar helm-source-grep-ag nil) @@ -1631,8 +1713,9 @@ returns if available with current AG version." (assoc-default 'follow helm-source-grep-ag)) (setf (slot-value source 'follow) it))) -(defun helm-grep-ag-1 (directory &optional type) - "Start helm ag in DIRECTORY maybe searching in files of type TYPE." +(defun helm-grep-ag-1 (directory &optional type input) + "Start helm ag in DIRECTORY maybe searching in files of type TYPE. +If INPUT is provided, use it as the search string." (setq helm-source-grep-ag (helm-make-source (upcase (helm-grep--ag-command)) 'helm-grep-ag-class :header-name (lambda (name) @@ -1644,6 +1727,7 @@ returns if available with current AG version." (helm :sources 'helm-source-grep-ag :keymap helm-grep-map :history 'helm-grep-ag-history + :input input :truncate-lines helm-grep-truncate-lines :buffer (format "*helm %s*" (helm-grep--ag-command)))) diff --git a/elpa/helm-20210729.1510/helm-help.el b/elpa/helm-20220616.1004/helm-help.el similarity index 93% rename from elpa/helm-20210729.1510/helm-help.el rename to elpa/helm-20220616.1004/helm-help.el index 097e6ae2..cafdddc6 100644 --- a/elpa/helm-20210729.1510/helm-help.el +++ b/elpa/helm-20220616.1004/helm-help.el @@ -1,6 +1,6 @@ ;;; helm-help.el --- Help messages for Helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -339,6 +339,9 @@ NOTE: When starting back narrowing i.e. entering something in minibuffer after \"/\" sorting is done again with fuzzy sorting and no more with sorting methods previously selected. +You can use these sort functions only on files or directory, +see [[Filter out files or directories][Filter out files or directories]]. + *** Find file at point Helm uses `ffap' partially or completely to find file at point depending on the @@ -408,10 +411,14 @@ It starts from the third character of the pattern. For instance \"fob\" or \"fbr\" will complete \"foobar\" but \"fb\" needs a third character in order to complete it. -*** `\\[helm-execute-persistent-action]' on a filename expands to that filename in the Helm buffer +*** Watch briefly files contents while navigating + +You can use `\\[helm-execute-persistent-action]' on a filename for this, then: + +- First hit expands to that filename in the Helm buffer. +- Second hit displays the buffer filename. +- Third hit kills the buffer filename. -Second hit displays the buffer filename. -Third hit kills the buffer filename. Note: `\\[universal-argument] \\[helm-execute-persistent-action]' displays the buffer directly. *** Browse images directories with `helm-follow-mode' and navigate up/down @@ -433,6 +440,16 @@ TIP: Use `\\\\[helm-toggle-resplit-and-swap-windows]' and `\\[helm-enl and to enlarge it while viewing images. Note this may not work with exotic Helm windows settings such as the ones in Spacemacs. +**** Show thumbnails + +Helm use image-dired to show thumbnails on image files, you can +toggle the thumbnail view with \\`\\[helm-ff-toggle-thumbnails]'. + +**** Launch a slideshow from marked files + +Helm provides an action from `helm-find-files' that allows running a slideshow on marked files. +Just mark image files and launch slideshow from action menu, bindings are self documented. + *** Open files externally - Open file with external program (`\\\\[helm-ff-run-open-file-externally]',`C-u' to choose). @@ -446,6 +463,10 @@ prefix arg Helm will see if there is an application suitable in mailcap files. If you want to specify which external application to use (and its options) use a prefix arg. +If you have to pass arguments after filename use `%s' in your command e.g. \"foo %s -a -b\" +If you want to detach your program from Emacs, you can use e.g. \"(foo %s &)\" (only supported on Linux/Unix). +When using `%s' do not quote it (i.e. \"%s\"), helm is already quoting filename argument. + Note: What you configure for Helm in `helm-external-programs-associations' will take precedence on mailcap files. @@ -455,8 +476,7 @@ Same as above but doesn't quit Helm session, it is apersistent action. - Open file externally with default tool (`\\[helm-ff-run-open-file-with-default-tool]'). -This uses xdg-open which sucks most of the time, but perhaps it -works fine on Windows. This is why it is kept in Helm. +Use `xdg-open' to open files. *** Toggle auto-completion @@ -475,11 +495,7 @@ Simply write the path in the prompt and press `RET', e.g. *** To create a new file, enter a filename not ending with \"/\" -Note that when you enter a new name, this one is prefixed with -\[?] if you are in a writable directory. If you are in a directory -where you have no write permission the new file name is not -prefixed and is colored in red. There is not such distinction -when using Tramp, new filename just appears on top of buffer. +Note that when you enter a new name, this one is prefixed with [?]. *** Recursive search from Helm-find-files @@ -841,6 +857,19 @@ automatically \"-e 'ssh -p 2222'\" to the rsync command line unless you have specified yourself the \"-e\" option by editing rsync command line with a prefix arg (see above). +*** Access files on Android phones from Helm + +Since Android doesn't provide anymore mass storage for USB, it is +not simple to access files on Android, the best way to do this +actually seems to use Adb, here some hints to set this up, read +in addition the Tramp documentation. + +1) Install Adb, most distribution provide it. +2) Enable on your phone USB debug in System/dvlpmnt settings. +3) From helm-find-files use adb tramp method: + /adb::/ +From there you can navigate as usual, mark and copy files etc... + *** Bookmark the `helm-find-files' session You can bookmark the `helm-find-files' session with `\\[helm-ff-bookmark-set]'. @@ -911,6 +940,12 @@ $ example foo bar baz Of course the alias command should support this. +NOTE: Helm assume that any alias command ending with '$*' or +'$*&' supports many files as arguments, so no need to give a +prefix arg for such alias, however if your command is not an +alias you have to specify a prefix arg if you want your command +to apply all files at once. + If you add %s to the command line %s will be replaced with the candidate, this mean you can add extra argument to your command e.g. command -extra-arg %s or command %s -extra-arg. If you want to pass many files inside %s, don't forget to use a prefix arg. @@ -949,6 +984,7 @@ the same hosts. As a rule of thumb, prefer the scp method unless using multihops (which only works with the ssh method), especially when copying large files. +IMPORTANT: You need to hit `C-j' once on top of a directory on the first connection to complete the pattern in the minibuffer. @@ -971,6 +1007,11 @@ without addind the ending \":\", second hit insert the last \":\". As soon the last \":\" is entered TRAMP will kick in and you should see the list of candidates soon after. +**** Completion on tramp methods + +If you enter \":\" directly after \"/\" or \"|\" you will have completion on tramp methods, +hitting `\\[helm-execute-persistent-action]' or `right' on a method will insert it in minibuffer. + When connection fails, be sure to delete your TRAMP connection with M-x `helm-delete-tramp-connection' before retrying. @@ -1133,6 +1174,11 @@ system doesn't support this, you can turn off file notifications by customizing the variable `helm-ff-use-notify'. In this case you will have to refresh manually directories when needed with `\\\\[helm-refresh]'. +*** Prefix file candidates with icons + +If `all-the-icons' package is installed, turning on +`helm-ff-icon-mode' will show icons before files and directories. + ** Commands \\ |Keys|Description @@ -1174,6 +1220,7 @@ you will have to refresh manually directories when needed with `\\\\[h |\\[helm-ff-rotate-right-persistent]|Rotate image right. |\\[helm-ff-increase-image-size-persistent]|Zoom in image. |\\[helm-ff-decrease-image-size-persistent]|Zoom out image. +|\\[helm-ff-toggle-thumbnails]|Show thumbnails on image files. |\\[helm-find-files-up-one-level]|Go to parent directory. |\\[helm-find-files-history]|Switch to the visited-directory history. |\\[helm-ff-file-name-history]|Switch to file name history. @@ -1191,11 +1238,12 @@ you will have to refresh manually directories when needed with `\\\\[h |\\[helm-ff-run-insert-org-link]|Insert org link. |\\[helm-ff-bookmark-set]|Set bookmark to current directory. |\\[helm-find-files-switch-to-bookmark]|Jump to bookmark list. -|\\[helm-ff-sort-alpha]|Sort alphabetically -|\\[helm-ff-sort-by-newest]|Sort by newest -|\\[helm-ff-sort-by-size]|Sort by size -|\\[helm-ff-toggle-dirs-only]|Show only directories -|\\[helm-ff-toggle-files-only]|Show only files") +|\\[helm-ff-sort-alpha]|Sort alphabetically. +|\\[helm-ff-sort-by-newest]|Sort by newest. +|\\[helm-ff-sort-by-size]|Sort by size. +|\\[helm-ff-toggle-dirs-only]|Show only directories. +|\\[helm-ff-toggle-files-only]|Show only files. +|\\[helm-ff-sort-by-ext]|Sort by extensions.") ;;; Help for file-name-history ;; @@ -1733,6 +1781,14 @@ See [[Commands][commands]] below. Once in that buffer you can use [[https://github.com/mhayashi1120/Emacs-wgrep][emacs-wgrep]] (external package not bundled with Helm) to edit your changes, for Helm the package name is `wgrep-helm', it is hightly recommended. +Type `g' to update (revert) the buffer (after saving your buffer's changes to file). + +NOTE: `next-error' is available from this `helm-grep-mode' buffer. + +When you are running `next-error' from elsewhere, you can update +the buffer with `helm-revert-next-error-last-buffer' (up to you +to bind it to a convenient key). + *** Helm-grep supports multi-matching \(Starting from version 1.9.4.) @@ -1888,6 +1944,9 @@ leaving Helm. (defvar helm-bookmark-help-message "* Helm bookmark name +When `helm-bookmark-use-icon' is non nil and `all-the-icons' +package is installed icons before candidates will be displayed. + ** Commands \\ |Keys|Description @@ -1950,23 +2009,37 @@ You can of course combine both placeholders if needed. *** Specify marked files as arguments +When you have marked files and your command support only one file +as arg, helm will execute command sequencially on each file like +this: + Example: - file1 file2... + file1 + file2 + ...etc -Call `helm-find-files-eshell-command-on-file' with one prefix argument. Otherwise -you can pass one prefix argument from the command selection buffer. +When you have marked files and your command accept many files at +once helm will run your command with all files at once like this: -Note: This does not work on remote files. +Example: -With two prefix-args the output is printed to the `current-buffer'. + file1 file2 etc... -With no prefix argument or a prefix argument value of '(16) (`\\[universal-argument] \\[universal-argument]') -the command is called once for each file like this: +The two use case above are applied automatically by Helm +depending if your command is an eshell alias which value ends by +'$1' or '$*'. If your command is not an alias, i.e. you entered +an arbitrary command on prompt with '%s' to specify filenames, +you will have to pass one prefix argument from the command +selection buffer. - file1 - file2 - ... +Note: This does not work on remote files. + +With two prefix-args the output is printed to the +`current-buffer', the command being executed in the same +conditions as described above. +NOTE: If your command is not an alias, you can't pass all files at once and print in current buffer at the same time. +Also note that running multiple files at once is not supported with remote files. *** Run eshell commands asynchronously @@ -1974,10 +2047,6 @@ You can run your commands asynchronously by adding \"&\" at end of any commands, e.g. \"foo %s &\". You can also directly setup your alias in the eshell alias file with e.g. \"alias foo $1 &\". -NOTE: If you use \"&\" in a command with marked files and your -command accept many files as argument don't forget to pass the -prefix arg to ensure you run only one command on all marked async. - ** Commands \\") @@ -1998,7 +2067,7 @@ prefix arg to ensure you run only one command on all marked async. |\\[helm-ff-run-delete-file]|Delete file. |\\[helm-ff-run-open-file-externally]|Open file externally.") -;;; Moccur help +;;; helm-occur help ;; ;; (defvar helm-moccur-help-message @@ -2069,7 +2138,11 @@ This can be done automatically by customizing `helm-moccur-auto-update-on-resume *** Refresh a saved buffer -Type `g' to update the buffer. +Type `g' to update (revert) the buffer. + +When you are running `next-error' from elsewhere, you can update +the buffer with `helm-revert-next-error-last-buffer' (up to you +to bind it to a convenient key). *** Edit a saved buffer @@ -2081,6 +2154,8 @@ First, install wgrep (https://github.com/mhayashi1120/Emacs-wgrep) and then: Tip: Use the excellent iedit (https://github.com/victorhge/iedit) to modify all occurences at once in the buffer. +NOTE: `next-error' is available from this `helm-occur-mode' buffer. + *** Search in region When searching in current-buffer with `helm-occur', if a region @@ -2183,15 +2258,49 @@ marking it (`C-c u' or `RET') . ** Tips -*** You can get help on any command with persistent action (\\\\[helm-execute-persistent-action]) +*** Display docstring without quitting session (persistent action) + +You can get help on any command with persistent action (\\\\[helm-execute-persistent-action]) + +*** Display short docstring in helm buffer + +You can toggle short docstring description with \\\\[helm-M-x-toggle-short-doc]. +if you want this at startup you can configure `helm-M-x-show-short-doc'. + +NOTE: helm-M-x will be slower with this enabled. + +*** History source + +Helm-M-x is displaying two sources, one for the commands +themselves and one for the command history, more exactly +`extended-command-history', by default the history source is +displayed in first position, however you can put it in second +position if you don't like that by customizing +`helm-M-x-reverse-history'. + +**** Duplicate entries in helm-M-x history + +helm-M-x history obey to history variables, if you have +duplicates in your helm-M-x history set `history-delete-duplicates' to non nil. + +**** Number of entries in history + +The number of entries saved is controlled by `history-length' +global value, however if you want a different value for +`extended-command-history' e.g. 50 you can add to your config: + + (put 'extended-command-history 'history-length 50) + +*** Enabled modes are highlighted in helm-M-x *** Prefix arguments You can pass prefix arguments *after* starting `helm-M-x'. A mode-line counter will display the number of given prefix arguments. -If you pass prefix arguments before running `helm-M-x', it will be displayed in the prompt. -The first `\\[universal-argument]' after `helm-M-x' clears those prefix arguments. +If you pass prefix arguments before running `helm-M-x', it will +be displayed in the prompt. +The first `\\\\[universal-argument]' after `helm-M-x' clears those prefix arguments. NOTE: When you specify prefix arguments once `helm-M-x' is started, the prefix argument apply on the next command, so if you @@ -2199,12 +2308,8 @@ hit RET, it will apply on the selected command, but if you type a new character at prompt to narrow down further candidates, the prefix arg will apply to `self-insert-command' (e.g. if you type `C-u e' \"eeee\" will be inserted in prompt) so select the -command you want to execute before specifying prefix arg. +command you want to execute before specifying prefix arg.") -*** Duplicate entries in helm-M-x history - -helm-M-x history obey to history variables, if you have -duplicates in your helm-M-x history set `history-delete-duplicates' to non nil.") ;;; Helm imenu ;; diff --git a/elpa/helm-20210729.1510/helm-id-utils.el b/elpa/helm-20220616.1004/helm-id-utils.el similarity index 98% rename from elpa/helm-20210729.1510/helm-id-utils.el rename to elpa/helm-20220616.1004/helm-id-utils.el index 05673582..0ff71e52 100644 --- a/elpa/helm-20210729.1510/helm-id-utils.el +++ b/elpa/helm-20220616.1004/helm-id-utils.el @@ -1,6 +1,6 @@ ;;; helm-id-utils.el --- Helm interface for id-utils. -*- lexical-binding: t -*- -;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-imenu.el b/elpa/helm-20220616.1004/helm-imenu.el similarity index 56% rename from elpa/helm-20210729.1510/helm-imenu.el rename to elpa/helm-20220616.1004/helm-imenu.el index 89607668..36aa9780 100644 --- a/elpa/helm-20210729.1510/helm-imenu.el +++ b/elpa/helm-20220616.1004/helm-imenu.el @@ -1,6 +1,6 @@ ;;; helm-imenu.el --- Helm interface for Imenu -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -24,7 +24,14 @@ (require 'helm-utils) (require 'helm-help) +(defvar all-the-icons-default-adjust) +(defvar all-the-icons-scale-factor) + (declare-function which-function "which-func") +(declare-function all-the-icons-material "ext:all-the-icons.el") +(declare-function all-the-icons-octicon "ext:all-the-icons.el") +(declare-function all-the-icons-faicon "ext:all-the-icons.el") +(declare-function all-the-icons-wicon "ext:all-the-icons.el") (defgroup helm-imenu nil @@ -46,8 +53,8 @@ "Major mode association alist for `helm-imenu-in-all-buffers'. Allow `helm-imenu-in-all-buffers' searching in these associated buffers even if they are not derived from each other. The alist -is bidirectional, i.e. no need to add '((foo . bar) (bar . foo)), -only '((foo . bar)) is needed." +is bidirectional, i.e. no need to add \\='((foo . bar) (bar . foo)), +only \\='((foo . bar)) is needed." :type '(alist :key-type symbol :value-type symbol) :group 'helm-imenu) @@ -84,6 +91,101 @@ string." "Extra modes where `helm-imenu-in-all-buffers' should look into." :group 'helm-imenu :type '(repeat symbol)) + +(defcustom helm-imenu-hide-item-type-name nil + "Hide display name of imenu item type along with the icon when non nil. + +This value can be toggled with \\\\[helm-imenu-toggle-type-view]." + :group 'helm-imenu + :type 'boolean) + +(defcustom helm-imenu-use-icon nil + "Display an icon from all-the-icons package when non nil." + :group 'helm-imenu + :type 'boolean) + +(defcustom helm-imenu-icon-type-alist + '(("Array" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Array" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Boolean" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Boolean" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Class" . (all-the-icons-octicon "package" :face font-lock-type-face)) + ("Class" . (all-the-icons-octicon "package" :face font-lock-type-face)) + ("Color" . (all-the-icons-material "color_lens" :face font-lock-builtin-face)) + ("Colors" . (all-the-icons-material "color_lens" :face font-lock-builtin-face)) + ("Constant" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Constants" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Constructor" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Constructors" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Enum Member" . (all-the-icons-octicon "three-bars" :face font-lock-type-face)) + ("Enum Members" . (all-the-icons-octicon "three-bars" :face font-lock-type-face)) + ("Enum" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Enums" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Event" . (all-the-icons-wicon "lightning" :face font-lock-builtin-face)) + ("Events" . (all-the-icons-wicon "lightning" :face font-lock-builtin-face)) + ("Field" . (all-the-icons-octicon "three-bars" :face font-lock-type-face)) + ("Fields" . (all-the-icons-octicon "three-bars" :face font-lock-type-face)) + ("File" . (all-the-icons-faicon "file" :face font-lock-variable-name-face)) + ("Files" . (all-the-icons-faicon "file" :face font-lock-variable-name-face)) + ("Folder" . (all-the-icons-faicon "folder" :face font-lock-variable-name-face)) + ("Folders" . (all-the-icons-faicon "folder" :face font-lock-variable-name-face)) + ("Interface" . (all-the-icons-octicon "package" :face font-lock-builtin-face)) + ("Interfaces" . (all-the-icons-octicon "package" :face font-lock-builtin-face)) + ("Keyword" . (all-the-icons-octicon "key" :face font-lock-builtin-face)) + ("Keywords" . (all-the-icons-octicon "key" :face font-lock-builtin-face)) + ("Method" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Methods" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Defun" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Defuns" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Fn" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Fns" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Function" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Functions" . (all-the-icons-faicon "cube" :face font-lock-function-name-face)) + ("Misc" . (all-the-icons-faicon "globe" :face font-lock-function-name-face)) + ("Miscs" . (all-the-icons-faicon "globe" :face font-lock-function-name-face)) + ("Module" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face)) + ("Modules" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face)) + ("Numeric" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Numeric" . (all-the-icons-material "crop" :face font-lock-builtin-face)) + ("Object" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face)) + ("Objects" . (all-the-icons-faicon "angle-double-right" :face font-lock-builtin-face)) + ("Operator" . (all-the-icons-faicon "calculator" :face font-lock-builtin-face)) + ("Operators" . (all-the-icons-faicon "calculator" :face font-lock-builtin-face)) + ("Property" . (all-the-icons-octicon "book" :face font-lock-variable-name-face)) + ("Properties" . (all-the-icons-octicon "book" :face font-lock-variable-name-face)) + ("Reference" . (all-the-icons-octicon "book" :face font-lock-variable-name-face)) + ("References" . (all-the-icons-octicon "book" :face font-lock-variable-name-face)) + ("Snippet" . (all-the-icons-material "border_style" :face font-lock-variable-name-face)) + ("Snippet" . (all-the-icons-material "border_style" :face font-lock-variable-name-face)) + ("String" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face)) + ("Strings" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face)) + ("Struct" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Structs" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Text" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face)) + ("Texts" . (all-the-icons-material "text_fields" :face font-lock-variable-name-face)) + ("Top level" . (all-the-icons-faicon "globe" :face font-lock-function-name-face)) + ("Trait" . (all-the-icons-octicon "package" :face font-lock-builtin-face)) + ("Traits" . (all-the-icons-octicon "package" :face font-lock-builtin-face)) + ("Type" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Types" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Type Parameter" . (all-the-icons-material "code" :face font-lock-type-face)) + ("Type Parameters" . (all-the-icons-material "code" :face font-lock-type-face)) + ("Unit" . (all-the-icons-faicon "bar-chart" :face font-lock-builtin-face)) + ("Units" . (all-the-icons-faicon "bar-chart" :face font-lock-builtin-face)) + ("Value" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Values" . (all-the-icons-faicon "cog" :face font-lock-type-face)) + ("Variable" . (all-the-icons-octicon "book" :face font-lock-variable-name-face)) + ("Variables" . (all-the-icons-octicon "book":face font-lock-variable-name-face))) + "An alist of types associated with a sexp returning an icon. +The sexp should be an `all-the-icons' function with its args." + :type '(alist :key-type string :value-type sexp) + :group 'helm-imenu) + +(defcustom helm-imenu-default-type-sexp + '(all-the-icons-faicon "globe" :face font-lock-function-name-face) + "Default sexp to use when no type for an object is found." + :type 'sexp + :group 'helm-imenu) ;;; keymap (defvar helm-imenu-map @@ -91,8 +193,26 @@ string." (set-keymap-parent map helm-map) (define-key map (kbd "M-") 'helm-imenu-next-section) (define-key map (kbd "M-") 'helm-imenu-previous-section) + (define-key map (kbd "C-]") 'helm-imenu-toggle-type-view) map)) +(defun helm-imenu-toggle-type-view () + "Toggle candidate type view." + (interactive) + (with-helm-window + (setq helm-imenu-hide-item-type-name (not helm-imenu-hide-item-type-name)) + (let* ((sel (substring (helm-get-selection nil 'withprop) + (if helm-imenu-use-icon 2 0))) + (type (get-text-property 1 'type-name sel))) + (setq sel (substring-no-properties sel)) + (helm-force-update (if helm-imenu-hide-item-type-name + (format "^[ ]*%s$" + (car (last (split-string + sel helm-imenu-delimiter t)))) + (format "^[ ]*%s / %s$" + type sel)))))) +(put 'helm-imenu-toggle-type-view 'no-helm-mx t) + (defcustom helm-imenu-lynx-style-map nil "Use Arrow keys to jump to occurences." :group 'helm-imenu @@ -109,10 +229,11 @@ string." (defun helm-imenu-next-or-previous-section (n) (with-helm-window (let* ((fn (lambda () - (car (split-string - (buffer-substring - (point-at-bol) (point-at-eol)) - helm-imenu-delimiter)))) + (let ((str (buffer-substring + (point-at-bol) (point-at-eol)))) + (if helm-imenu-hide-item-type-name + (get-text-property 1 'type-name str) + (car (split-string str helm-imenu-delimiter)))))) (curtype (funcall fn)) (stop-fn (if (> n 0) #'helm-end-of-source-p @@ -143,6 +264,7 @@ string." (make-variable-buffer-local 'helm-cached-imenu-tick) (defvar helm-imenu--in-all-buffers-cache nil) + (defvar helm-source-imenu nil "See (info \"(emacs)Imenu\")") (defvar helm-source-imenu-all nil) @@ -153,9 +275,10 @@ string." (persistent-action :initform 'helm-imenu-persistent-action) (persistent-help :initform "Show this entry") (nomark :initform t) - (keymap :initform helm-imenu-map) + (keymap :initform 'helm-imenu-map) (help-message :initform 'helm-imenu-help-message) (action :initform 'helm-imenu-action) + (find-file-target :initform #'helm-imenu-quit-and-find-file-fn) (group :initform 'helm-imenu))) (defcustom helm-imenu-fuzzy-match nil @@ -189,6 +312,11 @@ string." (helm-force-update)) t))) +(defun helm-imenu-quit-and-find-file-fn (source) + (let ((sel (helm-get-selection nil nil source))) + (when (and (consp sel) (markerp (cdr sel))) + (buffer-file-name (marker-buffer (cdr sel)))))) + (defun helm-imenu-action (candidate) "Default action for `helm-source-imenu'." (helm-log-run-hook 'helm-goto-line-before-hook) @@ -288,6 +416,19 @@ string." (and prop (push prop lst))) lst))) +(defun helm-imenu-icon-for-type (type) + "Return an icon for type TYPE. +The icon is found in `helm-imenu-icon-type-alist', if not +`helm-imenu-default-type-sexp' is evaled to provide a default icon." + (require 'all-the-icons) + (let ((all-the-icons-scale-factor 1.0) + (all-the-icons-default-adjust 0.0)) + (or (helm-aand (assoc-default + type helm-imenu-icon-type-alist) + (apply (car it) (cdr it))) + (apply (car helm-imenu-default-type-sexp) + (cdr helm-imenu-default-type-sexp))))) + (defun helm-imenu-transformer (candidates) (cl-loop for (k . v) in candidates ;; (k . v) == (symbol-name . marker) @@ -302,17 +443,30 @@ string." "Function" "Top level") k)) - for disp1 = (mapconcat - (lambda (x) - (propertize - x 'face - (cl-loop for (p . f) in helm-imenu-type-faces - when (string-match p x) return f - finally return 'default))) - types helm-imenu-delimiter) - for disp = (propertize disp1 'help-echo bufname 'types types) + for type-icon = (and helm-imenu-use-icon + (helm-imenu-icon-for-type (car types))) + for type-name = (propertize + (car types) 'face + (cl-loop for (p . f) in helm-imenu-type-faces + when (string-match p (car types)) + return f + finally return 'default)) + for disp1 = (mapconcat 'identity + (cdr types) + (propertize helm-imenu-delimiter + 'face 'shadow)) + for disp = (concat (if helm-imenu-use-icon + (concat (propertize " " 'display type-icon) " ") + "") + (if helm-imenu-hide-item-type-name + "" + (concat type-name + (propertize helm-imenu-delimiter + 'face 'shadow))) + (propertize disp1 'help-echo bufname 'types types)) collect - (cons disp (cons k v)))) + (cons (propertize disp 'type-name type-name) (cons k v)))) + ;;;###autoload (defun helm-imenu () @@ -338,7 +492,7 @@ string." ;;;###autoload (defun helm-imenu-in-all-buffers () - "Preconfigured `helm' for fetching imenu entries in all buffers with similar mode as current. + "Fetch Imenu entries in all buffers with similar mode as current. A mode is similar as current if it is the same, it is derived i.e. `derived-mode-p' or it have an association in `helm-imenu-all-buffer-assoc'." diff --git a/elpa/helm-20210729.1510/helm-info.el b/elpa/helm-20220616.1004/helm-info.el similarity index 75% rename from elpa/helm-20210729.1510/helm-info.el rename to elpa/helm-20220616.1004/helm-info.el index 883e7f5f..e996c096 100644 --- a/elpa/helm-20210729.1510/helm-info.el +++ b/elpa/helm-20220616.1004/helm-info.el @@ -1,6 +1,6 @@ ;;; helm-info.el --- Browse info index with helm -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -51,6 +51,9 @@ files with `helm-info-at-point'." ;;; Build info-index sources with `helm-info-source' class. (cl-defun helm-info-init (&optional (file (helm-get-attr 'info-file))) + "Initialize candidates for info FILE. +If FILE have nodes, loop through all nodes and accumulate candidates +found in each node, otherwise scan only the current info buffer." ;; Allow reinit candidate buffer when using edebug. (helm-aif (and debug-on-error (helm-candidate-buffer)) @@ -59,41 +62,67 @@ files with `helm-info-at-point'." (save-selected-window (info file " *helm info temp buffer*") (let ((tobuf (helm-candidate-buffer 'global)) - Info-history - start end line) - (cl-dolist (node (Info-index-nodes)) - (Info-goto-node node) - (goto-char (point-min)) - (while (search-forward "\n* " nil t) - (unless (search-forward "Menu:\n" (1+ (point-at-eol)) t) - (setq start (point-at-bol) - ;; Fix Bug#1503 by getting the invisible - ;; info displayed on next line in long strings. - ;; e.g "* Foo.\n (line 12)" instead of - ;; "* Foo.(line 12)" - end (or (save-excursion - (goto-char (point-at-bol)) - (re-search-forward "(line +[0-9]+)" nil t)) - (point-at-eol)) - ;; Long string have a new line inserted before the - ;; invisible spec, remove it. - line (replace-regexp-in-string - "\n" "" (buffer-substring start end))) - (with-current-buffer tobuf - (insert line) - (insert "\n"))))) + Info-history) + (helm-aif (Info-index-nodes) + (cl-dolist (node it) + (Info-goto-node node) + (helm-info-scan-current-buffer tobuf)) + (helm-info-scan-current-buffer tobuf)) (bury-buffer))))) +(defun helm-info-scan-current-buffer (tobuf) + "Scan current info buffer and print lines to TOBUF. +Argument TOBUF is the `helm-candidate-buffer'." + (let (start end line) + (goto-char (point-min)) + (while (search-forward "\n* " nil t) + (unless (search-forward "Menu:\n" (1+ (point-at-eol)) t) + (setq start (point-at-bol) + ;; Fix Bug#1503 by getting the invisible + ;; info displayed on next line in long strings. + ;; e.g "* Foo.\n (line 12)" instead of + ;; "* Foo.(line 12)" + end (or (save-excursion + (goto-char (point-at-bol)) + (re-search-forward "(line +[0-9]+)" nil t)) + (point-at-eol)) + ;; Long string have a new line inserted before the + ;; invisible spec, remove it. + line (replace-regexp-in-string + "\n" "" (buffer-substring start end))) + (with-current-buffer tobuf + (insert line) + (insert "\n")))))) + (defun helm-info-goto (node-line) + "The helm-info action to jump to NODE-LINE." (Info-goto-node (car node-line)) (helm-goto-line (cdr node-line))) +(defvar helm-info--node-regexp + "^\\* +\\(.+\\):[ \\t]+\\(.*\\)\\(?:[ \\t]*\\)(line +\\([0-9]+\\))" + "A regexp that should match file name, node name and line number in +a line like this: + +\* bind: Bash Builtins. (line 21).") + (defun helm-info-display-to-real (line) - (and (string-match - ;; This regexp is stolen from Info-apropos-matches - "\\* +\\([^\n]*.+[^\n]*\\):[ \t]+\\([^\n]*\\)\\.\\(?:[ \t\n]*(line +\\([0-9]+\\))\\)?" line) - (cons (format "(%s)%s" (helm-get-attr 'info-file) (match-string 2 line)) - (string-to-number (or (match-string 3 line) "1"))))) + "Transform LINE to an acceptable argument for `info'. +If line have a node use the node, otherwise use directly first name found." + (let (nodename linum) + (when (string-match helm-info--node-regexp line) + (setq nodename (match-string 2 line) + linum (match-string 3 line))) + (if nodename + (cons (format "(%s)%s" + (helm-get-attr 'info-file) + (replace-regexp-in-string ":\\'" "" nodename)) + (string-to-number (or linum "1"))) + (cons (format "(%s)%s" + (helm-get-attr 'info-file) + (helm-aand (replace-regexp-in-string "^* " "" line) + (replace-regexp-in-string "::?.*\\'" "" it))) + 1)))) (defclass helm-info-source (helm-source-in-buffer) ((info-file :initarg :info-file @@ -254,6 +283,9 @@ Info files are made available." (defun helm-info-at-point () "Preconfigured `helm' for searching info at point." (interactive) + ;; Symbol at point is used as default as long as one of the sources + ;; in `helm-info-default-sources' is member of + ;; `helm-sources-using-default-as-input'. (cl-loop for src in helm-info-default-sources for name = (if (symbolp src) (assoc 'name (symbol-value src)) diff --git a/elpa/helm-20210729.1510/helm-locate.el b/elpa/helm-20220616.1004/helm-locate.el similarity index 95% rename from elpa/helm-20210729.1510/helm-locate.el rename to elpa/helm-20220616.1004/helm-locate.el index 3e1eddef..222b5e05 100644 --- a/elpa/helm-20210729.1510/helm-locate.el +++ b/elpa/helm-20220616.1004/helm-locate.el @@ -1,6 +1,6 @@ ;;; helm-locate.el --- helm interface for locate. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -34,7 +34,7 @@ "Locate related Applications and libraries for Helm." :group 'helm) -(defcustom helm-locate-db-file-regexp "m?locate\.db$" +(defcustom helm-locate-db-file-regexp "m?locate\\.db$" "Default regexp to match locate database. If nil Search in all files." :type 'string @@ -91,7 +91,7 @@ space is detected in pattern)." (defcustom helm-locate-case-fold-search helm-case-fold-search "It have the same meaning as `helm-case-fold-search'. The -i option of locate will be used depending of value of -`helm-pattern' when this is set to 'smart. +`helm-pattern' when this is set to \\='smart. When nil \"-i\" will not be used at all and when non-nil it will always be used. NOTE: the -i option of the \"es\" command used on windows does @@ -176,7 +176,7 @@ It should receive the same arguments as Prefix arg LOCALDB when (4) search and use a local locate db file when it exists or create it, when (16) force update of existing db file even if exists. -It has no effect when locate command is 'es'. INIT is a string +It has no effect when locate command is \\='es'. INIT is a string to use as initial input in prompt. See `helm-locate-with-db' and `helm-locate'." (require 'helm-mode) @@ -284,9 +284,23 @@ See also `helm-locate'." 'face 'helm-locate-finish)))) (force-mode-line-update))) +(defun helm-locate--default-process-coding-system () + "Fix `default-process-coding-system' in locate for Windows systems." + ;; This is an attempt to fix issue #1322. + (if (and (eq system-type 'windows-nt) + (boundp 'w32-ansi-code-page)) + (let ((code-page-eol + (intern (format "cp%s-%s" w32-ansi-code-page "dos")))) + (if (ignore-errors (check-coding-system code-page-eol)) + (cons code-page-eol code-page-eol) + default-process-coding-system)) + default-process-coding-system)) + (defun helm-locate-init () "Initialize async locate process for `helm-source-locate'." - (let* ((locate-is-es (string-match "\\`es" helm-locate-command)) + (let* ((default-process-coding-system + (helm-locate--default-process-coding-system)) + (locate-is-es (string-match "\\`es" helm-locate-command)) (real-locate (string-match "\\`locate" helm-locate-command)) (case-sensitive-flag (if locate-is-es "-i" "")) (ignore-case-flag (if (or locate-is-es @@ -451,7 +465,7 @@ With a prefix arg refresh the database in each project." (defun helm-locate (arg) "Preconfigured `helm' for Locate. Note: you can add locate options after entering pattern. -See 'man locate' for valid options and also `helm-locate-command'. +See \\='man locate' for valid options and also `helm-locate-command'. You can specify a local database with prefix argument ARG. With two prefix arg, refresh the current local db or create it if diff --git a/elpa/helm-20210729.1510/helm-man.el b/elpa/helm-20220616.1004/helm-man.el similarity index 98% rename from elpa/helm-20210729.1510/helm-man.el rename to elpa/helm-20220616.1004/helm-man.el index 5e37dfb8..010b06da 100644 --- a/elpa/helm-20210729.1510/helm-man.el +++ b/elpa/helm-20220616.1004/helm-man.el @@ -1,6 +1,6 @@ ;;; helm-man.el --- Man and woman UI -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-misc.el b/elpa/helm-20220616.1004/helm-misc.el similarity index 77% rename from elpa/helm-20210729.1510/helm-misc.el rename to elpa/helm-20220616.1004/helm-misc.el index 4a2bbf79..fee7a440 100644 --- a/elpa/helm-20210729.1510/helm-misc.el +++ b/elpa/helm-20220616.1004/helm-misc.el @@ -1,6 +1,6 @@ ;;; helm-misc.el --- Various functions for helm -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -198,13 +198,75 @@ It is added to `extended-command-history'. map)) (defcustom helm-minibuffer-history-must-match t - "Allow inserting non matching elements when nil or 'confirm." + "Allow inserting non matching elements when nil or \\='confirm." :group 'helm-misc :type '(choice (const :tag "Must match" t) - (const :tag "Confirm" 'confirm) + (const :tag "Confirm" confirm) (const :tag "Always allow" nil))) +(defcustom helm-minibuffer-history-key "C-r" + "The key `helm-minibuffer-history' is bound to in minibuffer local maps." + :type '(choice (string :tag "Key") (const :tag "no binding")) + :group 'helm-mode) + +(defconst helm-minibuffer-history-old-key + (cl-loop for map in '(minibuffer-local-completion-map + minibuffer-local-filename-completion-map + minibuffer-local-filename-must-match-map ; Emacs 23.1.+ + minibuffer-local-isearch-map + minibuffer-local-map + minibuffer-local-must-match-filename-map ; Older Emacsen + minibuffer-local-must-match-map + minibuffer-local-ns-map) + when (and (boundp map) (symbol-value map)) + collect (cons map (lookup-key (symbol-value map) "\C-r")))) + +;;;###autoload +(define-minor-mode helm-minibuffer-history-mode + "Bind `helm-minibuffer-history-key' in al minibuffer maps. +This mode is enabled by `helm-mode', so there is no need to enable it directly." + :group 'helm-misc + :global t + (if helm-minibuffer-history-mode + (let ((key helm-minibuffer-history-key)) + (cl-dolist (map '(minibuffer-local-completion-map + minibuffer-local-filename-completion-map + minibuffer-local-filename-must-match-map ; Emacs 23.1.+ + minibuffer-local-isearch-map + minibuffer-local-map + minibuffer-local-must-match-filename-map ; Older Emacsen + minibuffer-local-must-match-map + minibuffer-local-ns-map)) + (let ((vmap (and (boundp map) (symbol-value map)))) + (when (keymapp vmap) + (let ((val (and (boundp 'helm-minibuffer-history-key) + (symbol-value 'helm-minibuffer-history-key)))) + (when val + (define-key vmap + (if (stringp val) (read-kbd-macro val) val) + nil))) + (when key + (define-key (symbol-value map) + (if (stringp key) (read-kbd-macro key) key) + 'helm-minibuffer-history)))))) + (cl-dolist (map '(minibuffer-local-completion-map + minibuffer-local-filename-completion-map + minibuffer-local-filename-must-match-map + minibuffer-local-isearch-map + minibuffer-local-map + minibuffer-local-must-match-filename-map + minibuffer-local-must-match-map + minibuffer-local-ns-map)) + (let ((vmap (and (boundp map) (symbol-value map)))) + (when (keymapp vmap) + (let ((val (and (boundp 'helm-minibuffer-history-key) + (symbol-value 'helm-minibuffer-history-key)))) + (when val + (define-key vmap + (if (stringp val) (read-kbd-macro val) val) + (assoc-default map helm-minibuffer-history-old-key))))))))) + ;;; Helm ratpoison UI ;; diff --git a/elpa/helm-20210729.1510/helm-mode.el b/elpa/helm-20220616.1004/helm-mode.el similarity index 86% rename from elpa/helm-20210729.1510/helm-mode.el rename to elpa/helm-20220616.1004/helm-mode.el index af1cd1ed..6f5bb0e8 100644 --- a/elpa/helm-20210729.1510/helm-mode.el +++ b/elpa/helm-20220616.1004/helm-mode.el @@ -1,6 +1,6 @@ ;;; helm-mode.el --- Enable helm completion everywhere. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -21,17 +21,23 @@ (require 'helm) (require 'helm-lib) (require 'helm-files) +(require 'helm-misc) (defvar crm-separator) (defvar ido-everywhere) (defvar completion-flex-nospace) (defvar helm-completion--sorting-done) (defvar helm-mode) +(defvar password-cache) + +;; No warnings in Emacs built --without-x +(declare-function x-file-dialog "xfns.c") (declare-function ido-mode "ido.el") (declare-function helm-apropos-init "helm-elisp") (declare-function helm-lisp-completion-persistent-action "helm-elisp") (declare-function helm-lisp-completion-persistent-help "helm-elisp") +(declare-function help--symbol-class "help-fns.el") (defgroup helm-mode nil "Enable helm completion." @@ -51,8 +57,8 @@ (dired-do-relsymlink . helm-read-file-name-handler-1) (dired-do-hardlink . helm-read-file-name-handler-1) (basic-save-buffer . helm-read-file-name-handler-1) - (write-file . helm-read-file-name-handler-1) - (write-region . helm-read-file-name-handler-1)) + (write-file . (default helm-read-file-name-handler-1)) + (write-region . (default helm-read-file-name-handler-1))) "Completing read functions for specific Emacs commands. By default `helm-mode' use `helm-completing-read-default-handler' to @@ -63,8 +69,20 @@ when needed. Each entry is a cons cell like (EMACS_COMMAND . COMPLETING-READ_HANDLER) where key and value are symbols. - -Each key is an Emacs command that use originaly `completing-read'. +However if a command is using in its definition both a `completing-read' AND +a `read-file-name' we may want to specify a handler for both of them, +this can be done by specifying value as a list of two symbols instead of +a single symbol where the 1st element of the list specify the handler for the +`completing-read' and the second the handler for the `read-file-name'. +Special symbol \\='default' means use the default helm handler for either +`completing-read' or `read-file-name'. +e.g. (write-region . (default helm-read-file-name-handler-1)) +means helm will use `helm-completing-read-default-handler' when +`write-region' calls `completing-read' and +`helm-read-file-name-handler-1' when it calls `read-file-name'. + +Each key is an Emacs command that use originaly `completing-read' +or/and `read-file-name'. Each value maybe a helm function that takes same arguments as `completing-read' plus NAME and BUFFER, where NAME is the name of the new @@ -85,7 +103,7 @@ Example: (defun foo/test () (interactive) - (message \"%S\" (completing-read \"test: \" '(a b c d e)))) + (message \"%S\" (completing-read \"test: \" \\='(a b c d e)))) (defun helm-foo/test-completing-read-handler (prompt collection predicate require-match @@ -96,8 +114,8 @@ Example: :name name :buffer buffer)) - (add-to-list 'helm-completing-read-handlers-alist - '(foo/test . helm-foo/test-completing-read-handler)) + (add-to-list \\='helm-completing-read-handlers-alist + \\='(foo/test . helm-foo/test-completing-read-handler)) We want here to make the regular `completing-read' in `foo/test' @@ -118,7 +136,7 @@ If you want to disable helm completion for `describe-function', use: (describe-function . nil) Ido is also supported, you can use `ido-completing-read' and -`ido-read-file-name' as value of an entry or just 'ido. +`ido-read-file-name' as value of an entry or just \\='ido. Example: Enable ido completion for `find-file': @@ -174,22 +192,31 @@ will be used." :group 'helm-mode :type 'function) -(defcustom helm-mode-fuzzy-match nil - "Enable fuzzy matching in `helm-mode' globally. - -This is deprecated, use instead helm-fuzzy as `helm-completion-style' or -even better 'emacs as `helm-completion-style' and add 'flex to -`completion-styles' (emacs-27) or 'helm-flex if 'flex is not available -in `completion-styles-alist' (emacs-26)." +(defcustom helm-mode-ignore-diacritics nil + "Ignore diacritics in completing-read." :group 'helm-mode :type 'boolean) -(make-obsolete-variable 'helm-mode-fuzzy-match 'helm-completion-style "3.6.0") (defcustom helm-completion-mark-suffix t "Push mark at end of suffix when non nil." :group 'helm-mode :type 'boolean) +(defcustom helm-read-file-name-use-default-arg-behavior nil + "Use emacs vanilla `read-file-name' behavior for default arg. + +The behavior of default arg in `read-file-name' and friends is using +the default arg as default value when initial input is not modified, +even if this initial input is a valid value i.e. an existing file. +We expect generally a default arg to be used if nothing is specified +in the prompt or if what is specified is invalid, but the emacs behavior +here is really weird, so we use this variable to disable this +behavior, letting user specify default if needed with `M-n'. +However we keep the emacs default for `read-file-name' and derived +fns, this variable affecting only `helm-read-file-name'." + :type 'boolean + :group 'helm-mode) + (defvar helm-mode-minibuffer-setup-hook-black-list '(minibuffer-completion-help) "Incompatible `minibuffer-setup-hook' functions go here. A list of symbols. `helm-mode' is rejecting all lambda's, byte-code fns @@ -249,7 +276,7 @@ the `completing-read' using the default handler i.e. `helm-completing-read-default-handler'. NB: This has nothing to do with `completion-styles', it is independent from -helm, but when using 'emacs as helm-completion-style helm +helm, but when using \\='emacs as helm-completion-style helm will use the `completion-styles' for its completions. Up to the user to configure `completion-styles'. @@ -258,24 +285,24 @@ There are three possible values to use: - helm, use multi match regular helm completion. - helm-fuzzy, use fuzzy matching. Note that as usual when - entering a space helm switch to multi matching mode. + entering a space helm switches to multi matching mode. - emacs, use regular Emacs completion according to `completion-styles'. Note that even in this style, helm allows using multi match. Emacs-27 provides a style called `flex' that can be used aside `helm' style (see `completion-styles-alist'). When `flex' style - is not available (Emacs<27) helm provides `helm-flex' style which is similar to - `flex' and helm fuzzy matching. + is not available (Emacs<27) helm provides `helm-flex' style which is + similar to `flex' and helm fuzzy matching. For a better experience with emacs style, if you don't know what to use, set -`completion-styles' to '(flex) if you are using emacs-27 or to -\'(helm-flex) if you are using emacs-26 and keep 'emacs as default +`completion-styles' to \\='(flex) if you are using emacs-27 or to +\\='(helm-flex) if you are using emacs-26 and keep \\='emacs as default value for `helm-completion-style'. Advanced users can also have a look to `completion-category-overrides' to set styles according to category. You can as well use `helm-completion-styles-alist' to override `helm-completion-style' in specific modes. -Of course when using `helm' of `helm-fuzzy' as `helm-completion-style' +Of course when using `helm' or `helm-fuzzy' as `helm-completion-style' emacs `completion-styles' have no effect. Please use custom interface or `customize-set-variable' to set this, @@ -302,7 +329,9 @@ NOT `setq'." (choice ,@(mapcar (lambda (x) (list 'const x)) helm-completion--all-styles)))) -(defcustom helm-completion-styles-alist '((gud-mode . helm)) +(defcustom helm-completion-styles-alist '((gud-mode . helm) + ;; See https://github.com/djcb/mu/issues/2181. + (mu4e-compose-mode . emacs)) "Allow configuring `helm-completion-style' per mode. Each entry is a cons cell like (mode . style) where style must be a @@ -310,7 +339,7 @@ suitable value for `helm-completion-style'. When specifying emacs as style for a mode, `completion-styles' can be specified by using a cons cell specifying completion-styles to use with helm emacs style, e.g. (foo-mode . (emacs helm flex)) will set -`completion-styles' to '(helm flex) for foo-mode. This affects only +`completion-styles' to \\='(helm flex) for foo-mode. This affects only completions happening in buffers and not minibuffer completions, i.e. completing-read's." :group 'helm-mode @@ -336,7 +365,7 @@ Use this ONLY in `let', NOT globally, this allows third party packages to use a list as return value when `helm-mode' is enabled, e.g. (let ((helm-comp-read-use-marked t)) - (completing-read \"test: \" '(a b c d e f g))) + (completing-read \"test: \" \\='(a b c d e f g))) ") @@ -366,13 +395,13 @@ SORT-FN is a predicate to sort COLLECTION. ALISTP when non--nil will not use `all-completions' to collect candidates because it doesn't handle alists correctly for helm. i.e In `all-completions' the car of each pair is used as value. -In helm we want to use the cdr instead like \(display . real\), +In helm we want to use the cdr instead like (display . real), so we return the alist as it is with no transformation by `all-completions'. e.g -\(setq A '((a . 1) (b . 2) (c . 3))) +\(setq A \\='((a . 1) (b . 2) (c . 3))) ==>((a . 1) (b . 2) (c . 3)) \(helm-comp-read \"test: \" A :alistp nil :exec-when-only-one t @@ -459,51 +488,41 @@ 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--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))) +(cl-defun helm-cr--pattern-in-candidates-p (candidates &optional (pattern helm-pattern)) + (or (assoc pattern candidates) + (assq (intern pattern) candidates) + (member pattern candidates) + (member (downcase pattern) candidates) + (member (upcase pattern) candidates))) (defun helm-cr-default-transformer (candidates source) "Default filter candidate function for `helm-comp-read'." - (let ((must-match (helm-get-attr 'must-match source)) - unknown-pattern) - (unless (or (eq must-match t) - (string= helm-pattern "") - ;; Check if pattern is already member of candidates. - (helm-cr--pattern-in-candidates-p candidates)) - (setq candidates (append (list - ;; Unquote helm-pattern - ;; when it is added - ;; as candidate: Why? (Bug#2015) - ;; (replace-regexp-in-string - ;; "\\s\\" "" helm-pattern) - helm-pattern) - candidates)) - ;; Notify pattern have been added to candidates. - (setq unknown-pattern t)) + (let ((must-match (helm-get-attr 'must-match source))) (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 (or (equal c pat) (equal c helm-pattern)) - 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)))) + for cand = (let ((elm (if (stringp c) + (replace-regexp-in-string "\\s\\" "" c) + c))) + (cond ((and (stringp elm) + (string-match "\n" elm)) + (cons (replace-regexp-in-string "\n" "->" elm) c)) + (t c))) + collect cand into lst + finally return + ;; Unquote helm-pattern when it is added as candidate + ;; (Bug#2015). + (let ((pat (replace-regexp-in-string "\\s\\" "" helm-pattern))) + (if (or (string= pat "") + (eq must-match t) + (helm-cr--pattern-in-candidates-p lst pat)) + lst + (append (list (cons (concat (propertize + " " 'display + (propertize "[?]" + 'face 'helm-ff-prefix + 'unknown t)) + pat) + pat)) + lst)))))) (defun helm-comp-read--move-to-first-real-candidate () (helm-aif (helm-get-selection nil 'withprop) @@ -541,10 +560,10 @@ If COLLECTION is an `obarray', a TEST should be needed. See `obarray'." fuzzy reverse-history (requires-pattern 0) - history + (history nil shistory) + raw-history input-history (case-fold helm-comp-read-case-fold-search) - (del-input t) (persistent-action nil) (persistent-help "DoNothing") (mode-line helm-comp-read-mode-line) @@ -553,6 +572,7 @@ If COLLECTION is an `obarray', a TEST should be needed. See `obarray'." (name "Helm Completions") header-name candidates-in-buffer + diacritics match-part match-dynamic exec-when-only-one @@ -603,19 +623,31 @@ Keys description: - REQUIRES-PATTERN: Same as helm attribute, default is 0. -- HISTORY: A list containing specific history, default is nil. - When it is non--nil, all elements of HISTORY are displayed in - a special source before COLLECTION. +- HISTORY: A symbol where each result will be saved. + If not specified as a symbol an error will popup. + When specified, all elements of HISTORY are displayed in + a special source before or after COLLECTION according to REVERSE-HISTORY. + The main difference with INPUT-HISTORY is that the result of the + completion is saved whereas in INPUT-HISTORY it is the minibuffer + contents which is saved when you exit. + Don't use the same symbol for INPUT-HISTORY and HISTORY. + NOTE: As mentionned above this has nothing to do with + `minibuffer-history-variable', therefore if you want to save this + history persistently, you will have to add this variable to the + relevant variable of your favorite tool for persistent emacs session + i.e. psession, desktop etc... + +- RAW-HISTORY: When non-nil do not remove backslashs if some in + HISTORY candidates. - INPUT-HISTORY: A symbol. The minibuffer input history will be stored there, if nil or not provided, `minibuffer-history' - will be used instead. + will be used instead. You can navigate in this history with + `M-p' and `M-n'. + Don't use the same symbol for INPUT-HISTORY and HISTORY. - CASE-FOLD: Same as `helm-case-fold-search'. -- DEL-INPUT: Boolean, when non--nil (default) remove the partial - minibuffer input from HISTORY is present. - - PERSISTENT-ACTION: A function called with one arg i.e candidate. - PERSISTENT-HELP: A string to document PERSISTENT-ACTION. @@ -647,7 +679,7 @@ Keys description: - HIST-FC-TRANSFORMER: A `filtered-candidate-transformer' function for the history source. -- MARKED-CANDIDATES: If non--nil return candidate or marked candidates as a list. +- MARKED-CANDIDATES: If non-nil return candidate or marked candidates as a list. - NOMARK: When non--nil don't allow marking candidates. @@ -682,7 +714,27 @@ in `helm-current-prefix-arg', otherwise if prefix args were given before `helm-comp-read' invocation, the value of `current-prefix-arg' will be used. That means you can pass prefix args before or after calling a command that use `helm-comp-read'. See `helm-M-x' for example." - + ;; Handle error with HISTORY: + ;; + ;; Should show helm with one source at first run and save result on + ;; exit, should show the history source along candidates source on + ;; next run as soon as `test-hist' value is feeded. + ;; (setq test-hist nil) + ;; (helm-comp-read "test: " '(a b c d e) + ;; :history 'test-hist) + ;; + ;; Should run normally as long as `test-hist' is bound and nil. As + ;; soon `test-hist' becomes non-nil throw an error. + ;; (helm-comp-read "test: " '(a b c d e) + ;; :history test-hist) + ;; + ;; Should run normally. + ;; (completing-read "test: " '(a b c d e)) + (cl-assert (if shistory + (or (null history) + (and history (symbolp history))) + t) + nil "Error: History should be specified as a symbol") (when (get-buffer helm-action-buffer) (kill-buffer helm-action-buffer)) (let ((action-fn `(("Sole action (Identity)" @@ -720,14 +772,16 @@ that use `helm-comp-read'. See `helm-M-x' for example." :multiline multiline :match-part match-part :filtered-candidate-transformer - (append '((lambda (candidates sources) - (cl-loop for i in candidates - ;; Input is added to history in completing-read's - ;; and may be regexp-quoted, so unquote it - ;; but check if cand is a string (it may be at this stage - ;; a symbol or nil) Bug#1553. - when (stringp i) - collect (replace-regexp-in-string "\\s\\" "" i)))) + (append `((lambda (candidates _source) + (if ,raw-history + candidates + (cl-loop for i in candidates + ;; Input is added to history in completing-read's + ;; and may be regexp-quoted, so unquote it + ;; but check if cand is a string (it may be at this stage + ;; a symbol or nil) Bug#1553. + when (stringp i) + collect (replace-regexp-in-string "\\s\\" "" i))))) (and hist-fc-transformer (helm-mklist hist-fc-transformer))) :persistent-action persistent-action :persistent-help persistent-help @@ -752,6 +806,7 @@ that use `helm-comp-read'. See `helm-M-x' for example." :persistent-action persistent-action :persistent-help persistent-help :fuzzy-match fuzzy + :diacritics diacritics :keymap keymap :must-match must-match :group group @@ -772,6 +827,7 @@ that use `helm-comp-read'. See `helm-M-x' for example." :requires-pattern requires-pattern :persistent-action persistent-action :fuzzy-match fuzzy + :diacritics diacritics :keymap keymap :must-match must-match :group group @@ -806,16 +862,12 @@ that use `helm-comp-read'. See `helm-M-x' for example." :history (and (symbolp input-history) input-history) :buffer buffer)) (remove-hook 'helm-after-update-hook 'helm-comp-read--move-to-first-real-candidate)) - ;; Avoid adding an incomplete input to history. - (when (and result history del-input) - (cond ((and (symbolp history) ; History is a symbol. - (not (symbolp (symbol-value history)))) ; Fix Bug#324. - ;; Be sure history is not a symbol with a nil value. - (helm-aif (symbol-value history) (setcar it result))) - ((consp history) ; A list with a non--nil value. - (setcar history result)) - (t ; Possibly a symbol with a nil value. - (set history (list result))))) + ;; If `history' is a symbol save it. + (when (and result history (symbolp history)) + (set history + ;; RESULT may be a a string or a list of strings bug #2461. + (delete-dups (append (mapcar #'substring-no-properties (helm-mklist result)) + (symbol-value history))))) (or result (helm-mode--keyboard-quit))))) @@ -857,7 +909,7 @@ that use `helm-comp-read'. See `helm-M-x' for example." (or (car-safe default) default))) :filtered-candidate-transformer 'helm-apropos-default-sort-fn :help-message #'helm-comp-read-help-message - :fuzzy-match helm-mode-fuzzy-match + :fuzzy-match (eq helm-completion-style 'helm-fuzzy) :persistent-action (lambda (candidate) (helm-lisp-completion-persistent-action @@ -897,6 +949,7 @@ It should be used when candidate list doesn't need to be rebuilt dynamically." :input-history history :must-match require-match :alistp nil + :diacritics helm-mode-ignore-diacritics :help-message #'helm-comp-read-help-message :name name :requires-pattern (if (and (stringp default) @@ -905,10 +958,11 @@ It should be used when candidate list doesn't need to be rebuilt dynamically." (eq require-match 'confirm-after-completion))) 1 0) + :quit-when-no-cand (eq require-match t) :nomark (null helm-comp-read-use-marked) :candidates-in-buffer cands-in-buffer :exec-when-only-one exec-when-only-one - :fuzzy helm-mode-fuzzy-match + :fuzzy (eq helm-completion-style 'helm-fuzzy) :buffer buffer ;; If DEF is not provided, fallback to empty string ;; to avoid `thing-at-point' to be appended on top of list @@ -938,6 +992,8 @@ This handler uses dynamic matching which allows honouring `completion-styles'." '(metadata))) (afun (or (plist-get completion-extra-properties :annotation-function) (completion-metadata-get metadata 'annotation-function))) + (afix (or (plist-get completion-extra-properties :affixation-function) + (completion-metadata-get metadata 'affixation-function))) (file-comp-p (eq (completion-metadata-get metadata 'category) 'file)) (compfn (lambda (str _predicate _action) (let* ((completion-ignore-case (helm-set-case-fold-search)) @@ -981,10 +1037,15 @@ This handler uses dynamic matching which allows honouring `completion-styles'." (memq helm-completion-style '(helm helm-fuzzy)) (list default)) (helm-completion-in-region--initial-filter - (if (and sort-fn (> (length str) 0)) - (funcall sort-fn all) - all) - afun file-comp-p))))) + (pcase-let ((lst (if (and sort-fn (> (length str) 0)) + (funcall sort-fn all) + all))) + (if (and default afix) + (prog1 (append (list default) + (delete default lst)) + (setq default nil)) + lst)) + afun afix file-comp-p))))) (data (if (memq helm-completion-style '(helm helm-fuzzy)) (funcall compfn (or input "") nil nil) compfn)) @@ -1007,15 +1068,17 @@ This handler uses dynamic matching which allows honouring `completion-styles'." :reverse-history helm-mode-reverse-history ;; In helm h-c-styles default is passed directly in ;; candidates. - :default (and (eq helm-completion-style 'emacs) default) + :default (and (eq helm-completion-style 'emacs) (null afix) default) :fc-transformer ;; Ensure sort fn is at the end. (append '(helm-cr-default-transformer) (and helm-completion-in-region-default-sort-fn (list helm-completion-in-region-default-sort-fn))) :match-dynamic (eq helm-completion-style 'emacs) + :diacritics helm-mode-ignore-diacritics :fuzzy (eq helm-completion-style 'helm-fuzzy) :exec-when-only-one exec-when-only-one + :quit-when-no-cand (eq require-match t) :must-match require-match) (setq helm-completion--sorting-done nil)))) @@ -1061,8 +1124,7 @@ This handler uses dynamic matching which allows honouring `completion-styles'." (standard (and (memq helm-completion-style '(helm helm-fuzzy)) t)) (fn (if standard #'helm-completing-read-default-1 - #'helm-completing-read-default-2)) - (helm-mode-fuzzy-match (eq helm-completion-style 'helm-fuzzy))) + #'helm-completing-read-default-2))) (funcall fn prompt collection test require-match init hist default inherit-input-method name buffer @@ -1084,10 +1146,38 @@ Don't use it directly." (defun helm--generic-read-buffer (prompt &optional default require-match predicate) "The `read-buffer-function' for `helm-mode'. Affects `switch-to-buffer' `kill-buffer' and related." - (helm--completing-read-default - prompt (or minibuffer-completion-table - (internal-complete-buffer "" nil t)) - predicate require-match nil nil default)) + ;; `read-buffer' is using internally `Vbuffer_alist' which is an + ;; alist with elements like (BUF-NAME . BUF-OBJ), therefore some + ;; predicates in Emacs are working only on such cons cells. + ;; However, helm is transforming COLLECTION in a list of strings and + ;; such predicates are failing because they expect cons cells (see + ;; bug#2506 with `project-switch-to-buffer'), even if they should + ;; handle strings as well according to `read-buffer' + ;; documentation. + (let ((pred (when predicate + (lambda (buffer) + (let ((buf (cons buffer (get-buffer buffer)))) + (condition-case _err + (funcall predicate buffer) + (wrong-type-argument + (funcall predicate buf)))))))) + (helm--completing-read-default + prompt (or minibuffer-completion-table + (internal-complete-buffer "" nil t)) + pred require-match nil nil default))) + +(defun helm-mode--get-default-handler-for (comp-or-file entry) + ;; Use 'comp for completing-read and 'file for 'read-file-name as + ;; COMP-OR-FILE value. + (let ((val (cdr-safe entry)) + (reading-file (eq comp-or-file 'file))) + (if (consp val) + (helm-acase (if reading-file (cadr val) (car val)) + (default (if reading-file + #'helm-read-file-name + #'helm-completing-read-default-handler)) + (t it)) + val))) (cl-defun helm--completing-read-default (prompt collection &optional @@ -1107,7 +1197,7 @@ See documentation of `completing-read' and `all-completions' for details." (buf-name (format "*helm-mode-%s*" str-command)) (entry (assq current-command helm-completing-read-handlers-alist)) - (def-com (cdr-safe entry)) + (def-com (helm-mode--get-default-handler-for 'comp entry)) (str-defcom (and def-com (helm-symbol-name def-com))) (def-args (list prompt collection predicate require-match initial-input hist def inherit-input-method)) @@ -1199,7 +1289,7 @@ See documentation of `completing-read' and `all-completions' for details." (prompt &key (name "Read File Name") - (initial-input default-directory) + initial-input (buffer "*Helm file completions*") test noret @@ -1217,6 +1307,7 @@ See documentation of `completing-read' and `all-completions' for details." (persistent-help "Hit1 Expand Candidate, Hit2 or (C-u) Find file") (mode-line helm-read-file-name-mode-line-string)) "Read a file name with helm completion. + It is helm `read-file-name' emulation. Argument PROMPT is the default prompt to use. @@ -1225,11 +1316,12 @@ Keys description: - NAME: Source name, default to \"Read File Name\". -- INITIAL-INPUT: Where to start reading file name, default to `default-directory'. +- INITIAL-INPUT: Where to start reading file name, + default to `default-directory' or $HOME. - BUFFER: `helm-buffer' name, defaults to \"*Helm Completions*\". -- TEST: A predicate called with one arg 'candidate'. +- TEST: A predicate called with one arg \\='candidate'. - NORET: Allow disabling helm-ff-RET (have no effect if helm-ff-RET isn't bound to RET). @@ -1240,7 +1332,7 @@ Keys description: - HISTORY: Display HISTORY in a special source. -- MUST-MATCH: Can be 'confirm, nil, or t. +- MUST-MATCH: Can be \\='confirm, nil, or t. - FUZZY: Enable fuzzy matching when non-nil (Enabled by default). @@ -1248,14 +1340,18 @@ Keys description: - NOMARK: When non--nil don't allow marking candidates. -- ALISTP: Don't use `all-completions' in history (take effect only on history). +- ALISTP: Don't use `all-completions' in history + (take effect only on history). - PERSISTENT-ACTION-IF: a persistent if action function. - PERSISTENT-HELP: persistent help message. -- MODE-LINE: A mode line message, default is `helm-read-file-name-mode-line-string'." +- MODE-LINE: A mode line message, default is + `helm-read-file-name-mode-line-string'." (require 'tramp) + (unless initial-input + (setq initial-input (or default-directory (getenv "HOME")))) (when (get-buffer helm-action-buffer) (kill-buffer helm-action-buffer)) (mapc (lambda (hook) @@ -1281,6 +1377,9 @@ Keys description: (helm-ff--RET-disabled noret) (minibuffer-completion-predicate test) (minibuffer-completing-file-name t) + ;; Ensure not being prompted for password each time we + ;; navigate to a directory. + (password-cache t) (helm--completing-file-name t) (helm-read-file-name-mode-line-string (replace-regexp-in-string "helm-maybe-exit-minibuffer" @@ -1336,8 +1435,10 @@ Keys description: (remhash helm-ff-default-directory helm-ff--list-directory-cache)) :match-on-real t - :filtered-candidate-transformer '(helm-ff-fct - helm-ff-sort-candidates) + :filtered-candidate-transformer (delq nil `(helm-ff-fct + helm-ff-sort-candidates + ,(and helm-ff-icon-mode + 'helm-ff-icons-transformer))) :persistent-action-if persistent-action-if :persistent-help persistent-help :volatile t @@ -1367,6 +1468,7 @@ Keys description: ((and result (stringp result) (file-equal-p result initial-input) + helm-read-file-name-use-default-arg-behavior default) (if (listp default) (car default) default)) ((and result (listp result)) @@ -1395,6 +1497,7 @@ Keys description: "Generic helm replacement of `read-file-name'. Don't use it directly, use instead `helm-read-file-name' in your programs." (let* ((init (or initial dir default-directory)) + (helm-read-file-name-use-default-arg-behavior t) (current-command (or (helm-this-command) this-command)) (str-command (if current-command (helm-symbol-name current-command) @@ -1405,7 +1508,7 @@ Don't use it directly, use instead `helm-read-file-name' in your programs." (buf-name (format "*helm-mode-%s*" str-command)) (entry (assq current-command helm-completing-read-handlers-alist)) - (def-com (cdr-safe entry)) + (def-com (helm-mode--get-default-handler-for 'file entry)) (str-defcom (and def-com (helm-symbol-name def-com))) ;; Don't modify the original args list for emacs generic functions. (def-args (list prompt dir default-filename mustmatch initial predicate)) @@ -1472,7 +1575,13 @@ Don't use it directly, use instead `helm-read-file-name' in your programs." ;; of INITIAL. ((and def-com helm-mode (not (eq def-com 'ido-read-file-name)) - (not (eq def-com 'incompatible))) + (not (eq def-com 'incompatible)) + ;; The entry in + ;; `helm-completing-read-handlers-alist' is + ;; a cons cell specifying a completing-read + ;; and a read-file-name handler default + ;; e.g. (foo (default default)). + (not (eq def-com 'helm-read-file-name))) (apply def-com others-args)) (;; Def-com value is `ido-read-file-name' ;; run it with default args. @@ -1563,32 +1672,55 @@ The `helm-find-files' history `helm-ff-history' is used here." (propertize str 'read-only t 'face 'helm-mode-prefix 'rear-nonsticky t) str)) -(defun helm-completion-in-region--initial-filter (comps afun file-comp-p) - "Add annotations at end of candidates and filter out dot files." +(defun helm--symbol-completion-table-affixation (completions) + "Same as `help--symbol-completion-table-affixation' but for helm. + +Return a list of cons cells of the form (disp . real)." + (mapcar (lambda (c) + (let* ((s (intern c)) + (doc (ignore-errors + (helm-get-first-line-documentation s)))) + (cons (concat (propertize + (format "%-4s" (help--symbol-class s)) + 'face 'completions-annotations) + c + (if doc + (propertize (format " -- %s" doc) + 'face 'completions-annotations) + "")) + c))) + completions)) + +(defun helm-completion-in-region--initial-filter (comps afun afix file-comp-p) + "Compute COMPS with function AFUN or AFIX unless FILE-COMP-P non nil. + +If both AFUN and AFIX are provided only AFIX is used. +When FILE-COMP-P is provided only filter out dot files." (if file-comp-p ;; Filter out dot files in file completion. (cl-loop for f in comps unless (string-match "\\`\\.\\{1,2\\}/\\'" f) collect f) - (if afun - ;; Add annotation at end of - ;; candidate if needed, e.g. foo, this happen when - ;; completing against a quoted symbol. - (mapcar (lambda (s) - (let ((ann (funcall afun s))) - (if ann - (cons - (concat - s - (propertize - " " 'display - (propertize - ann - 'face 'completions-annotations))) - s) - s))) - comps) - comps))) + (cond (afix (helm--symbol-completion-table-affixation comps)) + (afun + ;; Add annotation at end of + ;; candidate if needed, e.g. foo, this happen when + ;; completing against a quoted symbol. + (mapcar (lambda (s) + (let ((ann (funcall afun s))) + (if ann + (cons + (concat + s + (propertize + " " 'display + (propertize + ann + 'face 'completions-annotations))) + s) + s))) + comps)) + (t comps)))) ;; Helm multi matching style @@ -1725,19 +1857,6 @@ Actually does nothing." (when all (nconc (helm-flex-add-score-as-prop all regexp) (length prefix))))))) -(defun helm-flex-add-score-as-prop (candidates regexp) - (cl-loop with case-fold-search = (helm-set-case-fold-search) - for cand in candidates - collect (helm-flex--style-score cand regexp))) - -(defun helm-completion--flex-transform-pattern (pattern) - ;; "fob" => '(prefix "f" any "o" any "b" any point) - (cl-loop for p in pattern - if (stringp p) nconc - (cl-loop for str across p - nconc (list (string str) 'any)) - else nconc (list p))) - ;; Same as emacs-27 completion-substring--all-completions. (defun helm-completion--flex-all-completions (string table pred point &optional transform-pattern-fn) @@ -1829,6 +1948,10 @@ Can be used for `completion-in-region-function' by advicing it with an ;; See Bug#407. (afun (or (plist-get completion-extra-properties :annotation-function) (completion-metadata-get metadata 'annotation-function))) + ;; Not sure if affixations are provided in + ;; completion-in-region, try anyway never know. + (afix (or (plist-get completion-extra-properties :affixation-function) + (completion-metadata-get metadata 'affixation-function))) (init-space-suffix (unless (or (memq helm-completion-style '(helm-fuzzy emacs)) (string-suffix-p " " input) (string= input "")) @@ -1891,7 +2014,7 @@ Can be used for `completion-in-region-function' by advicing it with an (if (and sort-fn (> (length str) 0)) (funcall sort-fn all) all) - afun file-comp-p)))) + afun afix file-comp-p)))) (data (if (memq helm-completion-style '(helm helm-fuzzy)) (funcall compfn input nil nil) compfn)) @@ -2088,7 +2211,8 @@ Note: This mode is incompatible with Emacs23." ;; emacs-27 and `ffap-read-file-or-url' is fixed, so no need ;; to advice it. (advice-add 'ffap-read-file-or-url :override #'helm-advice--ffap-read-file-or-url)) - (advice-add 'read-buffer-to-switch :override #'helm-mode--read-buffer-to-switch)) + (advice-add 'read-buffer-to-switch :override #'helm-mode--read-buffer-to-switch) + (helm-minibuffer-history-mode 1)) (progn (remove-function completing-read-function #'helm--completing-read-default) (remove-function read-file-name-function #'helm--generic-read-file-name) @@ -2097,7 +2221,8 @@ Note: This mode is incompatible with Emacs23." (remove-hook 'ido-everywhere-hook #'helm-mode--ido-everywhere-hook) (when (fboundp 'ffap-read-file-or-url-internal) (advice-remove 'ffap-read-file-or-url #'helm-advice--ffap-read-file-or-url)) - (advice-remove 'read-buffer-to-switch #'helm-mode--read-buffer-to-switch)))) + (advice-remove 'read-buffer-to-switch #'helm-mode--read-buffer-to-switch) + (helm-minibuffer-history-mode -1)))) (provide 'helm-mode) diff --git a/elpa/helm-20210729.1510/helm-net.el b/elpa/helm-20220616.1004/helm-net.el similarity index 89% rename from elpa/helm-20210729.1510/helm-net.el rename to elpa/helm-20220616.1004/helm-net.el index 6af15523..e60e9cad 100644 --- a/elpa/helm-20210729.1510/helm-net.el +++ b/elpa/helm-20220616.1004/helm-net.el @@ -1,6 +1,6 @@ ;;; helm-net.el --- helm browse url and search web. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -142,13 +142,14 @@ This is a format string, don't forget the `%s'." :group 'helm-net :type '(alist :key-type string :value-type function)) -(defcustom helm-browse-url-firefox-new-window "-new-tab" +(defcustom helm-browse-url-firefox-new-window "--new-tab" "Allow choosing to browse url in new window or new tab. -Can be \"-new-tab\" (default) or \"-new-window\"." +Can be \"--new-tab\" (default), \"--new-window\" or \"--private-window\"." :group 'helm-net :type '(radio - (const :tag "New tab" "-new-tab") - (const :tag "New window" "-new-window"))) + (const :tag "New tab" "--new-tab") + (const :tag "New window" "--new-window") + (const :tag "New private window" "--private-window"))) (defcustom helm-net-curl-switches '("-s" "-L") "Arguments list passed to curl when using `helm-net-prefer-curl'." @@ -262,22 +263,24 @@ Can be \"-new-tab\" (default) or \"-new-window\"." (defvar helm-browse-url-nyxt-program "nyxt") (defvar helm-browse-url-conkeror-program "conkeror") (defvar helm-browse-url-opera-program "opera") +(defvar helm-browse-url-w3m-program (or (and (boundp 'w3m-command) w3m-command) + (executable-find "w3m"))) (defvar helm-browse-url-default-browser-alist - `((,(or (and (boundp 'w3m-command) w3m-command) - "/usr/bin/w3m") . w3m-browse-url) - (,browse-url-firefox-program . browse-url-firefox) - (,helm-browse-url-chromium-program . helm-browse-url-chromium) - (,helm-browse-url-conkeror-program . helm-browse-url-conkeror) - (,helm-browse-url-opera-program . helm-browse-url-opera) - (,helm-browse-url-uzbl-program . helm-browse-url-uzbl) - (,browse-url-kde-program . browse-url-kde) - (,browse-url-gnome-moz-program . browse-url-gnome-moz) - (,browse-url-mozilla-program . browse-url-mozilla) - (,browse-url-galeon-program . browse-url-galeon) - (,browse-url-netscape-program . browse-url-netscape) - (,browse-url-xterm-program . browse-url-text-xterm) + '((helm-browse-url-w3m-program . w3m-browse-url) + (browse-url-firefox-program . browse-url-firefox) + (helm-browse-url-chromium-program . helm-browse-url-chromium) + (helm-browse-url-conkeror-program . helm-browse-url-conkeror) + (helm-browse-url-opera-program . helm-browse-url-opera) + (helm-browse-url-uzbl-program . helm-browse-url-uzbl) + (helm-browse-url-nyxt-program . helm-browse-url-nyxt) + (browse-url-kde-program . browse-url-kde) + (browse-url-gnome-moz-program . browse-url-gnome-moz) + (browse-url-mozilla-program . browse-url-mozilla) + (browse-url-galeon-program . browse-url-galeon) + (browse-url-netscape-program . browse-url-netscape) + (browse-url-xterm-program . browse-url-text-xterm) ("emacs" . eww-browse-url)) - "*Alist of \(executable . function\) to try to find a suitable url browser.") + "Alist of (browse_url_variable . function) to try to find a suitable url browser.") (cl-defun helm-generic-browser (url cmd-name &rest args) "Browse URL with NAME browser." @@ -346,15 +349,18 @@ NOTE: Probably not supported on some systems (e.g., Windows)." ;;;###autoload (defun helm-browse-url-nyxt (url &optional _ignore) - "Browse URL with next browser." + "Browse URL with nyxt browser." (interactive "sURL: ") (helm-generic-browser url helm-browse-url-nyxt-program)) (defun helm-browse-url-default-browser (url &rest args) "Find the first available browser and ask it to load URL." (let ((default-browser-fn - (cl-loop for (exe . fn) in helm-browse-url-default-browser-alist - thereis (and exe (executable-find exe) (fboundp fn) fn)))) + (cl-loop for (var . fn) in helm-browse-url-default-browser-alist + for exe = (if (stringp var) + var + (and (boundp var) (symbol-value var))) + thereis (and exe (executable-find exe) (fboundp fn) fn)))) (if default-browser-fn (apply default-browser-fn url args) (error "No usable browser found")))) @@ -402,8 +408,7 @@ NOTE: Probably not supported on some systems (e.g., Windows)." (helm-build-elvi-list) :must-match t :name "Surfraw Search Engines" - :del-input nil - :history helm-surfraw-engines-history))) + :history 'helm-surfraw-engines-history))) (let* ((engine-nodesc (car (split-string engine))) (url (if (string= engine-nodesc "duckduckgo") ;; "sr duckduckgo -p foo" is broken, workaround. @@ -418,9 +423,7 @@ NOTE: Probably not supported on some systems (e.g., Windows)." browse-url-browser-function))) (if (string= engine-nodesc "W") (helm-browse-url helm-home-url) - (helm-browse-url url) - (setq helm-surfraw-engines-history - (cons engine (delete engine helm-surfraw-engines-history)))))) + (helm-browse-url url)))) ;;;###autoload (defun helm-google-suggest () diff --git a/elpa/helm-20210729.1510/helm-occur.el b/elpa/helm-20220616.1004/helm-occur.el similarity index 92% rename from elpa/helm-20210729.1510/helm-occur.el rename to elpa/helm-20220616.1004/helm-occur.el index 40fa6180..9fccfcdd 100644 --- a/elpa/helm-20210729.1510/helm-occur.el +++ b/elpa/helm-20220616.1004/helm-occur.el @@ -1,6 +1,6 @@ ;;; helm-occur.el --- Incremental Occur for Helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -126,7 +126,13 @@ Note that when using `buffer-substring' initialization will be slower." (defcustom helm-occur-keep-closest-position t "When non nil select closest candidate from point after update. -This happen only in `helm-source-occur' which is always related to `current-buffer'." +This happen only in `helm-source-occur' which is always related to +`current-buffer'." + :group 'helm-regexp + :type 'boolean) + +(defcustom helm-occur-ignore-diacritics nil + "When non nil helm-occur will ignore diacritics in patterns." :group 'helm-regexp :type 'boolean) @@ -246,23 +252,29 @@ engine beeing completely different and also much faster." (defun helm-occur-transformer (candidates source) "Return CANDIDATES prefixed with line number." (cl-loop with buf = (helm-get-attr 'buffer-name source) - for c in candidates collect - (when (string-match helm-occur--search-buffer-regexp c) - (let ((linum (match-string 1 c)) - (disp (match-string 2 c))) - (cons (format "%s:%s" - (propertize - linum 'face 'helm-grep-lineno - 'help-echo (buffer-file-name - (get-buffer buf))) - disp) - (string-to-number linum)))))) + for c in candidates + for cand = (when (string-match helm-occur--search-buffer-regexp c) + (let ((linum (match-string 1 c)) + (disp (match-string 2 c))) + (when (and disp (not (string= disp ""))) + (cons (concat + (propertize " " 'display + (concat + (propertize + linum 'face 'helm-grep-lineno + 'help-echo (buffer-file-name + (get-buffer buf))) + ":")) + disp) + (string-to-number linum))))) + when cand collect cand)) (defclass helm-moccur-class (helm-source-in-buffer) ((buffer-name :initarg :buffer-name :initform nil) (moccur-buffers :initarg :moccur-buffers - :initform nil))) + :initform nil) + (find-file-target :initform #'helm-occur-quit-an-find-file-fn))) (defun helm-occur-build-sources (buffers &optional source-name) "Build sources for `helm-occur' for each buffer in BUFFERS list." @@ -283,6 +295,7 @@ engine beeing completely different and also much faster." (when (string-match helm-occur--search-buffer-regexp candidate) (match-string 2 candidate))) + :diacritics helm-occur-ignore-diacritics :search (lambda (pattern) (when (string-match "\\`\\^\\([^ ]*\\)" pattern) (setq pattern (concat "^[0-9]* \\{1\\}" (match-string 1 pattern)))) @@ -445,6 +458,13 @@ persistent action." (helm-execute-persistent-action))) (put 'helm-occur-right 'helm-only t) +(defun helm-occur-quit-an-find-file-fn (source) + (let* ((sel (helm-get-selection nil nil source)) + (occur-fname (helm-aand (numberp sel) + (helm-get-attr 'buffer-name) + (buffer-file-name (get-buffer it))))) + (when (and occur-fname (file-exists-p occur-fname)) + (expand-file-name occur-fname)))) ;;; helm-occur-mode ;; @@ -575,7 +595,7 @@ persistent action." (defun helm-occur-buffer-substring-with-linums () "Return current-buffer contents as a string with all lines -numbered. The property 'buffer-name is added to the whole string." +numbered. The property \\='buffer-name is added to the whole string." (let ((bufstr (buffer-substring-no-properties (point-min) (point-max))) (bufname (buffer-name))) (with-temp-buffer @@ -676,9 +696,29 @@ Special commands: (set (make-local-variable 'revert-buffer-function) #'helm-occur-mode--revert-buffer-function) (set (make-local-variable 'helm-occur-mode--last-pattern) - helm-input)) + helm-input) + (set (make-local-variable 'next-error-function) + #'helm-occur-next-error)) (put 'helm-moccur-mode 'helm-only t) +(defun helm-occur-next-error (&optional argp reset) + "Goto ARGP position from a `helm-occur-mode' buffer. +RESET non-nil means rewind to the first match. +This is the `next-error-function' for `helm-occur-mode'." + (interactive "p") + (goto-char (cond (reset (point-min)) + ((< argp 0) (line-beginning-position)) + ((> argp 0) (line-end-position)) + ((point)))) + (let ((fun (if (> argp 0) + #'next-single-property-change + #'previous-single-property-change))) + (helm-aif (funcall fun (point) 'buffer-name) + (progn + (goto-char it) + (forward-line 0) + (helm-occur-mode-goto-line)) + (user-error "No more matches")))) ;;; Resume ;; diff --git a/elpa/helm-20220616.1004/helm-pkg.el b/elpa/helm-20220616.1004/helm-pkg.el new file mode 100644 index 00000000..30e2092b --- /dev/null +++ b/elpa/helm-20220616.1004/helm-pkg.el @@ -0,0 +1,11 @@ +(define-package "helm" "20220616.1004" "Helm is an Emacs incremental and narrowing framework" + '((helm-core "3.8.4") + (popup "0.5.3")) + :commit "a6df31a7cff0c64b8b999a85cbf5b4cc253a104f" :authors + '(("Thierry Volpiatto ")) + :maintainer + '("Thierry Volpiatto ") + :url "https://emacs-helm.github.io/helm/") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/helm-20210729.1510/helm-regexp.el b/elpa/helm-20220616.1004/helm-regexp.el similarity index 98% rename from elpa/helm-20210729.1510/helm-regexp.el rename to elpa/helm-20220616.1004/helm-regexp.el index f5dd4543..eea6e671 100644 --- a/elpa/helm-20210729.1510/helm-regexp.el +++ b/elpa/helm-20220616.1004/helm-regexp.el @@ -1,6 +1,6 @@ ;;; helm-regexp.el --- In buffer regexp searching and replacement for helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by diff --git a/elpa/helm-20210729.1510/helm-ring.el b/elpa/helm-20220616.1004/helm-ring.el similarity index 99% rename from elpa/helm-20210729.1510/helm-ring.el rename to elpa/helm-20220616.1004/helm-ring.el index aa44e4e5..6459ba39 100644 --- a/elpa/helm-20210729.1510/helm-ring.el +++ b/elpa/helm-20220616.1004/helm-ring.el @@ -1,6 +1,6 @@ ;;; helm-ring.el --- kill-ring, mark-ring, and register browsers for helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -495,7 +495,8 @@ This is a command for `helm-kill-ring-map'." ;;;###autoload (defun helm-all-mark-rings () - "Preconfigured `helm' for `helm-source-global-mark-ring' and \ + "Preconfigured `helm' for mark rings. +Source used are `helm-source-global-mark-ring' and `helm-source-mark-ring'." (interactive) (helm :sources '(helm-source-mark-ring diff --git a/elpa/helm-20210729.1510/helm-semantic.el b/elpa/helm-20220616.1004/helm-semantic.el similarity index 99% rename from elpa/helm-20210729.1510/helm-semantic.el rename to elpa/helm-20220616.1004/helm-semantic.el index 07d15082..46870294 100644 --- a/elpa/helm-20210729.1510/helm-semantic.el +++ b/elpa/helm-20220616.1004/helm-semantic.el @@ -1,7 +1,7 @@ ;;; helm-semantic.el --- Helm interface for Semantic -*- lexical-binding: t -*- ;; Copyright (C) 2012 ~ 2017 Daniel Hackney -;; 2012 ~ 2020 Thierry Volpiatto +;; 2012 ~ 2021 Thierry Volpiatto ;; Author: Daniel Hackney diff --git a/elpa/helm-20210729.1510/helm-shell.el b/elpa/helm-20220616.1004/helm-shell.el similarity index 100% rename from elpa/helm-20210729.1510/helm-shell.el rename to elpa/helm-20220616.1004/helm-shell.el diff --git a/elpa/helm-20210729.1510/helm-sys.el b/elpa/helm-20220616.1004/helm-sys.el similarity index 96% rename from elpa/helm-20210729.1510/helm-sys.el rename to elpa/helm-20220616.1004/helm-sys.el index d4ec6053..fcd36583 100644 --- a/elpa/helm-20210729.1510/helm-sys.el +++ b/elpa/helm-20220616.1004/helm-sys.el @@ -1,6 +1,6 @@ ;;; helm-sys.el --- System related functions for helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -41,20 +41,20 @@ "Top command used to display output of top. A format string where %s will be replaced with `frame-width'. -To use 'top' command, a version supporting batch mode (-b option) -is needed. On Mac OSX 'top' command doesn't support this, so the +To use \\='top' command, a version supporting batch mode (-b option) +is needed. On Mac OSX \\='top' command doesn't support this, so the 'ps' command is used instead by default. -Normally 'top' command output have 12 columns, but in some +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 +top to use 12 columns with the interactives \\='f' and \\='W' commands of top, or modify `helm-top-sort-columns-alist' to fit with the -number of columns your 'top' command is using. +number of columns your \\='top' command is using. -If you modify 'ps' command be sure that 'pid' comes in first and +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 +not start). 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 @@ -65,9 +65,10 @@ properly according to your settings." (cpu . 8) (user . 1)) "Allow defining which column to use when sorting output of top/ps command. -Only com, mem, cpu and user are sorted, so no need to put something else there, -it will have no effect. -Note that column numbers are counted from zero, i.e. column 1 is the nth 0 column." +Only com, mem, cpu and user are sorted, so no need to put something +else there,it will have no effect. +Note that column numbers are counted from zero, i.e. column 1 is the +nth 0 column." :group 'helm-sys :type '(alist :key-type symbol :value-type (integer :tag "Column number"))) @@ -86,7 +87,7 @@ being idle." (defcustom helm-top-poll-preselection 'linum "Stay on same line or follow candidate when `helm-top-poll' updates display. -Possible values are 'candidate or 'linum. +Possible values are \\='candidate or \\='linum. This affects also sorting functions in the same way." :group'helm-sys :type '(radio :tag "Preferred preselection action for helm-top" diff --git a/elpa/helm-20210729.1510/helm-tags.el b/elpa/helm-20220616.1004/helm-tags.el similarity index 97% rename from elpa/helm-20210729.1510/helm-tags.el rename to elpa/helm-20220616.1004/helm-tags.el index 47a2ad82..f977aae5 100644 --- a/elpa/helm-20210729.1510/helm-tags.el +++ b/elpa/helm-20220616.1004/helm-tags.el @@ -1,6 +1,6 @@ ;;; helm-tags.el --- Helm for Etags. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -24,7 +24,7 @@ (require 'helm-grep) (defvar helm-etags-fuzzy-match) -(declare-function ring-insert "ring") +(declare-function xref-push-marker-stack "xref") (defgroup helm-tags nil @@ -45,7 +45,7 @@ Don't search tag file deeply if outside this value." (defcustom helm-etags-match-part-only 'tag "Allow choosing the tag part of CANDIDATE in `helm-source-etags-select'. A tag looks like this: - filename: \(defun foo + filename: (defun foo You can choose matching against the tag part (i.e \"(defun foo\"), or against the whole candidate (i.e \"(filename:5:(defun foo\")." :type '(choice @@ -122,8 +122,10 @@ Look recursively in parents directorys for a (expand-file-name helm-etags-tag-file-name current-dir)))) (defun helm-etags-all-tag-files () - "Return files from the following sources: - 1) An automatically located file in the parent directories, by `helm-etags-get-tag-file'. + "Find Etags files. +Return files from the following sources: + 1) An automatically located file in the parent directories, + by `helm-etags-get-tag-file'. 2) `tags-file-name', which is commonly set by `find-tag' command. 3) `tags-table-list' which is commonly set by `visit-tags-table' command." (helm-fast-remove-dups @@ -253,8 +255,6 @@ If there is no entry in cache, create one." (setq helm-source-etags-select (helm-etags-build-source)))) -(defvar find-tag-marker-ring) - (defsubst helm-etags--file-from-tag (fname) (cl-loop for ext in (cons "" (remove "" tags-compression-info-list)) @@ -278,7 +278,7 @@ If there is no entry in cache, create one." (linum (string-to-number (cadr split)))) (if (null fname) (error "file %s not found" fname) - (ring-insert find-tag-marker-ring (point-marker)) + (xref-push-marker-stack) (funcall switcher fname) (helm-goto-line linum t) (when (search-forward elm nil t) diff --git a/elpa/helm-20210729.1510/helm-types.el b/elpa/helm-20220616.1004/helm-types.el similarity index 96% rename from elpa/helm-20210729.1510/helm-types.el rename to elpa/helm-20220616.1004/helm-types.el index 3ec05d90..887711e9 100644 --- a/elpa/helm-20210729.1510/helm-types.el +++ b/elpa/helm-20220616.1004/helm-types.el @@ -1,8 +1,8 @@ ;;; helm-types.el --- Helm types classes and methods. -*- lexical-binding: t -*- -;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto -;; Author: Thierry Volpiatto +;; Author: Thierry Volpiatto ;; URL: http://github.com/emacs-helm/helm ;; This program is free software; you can redistribute it and/or modify @@ -170,10 +170,12 @@ "Switch to buffer(s)" 'helm-buffer-switch-buffers "Switch to buffer(s) other window `C-c o'" 'helm-buffer-switch-buffers-other-window - "Switch to buffer other frame `C-c C-o'" - 'switch-to-buffer-other-frame + "Switch to buffer(s) other frame `C-c C-o'" + 'helm-buffer-switch-to-buffer-other-frame + "Raise buffer frame maybe" + 'helm-buffers-maybe-raise-buffer-frame (lambda () (and (fboundp 'tab-bar-mode) - "Switch to buffer other tab `C-c C-t'")) + "Switch to buffer(s) other tab `C-c C-t'")) 'helm-buffers-switch-to-buffer-other-tab "Switch to buffer at line number" 'helm-switch-to-buffer-at-linum @@ -227,9 +229,7 @@ (defcustom helm-type-function-actions (helm-make-actions "Describe function" 'helm-describe-function - "Find function" (if (fboundp 'xref-find-definitions) - ;; Find-function is broken in emacs-27. - 'xref-find-definitions 'find-function) + "Find function" 'helm-find-function "Info lookup" 'helm-info-lookup-symbol "Debug on entry" 'debug-on-entry "Cancel debug on entry" 'cancel-debug-on-entry diff --git a/elpa/helm-20210729.1510/helm-utils.el b/elpa/helm-20220616.1004/helm-utils.el similarity index 92% rename from elpa/helm-20210729.1510/helm-utils.el rename to elpa/helm-20220616.1004/helm-utils.el index ca3cd905..048bc5dc 100644 --- a/elpa/helm-20210729.1510/helm-utils.el +++ b/elpa/helm-20220616.1004/helm-utils.el @@ -1,6 +1,6 @@ ;;; helm-utils.el --- Utilities Functions for helm. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -45,7 +45,7 @@ (defvar helm-buffers-maybe-switch-to-tab) (defvar helm-ff-transformer-show-only-basename) (defvar helm-popup-tip-mode) - +(defvar helm-ff-last-expanded-candidate-regexp) (defgroup helm-utils nil @@ -85,10 +85,11 @@ Possible value are: (integer :tag "Match after")) (const :tag "Match in line only" 0) (integer :tag "Match after or before (+/-)") - (const :tag "Never match" 'never))) + (const :tag "Never match" never))) (defcustom helm-buffers-to-resize-on-pa nil - "A list of helm buffers where the helm-window should be reduced on persistent actions." + "A list of helm buffers where the helm-window should be reduced on PA. +Where PA means persistent action." :group 'helm-utils :type '(repeat (choice string))) @@ -104,8 +105,9 @@ Possible value are: (defcustom helm-html-decode-entities-function #'helm-html-decode-entities-string "Function used to decode HTML entities in HTML bookmarks. -Helm comes by default with `helm-html-decode-entities-string', if you need something -more sophisticated you can use `w3m-decode-entities-string' if available. +Helm comes by default with `helm-html-decode-entities-string', if +you need something more sophisticated you can use +`w3m-decode-entities-string' if available. In Emacs itself org-entities seem broken and `xml-substitute-numeric-entities' supports only numeric entities." @@ -579,71 +581,42 @@ from its directory." (require 'helm-grep) (require 'helm-elisp) (require 'bookmark) ; For bookmark-alist - (helm-run-after-exit - (lambda (f) - ;; Ensure specifics `helm-execute-action-at-once-if-one' - ;; fns don't run here. - (let (helm-execute-action-at-once-if-one - helm-actions-inherit-frame-settings) ; use this-command - (if (file-exists-p f) - (helm-find-files-1 (file-name-directory f) - (concat - "^" - (regexp-quote - (if helm-ff-transformer-show-only-basename - (helm-basename f) f)))) + (let ((src (helm-get-current-source))) + (helm-run-after-exit + (lambda (f) + ;; Ensure specifics `helm-execute-action-at-once-if-one' + ;; fns don't run here. + (let (helm-execute-action-at-once-if-one + helm-actions-inherit-frame-settings) ; use this-command + (if (file-exists-p f) + (helm-find-files-1 (file-name-directory f) + (format + helm-ff-last-expanded-candidate-regexp + (regexp-quote + (if helm-ff-transformer-show-only-basename + (helm-basename f) f)))) (helm-find-files-1 f)))) - (let* ((sel (helm-get-selection)) - (marker (and (consp sel) (markerp (cdr sel)))) - (grep-line (and (stringp sel) - (helm-grep-split-line sel))) - (occur-fname (helm-aand (numberp sel) - (helm-get-attr 'buffer-name) - (buffer-file-name (get-buffer it)))) - (bmk-name (and (stringp sel) - (not grep-line) - (replace-regexp-in-string "\\`\\*" "" sel))) - (bmk (and bmk-name (assoc bmk-name bookmark-alist))) - (buf (helm-aif (and (bufferp sel) (get-buffer sel)) - (buffer-name it))) - (pkg (and (stringp sel) - (get-text-property 0 'tabulated-list-id sel))) - (default-preselection (or (buffer-file-name helm-current-buffer) - default-directory))) - (cond - ;; Buffer. - (buf (or (buffer-file-name sel) - (car (rassoc buf dired-buffers)) - (and (with-current-buffer buf - (eq major-mode 'org-agenda-mode)) - org-directory - (expand-file-name org-directory)) - (with-current-buffer buf - (expand-file-name default-directory)))) - ;; imenu (marker). - (marker - (or (buffer-file-name (marker-buffer (cdr sel))) - default-preselection)) - ;; Bookmark. - (bmk (helm-aif (bookmark-get-filename bmk) - (if (and helm--url-regexp - (string-match helm--url-regexp it)) - it (expand-file-name it)) - (expand-file-name default-directory))) + (helm--quit-and-find-file-default-file src))))) +(put 'helm-quit-and-find-file 'helm-only t) + +(defun helm--quit-and-find-file-default-file (source) + (let ((target-fn (helm-get-attr 'find-file-target))) + ;; target-fn function may return nil, in this case fallback to default. + (helm-aif (and target-fn (funcall target-fn source)) + it + (let* ((sel (helm-get-selection nil nil source)) + (default-preselection (or (helm-default-directory) + (buffer-file-name helm-current-buffer) + default-directory))) + (cond ((and (stringp sel) (or (file-remote-p sel) (file-exists-p sel))) (expand-file-name sel)) - ;; Grep. - ((and grep-line (file-exists-p (car grep-line))) - (expand-file-name (car grep-line))) - ;; Occur. - ((and occur-fname (file-exists-p occur-fname)) - (expand-file-name occur-fname)) - ;; Package (installed). - ((and pkg (package-installed-p pkg)) - (expand-file-name (package-desc-dir pkg))) ;; Url. - ((and (stringp sel) helm--url-regexp (string-match helm--url-regexp sel)) sel) + ((and (stringp sel) + helm--url-regexp + (string-match helm--url-regexp sel)) + sel) ;; Exit brutally from a `with-helm-show-completion' ((and helm-show-completion-overlay (overlayp helm-show-completion-overlay)) @@ -652,11 +625,10 @@ from its directory." (expand-file-name default-preselection)) ;; Default. (t (expand-file-name default-preselection))))))) -(put 'helm-quit-and-find-file 'helm-only t) (defun helm-generic-sort-fn (s1 s2) "Sort predicate function for helm candidates. -Args S1 and S2 can be single or \(display . real\) candidates, +Args S1 and S2 can be single or (display . real) candidates, that is sorting is done against real value of candidate." (let* ((qpattern (regexp-quote helm-pattern)) (reg1 (concat "\\_<" qpattern "\\_>")) @@ -747,14 +719,14 @@ Availables keys are: - GID-CHANGE: See nth 9 `files-attributes'. - INODE: See nth 10 `files-attributes'. - DEVICE-NUM: See nth 11 `files-attributes'. -- DIRED: A line similar to what 'ls -l' return. +- DIRED: A line similar to what \\='ls -l' return. - HUMAN-SIZE: The size in human form, see `helm-file-human-size'. - MODE-TYPE, mode-owner,mode-group, mode-other: Split what nth 7 `files-attributes' return in four categories. - STRING: When non--nil (default) `helm-file-attributes' return more friendly values. If you want the same behavior as `files-attributes' , -\(but with return values in proplist\) use a nil value for STRING. +\(but with return values in proplist) use a nil value for STRING. However when STRING is non--nil, time and type value are different from what you have in `file-attributes'." (helm-aif (file-attributes file string) @@ -1070,10 +1042,6 @@ If FILE is a directory, open this directory." (dired (file-name-directory file)) (dired-goto-file file))) -(defun helm-require-or-error (feature function) - (or (require feature nil t) - (error "Need %s to use `%s'." feature function))) - (defun helm-find-file-as-root (candidate) (let* ((buf (helm-basename candidate)) (host (file-remote-p candidate 'host)) diff --git a/elpa/helm-20210729.1510/helm-x-files.el b/elpa/helm-20220616.1004/helm-x-files.el similarity index 94% rename from elpa/helm-20210729.1510/helm-x-files.el rename to elpa/helm-20220616.1004/helm-x-files.el index dad5876e..17c35e7b 100644 --- a/elpa/helm-20210729.1510/helm-x-files.el +++ b/elpa/helm-20220616.1004/helm-x-files.el @@ -1,6 +1,6 @@ ;;; helm-x-files.el --- helm auxiliary functions and sources. -*- lexical-binding: t -*- -;; Copyright (C) 2012 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2012 ~ 2021 Thierry Volpiatto ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -56,8 +56,8 @@ (or (string-match helm-tramp-file-name-regexp f) (file-exists-p f))) (mapcar 'car session-file-alist)))) - (keymap :initform helm-generic-files-map) - (help-message :initform helm-generic-file-help-message) + (keymap :initform 'helm-generic-files-map) + (help-message :initform 'helm-generic-file-help-message) (action :initform 'helm-type-file-actions))) (defvar helm-source-session nil @@ -107,8 +107,7 @@ :action-transformer '(helm-transform-file-load-el helm-transform-file-browse-url) :requires-pattern 3) - "Source for retrieving files matching the current input pattern \ -with the tracker desktop search.") + "Source for the Tracker desktop search engine.") ;; Spotlight (MacOS X desktop search) (defclass helm-mac-spotlight-source (helm-source-async helm-type-file) diff --git a/elpa/helm-20220616.1004/helm.el b/elpa/helm-20220616.1004/helm.el new file mode 100644 index 00000000..191aa538 --- /dev/null +++ b/elpa/helm-20220616.1004/helm.el @@ -0,0 +1,43 @@ +;;; helm.el --- Helm is an Emacs incremental and narrowing framework -*- lexical-binding: t -*- + +;; Copyright (C) 2007 Tamas Patrovics +;; 2008 ~ 2011 rubikitch +;; 2011 ~ 2021 Thierry Volpiatto + +;; This is a fork of anything.el wrote by Tamas Patrovics. + +;; Authors of anything.el: Tamas Patrovics +;; rubikitch +;; Thierry Volpiatto + +;; Author: Thierry Volpiatto +;; Version: 3.8.5 +;; URL: https://emacs-helm.github.io/helm/ +;; Package-Requires: ((helm-core "3.8.4") (popup "0.5.3")) + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This is just a wrapper for helm-core.el and a place holder we +;; currently use only to hold the package's metadata in the header. + +;;; Code: + +(require 'helm-core) +(require 'helm-global-bindings) + +(provide 'helm) + +;;; helm.el ends here diff --git a/elpa/helm-core-20210128.1814/helm-core-pkg.el b/elpa/helm-core-20210128.1814/helm-core-pkg.el deleted file mode 100644 index 61921426..00000000 --- a/elpa/helm-core-20210128.1814/helm-core-pkg.el +++ /dev/null @@ -1,7 +0,0 @@ -(define-package "helm-core" "20210128.1814" "Development files for Helm" - '((emacs "25.1") - (async "1.9.4")) - :commit "7023ed51ee839806adb07537e23351326ce04fd2") -;; Local Variables: -;; no-byte-compile: t -;; End: diff --git a/elpa/helm-core-20210128.1814/helm-core-autoloads.el b/elpa/helm-core-20220607.1243/helm-core-autoloads.el similarity index 84% rename from elpa/helm-core-20210128.1814/helm-core-autoloads.el rename to elpa/helm-core-20220607.1243/helm-core-autoloads.el index 7d831568..f210aeb6 100644 --- a/elpa/helm-core-20210128.1814/helm-core-autoloads.el +++ b/elpa/helm-core-20220607.1243/helm-core-autoloads.el @@ -1,4 +1,4 @@ -;;; helm-core-autoloads.el --- automatically extracted autoloads +;;; helm-core-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*- ;; ;;; Code: @@ -6,13 +6,13 @@ (or (file-name-directory #$) (car load-path)))) -;;;### (autoloads nil "helm" "helm.el" (0 0 0 0)) -;;; Generated autoloads from helm.el +;;;### (autoloads nil "helm-core" "helm-core.el" (0 0 0 0)) +;;; Generated autoloads from helm-core.el -(autoload 'helm-configuration "helm" "\ +(autoload 'helm-configuration "helm-core" "\ Customize Helm." t nil) -(autoload 'helm-define-multi-key "helm" "\ +(autoload 'helm-define-multi-key "helm-core" "\ In KEYMAP, define key sequence KEY for function list FUNCTIONS. Each function runs sequentially for each KEY press. If DELAY is specified, switch back to initial function of FUNCTIONS list @@ -29,7 +29,7 @@ E.g. (interactive) (message \"Run baz\")) -\(helm-define-multi-key global-map (kbd \" q\") '(foo bar baz) 2) +\(helm-define-multi-key global-map (kbd \" q\") \\='(foo bar baz) 2) Each time \" q\" is pressed, the next function is executed. Waiting more than 2 seconds between key presses switches back to @@ -37,7 +37,7 @@ executing the first function on the next hit. \(fn KEYMAP KEY FUNCTIONS &optional DELAY)" nil nil) -(autoload 'helm-multi-key-defun "helm" "\ +(autoload 'helm-multi-key-defun "helm-core" "\ Define NAME as a multi-key command running FUNS. After DELAY seconds, the FUNS list is reinitialized. See `helm-define-multi-key'. @@ -46,7 +46,7 @@ See `helm-define-multi-key'. (function-put 'helm-multi-key-defun 'lisp-indent-function '2) -(autoload 'helm-define-key-with-subkeys "helm" "\ +(autoload 'helm-define-key-with-subkeys "helm-core" "\ Define in MAP a KEY and SUBKEY to COMMAND. This allows typing KEY to call COMMAND the first time and @@ -59,8 +59,8 @@ Arg OTHER-SUBKEYS is an alist specifying other short key bindings to use once started, e.g.: (helm-define-key-with-subkeys global-map - (kbd \"C-x v n\") ?n 'git-gutter:next-hunk - '((?p . git-gutter:previous-hunk))) + (kbd \"C-x v n\") ?n \\='git-gutter:next-hunk + \\='((?p . git-gutter:previous-hunk))) In this example, `C-x v n' will run `git-gutter:next-hunk' subsequent \"n\" will run this command again and subsequent \"p\" @@ -73,17 +73,19 @@ on exit. For any other key pressed, run their assigned command as defined in MAP and then exit the loop running EXIT-FN, if specified. +If DELAY an integer is specified exit after DELAY seconds. + NOTE: SUBKEY and OTHER-SUBKEYS bindings support only char syntax and vectors, so don't use strings to define them. -\(fn MAP KEY SUBKEY COMMAND &optional OTHER-SUBKEYS PROMPT EXIT-FN)" nil nil) +\(fn MAP KEY SUBKEY COMMAND &optional OTHER-SUBKEYS PROMPT EXIT-FN DELAY)" nil nil) (function-put 'helm-define-key-with-subkeys 'lisp-indent-function '1) -(autoload 'helm-debug-open-last-log "helm" "\ +(autoload 'helm-debug-open-last-log "helm-core" "\ Open Helm log file or buffer of last Helm session." t nil) -(autoload 'helm "helm" "\ +(autoload 'helm "helm-core" "\ Main function to execute helm sources. PLIST is a list like @@ -138,7 +140,7 @@ Minibuffer prompt. Default value is `helm--prompt'. If t, allow resumption of the previous session of this Helm command, skipping initialization. -If 'noresume, this instance of `helm' cannot be resumed. +If \\='noresume, this instance of `helm' cannot be resumed. *** :preselect @@ -193,7 +195,7 @@ Allow running this Helm command in a running Helm session. Other keywords are interpreted as local variables of this Helm session. The `helm-' prefix can be omitted. For example, -\(helm :sources 'helm-source-buffers-list +\(helm :sources \\='helm-source-buffers-list :buffer \"*helm buffers*\" :candidate-number-limit 10) @@ -212,23 +214,23 @@ However, the use of non-keyword args is deprecated. \(fn &key SOURCES INPUT PROMPT RESUME PRESELECT BUFFER KEYMAP DEFAULT HISTORY ALLOW-NEST OTHER-LOCAL-VARS)" nil nil) -(autoload 'helm-cycle-resume "helm" "\ +(autoload 'helm-cycle-resume "helm-core" "\ Cycle in `helm-buffers' list and resume when waiting more than 1.2s." t nil) -(autoload 'helm-other-buffer "helm" "\ +(autoload 'helm-other-buffer "helm-core" "\ Simplified Helm interface with other `helm-buffer'. Call `helm' only with SOURCES and BUFFER as args. \(fn SOURCES BUFFER)" nil nil) -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm" '("helm-" "with-helm-"))) +(register-definition-prefixes "helm-core" '("helm-" "with-helm-")) ;;;*** ;;;### (autoloads nil "helm-lib" "helm-lib.el" (0 0 0 0)) ;;; Generated autoloads from helm-lib.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-lib" '("helm-" "with-helm-"))) +(register-definition-prefixes "helm-lib" '("helm-" "with-helm-")) ;;;*** @@ -236,14 +238,14 @@ Call `helm' only with SOURCES and BUFFER as args. ;;;;;; 0 0 0)) ;;; Generated autoloads from helm-multi-match.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-multi-match" '("helm-m"))) +(register-definition-prefixes "helm-multi-match" '("helm-m")) ;;;*** ;;;### (autoloads nil "helm-source" "helm-source.el" (0 0 0 0)) ;;; Generated autoloads from helm-source.el -(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "helm-source" '("helm-"))) +(register-definition-prefixes "helm-source" '("helm-")) ;;;*** diff --git a/elpa/helm-core-20220607.1243/helm-core-pkg.el b/elpa/helm-core-20220607.1243/helm-core-pkg.el new file mode 100644 index 00000000..0a8a5abf --- /dev/null +++ b/elpa/helm-core-20220607.1243/helm-core-pkg.el @@ -0,0 +1,11 @@ +(define-package "helm-core" "20220607.1243" "Development files for Helm" + '((emacs "25.1") + (async "1.9.4")) + :commit "a6df31a7cff0c64b8b999a85cbf5b4cc253a104f" :authors + '(("Thierry Volpiatto ")) + :maintainer + '("Thierry Volpiatto ") + :url "https://emacs-helm.github.io/helm/") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/helm-core-20210128.1814/helm.el b/elpa/helm-core-20220607.1243/helm-core.el similarity index 90% rename from elpa/helm-core-20210128.1814/helm.el rename to elpa/helm-core-20220607.1243/helm-core.el index eb3c0a44..f552ba10 100644 --- a/elpa/helm-core-20210128.1814/helm.el +++ b/elpa/helm-core-20220607.1243/helm-core.el @@ -1,20 +1,11 @@ -;;; helm.el --- Emacs incremental and narrowing framework -*- lexical-binding: t -*- +;;; helm-core.el --- Development files for Helm -*- lexical-binding: t; -*- -;; Version: 3.6.2 -;; URL: https://github.com/emacs-helm/helm +;; Copyright (C) 2022 Thierry Volpiatto -;; Copyright (C) 2007 Tamas Patrovics -;; 2008 ~ 2011 rubikitch -;; 2011 ~ 2020 Thierry Volpiatto - -;; This is a fork of anything.el wrote by Tamas Patrovics. - -;; Authors of anything.el: Tamas Patrovics -;; rubikitch -;; Thierry Volpiatto - -;; Author: Thierry Volpiatto -;; URL: http://github.com/emacs-helm/helm +;; Author: Thierry Volpiatto +;; URL: https://emacs-helm.github.io/helm/ +;; Version: 3.8.5 +;; Package-Requires: ((emacs "25.1") (async "1.9.4")) ;; This program is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -27,7 +18,11 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with this program. If not, see . +;; along with this program. If not, see . + +;;; Commentary: + +;; Contains the main code for Helm. ;;; Code: @@ -36,8 +31,6 @@ (require 'helm-lib) (require 'helm-multi-match) (require 'helm-source) -;; Soft require this as it is not bundled with helm-core package. -(require 'helm-global-bindings nil t) ;; Ensure async-bytecomp is used even with helm-core package. (declare-function async-bytecomp-package-mode "ext:async-bytecomp.el") @@ -81,7 +74,7 @@ E.g. (interactive) (message \"Run baz\")) -\(helm-define-multi-key global-map (kbd \" q\") '(foo bar baz) 2) +\(helm-define-multi-key global-map (kbd \" q\") \\='(foo bar baz) 2) Each time \" q\" is pressed, the next function is executed. Waiting more than 2 seconds between key presses switches back to @@ -100,7 +93,8 @@ See `helm-define-multi-key'." (defun helm-make-multi-command (functions &optional delay) "Return an anonymous multi-key command running FUNCTIONS. -Run each function in the FUNCTIONS list in turn when called within DELAY seconds." +Run each function in the FUNCTIONS list in turn when called within +DELAY seconds." (declare (indent 1)) (let ((funs functions) (iter (cl-gensym "helm-iter-key")) @@ -138,7 +132,7 @@ and second call within 1s runs `helm-swap-windows'." ;;;###autoload (defun helm-define-key-with-subkeys (map key subkey command - &optional other-subkeys prompt exit-fn) + &optional other-subkeys prompt exit-fn delay) "Define in MAP a KEY and SUBKEY to COMMAND. This allows typing KEY to call COMMAND the first time and @@ -151,8 +145,8 @@ Arg OTHER-SUBKEYS is an alist specifying other short key bindings to use once started, e.g.: (helm-define-key-with-subkeys global-map - (kbd \"C-x v n\") ?n 'git-gutter:next-hunk - '((?p . git-gutter:previous-hunk))\) + (kbd \"C-x v n\") ?n \\='git-gutter:next-hunk + \\='((?p . git-gutter:previous-hunk))) In this example, `C-x v n' will run `git-gutter:next-hunk' subsequent \"n\" will run this command again and subsequent \"p\" @@ -165,34 +159,43 @@ on exit. For any other key pressed, run their assigned command as defined in MAP and then exit the loop running EXIT-FN, if specified. +If DELAY an integer is specified exit after DELAY seconds. + NOTE: SUBKEY and OTHER-SUBKEYS bindings support only char syntax and vectors, so don't use strings to define them." (declare (indent 1)) (define-key map key (lambda () (interactive) - (unwind-protect - (progn - (call-interactively command) - (while (let ((input (read-key prompt)) other kb com) - (setq last-command-event input) - (cond - ((eq input subkey) - (call-interactively command) - t) - ((setq other (assoc input other-subkeys)) - (call-interactively (cdr other)) - t) - (t - (setq kb (vector last-command-event)) - (setq com (lookup-key map kb)) - (if (commandp com) - (call-interactively com) - (setq unread-command-events - (nconc (mapcar 'identity kb) - unread-command-events))) - nil))))) - (and exit-fn (funcall exit-fn)))))) + (let (timer) + (unwind-protect + (progn + (call-interactively command) + (when delay + (setq timer (run-with-idle-timer + delay nil (lambda () (keyboard-quit))))) + (while (let ((input (read-key prompt)) other kb com) + (setq last-command-event input) + (cond + ((eq input subkey) + (call-interactively command) + (setq last-command command) + t) + ((setq other (assoc input other-subkeys)) + (call-interactively (cdr other)) + (setq last-command (cdr other)) + t) + (t + (setq kb (vector last-command-event)) + (setq com (lookup-key map kb)) + (if (commandp com) + (call-interactively com) + (setq unread-command-events + (nconc (mapcar 'identity kb) + unread-command-events))) + nil))))) + (when timer (cancel-timer timer)) + (and exit-fn (funcall exit-fn))))))) ;;; Keymap ;; @@ -208,8 +211,8 @@ and vectors, so don't use strings to define them." (define-key map (kbd "") 'helm-follow-action-backward) (define-key map (kbd "") 'helm-previous-page) (define-key map (kbd "") 'helm-next-page) - (define-key map (kbd "M-v") 'helm-previous-page) - (define-key map (kbd "C-v") 'helm-next-page) + (define-key map (kbd "M-v") 'helm-scroll-up) + (define-key map (kbd "C-v") 'helm-scroll-down) (define-key map (kbd "M-<") 'helm-beginning-of-buffer) (define-key map (kbd "M->") 'helm-end-of-buffer) (define-key map (kbd "C-g") 'helm-keyboard-quit) @@ -251,7 +254,7 @@ and vectors, so don't use strings to define them." (define-key map (kbd "C-c %") 'helm-exchange-minibuffer-and-header-line) (define-key map (kbd "C-c C-y") 'helm-yank-selection) (define-key map (kbd "C-c C-k") 'helm-kill-selection-and-quit) - (define-key map (kbd "C-c C-i") 'helm-copy-to-buffer) + (define-key map (kbd "C-c C-i") 'helm-insert-or-copy) (define-key map (kbd "C-c C-f") 'helm-follow-mode) (define-key map (kbd "C-c C-u") 'helm-refresh) (define-key map (kbd "C-c >") 'helm-toggle-truncate-line) @@ -397,8 +400,8 @@ Set this value to nil for no limit." (defcustom helm-exit-idle-delay 0 "Idle time before exiting minibuffer while Helm is updating. -Has no affect when helm-buffer is up to date \(i.e. exit without -delay in this condition\)." +Has no affect when helm-buffer is up to date (i.e. exit without +delay in this condition)." :group 'helm :type 'float) @@ -425,7 +428,7 @@ Specified as a pair of functions, where car is the restore function and cdr is the save function. To save and restore frame configuration, set this variable to -'\(set-frame-configuration . current-frame-configuration\) +\\='(set-frame-configuration . current-frame-configuration) NOTE: This may not work properly with own-frame minibuffer settings. Older versions saves/restores frame configuration, but @@ -452,7 +455,7 @@ To set it locally to `helm-buffer' in Helm sources use :type 'symbol) (defcustom helm-case-fold-search 'smart - "Adds 'smart' option to `case-fold-search'. + "Adds \\='smart' option to `case-fold-search'. Smart option ignores case for searches as long as there are no upper case characters in the pattern. @@ -467,7 +470,7 @@ into their execution process. See helm-grep.el for an example." :group 'helm :type '(choice (const :tag "Ignore case" t) (const :tag "Respect case" nil) - (other :tag "Smart" 'smart))) + (other :tag "Smart" smart))) (defcustom helm-file-name-case-fold-search (if (memq system-type @@ -484,7 +487,7 @@ See `helm-case-fold-search' for more info." "Use the same state of window split, vertical or horizontal. `helm-toggle-resplit-window' for the next helm session will use the same window scheme as the previous session unless -`helm-split-window-default-side' is 'same or 'other." +`helm-split-window-default-side' is \\='same or \\='other." :group 'helm :type 'boolean) @@ -518,7 +521,7 @@ handle this." (defcustom helm-split-window-other-side-when-one-window 'below "The default side to display `helm-buffer' when (1) -`helm-split-window-default-side' is 'other and (2) +`helm-split-window-default-side' is \\='other and (2) the current frame only has one window. Possible values are acceptable args for `split-window' SIDE, that is `below', `above', `left' or `right'. @@ -577,7 +580,7 @@ in the other. 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. +\\='same. When `helm-autoresize-mode' is enabled, setting this to nil will have no effect. @@ -599,7 +602,7 @@ Also when non-nil it overrides the effect of (defcustom helm-default-display-buffer-functions nil "Action functions to pass to `display-buffer'. -See (info \"(elisp) Action Functions for Buffer Display\"). +See (info \"(elisp) Buffer Display Action Functions\"). It has no effect when `helm-always-two-windows' is non-nil and may override other settings like `helm-split-window-inside-p'." @@ -759,7 +762,7 @@ The default is to enable this by default and then toggle This will be used when `helm-echo-input-in-header-line' is non-nil. -Value can be one of the symbols 'left-fringe or 'left-margin or +Value can be one of the symbols \\='left-fringe or \\='left-margin or an integer specifying the number of spaces before prompt. Note that on input longer that `window-width' the continuation string will be shown on left side of window without taking care of @@ -767,8 +770,8 @@ this." :group 'helm :type '(choice (symbol - (const :tag "Fringe" 'left-fringe) - (const :tag "Margin" 'left-margin)) + (const :tag "Fringe" left-fringe) + (const :tag "Margin" left-margin)) integer)) (defcustom helm-tramp-connection-min-time-diff 5 @@ -870,10 +873,16 @@ Fallback to 100 when nil." :group 'helm :type 'boolean) -(defcustom helm-use-frame-when-dedicated-window nil +(defvaralias 'helm-use-frame-when-dedicated-window + 'helm-use-frame-when-no-suitable-window) + +(defcustom helm-use-frame-when-no-suitable-window nil "Display Helm buffer in frame when Helm is started from a dedicated window." :group 'helm :type 'boolean) +(make-obsolete-variable 'helm-use-frame-when-dedicated-window + 'helm-use-frame-when-no-suitable-window + "3.8.1") (defcustom helm-default-prompt-display-function #'helm-set-default-prompt-display @@ -887,6 +896,12 @@ You can toggle later `truncate-lines' with \\\\[helm-toggle-truncate-line]." :group 'helm :type 'boolean) + +(defcustom helm-visible-mark-prefix "*" + "Prefix used in margin for marked candidates. +Set this to an empty string if you don't want prefix in margin when marking." + :group 'helm + :type 'string) ;;; Faces ;; @@ -1019,6 +1034,11 @@ You can toggle later `truncate-lines' with "Face for empty line at end of sources in the Helm buffer. Allow specifying the height of this line." :group 'helm-faces) + +(defface helm-mark-prefix + `((t :inherit default)) + "Face for string `helm-visible-mark-prefix'." + :group 'helm-faces) ;;; Variables. ;; @@ -1094,10 +1114,9 @@ Should run also at end of `helm-display-function'.") (defvar helm-execute-action-at-once-if-one nil "When non-nil execute the default action and then exit if only one candidate. -If symbol 'current-source is given as value exit if only one +If symbol \\='current-source is given as value exit if only one candidate in current source. This variable accepts a function -with no args that should returns a boolean value or -'current-source.") +with no args that should returns a boolean value or \\='current-source.") (defvar helm-quit-if-no-candidate nil "When non-nil, quit if there are no candidates. @@ -1120,7 +1139,7 @@ size of `helm-debug-buffer' grows quickly.") \\[helm-help]:Help \ \\[helm-select-action]:Act \ \\[helm-maybe-exit-minibuffer]/\ -f1/f2/f-n:NthAct \ +f1..f12:NthAct \ \\[helm-toggle-suspend-update]:Tog.suspend \ \\[helm-customize-group]:Conf" "Help string displayed by Helm in the mode-line. @@ -1135,7 +1154,7 @@ A hook useful for modifying minibuffer settings in Helm. An example that hides the minibuffer when using `helm-echo-input-in-header-line': - (add-hook 'helm-minibuffer-set-up-hook #'helm-hide-minibuffer-maybe) + (add-hook \\='helm-minibuffer-set-up-hook #'helm-hide-minibuffer-maybe) Note that we check `helm-echo-input-in-header-line' value from `helm-buffer' which allows detecting possible local @@ -1183,9 +1202,7 @@ are called filtered actions. Helm uses what's called sources to provide different kinds of completions. Each Helm session can handle one or more source. A source is an alist object which is build from various classes, -see [[Writing your own Helm sources][here]] and -[[https://github.com/emacs-helm/helm/wiki/Developing#creating-a-source][Helm -wiki]] for more infos. +see [[Writing your own Helm sources][here]] and [[https://github.com/emacs-helm/helm/wiki/Developing#creating-a-source][Helm wiki]] for more infos. *** Configure sources @@ -1206,7 +1223,7 @@ Helm session. In this case you can add a defmethod called #+begin_src elisp - (defmethod helm-setup-user-source ((source helm-moccur-class)) + (cl-defmethod helm-setup-user-source ((source helm-moccur-class)) (setf (slot-value source 'follow) -1)) #+end_src @@ -1241,6 +1258,13 @@ match everything but this. *** Completion-styles +UPDATE: At version 3.8.0 Helm default is now to NOT use +`completion-styles' i.e. now `helm-completion-style' default to +'helm and no more to 'emacs. + +If you want to use `completion-styles' in Helm customize +`helm-completion-style' to 'emacs. + Helm generally fetches its candidates with the :candidates function up to `helm-candidate-number-limit' and then applies match functions to these candidates according to `helm-pattern'. @@ -1250,11 +1274,12 @@ Helm provides 'helm completion style but also 'helm-flex completion style for Emacs<27 that don't have 'flex completion style, otherwise (emacs-27) 'flex completion style is used to provide fuzzy aka flex completion. -By default, like in Emacs vanilla, all completion commands \(e.g., -`completion-at-point') using `completion-in-region' or -`completing-read' use `completion-styles'. -Some Helm native commands like `helm-M-x' do use -`completion-styles'. Any Helm sources can use `completion-styles' + +When using helm-fuzzy as `helm-completion-style' helm use its own +fuzzy implementation which have nothing to do with emacs `flex' +style. + +Any Helm sources can use `completion-styles' by using :match-dynamic slot and building their :candidates function with `helm-dynamic-completion'. @@ -1281,7 +1306,7 @@ emacs-26. Anyway, 'helm-flex is not provided in Finally Helm provides two user variables to control `completion-styles' usage: `helm-completion-style' and -`helm-completion-syles-alist'. Both variables are customizable. +`helm-completion-styles-alist'. Both variables are customizable. The former allows retrieving previous Helm behavior if needed, by setting it to `helm' or `helm-fuzzy', default being `emacs' which allows dynamic completion and usage of `completion-styles'. The @@ -1293,7 +1318,7 @@ helmized commands. File completion in `read-file-name' family doesn't obey completion-styles and has its own file completion implementation. Native Helm commands using `completion-styles' doesn't obey `helm-completion-style' and -`helm-completion-syles-alist' (e.g., helm-M-x). +`helm-completion-styles-alist' (e.g., helm-M-x). Also for a better control of styles in native Helm sources (not helmized by helm-mode) using :match-dynamic, @@ -1345,7 +1370,7 @@ matching or fuzzy matching (see [[Matching in Helm][Matching in Helm]]). Completion is not done dynamically (against `helm-pattern') -because backend functions (i.e. `competion-at-point-functions') +because backend functions (i.e. `completion-at-point-functions') are not aware of Helm matching methods. By behaving like this, the benefit is that you can fully use Helm @@ -1445,22 +1470,34 @@ you DO NOT need these packages to display helm buffers in frames. ** Helm's basic operations and default key bindings -| Key | Alternative Keys | Command | -|---------+------------------+----------------------------------------------------------------------| -| 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 [1] | -| 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 | -| M-o | left | Previous source | -| C-o | right | Next source | -| C-k | | Delete pattern (with prefix arg delete from point to end or all [2]) | -| C-j | | Persistent action (Execute and keep Helm session) | +| Key| Command| +|----+--------| +| | +| \\[helm-previous-line]| Previous line | +| \\[helm-next-line]| Next line | +| \\[helm-scroll-up]| Scroll up | +| \\[helm-scroll-down]| Scroll down | +| \\[helm-scroll-other-window]| Scroll up other-window | +| \\[helm-scroll-other-window-down]| Scroll down other-window | +| \\[helm-maybe-exit-minibuffer]| Execute first (default) action / Select [1] | +| \\[helm-beginning-of-buffer]| Goto beginning of buffer | +| \\[helm-end-of-buffer]| Goto end of buffer | +| \\[helm-select-action]| Show actions menu | +| \\[helm-previous-source]| Previous source | +| \\[helm-next-source]| Next source | +| \\[helm-delete-minibuffer-contents]| Delete pattern (with prefix arg delete from point to end or all [2]) | +| \\[helm-execute-persistent-action]| Persistent action (Execute and keep Helm session) | +|\\[helm-toggle-resplit-and-swap-windows]|Rotate or swap windows. | +|\\[helm-exchange-minibuffer-and-header-line]|Exchange minibuffer and header-line. | +|\\[helm-quit-and-find-file]|Drop into `helm-find-files'. | +|\\[helm-kill-selection-and-quit]|Kill display value of candidate and quit (with prefix arg, kill the real value). | +|\\[helm-yank-selection]|Yank current selection into pattern. | +|\\[helm-insert-or-copy]|Insert or copy marked candidates (C-u) . | +|\\[helm-follow-mode]|Toggle automatic execution of persistent action. | +|\\[helm-follow-action-forward]|Run persistent action then select next line. | +|\\[helm-follow-action-backward]|Run persistent action then select previous line. | +|\\[helm-refresh]|Recalculate and redisplay candidates. | +|\\[helm-toggle-suspend-update]|Toggle candidate updates. | \[1] Behavior may change depending context in some source e.g. `helm-find-files'. @@ -1589,20 +1626,6 @@ enabling `helm-follow-mode', you can use `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-exchange-minibuffer-and-header-line]\t\tExchange minibuffer and header-line. -\\[helm-quit-and-find-file]\t\tDrop into `helm-find-files'. -\\[helm-kill-selection-and-quit]\t\tKill display value of candidate and quit (with prefix arg, kill the real value). -\\[helm-yank-selection]\t\tYank current selection into pattern. -\\[helm-copy-to-buffer]\t\tCopy selected candidate at point in current buffer. -\\[helm-follow-mode]\t\tToggle automatic execution of persistent action. -\\[helm-follow-action-forward]\tRun persistent action then select next line. -\\[helm-follow-action-backward]\t\tRun persistent action then select previous line. -\\[helm-refresh]\t\tRecalculate and redisplay candidates. -\\[helm-toggle-suspend-update]\t\tToggle candidate updates. - ** Special yes, no or yes for all answers You may be prompted in the minibuffer to answer by [y,n,!,q] in @@ -1729,7 +1752,7 @@ It also accepts function or variable symbol.") (defvar helm-autoresize-mode) ;; Undefined in `helm-default-display-buffer'. (defvar helm-async-outer-limit-hook nil - "A hook that runs in async sources when process output comes out of `candidate-number-limit'. + "Run in async sources when process output is out of `candidate-number-limit'. Should be set locally to `helm-buffer' with `helm-set-local-variable'.") (defvar helm-quit-hook nil @@ -1741,6 +1764,10 @@ The hook should takes one arg SOURCES.") (defvar helm-help-buffer-name "*Helm Help*" "The name of helm help buffer.") + +;; See bug#2503. +(defvar helm-process-output-split-string-separator "\n" + "Separator to use when splitting helm async output.") ;;; Internal Variables ;; @@ -1751,8 +1778,6 @@ Other sources won't appear in the search results. If nil, no filtering is done. Don't set this directly, use `helm-set-source-filter' during a Helm session to modify it.") -(defvar helm-current-prefix-arg nil - "Record `current-prefix-arg' when exiting minibuffer.") (defvar helm-saved-action nil "Saved value of the currently selected action by key.") (defvar helm-saved-current-source nil @@ -1778,7 +1803,6 @@ in `helm-initialize'.") "Internal, store locally `helm-pattern' value for later use in `helm-resume'.") (defvar helm--source-name nil) (defvar helm-current-source nil) -(defvar helm-tick-hash (make-hash-table :test 'equal)) (defvar helm-issued-errors nil) (defvar helm--last-log-file nil "The name of the log file of the last Helm session.") @@ -1802,11 +1826,11 @@ Knowing this exit-status could help restore a window config when Helm aborts in some special circumstances. See `helm-exit-minibuffer' and `helm-keyboard-quit'.") (defvar helm-minibuffer-confirm-state nil) -(defvar helm-quit nil) +(defvar helm--quit nil) (defvar helm-buffers nil "Helm buffers listed in order of most recently used.") (defvar helm-current-position nil - "Cons of \(point . window-start\) when Helm is invoked. + "Cons of (point . window-start) when Helm is invoked. `helm-current-buffer' uses this to restore position after `helm-keyboard-quit'") (defvar helm-last-frame-or-window-configuration nil @@ -1816,7 +1840,7 @@ Helm aborts in some special circumstances. See (defvar helm--mode-line-string-real nil) ; The string to display in mode-line. (defvar helm-persistent-action-display-window nil) (defvar helm-marked-candidates nil - "Marked candidates. List of \(source . real\) pair.") + "Marked candidates. List of (source . real) pair.") (defvar helm--mode-line-display-prefarg nil) (defvar helm--temp-follow-flag nil "[INTERNAL] A simple flag to notify persistent action we are following.") @@ -1884,6 +1908,9 @@ session just like resume would do.") It is generally `helm-current-buffer', but when this one is displayed in a dedicated buffer, helm can't start in this window and use another window handling a buffer, it is this one we store.") +(defvar helm--tramp-archive-maybe-loaded nil) +(defvar helm--original-dedicated-windows-alist nil + "[INTERNAL] Store all dedicated windows with their dedicated state on startup") ;; Utility: logging (defun helm-log (format-string &rest args) @@ -1898,7 +1925,7 @@ Use optional arguments ARGS like in `format'." (buffer-disable-undo) (let ((inhibit-read-only t)) (goto-char (point-max)) - (insert (let ((tm (current-time))) + (insert (let ((tm (time-convert nil 'list))) (format (concat (if (string-match "Start session" format-string) "* " "** ") "%s.%06d (%s)\n %s\n") @@ -2020,15 +2047,12 @@ End:") (defmacro with-helm-temp-hook (hook &rest body) "Execute temporarily BODY as a function for HOOK." (declare (indent 1) (debug t)) - (helm-with-gensyms (helm--hook) - `(progn - (defun ,helm--hook () - (unwind-protect - (progn ,@body) - (remove-hook ,hook (quote ,helm--hook)) - (fmakunbound (quote ,helm--hook)))) - (push (cons ',helm--hook ,hook) helm--temp-hooks) - (add-hook ,hook (quote ,helm--hook))))) + `(letrec ((helm--hook (lambda () + (unwind-protect + (progn ,@body) + (remove-hook ,hook helm--hook))))) + (push (cons helm--hook ,hook) helm--temp-hooks) + (add-hook ,hook helm--hook))) (defmacro with-helm-after-update-hook (&rest body) "Execute BODY at end of `helm-update'." @@ -2059,7 +2083,7 @@ End:") 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, +`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. @@ -2152,13 +2176,13 @@ without modifying source code. E.g. Add the action \"Byte compile file async\" linked to function -'async-byte-compile-file to source `helm-source-find-files' only +`async-byte-compile-file' to source `helm-source-find-files' only when predicate helm-ff-candidates-lisp-p returns non-nil: \(helm-add-action-to-source-if \"Byte compile file async\" - 'async-byte-compile-file + \\='async-byte-compile-file helm-source-find-files - 'helm-ff-candidates-lisp-p\)." + \\='helm-ff-candidates-lisp-p)." (let* ((actions (helm-get-attr 'action source 'ignorefn)) (action-transformers (helm-get-attr 'action-transformer source)) (new-action (list (cons name fn))) @@ -2194,16 +2218,16 @@ only: Shift+F shows only file results from some sources: -\(define-key helm-map \"F\" 'helm-my-show-files-only) +\(define-key helm-map \"F\" \\='helm-my-show-files-only) \(defun helm-my-show-files-only () (interactive) - (helm-set-source-filter '(\"File Name History\" + (helm-set-source-filter \\='(\"File Name History\" \"Files from Current Directory\"))) Shift+A shows all results: -\(define-key helm-map \"A\" 'helm-my-show-all) +\(define-key helm-map \"A\" \\='helm-my-show-all) \(defun helm-my-show-all () (interactive) @@ -2238,42 +2262,47 @@ If NO-UPDATE is non-nil, skip executing `helm-update'." (unless no-update (helm-update))) (defun helm-get-selection (&optional buffer force-display-part source) - "Return the currently selected item or nil. + "Return the currently selected candidate from BUFFER. If BUFFER is nil or unspecified, use `helm-buffer' as default value. -If FORCE-DISPLAY-PART is non-nil, return the display string. -If FORCE-DISPLAY-PART value is `withprop' the display string is returned -with its properties." - (setq buffer (or buffer helm-buffer)) - (unless (or (helm-empty-buffer-p buffer) - (helm-pos-header-line-p)) - (with-current-buffer buffer - (let* ((disp-fn (if (eq force-display-part 'withprop) + +If FORCE-DISPLAY-PART is non-nil, return the display part of candidate. + +If FORCE-DISPLAY-PART value is `withprop' the display part of +candidate is returned with its properties. + +When FORCE-DISPLAY-PART is nil the real part of candidate is returned. + +SOURCE default to current-source when unspecified but it is better to +specify SOURCE when it is already available to avoid to call +`helm-get-current-source' uselessly. + +Note that FORCE-DISPLAY-PART when specified takes precedence over +`display-to-real' attribute, that's mean don't use FORCE-DISPLAY-PART +when you want the `display-to-real' function(s) to be applied." + (with-current-buffer (or buffer helm-buffer) + (unless (or (helm-empty-buffer-p (current-buffer)) + (helm-pos-header-line-p)) + (let* ((beg (overlay-start helm-selection-overlay)) + (end (overlay-end helm-selection-overlay)) + (disp-fn (if (eq force-display-part 'withprop) 'buffer-substring 'buffer-substring-no-properties)) - (selection - (or (and (not force-display-part) - (get-text-property (overlay-start - helm-selection-overlay) - 'helm-realvalue)) - ;; It is needed to return properties of DISP in some case, - ;; e.g for `helm-confirm-and-exit-minibuffer', - ;; so use `buffer-substring' here when 'withprop is specified. - (let* ((beg (overlay-start helm-selection-overlay)) - (end (overlay-end helm-selection-overlay)) - ;; If there is no selection at point, the - ;; overlay is at its initial pos, (point-min) - ;; (point-min), that's mean the helm-buffer - ;; is not empty but have no selection yet, - ;; this happen with grep sentinel sending an - ;; error message in helm-buffer when no matches. - (disp (unless (= beg end) (funcall disp-fn beg (1- end)))) - (src (or source (helm-get-current-source)))) - (helm-aif (and src disp - (not force-display-part) - (assoc-default 'display-to-real src)) - (helm-apply-functions-from-source source it disp) - disp))))) + ;; If there is no selection at point, the + ;; overlay is at its initial pos, (point-min) + ;; (point-min), that's mean the helm-buffer + ;; is not empty but have no selection yet, + ;; this happen with grep sentinel sending an + ;; error message in helm-buffer when no matches. + (disp (unless (= beg end) (funcall disp-fn beg (1- end)))) + (src (or source (helm-get-current-source))) + (selection (helm-acond (force-display-part disp) + ;; helm-realvalue always takes precedence + ;; over display-to-real. + ((get-text-property beg 'helm-realvalue) it) + ((assoc-default 'display-to-real src) + (helm-apply-functions-from-source source it disp)) + (t disp)))) (unless (equal selection "") (helm-log "selection = %S" selection) selection))))) @@ -2283,24 +2312,22 @@ with its properties." It is a function symbol (sole action) or list of (action-display . function)." (unless (helm-empty-buffer-p (helm-buffer-get)) - (let ((src (helm-get-current-source))) - (helm-aif (helm-get-attr 'action-transformer) + (let* ((src (or source (helm-get-current-source))) + (marked (helm-marked-candidates)) + (action-transformer (helm-get-attr 'action-transformer src)) + (actions (helm-get-attr 'action src 'ignorefn))) + (if action-transformer (helm-apply-functions-from-source - (or source src) it - (helm-get-attr 'action nil 'ignorefn) - ;; Check if the first given transformer - ;; returns the same set of actions for each - ;; candidate in marked candidates. - ;; If so use the car of marked to determine - ;; the set of actions, otherwise use the selection. - (if (cl-loop with marked = (helm-marked-candidates) - with act = (car (helm-mklist it)) - with acts = (funcall act nil (car marked)) - for c in marked - always (equal (funcall act nil c) acts)) - (car (helm-marked-candidates)) + src action-transformer actions + ;; When there is marked candidates assume the set of + ;; candidates user selected contains candidates of the same + ;; type so that the actions added by transformer fit with + ;; all marked (previously we were looping on each marked + ;; but it is too costly for the benefit it brings). + (if marked + (car marked) (helm-get-selection nil nil src))) - (helm-get-attr 'action nil 'ignorefn))))) + actions)))) (defun helm-get-current-source () "Return the source for the current selection. @@ -2322,22 +2349,6 @@ Return nil when `helm-buffer' is empty." (and (equal (assoc-default 'name source) source-name) source))))))))) -(defun helm-buffer-is-modified (buffer) - "Return non-nil when BUFFER is modified since Helm was invoked." - (let* ((buf (get-buffer buffer)) - (key (concat (buffer-name buf) "/" (helm-get-attr 'name))) - (source-tick (or (gethash key helm-tick-hash) 0)) - (buffer-tick (buffer-chars-modified-tick buf)) - (modifiedp (/= source-tick buffer-tick))) - (puthash key buffer-tick helm-tick-hash) - (helm-log "buffer = %S" buffer) - (helm-log "modifiedp = %S" modifiedp) - modifiedp)) - -(defun helm-current-buffer-is-modified () - "Check if `helm-current-buffer' is modified since Helm was invoked." - (helm-buffer-is-modified helm-current-buffer)) - (defun helm-run-after-exit (function &rest args) "Execute FUNCTION with ARGS after exiting Helm. The action is to call FUNCTION with arguments ARGS. @@ -2367,6 +2378,7 @@ i.e. functions called with RET." ;; source that inherit actions from type, note that ACTION have to ;; be bound to a symbol and not to be an anonymous action ;; i.e. lambda or byte-code. + (helm-log "Start executing action") (let ((actions (helm-get-actions-from-current-source))) (when actions (cl-assert (or (eq action actions) @@ -2418,7 +2430,7 @@ i.e. functions called with RET." (defun helm-interpret-value (value &optional source compute) "Interpret VALUE as variable, function or literal and return it. If VALUE is a function, call it with no arguments and return the value -unless COMPUTE value is 'ignorefn. +unless COMPUTE value is \\='ignorefn. If SOURCE compute VALUE for this source. If VALUE is a variable, return the value. If VALUE is a symbol, but it is not a function or a variable, cause an error. @@ -2503,7 +2515,7 @@ was deleted and the candidates list not updated." "From SOURCE apply FUNCTIONS on ARGS. This function is used to process filter functions. When filter is -a \`filtered-candidate-transformer', we pass to ARGS +a `filtered-candidate-transformer', we pass to ARGS candidates+source whereas when the filter is `candidate-transformer' we pass to ARGS candidates only. This function is also used to process functions called with no @@ -2585,24 +2597,11 @@ of current source only." while (not (if in-current-source (or (helm-pos-header-line-p) (eobp)) (eobp))) - ;; Don't count empty lines maybe added by popup (#1370). + ;; Don't count empty lines maybe added by popup (bug#1370). unless (or (eq (point-at-bol) (point-at-eol)) (helm-pos-header-line-p)) do (cl-incf ln) do (forward-line 1) finally return ln)))))) - -(defmacro with-helm-quittable (&rest body) - "If an error occurs in execution of BODY, safely quit helm." - (declare (indent 0) (debug t)) - `(condition-case _v - (let (inhibit-quit) - ,@body) - (quit (setq quit-flag t) - (setq helm-quit t) - (exit-minibuffer) - (keyboard-quit) - ;; See comment about this in `with-local-quit'. - (eval '(ignore nil))))) ;; Entry point ;; `:allow-nest' is not in this list because it is treated before. @@ -2616,12 +2615,12 @@ of current source only." PLIST is a list like -\(:key1 val1 :key2 val2 ...\) +\(:key1 val1 :key2 val2 ...) or \(&optional sources input prompt resume preselect - buffer keymap default history allow-nest\). + buffer keymap default history allow-nest). ** Keywords @@ -2666,7 +2665,7 @@ Minibuffer prompt. Default value is `helm--prompt'. If t, allow resumption of the previous session of this Helm command, skipping initialization. -If 'noresume, this instance of `helm' cannot be resumed. +If \\='noresume, this instance of `helm' cannot be resumed. *** :preselect @@ -2721,9 +2720,9 @@ Allow running this Helm command in a running Helm session. Other keywords are interpreted as local variables of this Helm session. The `helm-' prefix can be omitted. For example, -\(helm :sources 'helm-source-buffers-list +\(helm :sources \\='helm-source-buffers-list :buffer \"*helm buffers*\" - :candidate-number-limit 10\) + :candidate-number-limit 10) Starts a Helm session with the variable `helm-candidate-number-limit' set to 10. @@ -2734,7 +2733,7 @@ For backward compatibility, positional parameters are supported: \(helm sources input prompt resume preselect - buffer keymap default history allow-nest\) + buffer keymap default history allow-nest) However, the use of non-keyword args is deprecated. @@ -2791,7 +2790,7 @@ are valid helm variables nevertheless. For example, :candidate-number-limit is bound to `helm-candidate-number-limit' in the source. - (helm-parse-keys '(:sources ((name . \"test\") + (helm-parse-keys \\='(:sources ((name . \"test\") (candidates . (a b c))) :buffer \"toto\" :candidate-number-limit 4)) @@ -2805,6 +2804,18 @@ in the source. unless (memq key helm-argument-keys) collect (cons sym value))) +(defun helm--maybe-load-tramp-archive () + ;; Should fix bug#2393 and bug#2394. `while-no-input-ignore-events' + ;; is also let-bounded in `helm--maybe-use-while-no-input'. + (let ((while-no-input-ignore-events + (and (boundp 'while-no-input-ignore-events) + (cons 'dbus-event while-no-input-ignore-events)))) + (unless helm--tramp-archive-maybe-loaded + ;; This for Emacs-27 not requiring tramp-archive. + (and (boundp 'tramp-archive-enabled) + (require 'tramp-archive nil t)) + (setq helm--tramp-archive-maybe-loaded t)))) + ;;; Entry point helper (defun helm-internal (&optional sources input @@ -2818,7 +2829,16 @@ HISTORY args see `helm'." (null input)) nil "Error in %S buffer: Initial input should be a string or nil" buffer) + ;; Set all windows NON dedicated to avoid headaches with PA and + ;; helm-window (bug#2443) + (cl-loop for win in (window-list nil 1) + for state = (window-dedicated-p win) + when state + do (progn (set-window-dedicated-p win nil) + (push `(,win . ,state) helm--original-dedicated-windows-alist))) (unless helm--nested (setq helm-initial-frame (selected-frame))) + ;; Launch tramp-archive with dbus-event in `while-no-input-ignore-events'. + (helm--maybe-load-tramp-archive) ;; Activate the advices. ;; Advices will be available only in >=emacs-24.4, but ;; allow compiling without errors on lower emacs. @@ -2828,7 +2848,7 @@ HISTORY args see `helm'." (advice-add 'epa-passphrase-callback-function :around #'helm--suspend-read-passwd) ;; Ensure linum-mode is disabled in Helm buffers to preserve - ;; performances (Issue #1894). + ;; performances (Bug#1894). (advice-add 'linum-on :override #'helm--advice-linum-on '((depth . 100)))) (helm-log (concat "[Start session] " (make-string 41 ?+))) (helm-log "prompt = %S" prompt) @@ -2840,7 +2860,7 @@ HISTORY args see `helm'." (setq helm--prompt (or prompt "pattern: ")) (let ((non-essential t) ;; Prevent mouse jumping to the upper-right - ;; hand corner of the frame (#1538). + ;; hand corner of the frame (bug#1538). mouse-autoselect-window focus-follows-mouse mode-line-in-non-selected-windows @@ -2858,7 +2878,7 @@ HISTORY args see `helm'." helm--source-name helm-current-source helm-in-persistent-action - helm-quit + helm--quit (helm-buffer (or buffer helm-buffer))) (helm-initialize resume input default sources) @@ -2870,13 +2890,17 @@ HISTORY args see `helm'." ;; helm-read-from-minibuffer). (unless helm-execute-action-at-once-if-one (helm-display-buffer helm-buffer resume) - (select-window (helm-window))) + (select-window (helm-window)) + (when (and resume helm-visible-mark-overlays) + (set-window-margins (selected-window) + (+ (string-width helm-visible-mark-prefix) + helm-left-margin-width)))) ;; We are now in helm-buffer. (unless helm-allow-mouse (helm--remap-mouse-mode 1)) ; Disable mouse bindings. (add-hook 'post-command-hook 'helm--maybe-update-keymap) ;; Add also to update hook otherwise keymap is not updated - ;; until a key is hitted (Issue #1670). + ;; until a key is hitted (Bug#1670). (add-hook 'helm-after-update-hook 'helm--maybe-update-keymap) (add-hook 'post-command-hook 'helm--update-header-line) (helm-log "show prompt") @@ -2886,7 +2910,7 @@ HISTORY args see `helm'." resume keymap default history) (helm-cleanup)) (prog1 - (unless helm-quit (helm-execute-selection-action)) + (unless helm--quit (helm-execute-selection-action)) (helm-log (concat "[End session] " (make-string 41 ?-))))) (quit (helm-restore-position-on-quit) @@ -3167,6 +3191,12 @@ frame configuration as per `helm-save-configuration-functions'." (funcall (cdr helm-save-configuration-functions)))) (restore (funcall (car helm-save-configuration-functions) helm-last-frame-or-window-configuration) + ;; Restore dedicated windows (bug#2443). + (when helm--original-dedicated-windows-alist + (cl-loop for (win . state) in helm--original-dedicated-windows-alist + when (window-live-p win) + do (set-window-dedicated-p win state)) + (setq helm--original-dedicated-windows-alist nil)) ;; Restore frame focus. ;; This is needed for minibuffer own-frame config ;; when recursive minibuffers are in use. @@ -3186,7 +3216,7 @@ frame configuration as per `helm-save-configuration-functions'." ;; ;; Since they don't know about the new timestamp, ;; their keyboard handling can break after a helm - ;; user quits emacs, as reported in #1641. + ;; user quits emacs, as reported in bug#1641. ;; ;; Fortunately for us, we really don't need this ;; XSetInputFocus call, since we already have focus @@ -3267,17 +3297,19 @@ If `helm-initial-frame' has no minibuffer, use Fallback to global value of `helm-display-function' when no local value found and current command is not in `helm-commands-using-frame'." - (or (with-helm-buffer helm-display-function) - (and (or (memq com helm-commands-using-frame) - (and helm-use-frame-when-dedicated-window - (window-dedicated-p (get-buffer-window helm-current-buffer))) - (and helm-use-frame-when-more-than-two-windows - (null helm--nested) - (> (length (window-list)) 2)) - ;; Frame parameter is unreliable for minibuffer on emacs-26. - (null (member helm-initial-frame (minibuffer-frame-list)))) - #'helm-display-buffer-in-own-frame) - (default-value 'helm-display-function))) + (let ((win (get-buffer-window helm-current-buffer))) + (or (with-helm-buffer helm-display-function) + (and (or (memq com helm-commands-using-frame) + (and helm-use-frame-when-no-suitable-window + (or (window-dedicated-p win) + (window-parameter win 'window-side))) + (and helm-use-frame-when-more-than-two-windows + (null helm--nested) + (> (length (window-list)) 2)) + ;; Frame parameter is unreliable for minibuffer on emacs-26. + (null (member helm-initial-frame (minibuffer-frame-list)))) + #'helm-display-buffer-in-own-frame) + (default-value 'helm-display-function)))) (defun helm-display-buffer (buffer &optional resume) "Display BUFFER. @@ -3325,22 +3357,23 @@ It is the default value of `helm-display-function'. It uses `switch-to-buffer' or `display-buffer' depending on the value of `helm-full-frame' or `helm-split-window-default-side'." (let (pop-up-frames - (dedicated-p (window-dedicated-p - (get-buffer-window helm-current-buffer)))) - (if (and (null (eq dedicated-p t)) - (or (buffer-local-value 'helm-full-frame (get-buffer buffer)) - (and (eq helm-split-window-default-side 'same) - (one-window-p t)))) + (curwin (get-buffer-window helm-current-buffer))) + (if (or (buffer-local-value 'helm-full-frame (get-buffer buffer)) + (and (eq helm-split-window-default-side 'same) + (one-window-p t))) (progn (and (not (minibufferp helm-current-buffer)) + ;; side-windows can't be the only window in frame, + ;; emacs refuse to delete other windows when + ;; current is a side-window [1]. + (not (window-parameter curwin 'window-side)) (delete-other-windows)) (switch-to-buffer 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-inside-p) - ;; Prevent deleting OW only when helm-current-buffer - ;; is "strongly" dedicated. - (null (eq dedicated-p t))) + ;; Same comment as in [1]. + (not (window-parameter curwin 'window-side))) (delete-other-windows)) (display-buffer buffer `(,helm-default-display-buffer-functions @@ -3351,6 +3384,8 @@ value of `helm-full-frame' or `helm-split-window-default-side'." ;; Shut up byte-compiler in emacs-26 (defvar tab-bar-mode) +;; No warnings in Emacs built --without-x +(defvar x-display-name) (defun helm-display-buffer-in-own-frame (buffer &optional resume) "Display Helm buffer BUFFER in a separate frame. @@ -3618,7 +3653,7 @@ Helm was started, use `helm-current-buffer' instead." ;; as `helm-current-buffer', this allow to use helm ;; from an already active minibuffer (M-: etc...) (window-buffer (active-minibuffer-window)) - ;; Fix Issue #456 + ;; Fix Bug#456 ;; Use this instead of `current-buffer' to ensure ;; helm session started in helm-mode from a completing-read ;; Use really the buffer where we started and not the one @@ -3646,7 +3681,10 @@ Unuseful when used outside Helm, don't use it.") (set (make-local-variable 'buffer-read-only) nil) (buffer-disable-undo) (erase-buffer) - (set (make-local-variable 'helm-map) helm-map) + ;; Use this instead of setting helm-map local ensure we have all + ;; our keys when helm loose minibuffer focus. And the map is + ;; made local as well AFAIU. + (use-local-map helm-map) (set (make-local-variable 'helm-source-filter) nil) (make-local-variable 'helm-sources) (set (make-local-variable 'helm-display-function) nil) @@ -3705,7 +3743,17 @@ For PRESELECT RESUME KEYMAP DEFAULT HISTORY, see `helm'." resize-mini-windows)) (first-src (car helm-sources)) (source-process-p (or (assq 'candidates-process src) - (assq 'candidates-process first-src)))) + (assq 'candidates-process first-src))) + ;; As we are using `helm-keyboard-quit' for `C-g' we have + ;; to prevent emacs command loop redefining `C-g' during + ;; helm-session. This happen only on async source with + ;; large output after a certain delay. The effect is that + ;; the minibuffer is exited but the helm async process + ;; continue running, and because minibuffer is lost `C-g' + ;; have no more effect. By binding `inhibit-quit' here we + ;; prevent this and allow `C-g' (the helm one aka + ;; `helm-keyboard-quit') to quit immediately. + (inhibit-quit source-process-p)) (helm-log "helm-get-candidate-number => %S" (helm-get-candidate-number)) (helm-log "helm-execute-action-at-once-if-one = %S" @@ -3746,7 +3794,7 @@ For PRESELECT RESUME KEYMAP DEFAULT HISTORY, see `helm'." (ignore)) ; Don't enter the minibuffer loop. ((and helm-quit-if-no-candidate (= (helm-get-candidate-number) 0)) - (setq helm-quit t) + (setq helm--quit t) (and (functionp helm-quit-if-no-candidate) (funcall helm-quit-if-no-candidate))) (t ; Enter now minibuffer and wait for input. @@ -3867,7 +3915,7 @@ map)." ;; e.g C-x C-f M-y C-g ;; => *find-files have now the bindings of *kill-ring. ;; It is no more true now we are using `minor-mode-overriding-map-alist' - ;; and `helm--minor-mode' thus it fix issue #1076 for emacs-24.3 + ;; and `helm--minor-mode' thus it fix Bug#1076 for emacs-24.3 ;; where concurrent timers are not supported. ;; i.e update keymap+check input. (with-current-buffer (window-buffer (minibuffer-window)) @@ -3902,11 +3950,17 @@ WARNING: Do not use this mode yourself, it is internal to Helm." (defun helm-cleanup () "Clean up the mess when Helm exit or quit." (helm-log "start cleanup") - (with-current-buffer helm-buffer + (with-selected-window + ;; When exiting with `helm-execute-action-at-once-if-one', + ;; `helm-window' may not be created and we endup with an error + ;; e.g. in eshell completion when only one candidate to complete + ;; so fallback to selected-window in such cases. + (or (get-buffer-window helm-buffer) + (selected-window)) (let ((frame (selected-frame))) - (setq cursor-type t) + (setq cursor-type (default-value 'cursor-type)) ;; Ensure restoring default-value of mode-line to allow user - ;; using the mouse when helm is inactive (issues #1517,#2377). + ;; using the mouse when helm is inactive (Bug#1517,Bug#2377). (setq mode-line-format (default-value 'mode-line-format)) (remove-hook 'post-command-hook 'helm--maybe-update-keymap) (remove-hook 'post-command-hook 'helm--update-header-line) @@ -3929,7 +3983,8 @@ WARNING: Do not use this mode yourself, it is internal to Helm." ;; may not have been consumed. (when helm--temp-hooks (cl-loop for (fn . hook) in helm--temp-hooks - do (set hook (delete fn (symbol-value hook))))) + do (remove-hook hook fn)) + (setq helm--temp-hooks nil)) ;; When running helm from a dedicated frame ;; with no minibuffer, helm will run in the main frame ;; which have a minibuffer, so be sure to disable @@ -3965,10 +4020,9 @@ WARNING: Do not use this mode yourself, it is internal to Helm." ;; (defun helm-check-minibuffer-input () "Check minibuffer content." - (with-helm-quittable - (with-selected-window (or (active-minibuffer-window) - (minibuffer-window)) - (helm-check-new-input (minibuffer-contents))))) + (with-selected-window (or (active-minibuffer-window) + (minibuffer-window)) + (helm-check-new-input (minibuffer-contents)))) (defun helm-check-new-input (input) "Check INPUT string and update the helm buffer if necessary." @@ -3996,7 +4050,7 @@ WARNING: Do not use this mode yourself, it is internal to Helm." "Retrieve and return the list of candidates from SOURCE." (let* ((candidate-fn (assoc-default 'candidates source)) (candidate-proc (assoc-default 'candidates-process source)) - ;; See comment in helm-get-cached-candidates (Issue #2113). + ;; See comment in helm-get-cached-candidates (Bug#2113). (inhibit-quit candidate-proc) cfn-error (notify-error @@ -4033,7 +4087,7 @@ WARNING: Do not use this mode yourself, it is internal to Helm." ;; Can happen when the output of a process ;; is empty, and the candidates function call ;; something like (split-string (buffer-string) "\n") - ;; which result in a list of one empty string (Issue #938). + ;; which result in a list of one empty string (Bug#938). ;; e.g (completing-read "test: " '("")) (equal candidates '(""))) nil) @@ -4045,23 +4099,16 @@ WARNING: Do not use this mode yourself, it is internal to Helm." (helm-transform-candidates candidates source)) (t (funcall notify-error))))) -(defmacro helm-while-no-input (&rest body) - "Same as `while-no-input' but without the `input-pending-p' test." - (declare (debug t) (indent 0)) - (let ((catch-sym (make-symbol "input"))) - `(with-local-quit - (catch ',catch-sym - (let ((throw-on-input ',catch-sym)) - ,@body))))) - (defun helm-get-cached-candidates (source) "Return the cached value of candidates for SOURCE. Cache the candidates if there is no cached value yet." (let* ((name (assoc-default 'name source)) (candidate-cache (gethash name helm-candidate-cache)) ;; Bind inhibit-quit to ensure function terminate in case of - ;; quit from helm-while-no-input and processes are added to - ;; helm-async-processes for further deletion (Issue #2113). + ;; quit from `helm-while-no-input' and processes are added to + ;; helm-async-processes for further deletion (Bug#2113). + ;; FIXME: Is this still needed now `helm-while-no-input' + ;; handles quit-flag? (inhibit-quit (assoc-default 'candidates-process source))) (helm-aif candidate-cache (prog1 it (helm-log "Use cached candidates")) @@ -4166,17 +4213,17 @@ maybe filtered CANDIDATES." This overrides `helm-candidate-number-limit' variable. E.g.: -If \(candidate-number-limit\) is in SOURCE, show all candidates in SOURCE. -If \(candidate-number-limit . 123\) is in SOURCE limit candidate to 123." +If (candidate-number-limit) is in SOURCE, show all candidates in SOURCE. +If (candidate-number-limit . 123) is in SOURCE limit candidate to 123." (helm-aif (assq 'candidate-number-limit source) ;; When assoc value is nil use by default 99999999 otherwise use - ;; the assoc value, when it is a symbol interpret its value (#1831). + ;; the assoc value, when it is a symbol interpret its value (bug#1831). (or (helm-aand (cdr it) (helm-interpret-value it)) 99999999) (or helm-candidate-number-limit 99999999))) (defun helm-candidate-get-display (candidate) "Get searched display part from CANDIDATE. -CANDIDATE is either a string, a symbol, or a \(DISPLAY . REAL\) +CANDIDATE is either a string, a symbol, or a (DISPLAY . REAL) cons cell." (cond ((car-safe candidate)) ((symbolp candidate) @@ -4272,8 +4319,54 @@ This function is used with sources built with `helm-source-sync'." else do (goto-char eol) finally return nil))))) +(defvar helm-fuzzy-default-score-fn #'helm-fuzzy-flex-style-score) (defun helm-score-candidate-for-pattern (candidate pattern) - "Assign score to CANDIDATE according to PATTERN. + "Assign score to CANDIDATE according to PATTERN." + ;; Unknown candidates always go on top. + (if (equal (get-text-property 0 'display candidate) "[?]") + 200.00 + (funcall helm-fuzzy-default-score-fn candidate pattern))) + +;; The flex scoring needs a regexp whereas the fuzzy scoring works +;; directly with helm-pattern, so cache the needed regexp for flex +;; scoring to not (re)compute it at each candidate. We could reuse +;; the regexp cached in `helm--fuzzy-regexp-cache' but it is not +;; exactly the same as the one needed for flex and also it is always +;; computed against the whole helm-pattern which is not usable for +;; e.g. file completion. +(defvar helm--fuzzy-flex-regexp-cache (make-hash-table :test 'equal)) +(defun helm-fuzzy-flex-style-score (candidate pattern) + "Give a score to CANDIDATE according to PATTERN. +A regexp is generated from PATTERN to calculate score. +Score is calculated with the emacs-27 flex algorithm using +`helm-flex--style-score'." + (let ((regexp (helm-aif (gethash pattern helm--fuzzy-flex-regexp-cache) + it + (clrhash helm--fuzzy-flex-regexp-cache) + (puthash pattern (helm--fuzzy-flex-pattern-to-regexp pattern) + helm--fuzzy-flex-regexp-cache)))) + (helm-flex--style-score candidate regexp t))) + +(defun helm--fuzzy-flex-pattern-to-regexp (pattern) + "Return a regexp from PATTERN compatible with emacs-27 flex algorithm." + (completion-pcm--pattern->regex + (helm-completion--flex-transform-pattern (list pattern)) 'group)) + +(defun helm-flex-add-score-as-prop (candidates regexp) + (cl-loop with case-fold-search = (helm-set-case-fold-search) + for cand in candidates + collect (helm-flex--style-score cand regexp))) + +(defun helm-completion--flex-transform-pattern (pattern) + ;; "fob" => '(prefix "f" any "o" any "b" any point) + (cl-loop for p in pattern + if (stringp p) nconc + (cl-loop for str across p + nconc (list (string str) 'any)) + else nconc (list p))) + +(defun helm-fuzzy-helm-style-score (candidate pattern) + "Give a score to CANDIDATE according to PATTERN. Score is calculated for contiguous matches found with PATTERN. Score is 100 (maximum) if PATTERN is fully matched in CANDIDATE. One point bonus is added to score when PATTERN prefix matches @@ -4360,23 +4453,25 @@ the candidates." ((> scr1 scr2))))))))) (defun helm-fuzzy-matching-default-sort-fn (candidates _source) - "Default `filtered-candidate-transformer' to sort candidates in fuzzy matching." + "Default `filtered-candidate-transformer' to sort in fuzzy matching." (helm-fuzzy-matching-default-sort-fn-1 candidates)) (defun helm-fuzzy-matching-sort-fn-preserve-ties-order (candidates _source) - "`filtered-candidate-transformer' to sort candidates in fuzzy matching, preserving order of ties. + "Same as `helm-fuzzy-matching-default-sort-fn' but preserving order of ties. The default function, `helm-fuzzy-matching-default-sort-fn', sorts ties by length, shortest first. This function may be more useful when the order of the candidates is meaningful, e.g. with `recentf-list'." (helm-fuzzy-matching-default-sort-fn-1 candidates nil nil t)) -(defun helm--maybe-get-migemo-pattern (pattern) +(defun helm--maybe-get-migemo-pattern (pattern &optional diacritics) (or (and helm-migemo-mode (assoc-default pattern helm-mm--previous-migemo-info)) - pattern)) + (if diacritics + (char-fold-to-regexp pattern) + pattern))) -(defun helm-fuzzy-default-highlight-match (candidate) +(defun helm-fuzzy-default-highlight-match (candidate &optional diacritics) "The default function to highlight matches in fuzzy matching. Highlight elements in CANDIDATE matching `helm-pattern' according to the matching method in use." @@ -4387,7 +4482,7 @@ to the matching method in use." (let* ((pair (and (consp candidate) candidate)) (display (helm-stringify (if pair (car pair) candidate))) (real (cdr pair)) - (regex (helm--maybe-get-migemo-pattern helm-pattern)) + (regex (helm--maybe-get-migemo-pattern helm-pattern diacritics)) (mp (pcase (get-text-property 0 'match-part display) ((pred (string= display)) nil) (str str))) @@ -4403,7 +4498,7 @@ to the matching method in use." (with-temp-buffer ;; Insert the whole display part and remove non--match-part ;; to keep their original face properties. - (insert (propertize (or mp display) 'read-only nil)) ; Fix (#1176) + (insert (propertize (or mp display) 'read-only nil)) ; Fix (bug#1176) (goto-char (point-min)) (condition-case nil (progn @@ -4416,8 +4511,11 @@ to the matching method in use." (when (zerop count) (cl-loop with multi-match = (string-match-p " " helm-pattern) with patterns = (if multi-match - (mapcar #'helm--maybe-get-migemo-pattern - (helm-mm-split-pattern helm-pattern)) + (cl-loop for pat in (helm-mm-split-pattern + helm-pattern) + collect + (helm--maybe-get-migemo-pattern + pat diacritics)) (split-string helm-pattern "" t)) for p in patterns ;; Multi matches (regexps patterns). @@ -4440,61 +4538,65 @@ to the matching method in use." (setq display (if mp (concat beg-str (buffer-string) end-str) (buffer-string)))) (if real (cons display real) display)))) -(defun helm-fuzzy-highlight-matches (candidates _source) +(defun helm-fuzzy-highlight-matches (candidates source) "The filtered-candidate-transformer function to highlight fuzzy matches. See `helm-fuzzy-default-highlight-match'." (cl-assert helm-fuzzy-matching-highlight-fn nil "Wrong type argument functionp: nil") - (cl-loop for c in candidates - collect (funcall helm-fuzzy-matching-highlight-fn c))) + (cl-loop with diac = (helm-get-attr 'diacritics source) + for c in candidates + collect (funcall helm-fuzzy-matching-highlight-fn c diac))) ;;; helm-flex style ;; ;; Provide the emacs-27 flex style for emacs<27. ;; Reuse the flex scoring algorithm of flex style in emacs-27. -(defun helm-flex--style-score (str regexp) - "Score STR candidate according to PATTERN. +(defun helm-flex--style-score (str regexp &optional score) + "Score STR candidate according to REGEXP. REGEXP should be generated from a pattern which is a list like -\'(point \"f\" any \"o\" any \"b\" any) for \"fob\" as pattern. -Such pattern is build with -`helm-completion--flex-transform-pattern' function. +\\='(point \"f\" any \"o\" any \"b\" any) for \"fob\" as pattern. +Such pattern may be build with +`helm-completion--flex-transform-pattern' function, and the regexp +with `completion-pcm--pattern->regex'. For commodity, +`helm--fuzzy-flex-pattern-to-regexp' is used to build such regexp. Function extracted from `completion-pcm--hilit-commonality' in emacs-27 to provide such scoring in emacs<27." ;; Don't modify the string itself. (setq str (copy-sequence str)) - (unless (string-match regexp str) - (error "Internal error: %s does not match %s" regexp str)) - (let* ((md (match-data)) - (start (pop md)) - (len (length str)) - (score-numerator 0) - (score-denominator 0) - (last-b 0) - (update-score - (lambda (a b) - "Update score variables given match range (A B)." - (setq score-numerator (+ score-numerator (- b a))) - (unless (or (= a last-b) - (zerop last-b) - (= a (length str))) - (setq score-denominator (+ score-denominator - 1 - (expt (- a last-b 1) - (/ 1.0 3))))) - (setq last-b b)))) - (funcall update-score start start) - (setq md (cdr md)) - (while md - (funcall update-score start (pop md)) - (setq start (pop md))) - (funcall update-score len len) - (unless (zerop (length str)) - (put-text-property - 0 1 'completion-score - (/ score-numerator (* len (1+ score-denominator)) 1.0) str))) - str) + (if (string-match regexp str) + (let* ((md (match-data)) + (start (pop md)) + (len (length str)) + (score-numerator 0) + (score-denominator 0) + (last-b 0) + (update-score + (lambda (a b) + "Update score variables given match range (A B)." + (setq score-numerator (+ score-numerator (- b a))) + (unless (or (= a last-b) + (zerop last-b) + (= a (length str))) + (setq score-denominator (+ score-denominator + 1 + (expt (- a last-b 1) + (/ 1.0 3))))) + (setq last-b b))) + result) + (funcall update-score start start) + (setq md (cdr md)) + (while md + (funcall update-score start (pop md)) + (setq start (pop md))) + (funcall update-score len len) + (unless (zerop (length str)) + (setq result (/ score-numerator (* len (1+ score-denominator)) 1.0)) + (put-text-property 0 1 'completion-score result str)) + (if (and score result) result str)) + (put-text-property 0 1 'completion-score 0.0 str) + (if score 0.0 str))) ;;; Matching candidates @@ -4527,6 +4629,8 @@ emacs-27 to provide such scoring in emacs<27." for disp = (helm-candidate-get-display c) while (< count limit) for target = (if (helm-get-attr 'match-on-real source) + ;; Let's fails on error in + ;; case next block returns nil. (or (cdr-safe c) (get-text-property 0 'helm-realvalue disp)) disp) @@ -4627,6 +4731,23 @@ emacs-27 to provide such scoring in emacs<27." (put-text-property start (point) 'helm-multiline t))))) +(defmacro helm-while-no-input (&rest body) + "Same as `while-no-input' but returns either BODY or nil. +Unlike `while-no-input' this macro ensure to not returns `t'." + (declare (debug t) (indent 0)) + (let ((catch-sym (make-symbol "input"))) + `(with-local-quit + (catch ',catch-sym + (let ((throw-on-input ',catch-sym) + val) + (setq val (progn ,@body)) + ;; See comments in `while-no-input' about resetting + ;; quit-flag. + (cond ((eq quit-flag throw-on-input) + (setq quit-flag nil)) + (quit-flag nil) + (t val))))))) + (defmacro helm--maybe-use-while-no-input (&rest body) "Wrap BODY in `helm-while-no-input' unless initializing a remote connection." `(progn @@ -4635,13 +4756,20 @@ emacs-27 to provide such scoring in emacs<27." ;; Tramp will ask for passwd, don't use `helm-while-no-input'. ,@body (helm-log "Using here `helm-while-no-input'") - (helm-while-no-input ,@body)))) + ;; Emacs bug , unexpected + ;; dbus-event is triggered on dbus init. + ;; Ignoring the dbus-event work on emacs28+; for emacs27 or older + ;; version, require tramp-archive can workaround the issue. + (let ((while-no-input-ignore-events + (and (boundp 'while-no-input-ignore-events) + (cons 'dbus-event while-no-input-ignore-events)))) + (helm-while-no-input ,@body))))) (defun helm--collect-matches (src-list) "Return a list of matches for each source in SRC-LIST. The resulting value is a list of lists, e.g. ((a b c) (c d) (e -f)) or \(nil nil nil) for three sources when no matches found, +f)) or (nil nil nil) for three sources when no matches found, however this function can be interrupted by new input and in this case returns a plain nil i.e. not (nil), in this case `helm-update' is not rendering the source, keeping previous @@ -4727,13 +4855,13 @@ without recomputing them, it should be a list of lists." (setq matches (or candidates (helm--collect-matches sources)))) ;; If computing matches finished and is not interrupted ;; erase the helm-buffer and render results (Fix #1157). - (when matches ;; nil only when interrupted by helm-while-no-input. + (when matches ;; nil only when interrupted by while-no-input. (erase-buffer) ; [1] (cl-loop for src in sources for mtc in matches do (helm-render-source src mtc)) ;; Move to first line only when there is matches - ;; to avoid cursor moving upside down (issue #1703). + ;; to avoid cursor moving upside down (Bug#1703). (helm--update-move-first-line))) ;; When there is only one async source, update mode-line and run ;; `helm-after-update-hook' in `helm-output-filter--post-process', @@ -4767,8 +4895,9 @@ without recomputing them, it should be a list of lists." (helm-aif (assq 'requires-pattern source) (or (cdr it) 1) 0)) ;; Entering repeatedly these strings (*, ?) takes 100% CPU ;; and hang emacs on MacOs preventing deleting backward those - ;; characters (issue #1802). - (not (string-match-p "\\`[*]+\\'" helm-pattern)) + ;; characters (Bug#1802). Update: it seems it is no more true, + ;; thus this affect bug#2423, so let's remove this for now. + ;; (not (string-match-p "\\`[*]+\\'" helm-pattern)) ;; These incomplete regexps hang helm forever ;; so defer update. Maybe replace spaces quoted when using ;; multi-match. @@ -4893,6 +5022,7 @@ your candidates from `helm-async-outer-limit-hook'." "Remove SOURCE from `helm-candidate-cache'." (remhash (assoc-default 'name source) helm-candidate-cache)) +(defvar helm-drag-mouse-1-fn 'ignore) (defun helm-insert-match (match insert-function &optional num source) "Insert MATCH into `helm-buffer' with INSERT-FUNCTION. If MATCH is a cons cell then insert the car as display with the @@ -4919,6 +5049,7 @@ specified as respectively `helm-cand-num' and `helm-cur-source'." (put-text-property start end 'helm-realvalue realvalue))) (when map + (define-key map [drag-mouse-1] 'ignore) (define-key map [mouse-1] 'helm-mouse-select-candidate) (define-key map [mouse-2] 'ignore) (define-key map [mouse-3] 'helm-menu-select-action) @@ -4952,6 +5083,7 @@ specified as respectively `helm-cand-num' and `helm-cur-source'." (let ((inhibit-read-only t) (map (get-text-property pos 'keymap))) (when map + (define-key map [drag-mouse-1] helm-drag-mouse-1-fn) (define-key map [mouse-2] 'helm-maybe-exit-minibuffer) (put-text-property helm-selection-point @@ -5050,7 +5182,7 @@ This will work only in Emacs-26+, i.e. Emacs versions that have ;; (defun helm-output-filter (process output-string) "The `process-filter' function for Helm async sources." - (with-helm-quittable + (with-local-quit (helm-output-filter-1 (assoc process helm-async-processes) output-string))) (defun helm-output-filter-1 (process-assoc output-string) @@ -5072,7 +5204,8 @@ This will work only in Emacs-26+, i.e. Emacs versions that have (defun helm-output-filter--process-source (process output-string source limit) (cl-dolist (candidate (helm-transform-candidates (helm-output-filter--collect-candidates - (split-string output-string "\n") + (split-string output-string + helm-process-output-split-string-separator) (assq 'incomplete-line source)) source t)) (setq candidate @@ -5116,7 +5249,7 @@ This will work only in Emacs-26+, i.e. Emacs versions that have ;; incomplete-line-info assumed output was truncated in ;; only two chunks. But output could be large and ;; truncated in more than two chunks. Therefore store - ;; 'newline' to contain the previous chunks (Issue #1187). + ;; 'newline' to contain the previous chunks (Bug#1187). finally do (setcdr incomplete-line-info newline)))) (defun helm-output-filter--post-process () @@ -5259,7 +5392,7 @@ If action buffer is selected, back to the Helm buffer." (helm-subr-native-elisp-p actions)) "Anonymous" actions)) (helm-show-action-buffer actions) - ;; Be sure the minibuffer is entirely deleted (#907). + ;; Be sure the minibuffer is entirely deleted (bug#907). (helm--delete-minibuffer-contents-from "") (helm--set-action-prompt) (helm-check-minibuffer-input)))) @@ -5344,7 +5477,7 @@ If action buffer is selected, back to the Helm buffer." ;; Selection of candidates (defun helm-display-source-at-screen-top-maybe (unit) - "Display source at the top of screen when UNIT value is 'source. + "Display source at the top of screen when UNIT value is \\='source. Return nil for any other value of UNIT." (when (and helm-display-source-at-screen-top (eq unit 'source)) (set-window-start (selected-window) @@ -5352,7 +5485,7 @@ Return nil for any other value of UNIT." (defun helm-skip-noncandidate-line (direction) "Skip source header or candidates separator when going in DIRECTION. -DIRECTION is either 'next or 'previous. +DIRECTION is either \\='next or \\='previous. Same as `helm-skip-header-and-separator-line' but ensure point is moved to the right place when at bob or eob." (helm-skip-header-and-separator-line direction) @@ -5361,7 +5494,7 @@ moved to the right place when at bob or eob." (defun helm-skip-header-and-separator-line (direction) "Skip source header or candidate separator when going to next/previous line. -DIRECTION is either 'next or 'previous." +DIRECTION is either \\='next or \\='previous." (let ((fn (cl-ecase direction (next 'eobp) (previous 'bobp)))) @@ -5453,7 +5586,7 @@ mode and header lines." (with-selected-window (minibuffer-window) (when helm-display-header-line ;; Prevent cursor movement over the overlay displaying - ;; persistent-help in minibuffer (issue #2108). + ;; persistent-help in minibuffer (Bug#2108). (setq-local disable-point-adjustment t)) (let* ((beg (save-excursion (vertical-motion 0 (helm-window)) (point))) (end (save-excursion (end-of-visual-line) (point))) @@ -5469,11 +5602,11 @@ mode and header lines." "->" 'face 'helm-header-line-left-margin)))) (pos (- (point) beg))) - ;; Increment pos each time we find a "%" up to current-pos (#1648). + ;; Increment pos each time we find a "%" up to current-pos (bug#1648). (cl-loop for c across (buffer-substring-no-properties beg (point)) when (eql c ?%) do (cl-incf pos)) ;; Increment pos when cursor is on a "%" to make it visible in header-line - ;; i.e "%%|" and not "%|%" (#1649). + ;; i.e "%%|" and not "%|%" (bug#1649). (when (eql (char-after) ?%) (setq pos (1+ pos))) (setq cont (replace-regexp-in-string "%" "%%" cont)) (with-helm-buffer @@ -5540,7 +5673,7 @@ It has no effect if `helm-echo-input-in-header-line' is nil." (defun helm-show-candidate-number (&optional name) "Used to display candidate number in mode-line. You can specify NAME of candidates e.g. \"Buffers\" otherwise it -is \"Candidate\(s\)\" by default." +is \"Candidate(s)\" by default." (when helm-alive-p (unless (helm-empty-source-p) ;; Build a fixed width string when candidate-number < 1000 @@ -5566,7 +5699,7 @@ Key arg WHERE can be one of: Key arg DIRECTION can be one of: - previous - next - - A source or a source name when used with :WHERE 'source." + - A source or a source name when used with :WHERE \\='source." (let ((move-func (cl-case where (line (cl-ecase direction (previous 'helm-move--previous-line-fn) @@ -5652,16 +5785,17 @@ Key arg DIRECTION can be one of: helm-selection-overlay)) (helm-end-of-source-p t))) (helm-end-of-source-p t))) - (helm-move--beginning-of-source))) + (helm-move--beginning-of-source) + (helm-display-source-at-screen-top-maybe 'source))) (defun helm-move--previous-page-fn () (condition-case nil - (scroll-down) + (scroll-down helm-scroll-amount) (beginning-of-buffer (goto-char (point-min))))) (defun helm-move--next-page-fn () (condition-case nil - (scroll-up) + (scroll-up helm-scroll-amount) (end-of-buffer (goto-char (point-max))))) (defun helm-move--beginning-of-buffer-fn () @@ -5694,7 +5828,7 @@ Key arg DIRECTION can be one of: (forward-line 1) (eobp))) ;; Empty source at eob are just ;; not displayed unless they are dummy. - ;; Issue #1117. + ;; Bug#1117. (helm-get-next-header-pos)) (point-min)))) @@ -5751,18 +5885,34 @@ next source)." (helm--next-or-previous-line 'next arg))) (put 'helm-next-line 'helm-only t) +(defun helm-scroll-up () + "Scroll up helm-buffer by `helm-scroll-amount' lines." + (interactive) + (with-helm-alive-p + (helm-move-selection-common :where 'page :direction 'previous))) +(put 'helm-scroll-up 'helm-only t) + (defun helm-previous-page () "Move selection back with a pageful." (interactive) (with-helm-alive-p - (helm-move-selection-common :where 'page :direction 'previous))) + (let (helm-scroll-amount) + (helm-move-selection-common :where 'page :direction 'previous)))) (put 'helm-previous-page 'helm-only t) +(defun helm-scroll-down () + "Scroll down helm-buffer by `helm-scroll-amount' lines." + (interactive) + (with-helm-alive-p + (helm-move-selection-common :where 'page :direction 'next))) +(put 'helm-scroll-down 'helm-only t) + (defun helm-next-page () "Move selection forward with a pageful." (interactive) (with-helm-alive-p - (helm-move-selection-common :where 'page :direction 'next))) + (let (helm-scroll-amount) + (helm-move-selection-common :where 'page :direction 'next)))) (put 'helm-next-page 'helm-only t) (defun helm-beginning-of-buffer () @@ -5872,10 +6022,10 @@ marking candidates." (defun helm-confirm-and-exit-minibuffer () "Maybe ask for confirmation when exiting helm. It is similar to `minibuffer-complete-and-exit' adapted to Helm. -If `minibuffer-completion-confirm' value is 'confirm, send +If `minibuffer-completion-confirm' value is \\='confirm, send minibuffer confirm message and exit on next hit. If `minibuffer-completion-confirm' value is t, don't exit and send -message 'no match'." +message \\='no match'." (interactive) (with-helm-alive-p (if (and (helm--updating-p) @@ -6058,14 +6208,6 @@ to a list of forms.\n\n") ;; Misc -(defun helm-kill-buffer-hook () - "Remove tick entry from `helm-tick-hash' and remove buffer from -`helm-buffers' when killing a buffer." - (cl-loop for key being the hash-keys in helm-tick-hash - if (string-match (format "^%s/" (regexp-quote (buffer-name))) key) - do (remhash key helm-tick-hash)) - (setq helm-buffers (remove (buffer-name) helm-buffers))) -(add-hook 'kill-buffer-hook 'helm-kill-buffer-hook) (defun helm-preselect (candidate-or-regexp &optional source) "Move selection to CANDIDATE-OR-REGEXP on Helm start. @@ -6095,7 +6237,7 @@ Optional argument SOURCE is a Helm source object." (re-search-forward (cdr candidate-or-regexp) nil t)) (re-search-forward candidate-or-regexp nil t)) ;; If search fall on an header line continue loop - ;; until it match or fail (Issue #1509). + ;; until it match or fail (Bug#1509). (unless (helm-pos-header-line-p) (cl-return (setq mp it)))) (goto-char (or mp start))))) (forward-line 0) ; Avoid scrolling right on long lines. @@ -6191,12 +6333,14 @@ delete minibuffer contents from point instead of deleting all. With a prefix arg reverse this behaviour. When at the end of minibuffer, delete all." (interactive "P") - (let ((str (if helm-delete-minibuffer-contents-from-point - (if (or arg (eobp)) - "" (helm-minibuffer-completion-contents)) - (if (and arg (not (eobp))) - (helm-minibuffer-completion-contents) "")))) - (helm--delete-minibuffer-contents-from str))) + (with-helm-alive-p + (let ((str (if helm-delete-minibuffer-contents-from-point + (if (or arg (eobp)) + "" (helm-minibuffer-completion-contents)) + (if (and arg (not (eobp))) + (helm-minibuffer-completion-contents) "")))) + (helm--delete-minibuffer-contents-from str)))) +(put 'helm-delete-minibuffer-contents 'no-helm-mx t) ;;; helm-source-in-buffer. @@ -6216,12 +6360,12 @@ E.g.: (helm-build-in-buffer-source \"test\" :init (lambda () (helm-init-candidates-in-buffer - 'global '(foo foa fob bar baz)))) + \\='global \\='(foo foa fob bar baz)))) A shortcut can be used to simplify: (helm-build-in-buffer-source \"test\" - :data '(foo foa fob bar baz)) + :data \\='(foo foa fob bar baz)) By default, Helm makes candidates by evaluating the candidates function, then narrows them by `string-match' for each candidate. @@ -6298,7 +6442,8 @@ To customize `helm-candidates-in-buffer' behaviour, use `search', (defun helm-search-from-candidate-buffer (pattern get-line-fn search-fns limit start-point match-part-fn source) - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) + (diacritics (assoc-default 'diacritics source))) (helm--search-from-candidate-buffer-1 (lambda () (cl-loop with hash = (make-hash-table :test 'equal) @@ -6353,14 +6498,14 @@ To customize `helm-candidates-in-buffer' behaviour, use `search', ;; returns a cons cell, collect PATTERN only if it ;; match the part of CAND specified by ;; the match-part func. - (helm-search-match-part cand pattern))) + (helm-search-match-part cand pattern diacritics))) do (progn (puthash cand iter hash) (helm--maybe-process-filter-one-by-one-candidate cand source) (cl-incf count)) and collect cand)))))) -(defun helm-search-match-part (candidate pattern) +(defun helm-search-match-part (candidate pattern diacritics) "Match PATTERN only on match-part property value of CANDIDATE. Because `helm-search-match-part' may be called even if @@ -6370,8 +6515,9 @@ computed by match-part-fn and stored in the match-part property." (let ((part (or (get-text-property 0 'match-part candidate) candidate)) (fuzzy-regexp (cadr (gethash 'helm-pattern helm--fuzzy-regexp-cache))) - (matchfn (if helm-migemo-mode - 'helm-mm-migemo-string-match 'string-match))) + (matchfn (cond (helm-migemo-mode 'helm-mm-migemo-string-match) + (diacritics 'helm-mm-diacritics-string-match) + (t 'string-match)))) (if (string-match " " pattern) (cl-loop for i in (helm-mm-split-pattern pattern) always (if (string-match "\\`!" i) @@ -6386,11 +6532,11 @@ computed by match-part-fn and stored in the match-part property." (funcall matchfn (if helm--in-fuzzy fuzzy-regexp pattern) part))))) (defun helm-initial-candidates-from-candidate-buffer (get-line-fn limit) - (delq nil (cl-loop for i from 1 to limit - until (eobp) - collect (funcall get-line-fn - (point-at-bol) (point-at-eol)) - do (forward-line 1)))) + (cl-loop repeat limit + until (eobp) + for line = (funcall get-line-fn (point-at-bol) (point-at-eol)) + when line collect line + do (forward-line 1))) (defun helm--search-from-candidate-buffer-1 (search-fn) ;; We are adding a newline at bob and at eol @@ -6483,9 +6629,9 @@ before running again the init function." (delete (assoc helm--source-name helm--candidate-buffer-alist) helm--candidate-buffer-alist))) - ;; When using global or local as value of CREATE-OR-BUFFER + ;; When using global or local as value of BUFFER-SPEC ;; create the buffer global-bname or local-bname, otherwise - ;; reuse the named buffer. + ;; reuse the buffer named BUFFER-SPEC. (unless (bufferp buffer-spec) ;; Global buffers are killed and recreated. (and (eq buffer-spec 'global) @@ -6495,11 +6641,13 @@ before running again the init function." ;; Local buffer, once created are reused and a new one ;; is created when `helm-current-buffer' change across sessions. (with-current-buffer (get-buffer-create - (cl-ecase buffer-spec + (helm-acase buffer-spec (global global-bname) - (local local-bname))) + (local local-bname) + (t (and (stringp buffer-spec) + buffer-spec)))) ;; We need a buffer not read-only to perhaps insert later - ;; text coming from read-only buffers (issue #1176). + ;; text coming from read-only buffers (Bug#1176). (set (make-local-variable 'buffer-read-only) nil) ;; Undo is automatically disabled in buffer names starting ;; with a space, so no need to disable it. @@ -6513,13 +6661,20 @@ before running again the init function." (buffer-live-p (get-buffer it)) it))))) +(defvar helm-candidate-buffer-longest-len 0 + "May store the longest length of candidates in a in-buffer source. +It is a local variable set from `helm-init-candidates-in-buffer' in +`helm-candidate-buffer'. +Allow getting the longest length of initial candidates in transformers +without looping again through the whole list.") + (defun helm-init-candidates-in-buffer (buffer-spec data) "Register BUFFER-SPEC with DATA for a helm candidates-in-buffer session. Arg BUFFER-SPEC can be a `buffer-name' (stringp), a buffer-spec -object \(bufferp), or a symbol, either 'local or 'global which is +object (bufferp), or a symbol, either \\='local or \\='global which is passed to `helm-candidate-buffer'. -The most common usage of BUFFER-SPEC is 'global. +The most common usage of BUFFER-SPEC is \\='global. Arg DATA can be either a list or a plain string. Returns the resulting buffer. @@ -6532,19 +6687,19 @@ when initializing a source with `helm-source-in-buffer' class." (let ((caching (and (or (stringp buffer-spec) (bufferp buffer-spec)) (buffer-live-p (get-buffer buffer-spec)))) - (buf (helm-candidate-buffer - (if (or (stringp buffer-spec) - (bufferp buffer-spec)) - (get-buffer-create buffer-spec) - buffer-spec)))) ; a symbol 'global or 'local. + (buf (helm-candidate-buffer buffer-spec))) (unless caching (with-current-buffer buf (erase-buffer) (cond ((listp data) (insert (mapconcat (lambda (i) - (cond ((symbolp i) (symbol-name i)) - ((numberp i) (number-to-string i)) - (t i))) + (let ((cand (cond ((symbolp i) (symbol-name i)) + ((numberp i) (number-to-string i)) + (t i)))) + (setq-local helm-candidate-buffer-longest-len + (max helm-candidate-buffer-longest-len + (length cand))) + cand)) data "\n"))) ((stringp data) (insert data)))) buf))) @@ -6695,7 +6850,7 @@ If N is positive enlarge, if negative narrow." (defun helm--get-window-side-state () "Return the position of `helm-window' from `helm-current-buffer'. -Possible values are 'left 'right 'below or 'above." +Possible values are \\='left \\='right \\='below or \\='above." (let ((side-list '(left right below above))) (cl-loop for side in side-list thereis (and (equal (helm-window) @@ -6802,7 +6957,7 @@ splitting inconditionally, it is unused actually." :split (or split helm-onewindow-p))) (helm-log "current-buffer = %S" (current-buffer)) (let ((helm-in-persistent-action t) - (same-window-regexps '(".")) + (display-buffer-alist '((".*" (display-buffer-same-window)))) display-buffer-function pop-up-windows pop-up-frames special-display-regexps special-display-buffer-names) (helm-execute-selection-action-1 @@ -6826,35 +6981,19 @@ splitting inconditionally, it is unused actually." (cl-defun helm-persistent-action-display-window (&key split) "Return the window that will be used for persistent action. If SPLIT is t window is split in persistent action, if it has the -special symbol `never' don't split, if it is nil normally don't -split but this may happen in case of dedicated-windows or -unsuitable window to display persistent action buffer." +special symbol `never' don't split, if it is nil don't split either. +The symbol `never' is kept for backward compatibility." (with-helm-window - (let (prev-win cur-win) - (setq helm-persistent-action-display-window - (cond ((and (window-live-p helm-persistent-action-display-window) - (not (member helm-persistent-action-display-window - (get-buffer-window-list helm-buffer)))) - helm-persistent-action-display-window) - ((and helm--buffer-in-new-frame-p helm-initial-frame) - (with-selected-frame helm-initial-frame (selected-window))) - ((and split (not (eq split 'never))) (split-window)) - ;; Fix Issue #2050 with dedicated window. - ((and (window-dedicated-p - (setq prev-win (previous-window (selected-window) 1))) - (not (eq split 'never))) - (with-helm-after-update-hook - (and (window-live-p helm-persistent-action-display-window) - (delete-window helm-persistent-action-display-window))) - ;; If next-window is usable use it, otherwise split - ;; the helm window. - (let ((nw (next-window (selected-window) 1))) - (if (eql nw prev-win) (split-window) nw))) - ((window-dedicated-p - (setq cur-win (get-buffer-window helm-current-buffer))) - (previous-window (selected-window) 1)) - (cur-win) - (t prev-win)))))) + (setq helm-persistent-action-display-window + (cond ((and (window-live-p helm-persistent-action-display-window) + (not (member helm-persistent-action-display-window + (get-buffer-window-list helm-buffer)))) + helm-persistent-action-display-window) + ((and helm--buffer-in-new-frame-p helm-initial-frame) + (with-selected-frame helm-initial-frame (selected-window))) + ((and split (not (eq split 'never))) (split-window)) + ((get-buffer-window helm-current-buffer)) + (t (previous-window (selected-window) 1)))))) (cl-defun helm-select-persistent-action-window (&key split) "Select the window that will be used for persistent action. @@ -6948,10 +7087,16 @@ Meaning of prefix ARG is the same as in `reposition-window'." (o (make-overlay (point-at-bol) selection-end))) (overlay-put o 'priority 0) (overlay-put o 'face 'helm-visible-mark) - (overlay-put o 'source (assoc-default 'name source)) + (overlay-put o 'source source) (overlay-put o 'string (buffer-substring (overlay-start o) (overlay-end o))) (overlay-put o 'real sel) + (overlay-put o 'before-string (propertize " " 'display + `((margin left-margin) + ,(propertize + helm-visible-mark-prefix + 'face 'helm-mark-prefix)))) (overlay-put o 'visible-mark t) + (overlay-put o 'evaporate t) (cl-pushnew o helm-visible-mark-overlays) (push (cons source sel) helm-marked-candidates))) @@ -6977,7 +7122,12 @@ If ARG is negative toggle backward." (progn (helm-display-mode-line (helm-get-current-source)) (cl-return nil)) - (funcall (cdr next-fns)))))))))) + (funcall (cdr next-fns))))) + (set-window-margins (selected-window) + (if helm-visible-mark-overlays + (+ (string-width helm-visible-mark-prefix) + helm-left-margin-width) + helm-left-margin-width))))))) (put 'helm-toggle-visible-mark 'helm-only t) (defun helm-toggle-visible-mark-forward () @@ -7003,7 +7153,11 @@ With a prefix arg mark all visible unmarked candidates in all sources." (interactive "P") (with-helm-alive-p - (with-helm-window ; Using `with-helm-buffer' for some unknow reasons infloop. + (with-helm-window ; Using `with-helm-buffer' for some unknow + ; reasons infloop. + (set-window-margins (selected-window) + (+ (string-width helm-visible-mark-prefix) + helm-left-margin-width)) (if (null all) (helm-mark-all-1 t) (let ((pos (point))) @@ -7064,7 +7218,7 @@ starting it is not needed." ;; Non existing files in HFF and ;; RFN. Display may be an image. See ;; https://github.com/yyoncho/helm-treemacs-icons/issues/5 - ;; and also issue #2296. + ;; and also Bug#2296. (equal prefix "[?]") (and filecomp-p (or @@ -7090,7 +7244,8 @@ starting it is not needed." (helm-clear-visible-mark)) (setq helm-marked-candidates nil) (helm-mark-current-line) - (helm-display-mode-line (helm-get-current-source))))) + (helm-display-mode-line (helm-get-current-source)) + (set-window-margins (selected-window) helm-left-margin-width)))) (put 'helm-unmark-all 'helm-only t) (defun helm-toggle-all-marks (&optional all) @@ -7176,18 +7331,29 @@ sources." (with-current-buffer helm-buffer (save-excursion (cl-dolist (o helm-visible-mark-overlays) - (let ((o-src-str (overlay-get o 'source)) - (o-str (overlay-get o 'string)) - beg end) + (let* ((source (overlay-get o 'source)) + (ov-src-name (assoc-default 'name source)) + (ov-str (overlay-get o 'string)) + (ov-real (overlay-get o 'real)) + (ov-ml-str (helm-aif (helm-get-attr 'multiline source) + (if (numberp it) + ;; Assume display have been computed + ;; against real e.g. kill-ring. + (helm--multiline-get-truncated-candidate + ov-real it) + ov-str) + ov-str)) + beg end) ;; Move point to end of source header line. (goto-char (point-min)) - (search-forward o-src-str nil t) - (while (and (search-forward o-str nil t) + (search-forward ov-src-name nil t) + (while (and (search-forward ov-ml-str nil t) (cl-loop for ov in (overlays-at (point-at-bol 0)) never (overlay-get ov 'visible-mark)) - (helm-current-source-name= o-src-str)) + (helm-current-source-name= ov-src-name)) (setq beg (match-beginning 0) - end (match-end 0)) + end (if (string= ov-ml-str ov-str) + (match-end 0) (1+ (match-end 0)))) ;; Calculate real value of candidate. ;; It can be nil if candidate have only a display value. (let ((real (get-text-property (point-at-bol 0) 'helm-realvalue))) @@ -7196,10 +7362,10 @@ sources." ;; than the one stored in overlay. ;; This is needed when some cands have same display names. ;; Using equal allow testing any type of value for real cand. - ;; Issue (#706). - (and (equal (overlay-get o 'real) real) + ;; bug#706. + (and (equal ov-real real) (move-overlay o beg end)) - (and (equal o-str (buffer-substring beg end)) + (and (equal ov-str (buffer-substring beg end)) (move-overlay o beg end)))))))))) (add-hook 'helm-after-update-hook 'helm-revive-visible-mark) @@ -7273,20 +7439,22 @@ perform actions." (format "%s" (helm-get-selection nil (not arg)))))) (put 'helm-kill-selection-and-quit 'helm-only t) -(defun helm-copy-to-buffer () - "Copy selection or marked candidates to `helm-current-buffer'. -Note that the real values of candidates are copied and not the -display values." - (interactive) +(defun helm-insert-or-copy (&optional arg) + "Insert selection or marked candidates in current buffer. + +With a prefix arg copy marked candidates to kill-ring. +The real value of each candidate is used." + (interactive "P") (with-helm-alive-p (helm-run-after-exit (lambda (cands) (with-helm-current-buffer - (insert (mapconcat (lambda (c) - (format "%s" c)) - cands "\n")))) + (let ((sels (mapconcat (lambda (c) + (format "%s" c)) + cands "\n"))) + (if arg (kill-new sels) (insert sels))))) (helm-marked-candidates)))) -(put 'helm-copy-to-buffer 'helm-only t) +(put 'helm-insert-or-copy 'helm-only t) ;;; Follow-mode: Automatic execution of persistent-action @@ -7371,7 +7539,7 @@ They are bound by default to \\[helm-follow-action-forward] and (defun helm-follow-execute-persistent-action-maybe (&optional delay) "Execute persistent action in mode `helm-follow-mode'. -This happen after: DELAY or the 'follow-attr value of current +This happen after: DELAY or the \\='follow-attr value of current source or `helm-follow-input-idle-delay' or `helm-input-idle-delay' secs." (let* ((src (helm-get-current-source)) @@ -7473,13 +7641,6 @@ help." (helm-update (regexp-quote (helm-get-selection nil t))))))) (put 'helm-toggle-truncate-line 'helm-only t) - -(provide 'helm) - -;; Local Variables: -;; byte-compile-warnings: (not obsolete) -;; coding: utf-8 -;; indent-tabs-mode: nil -;; End: -;;; helm.el ends here +(provide 'helm-core) +;;; helm-core.el ends here diff --git a/elpa/helm-core-20210128.1814/helm-lib.el b/elpa/helm-core-20220607.1243/helm-lib.el similarity index 87% rename from elpa/helm-core-20210128.1814/helm-lib.el rename to elpa/helm-core-20220607.1243/helm-lib.el index 67d71a6f..565db187 100644 --- a/elpa/helm-core-20210128.1814/helm-lib.el +++ b/elpa/helm-core-20220607.1243/helm-lib.el @@ -1,8 +1,8 @@ ;;; helm-lib.el --- Helm routines. -*- lexical-binding: t -*- -;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto -;; Author: Thierry Volpiatto +;; Author: Thierry Volpiatto ;; URL: http://github.com/emacs-helm/helm ;; This program is free software; you can redistribute it and/or modify @@ -32,21 +32,24 @@ (declare-function dired-mark-remembered "dired.el") (declare-function ffap-file-remote-p "ffap.el") (declare-function ffap-url-p "ffap.el") -(declare-function helm-get-attr "helm.el") -(declare-function helm-set-attr "helm.el") -(declare-function helm-follow-mode-p "helm.el") -(declare-function helm-get-current-source "helm.el") -(declare-function helm-get-selection "helm.el") -(declare-function helm-get-sources "helm.el") -(declare-function helm-interpret-value "helm.el") -(declare-function helm-log-run-hook "helm.el") -(declare-function helm-marked-candidates "helm.el") -(declare-function helm-set-case-fold-search "helm.el") +(declare-function helm-get-attr "helm-core.el") +(declare-function helm-set-attr "helm-core.el") +(declare-function helm-follow-mode-p "helm-core.el") +(declare-function helm-get-current-source "helm-core.el") +(declare-function helm-get-selection "helm-core.el") +(declare-function helm-get-sources "helm-core.el") +(declare-function helm-interpret-value "helm-core.el") +(declare-function helm-log-run-hook "helm-core.el") +(declare-function helm-marked-candidates "helm-core.el") +(declare-function helm-set-case-fold-search "helm-core.el") (declare-function helm-source--cl--print-table "helm-source.el") -(declare-function helm-update "helm.el") +(declare-function helm-update "helm-core.el") (declare-function org-content "org.el") (declare-function org-mark-ring-goto "org.el") (declare-function org-mark-ring-push "org.el") +(declare-function org-table-p "org-compat.el") +(declare-function org-table-align "org-table.el") +(declare-function org-table-end "org-table.el") (declare-function org-open-at-point "org.el") (declare-function wdired-change-to-dired-mode "wdired.el") (declare-function wdired-do-perm-changes "wdired.el") @@ -55,6 +58,9 @@ (declare-function wdired-flag-for-deletion "wdired.el") (declare-function wdired-get-filename "wdired.el") (declare-function wdired-normalize-filename "wdired.el") +(declare-function helm-read-file-name "helm-mode.el") +(declare-function find-function-library "find-func.el") +(declare-function find-library-name "find-func.el") (defvar helm-sources) (defvar helm-initial-frame) @@ -69,6 +75,7 @@ (defvar helm-completion-styles-alist) (defvar helm-persistent-action-window-buffer) (defvar completion-flex-nospace) +(defvar find-function-source-path) ;;; User vars. ;; @@ -90,8 +97,8 @@ already provided by \\\\[next-history-element]." :group 'helm) (defcustom helm-scroll-amount nil - "Scroll amount when scrolling other window in a helm session. -It is used by `helm-scroll-other-window' + "Scroll amount when scrolling helm window or other window in a helm session. +It is used by `helm-scroll-other-window', `helm-scroll-up', `helm-scroll-down' and `helm-scroll-other-window-down'. If you prefer scrolling line by line, set this value to 1." @@ -169,7 +176,8 @@ the customize functions e.g. `customize-set-variable' and NOT (defvar helm-suspend-update-flag nil) (defvar helm-action-buffer "*helm action*" "Buffer showing actions.") - +(defvar helm-current-prefix-arg nil + "Record `current-prefix-arg' when exiting minibuffer.") ;;; Compatibility ;; @@ -190,6 +198,9 @@ available APPEND is ignored." (defun helm--advice-wdired-finish-edit () (interactive) (wdired-change-to-dired-mode) + ;; `wdired-old-marks' has been removed in emacs-28+. + (unless (boundp 'wdired-old-marks) + (setq-local wdired-old-marks nil)) (let ((changes nil) (errors 0) files-deleted @@ -392,24 +403,27 @@ available APPEND is ignored." ;;; Command loop helper ;; +(defconst helm-this-command-black-list + '(helm-maybe-exit-minibuffer + helm-confirm-and-exit-minibuffer + helm-exit-minibuffer + exit-minibuffer + helm-M-x)) + (defun helm-this-command () "Return the actual command in action. Like `this-command' but return the real command, and not `exit-minibuffer' or other unwanted functions." - (cl-loop with bl = '(helm-maybe-exit-minibuffer - helm-confirm-and-exit-minibuffer - helm-exit-minibuffer - exit-minibuffer) - for count from 1 to 50 + (cl-loop for count from 1 to 50 for btf = (backtrace-frame count) for fn = (cl-second btf) if (and ;; In some case we may have in the way an ;; advice compiled resulting in byte-code, - ;; ignore it (Issue #691). + ;; ignore it (Bug#691). (symbolp fn) (commandp fn) - (not (memq fn bl))) + (not (memq fn helm-this-command-black-list))) return fn else if (and (eq fn 'call-interactively) @@ -541,7 +555,7 @@ NOTE: Duplicate keys in CLAUSES are deliberately not handled. (defsubst helm--mapconcat-pattern (pattern) "Transform string PATTERN in regexp for further fuzzy matching. E.g.: helm.el$ - => \"[^h]*h[^e]*e[^l]*l[^m]*m[^.]*[.][^e]*e[^l]*l$\" + => \"[^h]*?h[^e]*?e[^l]*?l[^m]*?m[^.]*?[.][^e]*?e[^l]*?l$\" ^helm.el$ => \"helm[.]el$\"." (let ((ls (split-string-and-unquote pattern ""))) @@ -556,7 +570,7 @@ E.g.: helm.el$ (mapconcat (lambda (c) (if (and (string= c "$") (string-match "$\\'" pattern)) - c (format "[^%s]*%s" c (regexp-quote c)))) + c (format "[^%s]*?%s" c (regexp-quote c)))) ls "")))) (defsubst helm--collect-pairs-in-string (string) @@ -646,9 +660,14 @@ displayed in BUFNAME." (when helm-help-full-frame (delete-other-windows)) (delete-region (point-min) (point-max)) (org-mode) - (org-mark-ring-push) ; Put mark at bob (save-excursion - (funcall insert-content-fn)) + (funcall insert-content-fn) + (goto-char (point-min)) + (while (re-search-forward "^[|]" nil t) + (when (org-table-p t) + (org-table-align) + (goto-char (org-table-end))))) + (org-mark-ring-push) ; Put mark at bob (buffer-disable-undo) (helm-help-event-loop)) (raise-frame hframe) @@ -733,7 +752,7 @@ displayed in BUFNAME." (not (memq fun helm-help-not-interactive-command))) ;; For movement of cursor in help buffer we need to ;; call interactively commands for impaired people - ;; using a synthetizer (#1347). + ;; using a synthetizer (Bug#1347). (call-interactively fun) (funcall fun)))))))) @@ -788,26 +807,27 @@ See `helm-help-hkmap' for supported keys and functions." ;;; List processing ;; -(defun helm-flatten-list (seq &optional omit-nulls) - "Return a list of all single elements of sublists in SEQ." +(defun helm-flatten-list (seq) + "Return a list of all single elements of sublists in SEQ. + + Example: + (helm-flatten-list \\='(1 (2 . 3) nil (4 5 (6) 7) 8 (9 . 10))) + => (1 2 3 4 5 6 7 8 9 10)" (let (result) - (cl-labels ((flatten (seq) - (cl-loop - for elm in seq - if (and (or elm - (null omit-nulls)) - (or (atom elm) - (functionp elm) - (and (consp elm) - (cdr elm) - (atom (cdr elm))))) - do (push elm result) - else do (flatten elm)))) + (cl-labels ((flatten + (seq) + (cl-loop for elm in seq + if (consp elm) + do (flatten + (if (atom (cdr elm)) + (list (car elm) (cdr elm)) + elm)) + else do (and elm (push elm result))))) (flatten seq)) (nreverse result))) (defun helm-mklist (obj) - "If OBJ is a list \(but not lambda\), return itself. + "If OBJ is a list (but not lambda), return itself. Otherwise make a list with one element." (if (and (listp obj) (not (functionp obj))) obj @@ -858,7 +878,7 @@ hashtable itself." (helm-awhile (helm-basedir (directory-file-name (expand-file-name directory))) ;; Break at root to avoid infloop, root is / or on Windows - ;; C:/ i.e. :/ (issue #2308). + ;; C:/ i.e. :/ (Bug#2308). (when (string-match-p "\\`[A-Za-z]?:?/\\'" it) (cl-return nil)) (when (cl-loop for r in black-list @@ -904,9 +924,9 @@ hashtable itself." ARGS is (cand1 cand2 ...) or ((disp1 . real1) (disp2 . real2) ...) -\(helm-transform-mapcar 'upcase '(\"foo\" \"bar\")) +\(helm-transform-mapcar \\='upcase \\='(\"foo\" \"bar\")) => (\"FOO\" \"BAR\") -\(helm-transform-mapcar 'upcase '((\"1st\" . \"foo\") (\"2nd\" . \"bar\"))) +\(helm-transform-mapcar \\='upcase \\='((\"1st\" . \"foo\") (\"2nd\" . \"bar\"))) => ((\"1st\" . \"FOO\") (\"2nd\" . \"BAR\")) " (cl-loop for arg in args @@ -974,6 +994,51 @@ LIST is a list of numbers and NUM a number." collect (cons diff i) into res minimize diff into min finally return (cdr (assq min res)))) + +(defun helm-group-candidates-by (candidates function &optional selection separate) + "Group similar items in CANDIDATES according to FUNCTION. +Items not matching FUNCTION are grouped as well in a separate group. + +Example: + + (setq B \\='(1 2 3 4 5 6 7 8 9)) + + (helm-group-candidates-by B #'cl-oddp 2 \\='separate) + => ((2 4 6 8) (1 3 5 7 9)) + +SELECTION specify where to start in CANDIDATES. +Similar candidates to SELECTION will be listed on top. + +If SEPARATE is non-nil returns a list of groups i.e. a list of lists, +otherwise a plain list is returned." + (cl-loop with sel = (or selection (helm-get-selection) "") + with lst = (copy-sequence candidates) + while lst + for group = (cl-loop for c in lst + when (equal (funcall function c) + (funcall function sel)) + collect c into grp + and do (setq lst (delete c lst)) + finally return (prog1 grp + (setq sel (car lst)))) + if separate collect group + else append group)) + +(defun helm-reorganize-sequence-from-elm (sequence elm &optional reverse) + "Reorganize SEQUENCE from ELM. + +Examples: + + (helm-reorganize-sequence-from-elm \\='(a b c d e f g h i j k l) \\='e) + => (f g h i j k l a b c d e) + (helm-reorganize-sequence-from-elm \\='(a b c d e f g h i j k l) \\='e t) + => (d c b a l k j i h g f e) +" + (let* ((new-seq (if reverse + (reverse sequence) + sequence)) + (pos (1+ (cl-position elm new-seq :test 'equal)))) + (append (nthcdr pos new-seq) (cl-subseq new-seq 0 pos)))) ;;; Strings processing. ;; @@ -1013,11 +1078,15 @@ than WIDTH." (defun helm-get-pid-from-process-name (process-name) "Get pid from running process PROCESS-NAME." - (cl-loop with process-list = (list-system-processes) - for pid in process-list - for process = (assoc-default 'comm (process-attributes pid)) - when (and process (string-match process-name process)) - return pid)) + ;; Protect system processes calls (Issue #2497) + ;; Ensure `list-system-processes' and `process-attributes' don't run + ;; on remote (only Emacs-28/29+). + (cl-loop with default-directory = temporary-file-directory + with process-list = (list-system-processes) + for pid in process-list + for process = (assoc-default 'comm (process-attributes pid)) + when (and process (string-match process-name process)) + return pid)) (defun helm-ff-find-printers () "Return a list of available printers on Unix systems." @@ -1049,10 +1118,12 @@ function with SUBEXP specified. E.g.: - (helm--replace-regexp-in-buffer-string \"e\\\\(m\\\\)acs\" 'upcase \"emacs\" t nil 1) + (helm--replace-regexp-in-buffer-string + \"e\\\\(m\\\\)acs\" \\='upcase \"emacs\" t nil 1) => \"eMacs\" - (replace-regexp-in-string \"e\\\\(m\\\\)acs\" 'upcase \"emacs\" t nil 1) + (replace-regexp-in-string + \"e\\\\(m\\\\)acs\" \\='upcase \"emacs\" t nil 1) => \"eEMACSacs\" Also START argument behaves as expected unlike @@ -1114,7 +1185,7 @@ Example: (let ((answer (helm-read-answer \"answer [y,n,!,q]: \" - '(\"y\" \"n\" \"!\" \"q\")))) + \\='(\"y\" \"n\" \"!\" \"q\")))) (pcase answer (\"y\" \"yes\") (\"n\" \"no\") @@ -1210,17 +1281,75 @@ See `helm-elisp-show-help'." (helm-set-attr 'help-running-p t))) (helm-set-attr 'help-current-symbol candidate))) +(defcustom helm-find-function-default-project nil + "Default directories to search symbols definitions from `helm-apropos'. +A list of directories or a single directory name. +Helm will allow you selecting one of those directories with `M-n' when +using a prefix arg with the `find-function' action in `helm-apropos'. +This is a good idea to add the directory names of the projects you are +working on to quickly jump to the definitions in the project source +files instead of jumping to the loaded files located in `load-path'." + :type '(choice (repeat string) + string) + :group 'helm-elisp) + +(defun helm-find-function-noselect (func &optional root-dir type) + "Find FUNC definition without selecting buffer. +FUNC can be a symbol or a string. +Instead of looking in LOAD-PATH to find library, this function +search in all subdirs of ROOT-DIR, if ROOT-DIR is unspecified ask for +it with completion. +TYPE when nil specify function, for other values see +`find-function-regexp-alist'." + (require 'find-func) + (let* ((sym (helm-symbolify func)) + (dir (or root-dir (helm-read-file-name + "Project directory: " + :test 'file-directory-p + :default (helm-mklist helm-find-function-default-project) + :must-match t))) + (find-function-source-path + (cons dir (helm-walk-directory dir + :directories 'only + :path 'full))) + (symbol-lib (helm-acase type + ((defvar defface) + (or (symbol-file sym it) + (help-C-file-name sym 'var))) + (t (cdr (find-function-library sym))))) + (library (find-library-name + (helm-basename symbol-lib t)))) + (find-function-search-for-symbol sym type library))) + (defun helm-find-function (func) - "FUNC is symbol or string." - (find-function (helm-symbolify func))) + "Try to jump to FUNC definition. +With a prefix arg ask for the project directory to search in instead of +using LOAD-PATH." + (if (not helm-current-prefix-arg) + (find-function (helm-symbolify func)) + (let ((place (helm-find-function-noselect func))) + (when place + (switch-to-buffer (car place)) (goto-char (cdr place)))))) (defun helm-find-variable (var) - "VAR is symbol or string." - (find-variable (helm-symbolify var))) + "Try to jump to VAR definition. +With a prefix arg ask for the project directory to search in instead of +using LOAD-PATH." + (if (not helm-current-prefix-arg) + (find-variable (helm-symbolify var)) + (let ((place (helm-find-function-noselect var nil 'defvar))) + (when place + (switch-to-buffer (car place)) (goto-char (cdr place)))))) (defun helm-find-face-definition (face) - "FACE is symbol or string." - (find-face-definition (helm-symbolify face))) + "Try to jump to FACE definition. +With a prefix arg ask for the project directory to search in instead of +using LOAD-PATH." + (if (not helm-current-prefix-arg) + (find-face-definition (helm-symbolify face)) + (let ((place (helm-find-function-noselect face nil 'defface))) + (when place + (switch-to-buffer (car place)) (goto-char (cdr place)))))) (defun helm-kill-new (candidate &optional replace) "CANDIDATE is symbol or string. @@ -1274,11 +1403,19 @@ Argument ALIST is an alist of associated major modes." (defun helm-file-name-sans-extension (filename) "Same as `file-name-sans-extension' but remove all extensions." (helm-aif (file-name-sans-extension filename) - ;; Start searching at index 1 for files beginning with a dot (#1335). + ;; Start searching at index 1 for files beginning with a dot + ;; (bug#1335). (if (string-match "\\." (helm-basename it) 1) (helm-file-name-sans-extension it) it))) +(defsubst helm-file-name-extension (file) + "Returns FILE extension if it is not a number." + (helm-aif (file-name-extension file) + (and (not (string-match "\\`0+\\'" it)) + (zerop (string-to-number it)) + it))) + (defun helm-basename (fname &optional ext) "Print FNAME with any leading directory components removed. If specified, also remove filename extension EXT. @@ -1436,7 +1573,12 @@ Directories expansion is not supported." :skip-subdirs t) (helm-aif (helm-wildcard-to-regexp bn) (directory-files (helm-basedir pattern) full it) - (file-expand-wildcards pattern full))))) + ;; `file-expand-wildcards' fails to expand weird directories + ;; like "[ foo.zz ] bar.*.avi", fallback to `directory-files' + ;; in such cases. + (or (file-expand-wildcards pattern full) + (directory-files (helm-basedir pattern) + full (wildcard-to-regexp bn))))))) (defun helm-wildcard-to-regexp (wc) "Transform wilcard WC like \"**.{jpg,jpeg}\" in REGEXP." @@ -1565,7 +1707,7 @@ flex or helm-flex completion style if present." 1 0)))))) (defun helm-dynamic-completion (collection predicate &optional point metadata nomode styles) - "Build a function listing the possible completions of `helm-pattern' in COLLECTION. + "Build a completion function for `helm-pattern' in COLLECTION. Only the elements of COLLECTION that satisfy PREDICATE are considered. @@ -1586,8 +1728,8 @@ Example: (helm :sources (helm-build-sync-source \"test\" :candidates (helm-dynamic-completion - '(foo bar baz foab) - 'symbolp) + \\='(foo bar baz foab) + \\='symbolp) :match-dynamic t) :buffer \"*helm test*\") @@ -1732,6 +1874,9 @@ broken." (push (substring string start) result)) (apply 'concat (nreverse result)))) +(when (< emacs-major-version 26) + (advice-add 'ansi-color-apply :override #'helm--ansi-color-apply)) + ;;; Fontlock (cl-dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) @@ -1740,7 +1885,6 @@ broken." '(("(\\<\\(with-helm-after-update-hook\\)\\>" 1 font-lock-keyword-face) ("(\\<\\(with-helm-temp-hook\\)\\>" 1 font-lock-keyword-face) ("(\\<\\(with-helm-window\\)\\>" 1 font-lock-keyword-face) - ("(\\<\\(with-helm-quittable\\)\\>" 1 font-lock-keyword-face) ("(\\<\\(with-helm-current-buffer\\)\\>" 1 font-lock-keyword-face) ("(\\<\\(with-helm-buffer\\)\\>" 1 font-lock-keyword-face) ("(\\<\\(with-helm-show-completion\\)\\>" 1 font-lock-keyword-face) @@ -1757,10 +1901,4 @@ broken." (provide 'helm-lib) -;; Local Variables: -;; byte-compile-warnings: (not obsolete) -;; coding: utf-8 -;; indent-tabs-mode: nil -;; End: - ;;; helm-lib ends here diff --git a/elpa/helm-core-20210128.1814/helm-multi-match.el b/elpa/helm-core-20220607.1243/helm-multi-match.el similarity index 86% rename from elpa/helm-core-20210128.1814/helm-multi-match.el rename to elpa/helm-core-20220607.1243/helm-multi-match.el index 5ee35d76..173df2ab 100644 --- a/elpa/helm-core-20210128.1814/helm-multi-match.el +++ b/elpa/helm-core-20220607.1243/helm-multi-match.el @@ -3,9 +3,9 @@ ;; Original Author: rubikitch ;; Copyright (C) 2008 ~ 2011 rubikitch -;; Copyright (C) 2011 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2011 ~ 2020 Thierry Volpiatto -;; Author: Thierry Volpiatto +;; Author: Thierry Volpiatto ;; URL: http://github.com/emacs-helm/helm ;; This program is free software; you can redistribute it and/or modify @@ -80,7 +80,7 @@ If GREP-SPACE is used translate escaped space to \"\\s\" instead of \"\\s-\"." (if grep-space "\\s" "\\s-") pattern nil t))) (defun helm-mm-1-make-regexp (pattern) - "Replace spaces in PATTERN with \"\.*\"." + "Replace spaces in PATTERN with \".*\"." (mapconcat 'identity (helm-mm-split-pattern pattern) ".*")) @@ -126,7 +126,7 @@ If GREP-SPACE is used translate escaped space to \"\\s\" instead of \"\\s-\"." (defun helm-mm-prefix-match (candidate &optional pattern) ;; In filename completion basename and basedir may be - ;; quoted, unquote them for string comparison (Issue #1283). + ;; quoted, unquote them for string comparison (Bug#1283). (setq pattern (replace-regexp-in-string "\\\\" "" (or pattern helm-pattern))) (let ((len (length pattern))) @@ -206,6 +206,11 @@ E.g., ((identity . \"foo\") (not . \"bar\"))." (cons 'not (substring pat 1)) (cons 'identity pat))))) +(defun helm-mm-regexp-p (string) + (string-match-p "[][*+^$.?]" string)) + +(defvar helm-mm--match-on-diacritics nil) + (cl-defun helm-mm-3-match (candidate &optional (pattern helm-pattern)) "Check if PATTERN match CANDIDATE. When PATTERN contains a space, it is splitted and matching is @@ -219,12 +224,16 @@ the same cons cell against CANDIDATE. I.e. (identity (string-match \"foo\" \"foo bar\")) => t." (let ((pat (helm-mm-3-get-patterns pattern))) (cl-loop for (predicate . regexp) in pat + for re = (if (and (not (helm-mm-regexp-p regexp)) + helm-mm--match-on-diacritics) + (char-fold-to-regexp regexp) + regexp) always (funcall predicate (condition-case _err ;; FIXME: Probably do nothing when ;; using fuzzy leaving the job ;; to the fuzzy fn. - (string-match regexp candidate) + (string-match re candidate) (invalid-regexp nil)))))) (defun helm-mm-3-search-base (pattern searchfn1 searchfn2) @@ -236,29 +245,42 @@ i.e (identity (re-search-forward \"foo\" (point-at-eol) t)) => t." (cl-loop with pat = (if (stringp pattern) (helm-mm-3-get-patterns pattern) pattern) + with regex = (cdar pat) + with regex1 = (if (and regex + (not (helm-mm-regexp-p regex)) + helm-mm--match-on-diacritics) + (char-fold-to-regexp regex) + regex) when (eq (caar pat) 'not) return ;; Pass the job to `helm-search-match-part'. (prog1 (list (point-at-bol) (point-at-eol)) (forward-line 1)) while (condition-case _err - (funcall searchfn1 (or (cdar pat) "") nil t) + (funcall searchfn1 (or regex1 "") nil t) (invalid-regexp nil)) for bol = (point-at-bol) for eol = (point-at-eol) - if (cl-loop for (pred . str) in (cdr pat) always + if (cl-loop for (pred . str) in (cdr pat) + for regexp = (if (and (not (helm-mm-regexp-p str)) + helm-mm--match-on-diacritics) + (char-fold-to-regexp str) + str) + always (progn (goto-char bol) (funcall pred (condition-case _err - (funcall searchfn2 str eol t) + (funcall searchfn2 regexp eol t) (invalid-regexp nil))))) do (goto-char eol) and return t else do (goto-char eol) finally return nil)) (defun helm-mm-3-search (pattern &rest _ignore) - (when (stringp pattern) - (setq pattern (helm-mm-3-get-patterns pattern))) (helm-mm-3-search-base pattern 're-search-forward 're-search-forward)) + +(defun helm-mm-3-search-on-diacritics (pattern &rest _ignore) + (let ((helm-mm--match-on-diacritics t)) + (helm-mm-3-search pattern))) ;;; mp-3 with migemo ;; Needs https://github.com/emacs-jp/migemo @@ -299,6 +321,19 @@ i.e. the sources which have the slot :migemo with non--nil value." helm-mm--previous-migemo-info)))) (string-match (assoc-default pattern helm-mm--previous-migemo-info) str)) +(defun helm-mm-diacritics-string-match (pattern str) + "Check if PATTERN match STR ignoring diacritics. + +If PATTERN is a regexp (i.e. `helm-mm-regexp-p') use PATTERN +unmodified, otherwise transform PATTERN with `char-fold-to-regexp'. + +This function is used to search match-part of candidate in in-buffer +sources." + (string-match (if (helm-mm-regexp-p pattern) + pattern + (char-fold-to-regexp pattern)) + str)) + (cl-defun helm-mm-3-migemo-match (candidate &optional (pattern helm-pattern)) (and helm-migemo-mode (cl-loop for (pred . re) in (helm-mm-3-get-patterns pattern) @@ -337,8 +372,6 @@ E.g. \"bar foo baz\" will match \"barfoobaz\" or \"barbazfoo\" but not always (funcall predicate (string-match regexp candidate)))))) (defun helm-mm-3p-search (pattern &rest _ignore) - (when (stringp pattern) - (setq pattern (helm-mm-3-get-patterns pattern))) (helm-mm-3-search-base pattern 'helm-mm-prefix-search 're-search-forward)) @@ -355,6 +388,11 @@ E.g. \"bar foo baz\" will match \"barfoobaz\" or \"barbazfoo\" but not (multi3p #'helm-mm-3p-match)))) (funcall fun candidate pattern))) +(cl-defun helm-mm-3-match-on-diacritics (candidate &optional (pattern helm-pattern)) + "Same as `helm-mm-3-match' but match on diacritics if possible." + (let ((helm-mm--match-on-diacritics t)) + (helm-mm-match candidate pattern))) + (defun helm-mm-search (pattern &rest _ignore) "Search for PATTERN with `helm-mm-matching-method' function." (let ((fun (cl-ecase helm-mm-matching-method @@ -368,10 +406,4 @@ E.g. \"bar foo baz\" will match \"barfoobaz\" or \"barbazfoo\" but not (provide 'helm-multi-match) -;; Local Variables: -;; byte-compile-warnings: (not obsolete) -;; coding: utf-8 -;; indent-tabs-mode: nil -;; End: - ;;; helm-multi-match.el ends here diff --git a/elpa/helm-core-20210128.1814/helm-source.el b/elpa/helm-core-20220607.1243/helm-source.el similarity index 84% rename from elpa/helm-core-20210128.1814/helm-source.el rename to elpa/helm-core-20220607.1243/helm-source.el index 795e8be5..6b438234 100644 --- a/elpa/helm-core-20210128.1814/helm-source.el +++ b/elpa/helm-core-20220607.1243/helm-source.el @@ -1,8 +1,8 @@ ;;; helm-source.el --- Helm source creation. -*- lexical-binding: t -*- -;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto +;; Copyright (C) 2015 ~ 2020 Thierry Volpiatto -;; Author: Thierry Volpiatto +;; Author: Thierry Volpiatto ;; URL: http://github.com/emacs-helm/helm ;; This program is free software; you can redistribute it and/or modify @@ -36,27 +36,28 @@ (defvar helm-fuzzy-match-fn) (defvar helm-fuzzy-search-fn) -(declare-function helm-init-candidates-in-buffer "helm.el") -(declare-function helm-interpret-value "helm.el") -(declare-function helm-fuzzy-highlight-matches "helm.el") +(declare-function helm-init-candidates-in-buffer "helm-core.el") +(declare-function helm-interpret-value "helm-core.el") +(declare-function helm-fuzzy-highlight-matches "helm-core.el") ;;; Advice Emacs fn ;; Make Classes's docstrings more readable by removing al the ;; unnecessary crap. -(defun helm-source--cl--print-table (_header rows) +(defun helm-source--cl--print-table (&rest args) "Advice for `cl--print-table' to make readable class slots docstrings." - (let ((format "%s\n\n Initform=%s\n\n%s")) - (dolist (row rows) - (setcar row (propertize (car row) 'face 'bold)) - (setcdr row (nthcdr 1 (cdr row))) - (insert "\n* " (apply #'format format row) "\n")))) - + (cl-flet ((print-rows (rows) + (let ((format "%s\n\n Initform=%s\n\n%s")) + (dolist (row rows) + (setcar row (propertize (car row) 'face 'bold)) + (setcdr row (nthcdr 1 (cdr row))) + (insert "\n* " (apply #'format format row) "\n"))))) + (print-rows (cadr args)))) -(defgeneric helm--setup-source (source) +(cl-defgeneric helm--setup-source (source) "Prepare slots and handle slot errors before creating a helm source.") -(defgeneric helm-setup-user-source (source) +(cl-defgeneric helm-setup-user-source (source) "Allow users modifying slots in SOURCE just before creation.") @@ -148,7 +149,7 @@ (keymap :initarg :keymap - :initform helm-map + :initform 'helm-map :custom sexp :documentation " Specific keymap for this source. @@ -186,9 +187,9 @@ (defun foo-persistent-action (candidate) (do-something candidate)) - :persistent-action '(foo-persistent-action . never-split) ; Don't split + :persistent-action \\='(foo-persistent-action . never-split) ; Don't split or - :persistent-action 'foo-persistent-action ; Split + :persistent-action \\='foo-persistent-action ; Split When specifying :persistent-action by slot directly, foo-persistent-action will be executed without quitting helm when hitting `C-j'. @@ -204,8 +205,8 @@ \"Delete current candidate without quitting.\" (interactive) (with-helm-alive-p - (helm-set-attr 'quick-delete '(helm-ff-quick-delete . never-split)) - (helm-execute-persistent-action 'quick-delete))) + (helm-set-attr \\='quick-delete \\='(helm-ff-quick-delete . never-split)) + (helm-execute-persistent-action \\='quick-delete))) This function is then bound in `helm-find-files-map'.") @@ -224,13 +225,13 @@ ;; Don't split helm-window. (cons (lambda (_ignore) (do-something candidate)) - 'no-split)) + \\='no-split)) ;; Split helm-window. (something-else (lambda (_ignore) (do-something-else candidate))))) - :persistent-action-if 'foo-persistent-action + :persistent-action-if \\='foo-persistent-action Here when hitting `C-j' one of the lambda's will be executed depending on something or something-else condition, splitting or not @@ -242,8 +243,11 @@ :initform nil :custom string :documentation - " A string to explain persistent-action of this source. It also - accepts a function or a variable name. + " A string to explain persistent-action of this source. + It is a facility to display what persistent action does in + header-line, once your source is loaded don't use it directly, it will + have no effect, use instead `header-line' attribute. + It also accepts a function or a variable name. It will be displayed in `header-line' or in `minibuffer' depending of value of `helm-echo-input-in-header-line' and `helm-display-header-line'.") @@ -353,7 +357,15 @@ Avoid recomputing all candidates with candidate-transformer or filtered-candidate-transformer to give a new value to REAL, instead the selected candidate is transformed only when passing it - to action. + to action. This works (and make sense) only with plain string + candidates, it will NOT work when candidate is a cons cell, in this + case the real value of candidate will be used. + Example: + + (helm :sources (helm-build-sync-source \"test\" + :candidates \\='(a b c d e) + :display-to-real (lambda (c) (concat c \":modified by d-t-r\"))) + :buffer \"*helm test*\") Note that this is NOT a transformer, so the display will not be modified by this function.") @@ -367,10 +379,16 @@ Function called with one parameter, the selected candidate. - The real value of candidates will be shown in display. - Note: This have nothing to do with display-to-real. - It is unuseful as the same can be performed by using more than - one function in transformers, it is kept only for backward compatibility.") + The real value of candidates will be shown in display and of course + be used by action. + Example: + + (helm :sources (helm-build-sync-source \"test\" + :candidates \\='((\"foo\" . 1) (\"bar\" . 2) (\"baz\". 3)) + :real-to-display (lambda (c) (format \"%s\" (1+ c)))) + :buffer \"*helm test*\") + + Mostly deprecated, kept only for backward compatibility.") (marked-with-props :initarg :marked-with-props @@ -379,7 +397,7 @@ :documentation " Get candidates with their properties in `helm-marked-candidates'. Allow using the FORCE-DISPLAY-PART of `helm-get-selection' in marked - candidates, use t or 'withprop to pass it to `helm-get-selection'.") + candidates, use t or \\='withprop to pass it to `helm-get-selection'.") (action-transformer :initarg :action-transformer @@ -458,6 +476,13 @@ Note that FUZZY-MATCH slot will overhide value of this slot.") + (diacritics + :initarg :diacritics + :initform nil + :custom boolean + :documentation + " Ignore diacritics when searching.") + (match-on-real :initarg :match-on-real :initform nil @@ -574,8 +599,8 @@ :documentation " Function called with no parameters at end of initialization when `helm-resume' is started. - If this function try to do something against `helm-buffer', \(e.g updating, - searching etc...\) probably you should run it in a timer to ensure + If this function try to do something against `helm-buffer', (e.g updating, + searching etc...) probably you should run it in a timer to ensure `helm-buffer' is ready.") (follow @@ -670,9 +695,17 @@ minibuffer contents as candidate value (in this case helm-buffer is empty).") + (find-file-target + :initarg :find-file-target + :initform nil + :custom function + :documentation + " Determine the target file when running `helm-quit-and-find-file'. + It is a function called with one arg SOURCE.") + (group :initarg :group - :initform helm + :initform 'helm :custom symbol :documentation " The current source group, default to `helm' when not specified.")) @@ -690,7 +723,7 @@ :custom boolean :documentation " Enable migemo. - When multimatch is disabled, you can give the symbol 'nomultimatch as value + When multimatch is disabled, you can give the symbol \\='nomultimatch as value to force not using generic migemo matching function. In this case you have to provide your own migemo matching funtion that kick in when `helm-migemo-mode' is enabled. @@ -778,7 +811,7 @@ inherit from `helm-source'.") :custom boolean :documentation " Enable migemo. - When multimatch is disabled, you can give the symbol 'nomultimatch as value + When multimatch is disabled, you can give the symbol \\='nomultimatch as value to force not using generic migemo matching function. In this case you have to provide your own migemo matching funtion that kick in when `helm-migemo-mode' is enabled. @@ -793,7 +826,7 @@ inherit from `helm-source'.") (match :initform '(identity)) - + (get-line :initarg :get-line :initform 'buffer-substring-no-properties @@ -882,21 +915,26 @@ See `helm-candidates-in-buffer' for more infos.") (with-current-buffer (helm-candidate-buffer 'global) (insert-file-contents file) (goto-char (point-min)) - (while (not (eobp)) - (add-text-properties - (point-at-bol) (point-at-eol) - `(helm-linum ,count)) - (cl-incf count) - (forward-line 1)))))) + (when (helm-get-attr 'linum) + (while (not (eobp)) + (add-text-properties + (point-at-bol) (point-at-eol) + `(helm-linum ,count)) + (cl-incf count) + (forward-line 1))))))) (get-line :initform #'buffer-substring) (candidates-file :initarg :candidates-file :initform nil :custom string :documentation - " A filename. - Each line number of FILE is accessible with helm-linum property - from candidate display part.")) + " The file used to fetch candidates.") + (linum + :initarg :linum + :initform nil + :documentation + " Store line number in each candidate when non nil. + Line number is stored in `helm-linum' text property.")) "The contents of the FILE will be used as candidates in buffer.") @@ -915,7 +953,8 @@ See `helm-candidates-in-buffer' for more infos.") (defun helm--create-source (object) "[INTERNAL] Build a helm source from OBJECT. Where OBJECT is an instance of an eieio class." - (cl-loop for s in (object-slots object) + (cl-loop for sd in (eieio-class-slots (eieio-object-class object)) + for s = (eieio-slot-descriptor-name sd) for slot-val = (slot-value object s) when slot-val collect (cons s slot-val))) @@ -943,30 +982,51 @@ Arguments ARGS are keyword value pairs as defined in CLASS." (defvar helm-mm-default-match-functions) (defun helm-source-mm-get-search-or-match-fns (source method) - (let ((defmatch (helm-aif (slot-value source 'match) - (helm-mklist it))) - (defmatch-strict (helm-aif (and (eq method 'match) - (slot-value source 'match-strict)) - (helm-mklist it))) - (defsearch (helm-aif (and (eq method 'search) - (slot-value source 'search)) - (helm-mklist it))) - (defsearch-strict (helm-aif (and (eq method 'search-strict) - (slot-value source 'search-strict)) - (helm-mklist it))) - (migemo (slot-value source 'migemo))) + "Prepare match or search functions for class SOURCE. +Argument METHOD is the matching method used by SOURCE either `match' +or `search'." + (let* ((diacritics (slot-value source 'diacritics)) + (defmatch (helm-aif (slot-value source 'match) + (helm-mklist it))) + (defmatch-strict (helm-aif (and (eq method 'match) + (slot-value source 'match-strict)) + (helm-mklist it))) + (defsearch (helm-aif (and (eq method 'search) + (slot-value source 'search)) + (helm-mklist it))) + (defsearch-strict (helm-aif (and (eq method 'search-strict) + (slot-value source 'search-strict)) + (helm-mklist it))) + (migemo (slot-value source 'migemo))) (cl-case method (match (cond (defmatch-strict) + ((and migemo diacritics) + (append (list 'helm-mm-exact-match + 'helm-mm-3-match-on-diacritics) + defmatch '(helm-mm-3-migemo-match))) (migemo (append helm-mm-default-match-functions defmatch '(helm-mm-3-migemo-match))) + (diacritics + (delq nil + `(helm-mm-exact-match + ,@defmatch helm-mm-3-match-on-diacritics))) (defmatch (append helm-mm-default-match-functions defmatch)) (t helm-mm-default-match-functions))) (search (cond (defsearch-strict) + ((and migemo diacritics) + (append '(helm-mm-exact-search) + defsearch + '(helm-mm-3-migemo-search + helm-mm-3-search-on-diacritics))) (migemo (append helm-mm-default-search-functions defsearch '(helm-mm-3-migemo-search))) + (diacritics + (delq nil + `(helm-mm-exact-search + ,@defsearch helm-mm-3-search-on-diacritics))) (defsearch (append helm-mm-default-search-functions defsearch)) (t helm-mm-default-search-functions)))))) @@ -1000,45 +1060,55 @@ an eieio class." ;;; Methods to build sources. ;; ;; -(defun helm-source--persistent-help-string (string source) +(defun helm-source--persistent-help-string (value source) + "Format `persistent-help' VALUE in SOURCE. +Argument VALUE can be a string, a variable or a function." (substitute-command-keys - (concat "\\\\[helm-execute-persistent-action]: " - (or (format "%s (keeping session)" string) - (slot-value source 'header-line))))) + (format "\\\\[helm-execute-persistent-action]: %s (keeping session)" + (helm-aif value + (helm-interpret-value value source) + (slot-value source 'header-line))))) (defun helm-source--header-line (source) + "Compute a default header line for SOURCE. + +The header line is based on one of `persistent-action-if', +`persistent-action', or `action' (in this order of precedence)." (substitute-command-keys (concat "\\\\[helm-execute-persistent-action]: " - (helm-aif (or (slot-value source 'persistent-action) - (slot-value source 'action)) - (cond ((and (symbolp it) - (functionp it) - (eq it 'identity)) - "Do Nothing") - ((and (symbolp it) - (boundp it) - (listp (symbol-value it)) - (stringp (caar (symbol-value it)))) - (caar (symbol-value it))) - ((or (symbolp it) (functionp it)) - (helm-symbol-name it)) - ((listp it) - (let ((action (car it))) - ;; It comes from :action ("foo" . function). - (if (stringp (car action)) - (car action) - ;; It comes from :persistent-action - ;; (function . 'nosplit) Fix Issue #788. - (if (or (symbolp action) - (functionp action)) - (helm-symbol-name action))))) - (t "")) - "") + (helm-acond + ((slot-value source 'persistent-action-if) + (helm-symbol-name it)) + ((or (slot-value source 'persistent-action) + (slot-value source 'action)) + (cond ((and (symbolp it) + (functionp it) + (eq it 'identity)) + "Do Nothing") + ((and (symbolp it) + (boundp it) + (listp (symbol-value it)) + (stringp (caar (symbol-value it)))) + (caar (symbol-value it))) + ((or (symbolp it) (functionp it)) + (helm-symbol-name it)) + ((listp it) + (let ((action (car it))) + ;; It comes from :action ("foo" . function). + (if (stringp (car action)) + (car action) + ;; It comes from :persistent-action + ;; (function . 'nosplit) Fix Bug#788. + (if (or (symbolp action) + (functionp action)) + (helm-symbol-name action))))) + (t ""))) + (t "")) " (keeping session)"))) -(defmethod helm--setup-source :primary ((_source helm-source))) +(cl-defmethod helm--setup-source ((_source helm-source))) -(defmethod helm--setup-source :before ((source helm-source)) +(cl-defmethod helm--setup-source :before ((source helm-source)) (unless (slot-value source 'group) (setf (slot-value source 'group) 'helm)) (when (slot-value source 'delayed) @@ -1087,9 +1157,9 @@ an eieio class." it))) (setf (slot-value source 'requires-pattern) val)))) -(defmethod helm-setup-user-source ((_source helm-source))) +(cl-defmethod helm-setup-user-source ((_source helm-source))) -(defmethod helm--setup-source ((source helm-source-sync)) +(cl-defmethod helm--setup-source ((source helm-source-sync)) (when (slot-value source 'fuzzy-match) (helm-aif (slot-value source 'match) (setf (slot-value source 'match) @@ -1112,7 +1182,7 @@ an eieio class." (setf (slot-value source 'fuzzy-match) nil) (setf (slot-value source 'volatile) t))) -(defmethod helm--setup-source ((source helm-source-in-buffer)) +(cl-defmethod helm--setup-source ((source helm-source-in-buffer)) (cl-assert (eq (slot-value source 'candidates) 'helm-candidates-in-buffer) nil (format "Wrong usage of `candidates' attr in `%s' use `data' or `init' instead" @@ -1155,7 +1225,7 @@ an eieio class." (cl-assert (eq (slot-value source 'volatile) t) nil "Invalid slot value for `volatile'"))) -(defmethod helm--setup-source ((source helm-source-async)) +(cl-defmethod helm--setup-source ((source helm-source-async)) (cl-assert (null (slot-value source 'candidates)) nil "Incorrect use of `candidates' use `candidates-process' instead") (cl-assert (null (slot-value source 'multimatch)) @@ -1163,7 +1233,7 @@ an eieio class." (cl-assert (null (slot-value source 'fuzzy-match)) nil "`fuzzy-match' not supported in async sources.")) -(defmethod helm--setup-source ((source helm-source-dummy)) +(cl-defmethod helm--setup-source ((source helm-source-dummy)) (let ((mtc (slot-value source 'match))) (cl-assert (or (equal '(identity) mtc) (eq 'identity mtc)) @@ -1215,10 +1285,4 @@ Args ARGS are keywords provided by `helm-source-in-file'." (provide 'helm-source) -;; Local Variables: -;; byte-compile-warnings: (not obsolete) -;; coding: utf-8 -;; indent-tabs-mode: nil -;; End: - ;;; helm-source ends here -- 2.47.3