From 08d2a0f8c688cad717fc521574b9a0e48907679e Mon Sep 17 00:00:00 2001 From: Andreas Gerler Date: Sun, 5 Apr 2015 13:27:01 +0200 Subject: [PATCH] added helm for emacs-version 24+ Signed-off-by: Andreas Gerler --- bba.org | 107 +- elpa/helm-20150403.101/emacs-helm.sh | 96 + elpa/helm-20150403.101/helm-adaptive.el | 243 + elpa/helm-20150403.101/helm-aliases.el | 778 +++ elpa/helm-20150403.101/helm-apt.el | 292 + elpa/helm-20150403.101/helm-autoloads.el | 1258 +++++ elpa/helm-20150403.101/helm-bookmark.el | 764 +++ elpa/helm-20150403.101/helm-buffers.el | 854 +++ elpa/helm-20150403.101/helm-color.el | 163 + elpa/helm-20150403.101/helm-command.el | 234 + elpa/helm-20150403.101/helm-config.el | 228 + elpa/helm-20150403.101/helm-dabbrev.el | 338 ++ elpa/helm-20150403.101/helm-elisp-package.el | 297 + elpa/helm-20150403.101/helm-elisp.el | 829 +++ elpa/helm-20150403.101/helm-elscreen.el | 79 + elpa/helm-20150403.101/helm-eshell.el | 246 + elpa/helm-20150403.101/helm-eval.el | 177 + elpa/helm-20150403.101/helm-external.el | 216 + elpa/helm-20150403.101/helm-files.el | 3165 +++++++++++ elpa/helm-20150403.101/helm-font.el | 187 + elpa/helm-20150403.101/helm-grep.el | 1226 ++++ elpa/helm-20150403.101/helm-help.el | 1711 ++++++ elpa/helm-20150403.101/helm-imenu.el | 183 + elpa/helm-20150403.101/helm-info.el | 183 + elpa/helm-20150403.101/helm-locate.el | 345 ++ elpa/helm-20150403.101/helm-man.el | 102 + elpa/helm-20150403.101/helm-match-plugin.el | 368 ++ elpa/helm-20150403.101/helm-misc.el | 331 ++ elpa/helm-20150403.101/helm-mode.el | 1096 ++++ elpa/helm-20150403.101/helm-net.el | 607 ++ elpa/helm-20150403.101/helm-org.el | 145 + elpa/helm-20150403.101/helm-pkg.el | 8 + elpa/helm-20150403.101/helm-plugin.el | 137 + elpa/helm-20150403.101/helm-regexp.el | 624 +++ elpa/helm-20150403.101/helm-ring.el | 416 ++ elpa/helm-20150403.101/helm-semantic.el | 209 + elpa/helm-20150403.101/helm-source.el | 1109 ++++ elpa/helm-20150403.101/helm-sys.el | 299 + elpa/helm-20150403.101/helm-tags.el | 360 ++ elpa/helm-20150403.101/helm-utils.el | 871 +++ elpa/helm-20150403.101/helm.el | 5214 ++++++++++++++++++ 41 files changed, 26059 insertions(+), 36 deletions(-) create mode 100755 elpa/helm-20150403.101/emacs-helm.sh create mode 100644 elpa/helm-20150403.101/helm-adaptive.el create mode 100644 elpa/helm-20150403.101/helm-aliases.el create mode 100644 elpa/helm-20150403.101/helm-apt.el create mode 100644 elpa/helm-20150403.101/helm-autoloads.el create mode 100644 elpa/helm-20150403.101/helm-bookmark.el create mode 100644 elpa/helm-20150403.101/helm-buffers.el create mode 100644 elpa/helm-20150403.101/helm-color.el create mode 100644 elpa/helm-20150403.101/helm-command.el create mode 100644 elpa/helm-20150403.101/helm-config.el create mode 100644 elpa/helm-20150403.101/helm-dabbrev.el create mode 100644 elpa/helm-20150403.101/helm-elisp-package.el create mode 100644 elpa/helm-20150403.101/helm-elisp.el create mode 100644 elpa/helm-20150403.101/helm-elscreen.el create mode 100644 elpa/helm-20150403.101/helm-eshell.el create mode 100644 elpa/helm-20150403.101/helm-eval.el create mode 100644 elpa/helm-20150403.101/helm-external.el create mode 100644 elpa/helm-20150403.101/helm-files.el create mode 100644 elpa/helm-20150403.101/helm-font.el create mode 100644 elpa/helm-20150403.101/helm-grep.el create mode 100644 elpa/helm-20150403.101/helm-help.el create mode 100644 elpa/helm-20150403.101/helm-imenu.el create mode 100644 elpa/helm-20150403.101/helm-info.el create mode 100644 elpa/helm-20150403.101/helm-locate.el create mode 100644 elpa/helm-20150403.101/helm-man.el create mode 100644 elpa/helm-20150403.101/helm-match-plugin.el create mode 100644 elpa/helm-20150403.101/helm-misc.el create mode 100644 elpa/helm-20150403.101/helm-mode.el create mode 100644 elpa/helm-20150403.101/helm-net.el create mode 100644 elpa/helm-20150403.101/helm-org.el create mode 100644 elpa/helm-20150403.101/helm-pkg.el create mode 100644 elpa/helm-20150403.101/helm-plugin.el create mode 100644 elpa/helm-20150403.101/helm-regexp.el create mode 100644 elpa/helm-20150403.101/helm-ring.el create mode 100644 elpa/helm-20150403.101/helm-semantic.el create mode 100644 elpa/helm-20150403.101/helm-source.el create mode 100644 elpa/helm-20150403.101/helm-sys.el create mode 100644 elpa/helm-20150403.101/helm-tags.el create mode 100644 elpa/helm-20150403.101/helm-utils.el create mode 100644 elpa/helm-20150403.101/helm.el diff --git a/bba.org b/bba.org index 1b3c43e7..97e6e0e2 100644 --- a/bba.org +++ b/bba.org @@ -1107,7 +1107,8 @@ Bind f3 and f4 to previous/next pane. (require 'recentf) (recentf-mode 1) (setq recentf-max-menu-items 42) - (global-set-key "\C-cr" 'recentf-open-files) + (if (<= emacs-major-version 23) + (global-set-key "\C-cr" 'recentf-open-files)) #+END_SRC *** insert-date function @@ -1256,6 +1257,32 @@ safe files with #! in first line as user executable. (define-key global-map (kbd "M-p") 'bba/move-line-up) (global-set-key (kbd "M-n") 'bba/move-line-down) +#+END_SRC +*** helm + +Some links you might check out: + +- [[http://tuhdo.github.io/helm-intro.html][A Package in a league of its own: Helm]] +- [[http://wikemacs.org/wiki/Helm][Helm - WikEmacs]] +- [[http://emacs.stackexchange.com/questions/2867/how-should-i-change-my-workflow-when-moving-from-ido-to-helm][How should I change my workflow when moving from IDO to Helm - Emacs + Stack Exchange]] + +#+BEGIN_SRC emacs-lisp + (if (>= emacs-major-version 24) + (progn + (add-to-list 'load-path + "~/.emacs.d/elpa/helm-20150403.101") + (require 'helm) + (helm-mode 1) + (global-set-key (kbd "M-y") 'helm-show-kill-ring) + (global-set-key (kbd "C-c w") 'helm-man-woman) + (global-set-key (kbd "M-x") 'helm-M-x) + (global-set-key "\C-cr" 'helm-recentf) + (global-set-key (kbd "M-s o") 'helm-occur) + (define-key global-map "\C-x\C-b" 'helm-buffers-list) + ) + ) + #+END_SRC *** [[http://emacswiki.org/emacs/KeyChord][key-chord]] @@ -1305,55 +1332,60 @@ to convert hard tabs to the appropriate number of spaces, and a tabify function to convert groups of spaces to hard tabs. #+BEGIN_SRC emacs-lisp - (define-key bba/toggle "w" 'whitespace-mode) + (define-key bba/toggle "w" 'whitespace-mode) - (define-prefix-command 'bba/launcher) - (define-key global-map "\C-xl" 'bba/launcher) + (define-prefix-command 'bba/launcher) + (define-key global-map "\C-xl" 'bba/launcher) - (define-key bba/launcher "b" 'browse-url-at-point) - (define-key bba/launcher "c" 'calculator) - (define-key bba/launcher "d" 'ediff-buffers) - (define-key bba/launcher "e" 'elfeed) - (define-key bba/launcher "i" 'ielm) - (define-key bba/launcher "s" 'shell) - (define-key bba/launcher "S" 'synonyms) - (define-key bba/launcher "t" 'git-timemachine) - (define-key bba/launcher "T" 'twittering-mode) + (define-key bba/launcher "b" 'browse-url-at-point) + (define-key bba/launcher "c" 'calculator) + (define-key bba/launcher "d" 'ediff-buffers) + (define-key bba/launcher "e" 'elfeed) + (define-key bba/launcher "i" 'ielm) + (define-key bba/launcher "s" 'shell) + (define-key bba/launcher "S" 'synonyms) + (define-key bba/launcher "t" 'git-timemachine) + (define-key bba/launcher "T" 'twittering-mode) - (define-key global-map "\C-c\C-t" 'insert-timestamp) - (define-key global-map "\C-c\M-c" 'centered-cursor-mode) + (define-key global-map "\C-c\C-t" 'insert-timestamp) + (define-key global-map "\C-c\M-c" 'centered-cursor-mode) + + (define-key global-map "\C-ci" 'imenu) + (define-key global-map "\C-c\S-g" 'rgrep) + (define-key global-map "\C-cf" 'load-git-cfengine) - (define-key global-map "\C-ci" 'imenu) - (define-key global-map "\C-c\S-g" 'rgrep) - (define-key global-map "\C-cf" 'load-git-cfengine) + (define-key global-map "\C-c\C-w" 'fixup-whitespace) - (define-key global-map "\C-c\C-w" 'fixup-whitespace) + (define-key global-map "\M-g\M-d" 'magit-diff-unstaged) + (define-key global-map "\M-g\M-b" 'magit-branch-manager) + (define-key global-map "\M-gb" 'magit-blame-mode) + (define-key global-map "\C-cm" 'magit-status) - (define-key global-map "\M-g\M-d" 'magit-diff-unstaged) - (define-key global-map "\M-g\M-b" 'magit-branch-manager) - (define-key global-map "\M-gb" 'magit-blame-mode) - (define-key global-map "\C-cm" 'magit-status) + (define-key global-map "\C-c\S-f" (lambda() + (interactive) + (message (buffer-file-name)))) - (define-key global-map "\C-c\S-f" (lambda() - (interactive) - (message (buffer-file-name)))) + (if (<= emacs-major-version 23) + (progn + (define-key global-map "\C-cw" (lambda () + (interactive) + (let ((woman-use-topic-at-point t)) + (woman)))) + (define-key global-map "\C-x\C-b" 'ibuffer) + ) + ) - (define-key global-map "\C-cw" (lambda () - (interactive) - (let ((woman-use-topic-at-point t)) - (woman)))) + (define-key global-map "\C-cy" 'yas/insert-snippet) - (define-key global-map "\C-cy" 'yas/insert-snippet) + (define-key global-map "\C-c\M-d" 'diff-buffer-with-file) - (define-key global-map "\C-c\M-d" 'diff-buffer-with-file) + ;;; ** Use C-+ and C-- to adjust font size - ;;; ** Use C-+ and C-- to adjust font size + (define-key global-map (kbd "C-+") 'text-scale-increase) + (define-key global-map (kbd "C--") 'text-scale-decrease) - (define-key global-map (kbd "C-+") 'text-scale-increase) - (define-key global-map (kbd "C--") 'text-scale-decrease) - (define-key global-map "\C-x\C-b" 'ibuffer) #+END_SRC =isearch-forward-regexp= is much more useful than =isearch-forward= so @@ -1524,6 +1556,9 @@ Some nice functions #+END_SRC *** dns-mode +If you edit zone files via TRAMP you might want to activate them via +=rndc reload=. =C-c C-r= just does that for you. + #+BEGIN_SRC emacs-lisp (defun dns-rndc () "Do rndc reload of current buffers filename." diff --git a/elpa/helm-20150403.101/emacs-helm.sh b/elpa/helm-20150403.101/emacs-helm.sh new file mode 100755 index 00000000..d24128da --- /dev/null +++ b/elpa/helm-20150403.101/emacs-helm.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash + + +## Copyright (C) 2012 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 +## 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: + +# Preconfigured Emacs with a basic helm configuration. +# Useful to start quickly an emacs -Q with helm. +# Run it from this directory. + +TMP="/tmp/helm-cfg.el" +EMACS=emacs + +case $1 in + -P) + shift 1 + declare EMACS=$1 + shift 1 + ;; + -h) + echo "Usage: ${0##*/} [-P} Emacs path [-h} help [--] EMACS ARGS" + exit 2 + ;; +esac + +cd $(dirname "$0") + +# Check if autoload file exists. +# It is maybe in a different directory if +# emacs-helm.sh is a symlink. +LS=$(ls -l $0 | awk '{print $11}') +if [ ! -z $LS ]; then + AUTO_FILE="$(dirname $LS)/helm-autoloads.el" +else + AUTO_FILE="helm-autoloads.el" +fi +if [ ! -e "$AUTO_FILE" ]; then + echo No autoloads found, please run make first to generate autoload file + exit 2 +fi + + +cat > $TMP <\`helm-find-files'\n\ +;; - \`occur'(M-s o) =>\`helm-occur'\n\ +;; - \`list-buffers'(C-x C-b) =>\`helm-buffers-list'\n\ +;; - \`completion-at-point'(M-tab) =>\`helm-lisp-completion-at-point'[1]\n\ +;; - \`dabbrev-expand'(M-/) =>\`helm-dabbrev'\n\n\ +;; Some others native emacs commands are \"helmized\" by \`helm-mode'.\n\ +;; [1] Coming with emacs-24.4 \`completion-at-point' is \"helmized\" by \`helm-mode'\n\ +;; which provide helm completion in many other places like \`shell-mode'.\n\ +;; You will find embeded help for most helm commands with \`C-c ?'.\n\ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n")) + +(setq default-frame-alist '((vertical-scroll-bars . nil) + (tool-bar-lines . 0) + (menu-bar-lines . 0) + (fullscreen . nil))) +(blink-cursor-mode -1) +(add-to-list 'load-path (file-name-directory (file-truename "$0"))) +(require 'helm-config) +(helm-mode 1) +(define-key global-map [remap find-file] 'helm-find-files) +(define-key global-map [remap occur] 'helm-occur) +(define-key global-map [remap list-buffers] 'helm-buffers-list) +(define-key global-map [remap dabbrev-expand] 'helm-dabbrev) +(global-set-key (kbd "M-x") 'helm-M-x) +(unless (boundp 'completion-in-region-function) + (define-key lisp-interaction-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point) + (define-key emacs-lisp-mode-map [remap completion-at-point] 'helm-lisp-completion-at-point)) +(add-hook 'kill-emacs-hook #'(lambda () (and (file-exists-p "$TMP") (delete-file "$TMP")))) +EOF + +$EMACS -Q -l $TMP $@ + diff --git a/elpa/helm-20150403.101/helm-adaptive.el b/elpa/helm-20150403.101/helm-adaptive.el new file mode 100644 index 00000000..d7f05326 --- /dev/null +++ b/elpa/helm-20150403.101/helm-adaptive.el @@ -0,0 +1,243 @@ +;;; helm-adaptive.el --- Adaptive Sorting of Candidates. -*- lexical-binding: t -*- + +;; Original Author: Tamas Patrovics + +;; Copyright (C) 2007 Tamas Patrovics +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) + + +(defgroup helm-adapt nil + "Adaptative sorting of candidates for Helm." + :group 'helm) + +(defcustom helm-adaptive-history-file + "~/.emacs.d/helm-adaptive-history" + "Path of file where history information is stored." + :type 'string + :group 'helm-adapt) + +(defcustom helm-adaptive-history-length 50 + "Maximum number of candidates stored for a source." + :type 'number + :group 'helm-adapt) + + +;; Internal +(defvar helm-adaptive-done nil + "nil if history information is not yet stored for the current +selection.") + +(defvar helm-adaptive-history nil + "Contains the stored history information. +Format: ((SOURCE-NAME (SELECTED-CANDIDATE (PATTERN . NUMBER-OF-USE) ...) ...) ...)") + +(defun helm-adaptive-done-reset () + (setq helm-adaptive-done nil)) + +(define-minor-mode helm-adaptive-mode + "Toggle adaptive sorting in all sources." + :group 'helm-adapt + :require 'helm-adaptive + :global t + (if helm-adaptive-mode + (progn + (unless helm-adaptive-history + (helm-adaptive-maybe-load-history)) + (add-hook 'kill-emacs-hook 'helm-adaptive-save-history) + ;; Should run at beginning of `helm-initial-setup'. + (add-hook 'helm-before-initialize-hook 'helm-adaptive-done-reset) + ;; Should run at beginning of `helm-exit-minibuffer'. + (add-hook 'helm-before-action-hook 'helm-adaptive-store-selection) + ;; Should run at beginning of `helm-select-action'. + (add-hook 'helm-select-action-hook 'helm-adaptive-store-selection)) + (helm-adaptive-save-history) + (setq helm-adaptive-history nil) + (remove-hook 'kill-emacs-hook 'helm-adaptive-save-history) + (remove-hook 'helm-before-initialize-hook 'helm-adaptive-done-reset) + (remove-hook 'helm-before-action-hook 'helm-adaptive-store-selection) + (remove-hook 'helm-select-action-hook 'helm-adaptive-store-selection))) + +(defun helm-adapt-use-adaptive-p (&optional source-name) + "Return current source only if it use adaptive history, nil otherwise." + (when helm-adaptive-mode + (let* ((source (or source-name (helm-get-current-source))) + (adapt-source (or (assoc-default 'filtered-candidate-transformer + (assoc (assoc-default 'type source) + helm-type-attributes)) + (assoc-default 'candidate-transformer + (assoc (assoc-default 'type source) + helm-type-attributes)) + (assoc-default 'filtered-candidate-transformer source) + (assoc-default 'candidate-transformer source)))) + (if (listp adapt-source) + (and (member 'helm-adaptive-sort adapt-source) source) + (and (eq adapt-source 'helm-adaptive-sort) source))))) + +(defun helm-adaptive-store-selection () + "Store history information for the selected candidate." + (unless helm-adaptive-done + (setq helm-adaptive-done t) + (let ((source (helm-adapt-use-adaptive-p))) + (when source + (let* ((source-name (or (assoc-default 'type source) + (assoc-default 'name source))) + (source-info (or (assoc source-name helm-adaptive-history) + (progn + (push (list source-name) helm-adaptive-history) + (car helm-adaptive-history)))) + (selection (helm-get-selection)) + (selection-info (progn + (setcdr source-info + (cons + (let ((found (assoc selection (cdr source-info)))) + (if (not found) + ;; new entry + (list selection) + ;; move entry to the beginning of the + ;; list, so that it doesn't get + ;; trimmed when the history is + ;; truncated + (setcdr source-info + (delete found (cdr source-info))) + found)) + (cdr source-info))) + (cadr source-info))) + (pattern-info (progn + (setcdr selection-info + (cons + (let ((found (assoc helm-pattern (cdr selection-info)))) + (if (not found) + ;; new entry + (cons helm-pattern 0) + + ;; move entry to the beginning of the + ;; list, so if two patterns used the + ;; same number of times then the one + ;; used last appears first in the list + (setcdr selection-info + (delete found (cdr selection-info))) + found)) + (cdr selection-info))) + (cadr selection-info)))) + + ;; increase usage count + (setcdr pattern-info (1+ (cdr pattern-info))) + + ;; truncate history if needed + (if (> (length (cdr selection-info)) helm-adaptive-history-length) + (setcdr selection-info + (cl-subseq (cdr selection-info) 0 helm-adaptive-history-length)))))))) + +(defun helm-adaptive-maybe-load-history () + "Load `helm-adaptive-history-file' which contain `helm-adaptive-history'. +Returns nil if `helm-adaptive-history-file' doesn't exist." + (when (file-readable-p helm-adaptive-history-file) + (load-file helm-adaptive-history-file))) + +(defun helm-adaptive-save-history (&optional arg) + "Save history information to file given by `helm-adaptive-history-file'." + (interactive "p") + (with-temp-buffer + (insert + ";; -*- mode: emacs-lisp -*-\n" + ";; History entries used for helm adaptive display.\n") + (prin1 `(setq helm-adaptive-history ',helm-adaptive-history) + (current-buffer)) + (insert ?\n) + (write-region (point-min) (point-max) helm-adaptive-history-file nil + (unless arg 'quiet)))) + +(defun helm-adaptive-sort (candidates source) + "Sort the CANDIDATES for SOURCE by usage frequency. +This is a filtered candidate transformer you can use with the +`filtered-candidate-transformer' attribute." + (let* ((source-name (or (assoc-default 'type source) + (assoc-default 'name source))) + (source-info (assoc source-name helm-adaptive-history))) + (if source-info + (let ((usage + ;; ... assemble a list containing the (CANIDATE . USAGE-COUNT) + ;; pairs + (mapcar (lambda (candidate-info) + (let ((count 0)) + (cl-dolist (pattern-info (cdr candidate-info)) + (if (not (equal (car pattern-info) + helm-pattern)) + (cl-incf count (cdr pattern-info)) + + ;; if current pattern is equal to the previously + ;; used one then this candidate has priority + ;; (that's why its count is boosted by 10000) and + ;; it only has to compete with other candidates + ;; which were also selected with the same pattern + (setq count (+ 10000 (cdr pattern-info))) + (cl-return))) + (cons (car candidate-info) count))) + (cdr source-info)))) + (if (and usage (consp usage)) + ;; sort the list in descending order, so candidates with highest + ;; priorty come first + (progn + (setq usage (sort usage (lambda (first second) + (> (cdr first) (cdr second))))) + + ;; put those candidates first which have the highest usage count + (cl-loop for (info . _freq) in usage + for member = (cl-member info candidates + :test 'helm-adaptive-compare) + when member collect (car member) into sorted + and do + (setq candidates (cl-remove info candidates + :test 'helm-adaptive-compare)) + finally return (append sorted candidates))) + (message "Your `%s' is maybe corrupted or too old, \ +you should reinitialize it with `helm-reset-adaptive-history'" + helm-adaptive-history-file) + (sit-for 1) + candidates)) + ;; if there is no information stored for this source then do nothing + candidates))) + +;;;###autoload +(defun helm-reset-adaptive-history () + "Delete all `helm-adaptive-history' and his file. +Useful when you have a old or corrupted `helm-adaptive-history-file'." + (interactive) + (when (y-or-n-p "Really delete all your `helm-adaptive-history'? ") + (setq helm-adaptive-history nil) + (delete-file helm-adaptive-history-file))) + +(defun helm-adaptive-compare (x y) + "Compare candidates X and Y taking into account that the +candidate can be in (DISPLAY . REAL) format." + (equal (if (listp x) (cdr x) x) + (if (listp y) (cdr y) y))) + + +(provide 'helm-adaptive) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-adaptive.el ends here diff --git a/elpa/helm-20150403.101/helm-aliases.el b/elpa/helm-20150403.101/helm-aliases.el new file mode 100644 index 00000000..5427920a --- /dev/null +++ b/elpa/helm-20150403.101/helm-aliases.el @@ -0,0 +1,778 @@ +;;; helm-aliases.el --- Helm aliases for helm obsoletes functions. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) + + +;;; Helper functions to create aliases with old helm definitions +;; prefixed with "helm-c-" +;; +(defun helm-alias-p (sym) + (cond ((boundp sym) + (not (eq (indirect-variable sym) sym))) + ((fboundp sym) + (symbolp (symbol-function sym))) + (t nil))) + +(defun helm-check-conflicting-prefixes () + (cl-loop for s in (all-completions "helm-c-" obarray) + for rep = (replace-regexp-in-string "helm-c-" "helm-" s) + when (or (and (not (helm-alias-p (intern s))) (fboundp (intern rep))) + (and (not (helm-alias-p (intern s))) (boundp (intern rep)))) + collect rep)) + +(defun helm-collect-functions-with-bad-prefix () + (cl-loop for s in (all-completions "helm-c-" obarray) + for sym = (intern s) + when (and (not (helm-alias-p sym)) (fboundp sym)) + collect s)) + +(defun helm-collect-vars-with-bad-prefix () + (cl-loop for s in (all-completions "helm-c-" obarray) + for sym = (intern s) + when (and (not (helm-alias-p sym)) (boundp sym)) + collect s)) + +(defun helm-insert-fn-aliases () + (cl-loop for s in (helm-collect-functions-with-bad-prefix) + for rep = (replace-regexp-in-string "helm-c-" "helm-" s) + do (insert (format "(defalias '%s '%s)\n(make-obsolete '%s '%s \"1.5.1\")\n" s rep s rep)))) + +(defun helm-insert-var-aliases () + (cl-loop for s in (helm-collect-vars-with-bad-prefix) + for rep = (replace-regexp-in-string "helm-c-" "helm-" s) + do (insert (format "(defvaralias '%s '%s)\n(make-obsolete-variable '%s '%s \"1.5.1\")\n" s rep s rep)))) + + +;;; Alias old functions prefixed with "helm-c-" +;; +;; +(defalias 'helm-c-etags-default-action 'helm-etags-default-action) +(make-obsolete 'helm-c-etags-default-action 'helm-etags-default-action "1.5.1") +(defalias 'helm-c-show-info-in-mode-line 'helm-show-info-in-mode-line) +(make-obsolete 'helm-c-show-info-in-mode-line 'helm-show-info-in-mode-line "1.5.1") +(defalias 'helm-c-grep-highlight-match 'helm-grep-highlight-match) +(make-obsolete 'helm-c-grep-highlight-match 'helm-grep-highlight-match "1.5.1") +(defalias 'helm-c-apropos 'helm-apropos) +(make-obsolete 'helm-c-apropos 'helm-apropos "1.5.1") +(defalias 'helm-c-grep-guess-extensions 'helm-grep-guess-extensions) +(make-obsolete 'helm-c-grep-guess-extensions 'helm-grep-guess-extensions "1.5.1") +(defalias 'helm-c-apt-reinstall 'helm-apt-reinstall) +(make-obsolete 'helm-c-apt-reinstall 'helm-apt-reinstall "1.5.1") +(defalias 'helm-c-reset-adaptive-history 'helm-reset-adaptive-history) +(make-obsolete 'helm-c-reset-adaptive-history 'helm-reset-adaptive-history "1.5.1") +(defalias 'helm-adaptative-mode 'helm-adaptive-mode) +(make-obsolete 'helm-adaptative-mode 'helm-adaptive-mode "1.6.2") +(defalias 'helm-c-highlight-bookmark 'helm-highlight-bookmark) +(make-obsolete 'helm-c-highlight-bookmark 'helm-highlight-bookmark "1.5.1") +(defalias 'helm-c-locate-init 'helm-locate-init) +(make-obsolete 'helm-c-locate-init 'helm-locate-init "1.5.1") +(defalias 'helm-c-delete-file 'helm-delete-file) +(make-obsolete 'helm-c-delete-file 'helm-delete-file "1.5.1") +(defalias 'helm-c-regexp-persistent-action 'helm-regexp-persistent-action) +(make-obsolete 'helm-c-regexp-persistent-action 'helm-regexp-persistent-action "1.5.1") +(defalias 'helm-c-grep-split-line 'helm-grep-split-line) +(make-obsolete 'helm-c-grep-split-line 'helm-grep-split-line "1.5.1") +(defalias 'helm-c-info-display-to-real 'helm-info-display-to-real) +(make-obsolete 'helm-c-info-display-to-real 'helm-info-display-to-real "1.5.1") +(defalias 'helm-c-symbolify 'helm-symbolify) +(make-obsolete 'helm-c-symbolify 'helm-symbolify "1.5.1") +(defalias 'helm-c-zgrep-buffers 'helm-zgrep-buffers) +(make-obsolete 'helm-c-zgrep-buffers 'helm-zgrep-buffers "1.5.1") +(defalias 'helm-c-apt-persistent-action 'helm-apt-persistent-action) +(make-obsolete 'helm-c-apt-persistent-action 'helm-apt-persistent-action "1.5.1") +(defalias 'helm-c-pdfgrep-init 'helm-pdfgrep-init) +(make-obsolete 'helm-c-pdfgrep-init 'helm-pdfgrep-init "1.5.1") +(defalias 'helm-c-walk-directory 'helm-walk-directory) +(make-obsolete 'helm-c-walk-directory 'helm-walk-directory "1.5.1") +(defalias 'helm-c-grep-init 'helm-grep-init) +(make-obsolete 'helm-c-grep-init 'helm-grep-init "1.5.1") +(defalias 'helm-c-ucs-forward-char 'helm-ucs-forward-char) +(make-obsolete 'helm-c-ucs-forward-char 'helm-ucs-forward-char "1.5.1") +(defalias 'helm-c-complete-file-name-at-point 'helm-complete-file-name-at-point) +(make-obsolete 'helm-c-complete-file-name-at-point 'helm-complete-file-name-at-point "1.5.1") +(defalias 'helm-c-timer-real-to-display 'helm-timer-real-to-display) +(make-obsolete 'helm-c-timer-real-to-display 'helm-timer-real-to-display "1.5.1") +(defalias 'helm-c-ucs-init 'helm-ucs-init) +(make-obsolete 'helm-c-ucs-init 'helm-ucs-init "1.5.1") +(defalias 'helm-c-bookmark-run-delete 'helm-bookmark-run-delete) +(make-obsolete 'helm-c-bookmark-run-delete 'helm-bookmark-run-delete "1.5.1") +(defalias 'helm-c-uniq-list 'helm-uniq-list) +(make-obsolete 'helm-c-uniq-list 'helm-uniq-list "1.5.1") +(defalias 'helm-c-pp-bookmarks 'helm-pp-bookmarks) +(make-obsolete 'helm-c-pp-bookmarks 'helm-pp-bookmarks "1.5.1") +(defalias 'helm-c-top-sh-persistent-action 'helm-top-sh-persistent-action) +(make-obsolete 'helm-c-top-sh-persistent-action 'helm-top-sh-persistent-action "1.5.1") +(defalias 'helm-c-grep-action 'helm-grep-action) +(make-obsolete 'helm-c-grep-action 'helm-grep-action "1.5.1") +(defalias 'helm-c-file-buffers 'helm-file-buffers) +(make-obsolete 'helm-c-file-buffers 'helm-file-buffers "1.5.1") +(defalias 'helm-c-google-suggest-fetch 'helm-google-suggest-fetch) +(make-obsolete 'helm-c-google-suggest-fetch 'helm-google-suggest-fetch "1.5.1") +(defalias 'helm-c-arrange-type-attribute 'helm-arrange-type-attribute) +(make-obsolete 'helm-c-arrange-type-attribute 'helm-arrange-type-attribute "1.5.1") +(defalias 'helm-c-yahoo-suggest-action 'helm-yahoo-suggest-action) +(make-obsolete 'helm-c-yahoo-suggest-action 'helm-yahoo-suggest-action "1.5.1") +(defalias 'helm-c-buffer-query-replace-1 'helm-buffer-query-replace-1) +(make-obsolete 'helm-c-buffer-query-replace-1 'helm-buffer-query-replace-1 "1.5.1") +(defalias 'helm-c-make-info-source 'helm-make-info-source) +(make-obsolete 'helm-c-make-info-source 'helm-make-info-source "1.5.1") +(defalias 'helm-c-open-dired 'helm-open-dired) +(make-obsolete 'helm-c-open-dired 'helm-open-dired "1.5.1") +(defalias 'helm-c-kill-ring-transformer 'helm-kill-ring-transformer) +(make-obsolete 'helm-c-kill-ring-transformer 'helm-kill-ring-transformer "1.5.1") +(defalias 'helm-c-etags-init 'helm-etags-init) +(make-obsolete 'helm-c-etags-init 'helm-etags-init "1.5.1") +(defalias 'helm-c-advice-update-current-display-string 'helm-advice-update-current-display-string) +(make-obsolete 'helm-c-advice-update-current-display-string 'helm-advice-update-current-display-string "1.5.1") +(defalias 'helm-c-regexp-get-line 'helm-regexp-get-line) +(make-obsolete 'helm-c-regexp-get-line 'helm-regexp-get-line "1.5.1") +(defalias 'helm-c-grep-run-other-window-action 'helm-grep-run-other-window-action) +(make-obsolete 'helm-c-grep-run-other-window-action 'helm-grep-run-other-window-action "1.5.1") +(defalias 'helm-c-regexp-kill-new 'helm-regexp-kill-new) +(make-obsolete 'helm-c-regexp-kill-new 'helm-regexp-kill-new "1.5.1") +(defalias 'helm-c-grep-run-default-action 'helm-grep-run-default-action) +(make-obsolete 'helm-c-grep-run-default-action 'helm-grep-run-default-action "1.5.1") +(defalias 'helm-c-define-info-index-sources 'helm-define-info-index-sources) +(make-obsolete 'helm-c-define-info-index-sources 'helm-define-info-index-sources "1.5.1") +(defalias 'helm-c-transform-file-browse-url 'helm-transform-file-browse-url) +(make-obsolete 'helm-c-transform-file-browse-url 'helm-transform-file-browse-url "1.5.1") +(defalias 'helm-c-shell-command-if-needed 'helm-shell-command-if-needed) +(make-obsolete 'helm-c-shell-command-if-needed 'helm-shell-command-if-needed "1.5.1") +(defalias 'helm-c-kill-regexp-as-sexp 'helm-kill-regexp-as-sexp) +(make-obsolete 'helm-c-kill-regexp-as-sexp 'helm-kill-regexp-as-sexp "1.5.1") +(defalias 'helm-c-goto-next-or-prec-file 'helm-goto-next-or-prec-file) +(make-obsolete 'helm-c-goto-next-or-prec-file 'helm-goto-next-or-prec-file "1.5.1") +(defalias 'helm-c-insert-file-name-completion-at-point 'helm-insert-file-name-completion-at-point) +(make-obsolete 'helm-c-insert-file-name-completion-at-point 'helm-insert-file-name-completion-at-point "1.5.1") +(defalias 'helm-c-point-file-in-dired 'helm-point-file-in-dired) +(make-obsolete 'helm-c-point-file-in-dired 'helm-point-file-in-dired "1.5.1") +(defalias 'helm-c-info-goto 'helm-info-goto) +(make-obsolete 'helm-c-info-goto 'helm-info-goto "1.5.1") +(defalias 'helm-c-apt-install 'helm-apt-install) +(make-obsolete 'helm-c-apt-install 'helm-apt-install "1.5.1") +(defalias 'helm-c-skip-boring-buffers 'helm-skip-boring-buffers) +(make-obsolete 'helm-c-skip-boring-buffers 'helm-skip-boring-buffers "1.5.1") +(defalias 'helm-c-register-candidates 'helm-register-candidates) +(make-obsolete 'helm-c-register-candidates 'helm-register-candidates "1.5.1") +(defalias 'helm-c-find-function 'helm-find-function) +(make-obsolete 'helm-c-find-function 'helm-find-function "1.5.1") +(defalias 'helm-c-apt-display-to-real 'helm-apt-display-to-real) +(make-obsolete 'helm-c-apt-display-to-real 'helm-apt-display-to-real "1.5.1") +(defalias 'helm-c-org-keywords-init 'helm-org-keywords-init) +(make-obsolete 'helm-c-org-keywords-init 'helm-org-keywords-init "1.5.1") +(defalias 'helm-c-xrandr-screen 'helm-xrandr-screen) +(make-obsolete 'helm-c-xrandr-screen 'helm-xrandr-screen "1.5.1") +(defalias 'helm-c-position 'helm-position) +(make-obsolete 'helm-c-position 'helm-position "1.5.1") +(defalias 'helm-c-imenu-candidates 'helm-imenu-candidates) +(make-obsolete 'helm-c-imenu-candidates 'helm-imenu-candidates "1.5.1") +(defalias 'helm-c-ucs-persistent-forward 'helm-ucs-persistent-forward) +(make-obsolete 'helm-c-ucs-persistent-forward 'helm-ucs-persistent-forward "1.5.1") +(defalias 'helm-c-basename 'helm-basename) +(make-obsolete 'helm-c-basename 'helm-basename "1.5.1") +(defalias 'helm-c-files-in-all-dired-candidates 'helm-files-in-all-dired-candidates) +(make-obsolete 'helm-c-files-in-all-dired-candidates 'helm-files-in-all-dired-candidates "1.5.1") +(defalias 'helm-c-grep-other-window 'helm-grep-other-window) +(make-obsolete 'helm-c-grep-other-window 'helm-grep-other-window "1.5.1") +(defalias 'helm-c-yahoo-suggest-fetch 'helm-yahoo-suggest-fetch) +(make-obsolete 'helm-c-yahoo-suggest-fetch 'helm-yahoo-suggest-fetch "1.5.1") +(defalias 'helm-c-external-commands-list-1 'helm-external-commands-list-1) +(make-obsolete 'helm-c-external-commands-list-1 'helm-external-commands-list-1 "1.5.1") +(defalias 'helm-c-buffers-list-persistent-action 'helm-buffers-list-persistent-action) +(make-obsolete 'helm-c-buffers-list-persistent-action 'helm-buffers-list-persistent-action "1.5.1") +(defalias 'helm-c-show-completion-init-overlay 'helm-show-completion-init-overlay) +(make-obsolete 'helm-c-show-completion-init-overlay 'helm-show-completion-init-overlay "1.5.1") +(defalias 'helm-c-shadow-boring-files 'helm-shadow-boring-files) +(make-obsolete 'helm-c-shadow-boring-files 'helm-shadow-boring-files "1.5.1") +(defalias 'helm-c-bookmark-local-files-setup-alist 'helm-bookmark-local-files-setup-alist) +(make-obsolete 'helm-c-bookmark-local-files-setup-alist 'helm-bookmark-local-files-setup-alist "1.5.1") +(defalias 'helm-c-highlight-local-use 'helm-highlight-local-use) +(make-obsolete 'helm-c-highlight-local-use 'helm-highlight-local-use "1.5.1") +(defalias 'helm-c-skip-current-file 'helm-skip-current-file) +(make-obsolete 'helm-c-skip-current-file 'helm-skip-current-file "1.5.1") +(defalias 'helm-c-goto-next-file 'helm-goto-next-file) +(make-obsolete 'helm-c-goto-next-file 'helm-goto-next-file "1.5.1") +(defalias 'helm-c-info-init 'helm-info-init) +(make-obsolete 'helm-c-info-init 'helm-info-init "1.5.1") +(defalias 'helm-c-query-replace-args 'helm-query-replace-args) +(make-obsolete 'helm-c-query-replace-args 'helm-query-replace-args "1.5.1") +(defalias 'helm-c-bookmark-info-setup-alist 'helm-bookmark-info-setup-alist) +(make-obsolete 'helm-c-bookmark-info-setup-alist 'helm-bookmark-info-setup-alist "1.5.1") +(defalias 'helm-c-ratpoison-commands-execute 'helm-ratpoison-commands-execute) +(make-obsolete 'helm-c-ratpoison-commands-execute 'helm-ratpoison-commands-execute "1.5.1") +(defalias 'helm-c-ucs-persistent-backward 'helm-ucs-persistent-backward) +(make-obsolete 'helm-c-ucs-persistent-backward 'helm-ucs-persistent-backward "1.5.1") +(defalias 'helm-c-info-pages-init 'helm-info-pages-init) +(make-obsolete 'helm-c-info-pages-init 'helm-info-pages-init "1.5.1") +(defalias 'helm-c-grep-save-results 'helm-grep-save-results) +(make-obsolete 'helm-c-grep-save-results 'helm-grep-save-results "1.5.1") +(defalias 'helm-c-read-file-name 'helm-read-file-name) +(make-obsolete 'helm-c-read-file-name 'helm-read-file-name "1.5.1") +(defalias 'helm-c-org-keywords-insert 'helm-org-keywords-insert) +(make-obsolete 'helm-c-org-keywords-insert 'helm-org-keywords-insert "1.5.1") +(defalias 'helm-c-call-interactively 'helm-call-interactively) +(make-obsolete 'helm-c-call-interactively 'helm-call-interactively "1.5.1") +(defalias 'helm-c-adaptative-compare 'helm-adaptive-compare) +(make-obsolete 'helm-c-adaptative-compare 'helm-adaptive-compare "1.5.1") +(defalias 'helm-c-buffer-list 'helm-buffer-list) +(make-obsolete 'helm-c-buffer-list 'helm-buffer-list "1.5.1") +(defalias 'helm-c-thing-before-point 'helm-thing-before-point) +(make-obsolete 'helm-c-thing-before-point 'helm-thing-before-point "1.5.1") +(defalias 'helm-c-ratpoison-commands-display-to-real 'helm-ratpoison-commands-display-to-real) +(make-obsolete 'helm-c-ratpoison-commands-display-to-real 'helm-ratpoison-commands-display-to-real "1.5.1") +(defalias 'helm-c-imenu-default-action 'helm-imenu-default-action) +(make-obsolete 'helm-c-imenu-default-action 'helm-imenu-default-action "1.5.1") +(defalias 'helm-c-describe-function 'helm-describe-function) +(make-obsolete 'helm-c-describe-function 'helm-describe-function "1.5.1") +(defalias 'helm-c-colors-get-name 'helm-colors-get-name) +(make-obsolete 'helm-c-colors-get-name 'helm-colors-get-name "1.5.1") +(defalias 'helm-c-bookmark-help 'helm-bookmark-help) +(make-obsolete 'helm-c-bookmark-help 'helm-bookmark-help "1.5.1") +(defalias 'helm-c-ucs-persistent-delete 'helm-ucs-persistent-delete) +(make-obsolete 'helm-c-ucs-persistent-delete 'helm-ucs-persistent-delete "1.5.1") +(defalias 'helm-c-set-variable 'helm-set-variable) +(make-obsolete 'helm-c-set-variable 'helm-set-variable "1.5.1") +(defalias 'helm-c-grep-save-results-1 'helm-grep-save-results-1) +(make-obsolete 'helm-c-grep-save-results-1 'helm-grep-save-results-1 "1.5.1") +(defalias 'helm-c-adaptative-maybe-load-history 'helm-adaptive-maybe-load-history) +(make-obsolete 'helm-c-adaptative-maybe-load-history 'helm-adaptive-maybe-load-history "1.5.1") +(defalias 'helm-c-w32-pathname-transformer 'helm-w32-pathname-transformer) +(make-obsolete 'helm-c-w32-pathname-transformer 'helm-w32-pathname-transformer "1.5.1") +(defalias 'helm-c-top-display-to-real 'helm-top-display-to-real) +(make-obsolete 'helm-c-top-display-to-real 'helm-top-display-to-real "1.5.1") +(defalias 'helm-c-open-file-externally 'helm-open-file-externally) +(make-obsolete 'helm-c-open-file-externally 'helm-open-file-externally "1.5.1") +(defalias 'helm-c-colors-get-rgb 'helm-colors-get-rgb) +(make-obsolete 'helm-c-colors-get-rgb 'helm-colors-get-rgb "1.5.1") +(defalias 'helm-c-stumpwm-commands-init 'helm-stumpwm-commands-init) +(make-obsolete 'helm-c-stumpwm-commands-init 'helm-stumpwm-commands-init "1.5.1") +(defalias 'helm-c-highlight-world 'helm-highlight-world) +(make-obsolete 'helm-c-highlight-world 'helm-highlight-world "1.5.1") +(defalias 'helm-c-top-sh 'helm-top-sh) +(make-obsolete 'helm-c-top-sh 'helm-top-sh "1.5.1") +(defalias 'helm-c-persistent-xfont-action 'helm-persistent-xfont-action) +(make-obsolete 'helm-c-persistent-xfont-action 'helm-persistent-xfont-action "1.5.1") +(defalias 'helm-c-latex-math-candidates 'helm-latex-math-candidates) +(make-obsolete 'helm-c-latex-math-candidates 'helm-latex-math-candidates "1.5.1") +(defalias 'helm-c-ucs-backward-char 'helm-ucs-backward-char) +(make-obsolete 'helm-c-ucs-backward-char 'helm-ucs-backward-char "1.5.1") +(defalias 'helm-c-calculate-ucs-max-len 'helm-calculate-ucs-max-len) +(make-obsolete 'helm-c-calculate-ucs-max-len 'helm-calculate-ucs-max-len "1.5.1") +(defalias 'helm-c-etags-mtime 'helm-etags-mtime) +(make-obsolete 'helm-c-etags-mtime 'helm-etags-mtime "1.5.1") +(defalias 'helm-c-google-suggest-action 'helm-google-suggest-action) +(make-obsolete 'helm-c-google-suggest-action 'helm-google-suggest-action "1.5.1") +(defalias 'helm-c-elisp-library-scan-init 'helm-elisp-library-scan-init) +(make-obsolete 'helm-c-elisp-library-scan-init 'helm-elisp-library-scan-init "1.5.1") +(defalias 'helm-c-apt-refresh 'helm-apt-refresh) +(make-obsolete 'helm-c-apt-refresh 'helm-apt-refresh "1.5.1") +(defalias 'helm-c-kill-regexp 'helm-kill-regexp) +(make-obsolete 'helm-c-kill-regexp 'helm-kill-regexp "1.5.1") +(defalias 'helm-c-grep-buffers-1 'helm-grep-buffers-1) +(make-obsolete 'helm-c-grep-buffers-1 'helm-grep-buffers-1 "1.5.1") +(defalias 'helm-c-adaptative-store-selection 'helm-adaptive-store-selection) +(make-obsolete 'helm-c-adaptative-store-selection 'helm-adaptive-store-selection "1.5.1") +(defalias 'helm-c-browse-url 'helm-browse-url) +(make-obsolete 'helm-c-browse-url 'helm-browse-url "1.5.1") +(defalias 'helm-c-google-suggest-emacs-lisp 'helm-google-suggest-emacs-lisp) +(make-obsolete 'helm-c-google-suggest-emacs-lisp 'helm-google-suggest-emacs-lisp "1.5.1") +(defalias 'helm-c-ucs-persistent-insert 'helm-ucs-persistent-insert) +(make-obsolete 'helm-c-ucs-persistent-insert 'helm-ucs-persistent-insert "1.5.1") +(defalias 'helm-c-xrandr-output 'helm-xrandr-output) +(make-obsolete 'helm-c-xrandr-output 'helm-xrandr-output "1.5.1") +(defalias 'helm-c-kill-ring-action 'helm-kill-ring-action) +(make-obsolete 'helm-c-kill-ring-action 'helm-kill-ring-action "1.5.1") +(defalias 'helm-c-org-keywords-candidates 'helm-org-keywords-candidates) +(make-obsolete 'helm-c-org-keywords-candidates 'helm-org-keywords-candidates "1.5.1") +(defalias 'helm-c-bookmark-jump 'helm-bookmark-jump) +(make-obsolete 'helm-c-bookmark-jump 'helm-bookmark-jump "1.5.1") +(defalias 'helm-c-shadow-boring-buffers 'helm-shadow-boring-buffers) +(make-obsolete 'helm-c-shadow-boring-buffers 'helm-shadow-boring-buffers "1.5.1") +(defalias 'helm-c-buffer-match-major-mode 'helm-buffer-match-major-mode) +(make-obsolete 'helm-c-buffer-match-major-mode 'helm-buffer-match-major-mode "1.5.1") +(defalias 'helm-c-highlight-bookmark-su 'helm-highlight-bookmark-su) +(make-obsolete 'helm-c-highlight-bookmark-su 'helm-highlight-bookmark-su "1.5.1") +(defalias 'helm-c-grep-other-frame 'helm-grep-other-frame) +(make-obsolete 'helm-c-grep-other-frame 'helm-grep-other-frame "1.5.1") +(defalias 'helm-c-jabber-online-contacts 'helm-jabber-online-contacts) +(make-obsolete 'helm-c-jabber-online-contacts 'helm-jabber-online-contacts "1.5.1") +(defalias 'helm-c-apt-purge 'helm-apt-purge) +(make-obsolete 'helm-c-apt-purge 'helm-apt-purge "1.5.1") +(defalias 'helm-c-adaptative-sort 'helm-adaptive-sort) +(make-obsolete 'helm-c-adaptative-sort 'helm-adaptive-sort "1.5.1") +(defalias 'helm-c-bmkext-addressbook-setup-alist 'helm-bmkext-addressbook-setup-alist) +(make-obsolete 'helm-c-bmkext-addressbook-setup-alist 'helm-bmkext-addressbook-setup-alist "1.5.1") +(defalias 'helm-c-bmkext-filter-setup-alist 'helm-bmkext-filter-setup-alist) +(make-obsolete 'helm-c-bmkext-filter-setup-alist 'helm-bmkext-filter-setup-alist "1.5.1") +(defalias 'helm-c-grep-buffers 'helm-grep-buffers) +(make-obsolete 'helm-c-grep-buffers 'helm-grep-buffers "1.5.1") +(defalias 'helm-c-apt-init 'helm-apt-init) +(make-obsolete 'helm-c-apt-init 'helm-apt-init "1.5.1") +(defalias 'helm-c-grep-run-save-buffer 'helm-grep-run-save-buffer) +(make-obsolete 'helm-c-grep-run-save-buffer 'helm-grep-run-save-buffer "1.5.1") +(defalias 'helm-c-ggs-set-number-result 'helm-ggs-set-number-result) +(make-obsolete 'helm-c-ggs-set-number-result 'helm-ggs-set-number-result "1.5.1") +(defalias 'helm-c-grep-prepare-candidates 'helm-grep-prepare-candidates) +(make-obsolete 'helm-c-grep-prepare-candidates 'helm-grep-prepare-candidates "1.5.1") +(defalias 'helm-c-grep-jump-elscreen 'helm-grep-jump-elscreen) +(make-obsolete 'helm-c-grep-jump-elscreen 'helm-grep-jump-elscreen "1.5.1") +(defalias 'helm-c-show-completion-display-function 'helm-show-completion-display-function) +(make-obsolete 'helm-c-show-completion-display-function 'helm-show-completion-display-function "1.5.1") +(defalias 'helm-c-find-variable 'helm-find-variable) +(make-obsolete 'helm-c-find-variable 'helm-find-variable "1.5.1") +(defalias 'helm-c-build-elvi-list 'helm-build-elvi-list) +(make-obsolete 'helm-c-build-elvi-list 'helm-build-elvi-list "1.5.1") +(defalias 'helm-c-advice-toggle 'helm-advice-toggle) +(make-obsolete 'helm-c-advice-toggle 'helm-advice-toggle "1.5.1") +(defalias 'helm-c-buffers-persistent-kill 'helm-buffers-persistent-kill) +(make-obsolete 'helm-c-buffers-persistent-kill 'helm-buffers-persistent-kill "1.5.1") +(defalias 'helm-c-register-action-transformer 'helm-register-action-transformer) +(make-obsolete 'helm-c-register-action-transformer 'helm-register-action-transformer "1.5.1") +(defalias 'helm-c-kill-ring-candidates 'helm-kill-ring-candidates) +(make-obsolete 'helm-c-kill-ring-candidates 'helm-kill-ring-candidates "1.5.1") +(defalias 'helm-c-generic-browser 'helm-generic-browser) +(make-obsolete 'helm-c-generic-browser 'helm-generic-browser "1.5.1") +(defalias 'helm-c-top-init 'helm-top-init) +(make-obsolete 'helm-c-top-init 'helm-top-init "1.5.1") +(defalias 'helm-c-ucs-delete-backward 'helm-ucs-delete-backward) +(make-obsolete 'helm-c-ucs-delete-backward 'helm-ucs-delete-backward "1.5.1") +(defalias 'helm-c-apt-generic-action 'helm-apt-generic-action) +(make-obsolete 'helm-c-apt-generic-action 'helm-apt-generic-action "1.5.1") +(defalias 'helm-c-pdfgrep-action-1 'helm-pdfgrep-action-1) +(make-obsolete 'helm-c-pdfgrep-action-1 'helm-pdfgrep-action-1 "1.5.1") +(defalias 'helm-c-buffer-query-replace-regexp 'helm-buffer-query-replace-regexp) +(make-obsolete 'helm-c-buffer-query-replace-regexp 'helm-buffer-query-replace-regexp "1.5.1") +(defalias 'helm-c-apropos-init 'helm-apropos-init) +(make-obsolete 'helm-c-apropos-init 'helm-apropos-init "1.5.1") +(defalias 'helm-c-kill-new 'helm-kill-new) +(make-obsolete 'helm-c-kill-new 'helm-kill-new "1.5.1") +(defalias 'helm-c-bookmark-gnus-setup-alist 'helm-bookmark-gnus-setup-alist) +(make-obsolete 'helm-c-bookmark-gnus-setup-alist 'helm-bookmark-gnus-setup-alist "1.5.1") +(defalias 'helm-c-quit-and-execute-action 'helm-quit-and-execute-action) +(make-obsolete 'helm-c-quit-and-execute-action 'helm-quit-and-execute-action "1.5.1") +(defalias 'helm-c-build-info-index-command 'helm-build-info-index-command) +(make-obsolete 'helm-c-build-info-index-command 'helm-build-info-index-command "1.5.1") +(defalias 'helm-c-ratpoison-commands-init 'helm-ratpoison-commands-init) +(make-obsolete 'helm-c-ratpoison-commands-init 'helm-ratpoison-commands-init "1.5.1") +(defalias 'helm-c-etags-select 'helm-etags-select) +(make-obsolete 'helm-c-etags-select 'helm-etags-select "1.5.1") +(defalias 'helm-c-etags-create-buffer 'helm-etags-create-buffer) +(make-obsolete 'helm-c-etags-create-buffer 'helm-etags-create-buffer "1.5.1") +(defalias 'helm-c-yahoo-suggest-set-candidates 'helm-yahoo-suggest-set-candidates) +(make-obsolete 'helm-c-yahoo-suggest-set-candidates 'helm-yahoo-suggest-set-candidates "1.5.1") +(defalias 'helm-c-org-keywords-show-help 'helm-org-keywords-show-help) +(make-obsolete 'helm-c-org-keywords-show-help 'helm-org-keywords-show-help "1.5.1") +(defalias 'helm-c-highlight-files 'helm-highlight-files) +(make-obsolete 'helm-c-highlight-files 'helm-highlight-files "1.5.1") +(defalias 'helm-c-get-pid-from-process-name 'helm-get-pid-from-process-name) +(make-obsolete 'helm-c-get-pid-from-process-name 'helm-get-pid-from-process-name "1.5.1") +(defalias 'helm-c-insert-latex-math 'helm-insert-latex-math) +(make-obsolete 'helm-c-insert-latex-math 'helm-insert-latex-math "1.5.1") +(defalias 'helm-c-buffer-query-replace 'helm-buffer-query-replace) +(make-obsolete 'helm-c-buffer-query-replace 'helm-buffer-query-replace "1.5.1") +(defalias 'helm-c-bmkext-run-edit 'helm-bmkext-run-edit) +(make-obsolete 'helm-c-bmkext-run-edit 'helm-bmkext-run-edit "1.5.1") +(defalias 'helm-c-skip-boring-files 'helm-skip-boring-files) +(make-obsolete 'helm-c-skip-boring-files 'helm-skip-boring-files "1.5.1") +(defalias 'helm-c-transform-file-load-el 'helm-transform-file-load-el) +(make-obsolete 'helm-c-transform-file-load-el 'helm-transform-file-load-el "1.5.1") +(defalias 'helm-c-ucs-insert-char 'helm-ucs-insert-char) +(make-obsolete 'helm-c-ucs-insert-char 'helm-ucs-insert-char "1.5.1") +(defalias 'helm-c-buffer-help 'helm-buffer-help) +(make-obsolete 'helm-c-buffer-help 'helm-buffer-help "1.5.1") +(defalias 'helm-c-current-directory 'helm-current-directory) +(make-obsolete 'helm-c-current-directory 'helm-current-directory "1.5.1") +(defalias 'helm-c-find-file-or-marked 'helm-find-file-or-marked) +(make-obsolete 'helm-c-find-file-or-marked 'helm-find-file-or-marked "1.5.1") +(defalias 'helm-c-query-replace-regexp 'helm-query-replace-regexp) +(make-obsolete 'helm-c-query-replace-regexp 'helm-query-replace-regexp "1.5.1") +(defalias 'helm-c-describe-variable 'helm-describe-variable) +(make-obsolete 'helm-c-describe-variable 'helm-describe-variable "1.5.1") +(defalias 'helm-c-advice-persistent-action 'helm-advice-persistent-action) +(make-obsolete 'helm-c-advice-persistent-action 'helm-advice-persistent-action "1.5.1") +(defalias 'helm-c-show-completion 'helm-show-completion) +(make-obsolete 'helm-c-show-completion 'helm-show-completion "1.5.1") +(defalias 'helm-c-google-suggest-set-candidates 'helm-google-suggest-set-candidates) +(make-obsolete 'helm-c-google-suggest-set-candidates 'helm-google-suggest-set-candidates "1.5.1") +(defalias 'helm-c-grep-persistent-action 'helm-grep-persistent-action) +(make-obsolete 'helm-c-grep-persistent-action 'helm-grep-persistent-action "1.5.1") +(defalias 'helm-c-open-file-with-default-tool 'helm-open-file-with-default-tool) +(make-obsolete 'helm-c-open-file-with-default-tool 'helm-open-file-with-default-tool "1.5.1") +(defalias 'helm-c-run-external-command 'helm-run-external-command) +(make-obsolete 'helm-c-run-external-command 'helm-run-external-command "1.5.1") +(defalias 'helm-c-bookmark-images-setup-alist 'helm-bookmark-images-setup-alist) +(make-obsolete 'helm-c-bookmark-images-setup-alist 'helm-bookmark-images-setup-alist "1.5.1") +(defalias 'helm-c-apt-candidate-transformer 'helm-apt-candidate-transformer) +(make-obsolete 'helm-c-apt-candidate-transformer 'helm-apt-candidate-transformer "1.5.1") +(defalias 'helm-c-grep-run-persistent-action 'helm-grep-run-persistent-action) +(make-obsolete 'helm-c-grep-run-persistent-action 'helm-grep-run-persistent-action "1.5.1") +(defalias 'helm-c-highlight-buffers 'helm-highlight-buffers) +(make-obsolete 'helm-c-highlight-buffers 'helm-highlight-buffers "1.5.1") +(defalias 'helm-c-man-default-action 'helm-man-default-action) +(make-obsolete 'helm-c-man-default-action 'helm-man-default-action "1.5.1") +(defalias 'helm-c-advice-candidates 'helm-advice-candidates) +(make-obsolete 'helm-c-advice-candidates 'helm-advice-candidates "1.5.1") +(defalias 'helm-c-stumpwm-commands-execute 'helm-stumpwm-commands-execute) +(make-obsolete 'helm-c-stumpwm-commands-execute 'helm-stumpwm-commands-execute "1.5.1") +(defalias 'helm-c-ucs-help 'helm-ucs-help) +(make-obsolete 'helm-c-ucs-help 'helm-ucs-help "1.5.1") +(defalias 'helm-c-apt-uninstall 'helm-apt-uninstall) +(make-obsolete 'helm-c-apt-uninstall 'helm-apt-uninstall "1.5.1") +(defalias 'helm-c-bookmark-run-jump-other-window 'helm-bookmark-run-jump-other-window) +(make-obsolete 'helm-c-bookmark-run-jump-other-window 'helm-bookmark-run-jump-other-window "1.5.1") +(defalias 'helm-c-elisp-library-scan-list 'helm-elisp-library-scan-list) +(make-obsolete 'helm-c-elisp-library-scan-list 'helm-elisp-library-scan-list "1.5.1") +(defalias 'helm-c-bookmark-man-setup-alist 'helm-bookmark-man-setup-alist) +(make-obsolete 'helm-c-bookmark-man-setup-alist 'helm-bookmark-man-setup-alist "1.5.1") +(defalias 'helm-c-etags-find-tag-file-directory 'helm-etags-find-tag-file-directory) +(make-obsolete 'helm-c-etags-find-tag-file-directory 'helm-etags-find-tag-file-directory "1.5.1") +(defalias 'helm-c-xrandr-info 'helm-xrandr-info) +(make-obsolete 'helm-c-xrandr-info 'helm-xrandr-info "1.5.1") +(defalias 'helm-c-stringify 'helm-stringify) +(make-obsolete 'helm-c-stringify 'helm-stringify "1.5.1") +(defalias 'helm-c-goto-precedent-file 'helm-goto-precedent-file) +(make-obsolete 'helm-c-goto-precedent-file 'helm-goto-precedent-file "1.5.1") +(defalias 'helm-c-apt-cache-show 'helm-apt-cache-show) +(make-obsolete 'helm-c-apt-cache-show 'helm-apt-cache-show "1.5.1") +(defalias 'helm-c-etags-file-modified-p 'helm-etags-file-modified-p) +(make-obsolete 'helm-c-etags-file-modified-p 'helm-etags-file-modified-p "1.5.1") +(defalias 'helm-c-etags-get-tag-file 'helm-etags-get-tag-file) +(make-obsolete 'helm-c-etags-get-tag-file 'helm-etags-get-tag-file "1.5.1") +(defalias 'helm-c-highlight-not-logged 'helm-highlight-not-logged) +(make-obsolete 'helm-c-highlight-not-logged 'helm-highlight-not-logged "1.5.1") +(defalias 'helm-c-pdfgrep-action 'helm-pdfgrep-action) +(make-obsolete 'helm-c-pdfgrep-action 'helm-pdfgrep-action "1.5.1") +(defalias 'helm-c-adaptative-save-history 'helm-adaptive-save-history) +(make-obsolete 'helm-c-adaptative-save-history 'helm-adaptive-save-history "1.5.1") +(defalias 'helm-c-get-first-line-documentation 'helm-get-first-line-documentation) +(make-obsolete 'helm-c-get-first-line-documentation 'helm-get-first-line-documentation "1.5.1") +(defalias 'helm-approximate-candidate-number 'helm-get-candidate-number) +(make-obsolete 'helm-approximate-candidate-number 'helm-get-candidate-number "1.5.5") +(defalias 'helm-org-headlines 'helm-org-in-buffer-headings) +(make-obsolete 'helm-org-headlines 'helm-org-in-buffer-headings "1.6.5") + + +;;; variables +;; +;; + + +(defvaralias 'helm-c-pdfgrep-default-command 'helm-pdfgrep-default-command) +(make-obsolete-variable 'helm-c-pdfgrep-default-command 'helm-pdfgrep-default-command "1.5.1") +(defvaralias 'helm-c-source-time-world 'helm-source-time-world) +(make-obsolete-variable 'helm-c-source-time-world 'helm-source-time-world "1.5.1") +(defvaralias 'helm-c-grep-default-command 'helm-grep-default-command) +(make-obsolete-variable 'helm-c-grep-default-command 'helm-grep-default-command "1.5.1") +(defvaralias 'helm-c-default-info-index-list 'helm-default-info-index-list) +(make-obsolete-variable 'helm-c-default-info-index-list 'helm-default-info-index-list "1.5.1") +(defvaralias 'helm-c-etags-tag-file-dir 'helm-etags-tag-file-dir) +(make-obsolete-variable 'helm-c-etags-tag-file-dir 'helm-etags-tag-file-dir "1.5.1") +(defvaralias 'helm-c-source-man-pages 'helm-source-man-pages) +(make-obsolete-variable 'helm-c-source-man-pages 'helm-source-man-pages "1.5.1") +(defvaralias 'helm-c-source-bookmark-info 'helm-source-bookmark-info) +(make-obsolete-variable 'helm-c-source-bookmark-info 'helm-source-bookmark-info "1.5.1") +(defvaralias 'helm-c-file-cache-files 'helm-file-cache-files) +(make-obsolete-variable 'helm-c-file-cache-files 'helm-file-cache-files "1.5.1") +(defvaralias 'helm-c-ucs-map 'helm-ucs-map) +(make-obsolete-variable 'helm-c-ucs-map 'helm-ucs-map "1.5.1") +(defvaralias 'helm-c-show-completion-min-window-height 'helm-show-completion-min-window-height) +(make-obsolete-variable 'helm-c-show-completion-min-window-height 'helm-show-completion-min-window-height "1.5.1") +(defvaralias 'helm-c-adaptative-history 'helm-adaptive-history) +(make-obsolete-variable 'helm-c-adaptative-history 'helm-adaptive-history "1.5.1") +(defvaralias 'helm-c-source-bookmarks-local 'helm-source-bookmarks-local) +(make-obsolete-variable 'helm-c-source-bookmarks-local 'helm-source-bookmarks-local "1.5.1") +(defvaralias 'helm-c-grep-map 'helm-grep-map) +(make-obsolete-variable 'helm-c-grep-map 'helm-grep-map "1.5.1") +(defvaralias 'helm-c-source-session 'helm-source-session) +(make-obsolete-variable 'helm-c-source-session 'helm-source-session "1.5.1") +(defvaralias 'helm-c-source-minibuffer-history 'helm-source-minibuffer-history) +(make-obsolete-variable 'helm-c-source-minibuffer-history 'helm-source-minibuffer-history "1.5.1") +(defvaralias 'helm-c-source-files-in-current-dir 'helm-source-files-in-current-dir) +(make-obsolete-variable 'helm-c-source-files-in-current-dir 'helm-source-files-in-current-dir "1.5.1") +(defvaralias 'helm-c-source-etags-select 'helm-source-etags-select) +(make-obsolete-variable 'helm-c-source-etags-select 'helm-source-etags-select "1.5.1") +(defvaralias 'helm-c-show-completion-overlay 'helm-show-completion-overlay) +(make-obsolete-variable 'helm-c-show-completion-overlay 'helm-show-completion-overlay "1.5.1") +(defvaralias 'helm-c-buffer-help-message 'helm-buffer-help-message) +(make-obsolete-variable 'helm-c-buffer-help-message 'helm-buffer-help-message "1.5.1") +(defvaralias 'helm-c-ucs-max-len 'helm-ucs-max-len) +(make-obsolete-variable 'helm-c-ucs-max-len 'helm-ucs-max-len "1.5.1") +(defvaralias 'helm-c-imenu-index-filter 'helm-imenu-index-filter) +(make-obsolete-variable 'helm-c-imenu-index-filter 'helm-imenu-index-filter "1.5.1") +(defvaralias 'helm-c-org-keywords-info-location 'helm-org-keywords-info-location) +(make-obsolete-variable 'helm-c-org-keywords-info-location 'helm-org-keywords-info-location "1.5.1") +(defvaralias 'helm-c-kill-ring-max-lines-number 'helm-kill-ring-max-lines-number) +(make-obsolete-variable 'helm-c-kill-ring-max-lines-number 'helm-kill-ring-max-lines-number "1.5.1") +(defvaralias 'helm-c-source-apt 'helm-source-apt) +(make-obsolete-variable 'helm-c-source-apt 'helm-source-apt "1.5.1") +(defvaralias 'helm-c-bookmark-map 'helm-bookmark-map) +(make-obsolete-variable 'helm-c-bookmark-map 'helm-bookmark-map "1.5.1") +(defvaralias 'helm-c-source-xfonts 'helm-source-xfonts) +(make-obsolete-variable 'helm-c-source-xfonts 'helm-source-xfonts "1.5.1") +(defvaralias 'helm-c-source-kill-ring 'helm-source-kill-ring) +(make-obsolete-variable 'helm-c-source-kill-ring 'helm-source-kill-ring "1.5.1") +(defvaralias 'helm-c-home-url 'helm-home-url) +(make-obsolete-variable 'helm-c-home-url 'helm-home-url "1.5.1") +(defvaralias 'helm-c-etags-cache 'helm-etags-cache) +(make-obsolete-variable 'helm-c-etags-cache 'helm-etags-cache "1.5.1") +(defvaralias 'helm-c-source-latex-math 'helm-source-latex-math) +(make-obsolete-variable 'helm-c-source-latex-math 'helm-source-latex-math "1.5.1") +(defvaralias 'helm-c-source-bookmark-files&dirs 'helm-source-bookmark-files&dirs) +(make-obsolete-variable 'helm-c-source-bookmark-files&dirs 'helm-source-bookmark-files&dirs "1.5.1") +(defvaralias 'helm-c-source-ratpoison-commands 'helm-source-ratpoison-commands) +(make-obsolete-variable 'helm-c-source-ratpoison-commands 'helm-source-ratpoison-commands "1.5.1") +(defvaralias 'helm-c-apt-show-command 'helm-apt-show-command) +(make-obsolete-variable 'helm-c-apt-show-command 'helm-apt-show-command "1.5.1") +(defvaralias 'helm-c-pdfgrep-default-function 'helm-pdfgrep-default-function) +(make-obsolete-variable 'helm-c-pdfgrep-default-function 'helm-pdfgrep-default-function "1.5.1") +(defvaralias 'helm-c-source-register 'helm-source-register) +(make-obsolete-variable 'helm-c-source-register 'helm-source-register "1.5.1") +(defvaralias 'helm-c-boring-buffer-regexp-list 'helm-boring-buffer-regexp-list) +(make-obsolete-variable 'helm-c-boring-buffer-regexp-list 'helm-boring-buffer-regexp-list "1.5.1") +(defvaralias 'helm-c-source-locate 'helm-source-locate) +(make-obsolete-variable 'helm-c-source-locate 'helm-source-locate "1.5.1") +(defvaralias 'helm-c-source-advice 'helm-source-advice) +(make-obsolete-variable 'helm-c-source-advice 'helm-source-advice "1.5.1") +(defvaralias 'helm-c-source-yaoddmuse-emacswiki-edit-or-view 'helm-source-yaoddmuse-emacswiki-edit-or-view) +(defvaralias 'helm-c-ucs-mode-line-string 'helm-ucs-mode-line-string) +(make-obsolete-variable 'helm-c-ucs-mode-line-string 'helm-ucs-mode-line-string "1.5.1") +(defvaralias 'helm-c-xfonts-cache 'helm-xfonts-cache) +(make-obsolete-variable 'helm-c-xfonts-cache 'helm-xfonts-cache "1.5.1") +(defvaralias 'helm-c-source-yahoo-suggest 'helm-source-yahoo-suggest) +(make-obsolete-variable 'helm-c-source-yahoo-suggest 'helm-source-yahoo-suggest "1.5.1") +(defvaralias 'helm-c-rzgrep-cache 'helm-rzgrep-cache) +(make-obsolete-variable 'helm-c-rzgrep-cache 'helm-rzgrep-cache "1.5.1") +(defvaralias 'helm-c-source-org-keywords 'helm-source-org-keywords) +(make-obsolete-variable 'helm-c-source-org-keywords 'helm-source-org-keywords "1.5.1") +(defvaralias 'helm-c-pdfgrep-map 'helm-pdfgrep-map) +(make-obsolete-variable 'helm-c-pdfgrep-map 'helm-pdfgrep-map "1.5.1") +(defvaralias 'helm-c-source-lacarte 'helm-source-lacarte) +(make-obsolete-variable 'helm-c-source-lacarte 'helm-source-lacarte "1.5.1") +(defvaralias 'helm-c-apt-search-command 'helm-apt-search-command) +(make-obsolete-variable 'helm-c-apt-search-command 'helm-apt-search-command "1.5.1") +(defvaralias 'helm-c-default-external-file-browser 'helm-default-external-file-browser) +(make-obsolete-variable 'helm-c-default-external-file-browser 'helm-default-external-file-browser "1.5.1") +(defvaralias 'helm-c-source-evaluation-result 'helm-source-evaluation-result) +(make-obsolete-variable 'helm-c-source-evaluation-result 'helm-source-evaluation-result "1.5.1") +(defvaralias 'helm-c-yahoo-suggest-search-url 'helm-yahoo-suggest-search-url) +(make-obsolete-variable 'helm-c-yahoo-suggest-search-url 'helm-yahoo-suggest-search-url "1.5.1") +(defvaralias 'helm-c-source-occur 'helm-source-occur) +(make-obsolete-variable 'helm-c-source-occur 'helm-source-occur "1.5.1") +(defvaralias 'helm-c-source-calculation-result 'helm-source-calculation-result) +(make-obsolete-variable 'helm-c-source-calculation-result 'helm-source-calculation-result "1.5.1") +(defvaralias 'helm-c-default-zgrep-command 'helm-default-zgrep-command) +(make-obsolete-variable 'helm-c-default-zgrep-command 'helm-default-zgrep-command "1.5.1") +(defvaralias 'helm-c-show-info-in-mode-line-delay 'helm-show-info-in-mode-line-delay) +(make-obsolete-variable 'helm-c-show-info-in-mode-line-delay 'helm-show-info-in-mode-line-delay "1.5.1") +(defvaralias 'helm-c-source-ido-virtual-buffers 'helm-source-ido-virtual-buffers) +(make-obsolete-variable 'helm-c-source-ido-virtual-buffers 'helm-source-ido-virtual-buffers "1.5.1") +(defvaralias 'helm-c-source-top 'helm-source-top) +(make-obsolete-variable 'helm-c-source-top 'helm-source-top "1.5.1") +(defvaralias 'helm-c-source-colors 'helm-source-colors) +(make-obsolete-variable 'helm-c-source-colors 'helm-source-colors "1.5.1") +(defvaralias 'helm-c-read-file-map 'helm-read-file-map) +(make-obsolete-variable 'helm-c-read-file-map 'helm-read-file-map "1.5.1") +(defvaralias 'helm-c-source-file-cache 'helm-source-file-cache) +(make-obsolete-variable 'helm-c-source-file-cache 'helm-source-file-cache "1.5.1") +(defvaralias 'helm-c-google-suggest-default-browser-function 'helm-google-suggest-default-browser-function) +(make-obsolete-variable 'helm-c-google-suggest-default-browser-function 'helm-google-suggest-default-browser-function "1.5.1") +(defvaralias 'helm-c-external-programs-associations 'helm-external-programs-associations) +(make-obsolete-variable 'helm-c-external-programs-associations 'helm-external-programs-associations "1.5.1") +(defvaralias 'helm-c-source-complex-command-history 'helm-source-complex-command-history) +(make-obsolete-variable 'helm-c-source-complex-command-history 'helm-source-complex-command-history "1.5.1") +(defvaralias 'helm-c-cached-imenu-candidates 'helm-cached-imenu-candidates) +(make-obsolete-variable 'helm-c-cached-imenu-candidates 'helm-cached-imenu-candidates "1.5.1") +(defvaralias 'helm-c-external-commands-list 'helm-external-commands-list) +(make-obsolete-variable 'helm-c-external-commands-list 'helm-external-commands-list "1.5.1") +(defvaralias 'helm-c-source-ucs 'helm-source-ucs) +(make-obsolete-variable 'helm-c-source-ucs 'helm-source-ucs "1.5.1") +(defvaralias 'helm-c-adaptative-history-length 'helm-adaptive-history-length) +(make-obsolete-variable 'helm-c-adaptative-history-length 'helm-adaptive-history-length "1.5.1") +(defvaralias 'helm-c-source-customize-face 'helm-source-customize-face) +(make-obsolete-variable 'helm-c-source-customize-face 'helm-source-customize-face "1.5.1") +(defvaralias 'helm-c-source-bookmarks-ssh 'helm-source-bookmarks-ssh) +(make-obsolete-variable 'helm-c-source-bookmarks-ssh 'helm-source-bookmarks-ssh "1.5.1") +(defvaralias 'helm-c-eldoc-in-minibuffer-show-fn 'helm-eldoc-in-minibuffer-show-fn) +(make-obsolete-variable 'helm-c-eldoc-in-minibuffer-show-fn 'helm-eldoc-in-minibuffer-show-fn "1.5.1") +(defvaralias 'helm-c-google-suggest-search-url 'helm-google-suggest-search-url) +(make-obsolete-variable 'helm-c-google-suggest-search-url 'helm-google-suggest-search-url "1.5.1") +(defvaralias 'helm-c-source-bmkext-addressbook 'helm-source-bmkext-addressbook) +(make-obsolete-variable 'helm-c-source-bmkext-addressbook 'helm-source-bmkext-addressbook "1.5.1") +(defvaralias 'helm-c-source-ctags 'helm-source-ctags) +(make-obsolete-variable 'helm-c-source-ctags 'helm-source-ctags "1.5.1") +(defvaralias 'helm-c-apt-installed-packages 'helm-apt-installed-packages) +(make-obsolete-variable 'helm-c-apt-installed-packages 'helm-apt-installed-packages "1.5.1") +(defvaralias 'helm-c-apt-all-packages 'helm-apt-all-packages) +(make-obsolete-variable 'helm-c-apt-all-packages 'helm-apt-all-packages "1.5.1") +(defvaralias 'helm-c-find-files-doc-header 'helm-find-files-doc-header) +(make-obsolete-variable 'helm-c-find-files-doc-header 'helm-find-files-doc-header "1.5.1") +(defvaralias 'helm-c-source-imenu 'helm-source-imenu) +(make-obsolete-variable 'helm-c-source-imenu 'helm-source-imenu "1.5.1") +(defvaralias 'helm-c-grep-default-function 'helm-grep-default-function) +(make-obsolete-variable 'helm-c-grep-default-function 'helm-grep-default-function "1.5.1") +(defvaralias 'helm-c-top-command 'helm-top-command) +(make-obsolete-variable 'helm-c-top-command 'helm-top-command "1.5.1") +(defvaralias 'helm-c-source-bookmark-man 'helm-source-bookmark-man) +(make-obsolete-variable 'helm-c-source-bookmark-man 'helm-source-bookmark-man "1.5.1") +(defvaralias 'helm-c-source-stumpwm-commands 'helm-source-stumpwm-commands) +(make-obsolete-variable 'helm-c-source-stumpwm-commands 'helm-source-stumpwm-commands "1.5.1") +(defvaralias 'helm-c-source-idle-time-timers 'helm-source-idle-time-timers) +(make-obsolete-variable 'helm-c-source-idle-time-timers 'helm-source-idle-time-timers "1.5.1") +(defvaralias 'helm-c-turn-on-show-completion 'helm-turn-on-show-completion) +(make-obsolete-variable 'helm-c-turn-on-show-completion 'helm-turn-on-show-completion "1.5.1") +(defvaralias 'helm-c-esh-help-message 'helm-esh-help-message) +(make-obsolete-variable 'helm-c-esh-help-message 'helm-esh-help-message "1.5.1") +(defvaralias 'helm-c-register-max-offset 'helm-register-max-offset) +(make-obsolete-variable 'helm-c-register-max-offset 'helm-register-max-offset "1.5.1") +(defvaralias 'helm-c-source-bookmark-set 'helm-source-bookmark-set) +(make-obsolete-variable 'helm-c-source-bookmark-set 'helm-source-bookmark-set "1.5.1") +(defvaralias 'helm-c-source-file-name-history 'helm-source-file-name-history) +(make-obsolete-variable 'helm-c-source-file-name-history 'helm-source-file-name-history "1.5.1") +(defvaralias 'helm-c-file-cache-initialized-p 'helm-file-cache-initialized-p) +(make-obsolete-variable 'helm-c-file-cache-initialized-p 'helm-file-cache-initialized-p "1.5.1") +(defvaralias 'helm-c-grep-max-length-history 'helm-grep-max-length-history) +(make-obsolete-variable 'helm-c-grep-max-length-history 'helm-grep-max-length-history "1.5.1") +(defvaralias 'helm-c-source-jabber-contacts 'helm-source-jabber-contacts) +(make-obsolete-variable 'helm-c-source-jabber-contacts 'helm-source-jabber-contacts "1.5.1") +(defvaralias 'helm-c-grep-use-ioccur-style-keys 'helm-grep-use-ioccur-style-keys) +(make-obsolete-variable 'helm-c-grep-use-ioccur-style-keys 'helm-grep-use-ioccur-style-keys "1.5.1") +(defvaralias 'helm-c-ctags-modes 'helm-ctags-modes) +(make-obsolete-variable 'helm-c-ctags-modes 'helm-ctags-modes "1.5.1") +(defvaralias 'helm-c-source-moccur 'helm-source-moccur) +(make-obsolete-variable 'helm-c-source-moccur 'helm-source-moccur "1.5.1") +(defvaralias 'helm-c-locate-command 'helm-locate-command) +(make-obsolete-variable 'helm-c-locate-command 'helm-locate-command "1.5.1") +(defvaralias 'helm-c-etags-tag-file-name 'helm-etags-tag-file-name) +(make-obsolete-variable 'helm-c-etags-tag-file-name 'helm-etags-tag-file-name "1.5.1") +(defvaralias 'helm-c-source-bookmarks-su 'helm-source-bookmarks-su) +(make-obsolete-variable 'helm-c-source-bookmarks-su 'helm-source-bookmarks-su "1.5.1") +(defvaralias 'helm-c-buffer-map 'helm-buffer-map) +(make-obsolete-variable 'helm-c-buffer-map 'helm-buffer-map "1.5.1") +(defvaralias 'helm-c-source-files-in-all-dired 'helm-source-files-in-all-dired) +(make-obsolete-variable 'helm-c-source-files-in-all-dired 'helm-source-files-in-all-dired "1.5.1") +(defvaralias 'helm-c-source-eshell-history 'helm-source-eshell-history) +(make-obsolete-variable 'helm-c-source-eshell-history 'helm-source-eshell-history "1.5.1") +(defvaralias 'helm-c-source-absolute-time-timers 'helm-source-absolute-time-timers) +(make-obsolete-variable 'helm-c-source-absolute-time-timers 'helm-source-absolute-time-timers "1.5.1") +(defvaralias 'helm-c-source-findutils 'helm-source-findutils) +(make-obsolete-variable 'helm-c-source-findutils 'helm-source-findutils "1.5.1") +(defvaralias 'helm-c-ucs-help-message 'helm-ucs-help-message) +(make-obsolete-variable 'helm-c-ucs-help-message 'helm-ucs-help-message "1.5.1") +(defvaralias 'helm-c-source-find-files 'helm-source-find-files) +(make-obsolete-variable 'helm-c-source-find-files 'helm-source-find-files "1.5.1") +(defvaralias 'helm-c-source-recentf 'helm-source-recentf) +(make-obsolete-variable 'helm-c-source-recentf 'helm-source-recentf "1.5.1") +(defvaralias 'helm-c-cache-world 'helm-cache-world) +(make-obsolete-variable 'helm-c-cache-world 'helm-cache-world "1.5.1") +(defvaralias 'helm-c-source-picklist 'helm-source-picklist) +(make-obsolete-variable 'helm-c-source-picklist 'helm-source-picklist "1.5.1") +(defvaralias 'helm-c-source-buffer-not-found 'helm-source-buffer-not-found) +(make-obsolete-variable 'helm-c-source-buffer-not-found 'helm-source-buffer-not-found "1.5.1") +(defvaralias 'helm-c-source-xrandr-change-resolution 'helm-source-xrandr-change-resolution) +(make-obsolete-variable 'helm-c-source-xrandr-change-resolution 'helm-source-xrandr-change-resolution "1.5.1") +(defvaralias 'helm-c-google-suggest-url 'helm-google-suggest-url) +(make-obsolete-variable 'helm-c-google-suggest-url 'helm-google-suggest-url "1.5.1") +(defvaralias 'helm-c-source-semantic 'helm-source-semantic) +(make-obsolete-variable 'helm-c-source-semantic 'helm-source-semantic "1.5.1") +(defvaralias 'helm-c-source-mark-ring 'helm-source-mark-ring) +(make-obsolete-variable 'helm-c-source-mark-ring 'helm-source-mark-ring "1.5.1") +(defvaralias 'helm-c-grep-preferred-ext 'helm-grep-preferred-ext) +(make-obsolete-variable 'helm-c-grep-preferred-ext 'helm-grep-preferred-ext "1.5.1") +(defvaralias 'helm-c-source-bookmarks 'helm-source-bookmarks) +(make-obsolete-variable 'helm-c-source-bookmarks 'helm-source-bookmarks "1.5.1") +(defvaralias 'helm-c-source-elisp-library-scan 'helm-source-elisp-library-scan) +(make-obsolete-variable 'helm-c-source-elisp-library-scan 'helm-source-elisp-library-scan "1.5.1") +(defvaralias 'helm-c-source-info-pages 'helm-source-info-pages) +(make-obsolete-variable 'helm-c-source-info-pages 'helm-source-info-pages "1.5.1") +(defvaralias 'helm-c-source-bookmark-gnus 'helm-source-bookmark-gnus) +(make-obsolete-variable 'helm-c-source-bookmark-gnus 'helm-source-bookmark-gnus "1.5.1") +(defvaralias 'helm-c-source-elscreen 'helm-source-elscreen) +(make-obsolete-variable 'helm-c-source-elscreen 'helm-source-elscreen "1.5.1") +(defvaralias 'helm-c-etags-mtime-alist 'helm-etags-mtime-alist) +(make-obsolete-variable 'helm-c-etags-mtime-alist 'helm-etags-mtime-alist "1.5.1") +(defvaralias 'helm-c-grep-default-recurse-command 'helm-grep-default-recurse-command) +(make-obsolete-variable 'helm-c-grep-default-recurse-command 'helm-grep-default-recurse-command "1.5.1") +(defvaralias 'helm-c-source-google-suggest 'helm-source-google-suggest) +(make-obsolete-variable 'helm-c-source-google-suggest 'helm-source-google-suggest "1.5.1") +(defvaralias 'helm-c-etags-tag-file-search-limit 'helm-etags-tag-file-search-limit) +(make-obsolete-variable 'helm-c-etags-tag-file-search-limit 'helm-etags-tag-file-search-limit "1.5.1") +(defvaralias 'helm-c-source-ff-file-name-history 'helm-source-ff-file-name-history) +(make-obsolete-variable 'helm-c-source-ff-file-name-history 'helm-source-ff-file-name-history "1.5.1") +(defvaralias 'helm-c-source-buffers-list 'helm-source-buffers-list) +(make-obsolete-variable 'helm-c-source-buffers-list 'helm-source-buffers-list "1.5.1") +(defvaralias 'helm-c-cached-imenu-alist 'helm-cached-imenu-alist) +(make-obsolete-variable 'helm-c-cached-imenu-alist 'helm-cached-imenu-alist "1.5.1") +(defvaralias 'helm-c-source-tracker-search 'helm-source-tracker-search) +(make-obsolete-variable 'helm-c-source-tracker-search 'helm-source-tracker-search "1.5.1") +(defvaralias 'helm-c-google-suggest-default-function 'helm-google-suggest-default-function) +(make-obsolete-variable 'helm-c-google-suggest-default-function 'helm-google-suggest-default-function "1.5.1") +(defvaralias 'helm-c-imenu-delimiter 'helm-imenu-delimiter) +(make-obsolete-variable 'helm-c-imenu-delimiter 'helm-imenu-delimiter "1.5.1") +(defvaralias 'helm-c-source-emacs-process 'helm-source-emacs-process) +(make-obsolete-variable 'helm-c-source-emacs-process 'helm-source-emacs-process "1.5.1") +(defvaralias 'helm-c-etags-map 'helm-etags-map) +(make-obsolete-variable 'helm-c-etags-map 'helm-etags-map "1.5.1") +(defvaralias 'helm-c-grep-history 'helm-grep-history) +(make-obsolete-variable 'helm-c-grep-history 'helm-grep-history "1.5.1") +(defvaralias 'helm-c-cached-imenu-tick 'helm-cached-imenu-tick) +(make-obsolete-variable 'helm-c-cached-imenu-tick 'helm-cached-imenu-tick "1.5.1") +(defvaralias 'helm-c-source-esh 'helm-source-esh) +(make-obsolete-variable 'helm-c-source-esh 'helm-source-esh "1.5.1") +(defvaralias 'helm-c-source-global-mark-ring 'helm-source-global-mark-ring) +(make-obsolete-variable 'helm-c-source-global-mark-ring 'helm-source-global-mark-ring "1.5.1") +(defvaralias 'helm-c-man-pages 'helm-man-pages) +(make-obsolete-variable 'helm-c-man-pages 'helm-man-pages "1.5.1") +(defvaralias 'helm-c-adaptative-done 'helm-adaptive-done) +(make-obsolete-variable 'helm-c-adaptative-done 'helm-adaptive-done "1.5.1") +(defvaralias 'helm-c-source-regexp 'helm-source-regexp) +(make-obsolete-variable 'helm-c-source-regexp 'helm-source-regexp "1.5.1") +(defvaralias 'helm-c-boring-file-regexp-list 'helm-boring-file-regexp-list) +(make-obsolete-variable 'helm-c-boring-file-regexp-list 'helm-boring-file-regexp-list "1.5.1") +(defvaralias 'helm-c-show-completion-use-special-display 'helm-show-completion-use-special-display) +(make-obsolete-variable 'helm-c-show-completion-use-special-display 'helm-show-completion-use-special-display "1.5.1") +(defvaralias 'helm-c-apt-query 'helm-apt-query) +(make-obsolete-variable 'helm-c-apt-query 'helm-apt-query "1.5.1") +(defvaralias 'helm-c-pdfgrep-default-read-command 'helm-pdfgrep-default-read-command) +(make-obsolete-variable 'helm-c-pdfgrep-default-read-command 'helm-pdfgrep-default-read-command "1.5.1") +(defvaralias 'helm-c-source-bookmark-images 'helm-source-bookmark-images) +(make-obsolete-variable 'helm-c-source-bookmark-images 'helm-source-bookmark-images "1.5.1") +(defvaralias 'helm-c-source-mac-spotlight 'helm-source-mac-spotlight) +(make-obsolete-variable 'helm-c-source-mac-spotlight 'helm-source-mac-spotlight "1.5.1") +(defvaralias 'helm-c-yahoo-suggest-url 'helm-yahoo-suggest-url) +(make-obsolete-variable 'helm-c-yahoo-suggest-url 'helm-yahoo-suggest-url "1.5.1") +(defvaralias 'helm-c-zgrep-recurse-flag 'helm-zgrep-recurse-flag) +(make-obsolete-variable 'helm-c-zgrep-recurse-flag 'helm-zgrep-recurse-flag "1.5.1") +(defvaralias 'helm-c-source-use-flags 'helm-source-use-flags) +(make-obsolete-variable 'helm-c-source-use-flags 'helm-source-use-flags "1.5.1") +(defvaralias 'helm-c-moccur-map 'helm-moccur-map) +(make-obsolete-variable 'helm-c-moccur-map 'helm-moccur-map "1.5.1") +(defvaralias 'helm-c-adaptative-history-file 'helm-adaptive-history-file) +(make-obsolete-variable 'helm-c-adaptative-history-file 'helm-adaptive-history-file "1.5.1") +(defvaralias 'helm-c-grep-default-directory-fn 'helm-grep-default-directory-fn) +(make-obsolete-variable 'helm-c-grep-default-directory-fn 'helm-grep-default-directory-fn "1.5.1") +(defvaralias 'helm-c-apt-input-history 'helm-apt-input-history) +(make-obsolete-variable 'helm-c-apt-input-history 'helm-apt-input-history "1.5.1") +(defvaralias 'helm-async-be-async 'dired-async-be-async) +(make-obsolete-variable 'helm-async-be-async 'dired-async-be-async "1.5.9") + + +(provide 'helm-aliases) + +;;; helm-aliases.el ends here diff --git a/elpa/helm-20150403.101/helm-apt.el b/elpa/helm-20150403.101/helm-apt.el new file mode 100644 index 00000000..b667c5b3 --- /dev/null +++ b/elpa/helm-20150403.101/helm-apt.el @@ -0,0 +1,292 @@ +;;; helm-apt.el --- Helm interface for Debian/Ubuntu packages (apt-*) -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'helm-external) + +(declare-function term-line-mode "term") +(declare-function term-char-mode "term") +(declare-function term-send-input "term") +(declare-function term-send-eof "term") + + +(defgroup helm-apt nil + "Apt related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-apt-cache-show-function 'helm-apt-cache-show-1 + "Function of one argument used to show apt package. +Default is `helm-apt-cache-show-1' but you can use `apt-utils-show-package-1' +from `apt-utils.el' to have something more enhanced. +If nil default `helm-apt-cache-show-1' will be used." + :type 'function + :group 'helm-apt) + +(defface helm-apt-installed + '((t (:foreground "green"))) + "Face used for apt installed candidates." + :group 'helm-apt) + +(defface helm-apt-deinstalled + '((t (:foreground "DimGray"))) + "Face used for apt deinstalled candidates." + :group 'helm-apt) + + +(defvar helm-apt-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-apt-help) + (define-key map (kbd "M-I") 'helm-apt-show-only-installed) + (define-key map (kbd "M-U") 'helm-apt-show-only-not-installed) + (define-key map (kbd "M-D") 'helm-apt-show-only-deinstalled) + (define-key map (kbd "M-A") 'helm-apt-show-all) + map)) + + +(defvar helm-source-apt + `((name . "APT") + (init . helm-apt-init) + (candidates-in-buffer) + (candidate-transformer . helm-apt-candidate-transformer) + (display-to-real . helm-apt-display-to-real) + (update . helm-apt-refresh) + (keymap . ,helm-apt-map) + (mode-line . helm-apt-mode-line) + (action + ("Show package description" . helm-apt-cache-show) + ("Install package" . helm-apt-install) + ("Reinstall package" . helm-apt-reinstall) + ("Remove package" . helm-apt-uninstall) + ("Purge package" . helm-apt-purge)) + (persistent-action . helm-apt-persistent-action) + (persistent-help . "Show package description"))) + +;;; Internals vars +(defvar helm-apt-search-command "apt-cache search '%s'") +(defvar helm-apt-show-command "apt-cache show '%s'") +(defvar helm-apt-installed-packages nil) +(defvar helm-apt-all-packages nil) +(defvar helm-apt-input-history nil) +(defvar helm-apt-show-only 'all) +(defvar helm-apt-term-buffer nil) +(defvar helm-apt-default-archs nil) + +(defun helm-apt-refresh () + "Refresh installed candidates list." + (setq helm-apt-installed-packages nil) + (setq helm-apt-all-packages nil)) + +(defun helm-apt-persistent-action (candidate) + "Persistent action for APT source." + (helm-apt-cache-show candidate)) + +(defun helm-apt--installed-package-name (name) + (cl-loop for arch in helm-apt-default-archs + thereis (or (assoc-default + name helm-apt-installed-packages) + (assoc-default + (format "%s:%s" name arch) + helm-apt-installed-packages)))) + +(defun helm-apt-candidate-transformer (candidates) + "Show installed CANDIDATES and the ones to deinstall in a different color." + (cl-loop for cand in candidates + for name = (helm-apt-display-to-real cand) + for deinstall = (string= + (helm-apt--installed-package-name name) + "deinstall") + for install = (string= + (helm-apt--installed-package-name name) + "install") + for show = (cond ((and deinstall + (memq helm-apt-show-only '(all deinstalled))) + (propertize cand 'face 'helm-apt-deinstalled)) + ((and install + (memq helm-apt-show-only '(all installed))) + (propertize cand 'face 'helm-apt-installed)) + ((and (eq helm-apt-show-only 'noinstalled) + (not install)) cand) + ((eq helm-apt-show-only 'all) cand)) + when show collect show)) + +(defun helm-apt-show-only-installed () + (interactive) + (when helm-alive-p + (setq helm-apt-show-only 'installed) + (helm-update))) + +(defun helm-apt-show-only-not-installed () + (interactive) + (when helm-alive-p + (setq helm-apt-show-only 'noinstalled) + (helm-update))) + +(defun helm-apt-show-only-deinstalled () + (interactive) + (when helm-alive-p + (setq helm-apt-show-only 'deinstalled) + (helm-update))) + +(defun helm-apt-show-all () + (interactive) + (when helm-alive-p + (setq helm-apt-show-only 'all) + (helm-update))) + +(defun helm-apt-init () + "Initialize list of debian packages." + (let ((query "")) + (unless (and helm-apt-installed-packages + helm-apt-all-packages) + (message "Loading package list...") + (setq helm-apt-installed-packages + (with-temp-buffer + (call-process-shell-command "dpkg --get-selections" + nil (current-buffer)) + (cl-loop for i in (split-string (buffer-string) "\n" t) + for p = (split-string i) + collect (cons (car p) (cadr p))))) + (helm-init-candidates-in-buffer + 'global + (setq helm-apt-all-packages + (with-temp-buffer + (call-process-shell-command + (format helm-apt-search-command query) + nil (current-buffer)) + (buffer-string)))) + (message "Loading package list done") + (sit-for 0.5)))) + +(defun helm-apt-display-to-real (line) + "Return only name of a debian package. +LINE is displayed like: +package name - description." + (car (split-string line " - "))) + +(defvar helm-apt-show-current-package nil) +(define-derived-mode helm-apt-show-mode + special-mode "helm-apt-show" + "Mode to display infos on apt packages.") + +(defun helm-apt-cache-show (package) + "Show information on apt package PACKAGE." + (if (and (functionp helm-apt-cache-show-function) + (not (eq helm-apt-cache-show-function + 'helm-apt-cache-show))) + ;; A function, call it. + (funcall helm-apt-cache-show-function package) + ;; nil or whatever use default. + (helm-apt-cache-show-1 package))) + +(defun helm-apt-cache-show-1 (package) + (let* ((command (format helm-apt-show-command package)) + (buf (get-buffer-create "*helm apt show*"))) + (switch-to-buffer buf) + (unless (string= package helm-apt-show-current-package) + (let ((inhibit-read-only t)) + (erase-buffer) + (save-excursion + (call-process-shell-command + command nil (current-buffer) t)))) + (helm-apt-show-mode) + (set (make-local-variable 'helm-apt-show-current-package) + package))) + +(defun helm-apt-install (_package) + "Run 'apt-get install' shell command on PACKAGE." + (helm-apt-generic-action :action 'install)) + +(defun helm-apt-reinstall (_package) + "Run 'apt-get install --reinstall' shell command on PACKAGE." + (helm-apt-generic-action :action 'reinstall)) + +(defun helm-apt-uninstall (_package) + "Run 'apt-get remove' shell command on PACKAGE." + (helm-apt-generic-action :action 'uninstall)) + +(defun helm-apt-purge (_package) + "Run 'apt-get purge' shell command on PACKAGE." + (helm-apt-generic-action :action 'purge)) + +(cl-defun helm-apt-generic-action (&key action) + "Run 'apt-get ACTION'. +Support install, remove and purge actions." + (if (and helm-apt-term-buffer + (buffer-live-p (get-buffer helm-apt-term-buffer))) + (switch-to-buffer helm-apt-term-buffer) + (ansi-term (getenv "SHELL") "term apt") + (setq helm-apt-term-buffer (buffer-name))) + (term-line-mode) + (let ((command (cl-case action + (install "sudo apt-get install ") + (reinstall "sudo apt-get install --reinstall ") + (uninstall "sudo apt-get remove ") + (purge "sudo apt-get purge ") + (t (error "Unknown action")))) + (beg (point)) + end + (cand-list (mapconcat #'(lambda (x) (format "'%s'" x)) + (helm-marked-candidates) " "))) + (goto-char (point-max)) + (insert (concat command cand-list)) + (setq end (point)) + (if (y-or-n-p (format "%s package(s)" (symbol-name action))) + (progn + (setq helm-external-commands-list nil) + (setq helm-apt-installed-packages nil) + (term-char-mode) (term-send-input)) + (delete-region beg end)))) + +;;;###autoload +(defun helm-apt (arg) + "Preconfigured `helm' : frontend of APT package manager. +With a prefix arg reload cache." + (interactive "P") + (setq helm-apt-show-only 'all) + (unless helm-apt-default-archs + (setq helm-apt-default-archs + (append (split-string + (shell-command-to-string + "dpkg --print-architecture") + "\n" t) + (split-string + (shell-command-to-string + "dpkg --print-foreign-architectures") + "\n" t)))) + (let ((query (read-string "Search Package: " nil 'helm-apt-input-history))) + (when arg (helm-apt-refresh)) + (helm :sources 'helm-source-apt + :prompt "Search Package: " + :input query + :buffer "*helm apt*" + :history 'helm-apt-input-history))) + + +(provide 'helm-apt) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-apt.el ends here diff --git a/elpa/helm-20150403.101/helm-autoloads.el b/elpa/helm-20150403.101/helm-autoloads.el new file mode 100644 index 00000000..33f8ba89 --- /dev/null +++ b/elpa/helm-20150403.101/helm-autoloads.el @@ -0,0 +1,1258 @@ +;;; helm-autoloads.el --- automatically extracted autoloads +;; +;;; Code: + + +;;;### (autoloads (helm-other-buffer helm helm-debug-open-last-log +;;;;;; helm-define-key-with-subkeys helm-multi-key-defun helm-define-multi-key) +;;;;;; "helm" "helm.el" (21792 6081 0 0)) +;;; Generated autoloads from helm.el + +(autoload 'helm-define-multi-key "helm" "\ +In KEYMAP, define key sequence KEY for function list FUNCTIONS. +Each function run sequentially each time the key KEY is pressed. +If DELAY is specified switch back to initial function of FUNCTIONS list +after DELAY seconds. +The functions in FUNCTIONS list are functions with no args. +e.g + (defun foo () + (message \"Run foo\")) + (defun bar () + (message \"Run bar\")) + (defun baz () + (message \"Run baz\")) + +\(helm-define-multi-key global-map \" q\" '(foo bar baz) 2) + +Each time \" q\" is pressed the next function is executed, if you wait +More than 2 seconds, next hit will run again the first function and so on. + +\(fn KEYMAP KEY FUNCTIONS &optional DELAY)" nil nil) + +(autoload 'helm-multi-key-defun "helm" "\ +Define NAME as a multi-key command running FUNS. +After DELAY seconds the FUNS list is reinitialised. +See `helm-define-multi-key'. + +\(fn NAME DOCSTRING FUNS &optional DELAY)" nil t) + +(put 'helm-multi-key-defun 'lisp-indent-function '2) + +(autoload 'helm-define-key-with-subkeys "helm" "\ +Allow defining in MAP a KEY and SUBKEY to COMMAND. + +This allow typing KEY to call COMMAND the first time and +type only SUBKEY on subsequent calls. + +Arg MAP is the keymap to use, SUBKEY is the initial short keybinding to +call COMMAND. + +Arg OTHER-SUBKEYS is an alist specifying other short keybindings +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))) + + +In this example, `C-x v n' will run `git-gutter:next-hunk' +subsequent hits on \"n\" will run this command again +and subsequent hits on \"p\" will run `git-gutter:previous-hunk'. + +Arg MENU is a string to display in minibuffer +to describe SUBKEY and OTHER-SUBKEYS. +Arg EXIT-FN specify a function to run on exit. + +Any other keys pressed run their assigned command defined in MAP +and exit the loop running EXIT-FN if specified. + +NOTE: SUBKEY and OTHER-SUBKEYS bindings support +only char syntax actually (e.g ?n) +so don't use strings, vectors or whatever to define them. + +\(fn MAP KEY SUBKEY COMMAND &optional OTHER-SUBKEYS MENU EXIT-FN)" nil nil) + +(put 'helm-define-key-with-subkeys 'lisp-indent-function '1) + +(autoload 'helm-debug-open-last-log "helm" "\ +Open helm log file of last helm session. +If `helm-last-log-file' is nil, switch to `helm-debug-buffer' . + +\(fn)" t nil) + +(autoload 'helm "helm" "\ +Main function to execute helm sources. + +Keywords supported: +:sources :input :prompt :resume :preselect +:buffer :keymap :default :history :allow-nest + +Extra LOCAL-VARS keywords are supported, see below. + +PLIST is a list like (:key1 val1 :key2 val2 ...) or +\(&optional sources input prompt resume + preselect buffer keymap default history). + +Basic keywords are the following: + +:sources + +A list of sources used for this session. It also accepts a +symbol, interpreted as a variable of a helm source +i.e (a symbol can be passed instead of a list of sources). +It also accepts an alist representing a helm source, which is +detected by (assq 'name ANY-SOURCES). +NOTE: In this case the source is embedded in the helm command and +have no symbol name, so it is not reachable from outside. +It will be referenced in `helm-sources' as a whole alist. + +:input + +Temporary value of `helm-pattern', ie. initial input of minibuffer. + +:prompt + +Prompt other than \"pattern: \". + +:resume + +If t, Resurrect previously instance of `helm'. Skip the initialization. +If 'noresume, this instance of `helm' cannot be resumed. + +:preselect + +Initially selected candidate. Specified by exact candidate or a regexp. + +:buffer + +`helm-buffer' instead of *helm*. + +:keymap + +`helm-map' for current `helm' session. + +:default + +A default argument that will be inserted in minibuffer with \\\\[next-history-element]. +When nil or not present `thing-at-point' will be used instead. +If `helm-maybe-use-default-as-input' is non--nil display will be +updated using :default arg as input unless :input is specified, +which in this case will take precedence on :default +This is a string or a list, in this case the car of the list will +be used as initial default input, but you will be able to cycle in this +list with \\\\[next-history-element]. + +:history + +By default all minibuffer input is pushed to `minibuffer-history', +if an argument HISTORY is provided, input will be pushed to HISTORY. +History element should be a symbol. + +:allow-nest + +Allow running this helm command within a running helm session. + +Of course, conventional arguments are supported, the two are same. + +\(helm :sources sources :input input :prompt prompt :resume resume + :preselect preselect :buffer buffer :keymap keymap :default default + :history history) + +and + +\(helm sources input prompt resume preselect buffer keymap default history) + +are the same. + +However the use of non keyword args is deprecated and should not be used. + +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 + :buffer \"*buffers*\" :candidate-number-limit 10) + +means starting helm session with `helm-source-buffers' +source in *buffers* buffer and set variable `helm-candidate-number-limit' +to 10 as session local variable. + +\(fn &key SOURCES INPUT PROMPT RESUME PRESELECT BUFFER KEYMAP DEFAULT HISTORY ALLOW-NEST OTHER-LOCAL-VARS)" nil nil) + +(autoload 'helm-other-buffer "helm" "\ +Simplified interface of `helm' with other `helm-buffer'. +Call `helm' with only ANY-SOURCES and ANY-BUFFER as args. + +\(fn ANY-SOURCES ANY-BUFFER)" nil nil) + +;;;*** + +;;;### (autoloads (helm-reset-adaptive-history) "helm-adaptive" "helm-adaptive.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-adaptive.el + +(autoload 'helm-reset-adaptive-history "helm-adaptive" "\ +Delete all `helm-adaptive-history' and his file. +Useful when you have a old or corrupted `helm-adaptive-history-file'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-apt) "helm-apt" "helm-apt.el" (21792 6081 +;;;;;; 0 0)) +;;; Generated autoloads from helm-apt.el + +(autoload 'helm-apt "helm-apt" "\ +Preconfigured `helm' : frontend of APT package manager. +With a prefix arg reload cache. + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-filtered-bookmarks helm-pp-bookmarks helm-bookmarks) +;;;;;; "helm-bookmark" "helm-bookmark.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-bookmark.el + +(autoload 'helm-bookmarks "helm-bookmark" "\ +Preconfigured `helm' for bookmarks. + +\(fn)" t nil) + +(autoload 'helm-pp-bookmarks "helm-bookmark" "\ +Preconfigured `helm' for bookmarks (pretty-printed). + +\(fn)" t nil) + +(autoload 'helm-filtered-bookmarks "helm-bookmark" "\ +Preconfigured helm for bookmarks (filtered by category). +Optional source `helm-source-bookmark-addressbook' is loaded +only if external library addressbook-bookmark.el is available. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-buffers-list) "helm-buffers" "helm-buffers.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-buffers.el + +(autoload 'helm-buffers-list "helm-buffers" "\ +Preconfigured `helm' to list buffers. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-colors) "helm-color" "helm-color.el" (21792 +;;;;;; 6081 0 0)) +;;; Generated autoloads from helm-color.el + +(autoload 'helm-colors "helm-color" "\ +Preconfigured `helm' for color. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-M-x) "helm-command" "helm-command.el" (21792 +;;;;;; 6081 0 0)) +;;; Generated autoloads from helm-command.el + +(autoload 'helm-M-x "helm-command" "\ +Preconfigured `helm' for Emacs commands. +It is `helm' replacement of regular `M-x' `execute-extended-command'. + +Unlike regular `M-x' emacs vanilla `execute-extended-command' command, +the prefix args if needed, are passed AFTER starting `helm-M-x'. + +You can get help on each command by persistent action. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-configuration) "helm-config" "helm-config.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-config.el + +(autoload 'helm-configuration "helm-config" "\ +Customize `helm'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-dabbrev) "helm-dabbrev" "helm-dabbrev.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-dabbrev.el + +(autoload 'helm-dabbrev "helm-dabbrev" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-complex-command-history helm-timers helm-locate-library +;;;;;; helm-manage-advice helm-apropos helm-lisp-completion-or-file-name-at-point +;;;;;; helm-lisp-indent helm-complete-file-name-at-point helm-lisp-completion-at-point) +;;;;;; "helm-elisp" "helm-elisp.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-elisp.el + +(autoload 'helm-lisp-completion-at-point "helm-elisp" "\ +Helm lisp symbol completion at point. + +\(fn)" t nil) + +(autoload 'helm-complete-file-name-at-point "helm-elisp" "\ +Complete file name at point. + +\(fn &optional FORCE)" t nil) + +(autoload 'helm-lisp-indent "helm-elisp" "\ + + +\(fn)" t nil) + +(autoload 'helm-lisp-completion-or-file-name-at-point "helm-elisp" "\ +Complete lisp symbol or filename at point. +Filename completion happen if string start after or between a double quote. + +\(fn)" t nil) + +(autoload 'helm-apropos "helm-elisp" "\ +Preconfigured helm to describe commands, functions, variables and faces. + +\(fn)" t nil) + +(autoload 'helm-manage-advice "helm-elisp" "\ +Preconfigured `helm' to disable/enable function advices. + +\(fn)" t nil) + +(autoload 'helm-locate-library "helm-elisp" "\ + + +\(fn)" t nil) + +(autoload 'helm-timers "helm-elisp" "\ +Preconfigured `helm' for timers. + +\(fn)" t nil) + +(autoload 'helm-complex-command-history "helm-elisp" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-list-elisp-packages) "helm-elisp-package" +;;;;;; "helm-elisp-package.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-elisp-package.el + +(autoload 'helm-list-elisp-packages "helm-elisp-package" "\ + + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-elscreen) "helm-elscreen" "helm-elscreen.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-elscreen.el + +(autoload 'helm-elscreen "helm-elscreen" "\ +Preconfigured helm to list elscreen. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-eshell-history helm-esh-pcomplete) "helm-eshell" +;;;;;; "helm-eshell.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-eshell.el + +(autoload 'helm-esh-pcomplete "helm-eshell" "\ +Preconfigured helm to provide helm completion in eshell. + +\(fn)" t nil) + +(autoload 'helm-eshell-history "helm-eshell" "\ +Preconfigured helm for eshell history. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-calcul-expression helm-eval-expression-with-eldoc +;;;;;; helm-eval-expression) "helm-eval" "helm-eval.el" (21792 6081 +;;;;;; 0 0)) +;;; Generated autoloads from helm-eval.el + +(autoload 'helm-eval-expression "helm-eval" "\ +Preconfigured helm for `helm-source-evaluation-result'. + +\(fn ARG)" t nil) + +(autoload 'helm-eval-expression-with-eldoc "helm-eval" "\ +Preconfigured helm for `helm-source-evaluation-result' with `eldoc' support. + +\(fn)" t nil) + +(autoload 'helm-calcul-expression "helm-eval" "\ +Preconfigured helm for `helm-source-calculation-result'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-run-external-command) "helm-external" "helm-external.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-external.el + +(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'. + +\(fn PROGRAM)" t nil) + +;;;*** + +;;;### (autoloads (helm-recentf helm-multi-files helm-for-files helm-find-files +;;;;;; helm-find helm-browse-project) "helm-files" "helm-files.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-files.el + +(autoload 'helm-browse-project "helm-files" "\ +Browse files and see status of project with its vcs. +Only HG and GIT are supported for now. +Fall back to `helm-find-files' or `helm-browse-project-find-files' +if current directory is not under control of one of those vcs. +With a prefix ARG browse files recursively, with two prefix ARG +rebuild the cache. +If the current directory is found in the cache, start +`helm-browse-project-find-files' even with no prefix ARG. +NOTE: The prefix ARG have no effect on the VCS controlled directories. + +Need dependencies for VCS: + +and +. + +\(fn ARG)" t nil) + +(autoload 'helm-find "helm-files" "\ +Preconfigured `helm' for the find shell command. + +\(fn ARG)" t nil) + +(autoload 'helm-find-files "helm-files" "\ +Preconfigured `helm' for helm implementation of `find-file'. +Called with a prefix arg show history if some. +Don't call it from programs, use `helm-find-files-1' instead. +This is the starting point for nearly all actions you can do on files. + +\(fn ARG)" t nil) + +(autoload 'helm-for-files "helm-files" "\ +Preconfigured `helm' for opening files. +Run all sources defined in `helm-for-files-preferred-list'. + +\(fn)" t nil) + +(autoload 'helm-multi-files "helm-files" "\ +Same as `helm-for-files' but allow toggling from locate to others sources. + +\(fn)" t nil) + +(autoload 'helm-recentf "helm-files" "\ +Preconfigured `helm' for `recentf'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-ucs helm-select-xfont) "helm-font" "helm-font.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-font.el + +(autoload 'helm-select-xfont "helm-font" "\ +Preconfigured `helm' to select Xfont. + +\(fn)" t nil) + +(autoload 'helm-ucs "helm-font" "\ +Preconfigured helm for `ucs-names' math symbols. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-do-pdfgrep helm-do-zgrep helm-do-grep helm-grep-mode-jump-other-window +;;;;;; helm-grep-mode-jump-other-window-backward helm-grep-mode-jump-other-window-forward +;;;;;; helm-grep-mode-jump helm-gm-precedent-file helm-gm-next-file +;;;;;; helm-grep-mode helm-grep-run-save-buffer helm-goto-next-file +;;;;;; helm-goto-precedent-file) "helm-grep" "helm-grep.el" (21792 +;;;;;; 6081 0 0)) +;;; Generated autoloads from helm-grep.el + +(autoload 'helm-goto-precedent-file "helm-grep" "\ +Go to precedent file in helm grep/etags buffers. + +\(fn)" t nil) + +(autoload 'helm-goto-next-file "helm-grep" "\ +Go to precedent file in helm grep/etags buffers. + +\(fn)" t nil) + +(autoload 'helm-grep-run-save-buffer "helm-grep" "\ +Run grep save results action from `helm-do-grep-1'. + +\(fn)" t nil) + +(autoload 'helm-grep-mode "helm-grep" "\ +Major mode to provide actions in helm grep saved buffer. + +Special commands: +\\{helm-grep-mode-map} + +\(fn)" t nil) + +(autoload 'helm-gm-next-file "helm-grep" "\ + + +\(fn)" t nil) + +(autoload 'helm-gm-precedent-file "helm-grep" "\ + + +\(fn)" t nil) + +(autoload 'helm-grep-mode-jump "helm-grep" "\ + + +\(fn)" t nil) + +(autoload 'helm-grep-mode-jump-other-window-forward "helm-grep" "\ + + +\(fn)" t nil) + +(autoload 'helm-grep-mode-jump-other-window-backward "helm-grep" "\ + + +\(fn)" t nil) + +(autoload 'helm-grep-mode-jump-other-window "helm-grep" "\ + + +\(fn)" t nil) + +(autoload 'helm-do-grep "helm-grep" "\ +Preconfigured helm for grep. +Contrarily to Emacs `grep', no default directory is given, but +the full path of candidates in ONLY. +That allow to grep different files not only in `default-directory' but anywhere +by marking them (C-). If one or more directory is selected +grep will search in all files of these directories. +You can also use wildcard in the base name of candidate. +If a prefix arg is given use the -r option of grep (recurse). +The prefix arg can be passed before or after start file selection. +See also `helm-do-grep-1'. + +\(fn)" t nil) + +(autoload 'helm-do-zgrep "helm-grep" "\ +Preconfigured helm for zgrep. + +\(fn)" t nil) + +(autoload 'helm-do-pdfgrep "helm-grep" "\ +Preconfigured helm for pdfgrep. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-describe-helm-attribute helm-kmacro-help +;;;;;; helm-semantic-help helm-color-help helm-imenu-help helm-M-x-help +;;;;;; helm-el-package-help helm-apt-help helm-top-help helm-moccur-help +;;;;;; helm-buffers-ido-virtual-help helm-esh-help helm-bookmark-help +;;;;;; helm-ucs-help helm-etags-help helm-pdfgrep-help helm-grep-help +;;;;;; helm-generic-file-help helm-read-file-name-help helm-ff-help +;;;;;; helm-buffer-help helm-help helm-documentation) "helm-help" +;;;;;; "helm-help.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-help.el + +(autoload 'helm-documentation "helm-help" "\ +Helm documentation. +With a prefix arg refresh the documentation. + +Find here the documentation of all sources actually documented. + +\(fn ARG)" t nil) + +(autoload 'helm-help "helm-help" "\ +Help of `helm'. + +\(fn)" t nil) + +(autoload 'helm-buffer-help "helm-help" "\ +Help command for helm buffers. + +\(fn)" t nil) + +(autoload 'helm-ff-help "helm-help" "\ +Help command for `helm-find-files'. + +\(fn)" t nil) + +(autoload 'helm-read-file-name-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-generic-file-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-grep-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-pdfgrep-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-etags-help "helm-help" "\ +The help function for etags. + +\(fn)" t nil) + +(autoload 'helm-ucs-help "helm-help" "\ +Help command for `helm-ucs'. + +\(fn)" t nil) + +(autoload 'helm-bookmark-help "helm-help" "\ +Help command for bookmarks. + +\(fn)" t nil) + +(autoload 'helm-esh-help "helm-help" "\ +Help command for `helm-find-files-eshell-command-on-file'. + +\(fn)" t nil) + +(autoload 'helm-buffers-ido-virtual-help "helm-help" "\ +Help command for ido virtual buffers. + +\(fn)" t nil) + +(autoload 'helm-moccur-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-top-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-apt-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-el-package-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-M-x-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-imenu-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-color-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-semantic-help "helm-help" "\ + + +\(fn)" t nil) + +(autoload 'helm-kmacro-help "helm-help" "\ + + +\(fn)" t nil) + +(defvar helm-buffer-mode-line-string '("Buffer(s)" "\\\\[helm-buffer-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct" "String displayed in mode-line in `helm-source-buffers-list'")) + +(defvar helm-color-mode-line-string '("Colors" "\\\\[helm-color-help]:Help/\\[helm-color-run-insert-name]:Insert name/\\[helm-color-run-insert-rgb]:Insert RGB/with shift: Kill")) + +(defvar helm-buffers-ido-virtual-mode-line-string '("Killed Buffer(s)" "\\\\[helm-buffers-ido-virtual-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct" "String displayed in mode-line in `helm-source-buffers-list'")) + +(defvar helm-ff-mode-line-string "\\\\[helm-ff-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct" "\ +String displayed in mode-line in `helm-source-find-files'") + +(defvar helm-read-file-name-mode-line-string "\\\\[helm-read-file-name-help]:Help C/\\[helm-cr-empty-string]:Empty \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct" "\ +String displayed in mode-line in `helm-source-find-files'.") + +(defvar helm-generic-file-mode-line-string "\\\\[helm-generic-file-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend" "\ +String displayed in mode-line in Locate.") + +(defvar helm-grep-mode-line-string "\\\\[helm-grep-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend" "\ +String displayed in mode-line in `helm-do-grep'.") + +(defvar helm-pdfgrep-mode-line-string "\\\\[helm-pdfgrep-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend" "\ +String displayed in mode-line in `helm-do-pdfgrep'.") + +(defvar helm-etags-mode-line-string "\\\\[helm-etags-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct" "\ +String displayed in mode-line in `helm-etags-select'.") + +(defvar helm-ucs-mode-line-string "\\\\[helm-ucs-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct" "\ +String displayed in mode-line in `helm-ucs'.") + +(defvar helm-bookmark-mode-line-string '("Bookmark(s)" "\\\\[helm-bookmark-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct") "\ +String displayed in mode-line in `helm-source-buffers-list'") + +(defvar helm-occur-mode-line "\\\\[helm-help]:Help \\\\[helm-occur-run-query-replace-regexp]:Query replace regexp \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-moccur-mode-line "\\\\[helm-moccur-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-comp-read-mode-line "\\C/\\[helm-cr-empty-string]:Empty \\\\[helm-help]:Help \\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct") + +(defvar helm-top-mode-line "\\\\[helm-top-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-apt-mode-line "\\\\[helm-apt-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-el-package-mode-line "\\\\[helm-el-package-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-M-x-mode-line "\\\\[helm-M-x-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-imenu-mode-line "\\\\[helm-imenu-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(defvar helm-semantic-mode-line "\\\\[helm-semantic-help]:Help \\\\[helm-select-action]:Act \\[helm-maybe-exit-minibuffer]/f1/f2/f-n:NthAct \\[helm-toggle-suspend-update]:Tog.suspend") + +(autoload 'helm-describe-helm-attribute "helm-help" "\ +Display the full documentation of HELM-ATTRIBUTE. +HELM-ATTRIBUTE should be a symbol. + +\(fn HELM-ATTRIBUTE)" t nil) + +;;;*** + +;;;### (autoloads (helm-imenu) "helm-imenu" "helm-imenu.el" (21792 +;;;;;; 6081 0 0)) +;;; Generated autoloads from helm-imenu.el + +(autoload 'helm-imenu "helm-imenu" "\ +Preconfigured `helm' for `imenu'. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-info-at-point) "helm-info" "helm-info.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-info.el + +(autoload 'helm-info-at-point "helm-info" "\ +Preconfigured `helm' for searching info at point. +With a prefix-arg insert symbol at point. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-locate helm-locate-read-file-name) "helm-locate" +;;;;;; "helm-locate.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-locate.el + +(autoload 'helm-locate-read-file-name "helm-locate" "\ + + +\(fn PROMPT)" nil nil) + +(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'. + +You can specify a local database with prefix argument ARG. +With two prefix arg, refresh the current local db or create it +if it doesn't exists. +Many databases can be used: navigate and mark them. +See also `helm-locate-with-db'. + +To create a user specific db, use +\"updatedb -l 0 -o db_path -U directory\". +Where db_path is a filename matched by +`helm-locate-db-file-regexp'. + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-man-woman) "helm-man" "helm-man.el" (21792 +;;;;;; 6081 0 0)) +;;; Generated autoloads from helm-man.el + +(autoload 'helm-man-woman "helm-man" "\ +Preconfigured `helm' for Man and Woman pages. +With a prefix arg reinitialize the cache. + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-comint-input-ring helm-minibuffer-history +;;;;;; helm-mini helm-stumpwm-commands helm-ratpoison-commands helm-insert-latex-math +;;;;;; helm-world-time helm-browse-menubar) "helm-misc" "helm-misc.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-misc.el + +(autoload 'helm-browse-menubar "helm-misc" "\ +Helm interface to the menubar using lacarte.el. + +\(fn)" t nil) + +(autoload 'helm-world-time "helm-misc" "\ +Preconfigured `helm' to show world time. + +\(fn)" t nil) + +(autoload 'helm-insert-latex-math "helm-misc" "\ +Preconfigured helm for latex math symbols completion. + +\(fn)" t nil) + +(autoload 'helm-ratpoison-commands "helm-misc" "\ +Preconfigured `helm' to execute ratpoison commands. + +\(fn)" t nil) + +(autoload 'helm-stumpwm-commands "helm-misc" "\ + + +\(fn)" t nil) + +(autoload 'helm-mini "helm-misc" "\ +Preconfigured `helm' lightweight version (buffer -> recentf). + +\(fn)" t nil) + +(autoload 'helm-minibuffer-history "helm-misc" "\ +Preconfigured `helm' for `minibuffer-history'. + +\(fn)" t nil) + +(autoload 'helm-comint-input-ring "helm-misc" "\ +Predefined `helm' that provide completion of `comint' history. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-mode helm-comp-read) "helm-mode" "helm-mode.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-mode.el + +(autoload 'helm-comp-read "helm-mode" "\ +Read a string in the minibuffer, with helm completion. + +It is helm `completing-read' equivalent. + +- PROMPT is the prompt name to use. + +- COLLECTION can be a list, vector, obarray or hash-table. + It can be also a function that receives three arguments: + the values string, predicate and t. See `all-completions' for more details. + +Keys description: + +- TEST: A predicate called with one arg i.e candidate. + +- INITIAL-INPUT: Same as input arg in `helm'. + +- PRESELECT: See preselect arg of `helm'. + +- DEFAULT: This option is used only for compatibility with regular + Emacs `completing-read' (Same as DEFAULT arg of `completing-read'). + +- BUFFER: Name of helm-buffer. + +- MUST-MATCH: Candidate selected must be one of COLLECTION. + +- REVERSE-HISTORY: When non--nil display history source after current + source completion. + +- 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. + +- INPUT-HISTORY: A symbol. the minibuffer input history will be + stored there, if nil or not provided, `minibuffer-history' + will be used instead. + +- 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. + +- MODE-LINE: A string or list to display in mode line. + Default is `helm-comp-read-mode-line'. + +- KEYMAP: A keymap to use in this `helm-comp-read'. + (the keymap will be shared with history source) + +- NAME: The name related to this local source. + +- EXEC-WHEN-ONLY-ONE: Bound `helm-execute-action-at-once-if-one' + to non--nil. (possibles values are t or nil). + +- VOLATILE: Use volatile attribute (enabled by default). + +- SORT: A predicate to give to `sort' e.g `string-lessp'. + +- FC-TRANSFORMER: A `filtered-candidate-transformer' function. + +- 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. + +- NOMARK: When non--nil don't allow marking candidates. + +- ALISTP: (default is non--nil) See `helm-comp-read-get-candidates'. + +- CANDIDATES-IN-BUFFER: when non--nil use a source build with + `helm-candidates-in-buffer' which is much faster. + Argument VOLATILE have no effect when CANDIDATES-IN-BUFFER is non--nil. + +Any prefix args passed during `helm-comp-read' invocation will be recorded +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's mean 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) (keymap helm-comp-read-map) (name \"Helm Completions\") CANDIDATES-IN-BUFFER EXEC-WHEN-ONLY-ONE QUIT-WHEN-NO-CAND (volatile t) SORT (fc-transformer (quote helm-cr-default-transformer)) HIST-FC-TRANSFORMER MARKED-CANDIDATES NOMARK (alistp t))" nil nil) + +(defvar helm-mode nil "\ +Non-nil if Helm mode is enabled. +See the command `helm-mode' 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-mode'.") + +(custom-autoload 'helm-mode "helm-mode" nil) + +(autoload 'helm-mode "helm-mode" "\ +Toggle generic helm completion. + +All functions in Emacs that use `completing-read' +or `read-file-name' and friends will use helm interface +when this mode is turned on. +However you can modify this behavior for functions of your choice +with `helm-completing-read-handlers-alist'. + +Called with a positive arg, turn on unconditionally, with a +negative arg turn off. +You can turn it on with `helm-mode'. + +Some crap emacs functions may not be supported, +e.g `ffap-alternate-file' and maybe others +You can add such functions to `helm-completing-read-handlers-alist' +with a nil value. + +Note: This mode is incompatible with Emacs23. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-wikipedia-suggest helm-yahoo-suggest helm-google-suggest +;;;;;; helm-surfraw) "helm-net" "helm-net.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-net.el + +(autoload 'helm-surfraw "helm-net" "\ +Preconfigured `helm' to search PATTERN with search ENGINE. + +\(fn PATTERN ENGINE)" t nil) + +(autoload 'helm-google-suggest "helm-net" "\ +Preconfigured `helm' for google search with google suggest. + +\(fn)" t nil) + +(autoload 'helm-yahoo-suggest "helm-net" "\ +Preconfigured `helm' for Yahoo searching with Yahoo suggest. + +\(fn)" t nil) + +(autoload 'helm-wikipedia-suggest "helm-net" "\ +Preconfigured `helm' for Wikipedia lookup with Wikipedia suggest. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-org-capture-templates helm-org-in-buffer-headings +;;;;;; helm-org-agenda-files-headings) "helm-org" "helm-org.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-org.el + +(autoload 'helm-org-agenda-files-headings "helm-org" "\ + + +\(fn)" t nil) + +(autoload 'helm-org-in-buffer-headings "helm-org" "\ + + +\(fn)" t nil) + +(autoload 'helm-org-capture-templates "helm-org" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-multi-occur-from-isearch helm-multi-occur +;;;;;; helm-occur-from-isearch helm-occur helm-regexp helm-moccur-mode +;;;;;; helm-moccur-run-save-buffer) "helm-regexp" "helm-regexp.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-regexp.el + +(autoload 'helm-moccur-run-save-buffer "helm-regexp" "\ +Run grep save results action from `helm-do-grep-1'. + +\(fn)" t nil) + +(autoload 'helm-moccur-mode "helm-regexp" "\ +Major mode to provide actions in helm moccur saved buffer. + +Special commands: +\\{helm-moccur-mode-map} + +\(fn)" t nil) + +(autoload 'helm-regexp "helm-regexp" "\ +Preconfigured helm to build regexps. +`query-replace-regexp' can be run from there against found regexp. + +\(fn)" t nil) + +(autoload 'helm-occur "helm-regexp" "\ +Preconfigured helm for Occur. + +\(fn)" t nil) + +(autoload 'helm-occur-from-isearch "helm-regexp" "\ +Invoke `helm-occur' from isearch. + +\(fn)" t nil) + +(autoload 'helm-multi-occur "helm-regexp" "\ +Preconfigured helm for multi occur. + + BUFFERS is a list of buffers to search through. +With a prefix arg, reverse the behavior of +`helm-moccur-always-search-in-current'. +The prefix arg can be set before calling `helm-multi-occur' +or during the buffer selection. + +\(fn BUFFERS)" t nil) + +(autoload 'helm-multi-occur-from-isearch "helm-regexp" "\ +Invoke `helm-multi-occur' from isearch. + +With a prefix arg, reverse the behavior of +`helm-moccur-always-search-in-current'. +The prefix arg can be set before calling +`helm-multi-occur-from-isearch' or during the buffer selection. + +\(fn &optional ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-execute-kmacro helm-show-kill-ring helm-register +;;;;;; helm-all-mark-rings helm-global-mark-ring helm-mark-ring) +;;;;;; "helm-ring" "helm-ring.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-ring.el + +(autoload 'helm-mark-ring "helm-ring" "\ +Preconfigured `helm' for `helm-source-mark-ring'. + +\(fn)" t nil) + +(autoload 'helm-global-mark-ring "helm-ring" "\ +Preconfigured `helm' for `helm-source-global-mark-ring'. + +\(fn)" t nil) + +(autoload 'helm-all-mark-rings "helm-ring" "\ +Preconfigured `helm' for `helm-source-global-mark-ring' and `helm-source-mark-ring'. + +\(fn)" t nil) + +(autoload 'helm-register "helm-ring" "\ +Preconfigured `helm' for Emacs registers. + +\(fn)" t nil) + +(autoload 'helm-show-kill-ring "helm-ring" "\ +Preconfigured `helm' for `kill-ring'. +It is drop-in replacement of `yank-pop'. + +First call open the kill-ring browser, next calls move to next line. + +\(fn)" t nil) + +(autoload 'helm-execute-kmacro "helm-ring" "\ +Keyboard macros with helm interface. +Define your macros with `f3' and `f4'. +See (info \"(emacs) Keyboard Macros\") for detailed infos. +This command is useful when used with persistent action. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-semantic-or-imenu helm-semantic) "helm-semantic" +;;;;;; "helm-semantic.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-semantic.el + +(autoload 'helm-semantic "helm-semantic" "\ +Preconfigured `helm' for `semantic'. +If ARG is supplied, pre-select symbol at point instead of current + +\(fn ARG)" t nil) + +(autoload 'helm-semantic-or-imenu "helm-semantic" "\ +Run `helm' with `semantic' or `imenu'. +If ARG is supplied, pre-select symbol at point instead of current +semantic tag in scope. + +If `semantic-mode' is active in the current buffer, then use +semantic for generating tags, otherwise fall back to `imenu'. +Fill in the symbol at point by default. + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-xrandr-set helm-list-emacs-process helm-top) +;;;;;; "helm-sys" "helm-sys.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-sys.el + +(autoload 'helm-top "helm-sys" "\ +Preconfigured `helm' for top command. + +\(fn)" t nil) + +(autoload 'helm-list-emacs-process "helm-sys" "\ +Preconfigured `helm' for emacs process. + +\(fn)" t nil) + +(autoload 'helm-xrandr-set "helm-sys" "\ + + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads (helm-etags-select) "helm-tags" "helm-tags.el" +;;;;;; (21792 6081 0 0)) +;;; Generated autoloads from helm-tags.el + +(autoload 'helm-etags-select "helm-tags" "\ +Preconfigured helm for etags. +If called with a prefix argument or if any of the tag files have +been modified, reinitialize cache. + +This function aggregates three sources of tag files: + + 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. + +\(fn ARG)" t nil) + +;;;*** + +;;;### (autoloads (helm-yank-text-at-point helm-w32-shell-execute-open-file +;;;;;; helm-quit-and-find-file helm-display-all-sources helm-show-all-in-this-source-only) +;;;;;; "helm-utils" "helm-utils.el" (21792 6081 0 0)) +;;; Generated autoloads from helm-utils.el + +(autoload 'helm-show-all-in-this-source-only "helm-utils" "\ +Show only current source of this helm session with all its candidates. +With a numeric prefix arg show only the ARG number of candidates. + +\(fn ARG)" t nil) + +(autoload 'helm-display-all-sources "helm-utils" "\ +Display all sources previously hidden by `helm-set-source-filter'. + +\(fn)" t nil) + +(autoload 'helm-quit-and-find-file "helm-utils" "\ +Drop into `helm-find-files' from `helm'. +If current selection is a buffer or a file, `helm-find-files' +from its directory. + +\(fn)" t nil) + +(autoload 'helm-w32-shell-execute-open-file "helm-utils" "\ + + +\(fn FILE)" t nil) + +(autoload 'helm-yank-text-at-point "helm-utils" "\ +Yank text at point in `helm-current-buffer' into minibuffer. +If `helm-yank-symbol-first' is non--nil the first yank +grabs the entire symbol. + +\(fn)" t nil) + +;;;*** + +;;;### (autoloads nil nil ("helm-aliases.el" "helm-match-plugin.el" +;;;;;; "helm-pkg.el" "helm-plugin.el" "helm-source.el") (21792 6081 +;;;;;; 828452 0)) + +;;;*** + +(provide 'helm-autoloads) +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; coding: utf-8 +;; End: +;;; helm-autoloads.el ends here diff --git a/elpa/helm-20150403.101/helm-bookmark.el b/elpa/helm-20150403.101/helm-bookmark.el new file mode 100644 index 00000000..50fca7e7 --- /dev/null +++ b/elpa/helm-20150403.101/helm-bookmark.el @@ -0,0 +1,764 @@ +;;; helm-bookmark.el --- Helm for Emacs regular Bookmarks. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'bookmark) +(require 'helm) +(require 'helm-utils) +(require 'helm-info) +(require 'helm-adaptive) +(require 'helm-net) + +(declare-function addressbook-bookmark-edit "ext:addressbook-bookmark.el" (bookmark)) +(declare-function message-buffers "message.el") +(declare-function addressbook-set-mail-buffer-1 "ext:addressbook-bookmark.el" + (&optional bookmark-name append cc)) + + +(defgroup helm-bookmark nil + "Predefined configurations for `helm.el'." + :group 'helm) + +(defcustom helm-bookmark-show-location nil + "Show location of bookmark on display." + :group 'helm-bookmark + :type 'boolean) + + +(defface helm-bookmark-info + '((t (:foreground "green"))) + "Face used for W3m Emacs bookmarks (not w3m bookmarks)." + :group 'helm-bookmark) + +(defface helm-bookmark-w3m + '((t (:foreground "yellow"))) + "Face used for W3m Emacs bookmarks (not w3m bookmarks)." + :group 'helm-bookmark) + +(defface helm-bookmark-gnus + '((t (:foreground "magenta"))) + "Face used for Gnus bookmarks." + :group 'helm-bookmark) + +(defface helm-bookmark-man + '((t (:foreground "Orange4"))) + "Face used for Woman/man bookmarks." + :group 'helm-bookmark) + +(defface helm-bookmark-file + '((t (:foreground "Deepskyblue2"))) + "Face used for file bookmarks." + :group 'helm-bookmark) + +(defface helm-bookmark-directory + '((t (:inherit helm-ff-directory))) + "Face used for file bookmarks." + :group 'helm-bookmark) + +(defface helm-bookmark-addressbook + '((t (:foreground "tomato"))) + "Face used for addressbook bookmarks." + :group 'helm-bookmark) + + +(defvar helm-bookmark-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c o") 'helm-bookmark-run-jump-other-window) + (define-key map (kbd "C-d") 'helm-bookmark-run-delete) + (define-key map (kbd "C-]") 'helm-bookmark-toggle-filename) + (define-key map (kbd "M-e") 'helm-bookmark-run-edit) + (define-key map (kbd "C-c ?") 'helm-bookmark-help) + map) + "Generic Keymap for emacs bookmark sources.") + +(defclass helm-source-basic-bookmarks (helm-source-in-buffer helm-type-bookmark) + ((init :initform (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global + (bookmark-all-names)))) + (filtered-candidate-transformer :initform 'helm-bookmark-transformer) + (search :initform 'helm-bookmark-search-fn))) + +(defvar helm-source-bookmarks + (helm-make-source "Bookmarks" 'helm-source-basic-bookmarks) + "See (info \"(emacs)Bookmarks\").") + +(defun helm-bookmark-transformer (candidates _source) + (cl-loop for i in candidates + for loc = (bookmark-location i) + for len = (string-width i) + for trunc = (if (> len bookmark-bmenu-file-column) + (helm-substring i bookmark-bmenu-file-column) + i) + for sep = (make-string (- (+ bookmark-bmenu-file-column 2) + (length trunc)) + ? ) + if helm-bookmark-show-location + collect (cons (concat trunc sep (if (listp loc) (car loc) loc)) i) + else collect i)) + +(defun helm-bookmark-match-fn (candidate) + "Match function for bookmark sources using `candidates'." + (if helm-bookmark-show-location + ;; match only location, match-plugin will match also name. + (string-match helm-pattern (bookmark-location candidate)) + (string-match helm-pattern candidate))) + +(defun helm-bookmark-toggle-filename-1 (_candidate) + (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))) + (setq helm-bookmark-show-location (not helm-bookmark-show-location)) + (helm-force-update (if helm-bookmark-show-location + (concat (regexp-quote trunc) + " +" + (regexp-quote + (if (listp loc) (car loc) loc))) + real)))) + +(defun helm-bookmark-toggle-filename () + "Toggle bookmark location visibility." + (interactive) + (with-helm-alive-p + (helm-attrset 'toggle-filename + '(helm-bookmark-toggle-filename-1 . never-split)) + (helm-execute-persistent-action 'toggle-filename))) + +(defun helm-bookmark-jump (candidate) + "Jump to bookmark from keyboard." + (let ((current-prefix-arg helm-current-prefix-arg) + non-essential) + (bookmark-jump candidate))) + +(defun helm-bookmark-jump-other-window (candidate) + (let (non-essential) + (bookmark-jump-other-window candidate))) + + +;;; bookmark-set +;; +(defvar helm-source-bookmark-set + '((name . "Set Bookmark") + (dummy) + (action . bookmark-set)) + "See (info \"(emacs)Bookmarks\").") + + +;;; Colorize bookmarks by category +;; +(defvar helm-source-pp-bookmarks + '((name . "PP-Bookmarks") + (init . (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (cl-loop for b in (bookmark-all-names) collect + (propertize b 'location (bookmark-location b)))))) + (candidates-in-buffer) + (search helm-bookmark-search-fn) + (match-part . helm-pp-bookmark-match-fn) + (filtered-candidate-transformer + helm-adaptive-sort + helm-highlight-bookmark) + (type . bookmark)) + "See (info \"(emacs)Bookmarks\").") + +(defun helm-bookmark-search-fn (pattern) + "Search function for bookmark sources using `candidates-in-buffer'. +Should be used with `helm-pp-bookmark-match-fn' as `match-part' function." + (if helm-bookmark-show-location + (helm-aif (next-single-property-change (point) 'location) + (goto-char it)) + (re-search-forward pattern nil t))) + +(defun helm-pp-bookmark-match-fn (candidate) + "Search function for bookmark sources using `candidates-in-buffer'. +Should be used with `helm-bookmark-search-fn' as `search' function." + (helm-aif (and helm-bookmark-show-location + (bookmark-location candidate)) + ;; Match against bookmark-name and location. + (concat candidate " " it) + ;; Match against bookmark-name. + candidate)) + + +;;; Predicates +;; +(defconst helm-bookmark--non-file-filename " - no file -" + "Name to use for `filename' entry, for non-file bookmarks.") + +(defun helm-bookmark-gnus-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Gnus bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (eq (bookmark-get-handler bookmark) 'bmkext-jump-gnus) + (eq (bookmark-get-handler bookmark) 'gnus-summary-bookmark-jump) + (eq (bookmark-get-handler bookmark) 'bookmarkp-jump-gnus))) + +(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." + (or (eq (bookmark-get-handler bookmark) 'bmkext-jump-w3m) + (eq (bookmark-get-handler bookmark) 'bookmark-w3m-bookmark-jump) + (eq (bookmark-get-handler bookmark) 'bookmarkp-jump-w3m))) + +(defun helm-bookmark-woman-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Woman bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (eq (bookmark-get-handler bookmark) 'bmkext-jump-woman) + (eq (bookmark-get-handler bookmark) 'woman-bookmark-jump) + (eq (bookmark-get-handler bookmark) 'bookmarkp-jump-woman))) + +(defun helm-bookmark-man-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Man bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (eq (bookmark-get-handler bookmark) 'bmkext-jump-man) + (eq (bookmark-get-handler bookmark) 'Man-bookmark-jump) + (eq (bookmark-get-handler bookmark) 'bookmarkp-jump-man))) + +(defun helm-bookmark-woman-man-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is a Man or Woman bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (or (helm-bookmark-man-bookmark-p bookmark) + (helm-bookmark-woman-bookmark-p bookmark))) + +(defun helm-bookmark-info-bookmark-p (bookmark) + "Return non-nil if BOOKMARK is an Info bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (eq (bookmark-get-handler bookmark) 'Info-bookmark-jump)) + +(defun helm-bookmark-image-bookmark-p (bookmark) + "Return non-nil if BOOKMARK bookmarks an image file." + (if (stringp bookmark) + (assoc 'image-type (assoc bookmark bookmark-alist)) + (assoc 'image-type bookmark))) + +(defun helm-bookmark-file-p (bookmark) + "Return non-nil if BOOKMARK bookmarks a file or directory. +BOOKMARK is a bookmark name or a bookmark record. +This excludes bookmarks of a more specific kind (Info, Gnus, and W3m)." + (let* ((filename (bookmark-get-filename bookmark)) + (isnonfile (equal filename helm-bookmark--non-file-filename))) + (and filename (not isnonfile) (not (bookmark-get-handler bookmark))))) + +(defun helm-bookmark-addressbook-p (bookmark) + "Return non--nil if BOOKMARK is a contact recorded with addressbook-bookmark. +BOOKMARK is a bookmark name or a bookmark record." + (if (listp bookmark) + (string= (assoc-default 'type bookmark) "addressbook") + (string= (assoc-default + 'type (assoc bookmark bookmark-alist)) "addressbook"))) + +(defun helm-bookmark-uncategorized-bookmark-p (bookmark) + "Return non--nil if BOOKMARK match no known category." + (and (not (helm-bookmark-addressbook-p bookmark)) + (not (helm-bookmark-gnus-bookmark-p bookmark)) + (not (helm-bookmark-w3m-bookmark-p bookmark)) + (not (helm-bookmark-woman-man-bookmark-p bookmark)) + (not (helm-bookmark-info-bookmark-p bookmark)) + (not (helm-bookmark-image-bookmark-p bookmark)) + (not (helm-bookmark-file-p bookmark)) + (not (helm-bookmark-addressbook-p bookmark)))) + +(defun helm-bookmark-filter-setup-alist (fn) + "Return a filtered `bookmark-alist' sorted alphabetically." + (cl-loop with alist = (cl-loop for b in bookmark-alist + when (funcall fn b) collect b) + for bmk in alist + for name = (car bmk) + collect (propertize name 'location (bookmark-location name)))) + + +;;; Bookmark handlers +;; +(defvar w3m-async-exec) +(defun helm-bookmark-jump-w3m (bookmark) + "Jump to W3m bookmark BOOKMARK, setting a new tab. +If `browse-url-browser-function' is set to something else +than `w3m-browse-url' use it." + (require 'helm-net) + (let ((file (or (bookmark-prop-get bookmark 'filename) + (bookmark-prop-get bookmark 'url))) + (buf (generate-new-buffer-name "*w3m*")) + (w3m-async-exec nil) + (really-use-w3m (equal browse-url-browser-function 'w3m-browse-url))) + (helm-browse-url file really-use-w3m) + (when really-use-w3m + (bookmark-default-handler + `("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark)))))) + +;; All bookmarks recorded with the handler provided with w3m +;; (`bookmark-w3m-bookmark-jump') will use our handler which open +;; the bookmark in a new tab or in an external browser depending +;; on `browse-url-browser-function'. +(defalias 'bookmark-w3m-bookmark-jump 'helm-bookmark-jump-w3m) + +;; Provide compatibility with old handlers provided in external +;; packages bookmark-extensions.el and bookmark+. +(defalias 'bmkext-jump-woman 'woman-bookmark-jump) +(defalias 'bmkext-jump-man 'Man-bookmark-jump) +(defalias 'bmkext-jump-w3m 'helm-bookmark-jump-w3m) +(defalias 'bmkext-jump-gnus 'gnus-summary-bookmark-jump) +(defalias 'bookmarkp-jump-gnus 'gnus-summary-bookmark-jump) +(defalias 'bookmarkp-jump-w3m 'helm-bookmark-jump-w3m) +(defalias 'bookmarkp-jump-woman 'woman-bookmark-jump) +(defalias 'bookmarkp-jump-man 'Man-bookmark-jump) + + +;;;; Filtered bookmark sources +;; +;; +(defclass helm-source-filtered-bookmarks (helm-source-in-buffer helm-type-bookmark) + ((search :initform #'helm-bookmark-search-fn) + (match-part :initform #'helm-pp-bookmark-match-fn) + (filtered-candidate-transformer + :initform '(helm-adaptive-sort + helm-highlight-bookmark)))) + +;;; W3m bookmarks. +;; +(defun helm-bookmark-w3m-setup-alist () + "Specialized filter function for bookmarks w3m." + (helm-bookmark-filter-setup-alist 'helm-bookmark-w3m-bookmark-p)) + +(defvar helm-source-bookmark-w3m + (helm-make-source "Bookmark W3m" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-w3m-setup-alist))))) + +;;; Images +;; +(defun helm-bookmark-images-setup-alist () + "Specialized filter function for images bookmarks." + (helm-bookmark-filter-setup-alist 'helm-bookmark-image-bookmark-p)) + +(defvar helm-source-bookmark-images + (helm-make-source "Bookmark Images" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-images-setup-alist))))) + +;;; Woman Man +;; +(defun helm-bookmark-man-setup-alist () + "Specialized filter function for bookmarks w3m." + (helm-bookmark-filter-setup-alist 'helm-bookmark-woman-man-bookmark-p)) + +(defvar helm-source-bookmark-man + (helm-make-source "Bookmark Woman&Man" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-man-setup-alist))))) + +;;; Gnus +;; +(defun helm-bookmark-gnus-setup-alist () + "Specialized filter function for bookmarks gnus." + (helm-bookmark-filter-setup-alist 'helm-bookmark-gnus-bookmark-p)) + +(defvar helm-source-bookmark-gnus + (helm-make-source "Bookmark Gnus" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-gnus-setup-alist))))) + +;;; Info +;; +(defun helm-bookmark-info-setup-alist () + "Specialized filter function for bookmarks info." + (helm-bookmark-filter-setup-alist 'helm-bookmark-info-bookmark-p)) + +(defvar helm-source-bookmark-info + (helm-make-source "Bookmark Info" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-info-setup-alist))))) + +;;; Files and directories +;; +(defun helm-bookmark-local-files-setup-alist () + "Specialized filter function for bookmarks locals files." + (helm-bookmark-filter-setup-alist 'helm-bookmark-file-p)) + +(defvar helm-source-bookmark-files&dirs + (helm-make-source "Bookmark Files&Directories" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-local-files-setup-alist))))) + +;;; Uncategorized bookmarks +;; +(defun helm-bookmark-uncategorized-setup-alist () + "Specialized filter function for uncategorized bookmarks." + (helm-bookmark-filter-setup-alist 'helm-bookmark-uncategorized-bookmark-p)) + +(defvar helm-source-bookmark-uncategorized + (helm-make-source "Bookmark uncategorized" 'helm-source-filtered-bookmarks + :init (lambda () + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global (helm-bookmark-uncategorized-setup-alist))))) + +;;; Addressbook. +;; +;; +(defclass helm-bookmark-addressbook-class (helm-source-in-buffer) + ((init :initform (lambda () + (require 'addressbook-bookmark nil t) + (bookmark-maybe-load-default-file) + (helm-init-candidates-in-buffer + 'global + (helm-bookmark-addressbook-setup-alist)))) + (search :initform #'helm-bookmark-search-fn) + (match-part :initform #'helm-pp-bookmark-match-fn) + (persistent-action :initform + (lambda (candidate) + (let ((bmk (helm-bookmark-get-bookmark-from-name + candidate))) + (bookmark--jump-via bmk 'switch-to-buffer)))) + (persistent-help :initform "Show contact - Prefix with C-u to append") + (filtered-candidate-transformer :initform + '(helm-adaptive-sort + helm-highlight-bookmark)) + (action :initform (("Show Contact(s)" + . (lambda (candidate) + (let* ((contacts (helm-marked-candidates)) + (current-prefix-arg helm-current-prefix-arg)) + (bookmark-jump + (helm-bookmark-get-bookmark-from-name (car contacts))) + (helm-aif (cdr contacts) + (let ((current-prefix-arg '(4))) + (cl-loop for bmk in it do + (bookmark-jump + (helm-bookmark-get-bookmark-from-name bmk)))))))) + ("Mail To" . helm-bookmark-addressbook-send-mail-1) + ("Mail Cc" . (lambda (_candidate) + (helm-bookmark-addressbook-send-mail-1 nil 'cc))) + ("Mail Bcc" . (lambda (_candidate) + (helm-bookmark-addressbook-send-mail-1 nil 'bcc))) + ("Edit Bookmark" + . (lambda (candidate) + (let ((bmk (helm-bookmark-get-bookmark-from-name + candidate))) + (addressbook-bookmark-edit + (assoc bmk bookmark-alist))))) + ("Delete bookmark(s)" . helm-delete-marked-bookmarks) + ("Insert Email at point" + . (lambda (candidate) + (let* ((bmk (helm-bookmark-get-bookmark-from-name + candidate)) + (mlist (split-string + (assoc-default + 'email (assoc bmk bookmark-alist)) + ", "))) + (insert + (if (> (length mlist) 1) + (helm-comp-read + "Insert Mail Address: " mlist :must-match t) + (car mlist)))))) + ("Show annotation" + . (lambda (candidate) + (let ((bmk (helm-bookmark-get-bookmark-from-name + candidate))) + (bookmark-show-annotation bmk)))) + ("Edit annotation" + . (lambda (candidate) + (let ((bmk (helm-bookmark-get-bookmark-from-name + candidate))) + (bookmark-edit-annotation bmk)))) + ("Show Google map" + . (lambda (candidate) + (let* ((bmk (helm-bookmark-get-bookmark-from-name + candidate)) + (full-bmk (assoc bmk bookmark-alist))) + (addressbook-google-map full-bmk)))))))) + +(defun helm-bookmark-addressbook-send-mail-1 (_candidate &optional cc) + (let* ((contacts (helm-marked-candidates)) + (bookmark (helm-bookmark-get-bookmark-from-name + (car contacts))) + (append (message-buffers))) + (addressbook-set-mail-buffer-1 bookmark append) + (helm-aif (cdr contacts) + (progn + (when cc (addressbook-set-mail-buffer-1 (car it) nil cc)) + (cl-loop for bmk in (cdr it) do + (addressbook-set-mail-buffer-1 + (helm-bookmark-get-bookmark-from-name bmk) 'append cc)))))) + +(defun helm-bookmark-addressbook-setup-alist () + "Specialized filter function for addressbook bookmarks." + (helm-bookmark-filter-setup-alist 'helm-bookmark-addressbook-p)) + +(defvar helm-source-bookmark-addressbook + (helm-make-source "Bookmark Addressbook" 'helm-bookmark-addressbook-class)) + +;;; Transformer +;; + +(defun helm-highlight-bookmark (bookmarks _source) + "Used as `filtered-candidate-transformer' to colorize bookmarks. +Work both with standard Emacs bookmarks and bookmark-extensions.el." + (let ((non-essential t)) + (cl-loop for i in bookmarks + for isfile = (bookmark-get-filename i) + for handlerp = (and (fboundp 'bookmark-get-handler) + (bookmark-get-handler i)) + for isw3m = (and (fboundp 'helm-bookmark-w3m-bookmark-p) + (helm-bookmark-w3m-bookmark-p i)) + for isgnus = (and (fboundp 'helm-bookmark-gnus-bookmark-p) + (helm-bookmark-gnus-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 + (helm-bookmark-woman-bookmark-p i)) + for isannotation = (bookmark-get-annotation i) + for isabook = (string= (bookmark-prop-get i 'type) + "addressbook") + for isinfo = (eq handlerp 'Info-bookmark-jump) + for loc = (bookmark-location i) + for len = (string-width i) + for trunc = (if (and helm-bookmark-show-location + (> len bookmark-bmenu-file-column)) + (helm-substring + i bookmark-bmenu-file-column) + i) + ;; Add a * if bookmark have annotation + if (and isannotation (not (string-equal isannotation ""))) + do (setq trunc (concat "*" (if helm-bookmark-show-location trunc i))) + for sep = (and helm-bookmark-show-location + (make-string (- (+ bookmark-bmenu-file-column 2) + (string-width trunc)) + ? )) + for bmk = (cond ( ;; info buffers + isinfo + (propertize trunc 'face 'helm-bookmark-info + 'help-echo isfile)) + ( ;; w3m buffers + isw3m + (propertize trunc 'face 'helm-bookmark-w3m + 'help-echo isfile)) + ( ;; gnus buffers + isgnus + (propertize trunc 'face 'helm-bookmark-gnus + 'help-echo isfile)) + ( ;; Man Woman + (or iswoman isman) + (propertize trunc 'face 'helm-bookmark-man + 'help-echo isfile)) + ( ;; Addressbook + isabook + (propertize trunc 'face 'helm-bookmark-addressbook)) + ( ;; directories + (and isfile + ;; This is needed because `non-essential' + ;; is not working on Emacs-24.2 and the behavior + ;; of tramp seems to have changed since previous + ;; versions (Need to reenter password even if a + ;; first connection have been established, + ;; probably when host is named differently + ;; i.e machine/localhost) + (not (file-remote-p isfile)) + (file-directory-p isfile)) + (propertize trunc 'face 'helm-bookmark-directory + 'help-echo isfile)) + ( ;; regular files + t + (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)) + i) + (cons bmk i))))) + +(defun helm-bookmark-edit-bookmark (bookmark-name) + "Edit bookmark's name and file name, and maybe save them. +BOOKMARK-NAME is the current (old) name of the bookmark to be renamed." + (let ((bmk (helm-bookmark-get-bookmark-from-name bookmark-name)) + (handler (bookmark-prop-get bookmark-name 'handler))) + (if (eq handler 'addressbook-bookmark-jump) + (addressbook-bookmark-edit + (assoc bmk bookmark-alist)) + (helm-bookmark-edit-bookmark-1 bookmark-name handler)))) + +(defun helm-bookmark-edit-bookmark-1 (bookmark-name handler) + (let* ((helm--reading-passwd-or-string t) + (bookmark-fname (bookmark-get-filename bookmark-name)) + (bookmark-loc (bookmark-prop-get bookmark-name 'location)) + (new-name (read-from-minibuffer "Name: " bookmark-name)) + (new-loc (read-from-minibuffer "FileName or Location: " + (or bookmark-fname + (if (consp bookmark-loc) + (car bookmark-loc) + bookmark-loc)))) + (docid (and (eq handler 'mu4e-bookmark-jump) + (read-number "Docid: " (cdr bookmark-loc))))) + (when docid + (setq new-loc (cons new-loc docid))) + (when (and (not (equal new-name "")) (not (equal new-loc "")) + (y-or-n-p "Save changes? ")) + (if bookmark-fname + (progn + (helm-bookmark-rename bookmark-name new-name 'batch) + (bookmark-set-filename new-name new-loc)) + (bookmark-prop-set + (bookmark-get-bookmark bookmark-name) 'location new-loc) + (helm-bookmark-rename bookmark-name new-name 'batch)) + (helm-bookmark-maybe-save-bookmark) + (list new-name new-loc)))) + +(defun helm-bookmark-maybe-save-bookmark () + "Increment save counter and maybe save `bookmark-alist'." + (setq bookmark-alist-modification-count (1+ bookmark-alist-modification-count)) + (when (bookmark-time-to-save-p) (bookmark-save))) + +(defun helm-bookmark-rename (old &optional new batch) + "Change bookmark's name from OLD to NEW. +Interactively: + If called from the keyboard, then prompt for OLD. + If called from the menubar, select OLD from a menu. +If NEW is nil, then prompt for its string value. + +If BATCH is non-nil, then do not rebuild the menu list. + +While the user enters the new name, repeated `C-w' inserts consecutive +words from the buffer into the new bookmark name." + (interactive (list (bookmark-completing-read "Old bookmark name"))) + (bookmark-maybe-historicize-string old) + (bookmark-maybe-load-default-file) + (save-excursion (skip-chars-forward " ") (setq bookmark-yank-point (point))) + (setq bookmark-current-buffer (current-buffer)) + (let ((newname (or new (read-from-minibuffer + "New name: " nil + (let ((now-map (copy-keymap minibuffer-local-map))) + (define-key now-map "\C-w" 'bookmark-yank-word) + now-map) + nil 'bookmark-history)))) + (bookmark-set-name old newname) + (setq bookmark-current-bookmark newname) + (unless batch (bookmark-bmenu-surreptitiously-rebuild-list)) + (helm-bookmark-maybe-save-bookmark) newname)) + +(defun helm-bookmark-run-edit () + "Run `helm-bookmark-edit-bookmark' from keyboard." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-bookmark-edit-bookmark))) + + +;;; Bookmarks attributes +;; +(define-helm-type-attribute 'bookmark + `((coerce . helm-bookmark-get-bookmark-from-name) + (action . ,(helm-make-actions + "Jump to bookmark" 'helm-bookmark-jump + "Jump to BM other window" 'helm-bookmark-jump-other-window + "Bookmark edit annotation" 'bookmark-edit-annotation + "Bookmark show annotation" 'bookmark-show-annotation + "Delete bookmark(s)" 'helm-delete-marked-bookmarks + "Edit Bookmark" 'helm-bookmark-edit-bookmark + "Rename bookmark" 'helm-bookmark-rename + "Relocate bookmark" 'bookmark-relocate)) + (keymap . ,helm-bookmark-map) + (mode-line . helm-bookmark-mode-line-string)) + "Bookmark name.") + + +(defun helm-bookmark-run-jump-other-window () + "Jump to bookmark from keyboard." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'bookmark-jump-other-window))) + +(defun helm-bookmark-run-delete () + "Delete bookmark from keyboard." + (interactive) + (with-helm-alive-p + (when (y-or-n-p "Delete bookmark(s)?") + (helm-quit-and-execute-action 'helm-delete-marked-bookmarks)))) + +(defun helm-bookmark-get-bookmark-from-name (bmk) + "Return bookmark name even if it is a bookmark with annotation. +e.g prepended with *." + (let ((bookmark (replace-regexp-in-string "\\`\\*" "" bmk))) + (if (assoc bookmark bookmark-alist) bookmark bmk))) + +(defun helm-delete-marked-bookmarks (_ignore) + "Delete this bookmark or all marked bookmarks." + (cl-dolist (i (helm-marked-candidates)) + (bookmark-delete (helm-bookmark-get-bookmark-from-name i) + 'batch))) + + +;;;###autoload +(defun helm-bookmarks () + "Preconfigured `helm' for bookmarks." + (interactive) + (helm :sources '(helm-source-bookmarks + helm-source-bookmark-set) + :buffer "*helm bookmarks*" + :default (buffer-name helm-current-buffer))) + +;;;###autoload +(defun helm-pp-bookmarks () + "Preconfigured `helm' for bookmarks (pretty-printed)." + (interactive) + (helm :sources '(helm-source-pp-bookmarks + helm-source-bookmark-set) + :buffer "*helm pp bookmarks*" + :default (buffer-name helm-current-buffer))) + +;;;###autoload +(defun helm-filtered-bookmarks () + "Preconfigured helm for bookmarks (filtered by category). +Optional source `helm-source-bookmark-addressbook' is loaded +only if external library addressbook-bookmark.el is available." + (interactive) + (helm :sources (append '(helm-source-bookmark-files&dirs + helm-source-bookmark-info + helm-source-bookmark-gnus + helm-source-bookmark-man + helm-source-bookmark-images + helm-source-bookmark-w3m) + (and (locate-library "addressbook-bookmark") + (list 'helm-source-bookmark-addressbook)) + (list helm-source-bookmark-uncategorized + 'helm-source-bookmark-set)) + :prompt "Search Bookmark: " + :buffer "*helm filtered bookmarks*" + :default (list (thing-at-point 'symbol) + (buffer-name helm-current-buffer)))) + +(provide 'helm-bookmark) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-bookmark.el ends here diff --git a/elpa/helm-20150403.101/helm-buffers.el b/elpa/helm-20150403.101/helm-buffers.el new file mode 100644 index 00000000..6775f329 --- /dev/null +++ b/elpa/helm-20150403.101/helm-buffers.el @@ -0,0 +1,854 @@ +;;; helm-buffers.el --- helm support for buffers. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'helm-elscreen) +(require 'helm-grep) +(require 'helm-plugin) +(require 'helm-regexp) +(require 'helm-help) + +(declare-function ido-make-buffer-list "ido" (default)) +(declare-function ido-add-virtual-buffers-to-list "ido") +(declare-function helm-comp-read "helm-mode") + + +(defgroup helm-buffers nil + "Buffers related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-boring-buffer-regexp-list + '("\\` " "\\*helm" "\\*helm-mode" "\\*Echo Area" "\\*Minibuf") + "The regexp list that match boring buffers. +Buffer candidates matching these regular expression will be +filtered from the list of candidates if the +`helm-skip-boring-buffers' candidate transformer is used." + :type '(repeat (choice regexp)) + :group 'helm-buffers) + +(defcustom helm-buffers-favorite-modes '(lisp-interaction-mode + emacs-lisp-mode + text-mode + org-mode) + "List of preferred mode to open new buffers with." + :type '(repeat (choice function)) + :group 'helm-buffers) + +(defcustom helm-buffer-max-length 20 + "Max length of buffer names before truncate. +When disabled (nil) use the longest buffer-name length found." + :group 'helm-buffers + :type '(choice (const :tag "Disabled" nil) + (integer :tag "Length before truncate"))) + +(defcustom helm-buffer-details-flag t + "Always show details in buffer list when non--nil." + :group 'helm-buffers + :type 'boolean) + +(defcustom helm-buffers-fuzzy-matching nil + "Fuzzy matching buffer names when non--nil. +Only buffer names are fuzzy matched when this is enabled, +`major-mode' matching is not affected by this." + :group 'helm-buffers + :type 'boolean) + +(defcustom helm-buffer-skip-remote-checking nil + "Ignore checking for `file-exists-p' on remote files." + :group 'helm-buffers + :type 'boolean) + +;;; Faces +;; +;; +(defgroup helm-buffers-faces nil + "Customize the appearance of helm-buffers." + :prefix "helm-" + :group 'helm-buffers + :group 'helm-faces) + +(defface helm-buffer-saved-out + '((t (:foreground "red" :background "black"))) + "Face used for buffer files modified outside of emacs." + :group 'helm-buffers-faces) + +(defface helm-buffer-not-saved + '((t (:foreground "Indianred2"))) + "Face used for buffer files not already saved on disk." + :group 'helm-buffers-faces) + +(defface helm-buffer-size + '((((background dark)) :foreground "RosyBrown") + (((background light)) :foreground "SlateGray")) + "Face used for buffer size." + :group 'helm-buffers-faces) + +(defface helm-buffer-process + '((t (:foreground "Sienna3"))) + "Face used for process status in buffer." + :group 'helm-buffers-faces) + +(defface helm-buffer-directory + '((t (:foreground "DarkRed" :background "LightGray"))) + "Face used for directories in `helm-buffers-list'." + :group 'helm-buffers-faces) + +(defface helm-buffer-file + '((t :inherit font-lock-builtin-face)) + "Face for buffer file names in `helm-buffers-list'." + :group 'helm-buffers-faces) + + +;;; Buffers keymap +;; +(defvar helm-buffer-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-buffer-help) + ;; No need to have separate command for grep and zgrep + ;; as we don't use recursivity for buffers. + ;; So use zgrep for both as it is capable to handle non--compressed files. + (define-key map (kbd "M-g s") 'helm-buffer-run-zgrep) + (define-key map (kbd "C-s") 'helm-buffers-run-multi-occur) + (define-key map (kbd "C-c o") 'helm-buffer-switch-other-window) + (define-key map (kbd "C-c C-o") 'helm-buffer-switch-other-frame) + (define-key map (kbd "C-c =") 'helm-buffer-run-ediff) + (define-key map (kbd "M-=") 'helm-buffer-run-ediff-merge) + (define-key map (kbd "C-=") 'helm-buffer-diff-persistent) + (define-key map (kbd "M-U") 'helm-buffer-revert-persistent) + (define-key map (kbd "C-c d") 'helm-buffer-run-kill-persistent) + (define-key map (kbd "M-D") 'helm-buffer-run-kill-buffers) + (define-key map (kbd "C-x C-s") 'helm-buffer-save-persistent) + (define-key map (kbd "C-M-%") 'helm-buffer-run-query-replace-regexp) + (define-key map (kbd "M-%") 'helm-buffer-run-query-replace) + (define-key map (kbd "M-m") 'helm-toggle-all-marks) + (define-key map (kbd "M-a") 'helm-mark-all) + (define-key map (kbd "C-]") 'helm-toggle-buffers-details) + (define-key map (kbd "C-c a") 'helm-buffers-toggle-show-hidden-buffers) + (define-key map (kbd "") 'helm-buffers-mark-similar-buffers) + map) + "Keymap for buffer sources in helm.") + +(defvar helm-buffers-ido-virtual-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-buffers-ido-virtual-help) + (define-key map (kbd "C-c o") 'helm-ff-run-switch-other-window) + (define-key map (kbd "C-c C-o") 'helm-ff-run-switch-other-frame) + (define-key map (kbd "M-g s") 'helm-ff-run-grep) + (define-key map (kbd "M-g z") 'helm-ff-run-zgrep) + (define-key map (kbd "M-D") 'helm-ff-run-delete-file) + (define-key map (kbd "C-c C-x") 'helm-ff-run-open-file-externally) + map)) + + +(defvar helm-buffers-list-cache nil) +(defvar helm-buffer-max-len-mode nil) +(defclass helm-source-buffers (helm-source-sync helm-type-buffer) + ((buffer-list + :initarg :buffer-list + :initform #'helm-buffer-list + :custom function + :documentation + " A function with no arguments to create buffer list.") + (init :initform (lambda () + ;; Issue #51 Create the list before `helm-buffer' creation. + (setq helm-buffers-list-cache (funcall (helm-attr 'buffer-list))) + (let ((result (cl-loop for b in helm-buffers-list-cache + maximize (length b) into len-buf + maximize (length (with-current-buffer b + (symbol-name major-mode))) + into len-mode + finally return (cons len-buf len-mode)))) + (unless helm-buffer-max-length + (setq helm-buffer-max-length (car result))) + (unless helm-buffer-max-len-mode + ;; If a new buffer is longer that this value + ;; this value will be updated + (setq helm-buffer-max-len-mode (cdr result)))))) + (candidates :initform helm-buffers-list-cache) + (matchplugin :initform nil) + ;(nohighlight :initform t) + (match :initform 'helm-buffers-match-function) + (persistent-action :initform 'helm-buffers-list-persistent-action) + (resume :initform (lambda () + (run-with-idle-timer + 0.1 nil (lambda () + (with-helm-buffer + (helm-force-update)))))) + (keymap :initform helm-buffer-map) + (volatile :initform t) + (mode-line :initform helm-buffer-mode-line-string) + (persistent-help + :initform + "Show this buffer / C-u \\[helm-execute-persistent-action]: Kill this buffer"))) + +(defvar helm-source-buffers-list nil) + +(defvar helm-source-buffer-not-found + (helm-build-dummy-source + "Create buffer" + :action (helm-make-actions + "Create buffer (C-u choose mode)" + (lambda (candidate) + (let ((mjm (or (and helm-current-prefix-arg + (intern-soft (helm-comp-read + "Major-mode: " + helm-buffers-favorite-modes))) + (cl-loop for (r . m) in auto-mode-alist + when (string-match r candidate) + return m))) + (buffer (get-buffer-create candidate))) + (if mjm + (with-current-buffer buffer (funcall mjm)) + (set-buffer-major-mode buffer)) + (switch-to-buffer buffer)))))) + +(defvar ido-temp-list) +(defvar ido-ignored-list) +(defvar ido-process-ignore-lists) +(defvar ido-use-virtual-buffers) +(defvar ido-virtual-buffers) + +(defvar helm-source-ido-virtual-buffers + (helm-build-sync-source "Ido virtual buffers" + :candidates (lambda () + (let (ido-temp-list + ido-ignored-list + (ido-process-ignore-lists t)) + (when ido-use-virtual-buffers + (ido-add-virtual-buffers-to-list) + ido-virtual-buffers))) + :fuzzy-match helm-buffers-fuzzy-matching + :keymap helm-buffers-ido-virtual-map + :mode-line helm-buffers-ido-virtual-mode-line-string + :action '(("Find file" . helm-find-many-files) + ("Find file other window" . find-file-other-window) + ("Find file other frame" . find-file-other-frame) + ("Find file as root" . helm-find-file-as-root) + ("Grep File(s) `C-u recurse'" . helm-find-files-grep) + ("Zgrep File(s) `C-u Recurse'" . helm-ff-zgrep) + ("View file" . view-file) + ("Delete file(s)" . helm-delete-marked-files) + ("Open file externally (C-u to choose)" + . helm-open-file-externally)))) + + +(defvar ido-use-virtual-buffers) +(defun helm-buffer-list () + "Return the current list of buffers. +Currently visible buffers are put at the end of the list. +See `ido-make-buffer-list' for more infos." + (require 'ido) + (let ((ido-process-ignore-lists t) + ido-ignored-list + ido-use-virtual-buffers) + (ido-make-buffer-list nil))) + +(defun helm-buffer-size (buffer) + "Return size of BUFFER." + (with-current-buffer buffer + (save-restriction + (widen) + (helm-file-human-size + (- (position-bytes (point-max)) + (position-bytes (point-min))))))) + +(defun helm-buffer--show-details (buf-name prefix help-echo + size mode dir face1 face2 + proc details type) + (append + (list + (concat prefix + (propertize buf-name 'face face1 + 'help-echo help-echo + 'type type))) + (and details + (list size mode + (propertize + (if proc + (format "(%s %s in `%s')" + (process-name proc) + (process-status proc) dir) + (format "(in `%s')" dir)) + 'face face2))))) + +(defun helm-buffer--details (buffer &optional details) + (let* ((mode (with-current-buffer buffer (format-mode-line mode-name))) + (buf (get-buffer buffer)) + (size (propertize (helm-buffer-size buf) + 'face 'helm-buffer-size)) + (proc (get-buffer-process buf)) + (dir (with-current-buffer buffer (abbreviate-file-name default-directory))) + (file-name (helm-aif (buffer-file-name buf) (abbreviate-file-name it))) + (name (buffer-name buf)) + (name-prefix (when (file-remote-p dir) + (propertize "@ " 'face 'helm-ff-prefix)))) + ;; No fancy things on remote buffers. + (if (and name-prefix helm-buffer-skip-remote-checking) + (helm-buffer--show-details + name name-prefix file-name size mode dir + 'helm-buffer-file 'helm-buffer-process nil details 'filebuf) + (cond + ( ;; A dired buffer. + (rassoc buf dired-buffers) + (helm-buffer--show-details + name name-prefix dir size mode dir + 'helm-buffer-directory 'helm-buffer-process nil details 'dired)) + ;; A buffer file modified somewhere outside of emacs.=>red + ((and file-name + (file-exists-p file-name) + (not (verify-visited-file-modtime buf))) + (helm-buffer--show-details + name name-prefix file-name size mode dir + 'helm-buffer-saved-out 'helm-buffer-process nil details 'modout)) + ;; A new buffer file not already saved on disk.=>indianred2 + ((and file-name + (not (verify-visited-file-modtime buf))) + (helm-buffer--show-details + name name-prefix file-name size mode dir + 'helm-buffer-not-saved 'helm-buffer-process nil details 'notsaved)) + ;; A buffer file modified and not saved on disk.=>orange + ((and file-name (buffer-modified-p buf)) + (helm-buffer--show-details + name name-prefix file-name size mode dir + 'helm-ff-symlink 'helm-buffer-process nil details 'mod)) + ;; A buffer file not modified and saved on disk.=>green + (file-name + (helm-buffer--show-details + name name-prefix file-name size mode dir + 'helm-buffer-file 'helm-buffer-process nil details 'filebuf)) + ;; Any non--file buffer.=>grey italic + (t + (helm-buffer--show-details + name (and proc name-prefix) dir size mode dir + 'italic 'helm-buffer-process proc details 'nofile)))))) + +(defun helm-highlight-buffers (buffers _source) + "Transformer function to highlight BUFFERS list. +Should be called after others transformers i.e (boring buffers)." + (cl-loop for i in buffers + for (name size mode meta) = (if helm-buffer-details-flag + (helm-buffer--details i 'details) + (helm-buffer--details i)) + for truncbuf = (if (> (string-width name) helm-buffer-max-length) + (helm-substring-by-width + name helm-buffer-max-length) + (concat name (make-string + (- (+ helm-buffer-max-length 3) + (string-width name)) ? ))) + for len = (length mode) + when (> len helm-buffer-max-len-mode) + do (setq helm-buffer-max-len-mode len) + for fmode = (concat (make-string + (- (max helm-buffer-max-len-mode len) len) ? ) + mode) + ;; The max length of a number should be 1023.9X where X is the + ;; units, this is 7 characters. + for formatted-size = (and size (format "%7s" size)) + collect (cons (if helm-buffer-details-flag + (concat truncbuf "\t" formatted-size + " " fmode " " meta) + name) + (get-buffer i)))) + +(defun helm-buffer--get-preselection (buffer) + (let ((bufname (buffer-name buffer))) + (concat "^" + (if (and (null helm-buffer-details-flag) + (numberp helm-buffer-max-length) + (> (string-width bufname) + helm-buffer-max-length)) + (regexp-quote + (helm-substring-by-width + bufname helm-buffer-max-length)) + (concat (regexp-quote bufname) + (if helm-buffer-details-flag + "$" "[[:blank:]]+")))))) + +(defun helm-toggle-buffers-details () + (interactive) + (let ((preselect (helm-buffer--get-preselection + (helm-get-selection)))) + (when helm-alive-p + (setq helm-buffer-details-flag (not helm-buffer-details-flag)) + (helm-force-update preselect)))) + +(defun helm-buffers-sort-transformer (candidates _source) + (if (string= helm-pattern "") + candidates + (sort candidates + #'(lambda (s1 s2) + (< (string-width s1) (string-width s2)))))) + +(defun helm-buffers-mark-similar-buffers-1 () + (with-helm-window + (let ((type (get-text-property + 0 'type (helm-get-selection nil 'withprop)))) + (save-excursion + (goto-char (helm-get-previous-header-pos)) + (helm-next-line) + (let* ((next-head (helm-get-next-header-pos)) + (end (and next-head + (save-excursion + (goto-char next-head) + (forward-line -1) + (point)))) + (maxpoint (or end (point-max)))) + (while (< (point) maxpoint) + (helm-mark-current-line) + (let ((cand (helm-get-selection nil 'withprop))) + (when (and (not (helm-this-visible-mark)) + (eq (get-text-property 0 'type cand) type)) + (helm-make-visible-mark))) + (forward-line 1) (end-of-line)))) + (helm-mark-current-line) + (message "%s candidates marked" (length helm-marked-candidates))))) + +(defun helm-buffers-mark-similar-buffers () + "Mark All buffers that have same property `type' than current. +i.e same color." + (interactive) + (let ((marked (helm-marked-candidates))) + (if (and (>= (length marked) 1) + (with-helm-window helm-visible-mark-overlays)) + (helm-unmark-all) + (helm-buffers-mark-similar-buffers-1)))) + + +;;; match functions +;; +(defun helm-buffer--match-mjm (pattern mjm) + (when (string-match "\\`\\*" pattern) + (cl-loop with patterns = (split-string (substring pattern 1) ",") + for pat in patterns + if (string-match "\\`!" pat) + collect (string-match (substring pat 1) mjm) into neg + else collect (string-match pat mjm) into pos + finally return + (let ((neg-test (cl-loop for i in neg thereis (numberp i))) + (pos-test (cl-loop for i in pos thereis (numberp i)))) + (or + (and neg (not pos) (not neg-test)) + (and pos pos-test) + (and neg neg-test (not neg-test))))))) + +(defun helm-buffer--match-pattern (pattern candidate) + (let ((fun (if (and helm-buffers-fuzzy-matching + (not (string-match "\\`\\^" pattern))) + #'helm--mapconcat-pattern + #'identity))) + (if (string-match "\\`!" pattern) + (not (string-match (funcall fun (substring pattern 1)) + candidate)) + (string-match (funcall fun pattern) candidate)))) + +(defun helm-buffers--match-from-mjm (candidate) + (let* ((cand (replace-regexp-in-string "^\\s-\\{1\\}" "" candidate)) + (buf (get-buffer cand)) + (regexp (cl-loop with pattern = helm-pattern + for p in (split-string pattern) + when (string-match "\\`\\*" p) + return p))) + (if regexp + (when buf + (with-current-buffer buf + (let ((mjm (format-mode-line mode-name))) + (helm-buffer--match-mjm regexp mjm)))) + t))) + +(defun helm-buffers--match-from-pat (candidate) + (let ((regexp-list (cl-loop with pattern = helm-pattern + for p in (split-string pattern) + unless (string-match + "\\`\\(\\*\\)\\|\\(/\\)\\|\\(@\\)" p) + collect p))) + (if regexp-list + (cl-loop for re in regexp-list + always (helm-buffer--match-pattern re candidate)) + t))) + +(defun helm-buffers--match-from-inside (candidate) + (let* ((cand (replace-regexp-in-string "^\\s-\\{1\\}" "" candidate)) + (buf (get-buffer cand)) + (regexp (cl-loop with pattern = helm-pattern + for p in (split-string pattern) + when (string-match "\\`@\\(.*\\)" p) + return (match-string 1 p)))) + (if regexp + (with-current-buffer buf + (save-excursion + (goto-char (point-min)) + (re-search-forward regexp nil t))) + t))) + +(defun helm-buffers--match-from-directory (candidate) + (let* ((cand (replace-regexp-in-string "^\\s-\\{1\\}" "" candidate)) + (buf (get-buffer cand)) + (buf-fname (buffer-file-name buf)) + (regexps (cl-loop with pattern = helm-pattern + for p in (split-string pattern) + when (string-match "\\`/" p) + collect p))) + (if regexps + (cl-loop for re in regexps + thereis + (and buf-fname + (string-match + (substring re 1) (helm-basedir buf-fname)))) + t))) + +(defun helm-buffers-match-function (candidate) + "Default function to match buffers." + (and (helm-buffers--match-from-pat candidate) + (helm-buffers--match-from-mjm candidate) + (helm-buffers--match-from-inside candidate) + (helm-buffers--match-from-directory candidate))) + + +(defun helm-buffer-query-replace-1 (&optional regexp-flag buffers) + "Query replace in marked buffers. +If REGEXP-FLAG is given use `query-replace-regexp'." + (let ((fn (if regexp-flag 'query-replace-regexp 'query-replace)) + (prompt (if regexp-flag "Query replace regexp" "Query replace")) + (bufs (or buffers (helm-marked-candidates))) + (helm--reading-passwd-or-string t)) + (cl-loop with replace = (query-replace-read-from prompt regexp-flag) + with tostring = (unless (consp replace) + (query-replace-read-to + replace prompt regexp-flag)) + for buf in bufs + do + (save-window-excursion + (switch-to-buffer buf) + (save-excursion + (let ((case-fold-search t)) + (goto-char (point-min)) + (if (consp replace) + (apply fn (list (car replace) (cdr replace))) + (apply fn (list replace tostring))))))))) + +(defun helm-buffer-query-replace-regexp (_candidate) + (helm-buffer-query-replace-1 'regexp)) + +(defun helm-buffer-query-replace (_candidate) + (helm-buffer-query-replace-1)) + +(defun helm-buffer-toggle-diff (candidate) + "Toggle diff buffer CANDIDATE with it's file." + (let (helm-persistent-action-use-special-display) + (helm-aif (get-buffer-window "*Diff*") + (progn (kill-buffer "*Diff*") + (set-window-buffer it helm-current-buffer)) + (diff-buffer-with-file (get-buffer candidate))))) + +(defun helm-buffer-diff-persistent () + "Toggle diff buffer without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'diff-action 'helm-buffer-toggle-diff) + (helm-execute-persistent-action 'diff-action))) + +(defun helm-revert-buffer (candidate) + (with-current-buffer candidate + (helm-aif (buffer-file-name) + (and (file-exists-p it) (revert-buffer t t))))) + +(defun helm-revert-marked-buffers (_ignore) + (mapc 'helm-revert-buffer (helm-marked-candidates))) + +(defun helm-buffer-revert-and-update (_candidate) + (let ((marked (helm-marked-candidates)) + (preselect (helm-buffers--quote-truncated-buffer + (helm-get-selection)))) + (cl-loop for buf in marked do (helm-revert-buffer buf)) + (when (> (length marked) 1) (helm-unmark-all)) + (helm-force-update preselect))) + +(defun helm-buffer-revert-persistent () + "Revert buffer without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'revert-action '(helm-buffer-revert-and-update . never-split)) + (helm-execute-persistent-action 'revert-action))) + +(defun helm-buffer-save-and-update (_candidate) + (let ((marked (helm-marked-candidates)) + (preselect (helm-get-selection nil t)) + (enable-recursive-minibuffers t)) + (cl-loop for buf in marked do + (with-current-buffer (get-buffer buf) + (when (buffer-file-name) (save-buffer)))) + (when (> (length marked) 1) (helm-unmark-all)) + (helm-force-update (regexp-quote preselect)))) + +(defun helm-buffer-save-persistent () + "Save buffer without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'save-action '(helm-buffer-save-and-update . never-split)) + (helm-execute-persistent-action 'save-action))) + +(defun helm-buffer-run-kill-persistent () + "Kill buffer without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'kill-action '(helm-buffers-persistent-kill . never-split)) + (helm-execute-persistent-action 'kill-action))) + +(defun helm-kill-marked-buffers (_ignore) + (mapc 'kill-buffer (helm-marked-candidates)) + (with-helm-buffer + (setq helm-marked-candidates nil + helm-visible-mark-overlays nil))) + +(defun helm-buffer-run-kill-buffers () + "Run kill buffer action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-kill-marked-buffers))) + +(defun helm-buffer-run-grep () + "Run Grep action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-grep-buffers))) + +(defun helm-buffer-run-zgrep () + "Run Grep action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-zgrep-buffers))) + +(defun helm-buffer-run-query-replace-regexp () + "Run Query replace regexp action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-buffer-query-replace-regexp))) + +(defun helm-buffer-run-query-replace () + "Run Query replace action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-buffer-query-replace))) + +(defun helm-buffer-switch-other-window () + "Run switch to other window action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-switch-to-buffers-other-window))) + +(defun helm-buffer-switch-other-frame () + "Run switch to other frame action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'switch-to-buffer-other-frame))) + +(defun helm-buffer-switch-to-elscreen () + "Run switch to elscreen action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-buffer-on-elscreen))) + +(defun helm-buffer-run-ediff () + "Run ediff action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ediff-marked-buffers))) + +(defun helm-buffer-run-ediff-merge () + "Run ediff action from `helm-source-buffers-list'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ediff-marked-buffers-merge))) + +(defun helm-buffers-persistent-kill-1 (buffer) + "Persistent action to kill buffer." + (with-current-buffer (get-buffer buffer) + (if (and (buffer-modified-p) + (buffer-file-name (current-buffer))) + (progn + (save-buffer) + (kill-buffer buffer)) + (kill-buffer buffer))) + (helm-delete-current-selection) + (with-helm-temp-hook 'helm-after-persistent-action-hook + (helm-force-update (regexp-quote (helm-get-selection nil t))))) + +(defun helm-buffers--quote-truncated-buffer (buffer) + (let ((bufname (and (bufferp buffer) + (buffer-name buffer)))) + (when bufname + (regexp-quote + (if helm-buffer-max-length + (helm-substring-by-width + bufname helm-buffer-max-length + "") + bufname))))) + +(defun helm-buffers-persistent-kill (_buffer) + (let ((marked (helm-marked-candidates))) + (unwind-protect + (cl-loop for b in marked + do (progn (helm-preselect + (format "^%s" + (helm-buffers--quote-truncated-buffer b))) + (when (y-or-n-p (format "kill buffer (%s)? " b)) + (helm-buffers-persistent-kill-1 b)) + (message nil))) + (with-helm-buffer + (setq helm-marked-candidates nil + helm-visible-mark-overlays nil)) + (helm-force-update (helm-buffers--quote-truncated-buffer + (helm-get-selection)))))) + +(defun helm-buffers-list-persistent-action (candidate) + (if current-prefix-arg + (helm-buffers-persistent-kill candidate) + (switch-to-buffer candidate))) + +(defun helm-ediff-marked-buffers (_candidate &optional merge) + "Ediff 2 marked buffers or CANDIDATE and `helm-current-buffer'. +With optional arg MERGE call `ediff-merge-buffers'." + (let ((lg-lst (length (helm-marked-candidates))) + buf1 buf2) + (cl-case lg-lst + (0 + (error "Error:You have to mark at least 1 buffer")) + (1 + (setq buf1 helm-current-buffer + buf2 (cl-first (helm-marked-candidates)))) + (2 + (setq buf1 (cl-first (helm-marked-candidates)) + buf2 (cl-second (helm-marked-candidates)))) + (t + (error "Error:To much buffers marked!"))) + (if merge + (ediff-merge-buffers buf1 buf2) + (ediff-buffers buf1 buf2)))) + +(defun helm-ediff-marked-buffers-merge (candidate) + "Ediff merge `helm-current-buffer' with CANDIDATE. +See `helm-ediff-marked-buffers'." + (helm-ediff-marked-buffers candidate t)) + +(defun helm-multi-occur-as-action (_candidate) + "Multi occur action for `helm-source-buffers-list'. +Can be used by any source that list buffers." + (let ((helm-moccur-always-search-in-current + (if helm-current-prefix-arg + (not helm-moccur-always-search-in-current) + helm-moccur-always-search-in-current)) + (buffers (helm-marked-candidates)) + (input (cl-loop for i in (split-string helm-pattern " " t) + thereis (and (string-match "\\`@\\(.*\\)" i) + (match-string 1 i))))) + (helm-multi-occur-1 buffers input))) + +(defun helm-buffers-run-multi-occur () + "Run `helm-multi-occur-as-action' by key." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-multi-occur-as-action))) + +(defun helm-buffers-toggle-show-hidden-buffers () + (interactive) + (with-helm-alive-p + (let ((filter-attrs (helm-attr 'filtered-candidate-transformer + helm-source-buffers-list))) + (if (memq 'helm-shadow-boring-buffers filter-attrs) + (helm-attrset 'filtered-candidate-transformer + (cons 'helm-skip-boring-buffers + (remove 'helm-shadow-boring-buffers + filter-attrs)) + helm-source-buffers-list t) + (helm-attrset 'filtered-candidate-transformer + (cons 'helm-shadow-boring-buffers + (remove 'helm-skip-boring-buffers + filter-attrs)) + helm-source-buffers-list t)) + (helm-force-update)))) + + +;;; Candidate Transformers +;; +;; +(defun helm-skip-boring-buffers (buffers _source) + (helm-skip-entries buffers helm-boring-buffer-regexp-list)) + +(defun helm-shadow-boring-buffers (buffers _source) + "Buffers matching `helm-boring-buffer-regexp' will be +displayed with the `file-name-shadow' face if available." + (helm-shadow-entries buffers helm-boring-buffer-regexp-list)) + + +(define-helm-type-attribute 'buffer + `((action + . ,(helm-make-actions + "Switch to buffer" 'switch-to-buffer + (lambda () (and (locate-library "popwin") "Switch to buffer in popup window")) + 'popwin:popup-buffer + "Switch to buffer other window `C-c o'" 'switch-to-buffer-other-window + "Switch to buffer other frame `C-c C-o'" 'switch-to-buffer-other-frame + (lambda () (and (locate-library "elscreen") "Display buffer in Elscreen")) + 'helm-find-buffer-on-elscreen + "Query replace regexp `C-M-%'" 'helm-buffer-query-replace-regexp + "Query replace `M-%'" 'helm-buffer-query-replace + "View buffer" 'view-buffer + "Display buffer" 'display-buffer + "Grep buffers `M-g s' (C-u grep all buffers)" 'helm-zgrep-buffers + "Multi occur buffer(s) `C-s'" 'helm-multi-occur-as-action + "Revert buffer(s) `M-U'" 'helm-revert-marked-buffers + "Insert buffer" 'insert-buffer + "Kill buffer(s) `M-D'" 'helm-kill-marked-buffers + "Diff with file" 'diff-buffer-with-file + "Ediff Marked buffers `C-c ='" 'helm-ediff-marked-buffers + "Ediff Merge marked buffers `M-='" (lambda (candidate) + (helm-ediff-marked-buffers candidate t)))) + (persistent-help . "Show this buffer") + (filtered-candidate-transformer helm-skip-boring-buffers + helm-buffers-sort-transformer + helm-highlight-buffers)) + "Buffer or buffer name.") + +;;;###autoload +(defun helm-buffers-list () + "Preconfigured `helm' to list buffers." + (interactive) + (unless helm-source-buffers-list + (setq helm-source-buffers-list + (helm-make-source "Buffers" 'helm-source-buffers))) + (helm :sources '(helm-source-buffers-list + helm-source-ido-virtual-buffers + helm-source-buffer-not-found) + :buffer "*helm buffers*" + :keymap helm-buffer-map + :truncate-lines t)) + +(provide 'helm-buffers) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-buffers.el ends here diff --git a/elpa/helm-20150403.101/helm-color.el b/elpa/helm-20150403.101/helm-color.el new file mode 100644 index 00000000..af4af763 --- /dev/null +++ b/elpa/helm-20150403.101/helm-color.el @@ -0,0 +1,163 @@ +;;; helm-color.el --- colors and faces -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) + +;;; Customize Face +;; +;; +(defun helm-custom-faces-init () + "Initialize buffer for `helm-source-customize-face'." + (unless (helm-candidate-buffer) + (save-selected-window + (list-faces-display) + (message nil)) + (helm-init-candidates-in-buffer + 'global + (with-current-buffer (get-buffer "*Faces*") + (buffer-substring + (next-single-char-property-change (point-min) 'face) + (point-max)))) + (kill-buffer "*Faces*"))) + +(defvar helm-source-customize-face + '((name . "Customize Face") + (init . helm-custom-faces-init) + (candidates-in-buffer) + (get-line . buffer-substring) + (action . (("Customize" + . (lambda (line) + (customize-face (intern (car (split-string line)))))) + ("Copy name" + . (lambda (line) + (kill-new (car (split-string line " " t)))))))) + "See (info \"(emacs)Faces\")") + +;;; Colors browser +;; +;; +(defun helm-colors-init () + (unless (helm-candidate-buffer) + (save-selected-window + (list-colors-display) + (message nil)) + (helm-init-candidates-in-buffer + 'global + (with-current-buffer (get-buffer "*Colors*") + (buffer-string))) + (kill-buffer "*Colors*"))) + +(defun helm-color-insert-name (candidate) + (with-helm-current-buffer + (insert (helm-colors-get-name candidate)))) + +(defun helm-color-kill-name (candidate) + (kill-new (helm-colors-get-name candidate))) + +(defun helm-color-insert-rgb (candidate) + (with-helm-current-buffer + (insert (helm-colors-get-rgb candidate)))) + +(defun helm-color-kill-rgb (candidate) + (kill-new (helm-colors-get-rgb candidate))) + +(defun helm-color-run-insert-name () + "Insert name of color from `helm-source-colors'" + (interactive) + (with-helm-alive-p (helm-quit-and-execute-action 'helm-color-insert-name))) + +(defun helm-color-run-kill-name () + "Kill name of color from `helm-source-colors'" + (interactive) + (with-helm-alive-p (helm-quit-and-execute-action 'helm-color-kill-name))) + +(defun helm-color-run-insert-rgb () + "Insert RGB of color from `helm-source-colors'" + (interactive) + (with-helm-alive-p (helm-quit-and-execute-action 'helm-color-insert-rgb))) + +(defun helm-color-run-kill-rgb () + "Kill RGB of color from `helm-source-colors'" + (interactive) + (with-helm-alive-p (helm-quit-and-execute-action 'helm-color-kill-rgb))) + +(defvar helm-color-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c n") 'helm-color-run-insert-name) + (define-key map (kbd "C-c N") 'helm-color-run-kill-name) + (define-key map (kbd "C-c r") 'helm-color-run-insert-rgb) + (define-key map (kbd "C-c R") 'helm-color-run-kill-rgb) + (define-key map (kbd "C-c ?") 'helm-color-help) + map)) + +(defvar helm-source-colors + `((name . "Colors") + (init . helm-colors-init) + (candidates-in-buffer) + (get-line . buffer-substring) + (keymap . ,helm-color-map) + (persistent-help . "Kill entry in RGB format.") + (persistent-action . helm-color-kill-rgb) + (mode-line . helm-color-mode-line-string) + (action + ("Copy Name (C-c N)" . helm-color-kill-name) + ("Copy RGB (C-c R)" . helm-color-kill-rgb) + ("Insert Name (C-c n)" . helm-color-insert-name) + ("Insert RGB (C-c r)" . helm-color-insert-rgb)))) + +(defun helm-colors-get-name (candidate) + "Get color name." + (replace-regexp-in-string + " " "" + (with-temp-buffer + (insert (capitalize candidate)) + (goto-char (point-min)) + (search-forward-regexp "\\s-\\{2,\\}") + (delete-region (point) (point-max)) + (buffer-string)))) + +(defun helm-colors-get-rgb (candidate) + "Get color RGB." + (replace-regexp-in-string + " " "" + (with-temp-buffer + (insert (capitalize candidate)) + (goto-char (point-max)) + (search-backward-regexp "\\s-\\{2,\\}") + (delete-region (point) (point-min)) + (buffer-string)))) + +;;;###autoload +(defun helm-colors () + "Preconfigured `helm' for color." + (interactive) + (helm-other-buffer + '(helm-source-colors helm-source-customize-face) + "*helm colors*")) + +(provide 'helm-color) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-color.el ends here diff --git a/elpa/helm-20150403.101/helm-command.el b/elpa/helm-20150403.101/helm-command.el new file mode 100644 index 00000000..ffafb3f9 --- /dev/null +++ b/elpa/helm-20150403.101/helm-command.el @@ -0,0 +1,234 @@ +;;; helm-command.el --- Helm execute-exended-command. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-mode) +(require 'helm-elisp) + + +(defgroup helm-command nil + "Emacs command related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-M-x-requires-pattern 0 + "Value of requires-pattern for `helm-M-x'. +Show all candidates on startup when 0 (default)." + :group 'helm-command + :type 'boolean) + +(defcustom helm-M-x-always-save-history nil + "`helm-M-x' Save command in `extended-command-history' even when it fail." + :group 'helm-command + :type 'boolean) + +(defcustom helm-M-x-reverse-history nil + "The history source of `helm-M-x' appear in second position when non--nil." + :group 'helm-command + :type 'boolean) + +(defcustom helm-M-x-fuzzy-match nil + "Enable fuzzy matching in `helm-M-x' when non--nil.") + + +;;; Faces +;; +;; +(defgroup helm-command-faces nil + "Customize the appearance of helm-command." + :prefix "helm-" + :group 'helm-command + :group 'helm-faces) + +(defface helm-M-x-key '((t (:foreground "orange" :underline t))) + "Face used in helm-M-x to show keybinding." + :group 'helm-command-faces) + + +(defvar helm-M-x-input-history nil) + +(defvar helm-M-x-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-M-x-help) + map) + "Keymap for `helm-M-x'.") + + +(cl-defun helm-M-x-get-major-mode-command-alist (mode-map) + "Return alist of MODE-MAP." + (cl-loop for key being the key-seqs of mode-map using (key-bindings com) + for str-key = (key-description key) + for ismenu = (string-match "" str-key) + unless ismenu collect (cons str-key com))) + +(defun helm-get-mode-map-from-mode (mode) + "Guess the mode-map name according to MODE. +Some modes don't use conventional mode-map name +so we need to guess mode-map name. e.g python-mode ==> py-mode-map. +Return nil if no mode-map found." + (cl-loop ;; Start with a conventional mode-map name. + with mode-map = (intern-soft (format "%s-map" mode)) + with mode-string = (symbol-name mode) + with mode-name = (replace-regexp-in-string "-mode" "" mode-string) + while (not mode-map) + for count downfrom (length mode-name) + ;; Return when no result after parsing entire string. + when (eq count 0) return nil + for sub-name = (substring mode-name 0 count) + do (setq mode-map (intern-soft (format "%s-map" (concat sub-name "-mode")))) + finally return mode-map)) + +(defun helm-M-x-current-mode-map-alist () + "Return mode-map alist of current `major-mode'." + (let ((map (helm-get-mode-map-from-mode major-mode))) + (when (and map (boundp map)) + (helm-M-x-get-major-mode-command-alist (symbol-value map))))) + + +(defun helm-M-x-transformer-1 (candidates &optional sort) + "Transformer function to show bindings in emacs commands. +Show global bindings and local bindings according to current `major-mode'. +If SORT is non nil sort list with `helm-generic-sort-fn'. +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)) + collect + (cons (cond ((and (string-match "^M-x" key) local-key) + (format "%s (%s)" + cand (propertize + local-key + 'face 'helm-M-x-key))) + ((string-match "^M-x" key) cand) + (t (format "%s (%s)" + cand (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." + (helm-M-x-transformer-1 candidates (null helm--in-fuzzy))) + +(defun helm-M-x-transformer-hist (candidates _source) + "Transformer function for `helm-M-x' candidates." + (helm-M-x-transformer-1 candidates)) + +(defun helm-M-x--notify-prefix-arg () + ;; Notify a prefix-arg set AFTER calling M-x. + (when prefix-arg + (with-helm-window + (helm-display-mode-line (helm-get-current-source) 'force)))) + +;;;###autoload +(defun helm-M-x () + "Preconfigured `helm' for Emacs commands. +It is `helm' replacement of regular `M-x' `execute-extended-command'. + +Unlike regular `M-x' emacs vanilla `execute-extended-command' command, +the prefix args if needed, are passed AFTER starting `helm-M-x'. + +You can get help on each command by persistent action." + (interactive) + (let* ((history (cl-loop for i in extended-command-history + when (commandp (intern i)) + do (set-text-properties 0 (length i) nil i) + and collect i)) + command sym-com in-help help-cand + (orig-fuzzy-sort-fn helm-fuzzy-sort-fn) + (helm-fuzzy-sort-fn (lambda (candidates source) + (funcall orig-fuzzy-sort-fn candidates source 'real))) + (helm--mode-line-display-prefarg t) + (pers-help #'(lambda (candidate) + (let ((hbuf (get-buffer (help-buffer)))) + (if (and in-help (string= candidate help-cand) + (null helm-persistent-action-use-special-display)) + (progn + ;; When M-x is started from a help buffer, + ;; Don't kill it as it is helm-current-buffer. + (unless (equal hbuf helm-current-buffer) + (kill-buffer hbuf) + (set-window-buffer (get-buffer-window hbuf) + helm-current-buffer)) + (setq in-help nil)) + (helm-describe-function candidate) + (setq in-help t)) + (setq help-cand candidate)))) + (tm (run-at-time 1 0.1 'helm-M-x--notify-prefix-arg))) + (unwind-protect + (let ((msg "Error: Specifying a prefix arg before calling `helm-M-x'")) + (when current-prefix-arg + (ding) + (message "%s" msg) + (while (not (sit-for 1)) + (discard-input)) + (user-error msg)) + (setq current-prefix-arg nil) + (setq command (helm-comp-read + "M-x " obarray + :test 'commandp + :requires-pattern helm-M-x-requires-pattern + :name "Emacs Commands" + :buffer "*helm M-x*" + :persistent-action pers-help + :persistent-help "Describe this command" + :history history + :reverse-history helm-M-x-reverse-history + :del-input nil + :mode-line helm-M-x-mode-line + :must-match t + :fuzzy helm-M-x-fuzzy-match + :nomark t + :keymap helm-M-x-map + :candidates-in-buffer t + :fc-transformer 'helm-M-x-transformer + :hist-fc-transformer 'helm-M-x-transformer-hist))) + (cancel-timer tm) + (setq helm--mode-line-display-prefarg nil)) + (setq sym-com (intern command)) + (setq current-prefix-arg helm-current-prefix-arg) + ;; Avoid having `this-command' set to *exit-minibuffer. + (setq this-command sym-com + ;; Handle C-x z (repeat) Issue #322 + real-this-command sym-com) + (let ((prefix-arg current-prefix-arg)) + ;; This ugly construct is to save history even on error. + (unless helm-M-x-always-save-history + (command-execute sym-com 'record)) + (setq extended-command-history + (cons command (delete command history))) + (when helm-M-x-always-save-history + (command-execute sym-com 'record))))) + +(provide 'helm-command) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-command.el ends here diff --git a/elpa/helm-20150403.101/helm-config.el b/elpa/helm-20150403.101/helm-config.el new file mode 100644 index 00000000..2d4eb23e --- /dev/null +++ b/elpa/helm-20150403.101/helm-config.el @@ -0,0 +1,228 @@ +;;; helm-config.el --- Applications library for `helm.el' -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + + +;;; Require +;; +;; +(require 'easymenu) +(require 'helm-aliases) +(require 'async-bytecomp nil t) + + +(defgroup helm-config nil + "Various configurations for Helm." + :group 'helm) + +(defcustom helm-command-prefix-key "C-x 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 + :set + (lambda (var key) + (when (and (boundp var) (symbol-value var)) + (define-key (current-global-map) + (read-kbd-macro (symbol-value var)) nil)) + (when key + (define-key (current-global-map) + (read-kbd-macro key) 'helm-command-prefix)) + (set var key))) + +(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-config + :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)) + (when (and (boundp map) (keymapp (symbol-value map))) + (when (and (boundp var) (symbol-value var)) + (define-key (symbol-value map) + (read-kbd-macro (symbol-value var)) nil)) + (when key + (define-key (symbol-value map) + (read-kbd-macro key) 'helm-minibuffer-history)))) + (set var key))) + +;;; Command Keymap +;; +;; +(defvar helm-command-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "a") 'helm-apropos) + (define-key map (kbd "e") 'helm-etags-select) + (define-key map (kbd "l") 'helm-locate) + (define-key map (kbd "s") 'helm-surfraw) + (define-key map (kbd "r") 'helm-regexp) + (define-key map (kbd "m") 'helm-man-woman) + (define-key map (kbd "t") 'helm-top) + (define-key map (kbd "/") 'helm-find) + (define-key map (kbd "i") 'helm-semantic-or-imenu) + (define-key map (kbd "") 'helm-lisp-completion-at-point) + (define-key map (kbd "p") 'helm-list-emacs-process) + (define-key map (kbd "C-x r b") 'helm-filtered-bookmarks) + (define-key map (kbd "M-y") 'helm-show-kill-ring) + (define-key map (kbd "C-c ") 'helm-all-mark-rings) + (define-key map (kbd "C-x C-f") 'helm-find-files) + (define-key map (kbd "f") 'helm-multi-files) + (define-key map (kbd "C-:") 'helm-eval-expression-with-eldoc) + (define-key map (kbd "C-,") 'helm-calcul-expression) + (define-key map (kbd "M-x") 'helm-M-x) + (define-key map (kbd "M-s o") 'helm-occur) + (define-key map (kbd "M-g s") 'helm-do-grep) + (define-key map (kbd "c") 'helm-colors) + (define-key map (kbd "F") 'helm-select-xfont) + (define-key map (kbd "8") 'helm-ucs) + (define-key map (kbd "C-c f") 'helm-recentf) + (define-key map (kbd "C-c g") 'helm-google-suggest) + (define-key map (kbd "h i") 'helm-info-at-point) + (define-key map (kbd "h r") 'helm-info-emacs) + (define-key map (kbd "h g") 'helm-info-gnus) + (define-key map (kbd "C-x C-b") 'helm-buffers-list) + (define-key map (kbd "C-x r i") 'helm-register) + (define-key map (kbd "C-c C-x") 'helm-run-external-command) + (define-key map (kbd "b") 'helm-resume) + map)) + +;; Don't override the keymap we just defined with an empty +;; keymap. This also protect bindings changed by the user. +(defvar helm-command-prefix) +(define-prefix-command 'helm-command-prefix) +(fset 'helm-command-prefix helm-command-map) +(setq helm-command-prefix helm-command-map) + + +;;; Menu +;; +;; +(easy-menu-add-item + nil '("Tools") + '("Helm" + ["Find any Files/Buffers" helm-multi-files t] + ["Helm Everywhere (Toggle)" helm-mode t] + ["Helm resume" helm-resume t] + "----" + ("Files" + ["Find files" helm-find-files t] + ["Recent Files" helm-recentf t] + ["Locate" helm-locate t] + ["Search Files with find" helm-find t] + ["Bookmarks" helm-filtered-bookmarks t]) + ("Buffers" + ["Find buffers" helm-buffers-list t]) + ("Commands" + ["Emacs Commands" helm-M-x t] + ["Externals Commands" helm-run-external-command t]) + ("Help" + ["Helm Apropos" helm-apropos t]) + ("Info" + ["Info at point" helm-info-at-point t] + ["Emacs Manual index" helm-info-emacs t] + ["Gnus Manual index" helm-info-gnus t]) + ("Org" + ["Org keywords" helm-org-keywords t] + ["Org headlines" helm-org-headlines t]) + ("Tools" + ["Occur" helm-occur t] + ["Grep" helm-do-grep t] + ["Etags" helm-etags-select t] + ["Lisp complete at point" helm-lisp-completion-at-point t] + ["Browse Kill ring" helm-show-kill-ring t] + ["Browse register" helm-register t] + ["Mark Ring" helm-all-mark-rings t] + ["Regexp handler" helm-regexp t] + ["Colors & Faces" helm-colors t] + ["Show xfonts" helm-select-xfont t] + ["Ucs Symbols" helm-ucs t] + ["Imenu" helm-imenu t] + ["Semantic or Imenu" helm-semantic-or-imenu t] + ["Google Suggest" helm-google-suggest t] + ["Eval expression" helm-eval-expression-with-eldoc t] + ["Calcul expression" helm-calcul-expression t] + ["Man pages" helm-man-woman t] + ["Top externals process" helm-top t] + ["Emacs internals process" helm-list-emacs-process t]) + "----" + ["Preferred Options" helm-configuration t]) + "Spell Checking") + +(easy-menu-add-item nil '("Tools") '("----") "Spell Checking") + + +;;;###autoload +(defun helm-configuration () + "Customize `helm'." + (interactive) + (customize-group "helm")) + + +;;; Fontlock +(cl-dolist (mode '(emacs-lisp-mode lisp-interaction-mode)) + (font-lock-add-keywords + mode + '(("(\\<\\(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) + ("(\\<\\(with-helm-default-directory\\)\\>" 1 font-lock-keyword-face) + ("(\\<\\(with-helm-display-same-window\\)\\>" 1 font-lock-keyword-face) + ("(\\<\\(with-helm-restore-variables\\)\\>" 1 font-lock-keyword-face) + ("(\\<\\(define-helm-type-attribute\\)\\>" 1 font-lock-keyword-face) + ("(\\<\\(helm-multi-key-defun\\)\\>" 1 font-lock-keyword-face) + ("(\\<\\(helm-while-no-input\\)\\>" 1 font-lock-keyword-face) + ("(\\<\\(helm-aif\\)\\>" 1 font-lock-keyword-face)))) + + +;;; Compatibility emacs-24.4+ +;; Inlined from Emacs trunk. +(defalias 'function-put + ;; We don't want people to just use `put' because we can't conveniently + ;; hook into `put' to remap old properties to new ones. But for now, there's + ;; no such remapping, so we just call `put'. + #'(lambda (f prop value) (put f prop value)) + "Set function F's property PROP to VALUE. +The namespace for PROP is shared with symbols. +So far, F can only be a symbol, not a lambda expression.") + + +;;; Load the autoload file +;; It should have been generated either by +;; package.el or the make file. + +(load "helm-autoloads" nil t) + +(provide 'helm-config) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-config.el ends here diff --git a/elpa/helm-20150403.101/helm-dabbrev.el b/elpa/helm-20150403.101/helm-dabbrev.el new file mode 100644 index 00000000..d9cb2872 --- /dev/null +++ b/elpa/helm-20150403.101/helm-dabbrev.el @@ -0,0 +1,338 @@ +;;; helm-dabbrev.el --- Helm implementation of dabbrev. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'helm) +(require 'helm-elisp) ; For show-completion. + +(defgroup helm-dabbrev nil + "Dabbrev related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-dabbrev-always-search-all t + "Always search in all buffers when non--nil. +Note that even if nil, a search in all buffers +will occur if the length of candidates is <= than +`helm-dabbrev-max-length-result'." + :group 'helm-dabbrev + :type 'boolean) + +(defcustom helm-dabbrev-max-length-result 20 + "Max length of candidates before searching in all buffers. +If number of candidates found in current-buffer is <= to this, +search in all buffers. +Have no effect when `helm-dabbrev-always-search-all' is non--nil." + :group 'helm-dabbrev + :type 'integer) + +(defcustom helm-dabbrev-ignored-buffers-regexps + '("\\*helm" "\\*Messages" "\\*Echo Area" "\\*Buffer List") + "List of regexps matching names of buffers that helm-dabbrev should not check." + :group 'helm-dabbrev + :type '(repeat regexp)) + +(defcustom helm-dabbrev-related-buffer-fn #'helm-dabbrev--same-major-mode-p + "A function that decide if a buffer to search in is related to `current-buffer'. +This is actually determined by comparing `major-mode' of the buffer to search +and the `current-buffer'. +The function take one arg, the buffer which is current, look at +`helm-dabbrev--same-major-mode-p' for example. + +When nil all buffers are considered related to `current-buffer'." + :group 'helm-dabbrev + :type 'function) + +(defcustom helm-dabbrev-major-mode-assoc + '((emacs-lisp-mode . lisp-interaction-mode)) + "Major mode association alist. +This allow helm-dabbrev searching in buffers with the associated `major-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. + +When nil check is the searched buffer have same `major-mode' +than the `current-buffer'. +This have no effect when `helm-dabbrev-related-buffer-fn' is nil or of course +bound to a function that doesn't handle this var." + :type '(alist :key-type symbol :value-type symbol) + :group 'helm-dabbrev) + +(defcustom helm-dabbrev-lineno-around 30 + "Search first in this number of lines before an after point." + :group 'helm-dabbrev + :type 'integer) + +(defcustom helm-dabbrev-cycle-threshold nil + "Number of time helm-dabbrev cycle before displaying helm completion. +When nil or 0 disable cycling." + :group 'helm-dabbrev + :type '(choice (const :tag "Cycling disabled" nil) integer)) + +(defcustom helm-dabbrev-case-fold-search 'smart + "Set `case-fold-search' in `helm-dabbrev'. +Same as `helm-case-fold-search' but for `helm-dabbrev'. +Note that this is not affecting searching in helm buffer, +but the 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))) + + +(defvar helm-dabbrev-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-/") 'helm-next-line) + (define-key map (kbd "M-:") 'helm-previous-line) + map)) + +;; Internal +(defvar helm-dabbrev--exclude-current-buffer-flag nil) +(defvar helm-dabbrev--cache nil) +(defvar helm-dabbrev--data nil) +(defvar helm-dabbrev--regexp "\\s-\\|\t\\|[(\[\{\"'`=<$;]\\|\\s\\\\|^") +(cl-defstruct helm-dabbrev-info dabbrev limits iterator) + + +(defun helm-dabbrev--buffer-list () + (cl-loop with lst = (buffer-list) + for buf in (if helm-dabbrev--exclude-current-buffer-flag + (cdr lst) lst) + unless (cl-loop for r in helm-dabbrev-ignored-buffers-regexps + thereis (string-match r (buffer-name buf))) + collect buf)) + +(defun helm-dabbrev--same-major-mode-p (start-buffer) + ;; START-BUFFER is the current-buffer where we start searching. + ;; Determine the major-mode of START-BUFFER as `cur-maj-mode'. + ;; Each time the loop go in another buffer we try to find if its + ;; `major-mode' is: + ;; - same as the `cur-maj-mode' + ;; - derived from `cur-maj-mode' + ;; - have an assoc entry (major-mode . cur-maj-mode) + ;; - have an rassoc entry (cur-maj-mode . major-mode) + ;; - check if one of these entries inherit from another one in + ;; `helm-dabbrev-major-mode-assoc'. + (let* ((cur-maj-mode (with-current-buffer start-buffer major-mode)) + (c-assoc-mode (assq cur-maj-mode helm-dabbrev-major-mode-assoc)) + (c-rassoc-mode (rassq cur-maj-mode helm-dabbrev-major-mode-assoc)) + (o-assoc-mode (assq major-mode helm-dabbrev-major-mode-assoc)) + (o-rassoc-mode (rassq major-mode helm-dabbrev-major-mode-assoc)) + (cdr-c-assoc-mode (cdr c-assoc-mode)) + (cdr-o-assoc-mode (cdr o-assoc-mode))) + (or (eq major-mode cur-maj-mode) + (derived-mode-p cur-maj-mode) + (or (eq cdr-c-assoc-mode major-mode) + (eq (car c-rassoc-mode) major-mode) + (eq (cdr (assq cdr-c-assoc-mode helm-dabbrev-major-mode-assoc)) + major-mode) + (eq (car (rassq cdr-c-assoc-mode helm-dabbrev-major-mode-assoc)) + major-mode)) + (or (eq cdr-o-assoc-mode cur-maj-mode) + (eq (car o-rassoc-mode) cur-maj-mode) + (eq (cdr (assq cdr-o-assoc-mode helm-dabbrev-major-mode-assoc)) + cur-maj-mode) + (eq (car (rassq cdr-o-assoc-mode helm-dabbrev-major-mode-assoc)) + cur-maj-mode))))) + +(defun helm-dabbrev--collect (str limit ignore-case all) + (let* ((case-fold-search ignore-case) + (buffer1 (current-buffer)) ; start buffer. + (minibuf (minibufferp buffer1)) + result pos-before pos-after + (search-and-store + #'(lambda (pattern direction) + (while (cl-case direction + (1 (search-forward pattern nil t)) + (-1 (search-backward pattern nil t)) + (2 (let ((pos + (save-excursion + (forward-line + helm-dabbrev-lineno-around) + (point)))) + (setq pos-after pos) + (search-forward pattern pos t))) + (-2 (let ((pos + (save-excursion + (forward-line + (- helm-dabbrev-lineno-around)) + (point)))) + (setq pos-before pos) + (search-backward pattern pos t)))) + (let* ((match-1 (helm-aif (thing-at-point 'symbol) + ;; `thing-at-point' returns + ;; the quote outside of e-lisp mode, + ;; e.g in message mode, + ;; `foo' => foo' + ;; but in e-lisp like modes: + ;; `foo' => foo + ;; so remove it [1]. + (replace-regexp-in-string + "[']\\'" "" (substring-no-properties it)))) + (match-2 (helm-aif (thing-at-point 'filename) + ;; Same as in [1]. + (replace-regexp-in-string + "[']\\'" "" (substring-no-properties it)))) + (lst (if (string= match-1 match-2) + (list match-1) + (list match-1 match-2)))) + (cl-loop for match in lst + unless (or (string= str match) + (member match result)) + do (push match result))))))) + (cl-loop for buf in (if all (helm-dabbrev--buffer-list) + (list (current-buffer))) + + do (with-current-buffer buf + (when (or minibuf ; check against all buffers when in minibuffer. + (if helm-dabbrev-related-buffer-fn + (funcall helm-dabbrev-related-buffer-fn buffer1) + t)) + (save-excursion + ;; Start searching before thing before point. + (goto-char (- (point) (length str))) + ;; Search the last 30 lines before point. + (funcall search-and-store str -2)) ; store pos [1] + (save-excursion + ;; Search the next 30 lines after point. + (funcall search-and-store str 2)) ; store pos [2] + (save-excursion + ;; Search all before point. + (goto-char pos-before) ; start from [1] + (funcall search-and-store str -1)) + (save-excursion + ;; Search all after point. + (goto-char pos-after) ; start from [2] + (funcall search-and-store str 1)))) + when (> (length result) limit) return (nreverse result) + finally return (nreverse result)))) + +(defun helm-dabbrev--get-candidates (abbrev) + (cl-assert abbrev nil "[No Match]") + (with-current-buffer (current-buffer) + (let* ((dabbrev-get #'(lambda (str all-bufs) + (helm-dabbrev--collect + str helm-candidate-number-limit + (cl-case helm-dabbrev-case-fold-search + (smart (helm-set-case-fold-search-1 abbrev)) + (t helm-dabbrev-case-fold-search)) + all-bufs))) + (lst (funcall dabbrev-get abbrev helm-dabbrev-always-search-all))) + (if (and (not helm-dabbrev-always-search-all) + (<= (length lst) helm-dabbrev-max-length-result)) + ;; Search all but don't recompute current-buffer. + (let ((helm-dabbrev--exclude-current-buffer-flag t)) + (append lst (funcall dabbrev-get abbrev 'all-bufs))) + lst)))) + +(defun helm-dabbrev-default-action (candidate) + (with-helm-current-buffer + (let* ((limits (helm-bounds-of-thing-before-point + helm-dabbrev--regexp)) + (beg (car limits)) + (end (point))) + (run-with-timer + 0.01 nil + 'helm-insert-completion-at-point + beg end candidate)))) + +;;;###autoload +(defun helm-dabbrev () + (interactive) + (let ((dabbrev (helm-thing-before-point nil helm-dabbrev--regexp)) + (limits (helm-bounds-of-thing-before-point helm-dabbrev--regexp)) + (enable-recursive-minibuffers t) + (cycling-disabled-p (or (null helm-dabbrev-cycle-threshold) + (zerop helm-dabbrev-cycle-threshold))) + (helm-execute-action-at-once-if-one t) + (helm-quit-if-no-candidate + #'(lambda () + (message "[Helm-dabbrev: No expansion found]")))) + (cl-assert (and (stringp dabbrev) (not (string= dabbrev ""))) + nil "[Helm-dabbrev: Nothing found before point]") + (when (and + ;; have been called at least once. + (helm-dabbrev-info-p helm-dabbrev--data) + ;; But user have moved with some other command + ;; in the meaning time. + (not (eq last-command 'helm-dabbrev))) + (setq helm-dabbrev--data nil)) + (when cycling-disabled-p + (setq helm-dabbrev--cache (helm-dabbrev--get-candidates dabbrev))) + (unless (or cycling-disabled-p + (helm-dabbrev-info-p helm-dabbrev--data)) + (setq helm-dabbrev--cache (helm-dabbrev--get-candidates dabbrev)) + (setq helm-dabbrev--data (make-helm-dabbrev-info + :dabbrev dabbrev + :limits limits + :iterator + (helm-iter-list + (cl-loop for i in helm-dabbrev--cache when + (and i (string-match + (concat "^" (regexp-quote dabbrev)) i)) + collect i into selection + when (and selection + (= (length selection) + helm-dabbrev-cycle-threshold)) + ;; When selection len reach + ;; `helm-dabbrev-cycle-threshold' + ;; return selection. + return selection + ;; selection len never reach + ;; `helm-dabbrev-cycle-threshold' + ;; return selection. + finally return selection))))) + (let ((iter (and (helm-dabbrev-info-p helm-dabbrev--data) + (helm-dabbrev-info-iterator helm-dabbrev--data))) + deactivate-mark) + (helm-aif (and iter (helm-iter-next iter)) + (progn + (helm-insert-completion-at-point + (car (helm-dabbrev-info-limits helm-dabbrev--data)) + (cdr limits) it) + ;; Move already tried candidates to end of list. + (setq helm-dabbrev--cache (append (remove it helm-dabbrev--cache) + (list it)))) + (unless cycling-disabled-p + (delete-region (car limits) (point)) + (setq dabbrev (helm-dabbrev-info-dabbrev helm-dabbrev--data) + limits (helm-dabbrev-info-limits helm-dabbrev--data)) + (setq helm-dabbrev--data nil) + (insert dabbrev)) + (with-helm-show-completion (car limits) (cdr limits) + (helm :sources (helm-build-in-buffer-source "Dabbrev Expand" + :data helm-dabbrev--cache + :persistent-action 'ignore + :persistent-help "DoNothing" + :keymap helm-dabbrev-map + :action 'helm-dabbrev-default-action) + :buffer "*helm dabbrev*" + :input (concat "^" dabbrev " ") + :resume 'noresume + :allow-nest t)))))) + +(provide 'helm-dabbrev) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-dabbrev.el ends here diff --git a/elpa/helm-20150403.101/helm-elisp-package.el b/elpa/helm-20150403.101/helm-elisp-package.el new file mode 100644 index 00000000..5afd362b --- /dev/null +++ b/elpa/helm-20150403.101/helm-elisp-package.el @@ -0,0 +1,297 @@ +;;; helm-elisp-package.el --- helm interface for package.el -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'package) + +;; internals vars +(defvar helm-el-package--show-only 'all) +(defvar helm-el-package--initialized-p nil) +(defvar helm-el-package--tabulated-list nil) +(defvar helm-el-package--upgrades nil) +(defvar helm-el-package--removable-packages nil) + +(defun helm-el-package--init () + (when (null package-alist) + (setq helm-el-package--show-only 'all)) + (when (fboundp 'package--removable-packages) + (setq helm-el-package--removable-packages + (package--removable-packages))) + (save-selected-window + (list-packages helm-el-package--initialized-p) + (setq helm-el-package--initialized-p t) + (message nil)) + (helm-init-candidates-in-buffer + 'global + (with-current-buffer (get-buffer "*Packages*") + (setq helm-el-package--tabulated-list tabulated-list-entries) + (buffer-string))) + (setq helm-el-package--upgrades (helm-el-package-menu--find-upgrades)) + (if helm-force-updating-p + (message "Refreshing packages list done") + (setq helm-el-package--show-only 'all)) + (kill-buffer "*Packages*")) + +(defun helm-el-package-describe (candidate) + (let ((id (get-text-property 0 'tabulated-list-id candidate))) + (describe-package (if (fboundp 'package-desc-name) + (package-desc-name id) + (car id))))) + +(defun helm-el-package-install-1 (pkg-list) + (cl-loop with mkd = pkg-list + for p in mkd + for id = (get-text-property 0 'tabulated-list-id p) + do (package-install + (if (fboundp 'package-desc-name) + (package-desc-name id) + (car id))) + collect (if (fboundp 'package-desc-full-name) + id + (car id)) + into installed-list + finally do (progn + (when (boundp 'package-selected-packages) + (customize-save-variable + 'package-selected-packages + (append (mapcar 'package-desc-name installed-list) + package-selected-packages))) + (if (fboundp 'package-desc-full-name) + (message (format "%d packages installed:\n(%s)" + (length installed-list) + (mapconcat #'package-desc-full-name + installed-list ", "))) + (message (format "%d packages installed:\n(%s)" + (length installed-list) + (mapconcat 'symbol-name installed-list ", "))))))) + +(defun helm-el-package-install (_candidate) + (helm-el-package-install-1 (helm-marked-candidates))) + +(defun helm-el-package-uninstall-1 (pkg-list) + (cl-loop with mkd = pkg-list + for p in mkd + for id = (get-text-property 0 'tabulated-list-id p) + do + (condition-case-unless-debug err + (with-no-warnings + (if (fboundp 'package-desc-full-name) + ;; emacs 24.4 + (package-delete id) + ;; emacs 24.3 + (package-delete (symbol-name (car id)) + (package-version-join (cdr id))))) + (error (message (cadr err)))) + unless (assoc (elt id 1) package-alist) + collect (if (fboundp 'package-desc-full-name) + id + (cons (symbol-name (car id)) + (package-version-join (cdr id)))) + into delete-list + finally do (if delete-list + (if (fboundp 'package-desc-full-name) + ;; emacs 24.4 + (message (format "%d packages deleted:\n(%s)" + (length delete-list) + (mapconcat #'package-desc-full-name + delete-list ", "))) + ;; emacs 24.3 + (message (format "%d packages deleted:\n(%s)" + (length delete-list) + (mapconcat (lambda (x) + (concat (car x) "-" (cdr x))) + delete-list ", "))) + ;; emacs 24.3 doesn't update + ;; its `package-alist' after deleting. + (cl-loop for p in package-alist + when (assq (symbol-name (car p)) delete-list) + do (setq package-alist (delete p package-alist)))) + "No package deleted"))) + +(defun helm-el-package-uninstall (_candidate) + (helm-el-package-uninstall-1 (helm-marked-candidates))) + +(defun helm-el-package-menu--find-upgrades () + (cl-loop for entry in helm-el-package--tabulated-list + for pkg-desc = (car entry) + for status = (package-desc-status pkg-desc) + when (member status '("installed" "unsigned" "dependency")) + collect pkg-desc + into installed + when (member status '("available" "new")) + collect (cons (package-desc-name pkg-desc) pkg-desc) + into available + finally return + (cl-loop for pkg in installed + for avail-pkg = (assq (package-desc-name pkg) available) + when (and avail-pkg + (version-list-< (package-desc-version pkg) + (package-desc-version + (cdr avail-pkg)))) + collect avail-pkg))) + +(defun helm-el-package-upgrade-1 (pkg-list) + (cl-loop for p in pkg-list + for pkg-desc = (car p) + for upgrade = (cdr (assq (package-desc-name pkg-desc) + helm-el-package--upgrades)) + do + (cond ((null upgrade) + (ignore)) + ((equal pkg-desc upgrade) + ;;Install. + (package-install pkg-desc)) + (t + ;; Delete. + (if (boundp 'package-selected-packages) + (with-no-warnings + (package-delete pkg-desc t t)) + (package-delete pkg-desc)))))) + +(defun helm-el-package-upgrade (_candidate) + (helm-el-package-upgrade-1 + (cl-loop with pkgs = (helm-marked-candidates) + for p in helm-el-package--tabulated-list + for pkg = (car p) + if (member (symbol-name (package-desc-name pkg)) pkgs) + collect p))) + +(defun helm-el-package-upgrade-all () + (if helm-el-package--upgrades + (with-helm-display-marked-candidates + helm-marked-buffer-name (mapcar (lambda (x) (symbol-name (car x))) + helm-el-package--upgrades) + (when (y-or-n-p "Upgrade all packages? ") + (helm-el-package-upgrade-1 helm-el-package--tabulated-list))) + (message "No packages to upgrade actually!"))) + +(defun helm-el-package-upgrade-all-action (_candidate) + (helm-el-package-upgrade-all)) + +(defun helm-el-package--transformer (candidates _source) + (cl-loop for c in candidates + for id = (get-text-property 0 'tabulated-list-id c) + for name = (if (fboundp 'package-desc-name) + (package-desc-name id) + (car id)) + for installed-p = (assq name package-alist) + for upgrade-p = (assq name helm-el-package--upgrades) + for user-installed-p = (and (boundp 'package-selected-packages) + (memq name package-selected-packages)) + do (when user-installed-p (put-text-property 0 2 'display "S " c)) + do (when (memq name helm-el-package--removable-packages) + (put-text-property 0 2 'display "U " c) + (put-text-property + 2 (+ (length (symbol-name name)) 2) + 'face 'font-lock-variable-name-face c)) + for cand = (cons c (car (split-string c))) + when (or (and upgrade-p + (eq helm-el-package--show-only 'upgrade)) + (and installed-p + (eq helm-el-package--show-only 'installed)) + (and (not installed-p) + (eq helm-el-package--show-only 'uninstalled)) + (eq helm-el-package--show-only 'all)) + collect cand)) + +(defun helm-el-package-show-upgrade () + (interactive) + (with-helm-alive-p + (setq helm-el-package--show-only 'upgrade) + (helm-update))) + +(defun helm-el-package-show-installed () + (interactive) + (with-helm-alive-p + (setq helm-el-package--show-only 'installed) + (helm-update))) + +(defun helm-el-package-show-all () + (interactive) + (with-helm-alive-p + (setq helm-el-package--show-only 'all) + (helm-update))) + +(defun helm-el-package-show-uninstalled () + (interactive) + (with-helm-alive-p + (setq helm-el-package--show-only 'uninstalled) + (helm-update))) + +(defvar helm-el-package-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-I") 'helm-el-package-show-installed) + (define-key map (kbd "M-U") 'helm-el-package-show-upgrade) + (define-key map (kbd "M-A") 'helm-el-package-show-all) + (define-key map (kbd "C-c ?") 'helm-el-package-help) + map)) + +(defvar helm-source-list-el-package nil) +(defclass helm-list-el-package-source (helm-source-in-buffer) + ((init :initform 'helm-el-package--init) + (get-line :initform 'buffer-substring) + (filtered-candidate-transformer :initform 'helm-el-package--transformer) + (action-transformer + :initform + (lambda (actions candidate) + (let ((pkg-desc (get-text-property + 0 'tabulated-list-id candidate)) + (acts (if helm-el-package--upgrades + (append actions '(("Upgrade all packages" + . helm-el-package-upgrade-all-action))) + actions))) + (cond ((cdr (assq (package-desc-name pkg-desc) + helm-el-package--upgrades)) + (append '(("Upgrade package" . helm-el-package-upgrade)) acts)) + ((package-installed-p (package-desc-name pkg-desc)) + (append acts '(("Reinstall package" . helm-el-package-reinstall) + ("Uninstall" . helm-el-package-uninstall)))) + (t (append acts '(("Install" . helm-el-package-install)))))))) + (mode-line :initform helm-el-package-mode-line) + (keymap :initform helm-el-package-map) + (update :initform 'helm-el-package--update) + (candidate-number-limit :initform 9999) + (action :initform '(("Describe" . helm-el-package-describe))))) + +(defun helm-el-package--update () + (setq helm-el-package--initialized-p nil)) + +(defun helm-el-package-reinstall (_pkg) + (cl-loop for p in (helm-marked-candidates) + for pkg-desc = (get-text-property 0 'tabulated-list-id p) + for name = (package-desc-name pkg-desc) + do (if (fboundp 'package-reinstall) + (package-reinstall name) + (package-delete pkg-desc) + (package-install name)))) + +;;;###autoload +(defun helm-list-elisp-packages (arg) + (interactive "P") + (when arg (setq helm-el-package--initialized-p nil)) + (unless helm-source-list-el-package + (setq helm-source-list-el-package + (helm-make-source "list packages" 'helm-list-el-package-source))) + (helm :sources 'helm-source-list-el-package + :buffer "*helm list packages*")) + +(provide 'helm-elisp-package) + +;;; helm-elisp-package.el ends here diff --git a/elpa/helm-20150403.101/helm-elisp.el b/elpa/helm-20150403.101/helm-elisp.el new file mode 100644 index 00000000..6c69411e --- /dev/null +++ b/elpa/helm-20150403.101/helm-elisp.el @@ -0,0 +1,829 @@ +;;; helm-elisp.el --- Elisp symbols completion for helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'helm-info) +(require 'helm-eval) +(require 'helm-files) +(require 'advice) + + +(defgroup helm-elisp nil + "Elisp related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-turn-on-show-completion t + "Display candidate in buffer while moving selection when non--nil." + :group 'helm-elisp + :type 'boolean) + +(defcustom helm-show-completion-use-special-display t + "A special display will be used in lisp completion if non--nil. +All functions that are wrapped in macro `with-helm-show-completion' +will be affected." + :group 'helm-elisp + :type 'boolean) + +(defcustom helm-show-completion-min-window-height 7 + "Minimum completion window height used in show completion. +This is used in macro `with-helm-show-completion'." + :group 'helm-elisp + :type 'integer) + +(defcustom helm-lisp-quoted-function-list + '(funcall apply mapc cl-mapc mapcar cl-mapcar + 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 '." + :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 ." + :group 'helm-elisp + :type '(repeat (choice symbol))) + +(defcustom helm-apropos-fuzzy-match nil + "Enable fuzzy matching for `helm-apropos' when non-nil." + :group 'helm-elisp + :type 'boolean) + +(defcustom helm-lisp-fuzzy-completion nil + "Enable fuzzy matching in emacs-lisp completion when non-nil. +NOTE: This enable fuzzy matching in helm native implementation of +elisp completion, but not on helmized elisp completion, i.e +fuzzy completion is not available in `completion-at-point'." + :group 'helm-elisp + :type 'boolean) + +(defcustom helm-apropos-function-list '(helm-def-source--emacs-commands + helm-def-source--emacs-functions + helm-def-source--eieio-classes + helm-def-source--eieio-generic + helm-def-source--emacs-variables + helm-def-source--emacs-faces + helm-def-source--helm-attributes) + "A list of functions that build helm sources to use in `helm-apropos'." + :group 'helm-elisp + :type '(repeat (choice symbol))) + + +;;; Faces +;; +;; +(defgroup helm-elisp-faces nil + "Customize the appearance of helm-elisp." + :prefix "helm-" + :group 'helm-elisp + :group 'helm-faces) + +(defface helm-lisp-show-completion + '((t (:background "DarkSlateGray"))) + "Face used for showing candidates in `helm-lisp-completion'." + :group 'helm-elisp-faces) + +(defface helm-lisp-completion-info + '((t (:foreground "red"))) + "Face used for showing info in `helm-lisp-completion'." + :group 'helm-elisp-faces) + + +;;; Show completion. +;; +;; Provide show completion with macro `with-helm-show-completion'. + +(defvar helm-show-completion-overlay nil) + +;; Called each time cursor move in helm-buffer. +(defun helm-show-completion () + (with-helm-current-buffer + (overlay-put helm-show-completion-overlay + 'display (substring-no-properties + (helm-get-selection))))) + +(defun helm-show-completion-init-overlay (beg end) + (when (and helm-turn-on-show-completion beg end) + (setq helm-show-completion-overlay (make-overlay beg end)) + (overlay-put helm-show-completion-overlay + 'face 'helm-lisp-show-completion))) + +(defun helm-show-completion-display-function (buffer &rest _args) + "A special resized helm window is used depending on position in BUFFER." + (with-selected-window (selected-window) + (if (window-dedicated-p) + (helm-default-display-buffer buffer) + (let* ((screen-size (+ (count-screen-lines (window-start) (point) t) + 1 ; mode-line + (if header-line-format 1 0))) ; header-line + (def-size (- (window-height) + helm-show-completion-min-window-height)) + (upper-height (max window-min-height (min screen-size def-size))) + split-window-keep-point) + (recenter -1) + (set-window-buffer (if (active-minibuffer-window) + (minibuffer-selected-window) + (split-window nil upper-height)) + buffer))))) + +(defmacro with-helm-show-completion (beg end &rest body) + "Show helm candidate in an overlay at point. +BEG and END are the beginning and end position of the current completion +in `helm-current-buffer'. +BODY is an helm call where we want to enable show completion. +If `helm-turn-on-show-completion' is nil just do nothing." + (declare (indent 2) (debug t)) + `(let ((helm-move-selection-after-hook + (and helm-turn-on-show-completion + (append (list 'helm-show-completion) + helm-move-selection-after-hook)))) + (with-helm-temp-hook 'helm-after-initialize-hook + (with-helm-buffer + (set (make-local-variable 'helm-display-function) + (if helm-show-completion-use-special-display + 'helm-show-completion-display-function + 'helm-default-display-buffer)))) + (unwind-protect + (progn + (helm-show-completion-init-overlay ,beg ,end) + ,@body) + (when (and helm-turn-on-show-completion + helm-show-completion-overlay + (overlayp helm-show-completion-overlay)) + (delete-overlay helm-show-completion-overlay))))) + + +;;; Lisp symbol completion. +;; +;; +(defun helm-lisp-completion--predicate-at-point (beg) + ;; Return a predicate for `all-completions'. + (let ((fn-sym-p (lambda () + (or + (and (eq (char-before) ?\ ) + (save-excursion + (skip-syntax-backward " " (point-at-bol)) + (memq (symbol-at-point) + helm-lisp-unquoted-function-list))) + (and (eq (char-before) ?\') + (save-excursion + (forward-char -1) + (eq (char-before) ?\#))))))) + (save-excursion + (goto-char beg) + (if (or + ;; Complete on all symbols in non--lisp modes (logs mail etc..) + (not (memq major-mode '(emacs-lisp-mode + lisp-interaction-mode + inferior-emacs-lisp-mode))) + (not (or (funcall fn-sym-p) + (and (eq (char-before) ?\') + (save-excursion + (forward-char (if (funcall fn-sym-p) -2 -1)) + (skip-syntax-backward " " (point-at-bol)) + (memq (symbol-at-point) + helm-lisp-quoted-function-list))) + (eq (char-before) ?\())) ; no paren before str. + ;; Looks like we are in a let statement. + (condition-case nil + (progn (up-list -2) (forward-char 1) + (eq (char-after) ?\()) + (error nil))) + (lambda (sym) + (or (boundp sym) (fboundp sym) (symbol-plist sym))) + #'fboundp)))) + +(defun helm-thing-before-point (&optional limits regexp) + "Return symbol name before point. +If REGEXP is specified return what REGEXP find before point. +By default match the beginning of symbol before point. +With LIMITS arg specified return the beginning and end position +of symbol before point." + (save-excursion + (let (beg + (end (point)) + (boundary (field-beginning nil nil (point-at-bol)))) + (if (re-search-backward (or regexp "\\_<") boundary t) + (setq beg (match-end 0)) + (setq beg boundary)) + (unless (= beg end) + (if limits + (cons beg end) + (buffer-substring-no-properties beg end)))))) + +(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\)." + (helm-thing-before-point 'limits regexp)) + +(defun helm-insert-completion-at-point (beg end str) + ;; When there is no space after point + ;; we are completing inside a symbol or + ;; after a partial symbol with the next arg aside + ;; without space, in this case mark the region. + ;; deleting it would remove the + ;; next arg which is unwanted. + (delete-region beg end) + (insert str) + (let ((pos (cdr (or (bounds-of-thing-at-point 'symbol) + ;; needed for helm-dabbrev. + (bounds-of-thing-at-point 'filename))))) + (when (and pos (< (point) pos)) + (push-mark pos t t)))) + +(defvar helm-lisp-completion--cache nil) +(defvar helm-lgst-len nil) +;;;###autoload +(defun helm-lisp-completion-at-point () + "Helm lisp symbol completion at point." + (interactive) + (setq helm-lgst-len 0) + (let* ((target (helm-thing-before-point)) + (beg (car (helm-bounds-of-thing-before-point))) + (end (point)) + (pred (and beg (helm-lisp-completion--predicate-at-point beg))) + (loc-vars (and (fboundp 'elisp--local-variables) + (ignore-errors + (mapcar #'symbol-name (elisp--local-variables))))) + (glob-syms (and target pred (all-completions target obarray pred))) + (candidates (append loc-vars glob-syms)) + (helm-quit-if-no-candidate t) + (helm-execute-action-at-once-if-one t) + (enable-recursive-minibuffers t)) + (setq helm-lisp-completion--cache (cl-loop for sym in candidates + for len = (length sym) + when (> len helm-lgst-len) + do (setq helm-lgst-len len) + collect sym)) + (if candidates + (with-helm-show-completion beg end + ;; Overlay is initialized now in helm-current-buffer. + (helm + :sources (helm-build-in-buffer-source "Lisp completion" + :data helm-lisp-completion--cache + :persistent-action 'helm-lisp-completion-persistent-action + :nomark t + :fuzzy-match helm-lisp-fuzzy-completion + :persistent-help "Show brief doc in mode-line" + :filtered-candidate-transformer 'helm-lisp-completion-transformer + :action `(lambda (candidate) + (with-helm-current-buffer + (run-with-timer + 0.01 nil + 'helm-insert-completion-at-point + ,beg ,end candidate)))) + :input (if helm-lisp-fuzzy-completion + target (concat target " ")) + :resume 'noresume + :buffer "*helm lisp completion*" + :allow-nest t)) + (message "[No Match]")))) + +(defun helm-lisp-completion-persistent-action (candidate) + (let ((cursor-in-echo-area t) + mode-line-in-non-selected-windows) + (helm-show-info-in-mode-line + (propertize + (helm-get-first-line-documentation + (intern candidate)) + 'face 'helm-lisp-completion-info)))) + +(defun helm-lisp-completion-transformer (candidates _source) + "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)") + (generic " (Gen)") + (fbound " (Fun)") + (bound " (Var)") + (face " (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) + "Return first line documentation of symbol SYM. +If SYM is not documented, return \"Not documented\"." + (let ((doc (cond ((fboundp sym) + (documentation sym t)) + ((boundp sym) + (documentation-property sym 'variable-documentation t)) + ((facep sym) + (face-documentation sym)) + (t nil)))) + (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")) + "Not documented"))) + +;;; File completion. +;; +;; Complete file name at point. + +;;;###autoload +(defun helm-complete-file-name-at-point (&optional force) + "Complete file name at point." + (interactive) + (require 'helm-mode) + (let* ((tap (thing-at-point 'filename)) + beg + (init (and tap + (or force + (save-excursion + (end-of-line) + (search-backward tap (point-at-bol) t) + (setq beg (point)) + (looking-back "[^'`( ]"))) + (expand-file-name + (substring-no-properties tap)))) + (end (point)) + (helm-quit-if-no-candidate t) + (helm-execute-action-at-once-if-one t) + completion) + (with-helm-show-completion beg end + (setq completion (helm-read-file-name "FileName: " + :initial-input init))) + (when (and completion (not (string= completion ""))) + (delete-region beg end) (insert (if (string-match "^~" tap) + (abbreviate-file-name completion) + completion))))) + +;;;###autoload +(defun helm-lisp-indent () + ;; It is meant to use with `helm-define-multi-key' which + ;; does not support args for functions yet, so use `current-prefix-arg' + ;; for now instead of (interactive "P"). + (interactive) + (let ((tab-always-indent (or (eq tab-always-indent 'complete) + tab-always-indent))) + (indent-for-tab-command current-prefix-arg))) + +;;;###autoload +(defun helm-lisp-completion-or-file-name-at-point () + "Complete lisp symbol or filename at point. +Filename completion happen if string start after or between a double quote." + (interactive) + (let* ((tap (thing-at-point 'filename))) + (if (and tap (save-excursion + (end-of-line) + (search-backward tap (point-at-bol) t) + (looking-back "[^'`( ]"))) + (helm-complete-file-name-at-point) + (helm-lisp-completion-at-point)))) + + +;;; Apropos +;; +;; +(defun helm-apropos-init (test default) + "Init candidates buffer for `helm-apropos' sources." + (require 'helm-help) + (helm-init-candidates-in-buffer 'global + (let ((default-symbol (and (stringp default) + (intern-soft default))) + (symbols (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-default-sort-fn (candidates _source) + (if (string= helm-pattern "") + candidates + (sort candidates #'helm-generic-sort-fn))) + +(defun helm-def-source--emacs-variables (&optional default) + (helm-build-in-buffer-source "Variables" + :init `(lambda () + (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) + :nomark t + :action '(("Describe Variable" . helm-describe-variable) + ("Find Variable" . helm-find-variable) + ("Info lookup" . helm-info-lookup-symbol) + ("Set variable" . helm-set-variable)))) + +(defun helm-def-source--emacs-faces (&optional default) + (helm-build-in-buffer-source "Faces" + :init (lambda () (helm-apropos-init-faces default)) + :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)))))) + :nomark t + :action (lambda (candidate) + (describe-face (intern candidate))))) + +(defun helm-def-source--helm-attributes (&optional _default) + (helm-build-sync-source "Helm attributes" + :candidates (lambda () + (mapcar 'symbol-name helm-attributes)) + :fuzzy-match helm-apropos-fuzzy-match + :nomark t + :action (lambda (candidate) + (let (special-display-buffer-names + special-display-regexps + helm-persistent-action-use-special-display) + (with-output-to-temp-buffer "*Help*" + (princ (get (intern candidate) 'helm-attrdoc))))))) + +(defun helm-def-source--emacs-commands (&optional default) + (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) + :nomark t + :action '(("Describe Function" . helm-describe-function) + ("Find Function" . helm-find-function) + ("Info lookup" . helm-info-lookup-symbol)))) + +(defun helm-def-source--emacs-functions (&optional default) + (helm-build-in-buffer-source "Functions" + :init `(lambda () + (helm-apropos-init #'(lambda (x) + (and (fboundp x) + (not (commandp x)) + (not (generic-p x)) + (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) + :nomark t + :action '(("Describe Function" . helm-describe-function) + ("Find Function" . helm-find-function) + ("Info lookup" . helm-info-lookup-symbol)))) + +(defun helm-def-source--eieio-classes (&optional default) + (helm-build-in-buffer-source "Classes" + :init `(lambda () + (helm-apropos-init #'(lambda (x) + (class-p x)) + ,default)) + :fuzzy-match helm-apropos-fuzzy-match + :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) + 'helm-apropos-default-sort-fn) + :nomark t + :action '(("Describe Function" . helm-describe-function) + ("Find Function" . helm-find-function) + ("Info lookup" . helm-info-lookup-symbol)))) + +(defun helm-def-source--eieio-generic (&optional default) + (helm-build-in-buffer-source "Generic functions" + :init `(lambda () + (helm-apropos-init #'(lambda (x) + (generic-p x)) + ,default)) + :fuzzy-match helm-apropos-fuzzy-match + :filtered-candidate-transformer (and (null helm-apropos-fuzzy-match) + 'helm-apropos-default-sort-fn) + :nomark t + :action '(("Describe Function" . helm-describe-function) + ("Find Function" . helm-find-function) + ("Info lookup" . helm-info-lookup-symbol)))) + +(defun helm-info-lookup-symbol (candidate) + (let ((helm-execute-action-at-once-if-one t) + (helm-quit-if-no-candidate + `(lambda () + (message "`%s' Not Documented as a symbol" ,candidate)))) + (helm :sources '(helm-source-info-elisp + helm-source-info-cl + helm-source-info-eieio) + :resume 'noresume + :buffer "*helm lookup*" + :input candidate))) + +;;;###autoload +(defun helm-apropos () + "Preconfigured helm to describe commands, functions, variables and faces." + (interactive) + (let ((default (thing-at-point 'symbol))) + (helm :sources + (mapcar (lambda (func) + (funcall func default)) + helm-apropos-function-list) + :buffer "*helm apropos*" + :preselect (and default (concat "\\_<" (regexp-quote default) "\\_>"))))) + + +;;; Advices +;; +;; +(defvar helm-source-advice + '((name . "Function Advice") + (candidates . helm-advice-candidates) + (action ("Toggle Enable/Disable" . helm-advice-toggle)) + (persistent-action . helm-advice-persistent-action) + (nomark) + (multiline) + (persistent-help . "Describe function / C-u C-j: Toggle advice"))) + +(defun helm-advice-candidates () + (cl-loop for (fname) in ad-advised-functions + for function = (intern fname) + append + (cl-loop for class in ad-advice-classes append + (cl-loop for advice in (ad-get-advice-info-field function class) + for enabled = (ad-advice-enabled advice) + collect + (cons (format + "%s %s %s" + (if enabled "Enabled " "Disabled") + (propertize fname 'face 'font-lock-function-name-face) + (ad-make-single-advice-docstring advice class nil)) + (list function class advice)))))) + +(defun helm-advice-persistent-action (func-class-advice) + (if current-prefix-arg + (helm-advice-toggle func-class-advice) + (describe-function (car func-class-advice)))) + +(defun helm-advice-toggle (func-class-advice) + (cl-destructuring-bind (function _class advice) func-class-advice + (cond ((ad-advice-enabled advice) + (ad-advice-set-enabled advice nil) + (message "Disabled")) + (t + (ad-advice-set-enabled advice t) + (message "Enabled"))) + (ad-activate function) + (and helm-in-persistent-action + (helm-advice-update-current-display-string)))) + +(defun helm-advice-update-current-display-string () + (helm-edit-current-selection + (let ((newword (cond ((looking-at "Disabled") "Enabled") + ((looking-at "Enabled") "Disabled")))) + (when newword + (delete-region (point) (progn (forward-word 1) (point))) + (insert newword))))) + +;;;###autoload +(defun helm-manage-advice () + "Preconfigured `helm' to disable/enable function advices." + (interactive) + (helm-other-buffer 'helm-source-advice "*helm advice*")) + + +;;; Locate elisp library +;; +;; +(defun helm-locate-library-scan-list () + (cl-loop for dir in load-path + when (file-directory-p dir) + append (directory-files dir t (concat (regexp-opt (get-load-suffixes)) + "\\'")) + into lst + finally return (helm-fast-remove-dups lst :test 'equal))) + +;;;###autoload +(defun helm-locate-library () + (interactive) + (helm :sources (helm-build-in-buffer-source "Elisp libraries (Scan)" + :data (lambda () (helm-locate-library-scan-list)) + :fuzzy-match t + :keymap helm-generic-files-map + :match-part (lambda (candidate) + (if helm-ff-transformer-show-only-basename + (helm-basename candidate) candidate)) + :filter-one-by-one (lambda (c) + (if helm-ff-transformer-show-only-basename + (cons (helm-basename c) c) c)) + :action (helm-actions-from-type-file)) + :buffer "*helm locate library*")) + +(defun helm-set-variable (var) + "Set value to VAR interactively." + (let* ((sym (helm-symbolify var)) + (val (default-value sym))) + (set-default sym (eval-minibuffer (format "Set `%s': " var) + (if (or (stringp val) (memq val '(nil t))) + (prin1-to-string val) + (format "'%s" (prin1-to-string val))))))) + + +;;; Type attributes +;; +;; +(let ((actions '(("Describe command" . describe-function) + ("Add command to kill ring" . helm-kill-new) + ("Go to command's definition" . find-function) + ("Debug on entry" . debug-on-entry) + ("Cancel debug on entry" . cancel-debug-on-entry) + ("Trace function" . trace-function) + ("Trace function (background)" . trace-function-background) + ("Untrace function" . untrace-function)))) + (define-helm-type-attribute 'command + `((action ("Call interactively" . helm-call-interactively) + ,@actions) + (coerce . helm-symbolify) + (persistent-action . describe-function)) + "Command. (string or symbol)") + + (define-helm-type-attribute 'function + `((action . ,actions) + (action-transformer helm-transform-function-call-interactively) + (candidate-transformer helm-mark-interactive-functions) + (coerce . helm-symbolify)) + "Function. (string or symbol)")) + +(define-helm-type-attribute 'variable + '((action + ("Describe variable" . describe-variable) + ("Add variable to kill ring" . helm-kill-new) + ("Go to variable's definition" . find-variable) + ("Set variable" . helm-set-variable)) + (coerce . helm-symbolify)) + "Variable.") + +(defun helm-btf--usable-p () + "Return t if current version of `backtrace-frame' accept 2 arguments." + (condition-case nil + (and (backtrace-frame 1 'condition-case) t) + (wrong-number-of-arguments nil))) + +(if (helm-btf--usable-p) ; Check if BTF accept more than one arg. + ;; Emacs 24.4. + (dont-compile + (defvar helm-sexp--last-sexp nil) + ;; This wont work compiled. + (defun helm-sexp-eval-1 () + (interactive) + (unwind-protect + (progn + ;; Trick called-interactively-p into thinking that `cand' is + ;; an interactive call, See `repeat-complex-command'. + (add-hook 'called-interactively-p-functions + #'helm-complex-command-history--called-interactively-skip) + (eval (read helm-sexp--last-sexp))) + (remove-hook 'called-interactively-p-functions + #'helm-complex-command-history--called-interactively-skip))) + + (defun helm-complex-command-history--called-interactively-skip (i _frame1 frame2) + (and (eq 'eval (cadr frame2)) + (eq 'helm-sexp-eval-1 + (cadr (backtrace-frame (+ i 2) #'called-interactively-p))) + 1)) + + (defun helm-sexp-eval (_candidate) + (call-interactively #'helm-sexp-eval-1))) + ;; Emacs 24.3 + (defun helm-sexp-eval (cand) + (let ((sexp (read cand))) + (condition-case err + (if (> (length (remove nil sexp)) 1) + (eval sexp) + (apply 'call-interactively sexp)) + (error (message "Evaluating gave an error: %S" err) + nil))))) + +(define-helm-type-attribute 'sexp + '((action + ("Eval" . (lambda (candidate) + (and (boundp 'helm-sexp--last-sexp) + (setq helm-sexp--last-sexp candidate)) + (run-with-timer 0.1 nil #'helm-sexp-eval candidate))) + ("Edit and eval" . + (lambda (cand) + (minibuffer-with-setup-hook + (lambda () (insert cand)) + (call-interactively #'eval-expression))))) + (persistent-action . helm-sexp-eval)) + "Sexp.") + +(define-helm-type-attribute 'timer + '((action + ("Cancel Timer" . (lambda (_timer) + (let ((mkd (helm-marked-candidates))) + (cl-loop for timer in mkd + do (cancel-timer timer))))) + ("Describe Function" . (lambda (tm) (describe-function (timer--function tm)))) + ("Find Function" . (lambda (tm) (find-function (timer--function tm))))) + (persistent-action . (lambda (tm) (describe-function (timer--function tm)))) + (persistent-help . "Describe Function")) + "Timer.") + + +;;; Elisp Timers. +;; +;; +(defvar helm-source-absolute-time-timers + '((name . "Absolute Time Timers") + (candidates . timer-list) + (filtered-candidate-transformer + . (lambda (candidates _source) + (cl-loop for timer in candidates + collect (cons (helm-elisp--format-timer timer) timer)))) + (allow-dups) + (volatile) + (type . timer))) + +(defvar helm-source-idle-time-timers + '((name . "Idle Time Timers") + (candidates . timer-idle-list) + (allow-dups) + (volatile) + (filtered-candidate-transformer + . (lambda (candidates _source) + (cl-loop for timer in candidates + collect (cons (helm-elisp--format-timer timer) timer)))) + (type . timer))) + +(defun helm-elisp--format-timer (timer) + (format "%s repeat=%s %s(%s)" + (let ((time (timer--time timer))) + (if (timer--idle-delay timer) + (format-time-string "idle-for=%5s" time) + (format-time-string "%m/%d %T" time))) + (or (timer--repeat-delay timer) "nil") + (mapconcat 'identity (split-string + (prin1-to-string (timer--function timer)) + "\n") " ") + (mapconcat 'prin1-to-string (timer--args timer) " "))) + +;;;###autoload +(defun helm-timers () + "Preconfigured `helm' for timers." + (interactive) + (helm-other-buffer '(helm-source-absolute-time-timers + helm-source-idle-time-timers) + "*helm timers*")) + + +;;; Complex command history +;; +;; +(defvar helm-source-complex-command-history + '((name . "Complex Command History") + (candidates . (lambda () + ;; Use cdr to avoid adding + ;; `helm-complex-command-history' here. + (cl-loop for i in command-history + unless (equal i '(helm-complex-command-history)) + collect (prin1-to-string i)))) + (type . sexp))) + +;;;###autoload +(defun helm-complex-command-history () + (interactive) + (helm :sources 'helm-source-complex-command-history + :buffer "*helm complex commands*")) + +(provide 'helm-elisp) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-elisp.el ends here diff --git a/elpa/helm-20150403.101/helm-elscreen.el b/elpa/helm-20150403.101/helm-elscreen.el new file mode 100644 index 00000000..178d37fe --- /dev/null +++ b/elpa/helm-20150403.101/helm-elscreen.el @@ -0,0 +1,79 @@ +;;; helm-elscreen.el -- Elscreen support -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) + +(declare-function elscreen-find-screen-by-buffer "ext:elscreen.el" (buffer &optional create)) +(declare-function elscreen-find-file "ext:elscreen.el" (filename)) +(declare-function elscreen-goto "ext:elscreen.el" (screen)) + +(defun helm-find-buffer-on-elscreen (candidate) + "Open buffer in new screen, if marked buffers open all in elscreens." + (helm-require-or-error 'elscreen 'helm-find-buffer-on-elscreen) + (helm-aif (helm-marked-candidates) + (cl-dolist (i it) + (let ((target-screen (elscreen-find-screen-by-buffer + (get-buffer i) 'create))) + (elscreen-goto target-screen))) + (let ((target-screen (elscreen-find-screen-by-buffer + (get-buffer candidate) 'create))) + (elscreen-goto target-screen)))) + +(defun helm-elscreen-find-file (file) + (helm-require-or-error 'elscreen 'helm-elscreen-find-file) + (elscreen-find-file file)) + +(defvar helm-source-elscreen + '((name . "Elscreen") + (candidates + . (lambda () + (if (cdr (elscreen-get-screen-to-name-alist)) + (sort + (cl-loop for sname in (elscreen-get-screen-to-name-alist) + append (list (format "[%d] %s" (car sname) (cdr sname)))) + #'(lambda (a b) (compare-strings a nil nil b nil nil)))))) + (action + . (("Change Screen" . + (lambda (candidate) + (elscreen-goto (- (aref candidate 1) (aref "0" 0))))) + ("Kill Screen(s)" . + (lambda (candidate) + (cl-dolist (i (helm-marked-candidates)) + (elscreen-goto (- (aref i 1) (aref "0" 0))) + (elscreen-kill)))) + ("Only Screen" . + (lambda (candidate) + (elscreen-goto (- (aref candidate 1) (aref "0" 0))) + (elscreen-kill-others))))))) + +;;;###autoload +(defun helm-elscreen () + "Preconfigured helm to list elscreen." + (interactive) + (helm-other-buffer 'helm-source-elscreen "*Helm Elscreen*")) + +(provide 'helm-elscreen) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-elscreen.el ends here diff --git a/elpa/helm-20150403.101/helm-eshell.el b/elpa/helm-20150403.101/helm-eshell.el new file mode 100644 index 00000000..3d85c3c8 --- /dev/null +++ b/elpa/helm-20150403.101/helm-eshell.el @@ -0,0 +1,246 @@ +;;; helm-eshell.el --- pcomplete and eshell completion for helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;; Enable like this in .emacs: +;; +;; (add-hook 'eshell-mode-hook +;; #'(lambda () +;; (define-key eshell-mode-map [remap pcomplete] 'helm-esh-pcomplete))) +;; + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'helm-elisp) +(require 'helm-regexp) + +(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-bol "esh-mode") +(declare-function eshell-parse-arguments "esh-arg" (beg end)) +(declare-function eshell-backward-argument "esh-mode" (&optional arg)) + +(defvar helm-eshell-history-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-p") 'helm-next-line) + map) + "Keymap for `helm-eshell-history'.") + +(defvar helm-esh-completion-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "TAB") 'helm-next-line) + map) + "Keymap for `helm-esh-pcomplete'.") + +(defclass helm-esh-source (helm-source-sync) + ((init :initform (lambda () + (setq pcomplete-current-completions nil + pcomplete-last-completion-raw nil) + ;; Eshell-command add this hook in all minibuffers + ;; Remove it for the helm one. (Fixed in Emacs24) + (remove-hook 'minibuffer-setup-hook 'eshell-mode))) + (candidates :initform 'helm-esh-get-candidates) + (nomark :initform t) + (persistent-action :initform 'ignore) + (filtered-candidate-transformer + :initform + (lambda (candidates _sources) + (cl-loop + for i in candidates + collect + (cond ((string-match "\\`~/?" helm-ec-target) + (abbreviate-file-name i)) + ((string-match "\\`/" helm-ec-target) i) + (t + (file-relative-name i))) + into lst + finally return (sort lst 'helm-generic-sort-fn)))) + (action :initform 'helm-ec-insert)) + "Helm class to define source for Eshell completion.") + +;; Internal. +(defvar helm-ec-target "") +(defun helm-ec-insert (candidate) + "Replace text at point with CANDIDATE. +The function that call this should set `helm-ec-target' to thing at point." + (let ((pt (point))) + (when (and helm-ec-target + (search-backward helm-ec-target nil t) + (string= (buffer-substring (point) pt) helm-ec-target)) + (delete-region (point) pt))) + (when (string-match "\\`\\*" helm-ec-target) (insert "*")) + (cond ((string-match "\\`~/?" helm-ec-target) + (insert (helm-quote-whitespace (abbreviate-file-name candidate)))) + ((string-match "\\`/" helm-ec-target) + (insert (helm-quote-whitespace candidate))) + (t + (insert (concat (and (string-match "\\`[.]/" helm-ec-target) "./") + (helm-quote-whitespace + (file-relative-name candidate))))))) + +(defun helm-esh-get-candidates () + "Get candidates for eshell completion using `pcomplete'." + (catch 'pcompleted + (with-helm-current-buffer + (let* ((pcomplete-stub) + pcomplete-seen pcomplete-norm-func + pcomplete-args pcomplete-last pcomplete-index + (pcomplete-autolist pcomplete-autolist) + (pcomplete-suffix-list pcomplete-suffix-list) + (table (pcomplete-completions)) + (entry (or (try-completion helm-pattern + (pcomplete-entries)) + helm-pattern))) + (cl-loop ;; expand entry too to be able to compare it with file-cand. + with exp-entry = (and (stringp entry) + (not (string= entry "")) + (file-name-as-directory + (expand-file-name entry default-directory))) + for i in (all-completions pcomplete-stub table) + ;; Transform the related names to abs names. + for file-cand = (and exp-entry + (if (file-remote-p i) i + (expand-file-name + i (file-name-directory entry)))) + ;; Compare them to avoid dups. + for file-entry-p = (and (stringp exp-entry) + (stringp file-cand) + ;; Fix :/tmp/foo/ $ cd foo + (not (file-directory-p file-cand)) + (file-equal-p exp-entry file-cand)) + if (and file-cand (or (file-remote-p file-cand) + (file-exists-p file-cand)) + (not file-entry-p)) + collect file-cand into ls + else + ;; Avoid adding entry here. + unless file-entry-p collect i into ls + finally return + (if (and exp-entry + (file-directory-p exp-entry) + ;; If the car of completion list is + ;; an executable, probably we are in + ;; command completion, so don't add a + ;; possible file related entry here. + (and ls (not (executable-find (car ls)))) + ;; Don't add entry if already in prompt. + (not (file-equal-p exp-entry pcomplete-stub))) + (append (list exp-entry) + ;; Entry should not be here now but double check. + (remove entry ls)) + ls)))))) + +;;; Eshell history. +;; +;; +(defclass helm-eshell-history-source (helm-source-in-buffer) + ((init :initform (lambda () + (let (eshell-hist-ignoredups) + (eshell-write-history eshell-history-file-name t) + (with-current-buffer (helm-candidate-buffer 'global) + (insert-file-contents eshell-history-file-name))) + ;; Same comment as in `helm-source-esh' + (remove-hook 'minibuffer-setup-hook 'eshell-mode))) + (nomark :initform t) + (keymap :initform helm-eshell-history-map) + (filtered-candidate-transformer :initform (lambda (candidates sources) + (reverse candidates))) + (candidate-number-limit :initform 9999) + (action :initform (lambda (candidate) + (eshell-kill-input) + (insert candidate)))) + "Helm class to define source for Eshell history.") + +;;;###autoload +(defun helm-esh-pcomplete () + "Preconfigured helm to provide helm completion in eshell." + (interactive) + (let* ((helm-quit-if-no-candidate t) + (helm-execute-action-at-once-if-one t) + (end (point-marker)) + (beg (save-excursion (eshell-bol) (point))) + (args (catch 'eshell-incomplete + (eshell-parse-arguments beg end))) + (target + (or (and (looking-back " ") " ") + (buffer-substring-no-properties + (save-excursion + (eshell-backward-argument 1) (point)) + end))) + (first (car args)) ; Maybe lisp delimiter "(". + last) ; Will be the last but parsed by pcomplete. + (setq helm-ec-target (or target " ") + end (point) + ;; Reset beg for `with-helm-show-completion'. + beg (or (and target (not (string= target " ")) + (- end (length target))) + ;; Nothing at point. + (progn (insert " ") (point)))) + (cond ((eq first ?\() + (helm-lisp-completion-or-file-name-at-point)) + ;; In eshell `pcomplete-parse-arguments' is called + ;; with `pcomplete-parse-arguments-function' + ;; locally bound to `eshell-complete-parse-arguments' + ;; which is calling `lisp-complete-symbol', + ;; calling it before would popup the + ;; *completions* buffer. + (t (setq last (replace-regexp-in-string + "\\`\\*" "" + (car (last (ignore-errors + (pcomplete-parse-arguments)))))) + (with-helm-show-completion beg end + (helm :sources (helm-make-source "Eshell completions" 'helm-esh-source) + :buffer "*helm pcomplete*" + :keymap helm-esh-completion-map + :resume 'noresume + :input (and (stringp last) + (helm-ff-set-pattern last)))))))) + +;;;###autoload +(defun helm-eshell-history () + "Preconfigured helm for eshell history." + (interactive) + (let* ((end (point)) + (beg (save-excursion (eshell-bol) (point))) + (input (buffer-substring beg end)) + flag-empty) + (when (eq beg end) + (insert " ") + (setq flag-empty t) + (setq end (point))) + (unwind-protect + (with-helm-show-completion beg end + (helm :sources (helm-make-source "Eshell history" + 'helm-eshell-history-source) + :buffer "*helm eshell history*" + :resume 'noresume + :input input)) + (when (and flag-empty + (looking-back " ")) + (delete-char -1))))) + +(provide 'helm-eshell) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-eshell ends here diff --git a/elpa/helm-20150403.101/helm-eval.el b/elpa/helm-20150403.101/helm-eval.el new file mode 100644 index 00000000..850cdf4f --- /dev/null +++ b/elpa/helm-20150403.101/helm-eval.el @@ -0,0 +1,177 @@ +;;; helm-eval.el --- eval expressions from helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'eldoc) + + +(defgroup helm-eval nil + "Eval related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-eldoc-in-minibuffer-show-fn + 'helm-show-info-in-mode-line + "A function to display eldoc info. +Should take one arg: the string to display." + :group 'helm-eval + :type 'symbol) + +(defcustom helm-show-info-in-mode-line-delay 12 + "Eldoc will show info in mode-line during this delay if user is idle." + :type 'integer + :group 'helm-eval) + + +(declare-function eldoc-current-symbol "eldoc") +(declare-function eldoc-get-fnsym-args-string "eldoc" (sym &optional index)) +(declare-function eldoc-get-var-docstring "eldoc" (sym)) +(declare-function eldoc-fnsym-in-current-sexp "eldoc") + +;;; Evaluation Result +;; +;; +;; Internal +(defvar helm-eldoc-active-minibuffers-list nil) + +(defvar helm-eval-expression-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "") 'helm-eval-new-line-and-indent) + (define-key map (kbd "") 'lisp-indent-line) + (define-key map (kbd "") 'helm-lisp-completion-at-point) + (define-key map (kbd "C-p") 'previous-line) + (define-key map (kbd "C-n") 'next-line) + (define-key map (kbd "") 'previous-line) + (define-key map (kbd "") 'next-line) + (define-key map (kbd "") 'forward-char) + (define-key map (kbd "") 'backward-char) + map)) + +(defvar helm-source-evaluation-result + '((name . "Evaluation Result") + (init . (lambda () (require 'edebug))) + (dummy) + (multiline) + (mode-line . "C-RET: nl-and-indent, tab: reindent, C-tab:complete, C-p/n: next/prec-line.") + (filtered-candidate-transformer . (lambda (candidates _source) + (list + (condition-case nil + (with-helm-current-buffer + (pp-to-string + (if edebug-active + (edebug-eval-expression + (read helm-pattern)) + (eval (read helm-pattern))))) + (error "Error"))))) + (action . (("Copy result to kill-ring" . (lambda (candidate) + (kill-new + (replace-regexp-in-string + "\n" "" candidate)))) + ("copy sexp to kill-ring" . (lambda (candidate) + (kill-new helm-input))))))) + +(defun helm-eval-new-line-and-indent () + (interactive) + (newline) (lisp-indent-line)) + +(defun helm-eldoc-store-minibuffer () + "Store minibuffer buffer name in `helm-eldoc-active-minibuffers-list'." + (with-selected-window (minibuffer-window) + (push (current-buffer) helm-eldoc-active-minibuffers-list))) + +(defun helm-eldoc-show-in-eval () + "Return eldoc in mode-line for current minibuffer input." + (let ((buf (window-buffer (active-minibuffer-window)))) + (condition-case err + (when (member buf helm-eldoc-active-minibuffers-list) + (with-current-buffer buf + (let* ((sym (save-excursion + (unless (looking-back ")\\|\"") + (forward-char -1)) + (eldoc-current-symbol))) + (info-fn (eldoc-fnsym-in-current-sexp)) + (doc (or (eldoc-get-var-docstring sym) + (eldoc-get-fnsym-args-string + (car info-fn) (cadr info-fn))))) + (when doc (funcall helm-eldoc-in-minibuffer-show-fn doc))))) + (error (message "Eldoc in minibuffer error: %S" err) nil)))) + +(defun helm-show-info-in-mode-line (str) + "Display string STR in mode-line." + (save-selected-window + (with-current-buffer helm-buffer + (let ((mode-line-format (concat " " str))) + (force-mode-line-update) + (sit-for helm-show-info-in-mode-line-delay)) + (force-mode-line-update)))) + +;;; Calculation Result +;; +;; +(defvar helm-source-calculation-result + '((name . "Calculation Result") + (dummy) + (filtered-candidate-transformer . (lambda (candidates _source) + (list + (condition-case nil + (calc-eval helm-pattern) + (error "error"))))) + (action ("Copy result to kill-ring" . kill-new)))) + +;;;###autoload +(defun helm-eval-expression (arg) + "Preconfigured helm for `helm-source-evaluation-result'." + (interactive "P") + (helm :sources 'helm-source-evaluation-result + :input (when arg (thing-at-point 'sexp)) + :buffer "*helm eval*" + :history 'read-expression-history + :keymap helm-eval-expression-map)) + +(defvar eldoc-idle-delay) +;;;###autoload +(defun helm-eval-expression-with-eldoc () + "Preconfigured helm for `helm-source-evaluation-result' with `eldoc' support. " + (interactive) + (let ((timer (run-with-idle-timer + eldoc-idle-delay 'repeat + 'helm-eldoc-show-in-eval))) + (unwind-protect + (minibuffer-with-setup-hook + 'helm-eldoc-store-minibuffer + (call-interactively 'helm-eval-expression)) + (and timer (cancel-timer timer)) + (setq helm-eldoc-active-minibuffers-list + (cdr helm-eldoc-active-minibuffers-list))))) + +;;;###autoload +(defun helm-calcul-expression () + "Preconfigured helm for `helm-source-calculation-result'." + (interactive) + (helm-other-buffer 'helm-source-calculation-result "*helm calcul*")) + +(provide 'helm-eval) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-eval.el ends here diff --git a/elpa/helm-20150403.101/helm-external.el b/elpa/helm-20150403.101/helm-external.el new file mode 100644 index 00000000..28298e3a --- /dev/null +++ b/elpa/helm-20150403.101/helm-external.el @@ -0,0 +1,216 @@ +;;; helm-external.el --- Run Externals commands within Emacs with helm completion. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-net) + + +(defgroup helm-external nil + "External related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-raise-command nil + "A shell command to jump to a window running specific program. +Need external program wmctrl. +This will be use with `format', so use something like \"wmctrl -xa %s\"." + :type 'string + :group 'helm-external) + +(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\"\)\) " + :type '(alist :key-type string :value-type string) + :group 'helm-external) + +(defcustom helm-default-external-file-browser "nautilus" + "Default external file browser for your system. +Directories will be opened externally with it when +opening file externally in `helm-find-files'. +Set to nil if you do not have external file browser +or do not want to use it. +Windows users should set that to \"explorer.exe\"." + :group 'helm-external + :type 'string) + + +;;; Internals +(defvar helm-external-command-history nil) +(defvar helm-external-commands-list nil + "A list of all external commands the user can execute. +If this variable is not set by the user, it will be calculated +automatically.") + +(defun helm-external-commands-list-1 (&optional sort) + "Returns a list of all external commands the user can execute. +If `helm-external-commands-list' is non-nil it will +return its contents. Else it calculates all external commands +and sets `helm-external-commands-list'." + (helm-aif helm-external-commands-list + it + (setq helm-external-commands-list + (cl-loop + for dir in (split-string (getenv "PATH") path-separator) + when (and (file-exists-p dir) (file-accessible-directory-p dir)) + for lsdir = (cl-loop for i in (directory-files dir t) + for bn = (file-name-nondirectory i) + when (and (not (member bn completions)) + (not (file-directory-p i)) + (file-executable-p i)) + collect bn) + append lsdir into completions + finally return + (if sort (sort completions 'string-lessp) completions))))) + +(defun helm-run-or-raise (exe &optional file) + "Generic command that run asynchronously EXE. +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. +In this case EXE must be provided as \"EXE %s\"." + (let* ((real-com (car (split-string (replace-regexp-in-string + "%s" "" 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 (cl-loop for i in helm-external-commands-list thereis (string= real-com i)) + (message "Starting %s..." real-com) + (if file + (start-process-shell-command + proc nil (format exe (shell-quote-argument + (if (eq system-type 'windows-nt) + (helm-w32-prepare-filename file) + file)))) + (start-process-shell-command proc nil real-com)) + (set-process-sentinel + (get-process 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)))) + (setq helm-external-commands-list + (cons real-com + (delete real-com helm-external-commands-list)))))) + +(defun helm-get-mailcap-for-file (filename) + "Get the command to use for FILENAME from mailcap files. +The command is like and is meant to use with `format'." + (mailcap-parse-mailcaps) + (let* ((ext (file-name-extension filename)) + (mime (when ext (mailcap-extension-to-mime ext))) + (result (when mime (mailcap-mime-info mime)))) + ;; If elisp file have no associations in .mailcap + ;; `mailcap-maybe-eval' is returned, in this case just return nil. + (when (stringp result) result))) + +(defun helm-get-default-program-for-file (filename) + "Try to find a default program to open FILENAME. +Try first in `helm-external-programs-associations' and then in mailcap file +if nothing found return nil." + (let* ((ext (file-name-extension filename)) + (def-prog (assoc-default ext helm-external-programs-associations))) + (cond ((and def-prog (not (string= def-prog ""))) + (concat def-prog " %s")) + ((and helm-default-external-file-browser + (file-directory-p filename)) + (concat helm-default-external-file-browser " %s")) + (t (helm-get-mailcap-for-file filename))))) + +(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)) + (collection (helm-external-commands-list-1 'sort)) + (def-prog (helm-get-default-program-for-file fname)) + (real-prog-name (if (or helm-current-prefix-arg (not def-prog)) + ;; Prefix arg or no default program. + (prog1 + (helm-comp-read + "Program: " collection + :must-match t + :name "Open file Externally" + :del-input nil + :history helm-external-command-history) + ;; Always prompt to set this program as default. + (setq def-prog nil)) + ;; No prefix arg or default program exists. + (replace-regexp-in-string " %s\\| '%s'" "" def-prog))) + (program (concat real-prog-name " %s"))) + (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))) + (when + (y-or-n-p + (format + "Do you want to make `%s' the default program for this kind of files? " + real-prog-name)) + (helm-aif (assoc (file-name-extension fname) + helm-external-programs-associations) + (setq helm-external-programs-associations + (delete it helm-external-programs-associations))) + (push (cons (file-name-extension fname) + (helm-read-string + "Program (Add args maybe and confirm): " real-prog-name)) + helm-external-programs-associations) + (customize-save-variable 'helm-external-programs-associations + helm-external-programs-associations))) + (helm-run-or-raise program file) + (setq helm-external-command-history + (cons real-prog-name + (delete real-prog-name + (cl-loop for i in helm-external-command-history + when (executable-find i) collect i)))))) + +;;;###autoload +(defun helm-run-external-command (program) + "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) + (setq helm-external-command-history + (cons program (delete program + (cl-loop for i in helm-external-command-history + when (executable-find i) collect i))))) + + +(provide 'helm-external) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-external ends here diff --git a/elpa/helm-20150403.101/helm-files.el b/elpa/helm-20150403.101/helm-files.el new file mode 100644 index 00000000..a13fbc42 --- /dev/null +++ b/elpa/helm-20150403.101/helm-files.el @@ -0,0 +1,3165 @@ +;;; helm-files.el --- helm file browser and related. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'helm-external) +(require 'helm-grep) +(require 'helm-match-plugin) +(require 'helm-help) +(require 'helm-locate) +(require 'helm-bookmark) +(require 'helm-tags) +(require 'helm-buffers) +(require 'thingatpt) +(require 'ffap) +(require 'dired-aux) +(require 'dired-x) +(require 'tramp) +(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") +(declare-function eshell-bol "esh-mode") +(declare-function helm-ls-git-ls "ext:helm-ls-git") +(declare-function helm-hg-find-files-in-project "ext:helm-ls-hg") + +(defvar recentf-list) + + +;;; Type attributes +;; +;; +(define-helm-type-attribute 'file + (helm-build-type-file) + "File name.") + + + +(defgroup helm-files nil + "Files applications and libraries for Helm." + :group 'helm) + +(defcustom helm-boring-file-regexp-list + (mapcar (lambda (f) + (concat + (rx-to-string + (replace-regexp-in-string + "/$" "" f) t) "$")) + completion-ignored-extensions) + "The regexp list matching boring files." + :group 'helm-files + :type '(repeat (choice regexp))) + +(defcustom helm-for-files-preferred-list + '(helm-source-buffers-list + helm-source-recentf + helm-source-bookmarks + helm-source-file-cache + helm-source-files-in-current-dir + helm-source-locate) + "Your preferred sources to find files." + :type '(repeat (choice symbol)) + :group 'helm-files) + +(defcustom helm-tramp-verbose 0 + "Just like `tramp-verbose' but specific to helm. +When set to 0 don't show tramp messages in helm. +If you want to have the default tramp messages set it to 3." + :type 'integer + :group 'helm-files) + +(defcustom helm-ff-auto-update-initial-value nil + "Auto update when only one candidate directory is matched. +Default value when starting `helm-find-files' is nil because +it prevent using to delete char backward and by the way +confuse beginners. +For a better experience with `helm-find-files' set this to non--nil +and use C- to toggle it." + :group 'helm-files + :type 'boolean) + +(defcustom helm-ff-lynx-style-map t + "Use arrow keys to navigate with `helm-find-files'. +You will have to restart Emacs or reeval `helm-find-files-map' +and `helm-read-file-map' for this take effect." + :group 'helm-files + :type 'boolean) + +(defcustom helm-ff-history-max-length 100 + "Number of elements shown in `helm-find-files' history." + :group 'helm-files + :type 'integer) + +(defcustom helm-ff-smart-completion t + "Try to complete filenames smarter when non--nil. +See `helm-ff--transform-pattern-for-completion' for more info." + :group 'helm-files + :type 'boolean) + +(defcustom helm-ff-tramp-not-fancy t + "No colors when listing remote files when set to non--nil. +This make listing much faster, specially on slow machines." + :group 'helm-files + :type 'boolean) + +(defcustom helm-ff-exif-data-program "exiftran" + "Program used to extract exif data of an image file." + :group 'helm-files + :type 'string) + +(defcustom helm-ff-exif-data-program-args "-d" + "Arguments used for `helm-ff-exif-data-program'." + :group 'helm-files + :type 'string) + +(defcustom helm-ff-newfile-prompt-p t + "Whether Prompt or not when creating new file. +This set `ffap-newfile-prompt'." + :type 'boolean + :group 'helm-files) + +(defcustom helm-ff-avfs-directory "~/.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 ." + :type 'string + :group 'helm-files) + +(defcustom helm-ff-file-compressed-list '("gz" "bz2" "zip" "7z") + "Minimal list of compressed files extension." + :type '(repeat (choice string)) + :group 'helm-files) + +(defcustom helm-ff-printer-list nil + "A list of available printers on your system. +When non--nil let you choose a printer to print file. +Otherwise when nil the variable `printer-name' will be used. +On Unix based systems (lpstat command needed) you don't need to set this, +`helm-ff-find-printers' will find a list of available printers for you." + :type '(repeat (choice string)) + :group 'helm-files) + +(defcustom helm-ff-transformer-show-only-basename t + "Show only basename of candidates in `helm-find-files'. +This can be toggled at anytime from `helm-find-files' with \ +\\\\[helm-ff-run-toggle-basename]." + :type 'boolean + :group 'helm-files) + +(defcustom helm-ff-signal-error-on-dot-files t + "Signal error when file is `.' or `..' on file deletion when non--nil. +Default is non--nil. +WARNING: Setting this to nil is unsafe and can cause deletion of a whole tree." + :group 'helm-files + :type 'boolean) + +(defcustom helm-ff-search-library-in-sexp nil + "Search for library in `require' and `declare-function' sexp." + :group 'helm-files + :type 'boolean) + +(defcustom helm-tooltip-hide-delay 25 + "Hide tooltips automatically after this many seconds." + :group 'helm-files + :type 'integer) + +(defcustom helm-ff-file-name-history-use-recentf nil + "Use `recentf-list' instead of `file-name-history' in `helm-find-files'." + :group 'helm-files + :type 'boolean) + +(defcustom helm-ff-skip-boring-files nil + "Non--nil to skip files matching regexps in `helm-boring-file-regexp-list'. +This take effect in `helm-find-files' and file completion used by `helm-mode' +i.e `helm-read-file-name'." + :group 'helm-files + :type 'boolean) + +(defcustom helm-findutils-skip-boring-files t + "Ignore files matching regexps in `completion-ignored-extensions'." + :group 'helm-files + :type 'boolean) + +(defcustom helm-findutils-search-full-path nil + "Search in full path with shell command find when non--nil. +I.e use the -path/ipath arguments of find instead of -name/iname." + :group 'helm-files + :type 'boolean) + +(defcustom helm-files-save-history-extra-sources '("Find" "Locate") + "Extras source that save candidate to `file-name-history'." + :group 'helm-files + :type '(repeat (choice string))) + +(defcustom helm-find-files-before-init-hook nil + "Hook that run before initialization of `helm-find-files'." + :group 'helm-files + :type 'hook) + +(defcustom helm-find-files-after-init-hook nil + "Hook that run after initialization of `helm-find-files'." + :group 'helm-files + :type 'hook) + +(defcustom helm-multi-files-toggle-locate-binding "C-c p" + "Default binding to switch back and forth locate in `helm-multi-files'." + :group 'helm-files + :type 'string) + + +;;; Faces +;; +;; +(defgroup helm-files-faces nil + "Customize the appearance of helm-files." + :prefix "helm-" + :group 'helm-files + :group 'helm-faces) + +(defface helm-ff-prefix + '((t (:background "yellow" :foreground "black"))) + "Face used to prefix new file or url paths in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-ff-executable + '((t (:foreground "green"))) + "Face used for executable files in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-ff-directory + '((t (:foreground "DarkRed" :background "LightGray"))) + "Face used for directories in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-ff-dotted-directory + '((t (:foreground "black" :background "DimGray"))) + "Face used for dotted directories in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-ff-symlink + '((t (:foreground "DarkOrange"))) + "Face used for symlinks in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-ff-invalid-symlink + '((t (:foreground "black" :background "red"))) + "Face used for invalid symlinks in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-ff-file + '((t (:inherit font-lock-builtin-face))) + "Face used for file names in `helm-find-files'." + :group 'helm-files-faces) + +(defface helm-history-deleted + '((t (:inherit helm-ff-invalid-symlink))) + "Face used for deleted files in `file-name-history'." + :group 'helm-files-faces) + +(defface helm-history-remote + '((t (:foreground "Indianred1"))) + "Face used for remote files in `file-name-history'." + :group 'helm-files-faces) + + +;;; Helm-find-files - The helm file browser. +;; +;; Keymaps +(defvar helm-find-files-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-]") 'helm-ff-run-toggle-basename) + (define-key map (kbd "C-x C-f") 'helm-ff-run-locate) + (define-key map (kbd "C-x C-d") 'helm-ff-run-browse-project) + (define-key map (kbd "C-s") 'helm-ff-run-grep) + (define-key map (kbd "M-g s") 'helm-ff-run-grep) + (define-key map (kbd "M-g p") 'helm-ff-run-pdfgrep) + (define-key map (kbd "M-g z") 'helm-ff-run-zgrep) + (define-key map (kbd "M-.") 'helm-ff-run-etags) + (define-key map (kbd "M-R") 'helm-ff-run-rename-file) + (define-key map (kbd "M-C") 'helm-ff-run-copy-file) + (define-key map (kbd "M-B") 'helm-ff-run-byte-compile-file) + (define-key map (kbd "M-L") 'helm-ff-run-load-file) + (define-key map (kbd "M-S") 'helm-ff-run-symlink-file) + (define-key map (kbd "M-H") 'helm-ff-run-hardlink-file) + (define-key map (kbd "M-D") 'helm-ff-run-delete-file) + (define-key map (kbd "M-K") 'helm-ff-run-kill-buffer-persistent) + (define-key map (kbd "C-c d") 'helm-ff-persistent-delete) + (define-key map (kbd "M-e") 'helm-ff-run-switch-to-eshell) + (define-key map (kbd "C-c i") 'helm-ff-run-complete-fn-at-point) + (define-key map (kbd "C-c o") 'helm-ff-run-switch-other-window) + (define-key map (kbd "C-c C-o") 'helm-ff-run-switch-other-frame) + (define-key map (kbd "C-c C-x") 'helm-ff-run-open-file-externally) + (define-key map (kbd "C-c X") 'helm-ff-run-open-file-with-default-tool) + (define-key map (kbd "M-!") 'helm-ff-run-eshell-command-on-file) + (define-key map (kbd "M-%") 'helm-ff-run-query-replace-on-marked) + (define-key map (kbd "C-c =") 'helm-ff-run-ediff-file) + (define-key map (kbd "M-=") 'helm-ff-run-ediff-merge-file) + (define-key map (kbd "M-p") 'helm-ff-run-switch-to-history) + (define-key map (kbd "C-c h") 'helm-ff-file-name-history) + (define-key map (kbd "M-i") 'helm-ff-properties-persistent) + (define-key map (kbd "C-c ?") 'helm-ff-help) + (define-key map (kbd "C-}") 'helm-narrow-window) + (define-key map (kbd "C-{") 'helm-enlarge-window) + (define-key map (kbd "C-") 'helm-ff-run-toggle-auto-update) + (define-key map (kbd "C-c ") 'helm-ff-run-toggle-auto-update) + (define-key map (kbd "C-c C-a") 'helm-ff-run-gnus-attach-files) + (define-key map (kbd "C-c p") 'helm-ff-run-print-file) + (define-key map (kbd "C-c /") 'helm-ff-run-find-sh-command) + ;; Next 2 have no effect if candidate is not an image file. + (define-key map (kbd "M-l") 'helm-ff-rotate-left-persistent) + (define-key map (kbd "M-r") 'helm-ff-rotate-right-persistent) + (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-h C-b") 'helm-send-bug-report-from-helm) + (define-key map (kbd "C-c r") 'helm-ff-run-find-file-as-root) + (define-key map (kbd "C-c @") 'helm-ff-run-insert-org-link) + (helm-define-key-with-subkeys map (kbd "DEL") ?\d 'helm-ff-delete-char-backward + nil nil 'helm-ff-delete-char-backward--exit-fn) + (when helm-ff-lynx-style-map + (define-key map (kbd "") 'helm-find-files-up-one-level) + (define-key map (kbd "") 'helm-execute-persistent-action)) + (delq nil map)) + "Keymap for `helm-find-files'.") + +(defvar helm-read-file-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "") 'helm-cr-empty-string) + (define-key map (kbd "") 'helm-cr-empty-string) + (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-c h") 'helm-ff-file-name-history) + (define-key map (kbd "C-") 'helm-ff-run-toggle-auto-update) + (define-key map (kbd "C-c ") 'helm-ff-run-toggle-auto-update) + (define-key map (kbd "C-c ?") 'helm-read-file-name-help) + (helm-define-key-with-subkeys map (kbd "DEL") ?\d 'helm-ff-delete-char-backward + nil nil 'helm-ff-delete-char-backward--exit-fn) + (when helm-ff-lynx-style-map + (define-key map (kbd "") 'helm-find-files-up-one-level) + (define-key map (kbd "") 'helm-execute-persistent-action) + (define-key map (kbd "") 'helm-previous-source) + (define-key map (kbd "") 'helm-next-source)) + (delq nil map)) + "Keymap for `helm-read-file-name'.") + +(defvar helm-esh-on-file-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-esh-help) + map) + "Keymap for `helm-find-files-eshell-command-on-file'.") + + +;; Internal. +(defvar helm-find-files-doc-header " (`C-l': Go up one level)" + "*The doc that is inserted in the Name header of a find-files or dired source.") +(defvar helm-ff-auto-update-flag nil + "Internal, flag to turn on/off auto-update in `helm-find-files'. +Don't set it directly, use instead `helm-ff-auto-update-initial-value'.") +(defvar helm-ff-last-expanded nil + "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.") +(defvar helm-tramp-file-name-regexp "\\`/\\([^[/:]+\\|[^/]+]\\):") +(defvar helm-marked-buffer-name "*helm marked*") +(defvar helm-ff--auto-update-state nil) +(defvar helm-ff--deleting-char-backward nil) +(defvar helm-multi-files--toggle-locate nil) +(defvar helm-ff--move-to-first-real-candidate t) + + +;;; Helm-find-files +;; +;; +(defvar helm-source-find-files nil + "The main source to browse files. +Should not be used among other sources.") + +(defclass helm-source-ffiles (helm-source-sync) + ((header-name + :initform (lambda (name) + (concat name helm-find-files-doc-header))) + (init + :initform (lambda () + (setq helm-ff-auto-update-flag + helm-ff-auto-update-initial-value) + (setq helm-ff--auto-update-state + helm-ff-auto-update-flag))) + (candidates :initform 'helm-find-files-get-candidates) + (filtered-candidate-transformer :initform 'helm-ff-sort-candidates) + (filter-one-by-one :initform 'helm-ff-filter-candidate-one-by-one) + (persistent-action :initform 'helm-find-files-persistent-action) + (persistent-help :initform "Hit1 Expand Candidate, Hit2 or (C-u) Find file") + (mode-line :initform helm-ff-mode-line-string) + (volatile :initform t) + (nohighlight :initform t) + (candidate-number-limit + :initform 9999) + (action-transformer + :initform 'helm-find-files-action-transformer) + (action + :initform + (helm-make-actions + "Find File" 'helm-find-file-or-marked + "Find file in Dired" 'helm-point-file-in-dired + (lambda () (and (locate-library "elscreen") "Find file in Elscreen")) + 'helm-elscreen-find-file + "View file" 'view-file + "Checksum File" 'helm-ff-checksum + "Query replace fnames on marked" 'helm-ff-query-replace-on-marked + "Query replace contents on marked" 'helm-ff-query-replace + "Query replace regexp contents on marked" 'helm-ff-query-replace-regexp + "Serial rename files" 'helm-ff-serial-rename + "Serial rename by symlinking files" 'helm-ff-serial-rename-by-symlink + "Serial rename by copying files" 'helm-ff-serial-rename-by-copying + "Open file with default tool" 'helm-open-file-with-default-tool + "Find file in hex dump" 'hexl-find-file + "Browse project" 'helm-ff-browse-project + "Complete at point `C-c i'" 'helm-insert-file-name-completion-at-point + "Insert as org link `C-c @'" 'helm-files-insert-as-org-link + "Find shell command `C-c /'" 'helm-ff-find-sh-command + "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 + "Zgrep File(s) `M-g z, C-u Recurse'" 'helm-ff-zgrep + "Switch to Eshell `M-e'" 'helm-ff-switch-to-eshell + "Etags `M-., C-u reload tag file'" 'helm-ff-etags-select + "Eshell command on file(s) `M-!, C-u take all marked as arguments.'" + 'helm-find-files-eshell-command-on-file + "Find file as root `C-c r'" 'helm-find-file-as-root + "Ediff File `C-='" 'helm-find-files-ediff-files + "Ediff Merge File `C-c ='" 'helm-find-files-ediff-merge-files + "Delete File(s) `M-D'" 'helm-delete-marked-files + "Copy file(s) `M-C, C-u to follow'" 'helm-find-files-copy + "Rename file(s) `M-R, C-u to follow'" 'helm-find-files-rename + "Symlink files(s) `M-S, C-u to follow'" 'helm-find-files-symlink + "Relsymlink file(s) `C-u to follow'" 'helm-find-files-relsymlink + "Hardlink file(s) `M-H, C-u to follow'" 'helm-find-files-hardlink + "Find file other window `C-c o'" 'find-file-other-window + "Switch to history `M-p'" 'helm-find-files-switch-to-hist + "Find file other frame `C-c C-o'" 'find-file-other-frame + "Print File `C-c p, C-u to refresh'" 'helm-ff-print + "Locate `C-x C-f, C-u to specify locate db'" 'helm-ff-locate)) + (before-init-hook :initform 'helm-find-files-before-init-hook) + (after-init-hook :initform 'helm-find-files-after-init-hook))) + +(defun helm-dwim-target-directory () + "Return value of `default-directory' of buffer in other window. +If there is only one window return the value ot `default-directory' +for current buffer." + (with-helm-current-buffer + (let ((num-windows (length (remove (get-buffer-window helm-marked-buffer-name) + (window-list))))) + (expand-file-name + (if (> num-windows 1) + (save-selected-window + (other-window 1) + default-directory) + (car helm-ff-history)))))) + +(defun helm-find-files-do-action (action) + "Generic function for creating actions from `helm-source-find-files'. +ACTION must be an action supported by `helm-dired-action'." + (let* ((ifiles (mapcar 'expand-file-name ; Allow modify '/foo/.' -> '/foo' + (helm-marked-candidates :with-wildcard t))) + (cand (helm-get-selection)) ; Target + (prompt (format "%s %s file(s) to: " + (capitalize (symbol-name action)) + (length ifiles))) + helm-ff--move-to-first-real-candidate + (helm-always-two-windows t) + (helm-reuse-last-window-split-state t) + (helm-split-window-default-side + (eq helm-split-window-default-side 'same)) + helm-split-window-in-side-p + (parg helm-current-prefix-arg) + helm-display-source-at-screen-top ; prevent setting window-start. + helm-ff-auto-update-initial-value + (dest (with-helm-display-marked-candidates + helm-marked-buffer-name + (mapcar #'(lambda (f) + (if (file-directory-p f) + (concat (helm-basename f) "/") + (helm-basename f))) + ifiles) + (with-helm-current-buffer + (helm-read-file-name + prompt + :preselect (if helm-ff-transformer-show-only-basename + (helm-basename cand) cand) + :initial-input (helm-dwim-target-directory) + :history (helm-find-files-history :comp-read nil)))))) + (helm-dired-action + dest :files ifiles :action action :follow parg))) + +(defun helm-find-files-copy (_candidate) + "Copy files from `helm-find-files'." + (helm-find-files-do-action 'copy)) + +(defun helm-find-files-rename (_candidate) + "Rename files from `helm-find-files'." + (helm-find-files-do-action 'rename)) + +(defun helm-find-files-symlink (_candidate) + "Symlink files from `helm-find-files'." + (helm-find-files-do-action 'symlink)) + +(defun helm-find-files-relsymlink (_candidate) + "Relsymlink files from `helm-find-files'." + (helm-find-files-do-action 'relsymlink)) + +(defun helm-find-files-hardlink (_candidate) + "Hardlink files from `helm-find-files'." + (helm-find-files-do-action 'hardlink)) + +(defun helm-find-files-byte-compile (_candidate) + "Byte compile elisp files from `helm-find-files'." + (let ((files (helm-marked-candidates :with-wildcard t)) + (parg helm-current-prefix-arg)) + (cl-loop for fname in files + do (byte-compile-file fname parg)))) + +(defun helm-find-files-load-files (_candidate) + "Load elisp files from `helm-find-files'." + (let ((files (helm-marked-candidates :with-wildcard t))) + (cl-loop for fname in files + do (load fname)))) + +(defun helm-find-files-ediff-files-1 (candidate &optional merge) + "Generic function to ediff/merge files in `helm-find-files'." + (let* ((bname (helm-basename candidate)) + (marked (helm-marked-candidates :with-wildcard t)) + (prompt (if merge "Ediff Merge `%s' With File: " + "Ediff `%s' With File: ")) + (fun (if merge 'ediff-merge-files 'ediff-files)) + (input (helm-dwim-target-directory)) + (presel (if helm-ff-transformer-show-only-basename + (helm-basename candidate) + (expand-file-name + (helm-basename candidate) + input)))) + (if (= (length marked) 2) + (funcall fun (car marked) (cadr marked)) + (funcall fun candidate (helm-read-file-name + (format prompt bname) + :initial-input input + :preselect presel))))) + +(defun helm-find-files-ediff-files (candidate) + (helm-find-files-ediff-files-1 candidate)) + +(defun helm-find-files-ediff-merge-files (candidate) + (helm-find-files-ediff-files-1 candidate 'merge)) + +(defun helm-find-files-grep (_candidate) + "Default action to grep files from `helm-find-files'." + (apply 'run-with-timer 0.01 nil + #'helm-do-grep-1 + (helm-marked-candidates :with-wildcard t) + helm-current-prefix-arg)) + +(defun helm-ff-zgrep (_candidate) + "Default action to zgrep files from `helm-find-files'." + (helm-ff-zgrep-1 (helm-marked-candidates :with-wildcard t) helm-current-prefix-arg)) + +(defun helm-ff-pdfgrep (_candidate) + "Default action to pdfgrep files from `helm-find-files'." + (let ((cands (cl-loop for file in (helm-marked-candidates :with-wildcard t) + if (or (string= (file-name-extension file) "pdf") + (string= (file-name-extension file) "PDF")) + collect file)) + (helm-pdfgrep-default-function 'helm-pdfgrep-init)) + (when cands + (helm-do-pdfgrep-1 cands)))) + +(defun helm-ff-etags-select (candidate) + "Default action to jump to etags from `helm-find-files'." + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + (let* ((source-name (assoc-default 'name (helm-get-current-source))) + (default-directory (if (string= source-name "Find Files") + helm-ff-default-directory + (file-name-directory candidate)))) + (helm-etags-select helm-current-prefix-arg))) + +(defun helm-find-files-switch-to-hist (_candidate) + "Switch to helm-find-files history." + (helm-find-files t)) + +(defvar eshell-command-aliases-list nil) +(defvar helm-eshell-command-on-file-input-history nil) +(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, you can type in +an eshell command. + +Basename of CANDIDATE can be a wild-card. +e.g you can do \"eshell-command command *.el\" +Where \"*.el\" is the CANDIDATE. + +It is possible to do eshell-command command +like this: \"command %s some more args\". + +If MAP is given run `eshell-command' on all marked files at once, +Otherwise, run `eshell-command' on each marked files. +In other terms, with a prefix arg do on the three marked files +\"foo\" \"bar\" \"baz\": + +\"eshell-command command foo bar baz\" + +otherwise do + +\"eshell-command command foo\" +\"eshell-command command bar\" +\"eshell-command command baz\" + +Note: +If `eshell' or `eshell-command' have not been run once, +or if you have no eshell aliases `eshell-command-aliases-list' +will not be loaded first time you use this." + (when (or eshell-command-aliases-list + (y-or-n-p "Eshell is not loaded, run eshell-command without alias anyway? ")) + (and eshell-command-aliases-list (eshell-read-aliases-list)) + (let* ((cand-list (helm-marked-candidates :with-wildcard t)) + (default-directory (or helm-ff-default-directory + ;; If candidate is an url *-ff-default-directory is nil + ;; so keep value of default-directory. + default-directory)) + (command (helm-comp-read + "Command: " + (cl-loop for (a . c) in eshell-command-aliases-list + when (string-match "\\(\\$1\\|\\$\\*\\)$" (car c)) + collect (propertize a 'help-echo (car c)) into ls + finally return (sort ls 'string<)) + :buffer "*helm eshell on file*" + :name "Eshell command" + :keymap helm-esh-on-file-map + :mode-line + '("Eshell alias" + "C-c ?: Help, \\[universal-argument]: Insert output at point") + :input-history + 'helm-eshell-command-on-file-input-history)) + (alias-value (car (assoc-default command eshell-command-aliases-list)))) + (if (or (equal helm-current-prefix-arg '(16)) + (equal map '(16))) + ;; Two time C-u from `helm-comp-read' mean print to current-buffer. + ;; i.e `eshell-command' will use this value. + (setq current-prefix-arg '(16)) + ;; Else reset the value of `current-prefix-arg' + ;; to avoid printing in current-buffer. + (setq current-prefix-arg nil)) + (if (and (or + ;; One prefix-arg have been passed before `helm-comp-read'. + ;; If map have been set with C-u C-u (value == '(16)) + ;; ignore it. + (and map (equal map '(4))) + ;; One C-u from `helm-comp-read'. + (equal helm-current-prefix-arg '(4)) + ;; An alias that finish with $* + (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 + ;; on `default-directory' (limitation). + (let ((mapfiles (mapconcat 'shell-quote-argument cand-list " "))) + (if (string-match "'%s'\\|\"%s\"\\|%s" command) + (eshell-command (format command mapfiles)) ; See [1] + (eshell-command (format "%s %s" command mapfiles)))) + + ;; 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 dir = (and (not (string-match ffap-url-regexp f)) + (helm-basedir f)) + for file = (format "'%s'" (if (and dir (file-remote-p dir)) + (helm-basename f) f)) + for com = (if (string-match "'%s'\\|\"%s\"\\|%s" command) + ;; [1] This allow to enter other args AFTER filename + ;; i.e + (format command file) + (format "%s %s" command file)) + do (let ((default-directory (or dir default-directory))) + (eshell-command com))))))) + +(defun helm-find-files-eshell-command-on-file (_candidate) + "Run `eshell-command' on CANDIDATE or marked candidates. +See `helm-find-files-eshell-command-on-file-1' for more info." + (helm-find-files-eshell-command-on-file-1 helm-current-prefix-arg)) + +(defun helm-ff-switch-to-eshell (_candidate) + "Switch to eshell and cd to `helm-ff-default-directory'." + (let ((cd-eshell #'(lambda () + (eshell-kill-input) + (goto-char (point-max)) + (insert + (format "cd '%s'" helm-ff-default-directory)) + (eshell-send-input)))) + (if (get-buffer "*eshell*") + (switch-to-buffer "*eshell*") + (call-interactively 'eshell)) + (unless (get-buffer-process (current-buffer)) + (funcall cd-eshell)))) + +(defun helm-ff-serial-rename-action (method) + "Rename all marked files in `helm-ff-default-directory' with METHOD. +See `helm-ff-serial-rename-1'." + (let* ((helm--reading-passwd-or-string t) + (cands (helm-marked-candidates :with-wildcard t)) + (def-name (car cands)) + (name (helm-read-string "NewName: " + (replace-regexp-in-string + "[0-9]+$" "" + (helm-basename + def-name + (file-name-extension def-name))))) + (start (read-number "StartAtNumber: ")) + (extension (helm-read-string "Extension: " + (file-name-extension (car cands)))) + (dir (expand-file-name + (helm-read-file-name + "Serial Rename to directory: " + :initial-input + (expand-file-name helm-ff-default-directory) + :test 'file-directory-p + :must-match t))) + done) + (with-helm-display-marked-candidates + helm-marked-buffer-name (mapcar 'helm-basename cands) + (if (y-or-n-p + (format "Rename %s file(s) to <%s> like this ?\n%s " + (length cands) dir (format "%s <-> %s%s.%s" + (helm-basename (car cands)) + name start extension))) + (progn + (helm-ff-serial-rename-1 + dir cands name start extension :method method) + (setq done t) + (message nil)))) + (if done + (with-helm-current-buffer (helm-find-files-1 dir)) + (message "Operation aborted")))) + +(defun helm-ff-member-directory-p (file directory) + (let ((dir-file (expand-file-name + (file-name-as-directory (file-name-directory file)))) + (cur-dir (expand-file-name (file-name-as-directory directory)))) + (string= dir-file cur-dir))) + +(cl-defun helm-ff-serial-rename-1 + (directory collection new-name start-at-num extension &key (method 'rename)) + "rename files in COLLECTION to DIRECTORY with the prefix name NEW-NAME. +Rename start at number START-AT-NUM - ex: prefixname-01.jpg. +EXTENSION is the file extension to use, in empty prompt, +reuse the original extension of file. +METHOD can be one of rename, copy or symlink. +Files will be renamed if they are files of current directory, otherwise they +will be treated with METHOD. +Default METHOD is rename." + ;; Maybe remove directories selected by error in collection. + (setq collection (cl-remove-if 'file-directory-p collection)) + (let* ((tmp-dir (file-name-as-directory + (concat (file-name-as-directory directory) + (symbol-name (cl-gensym "tmp"))))) + (fn (cl-case method + (copy 'copy-file) + (symlink 'make-symbolic-link) + (rename 'rename-file) + (t (error "Error: Unknown method %s" method))))) + (make-directory tmp-dir) + (unwind-protect + (progn + ;; Rename all files to tmp-dir with new-name. + ;; If files are not from start directory, use method + ;; to move files to tmp-dir. + (cl-loop for i in collection + for count from start-at-num + for fnum = (if (< count 10) "0%s" "%s") + for nname = (concat tmp-dir new-name (format fnum count) + (if (not (string= extension "")) + (format ".%s" (replace-regexp-in-string + "[.]" "" extension)) + (file-name-extension i 'dot))) + do (if (helm-ff-member-directory-p i directory) + (rename-file i nname) + (funcall fn i nname))) + ;; Now move all from tmp-dir to destination. + (cl-loop with dirlist = (directory-files + tmp-dir t directory-files-no-dot-files-regexp) + for f in dirlist do + (if (file-symlink-p f) + (make-symbolic-link (file-truename f) + (concat (file-name-as-directory directory) + (helm-basename f))) + (rename-file f directory)))) + (delete-directory tmp-dir t)))) + +(defun helm-ff-serial-rename (_candidate) + "Serial rename all marked files to `helm-ff-default-directory'. +Rename only file of current directory, and symlink files coming from +other directories. +See `helm-ff-serial-rename-1'." + (helm-ff-serial-rename-action 'rename)) + +(defun helm-ff-serial-rename-by-symlink (_candidate) + "Serial rename all marked files to `helm-ff-default-directory'. +Rename only file of current directory, and symlink files coming from +other directories. +See `helm-ff-serial-rename-1'." + (helm-ff-serial-rename-action 'symlink)) + +(defun helm-ff-serial-rename-by-copying (_candidate) + "Serial rename all marked files to `helm-ff-default-directory'. +Rename only file of current directory, and copy files coming from +other directories. +See `helm-ff-serial-rename-1'." + (helm-ff-serial-rename-action 'copy)) + +(defun helm-ff-query-replace-on-marked-1 (candidates) + (with-helm-display-marked-candidates + helm-marked-buffer-name + (mapcar 'helm-basename candidates) + (let* ((regexp (read-string "Replace regexp on filename(s): ")) + (str (read-string (format "Replace regexp `%s' with: " regexp)))) + (cl-loop with query = "y" + with count = 0 + for old in candidates + for new = (concat (helm-basedir old) + (replace-regexp-in-string + regexp str + (helm-basename old))) + ;; If `regexp' is not matched in `old' + ;; `replace-regexp-in-string' will + ;; return `old' unmodified. + unless (string= old new) + do (progn + (unless (string= query "!") + (while (not (member + (setq query + (string + (read-key + (propertize + (format + "Replace `%s' by `%s' [!,y,n,q]" + old new) + 'face 'minibuffer-prompt)))) + '("y" "!" "n" "q"))) + (message "Please answer by y,n,! or q") (sit-for 1))) + (when (string= query "q") + (cl-return (message "Operation aborted"))) + (unless (string= query "n") + (rename-file old new) + (cl-incf count))) + finally (message "%d Files renamed" count)))) + ;; This fix the emacs bug where "Emacs-Lisp:" is sent + ;; in minibuffer (not the echo area). + (sit-for 0.1) + (with-current-buffer (window-buffer (minibuffer-window)) + (delete-minibuffer-contents))) + +;; The action. +(defun helm-ff-query-replace-on-marked (_candidate) + (let ((marked (helm-marked-candidates))) + (helm-run-after-quit #'helm-ff-query-replace-on-marked-1 marked))) + +;; The command for `helm-find-files-map'. +(defun helm-ff-run-query-replace-on-marked () + (interactive) + (helm-ff-query-replace-on-marked nil)) + +(defun helm-ff-query-replace (_candidate) + (let ((bufs (cl-loop for f in (helm-marked-candidates) + collect (buffer-name (find-file-noselect f))))) + (helm-run-after-quit #'helm-buffer-query-replace-1 nil bufs))) + +(defun helm-ff-query-replace-regexp (_candidate) + (let ((bufs (cl-loop for f in (helm-marked-candidates) + collect (buffer-name (find-file-noselect f))))) + (helm-run-after-quit #'helm-buffer-query-replace-1 'regexp bufs))) + +(defun helm-ff-run-query-replace () + (interactive) + (helm-ff-query-replace nil)) + +(defun helm-ff-run-query-replace-regexp () + (interactive) + (helm-ff-query-replace-regexp nil)) + +(defun helm-ff-toggle-auto-update (_candidate) + (setq helm-ff-auto-update-flag (not helm-ff-auto-update-flag)) + (setq helm-ff--auto-update-state helm-ff-auto-update-flag) + (message "[Auto expansion %s]" + (if helm-ff-auto-update-flag "enabled" "disabled"))) + +(defun helm-ff-run-toggle-auto-update () + (interactive) + (with-helm-alive-p + (helm-attrset 'toggle-auto-update '(helm-ff-toggle-auto-update . never-split)) + (helm-execute-persistent-action 'toggle-auto-update))) + +(defun helm-ff-delete-char-backward () + "Disable helm find files auto update and delete char backward." + (interactive) + (setq helm-ff-auto-update-flag nil) + (setq helm-ff--deleting-char-backward t) + (call-interactively + (lookup-key (current-global-map) + (read-kbd-macro "DEL")))) + +(defun helm-ff-delete-char-backward--exit-fn () + (setq helm-ff-auto-update-flag helm-ff--auto-update-state) + (setq helm-ff--deleting-char-backward nil)) + +(defun helm-ff-run-switch-to-history () + "Run Switch to history action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (when (helm-file-completion-source-p) + (helm-quit-and-execute-action 'helm-find-files-switch-to-hist)))) + +(defun helm-ff-run-grep () + "Run Grep action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-grep))) + +(defun helm-ff-run-pdfgrep () + "Run Pdfgrep action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-pdfgrep))) + +(defun helm-ff-run-zgrep () + "Run Grep action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-zgrep))) + +(defun helm-ff-run-copy-file () + "Run Copy file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-copy))) + +(defun helm-ff-run-rename-file () + "Run Rename file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-rename))) + +(defun helm-ff-run-byte-compile-file () + "Run Byte compile file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-byte-compile))) + +(defun helm-ff-run-load-file () + "Run Load file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-load-files))) + +(defun helm-ff-run-eshell-command-on-file () + "Run eshell command on file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action + 'helm-find-files-eshell-command-on-file))) + +(defun helm-ff-run-ediff-file () + "Run Ediff file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-ediff-files))) + +(defun helm-ff-run-ediff-merge-file () + "Run Ediff merge file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action + 'helm-find-files-ediff-merge-files))) + +(defun helm-ff-run-symlink-file () + "Run Symlink file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-symlink))) + +(defun helm-ff-run-hardlink-file () + "Run Hardlink file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-files-hardlink))) + +(defun helm-ff-run-delete-file () + "Run Delete file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-delete-marked-files))) + +(defun helm-ff-run-complete-fn-at-point () + "Run complete file name action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action + 'helm-insert-file-name-completion-at-point))) + +(defun helm-ff-run-switch-to-eshell () + "Run switch to eshell action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-switch-to-eshell))) + +(defun helm-ff-run-switch-other-window () + "Run switch to other window action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'find-file-other-window))) + +(defun helm-ff-run-switch-other-frame () + "Run switch to other frame action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'find-file-other-frame))) + +(defun helm-ff-run-open-file-externally () + "Run open file externally command action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-open-file-externally))) + +(defun helm-ff-run-open-file-with-default-tool () + "Run open file externally command action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-open-file-with-default-tool))) + +(defun helm-ff-locate (candidate) + "Locate action function for `helm-find-files'." + (helm-locate-set-command) + (let ((input (concat (helm-basename + (expand-file-name + candidate + helm-ff-default-directory)) + ;; The locate '-b' option doesn't exists + ;; in everything (es). + (unless (and (eq system-type 'windows-nt) + (string-match "^es" helm-locate-command)) + " -b")))) + (helm-locate-1 helm-current-prefix-arg nil 'from-ff input))) + +(defun helm-ff-run-locate () + "Run locate action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-locate))) + +(defun helm-files-insert-as-org-link (candidate) + (insert (format "[[%s][]]" candidate)) + (goto-char (- (point) 2))) + +(defun helm-ff-run-insert-org-link () + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-files-insert-as-org-link))) + +(defun helm-ff-run-find-file-as-root () + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-find-file-as-root))) + +(defun helm-ff-run-gnus-attach-files () + "Run gnus attach files command action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-gnus-attach-files))) + +(defun helm-ff-run-etags () + "Run Etags command action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-etags-select))) + +(defvar lpr-printer-switch) +(defun helm-ff-print (_candidate) + "Print marked files. + +You may to set in order +variables `lpr-command',`lpr-switches' and/or `printer-name', +but with no settings helm should detect your printer(s) and +print with the default `lpr' settings. + +NOTE: DO NOT set the \"-P\" flag in `lpr-switches', if you really +have to modify this, do it in `lpr-printer-switch'. + +Same as `dired-do-print' but for helm." + (require 'lpr) + (when (or helm-current-prefix-arg + (not helm-ff-printer-list)) + (setq helm-ff-printer-list + (helm-ff-find-printers))) + (let* ((file-list (helm-marked-candidates :with-wildcard t)) + (len (length file-list)) + (printer-name (if helm-ff-printer-list + (helm-comp-read + "Printer: " helm-ff-printer-list) + printer-name)) + (lpr-switches + (if (and (stringp printer-name) + (string< "" printer-name)) + (cons (concat lpr-printer-switch printer-name) + lpr-switches) + lpr-switches)) + (command (helm-read-string + (format "Print *%s File(s):\n%s with: " + len + (mapconcat + (lambda (f) (format "- %s\n" f)) + file-list "")) + (when (and lpr-command lpr-switches) + (mapconcat 'identity + (cons lpr-command + (if (stringp lpr-switches) + (list lpr-switches) + lpr-switches)) + " ")))) + (file-args (mapconcat #'(lambda (x) + (format "'%s'" x)) + file-list " ")) + (cmd-line (concat command " " file-args))) + (if command + (start-process-shell-command "helm-print" nil cmd-line) + (error "Error: Please verify your printer settings in Emacs.")))) + +(defun helm-ff-run-print-file () + "Run Print file action from `helm-source-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-print))) + +(defun helm-ff-checksum (file) + "Calculate the checksum of FILE. +The checksum is copied to kill-ring." + (let ((algo (intern (helm-comp-read + "Algorithm: " + '(md5 sha1 sha224 sha256 sha384 sha512))))) + (kill-new (with-temp-buffer + (insert-file-contents-literally file) + (secure-hash algo (current-buffer)))) + (message "Checksum copied to kill-ring."))) + +(defun helm-ff-toggle-basename (_candidate) + (setq helm-ff-transformer-show-only-basename + (not helm-ff-transformer-show-only-basename)) + (let* ((cand (helm-get-selection nil t)) + (target (if helm-ff-transformer-show-only-basename + (helm-basename cand) cand))) + (helm-force-update (regexp-quote target)))) + +(defun helm-ff-run-toggle-basename () + (interactive) + (with-helm-alive-p + (unless (helm-empty-source-p) + (helm-attrset 'toggle-basename '(helm-ff-toggle-basename . never-split)) + (helm-execute-persistent-action 'toggle-basename)))) + +(cl-defun helm-reduce-file-name (fname level &key unix-close expand) + "Reduce FNAME by LEVEL from end or beginning depending LEVEL value. +If LEVEL is positive reduce from end else from beginning. +If UNIX-CLOSE is non--nil close filename with /. +If EXPAND is non--nil expand-file-name." + (let* ((exp-fname (expand-file-name fname)) + (fname-list (split-string (if (or (string= fname "~/") expand) + exp-fname fname) "/" t)) + (len (length fname-list)) + (pop-list (if (< level 0) + (cl-subseq fname-list (* level -1)) + (cl-subseq fname-list 0 (- len level)))) + (result (mapconcat 'identity pop-list "/")) + (empty (string= result ""))) + (when unix-close (setq result (concat result "/"))) + (if (string-match "^~" result) + (if (string= result "~/") "~/" result) + (if (< level 0) + (if empty "../" (concat "../" result)) + (cond ((eq system-type 'windows-nt) + (if empty (expand-file-name "/") ; Expand to "/" or "c:/". + result)) + (empty "/") + (t + (concat "/" result))))))) + +;; Internal +(defvar helm--file-completion-sources + '("Find Files" "Read File Name" "Read File Name History") + "Sources that use the *find-files mechanism can be added here. +Sources generated by `helm-mode' don't need to be added here, it will +be done automatically. +You should not modify this yourself unless you know what you do.") + +(defun helm-file-completion-source-p () + "Return non--nil if current source is a file completion source." + (or minibuffer-completing-file-name + (let ((cur-source (cdr (assoc 'name (helm-get-current-source))))) + (cl-loop for i in helm--file-completion-sources + thereis (string= cur-source i))))) + +(defun helm-find-files-up-one-level (arg) + "Go up one level like unix command `cd ..'. +If prefix numeric arg is given go ARG level up." + (interactive "p") + (with-helm-alive-p + (when (and (helm-file-completion-source-p) + (not (helm-ff-invalid-tramp-name-p))) + (with-helm-window + (when helm-follow-mode + (helm-follow-mode -1) (message nil))) + ;; When going up one level we want to be at the line + ;; corresponding to actual directory, so store this info + ;; in `helm-ff-last-expanded'. + (let ((cur-cand (helm-get-selection)) + (new-pattern (helm-reduce-file-name + helm-pattern arg :unix-close t :expand t))) + (cond ((file-directory-p helm-pattern) + (setq helm-ff-last-expanded helm-ff-default-directory)) + ((file-exists-p helm-pattern) + (setq helm-ff-last-expanded helm-pattern)) + ((and cur-cand (file-exists-p cur-cand)) + (setq helm-ff-last-expanded cur-cand))) + (helm-set-pattern new-pattern helm-suspend-update-flag) + (with-helm-after-update-hook (helm-ff-retrieve-last-expanded)))))) + +(defun helm-ff-retrieve-last-expanded () + "Move overlay to last visited directory `helm-ff-last-expanded'. +This happen after using `helm-find-files-up-one-level', +or hitting C-j on \"..\"." + (when helm-ff-last-expanded + (let ((presel (if helm-ff-transformer-show-only-basename + (helm-basename + (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) + (forward-line 0) + (helm-mark-current-line))) + (setq helm-ff-last-expanded nil)))) + +(defun helm-ff-move-to-first-real-candidate () + "When candidate is an incomplete file name move to first real candidate." + (helm-aif (and (helm-file-completion-source-p) + (not (helm-empty-source-p)) + (not (string-match + "\\`[Dd]ired" + (assoc-default 'name (helm-get-current-source)))) + helm-ff--move-to-first-real-candidate + (helm-get-selection)) + (unless (or (not (stringp it)) + (and (string-match helm-tramp-file-name-regexp it) + (not (file-remote-p it nil t))) + (file-exists-p it)) + (helm-next-line)))) +(add-hook 'helm-after-update-hook 'helm-ff-move-to-first-real-candidate) + +;;; Auto-update - helm-find-files auto expansion of directories. +;; +;; +(defun helm-ff-update-when-only-one-matched () + "Expand to directory when sole completion. +When only one candidate is remaining and it is a directory, +expand to this directory. +This happen only when `helm-ff-auto-update-flag' is non--nil +or when `helm-pattern' is equal to \"~/\"." + (when (or (and helm-ff-auto-update-flag + (null helm-ff--deleting-char-backward) + (helm-file-completion-source-p) + ;; Issue #295 + ;; File predicates are returning t + ;; with paths like //home/foo. + ;; So check it is not the case by regexp + ;; to allow user to do C-a / to start e.g + ;; entering a tramp method e.g /sudo::. + (not (string-match "\\`//" helm-pattern)) + (not (helm-ff-invalid-tramp-name-p))) + ;; Fix issue #542. + (string= helm-pattern "~/")) + (let* ((history-p (string= (assoc-default + 'name (helm-get-current-source)) + "Read File Name History")) + (pat (if (string-match helm-tramp-file-name-regexp + helm-pattern) + (helm-create-tramp-name helm-pattern) + helm-pattern)) + (completed-p (string= (file-name-as-directory + (expand-file-name pat)) + helm-ff-default-directory)) + (candnum (helm-get-candidate-number))) + (when (and (or + ;; Only one candidate remaining + ;; and at least 2 char in basename. + (and (<= candnum 2) + (>= (string-width (helm-basename helm-pattern)) 2)) + ;; Already completed. + completed-p) + (not history-p)) ; Don't try to auto complete in history. + (with-helm-window + (let ((cur-cand (prog2 + (unless (or completed-p (file-exists-p pat)) + ;; Only one non--existing candidate + ;; and one directory candidate, move to it. + (helm-next-line)) + (helm-get-selection)))) + (when (and (stringp cur-cand) + (file-accessible-directory-p cur-cand)) + (if (and (not (helm-dir-is-dot cur-cand)) ; [1] + ;; Maybe we are here because completed-p is true + ;; but check this again to be sure. (Windows fix) + (<= candnum 2)) ; [2] + ;; If after going to next line the candidate + ;; is not one of "." or ".." [1] + ;; and only one candidate is remaining [2], + ;; assume candidate is a new directory to expand, and do it. + (helm-set-pattern (file-name-as-directory cur-cand)) + ;; 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))))) + (helm-check-minibuffer-input)))))))) + +(defun helm-ff-auto-expand-to-home-or-root () + "Allow expanding to home/user directory or root or text yanked after pattern." + (when (and (helm-file-completion-source-p) + (string-match + "/\\$.*/\\|/\\./\\|/\\.\\./\\|/~.*/\\|//\\|\\(/[[:alpha:]]:/\\|\\s\\+\\)" + helm-pattern) + (with-current-buffer (window-buffer (minibuffer-window)) (eolp)) + (not (string-match helm-ff-url-regexp helm-pattern))) + (let* ((match (match-string 0 helm-pattern)) + (input (cond ((string= match "/./") + (expand-file-name default-directory)) + ((string= helm-pattern "/../") "/") + ((string-match-p "\\`/\\$" match) + (let ((sub (substitute-in-file-name match))) + (if (file-directory-p sub) + sub (replace-regexp-in-string "/\\'" "" sub)))) + (t (expand-file-name + (helm-substitute-in-filename helm-pattern) + ;; [Windows] On UNC paths "/" expand to current machine, + ;; so use the root of current Drive. (i.e "C:/") + (and (memq system-type '(windows-nt ms-dos)) + (getenv "SystemDrive")) ; nil on Unix. + ))))) + (if (file-directory-p input) + (setq helm-ff-default-directory + (setq input (file-name-as-directory input))) + (setq helm-ff-default-directory (file-name-as-directory + (file-name-directory input)))) + (with-helm-window + (helm-set-pattern input) + (helm-check-minibuffer-input))))) + +(defun helm-substitute-in-filename (fname) + "Substitute all parts of FNAME from start up to \"~/\" or \"/\". +On windows system substitute from start up to \"/[[:lower:]]:/\". +This function is needed for `helm-ff-auto-expand-to-home-or-root' +and should be used carefully elsewhere, or not at all, using +`substitute-in-file-name' instead." + (if (and ffap-url-regexp + (string-match-p ffap-url-regexp fname)) + fname + (with-temp-buffer + (insert fname) + (goto-char (point-min)) + (skip-chars-forward "/") ;; Avoid infloop in UNC paths Issue #424 + (if (re-search-forward "~.*/?\\|//\\|/[[:alpha:]]:/" nil t) + (let ((match (match-string 0))) + (goto-char (if (or (string= match "//") + (string-match-p "/[[:alpha:]]:/" match)) + (1+ (match-beginning 0)) + (match-beginning 0))) + (buffer-substring-no-properties (point) (point-at-eol))) + fname)))) + +(add-hook 'helm-after-update-hook 'helm-ff-update-when-only-one-matched) +(add-hook 'helm-after-update-hook 'helm-ff-auto-expand-to-home-or-root) + +(defun helm-point-file-in-dired (file) + "Put point on filename FILE in dired buffer." + (unless (and ffap-url-regexp + (string-match-p ffap-url-regexp file)) + (let ((target (expand-file-name (helm-substitute-in-filename file)))) + (dired (file-name-directory target)) + (dired-goto-file target)))) + +(defun helm-create-tramp-name (fname) + "Build filename for `helm-pattern' like /su:: or /sudo::." + (apply #'tramp-make-tramp-file-name + (cl-loop with v = (tramp-dissect-file-name fname) + for i across v collect i))) + +(cl-defun helm-ff-tramp-hostnames (&optional (pattern helm-pattern)) + "Get a list of hosts for tramp method found in `helm-pattern'. +Argument PATTERN default to `helm-pattern', it is here only for debugging +purpose." + (when (string-match helm-tramp-file-name-regexp pattern) + (let ((method (match-string 1 pattern)) + (tn (match-string 0 pattern)) + (all-methods (mapcar 'car tramp-methods))) + (helm-fast-remove-dups + (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)) + when (and host (not (member host all-methods))) + collect (concat tn host))) + :test 'equal)))) + +(defun helm-ff-before-action-hook-fn () + "Exit helm when user try to execute action on an invalid tramp fname." + (let ((cand (helm-get-selection))) + (when (and (helm-file-completion-source-p) + (stringp cand) + (helm-ff-invalid-tramp-name-p cand) ; Check candidate. + (helm-ff-invalid-tramp-name-p)) ; check helm-pattern. + (error "Error: Unknown file or directory `%s'" cand)))) +(add-hook 'helm-before-action-hook 'helm-ff-before-action-hook-fn) + +(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) + "Invalid tramp file name")) + +(defun helm-ff-set-pattern (pattern) + "Handle tramp filenames in `helm-pattern'." + (let ((methods (mapcar 'car tramp-methods)) + (reg "\\`/\\([^[/:]+\\|[^/]+]\\):.*:") + cur-method tramp-name) + ;; In some rare cases tramp can return a nil input, + ;; so be sure pattern is a string for safety (Issue #476). + (unless pattern (setq pattern "")) + (cond ((string-match "\\`\\$" pattern) + (substitute-in-file-name pattern)) + ((string= pattern "") "") + ((string-match "\\`[.]\\{1,2\\}/\\'" pattern) + (expand-file-name pattern)) + ((string-match ".*\\(~?/?[.]\\{1\\}/\\)\\'" pattern) + (expand-file-name default-directory)) + ((and (string-match ".*\\(~//\\|//\\)\\'" pattern) + (not (string-match helm-ff-url-regexp helm-pattern))) + (expand-file-name "/")) ; Expand to "/" or "c:/" + ((string-match "\\`\\(~/\\|.*/~/\\)\\'" pattern) + (expand-file-name "~/")) + ;; Match "/method:maybe_hostname:~" + ((and (string-match (concat reg "~") pattern) + (setq cur-method (match-string 1 pattern)) + (member cur-method methods)) + (setq tramp-name (expand-file-name + (helm-create-tramp-name + (match-string 0 pattern)))) + (replace-match tramp-name nil t pattern)) + ;; Match "/method:maybe_hostname:" + ((and (string-match reg pattern) + (setq cur-method (match-string 1 pattern)) + (member cur-method methods)) + (setq tramp-name (helm-create-tramp-name + (match-string 0 pattern))) + (replace-match tramp-name nil t pattern)) + ;; Match "/hostname:" + ((and (string-match helm-tramp-file-name-regexp pattern) + (setq cur-method (match-string 1 pattern)) + (and cur-method (not (member cur-method methods)))) + (setq tramp-name (helm-create-tramp-name + (match-string 0 pattern))) + (replace-match tramp-name nil t pattern)) + ;; Match "/method:" in this case don't try to connect. + ((and (not (string-match reg pattern)) + (string-match helm-tramp-file-name-regexp pattern) + (member (match-string 1 pattern) methods)) + "Invalid tramp file name") ; Write in helm-buffer. + ;; PATTERN is a directory, end it with "/". + ;; This will make PATTERN not ending yet with "/" + ;; candidate for `helm-ff-default-directory', + ;; allowing `helm-ff-retrieve-last-expanded' to retrieve it + ;; when descending level. + ;; However, we don't add automatically the "/" when + ;; `helm-ff-auto-update-flag' is enabled to avoid quick expansion. + ((and (file-accessible-directory-p pattern) + helm-ff-auto-update-flag) + (file-name-as-directory (expand-file-name pattern))) + ;; Return PATTERN unchanged. + (t pattern)))) + +(defun helm-find-files-get-candidates (&optional require-match) + "Create candidate list for `helm-source-find-files'." + (let* ((path (helm-ff-set-pattern helm-pattern)) + (dir-p (file-accessible-directory-p path)) + basedir + invalid-basedir + non-essential + (tramp-verbose helm-tramp-verbose)) ; No tramp message when 0. + (set-text-properties 0 (length path) nil path) + ;; Issue #118 allow creation of newdir+newfile. + (unless (or + ;; A tramp file name not completed. + (string= path "Invalid tramp file name") + ;; An empty pattern + (string= path "") + ;; Check if base directory of PATH is valid. + (helm-aif (file-name-directory path) + ;; If PATH is a valid directory IT=PATH, + ;; else IT=basedir of PATH. + (file-directory-p it))) + ;; BASEDIR is invalid, that's mean user is starting + ;; to write a non--existing path in minibuffer + ;; probably to create a 'new_dir' or a 'new_dir+new_file'. + (setq invalid-basedir t)) + ;; Don't set now `helm-pattern' if `path' == "Invalid tramp file name" + ;; like that the actual value (e.g /ssh:) is passed to + ;; `helm-ff-tramp-hostnames'. + (unless (or (string= path "Invalid tramp file name") + invalid-basedir) ; Leave helm-pattern unchanged. + (setq helm-ff-auto-update-flag ; [1] + ;; Unless auto update is disabled at startup or + ;; interactively, start auto updating only at third char. + (unless (or (null helm-ff-auto-update-initial-value) + (null helm-ff--auto-update-state) + ;; But don't enable auto update when + ;; deleting backward. + helm-ff--deleting-char-backward) + (or (>= (length (helm-basename path)) 3) dir-p))) + (setq helm-pattern (helm-ff--transform-pattern-for-completion path)) + ;; This have to be set after [1] to allow deleting char backward. + (setq basedir (expand-file-name + (if (and dir-p helm-ff-auto-update-flag) + ;; Add the final "/" to path + ;; when `helm-ff-auto-update-flag' is enabled. + (file-name-as-directory path) + (file-name-directory path)))) + (setq helm-ff-default-directory + (if (string= helm-pattern "") + (expand-file-name "/") ; Expand to "/" or "c:/" + ;; If path is an url *default-directory have to be nil. + (unless (or (string-match helm-ff-url-regexp path) + (and ffap-url-regexp + (string-match ffap-url-regexp path))) + basedir)))) + (cond ((string= path "Invalid tramp file name") + (or (helm-ff-tramp-hostnames) ; Hostnames completion. + (prog2 + ;; `helm-pattern' have not been modified yet. + ;; Set it here to the value of `path' that should be now + ;; "Invalid tramp file name" and set the candidates list + ;; to ("Invalid tramp file name") to make `helm-pattern' + ;; match single candidate "Invalid tramp file name". + (setq helm-pattern path) + ;; "Invalid tramp file name" is now printed + ;; in `helm-buffer'. + (list path)))) + ((or (and (file-regular-p path) + (eq last-repeatable-command 'helm-execute-persistent-action)) + ;; `ffap-url-regexp' don't match until url is complete. + (string-match helm-ff-url-regexp path) + invalid-basedir + (and (not (file-exists-p path)) (string-match "/$" path)) + (and ffap-url-regexp (string-match ffap-url-regexp path))) + (list path)) + ((string= path "") (helm-ff-directory-files "/" t)) + ((and (file-directory-p path) (not (file-readable-p path))) + (list (format "Opening directory: access denied, `%s'" path))) + ;; A fast expansion of PATH is made only if `helm-ff-auto-update-flag' + ;; is enabled. + ((and dir-p helm-ff-auto-update-flag) + (helm-ff-directory-files path t)) + (t (append (unless (or require-match + ;; When `helm-ff-auto-update-flag' has been + ;; disabled, whe don't want PATH to be added on top + ;; if it is a directory. + dir-p) + (list path)) + (helm-ff-directory-files basedir t)))))) + +(defsubst helm-ff-directory-files (directory &optional full) + "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 +systems." + (setq directory (file-name-as-directory + (expand-file-name directory))) + (let ((ls (directory-files + directory full directory-files-no-dot-files-regexp)) + (dot (concat directory ".")) + (dot2 (concat directory ".."))) + (append (list dot dot2) ls))) + +(defun helm-ff-handle-backslash (fname) + ;; Allow creation of filenames containing a backslash. + (cl-loop with bad = '((92 . "")) + for i across fname + for isbad = (assq i bad) + if isbad concat (cdr isbad) + else concat (string i))) + +(defun helm-ff-smart-completion-p () + (and helm-ff-smart-completion + (not (memq helm-mp-matching-method '(multi1 multi3p))))) + +(defun helm-ff--transform-pattern-for-completion (pattern) + "Maybe return PATTERN with it's basename modified as a regexp. +This happen only when `helm-ff-smart-completion' is enabled. +This provide a similar behavior as `ido-enable-flex-matching'. +See also `helm--mapconcat-pattern'. +If PATTERN is an url returns it unmodified. +When PATTERN contain a space fallback to match-plugin. +If basename contain one or more space fallback to match-plugin. +If PATTERN is a valid directory name,return PATTERN unchanged." + ;; handle bad filenames containing a backslash. + (setq pattern (helm-ff-handle-backslash pattern)) + (let ((bn (helm-basename pattern)) + (bd (or (helm-basedir pattern) "")) + (dir-p (file-directory-p pattern)) + (tramp-p (cl-loop for (m . f) in tramp-methods + thereis (string-match m pattern)))) + ;; Always regexp-quote base directory name to handle + ;; crap dirnames such e.g bookmark+ + (cond + ((or (and dir-p tramp-p (string-match ":\\'" pattern)) + (string= pattern "") + (and dir-p (<= (length bn) 2)) + ;; Fix Issue #541 when BD have a subdir similar + ;; to BN, don't switch to match plugin + ;; which will match both. + (and dir-p (string-match (regexp-quote bn) bd))) + ;; Use full PATTERN on e.g "/ssh:host:". + (regexp-quote pattern)) + ;; Prefixing BN with a space call match-plugin completion. + ;; This allow showing all files/dirs matching BN (Issue #518). + ;; FIXME: some match-plugin methods may not work here. + (dir-p (concat (regexp-quote bd) " " (regexp-quote bn))) + ((or (not (helm-ff-smart-completion-p)) + (string-match "\\s-" bn)) ; Fall back to match-plugin. + (concat (regexp-quote bd) bn)) + ((or (string-match "[*][.]?.*" bn) ; Allow entering wilcard. + (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. + ;; (e.g ./foo/*.el => ./foo/[*].el) + (concat (regexp-quote bd) + (replace-regexp-in-string "[*]" "[*]" bn))) + (t + (setq bn (if (>= (length bn) 2) ; wait 2nd char before concating. + (helm--mapconcat-pattern bn) + (concat ".*" (regexp-quote bn)))) + (concat (regexp-quote bd) bn))))) + +(defun helm-dir-is-dot (dir) + (string-match "\\(?:/\\|\\`\\)\\.\\{1,2\\}\\'" dir)) + +(defun helm-ff-save-history () + "Store the last value of `helm-ff-default-directory' in `helm-ff-history'. +Note that only existing directories are saved here." + (when (and helm-ff-default-directory + (helm-file-completion-source-p) + (file-directory-p helm-ff-default-directory)) + (set-text-properties 0 (length helm-ff-default-directory) + nil helm-ff-default-directory) + (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 selected file to `file-name-history'." + (let ((src-name (assoc-default 'name (helm-get-current-source)))) + (when (or force (helm-file-completion-source-p) + (member src-name helm-files-save-history-extra-sources)) + (let ((mkd (helm-marked-candidates)) + (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) + (helm-aif (condition-case-unless-debug nil + ;; `file-truename' send error + ;; on cyclic symlinks (Issue #692). + (file-truename file) + (error nil)) + (file-exists-p it))) + +(defun helm-get-default-mode-for-file (filename) + "Return the default mode to open FILENAME." + (let ((mode (cl-loop for (r . m) in auto-mode-alist + thereis (and (string-match r filename) m)))) + (or (and (symbolp mode) mode) "Fundamental"))) + +(defun helm-ff-properties (candidate) + "Show file properties of CANDIDATE in a tooltip or message." + (let* ((all (helm-file-attributes candidate)) + (dired-line (helm-file-attributes + candidate :dired t :human-size t)) + (type (cl-getf all :type)) + (mode-type (cl-getf all :mode-type)) + (owner (cl-getf all :uid)) + (owner-right (cl-getf all :user t)) + (group (cl-getf all :gid)) + (group-right (cl-getf all :group)) + (other-right (cl-getf all :other)) + (size (helm-file-human-size (cl-getf all :size))) + (modif (cl-getf all :modif-time)) + (access (cl-getf all :access-time)) + (ext (helm-get-default-program-for-file candidate)) + (tooltip-hide-delay (or helm-tooltip-hide-delay tooltip-hide-delay))) + (if (and (window-system) tooltip-mode) + (tooltip-show + (concat + (helm-basename candidate) "\n" + dired-line "\n" + (format "Mode: %s\n" (helm-get-default-mode-for-file candidate)) + (format "Ext prog: %s\n" (or (and ext (replace-regexp-in-string + " %s" "" ext)) + "Not defined")) + (format "Type: %s: %s\n" type mode-type) + (when (string= type "symlink") + (format "True name: '%s'\n" + (cond ((string-match "^\.#" (helm-basename candidate)) + "Autosave symlink") + ((helm-ff-valid-symlink-p candidate) + (file-truename candidate)) + (t "Invalid Symlink")))) + (format "Owner: %s: %s\n" owner owner-right) + (format "Group: %s: %s\n" group group-right) + (format "Others: %s\n" other-right) + (format "Size: %s\n" size) + (format "Modified: %s\n" modif) + (format "Accessed: %s\n" access))) + (message dired-line) (sit-for 5)))) + +(defun helm-ff-properties-persistent () + "Show properties without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'properties-action '(helm-ff-properties . never-split)) + (helm-execute-persistent-action 'properties-action))) + +(defun helm-ff-persistent-delete () + "Delete current candidate without quitting." + (interactive) + (with-helm-alive-p + (helm-attrset 'quick-delete '(helm-ff-quick-delete . never-split)) + (helm-execute-persistent-action 'quick-delete))) + +(defun helm-ff-dot-file-p (file) + "Check if FILE is `.' or `..'." + (member (helm-basename file) '("." ".."))) + +(defun helm-ff-quick-delete (_candidate) + "Delete file CANDIDATE without quitting." + (let ((marked (helm-marked-candidates))) + (unwind-protect + (save-selected-window + (cl-loop for c in marked do + (progn (helm-preselect (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 Delete file `%s'? " c)) + (helm-delete-file c helm-ff-signal-error-on-dot-files + 'synchro) + (helm-delete-current-selection) + (message nil))))) + (with-helm-buffer + (setq helm-marked-candidates nil + helm-visible-mark-overlays nil)) + (helm-force-update)))) + +(defun helm-ff-kill-buffer-fname (candidate) + (let ((buf (get-file-buffer candidate))) + (if buf + (progn + (kill-buffer buf) (message "Buffer `%s' killed" buf)) + (message "No buffer to kill")))) + +(defun helm-ff-kill-or-find-buffer-fname (candidate) + "Find file CANDIDATE or kill it's buffer if it is visible. +Never kill `helm-current-buffer'. +Never kill buffer modified. +This is called normally on third hit of \ +\\\\[helm-execute-persistent-action] +in `helm-find-files-persistent-action'." + (let* ((buf (get-file-buffer candidate)) + (buf-name (buffer-name buf)) + (win (get-buffer-window buf)) + (helm--reading-passwd-or-string t)) + (if (and buf win + (not (eq buf (get-buffer helm-current-buffer))) + (not (buffer-modified-p buf))) + (progn + (kill-buffer buf) + (set-window-buffer win helm-current-buffer) + (message "Buffer `%s' killed" buf-name)) + (find-file candidate)))) + +(defun helm-ff-run-kill-buffer-persistent () + "Execute `helm-ff-kill-buffer-fname' whitout quitting." + (interactive) + (with-helm-alive-p + (helm-attrset 'kill-buffer-fname 'helm-ff-kill-buffer-fname) + (helm-execute-persistent-action 'kill-buffer-fname))) + +(defun helm-ff-prefix-filename (fname &optional file-or-symlinkp new-file) + "Return filename FNAME maybe prefixed with [?] or [@]. +If FILE-OR-SYMLINKP is non--nil this mean we assume FNAME is an +existing filename or valid symlink and there is no need to test it. +NEW-FILE when non--nil mean FNAME is a non existing file and +return FNAME prefixed with [?]." + (let* ((prefix-new (propertize + " " 'display + (propertize "[?]" 'face 'helm-ff-prefix))) + (prefix-url (propertize + " " 'display + (propertize "[@]" 'face 'helm-ff-prefix)))) + (cond ((or file-or-symlinkp (file-exists-p fname)) fname) + ((or (string-match helm-ff-url-regexp fname) + (and ffap-url-regexp (string-match ffap-url-regexp fname))) + (concat prefix-url " " fname)) + ((or new-file (not (file-exists-p fname))) + (concat prefix-new " " fname))))) + +(defun helm-ff-score-candidate-for-pattern (str pattern) + (if (member str '("." "..")) + 200 + (helm-score-candidate-for-pattern str pattern))) + +(defun helm-ff-sort-candidates (candidates _source) + "Sort function for `helm-source-find-files'. +Return candidates prefixed with basename of `helm-input' first." + (if (or (and (file-directory-p helm-input) + (string-match "/\\'" helm-input)) + (string-match "\\`\\$" helm-input) + (null candidates)) + candidates + (let* ((c1 (car candidates)) + (cand1real (if (consp c1) (cdr c1) c1)) + (cand1 (unless (file-exists-p cand1real) c1)) + (rest-cand (if cand1 (cdr candidates) candidates)) + (memo-src (make-hash-table :test 'equal)) + (all (sort rest-cand + #'(lambda (s1 s2) + (let* ((score (lambda (str) + (helm-ff-score-candidate-for-pattern + str (helm-basename helm-input)))) + (bn1 (helm-basename (if (consp s1) (cdr s1) s1))) + (bn2 (helm-basename (if (consp s2) (cdr s2) s2))) + (sc1 (or (gethash bn1 memo-src) + (puthash bn1 (funcall score bn1) memo-src))) + (sc2 (or (gethash bn2 memo-src) + (puthash bn2 (funcall score bn2) memo-src)))) + (cond ((= sc1 sc2) + (< (string-width bn1) + (string-width bn2))) + ((> sc1 sc2)))))))) + (if cand1 (cons cand1 all) all)))) + +(defun helm-ff-filter-candidate-one-by-one (file) + "`filter-one-by-one' Transformer function for `helm-source-find-files'." + ;; Handle boring files + (unless (and helm-ff-skip-boring-files + (cl-loop for r in helm-boring-file-regexp-list + ;; Prevent user doing silly thing like + ;; adding the dotted files to boring regexps (#924). + thereis (and (not (string-match "\\.$" file)) + (string-match r file)))) + ;; Handle tramp files. + (if (and (string-match helm-tramp-file-name-regexp helm-pattern) + helm-ff-tramp-not-fancy) + (if helm-ff-transformer-show-only-basename + (if (helm-dir-is-dot file) + file + (cons (or (helm-ff-get-host-from-tramp-invalid-fname file) + (helm-basename file)) + file)) + file) + ;; Now highlight. + (let* ((disp (if (and helm-ff-transformer-show-only-basename + (not (helm-dir-is-dot file)) + (not (and ffap-url-regexp + (string-match ffap-url-regexp file))) + (not (string-match helm-ff-url-regexp file))) + (or (helm-ff-get-host-from-tramp-invalid-fname file) + (helm-basename file)) file)) + (attr (file-attributes file)) + (type (car attr))) + + (cond ((string-match "access denied" file) file) + ( ;; A not already saved file. + (and (stringp type) + (not (helm-ff-valid-symlink-p file)) + (not (string-match "^\.#" (helm-basename file)))) + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-invalid-symlink) t) + file)) + ;; A symlink. + ((stringp type) + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-symlink) t) + file)) + ;; A dotted directory. + ((and (eq t type) (helm-ff-dot-file-p file)) + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-dotted-directory) t) + file)) + ;; A directory. + ((eq t type) + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-directory) t) + file)) + ;; An executable file. + ((and attr (string-match "x" (nth 8 attr))) + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-executable) t) + file)) + ;; A file. + ((and attr (null type)) + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-file) t) + file)) + ;; A non--existing file. + (t + (cons (helm-ff-prefix-filename + (propertize disp 'face 'helm-ff-file) nil 'new-file) + file))))))) + +(defun helm-find-files-action-transformer (actions candidate) + "Action transformer for `helm-source-find-files'." + (cond ((with-helm-current-buffer + (eq major-mode 'message-mode)) + (append actions + '(("Gnus attach file(s)" . helm-ff-gnus-attach-files)))) + ((string-match (image-file-name-regexp) candidate) + (append actions + '(("Rotate image right `M-r'" . helm-ff-rotate-image-right) + ("Rotate image left `M-l'" . helm-ff-rotate-image-left)))) + ((string-match "\.el$" (helm-aif (helm-marked-candidates) + (car it) candidate)) + (append 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)))) + ((and (string-match "\.html?$" candidate) + (file-exists-p candidate)) + (append actions + '(("Browse url file" . browse-url-of-file)))) + ((or (string= (file-name-extension candidate) "pdf") + (string= (file-name-extension candidate) "PDF")) + (append actions + '(("Pdfgrep File(s)" . helm-ff-pdfgrep)))) + (t actions))) + +(defun helm-ff-gnus-attach-files (_candidate) + "Run `gnus-dired-attach' on `helm-marked-candidates' or CANDIDATE." + (require 'gnus-dired) + (let ((flist (helm-marked-candidates :with-wildcard t))) + (gnus-dired-attach flist))) + +(defvar image-dired-display-image-buffer) +(defun helm-ff-rotate-current-image-1 (file &optional num-arg) + "Rotate current image at NUM-ARG degrees. +This is a destructive operation on FILE made by external tool mogrify." + (setq file (file-truename file)) ; For symlinked images. + ;; When FILE is not an image-file, do nothing. + (when (string-match (image-file-name-regexp) file) + (if (executable-find "mogrify") + (progn + (shell-command (format "mogrify -rotate %s %s" + (or num-arg 90) + (shell-quote-argument file))) + (when (buffer-live-p image-dired-display-image-buffer) + (kill-buffer image-dired-display-image-buffer)) + (image-dired-display-image file) + (message nil) + (display-buffer (get-buffer image-dired-display-image-buffer))) + (error "mogrify not found")))) + +(defun helm-ff-rotate-image-left (candidate) + "Rotate image file CANDIDATE left. +This affect directly file CANDIDATE." + (helm-ff-rotate-current-image-1 candidate -90)) + +(defun helm-ff-rotate-image-right (candidate) + "Rotate image file CANDIDATE right. +This affect directly file CANDIDATE." + (helm-ff-rotate-current-image-1 candidate)) + +(defun helm-ff-rotate-left-persistent () + "Rotate image left without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'image-action1 'helm-ff-rotate-image-left) + (helm-execute-persistent-action 'image-action1))) + +(defun helm-ff-rotate-right-persistent () + "Rotate image right without quitting helm." + (interactive) + (with-helm-alive-p + (helm-attrset 'image-action2 'helm-ff-rotate-image-right) + (helm-execute-persistent-action 'image-action2))) + +(defun helm-ff-exif-data (candidate) + "Extract exif data from file CANDIDATE using `helm-ff-exif-data-program'." + (if (and helm-ff-exif-data-program + (executable-find helm-ff-exif-data-program)) + (shell-command-to-string (format "%s %s %s" + helm-ff-exif-data-program + helm-ff-exif-data-program-args + candidate)) + (format "No program %s found to extract exif" + helm-ff-exif-data-program))) + +(defun helm-find-files-persistent-action (candidate) + "Open subtree CANDIDATE without quitting helm. +If CANDIDATE is not a directory expand CANDIDATE filename. +If CANDIDATE is alone, open file CANDIDATE filename. +That's mean: +First hit on C-j expand CANDIDATE second hit open file. +If a prefix arg is given or `helm-follow-mode' is on open file." + (let* ((follow (or (buffer-local-value + 'helm-follow-mode + (get-buffer-create helm-buffer)) + helm--temp-follow-flag)) + (new-pattern (helm-get-selection)) + (num-lines-buf (with-current-buffer helm-buffer + (count-lines (point-min) (point-max)))) + (insert-in-minibuffer #'(lambda (fname) + (with-selected-window (minibuffer-window) + (unless follow + (delete-minibuffer-contents) + (set-text-properties 0 (length fname) + nil fname) + (insert fname)))))) + (cond ((and (helm-ff-invalid-tramp-name-p) + (string-match helm-tramp-file-name-regexp candidate)) + ;; First hit insert hostname and + ;; second hit insert ":" and expand. + (if (string= candidate helm-pattern) + (funcall insert-in-minibuffer (concat candidate ":")) + (funcall insert-in-minibuffer candidate))) + ( ;; A symlink directory, expand it's truename. + (and (file-directory-p candidate) (file-symlink-p candidate)) + (funcall insert-in-minibuffer (file-name-as-directory + (file-truename + (expand-file-name candidate))))) + ;; A directory, open it. + ((file-directory-p candidate) + (when (string= (helm-basename candidate) "..") + (setq helm-ff-last-expanded helm-ff-default-directory)) + (funcall insert-in-minibuffer (file-name-as-directory + (expand-file-name candidate)))) + ;; A symlink file, expand to it's true name. (first hit) + ((and (file-symlink-p candidate) (not current-prefix-arg) (not follow)) + (funcall insert-in-minibuffer (file-truename candidate))) + ;; A regular file, expand it, (first hit) + ((and (>= num-lines-buf 3) (not current-prefix-arg) (not follow)) + (setq helm-pattern "") ; Force update. + (funcall insert-in-minibuffer new-pattern)) + ;; An image file and it is the second hit on C-j, + ;; show the file in `image-dired'. + ((string-match (image-file-name-regexp) candidate) + (when (buffer-live-p (get-buffer image-dired-display-image-buffer)) + (kill-buffer image-dired-display-image-buffer)) + ;; Fix emacs bug never fixed upstream. + (unless (file-directory-p image-dired-dir) + (make-directory image-dired-dir)) + (image-dired-display-image candidate) + (message nil) + (switch-to-buffer image-dired-display-image-buffer) + (with-current-buffer image-dired-display-image-buffer + (let ((exif-data (helm-ff-exif-data candidate))) + (setq default-directory helm-ff-default-directory) + (image-dired-update-property 'help-echo exif-data)))) + ;; Allow browsing archive on avfs fs. + ;; Assume volume is already mounted with mountavfs. + ((and helm-ff-avfs-directory + (string-match + (regexp-quote (expand-file-name helm-ff-avfs-directory)) + (file-name-directory candidate)) + (helm-ff-file-compressed-p candidate)) + (funcall insert-in-minibuffer (concat candidate "#"))) + ;; On second hit we open file. + ;; On Third hit we kill it's buffer maybe. + (t + (helm-ff-kill-or-find-buffer-fname candidate))))) + +(defun helm-ff-file-compressed-p (candidate) + "Whether CANDIDATE is a compressed file or not." + (member (file-name-extension candidate) + helm-ff-file-compressed-list)) + +(defun helm-insert-file-name-completion-at-point (candidate) + "Insert file name completion at point." + (with-helm-current-buffer + (if buffer-read-only + (error "Error: Buffer `%s' is read-only" (buffer-name)) + (let* ((end (point)) + (tap (thing-at-point 'filename)) + (guess (and (stringp tap) (substring-no-properties tap))) + (beg (- (point) (length guess))) + (full-path-p (and (stringp guess) + (or (string-match-p + (concat "^" (getenv "HOME")) + guess) + (string-match-p + "\\`\\(/\\|[[:lower:][:upper:]]:/\\)" + guess))))) + (set-text-properties 0 (length candidate) nil candidate) + (if (and guess (not (string= guess "")) + (or (string-match "^\\(~/\\|/\\|[[:lower:][:upper:]]:/\\)" + guess) + (file-exists-p candidate))) + (progn + (delete-region beg end) + (insert (cond (full-path-p + (expand-file-name candidate)) + ((string= (match-string 1 guess) "~/") + (abbreviate-file-name candidate)) + (t (file-relative-name candidate))))) + (insert (cond ((equal helm-current-prefix-arg '(4)) + (abbreviate-file-name candidate)) + ((equal helm-current-prefix-arg '(16)) + (file-relative-name candidate)) + (t candidate)))))))) + +(cl-defun helm-find-files-history (&key (comp-read t)) + "The `helm-find-files' history. +Show the first `helm-ff-history-max-length' elements of +`helm-ff-history' in an `helm-comp-read'." + (let ((history (when helm-ff-history + (helm-fast-remove-dups helm-ff-history + :test 'equal)))) + (when history + (setq helm-ff-history + (if (>= (length history) helm-ff-history-max-length) + (cl-subseq history 0 helm-ff-history-max-length) + history)) + (if comp-read + (helm-comp-read + "Switch to Directory: " + helm-ff-history + :name "Helm Find Files History" + :must-match t) + helm-ff-history)))) + +(defun helm-find-files-1 (fname &optional preselect) + "Find FNAME with `helm' completion. +Like `find-file' but with `helm' support. +Use it for non--interactive calls of `helm-find-files'." + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + (let* ( ;; Be sure we don't erase the precedent minibuffer if some. + (helm-ff-auto-update-initial-value + (and helm-ff-auto-update-initial-value + (not (minibuffer-window-active-p (minibuffer-window))))) + (tap (thing-at-point 'filename)) + (def (and tap (or (file-remote-p tap) + (expand-file-name tap))))) + (unless helm-source-find-files + (setq helm-source-find-files (helm-make-source + "Find Files" 'helm-source-ffiles))) + (helm :sources 'helm-source-find-files + :input fname + :case-fold-search helm-file-name-case-fold-search + :keymap helm-find-files-map + :preselect preselect + :default def + :prompt "Find Files or Url: " + :buffer "*Helm Find Files*"))) + + +(defun helm-find-files-initial-input (&optional input) + "Return INPUT if present, otherwise try to guess it." + (let ((ffap-machine-p-known 'reject)) + (unless (eq major-mode 'image-mode) + (or (and input (or (and (file-remote-p input) input) + (expand-file-name input))) + (helm-find-files-input + (ffap-guesser) + (thing-at-point 'filename)))))) + +(defun helm-find-files-input (file-at-pt thing-at-pt) + "Try to guess a default input for `helm-find-files'." + (let* ((non-essential t) + (remp (or (and file-at-pt (file-remote-p file-at-pt)) + (and thing-at-pt (file-remote-p thing-at-pt)))) + (def-dir (helm-current-directory)) + (urlp (and file-at-pt ffap-url-regexp + (string-match ffap-url-regexp file-at-pt))) + (lib (when helm-ff-search-library-in-sexp + (helm-find-library-at-point))) + (hlink (helm-ff-find-url-at-point)) + (file-p (and file-at-pt + (not (string= file-at-pt "")) + (not remp) + (file-exists-p file-at-pt) + thing-at-pt + (not (string= thing-at-pt "")) + (file-exists-p + (file-name-directory + (expand-file-name thing-at-pt def-dir)))))) + (cond (lib) ; e.g we are inside a require sexp. + (hlink) ; String at point is an hyperlink. + (file-p ; a regular file + (helm-aif (ffap-file-at-point) (expand-file-name it))) + (urlp file-at-pt) ; possibly an url or email. + ((and file-at-pt + (not remp) + (file-exists-p file-at-pt)) + file-at-pt)))) + +(defun helm-ff-find-url-at-point () + "Try to find link to an url in text-property at point." + (let* ((he (get-text-property (point) 'help-echo)) + (ov (overlays-at (point))) + (ov-he (and ov (overlay-get + (car (overlays-at (point))) 'help-echo))) + (w3m-l (get-text-property (point) 'w3m-href-anchor)) + (nt-prop (get-text-property (point) 'nt-link))) + ;; Org link. + (when (and (stringp he) (string-match "^LINK: " he)) + (setq he (replace-match "" t t he))) + (cl-loop for i in (list he ov-he w3m-l nt-prop) + thereis (and (stringp i) ffap-url-regexp (string-match ffap-url-regexp i) i)))) + +(defun helm-find-library-at-point () + "Try to find library path at point. +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))) + (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))))) + (t nil))))) + + +;;; Handle copy, rename, symlink, relsymlink and hardlink from helm. +;; +;; +(defvar dired-async-be-async) +(cl-defun helm-dired-action (candidate + &key action follow (files (dired-get-marked-files))) + "Execute ACTION on FILES to CANDIDATE. +Where ACTION is a symbol that can be one of: +'copy, 'rename, 'symlink,'relsymlink, 'hardlink. +Argument FOLLOW when non--nil specify to follow FILES to destination for the actions +copy and rename." + (when (get-buffer dired-log-buffer) (kill-buffer dired-log-buffer)) + (let ((fn (cl-case action + (copy 'dired-copy-file) + (rename 'dired-rename-file) + (symlink 'make-symbolic-link) + (relsymlink 'dired-make-relative-symlink) + (hardlink 'dired-hardlink))) + (marker (cl-case action + ((copy rename) dired-keep-marker-copy) + (symlink dired-keep-marker-symlink) + (relsymlink dired-keep-marker-relsymlink) + (hardlink dired-keep-marker-hardlink))) + (dirflag (and (= (length files) 1) + (file-directory-p (car files)) + (not (file-directory-p candidate)))) + ;; When FOLLOW is enabled, disable helm-async. + ;; If it is globally disabled use this nil value. + (dired-async-be-async (and (boundp 'dired-async-be-async) + dired-async-be-async + (not follow)))) + (dired-create-files + fn (symbol-name action) files + ;; CANDIDATE is the destination. + (if (file-directory-p candidate) + ;; When CANDIDATE is a directory, build file-name in this directory. + ;; Else we use CANDIDATE. + #'(lambda (from) + (expand-file-name (file-name-nondirectory from) candidate)) + #'(lambda (_from) candidate)) + marker) + (push (file-name-as-directory + (if (file-directory-p candidate) + (expand-file-name candidate) + (file-name-directory candidate))) + helm-ff-history) + ;; If follow is non--nil we should not be in async mode. + (when (and follow + (not (memq action '(symlink relsymlink hardlink))) + (not (get-buffer dired-log-buffer))) + (let ((target (directory-file-name candidate))) + (unwind-protect + (progn + (setq helm-ff-cand-to-mark + (helm-get-dest-fnames-from-list files candidate dirflag)) + (with-helm-after-update-hook (helm-ff-maybe-mark-candidates)) + (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 (file-name-as-directory + (expand-file-name candidate))))) + (setq helm-ff-cand-to-mark nil)))))) + +(defun helm-get-dest-fnames-from-list (flist dest-cand rename-dir-flag) + "Transform filenames of FLIST to abs of DEST-CAND. +If RENAME-DIR-FLAG is non--nil collect the `directory-file-name' of transformed +members of FLIST." + ;; At this point files have been renamed/copied at destination. + ;; That's mean DEST-CAND exists. + (cl-loop + with dest = (expand-file-name dest-cand) + for src in flist + for basename-src = (helm-basename src) + for fname = (cond (rename-dir-flag (directory-file-name dest)) + ((file-directory-p dest) + (concat (file-name-as-directory dest) basename-src)) + (t dest)) + when (file-exists-p fname) + 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'. +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) + (with-helm-window + (while helm-ff-cand-to-mark + (if (string= (car helm-ff-cand-to-mark) (helm-get-selection)) + (progn + (helm-make-visible-mark) + (helm-next-line) + (setq helm-ff-cand-to-mark (cdr helm-ff-cand-to-mark))) + (helm-next-line))) + (unless (helm-this-visible-mark) + (helm-prev-visible-mark))))) + + +;;; Routines for files +;; +;; +(defun helm-file-buffers (filename) + "Returns a list of buffer names corresponding to FILENAME." + (cl-loop with name = (expand-file-name filename) + for buf in (buffer-list) + for bfn = (buffer-file-name buf) + when (and bfn (string= name bfn)) + collect (buffer-name buf))) + +(defun helm-delete-file (file &optional error-if-dot-file-p synchro) + "Delete the given file after querying the user. +Ask to kill buffers associated with that file, too." + (when (and error-if-dot-file-p + (helm-ff-dot-file-p file)) + (error "Error: Cannot operate on `.' or `..'")) + (let ((buffers (helm-file-buffers file)) + (helm--reading-passwd-or-string t)) + (if (or (< emacs-major-version 24) synchro) + ;; `dired-delete-file' in Emacs versions < 24 + ;; doesn't support delete-by-moving-to-trash + ;; so use `delete-directory' and `delete-file' + ;; that handle it. + (cond ((and (not (file-symlink-p file)) + (file-directory-p file) + (directory-files file t dired-re-no-dot)) + (when (y-or-n-p (format "Recursive delete of `%s'? " file)) + (delete-directory file 'recursive))) + ((and (not (file-symlink-p file)) + (file-directory-p file)) + (delete-directory file)) + (t (delete-file file))) + (dired-delete-file + file dired-recursive-deletes delete-by-moving-to-trash)) + (when buffers + (cl-dolist (buf buffers) + (when (y-or-n-p (format "Kill buffer %s, too? " buf)) + (kill-buffer buf)))))) + +(defun helm-delete-marked-files (_ignore) + (let* ((files (helm-marked-candidates :with-wildcard t)) + (len (length files))) + (with-helm-display-marked-candidates + helm-marked-buffer-name + (mapcar #'(lambda (f) + (if (file-directory-p f) + (concat (helm-basename f) "/") + (helm-basename f))) + files) + (if (not (y-or-n-p (format "Delete *%s File(s)" len))) + (message "(No deletions performed)") + (cl-dolist (i files) + (set-text-properties 0 (length i) nil i) + (helm-delete-file i helm-ff-signal-error-on-dot-files)) + (message "%s File(s) deleted" len))))) + +(defun helm-find-file-or-marked (candidate) + "Open file CANDIDATE or open helm marked files in separate windows. +Called with a prefix arg open files in background without selecting them." + (let ((marked (helm-marked-candidates :with-wildcard t)) + (url-p (and ffap-url-regexp ; we should have only one candidate. + (string-match ffap-url-regexp candidate))) + (ffap-newfile-prompt helm-ff-newfile-prompt-p) + (find-file-wildcards nil) + (make-dir-fn + #'(lambda (dir &optional helm-ff) + (when (y-or-n-p (format "Create directory `%s'? " dir)) + (let ((dirfname (directory-file-name dir))) + (if (file-exists-p dirfname) + (error + "Mkdir: Unable to create directory `%s': file exists." + (helm-basename dirfname)) + (make-directory dir 'parent))) + (when helm-ff + ;; Allow having this new dir in history + ;; to be able to retrieve it immediately + ;; if we want to e.g copy a file from somewhere in it. + (setq helm-ff-default-directory + (file-name-as-directory dir)) + (push helm-ff-default-directory helm-ff-history)) + (or (and helm-ff (helm-find-files-1 dir)) t)))) + (helm--reading-passwd-or-string t)) + (if (cdr marked) + (if helm-current-prefix-arg + (dired-simultaneous-find-file marked nil) + (mapc 'find-file-noselect (cdr marked)) + (find-file (car marked))) + (if (and (not (file-exists-p candidate)) + (not url-p) + (string-match "/$" candidate)) + ;; A a non--existing filename ending with / + ;; Create a directory and jump to it. + (funcall make-dir-fn candidate 'helm-ff) + ;; A non--existing filename NOT ending with / or + ;; an existing filename, create or jump to it. + ;; If the basedir of candidate doesn't exists, + ;; ask for creating it. + (let ((dir (file-name-directory candidate))) + (find-file-at-point + (cond ((and dir (file-directory-p dir)) + (substitute-in-file-name (car marked))) + ;; FIXME Why do we use this on urls ? + (url-p (helm-substitute-in-filename (car marked))) + ((funcall make-dir-fn dir) candidate)))))))) + +(defun helm-shadow-boring-files (files) + "Files matching `helm-boring-file-regexp' will be +displayed with the `file-name-shadow' face if available." + (helm-shadow-entries files helm-boring-file-regexp-list)) + +(defun helm-skip-boring-files (files) + "Files matching `helm-boring-file-regexp' will be skipped." + (helm-skip-entries files helm-boring-file-regexp-list)) + +(defun helm-skip-current-file (files) + "Current file will be skipped." + (remove (buffer-file-name helm-current-buffer) files)) + +(defun helm-w32-pathname-transformer (args) + "Change undesirable features of windows pathnames to ones more acceptable to +other candidate transformers." + (if (eq system-type 'windows-nt) + (helm-transform-mapcar + (lambda (x) + (replace-regexp-in-string + "/cygdrive/\\(.\\)" "\\1:" + (replace-regexp-in-string "\\\\" "/" x))) + args) + args)) + +(defun helm-transform-file-load-el (actions candidate) + "Add action to load the file CANDIDATE if it is an emacs lisp +file. Else return ACTIONS unmodified." + (if (member (file-name-extension candidate) '("el" "elc")) + (append actions '(("Load Emacs Lisp File" . load-file))) + actions)) + +(defun helm-transform-file-browse-url (actions candidate) + "Add an action to browse the file CANDIDATE if it is a html file or URL. +Else return ACTIONS unmodified." + (let ((browse-action '("Browse with Browser" . browse-url))) + (cond ((string-match "^http\\|^ftp" candidate) + (cons browse-action actions)) + ((string-match "\\.html?$" candidate) + (append actions (list browse-action))) + (t actions)))) + +(defun helm-multi-files-toggle-to-locate () + (interactive) + (with-helm-buffer + (if (setq helm-multi-files--toggle-locate + (not helm-multi-files--toggle-locate)) + (progn + (helm-set-sources (unless (memq 'helm-source-locate + helm-sources) + (cons 'helm-source-locate helm-sources))) + (helm-set-source-filter '(helm-source-locate))) + (helm-kill-async-processes) + (helm-set-sources (remove 'helm-source-locate + helm-for-files-preferred-list)) + (helm-set-source-filter nil)))) + + +;;; List of files gleaned from every dired buffer +;; +;; +(defun helm-files-in-all-dired-candidates () + (save-excursion + (cl-loop for (f . b) in dired-buffers + when (buffer-live-p b) + append (let ((dir (with-current-buffer b dired-directory))) + (if (listp dir) (cdr dir) + (directory-files f t dired-re-no-dot)))))) + +;; (dired '("~/" "~/.emacs.d/.emacs-custom.el" "~/.emacs.d/.emacs.bmk")) + +(defvar helm-source-files-in-all-dired + '((name . "Files in all dired buffer.") + (candidates . helm-files-in-all-dired-candidates) + (type . file))) + + +;;; File Cache +;; +;; +(defvar file-cache-alist) + +(defclass helm-file-cache (helm-source-in-buffer helm-type-file) + ((init :initform (lambda () (require 'filecache))) + (keymap :initform helm-generic-files-map) + (help-message :initform helm-generic-file-help-message) + (mode-line :initform helm-generic-file-mode-line-string))) + +(defun helm-file-cache-get-candidates () + (cl-loop for item in file-cache-alist append + (cl-destructuring-bind (base &rest dirs) item + (cl-loop for dir in dirs collect + (concat dir base))))) + +(defvar helm-source-file-cache nil) + +(defcustom helm-file-cache-fuzzy-match nil + "Enable fuzzy matching in `helm-source-file-cache' when non--nil." + :group 'helm-files + :type 'boolean + :set (lambda (var val) + (set var val) + (setq helm-source-file-cache + (helm-make-source "File Cache" 'helm-file-cache + :fuzzy-match helm-file-cache-fuzzy-match + :data 'helm-file-cache-get-candidates)))) + +(cl-defun helm-file-cache-add-directory-recursively + (dir &optional match (ignore-dirs t)) + (require 'filecache) + (cl-loop for f in (helm-walk-directory + dir + :path 'full + :directories nil + :match match + :skip-subdirs ignore-dirs) + do (file-cache-add-file f))) + +(defun helm-ff-cache-add-file (_candidate) + (require 'filecache) + (let ((mkd (helm-marked-candidates :with-wildcard t))) + (mapc 'file-cache-add-file mkd))) + +(defun helm-ff-file-cache-remove-file-1 (file) + "Remove FILE from `file-cache-alist'." + (let ((entry (assoc (helm-basename file) file-cache-alist)) + (dir (helm-basedir file)) + new-entry) + (setq new-entry (remove dir entry)) + (when (= (length entry) 1) + (setq new-entry nil)) + (setq file-cache-alist + (cons new-entry (remove entry file-cache-alist))))) + +(defun helm-ff-file-cache-remove-file (_file) + "Remove marked files from `file-cache-alist.'" + (let ((mkd (helm-marked-candidates))) + (mapc 'helm-ff-file-cache-remove-file-1 mkd))) + +(defun helm-transform-file-cache (actions _candidate) + (let ((source (helm-get-current-source))) + (if (string= (assoc-default 'name source) "File Cache") + (append actions + '(("Remove marked files from file-cache" + . helm-ff-file-cache-remove-file))) + actions))) + + +;;; File name history +;; +;; +(defvar helm-source-file-name-history + `((name . "File Name History") + (candidates . file-name-history) + (persistent-action . ignore) + (filtered-candidate-transformer . helm-file-name-history-transformer) + (action . ,(helm-actions-from-type-file)))) + +(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.") + +(defun helm-file-name-history-transformer (candidates _source) + (cl-loop for c in candidates collect + (cond ((file-remote-p c) + (cons (propertize c 'face 'helm-history-remote) c)) + ((file-exists-p c) + (cons (propertize c 'face 'helm-ff-file) c)) + (t (cons (propertize c 'face 'helm-history-deleted) c))))) + +(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 + (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)) + :fuzzy-match t + :persistent-action 'ignore + :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" (lambda (candidate) + (helm-set-pattern + (expand-file-name candidate))))))) + (with-helm-alive-p + (helm :sources 'helm-source--ff-file-name-history + :buffer "*helm-file-name-history*" + :allow-nest t + :resume 'noresume))) + +;;; Recentf files +;; +;; +(defvar helm-recentf--basename-flag nil) + +(defun helm-recentf-pattern-transformer (pattern) + (let ((pattern-no-flag (replace-regexp-in-string " -b" "" pattern))) + (cond ((and (string-match " " pattern-no-flag) + (string-match " -b\\'" pattern)) + (setq helm-recentf--basename-flag t) + pattern-no-flag) + ((string-match "\\([^ ]*\\) -b\\'" pattern) + (prog1 (match-string 1 pattern) + (setq helm-recentf--basename-flag t))) + (t (setq helm-recentf--basename-flag nil) + pattern)))) + +(defclass helm-recentf-source (helm-source-sync) + ((init :initform (lambda () + (require 'recentf) + (recentf-mode 1))) + (candidates :initform (lambda () recentf-list)) + (pattern-transformer :initform 'helm-recentf-pattern-transformer) + (match-part :initform (lambda (candidate) + (if (or helm-ff-transformer-show-only-basename + helm-recentf--basename-flag) + (helm-basename candidate) candidate))) + (filter-one-by-one :initform (lambda (c) + (if (and helm-ff-transformer-show-only-basename + (not (consp c))) + (cons (helm-basename c) c) + c))) + (keymap :initform helm-generic-files-map) + (help-message :initform helm-generic-file-help-message) + (mode-line :initform helm-generic-file-mode-line-string) + (action :initform (helm-actions-from-type-file)))) + +(defvar helm-source-recentf nil + "See (info \"(emacs)File Conveniences\"). +Set `recentf-max-saved-items' to a bigger value if default is too small.") + +(defcustom helm-recentf-fuzzy-match nil + "Enable fuzzy matching in `helm-source-recentf' when non--nil." + :group 'helm-files + :type 'boolean + :set (lambda (var val) + (set var val) + (setq helm-source-recentf + (helm-make-source "Recentf" 'helm-recentf-source + :fuzzy-match helm-recentf-fuzzy-match)))) + +;;; Browse project +;; Need dependencies: +;; +;; +;; Only hg and git are supported for now. +(defvar helm--browse-project-cache (make-hash-table :test 'equal)) +(defun helm-browse-project-find-files (directory &optional refresh) + (when refresh (remhash directory helm--browse-project-cache)) + (unless (gethash directory helm--browse-project-cache) + (puthash directory (helm-walk-directory + directory + :directories nil :path 'full :skip-subdirs t) + helm--browse-project-cache)) + (helm :sources (helm-build-in-buffer-source "Browse project" + :data (gethash directory helm--browse-project-cache) + :header-name (lambda (name) + (format + "%s (%s)" + name (abbreviate-file-name directory))) + :match-part (lambda (c) + (if helm-ff-transformer-show-only-basename + (helm-basename c) c)) + :filter-one-by-one + (lambda (c) + (if helm-ff-transformer-show-only-basename + (cons (propertize (helm-basename c) + 'face 'helm-ff-file) + c) + (propertize c 'face 'helm-ff-file))) + :mode-line helm-generic-file-mode-line-string + :keymap helm-generic-files-map + :action (helm-actions-from-type-file)) + :buffer "*helm browse project*")) + +;;;###autoload +(defun helm-browse-project (arg) + "Browse files and see status of project with its vcs. +Only HG and GIT are supported for now. +Fall back to `helm-find-files' or `helm-browse-project-find-files' +if current directory is not under control of one of those vcs. +With a prefix ARG browse files recursively, with two prefix ARG +rebuild the cache. +If the current directory is found in the cache, start +`helm-browse-project-find-files' even with no prefix ARG. +NOTE: The prefix ARG have no effect on the VCS controlled directories. + +Need dependencies for VCS: + +and +." + (interactive "P") + (cond ((and (require 'helm-ls-git nil t) + (fboundp 'helm-ls-git-root-dir) + (helm-ls-git-root-dir)) + (helm-ls-git-ls)) + ((and (require 'helm-ls-hg nil t) + (fboundp 'helm-hg-root) + (helm-hg-root)) + (helm-hg-find-files-in-project)) + (t (let ((cur-dir (helm-current-directory))) + (if (or arg (gethash cur-dir helm--browse-project-cache)) + (helm-browse-project-find-files cur-dir (equal arg '(16))) + (helm-find-files nil)))))) + +(defun helm-ff-browse-project (_candidate) + "Browse project in current directory. +See `helm-browse-project'." + (with-helm-default-directory helm-ff-default-directory + ;; `helm-browse-project' will call `helm-ls-git-ls' + ;; which will set locally `helm-default-directory' + (helm-browse-project helm-current-prefix-arg))) + +(defun helm-ff-run-browse-project () + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-browse-project))) + +;;; session.el files +;; +;; session (http://emacs-session.sourceforge.net/) is an alternative to +;; recentf that saves recent file history and much more. +(defvar helm-source-session + `((name . "Session") + (candidates . (lambda () + (cl-delete-if-not #'(lambda (f) + (or (string-match helm-tramp-file-name-regexp f) + (file-exists-p f))) + (mapcar 'car session-file-alist)))) + (keymap . ,helm-generic-files-map) + (help-message . helm-generic-file-help-message) + (mode-line . helm-generic-file-mode-line-string) + (action . ,(helm-actions-from-type-file))) + "File list from emacs-session.") + + +;;; Files in current dir +;; +;; +(defun helm-highlight-files (files) + "A basic transformer for helm files sources. +Colorize only symlinks, directories and files." + (cl-loop for i in files + for disp = (if (and helm-ff-transformer-show-only-basename + (not (helm-dir-is-dot i)) + (not (and ffap-url-regexp + (string-match ffap-url-regexp i))) + (not (string-match helm-ff-url-regexp i))) + (helm-basename i) i) + for type = (car (file-attributes i)) + collect + (cond ((and helm-ff-tramp-not-fancy + (string-match helm-tramp-file-name-regexp i)) + (cons disp i)) + ((stringp type) + (cons (propertize disp + 'face 'helm-ff-symlink + 'help-echo (expand-file-name i)) + i)) + ((eq type t) + (cons (propertize disp + 'face 'helm-ff-directory + 'help-echo (expand-file-name i)) + i)) + (t (cons (propertize disp + 'face 'helm-ff-file + 'help-echo (expand-file-name i)) + i))))) + +(defclass helm-files-in-current-dir-source (helm-source-sync helm-type-file) + ((candidates :initform (lambda () + (with-helm-current-buffer + (let ((dir (helm-current-directory))) + (when (file-accessible-directory-p dir) + (directory-files dir t)))))) + (pattern-transformer :initform 'helm-recentf-pattern-transformer) + (match-part :initform (lambda (candidate) + (if (or helm-ff-transformer-show-only-basename + helm-recentf--basename-flag) + (helm-basename candidate) candidate))) + (fuzzy-match :initform t) + (keymap :initform helm-generic-files-map) + (help-message :initform helm-generic-file-help-message) + (mode-line :initform helm-generic-file-mode-line-string))) + +(defvar helm-source-files-in-current-dir + (helm-make-source "Files from Current Directory" + helm-files-in-current-dir-source)) + + +;;; External searching file tools. +;; +;; Tracker desktop search +(defvar helm-source-tracker-cand-incomplete nil "Contains incomplete candidate") +(defun helm-source-tracker-transformer (candidates _source) + (helm-log "received: %S" candidates) + (cl-loop for cand in candidates + for path = (when (stringp helm-source-tracker-cand-incomplete) + (caar (helm-highlight-files + (list helm-source-tracker-cand-incomplete)))) + for built = (if (not (stringp cand)) cand + (let ((snippet cand)) + (unless (or (null path) + (string= "" path) + (not (string-match-p + "\\`[[:space:]]*\\.\\.\\." + snippet))) + (let ((complete-candidate + (cons (concat path "\n" snippet) path))) + (setq helm-source-tracker-cand-incomplete nil) + (helm-log "built: %S" complete-candidate) + complete-candidate)))) + when (and (stringp cand) + (string-match "\\`[[:space:]]*file://" cand)) + do (setq helm-source-tracker-cand-incomplete ; save path + (replace-match "" t t cand)) end + collect built)) + +(defvar helm-source-tracker-search + `((name . "Tracker Search") + (candidates-process + . (lambda () + (start-process "tracker-search-process" nil + "tracker-search" + "--disable-color" + "--limit=512" + helm-pattern))) + (filtered-candidate-transformer . helm-source-tracker-transformer) + ;;(multiline) ; https://github.com/emacs-helm/helm/issues/529 + (keymap . ,helm-generic-files-map) + (action . ,(cdr (helm-get-attribute-from-type 'action 'file))) + (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.") + +;; Spotlight (MacOS X desktop search) +(defvar helm-source-mac-spotlight + '((name . "mdfind") + (candidates-process + . (lambda () (start-process "mdfind-process" nil "mdfind" helm-pattern))) + (type . file) + (requires-pattern . 3)) + "Source for retrieving files via Spotlight's command line +utility mdfind.") + + +;;; Findutils +;; +;; +(defvar helm-source-findutils + (helm-build-async-source "Find" + :header-name (lambda (name) + (concat name " in [" helm-default-directory "]")) + :candidates-process 'helm-find-shell-command-fn + :filtered-candidate-transformer 'helm-findutils-transformer + :action-transformer 'helm-transform-file-load-el + :action (helm-actions-from-type-file) + :mode-line helm-generic-file-mode-line-string + :keymap helm-generic-files-map + :candidate-number-limit 9999 + :requires-pattern 3)) + +(defun helm-findutils-transformer (candidates _source) + (cl-loop for i in candidates + for type = (car (file-attributes i)) + for abs = (expand-file-name i helm-default-directory) + for disp = (if (and helm-ff-transformer-show-only-basename + (not (string-match "[.]\\{1,2\\}$" i))) + (helm-basename i) abs) + collect (cond ((eq t type) + (cons (propertize disp 'face 'helm-ff-directory) abs)) + ((stringp type) + (cons (propertize disp 'face 'helm-ff-symlink) abs)) + (t (cons (propertize disp 'face 'helm-ff-file) abs))))) + +(defun helm-find-shell-command-fn () + "Asynchronously fetch candidates for `helm-find'. +Additional find options can be sepcified after a \"*\" +separator." + (require 'find-cmd) + (with-helm-default-directory (helm-default-directory) + (let* (process-connection-type + (patterns+options (split-string helm-pattern "\\(\\`\\| +\\)\\* +")) + (fold-case (helm-set-case-fold-search (car patterns+options))) + (patterns (split-string (car patterns+options))) + (additional-options (and (cdr patterns+options) + (list (concat (cadr patterns+options) " ")))) + (ignored-dirs ()) + (ignored-files (when helm-findutils-skip-boring-files + (cl-loop for f in completion-ignored-extensions + if (string-match "/$" f) + do (push (replace-match "" nil t f) + ignored-dirs) + else collect (concat "*" f)))) + (path-or-name (if helm-findutils-search-full-path + '(ipath path) '(iname name))) + (name-or-iname (if fold-case + (car path-or-name) (cadr path-or-name))) + (cmd (find-cmd (and ignored-dirs + `(prune (name ,@ignored-dirs))) + (and ignored-files + `(not (name ,@ignored-files))) + `(and ,@(mapcar + (lambda (pattern) + `(,name-or-iname ,(concat "*" pattern "*"))) + patterns) + ,@additional-options))) + (proc (start-file-process-shell-command "hfind" helm-buffer cmd))) + (helm-log "Find command:\n%s" cmd) + (prog1 proc + (set-process-sentinel + proc + #'(lambda (process event) + (helm-process-deferred-sentinel-hook + process event (helm-default-directory)) + (if (string= event "finished\n") + (with-helm-window + (setq mode-line-format + '(" " mode-line-buffer-identification " " + (:eval (format "L%s" (helm-candidate-number-at-point))) " " + (:eval (propertize + (format "[Find process finished - (%s results)]" + (max (1- (count-lines + (point-min) (point-max))) + 0)) + 'face 'helm-locate-finish)))) + (force-mode-line-update)) + (helm-log "Error: Find %s" + (replace-regexp-in-string "\n" "" event))))))))) + +(defun helm-find-1 (dir) + (helm :sources 'helm-source-findutils + :buffer "*helm find*" + ;; Make these vars local for further resuming. + :default-directory dir ; reset it when called from elsewhere. + :ff-transformer-show-only-basename nil + :case-fold-search helm-file-name-case-fold-search)) + +;; helm-find-files integration. +(defun helm-ff-find-sh-command (_candidate) + "Run `helm-find' from `helm-find-files'." + (helm-find-1 helm-ff-default-directory)) + +(defun helm-ff-run-find-sh-command () + "Run find shell command action with key from `helm-find-files'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-ff-find-sh-command))) + + +;;; Preconfigured commands +;; +;; +;;;###autoload +(defun helm-find (arg) + "Preconfigured `helm' for the find shell command." + (interactive "P") + (let ((directory + (if arg + (file-name-as-directory + (read-directory-name "DefaultDirectory: ")) + default-directory))) + (helm-find-1 directory))) + +(defvar org-directory) +;;;###autoload +(defun helm-find-files (arg) + "Preconfigured `helm' for helm implementation of `find-file'. +Called with a prefix arg show history if some. +Don't call it from programs, use `helm-find-files-1' instead. +This is the starting point for nearly all actions you can do on files." + (interactive "P") + (let* ((hist (and arg helm-ff-history (helm-find-files-history))) + (default-input (or hist (helm-find-files-initial-input))) + (input (cond ((and (eq major-mode 'org-agenda-mode) + org-directory + (not default-input)) + (expand-file-name org-directory)) + ((and (eq major-mode 'dired-mode) default-input) + (file-name-directory default-input)) + ((and (not (string= default-input "")) + default-input)) + (t (expand-file-name (helm-current-directory))))) + (presel (helm-aif (or hist + (buffer-file-name (current-buffer)) + (and (eq major-mode 'dired-mode) + default-input)) + (if helm-ff-transformer-show-only-basename + (helm-basename it) it)))) + (set-text-properties 0 (length input) nil input) + (helm-find-files-1 input (and presel (concat "^" (regexp-quote presel)))))) + +;;;###autoload +(defun helm-for-files () + "Preconfigured `helm' for opening files. +Run all sources defined in `helm-for-files-preferred-list'." + (interactive) + (unless helm-source-buffers-list + (setq helm-source-buffers-list + (helm-make-source "Buffers" 'helm-source-buffers))) + (let ((helm-ff-transformer-show-only-basename nil)) + (helm :sources helm-for-files-preferred-list :buffer "*helm for files*"))) + +;;;###autoload +(defun helm-multi-files () + "Same as `helm-for-files' but allow toggling from locate to others sources." + (interactive) + (unless helm-source-buffers-list + (setq helm-source-buffers-list + (helm-make-source "Buffers" 'helm-source-buffers))) + (setq helm-multi-files--toggle-locate nil) + (let ((sources (remove 'helm-source-locate helm-for-files-preferred-list)) + (helm-ff-transformer-show-only-basename nil) + (old-key (lookup-key + helm-map + (read-kbd-macro helm-multi-files-toggle-locate-binding)))) + (with-helm-temp-hook 'helm-after-initialize-hook + (define-key helm-map (kbd helm-multi-files-toggle-locate-binding) + 'helm-multi-files-toggle-to-locate)) + (unwind-protect + (helm :sources sources + :buffer "*helm multi files*") + (define-key helm-map (kbd helm-multi-files-toggle-locate-binding) + old-key)))) + +;;;###autoload +(defun helm-recentf () + "Preconfigured `helm' for `recentf'." + (interactive) + (let ((helm-ff-transformer-show-only-basename nil)) + (helm-other-buffer 'helm-source-recentf "*helm recentf*"))) + +(provide 'helm-files) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-files.el ends here diff --git a/elpa/helm-20150403.101/helm-font.el b/elpa/helm-20150403.101/helm-font.el new file mode 100644 index 00000000..e7a7d240 --- /dev/null +++ b/elpa/helm-20150403.101/helm-font.el @@ -0,0 +1,187 @@ +;;; helm-font --- Font and ucs selection for Helm -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) + +(defvar helm-ucs-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "") 'helm-ucs-persistent-delete) + (define-key map (kbd "") 'helm-ucs-persistent-backward) + (define-key map (kbd "") 'helm-ucs-persistent-forward) + (define-key map (kbd "") 'helm-ucs-persistent-insert) + (define-key map (kbd "C-c ?") 'helm-ucs-help) + map) + "Keymap for `helm-ucs'.") + + +;;; Xfont selection +;; +;; +(defun helm-persistent-xfont-action (elm) + "Show current font temporarily" + (let ((current-font (cdr (assoc 'font (frame-parameters)))) + (default-font elm)) + (unwind-protect + (progn (set-frame-font default-font 'keep-size) (sit-for 2)) + (set-frame-font current-font)))) + +(defvar helm-xfonts-cache nil) +(defvar helm-source-xfonts + '((name . "X Fonts") + (init . (lambda () + (unless helm-xfonts-cache + (setq helm-xfonts-cache + (x-list-fonts "*"))))) + (candidates . helm-xfonts-cache) + (action . (("Copy to kill ring" . (lambda (elm) + (kill-new elm))) + ("Set Font" . (lambda (elm) + (kill-new elm) + (set-frame-font elm 'keep-size) + (message "New font have been copied to kill ring"))))) + (persistent-action . helm-persistent-xfont-action) + (persistent-help . "Switch to this font temporarily"))) + +;;; 𝕌𝕔𝕤 𝕊𝕪𝕞𝕓𝕠𝕝 𝕔𝕠𝕞𝕡𝕝𝕖𝕥𝕚𝕠𝕟 +;; +;; +(defvar helm-ucs-max-len 0) +(defun helm-calculate-ucs-max-len () + "Calculate the length of longest `ucs-names' candidate." + (cl-loop with count = 0 + for (n . v) in (ucs-names) + for len = (length n) + if (> len count) + do (setq count len) + finally return count)) + +(defun helm-ucs-init () + "Initialize an helm buffer with ucs symbols. +Only math* symbols are collected." + (unless (> helm-ucs-max-len 0) + (setq helm-ucs-max-len + (helm-calculate-ucs-max-len))) + (with-current-buffer (helm-candidate-buffer + (get-buffer-create "*helm ucs*")) + ;; `ucs-names' fn will not run again, data is cached in + ;; var `ucs-names'. + (cl-loop for (n . v) in (ucs-names) + for len = (length n) + for diff = (+ (- helm-ucs-max-len len) 2) + unless (string= "" n) + do (progn (insert (concat + n ":" + (make-string + diff ? ))) + (if (fboundp 'ucs-insert) + (ucs-insert v) + ;; call `insert-char' with nil nil + ;; to shutup byte compiler in 24.1. + (insert-char v nil nil)) + (insert (format " #x%x" v)) + (insert "\n"))))) + +(defun helm-ucs-forward-char (_candidate) + (with-helm-current-buffer + (forward-char 1))) + +(defun helm-ucs-backward-char (_candidate) + (with-helm-current-buffer + (forward-char -1))) + +(defun helm-ucs-delete-backward (_candidate) + (with-helm-current-buffer + (delete-char -1))) + +(defun helm-ucs-insert (candidate n) + (with-helm-current-buffer + (string-match "^\\([^:]+\\): +\\(.\\) #x\\([a-f0-9]+\\)$" candidate) + (insert (match-string n candidate)))) + +(defun helm-ucs-insert-name (candidate) + (helm-ucs-insert candidate 1)) + +(defun helm-ucs-insert-char (candidate) + (helm-ucs-insert candidate 2)) + +(defun helm-ucs-insert-code (candidate) + (helm-ucs-insert candidate 3)) + +(defun helm-ucs-persistent-insert () + (interactive) + (with-helm-alive-p + (helm-attrset 'action-insert 'helm-ucs-insert-char) + (helm-execute-persistent-action 'action-insert))) + +(defun helm-ucs-persistent-forward () + (interactive) + (with-helm-alive-p + (helm-attrset 'action-forward 'helm-ucs-forward-char) + (helm-execute-persistent-action 'action-forward))) + +(defun helm-ucs-persistent-backward () + (interactive) + (with-helm-alive-p + (helm-attrset 'action-back 'helm-ucs-backward-char) + (helm-execute-persistent-action 'action-back))) + +(defun helm-ucs-persistent-delete () + (interactive) + (with-helm-alive-p + (helm-attrset 'action-delete 'helm-ucs-delete-backward) + (helm-execute-persistent-action 'action-delete))) + +(defvar helm-source-ucs + '((name . "Ucs names") + (init . helm-ucs-init) + (candidate-number-limit . 9999) + (candidates-in-buffer) + (mode-line . helm-ucs-mode-line-string) + (action . (("Insert character" . helm-ucs-insert-char) + ("Insert character name" . helm-ucs-insert-name) + ("Insert character code in hex" . helm-ucs-insert-code) + ("Forward char" . helm-ucs-forward-char) + ("Backward char" . helm-ucs-backward-char) + ("Delete char backward" . helm-ucs-delete-backward)))) + "Source for collecting `ucs-names' math symbols.") + +;;;###autoload +(defun helm-select-xfont () + "Preconfigured `helm' to select Xfont." + (interactive) + (helm-other-buffer 'helm-source-xfonts "*helm select* xfont")) + +;;;###autoload +(defun helm-ucs () + "Preconfigured helm for `ucs-names' math symbols." + (interactive) + (helm :sources 'helm-source-ucs + :keymap helm-ucs-map)) + +(provide 'helm-font) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-font.el ends here diff --git a/elpa/helm-20150403.101/helm-grep.el b/elpa/helm-20150403.101/helm-grep.el new file mode 100644 index 00000000..004ea1fb --- /dev/null +++ b/elpa/helm-20150403.101/helm-grep.el @@ -0,0 +1,1226 @@ +;;; helm-grep.el --- Helm Incremental Grep. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'grep) +(require 'helm-regexp) + +;;; load wgrep proxy if it's available +(require 'wgrep-helm nil t) + +(declare-function helm-buffer-list "helm-buffers") +(declare-function helm-elscreen-find-file "helm-elscreen" (file)) +(declare-function View-quit "view") +(declare-function doc-view-goto-page "doc-view" (page)) + + +(defgroup helm-grep nil + "Grep related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-grep-default-command + "grep --color=never -a -d skip %e -n%cH -e %p %f" + "Default grep format command for `helm-do-grep-1'. +Where: +'%e' format spec is for --exclude or --include grep options or + ack-grep --type option. (Not mandatory) + +'%c' format spec is for case-fold-search, + 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'. + If you don't want this behavior, don't use this spec and + specify or not the '-i' option. + Note that with ack-grep this is not needed, just specify + 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. + +Helm also support ack-grep and git-grep , +here a default command example for ack-grep: + +\(setq helm-grep-default-command \"ack-grep -Hn --no-group --no-color %e %p %f\" + helm-grep-default-recurse-command \"ack-grep -H --no-group --no-color %e %p %f\") + +You can ommit the %e spec if you don't want to be prompted for types. + +NOTE: Helm for ack-grep support ANSI sequences, so you can remove +the \"--no-color\" option safely (recommended). + +To enable ANSI in grep it is a little more difficult: + 1) Modify env var + \(setenv \"GREP_COLORS\" \"ms=01;31:mc=01;31:sl=01;37:cx=:fn=35:ln=32:bn=32:se=36\") + 2) Add the option \"--color=always\". + +To enable ANSI color in git-grep just add \"--color=always\". +To customize the ANSI color in git-grep, GREP_COLORS have no effect, +you will have to setup this in your .gitconfig: + + [color \"grep\"] + match = black yellow + +where \"black\" is the foreground and \"yellow\" the background. +See the git documentation for more infos. + +`helm-grep-default-command' and `helm-grep-default-recurse-command'are +independents, so you can enable `helm-grep-default-command' with ack-grep +and `helm-grep-default-recurse-command' with grep if you want to be faster +on recursive grep. + +NOTE: Remote grepping is not available with ack-grep, + and badly supported with grep because tramp handle badly + repeated remote processes in a short delay (< to 5s)." + :group 'helm-grep + :type 'string) + +(defcustom helm-grep-default-recurse-command + "grep --color=never -a -d recurse %e -n%cH -e %p %f" + "Default recursive grep format command for `helm-do-grep-1'. +See `helm-grep-default-command' for format specs and infos about ack-grep." + :group 'helm-grep + :type 'string) + +(defcustom helm-default-zgrep-command + "zgrep -a -n%cH -e %p %f" + "Default command for Zgrep. +See `helm-grep-default-command' for infos on format specs. +Option --color=always is supported and can be used safely +to replace the helm internal match highlighting, +see `helm-grep-default-command' for more infos." + :group 'helm-grep + :type 'string) + +(defcustom helm-pdfgrep-default-command + "pdfgrep --color never -niH %s %s" + "Default command for pdfgrep. +Option --color always is not supported, expect +errors when executing actions." + :group 'helm-grep + :type 'string) + +(defcustom helm-grep-use-ioccur-style-keys t + "Use Arrow keys to jump to occurences." + :group 'helm-grep + :type 'boolean) + +(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. +e.g In Ubuntu you can set it to: + + \"evince --page-label=%p '%f'\" + +If set to nil `doc-view-mode' will be used instead of an external command." + :group 'helm-grep + :type 'string) + +(defcustom helm-grep-max-length-history 100 + "Max number of elements to save in `helm-grep-history'." + :group 'helm-grep + :type 'integer) + +(defcustom helm-zgrep-file-extension-regexp + ".*\\(\\.gz\\|\\.bz\\|\\.xz\\|\\.lzma\\)$" + "Default file extensions zgrep will search in." + :group 'helm-grep + :type 'string) + +(defcustom helm-do-grep-preselect-candidate nil + "When non--nil the file name of current buffer will be selected." + :group 'helm-grep + :type 'boolean) + +(defcustom helm-grep-preferred-ext nil + "This file extension will be preselected for grep." + :group 'helm-grep + :type 'string) + + +;;; Faces +;; +;; +(defgroup helm-grep-faces nil + "Customize the appearance of helm-grep." + :prefix "helm-" + :group 'helm-grep + :group 'helm-faces) + +(defface helm-grep-match + '((((background light)) :foreground "#b00000") + (((background dark)) :foreground "gold1")) + "Face used to highlight grep matches." + :group 'helm-grep-faces) + +(defface helm-grep-file + '((t (:foreground "BlueViolet" + :underline t))) + "Face used to highlight grep results filenames." + :group 'helm-grep-faces) + +(defface helm-grep-lineno + '((t (:foreground "Darkorange1"))) + "Face used to highlight grep number lines." + :group 'helm-grep-faces) + +(defface helm-grep-running + '((t (:foreground "Red"))) + "Face used in mode line when grep is running." + :group 'helm-grep-faces) + +(defface helm-grep-finish + '((t (:foreground "Green"))) + "Face used in mode line when grep is finish." + :group 'helm-grep-faces) + +(defface helm-grep-cmd-line + '((t (:inherit diff-added))) + "Face used to highlight grep command line when no results." + :group 'helm-grep-faces) + + +;;; Keymaps +;; +;; +(defvar helm-grep-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-") 'helm-goto-next-file) + (define-key map (kbd "M-") 'helm-goto-precedent-file) + (define-key map (kbd "C-c o") 'helm-grep-run-other-window-action) + (define-key map (kbd "C-c C-o") 'helm-grep-run-other-frame-action) + (define-key map (kbd "C-w") 'helm-yank-text-at-point) + (define-key map (kbd "C-x C-s") 'helm-grep-run-save-buffer) + (when helm-grep-use-ioccur-style-keys + (define-key map (kbd "") 'helm-execute-persistent-action) + (define-key map (kbd "") 'helm-grep-run-default-action)) + (define-key map (kbd "C-c ?") 'helm-grep-help) + (delq nil map)) + "Keymap used in Grep sources.") + +(defvar helm-pdfgrep-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-") 'helm-goto-next-file) + (define-key map (kbd "M-") 'helm-goto-precedent-file) + (define-key map (kbd "C-w") 'helm-yank-text-at-point) + (define-key map (kbd "C-c ?") 'helm-pdfgrep-help) + map) + "Keymap used in pdfgrep.") + +(defvar helm-grep-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "RET") 'helm-grep-mode-jump) + (define-key map (kbd "C-o") 'helm-grep-mode-jump-other-window) + (define-key map (kbd "") 'helm-grep-mode-jump-other-window-forward) + (define-key map (kbd "") 'helm-grep-mode-jump-other-window-backward) + (define-key map (kbd "") 'helm-gm-next-file) + (define-key map (kbd "") 'helm-gm-precedent-file) + map)) + + +;;; Internals vars +;; +;; +(defvar helm-rzgrep-cache (make-hash-table :test 'equal)) +(defvar helm-grep-default-function 'helm-grep-init) +(defvar helm-zgrep-recurse-flag nil) +(defvar helm-grep-history nil) +(defvar helm-grep-last-targets nil) +(defvar helm-grep-include-files nil) +(defvar helm-grep-in-recurse nil) +(defvar helm-grep-use-zgrep nil) +(defvar helm-grep-default-directory-fn nil + "A function that should return a directory to expand candidate to. +It is intended to use as a let-bound variable, DON'T set this globaly.") +(defvar helm-pdfgrep-targets nil) +(defvar helm-grep-last-cmd-line nil) +(defvar helm-grep-split-line-regexp "^\\([[:lower:][:upper:]]?:?.*?\\):\\([0-9]+\\):\\(.*\\)") + + +;;; Init +;; +;; +(defun helm-grep-prepare-candidates (candidates in-directory) + "Prepare filenames and directories CANDIDATES for grep command line." + ;; If one or more candidate is a directory, search in all files + ;; of this candidate (e.g /home/user/directory/*). + ;; If r option is enabled search also in subdidrectories. + ;; We need here to expand wildcards to support crap windows filenames + ;; as grep doesn't accept quoted wildcards (e.g "dir/*.el"). + (if helm-zgrep-recurse-flag + (mapconcat 'shell-quote-argument candidates " ") + ;; When candidate is a directory, search in all its files. + ;; NOTE that `file-expand-wildcards' will return also + ;; directories, they will be ignored by grep but not + ;; by ack-grep that will grep all files of this directory + ;; without recursing in their subdirs though, see that as a one + ;; level recursion with ack-grep. + ;; So I leave it as it is, considering it is a feature. [1] + (cl-loop for i in candidates append + (cond ((string-match "^git" helm-grep-default-command) + (list i)) + ;; Candidate is a directory and we use recursion or ack. + ((and (file-directory-p i) + (or helm-grep-in-recurse + ;; ack-grep accept directory [1]. + (helm-grep-use-ack-p))) + (list (expand-file-name i))) + ;; Grep doesn't support directory only when not in recurse. + ((file-directory-p i) + (file-expand-wildcards + (concat (file-name-as-directory (expand-file-name i)) "*") t)) + ;; Candidate is a file or wildcard and we use recursion, use the + ;; current directory instead of candidate. + ((and (or (file-exists-p i) (string-match "[*]" i)) + helm-grep-in-recurse) + (list (expand-file-name + (directory-file-name ; Needed for windoze. + (file-name-directory (directory-file-name i)))))) + ;; Else should be one or more file/directory + ;; possibly marked. + ;; When real is a normal filename without wildcard + ;; file-expand-wildcards returns a list of one file. + ;; wildcards should have been already handled by + ;; helm-read-file-name or helm-find-files but do it from + ;; here too in case we are called from elsewhere. + (t (file-expand-wildcards i t))) into all-files ; [1] + finally return + (let ((files (if (file-remote-p in-directory) + ;; Grep don't understand tramp filenames + ;; use the local name. + (mapcar #'(lambda (x) + (file-remote-p x 'localname)) + all-files) + all-files))) + (if (string-match "^git" helm-grep-default-command) + (mapconcat 'identity files " ") + (mapconcat 'shell-quote-argument files " ")))))) + +(defun helm-grep-command (&optional recursive) + (let* ((com (if recursive + helm-grep-default-recurse-command + helm-grep-default-command)) + (exe (and com (car (split-string com " "))))) + (if (and exe (string= exe "git")) "git-grep" exe))) + +(cl-defun helm-grep-use-ack-p (&key where) + (let* ((rec-com (helm-grep-command t)) + (norm-com (helm-grep-command)) + (norm-com-ack-p (string-match "\\`ack" norm-com)) + (rec-com-ack-p (and rec-com (string-match "\\`ack" rec-com)))) + (cl-case where + (default (and norm-com norm-com-ack-p)) + (recursive (and rec-com rec-com-ack-p)) + (strict (and norm-com rec-com rec-com-ack-p norm-com-ack-p)) + (t (and (not (and norm-com (string= norm-com "git-grep"))) + (or (and norm-com norm-com-ack-p) + (and rec-com rec-com-ack-p))))))) + +(defun helm-grep--prepare-cmd-line (only-files &optional include zgrep) + (let* ((default-directory (or helm-default-directory + (expand-file-name helm-ff-default-directory))) + (fnargs (helm-grep-prepare-candidates only-files default-directory)) + (ignored-files (unless (helm-grep-use-ack-p) + (mapconcat + #'(lambda (x) + (concat "--exclude=" + (shell-quote-argument x))) + grep-find-ignored-files " "))) + (ignored-dirs (unless (helm-grep-use-ack-p) + (mapconcat + ;; Need grep version >=2.5.4 + ;; of Gnuwin32 on windoze. + #'(lambda (x) + (concat "--exclude-dir=" + (shell-quote-argument x))) + grep-find-ignored-directories " "))) + (exclude (unless (helm-grep-use-ack-p) + (if helm-grep-in-recurse + (concat (or include ignored-files) + " " ignored-dirs) + ignored-files))) + (types (and (helm-grep-use-ack-p) + ;; When %e format spec is not specified + ;; in `helm-grep-default-command' + ;; we need to pass an empty string + ;; to types to avoid error. + (or include ""))) + (smartcase (if (helm-grep-use-ack-p) "" + (unless (let ((case-fold-search nil)) + (string-match-p + "[[:upper:]]" helm-pattern)) "i")))) + (format-spec + helm-grep-default-command + (delq nil + (list (unless zgrep + (if types + (cons ?e types) + (cons ?e exclude))) + (cons ?c (or smartcase "")) + (cons ?p (shell-quote-argument helm-pattern)) + (cons ?f fnargs)))))) + +(defun helm-grep-init (cmd-line) + "Start an asynchronous grep process with CMD-LINE using ZGREP if non--nil." + (let* ((default-directory (or (expand-file-name helm-ff-default-directory) + helm-default-directory)) + (zgrep (string-match "\\`zgrep" cmd-line)) + ;; Use pipe only with grep, zgrep or git-grep. + (process-connection-type (and (not zgrep) (helm-grep-use-ack-p))) + (tramp-verbose helm-tramp-verbose) + non-essential) + ;; Start grep process. + (helm-log "Starting Grep process in directory `%s'" default-directory) + (helm-log "Command line used was:\n\n%s" + (concat ">>> " (propertize cmd-line 'face 'helm-grep-cmd-line) "\n\n")) + (prog1 ; This function should return the process first. + (start-file-process-shell-command + "grep" helm-buffer cmd-line) + ;; Init sentinel. + (set-process-sentinel + (get-buffer-process helm-buffer) + #'(lambda (process event) + (let ((noresult (= (process-exit-status process) 1))) + (unless noresult + (helm-process-deferred-sentinel-hook + process event helm-ff-default-directory)) + (cond ((and noresult + ;; [FIXME] This is a workaround for zgrep + ;; that exit with code 1 + ;; after a certain amount of results. + (not (with-helm-buffer helm-grep-use-zgrep))) + (with-current-buffer helm-buffer + (insert (concat "* Exit with code 1, no result found," + " Command line was:\n\n " + (propertize helm-grep-last-cmd-line + 'face 'helm-grep-cmd-line))) + (setq mode-line-format + '(" " mode-line-buffer-identification " " + (:eval (format "L%s" (helm-candidate-number-at-point))) " " + (:eval (propertize + (format + "[%s process finished - (no results)] " + (if helm-grep-use-zgrep + "Zgrep" + (capitalize + (if helm-grep-in-recurse + (helm-grep-command t) + (helm-grep-command))))) + 'face 'helm-grep-finish)))))) + ((string= event "finished\n") + (with-helm-window + (setq mode-line-format + '(" " mode-line-buffer-identification " " + (:eval (format "L%s" (helm-candidate-number-at-point))) " " + (:eval (propertize + (format + "[%s process finished - (%s results)] " + (if helm-grep-use-zgrep + "Zgrep" + (capitalize + (if helm-grep-in-recurse + (helm-grep-command t) + (helm-grep-command)))) + (max (1- (count-lines + (point-min) + (point-max))) + 0)) + 'face 'helm-grep-finish)))) + (force-mode-line-update))) + ;; Catch error output in log. + (t (helm-log + "Error: %s %s" + (if helm-grep-use-zgrep "Zgrep" "Grep") + (replace-regexp-in-string "\n" "" event)))))))))) + +(defun helm-grep-collect-candidates () + (let ((cmd-line (helm-grep--prepare-cmd-line + helm-grep-last-targets + helm-grep-include-files + helm-grep-use-zgrep))) + (set (make-local-variable 'helm-grep-last-cmd-line) cmd-line) + (funcall helm-grep-default-function cmd-line))) + + +;;; Actions +;; +;; +(defun helm-grep-action (candidate &optional where mark) + "Define a default action for `helm-do-grep' on CANDIDATE. +WHERE can be one of other-window, elscreen, other-frame." + (let* ((split (helm-grep-split-line candidate)) + (lineno (string-to-number (nth 1 split))) + (loc-fname (or (with-current-buffer + (if (eq major-mode 'helm-grep-mode) + (current-buffer) + helm-buffer) + (get-text-property (point-at-bol) 'help-echo)) + (car split))) + (tramp-method (file-remote-p (or helm-ff-default-directory + default-directory) 'method)) + (tramp-host (file-remote-p (or helm-ff-default-directory + default-directory) 'host)) + (tramp-prefix (concat "/" tramp-method ":" tramp-host ":")) + (fname (if tramp-host + (concat tramp-prefix loc-fname) loc-fname))) + (cl-case where + (other-window (find-file-other-window fname)) + (elscreen (helm-elscreen-find-file fname)) + (other-frame (find-file-other-frame fname)) + (grep (helm-grep-save-results-1)) + (pdf (if helm-pdfgrep-default-read-command + (helm-pdfgrep-action-1 split lineno (car split)) + (find-file (car split)) (doc-view-goto-page lineno))) + (t (find-file fname))) + (unless (or (eq where 'grep) (eq where 'pdf)) + (helm-goto-line lineno)) + (when mark + (set-marker (mark-marker) (point)) + (push-mark (point) 'nomsg)) + ;; Save history + (unless (or helm-in-persistent-action + (eq major-mode 'helm-grep-mode) + (string= helm-pattern "")) + (setq helm-grep-history + (cons helm-pattern + (delete helm-pattern helm-grep-history))) + (when (> (length helm-grep-history) + helm-grep-max-length-history) + (setq helm-grep-history + (delete (car (last helm-grep-history)) + helm-grep-history)))))) + +(defun helm-grep-persistent-action (candidate) + "Persistent action for `helm-do-grep'. +With a prefix arg record CANDIDATE in `mark-ring'." + (if current-prefix-arg + (helm-grep-action candidate nil 'mark) + (helm-grep-action candidate)) + (helm-highlight-current-line)) + +(defun helm-grep-other-window (candidate) + "Jump to result in other window from helm grep." + (helm-grep-action candidate 'other-window)) + +(defun helm-grep-other-frame (candidate) + "Jump to result in other frame from helm grep." + (helm-grep-action candidate 'other-frame)) + +(defun helm-grep-jump-elscreen (candidate) + "Jump to result in elscreen from helm grep." + (helm-grep-action candidate 'elscreen)) + +(defun helm-goto-next-or-prec-file (n &optional type) + "Go to next or precedent candidate file in helm grep/etags buffers. +If N is positive go forward otherwise go backward." + (let* ((allow-mode (or (eq major-mode 'helm-grep-mode) + (eq major-mode 'helm-moccur-mode))) + (sel (if allow-mode + (buffer-substring (point-at-bol) (point-at-eol)) + (helm-get-selection nil t))) + (current-line-list (if (eq type 'etags) + (split-string sel ": +" t) + (helm-grep-split-line sel))) + (current-fname (nth 0 current-line-list)) + (bob-or-eof (if (eq n 1) 'eobp 'bobp)) + (mark-maybe #'(lambda () + (if allow-mode + (ignore) + (helm-mark-current-line))))) + (catch 'break + (while (not (funcall bob-or-eof)) + (forward-line n) ; Go forward or backward depending of n value. + ;; Exit when current-fname is not matched or in `helm-grep-mode' + ;; the line is not a grep line i.e 'fname:num:tag'. + (setq sel (buffer-substring (point-at-bol) (point-at-eol))) + (unless (or (string= current-fname + (car (if (eq type 'etags) + (split-string sel ": +" t) + (helm-grep-split-line sel)))) + (and (eq major-mode 'helm-grep-mode) + (not (get-text-property (point-at-bol) 'help-echo)))) + (funcall mark-maybe) + (throw 'break nil)))) + (cond ((and (> n 0) (eobp)) + (re-search-backward ".") + (forward-line 0) + (funcall mark-maybe)) + ((and (< n 0) (bobp)) + (helm-aif (next-single-property-change (point-at-bol) 'help-echo) + (goto-char it) + (forward-line 1)) + (funcall mark-maybe))))) + +;;;###autoload +(defun helm-goto-precedent-file () + "Go to precedent file in helm grep/etags buffers." + (interactive) + (let ((etagp (when (string= (assoc-default + 'name (helm-get-current-source)) "Etags") + 'etags))) + (with-helm-window + (helm-goto-next-or-prec-file -1 etagp)))) + +;;;###autoload +(defun helm-goto-next-file () + "Go to precedent file in helm grep/etags buffers." + (interactive) + (let ((etagp (when (string= (assoc-default + 'name (helm-get-current-source)) "Etags") + 'etags))) + (with-helm-window + (helm-goto-next-or-prec-file 1 etagp)))) + +(defun helm-grep-run-default-action () + "Run grep default action from `helm-do-grep-1'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-grep-action))) + +(defun helm-grep-run-other-window-action () + "Run grep goto other window action from `helm-do-grep-1'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-grep-other-window))) + +(defun helm-grep-run-other-frame-action () + "Run grep goto other frame action from `helm-do-grep-1'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-grep-other-frame))) + +;;;###autoload +(defun helm-grep-run-save-buffer () + "Run grep save results action from `helm-do-grep-1'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-grep-save-results))) + + +;;; helm-grep-mode +;; +;; +(defun helm-grep-save-results (candidate) + (helm-grep-action candidate 'grep)) + +(defun helm-grep-save-results-1 () + "Save helm grep result in a `helm-grep-mode' buffer." + (let ((buf "*hgrep*") + new-buf) + (when (get-buffer buf) + (setq new-buf (helm-read-string "GrepBufferName: " buf)) + (cl-loop for b in (helm-buffer-list) + when (and (string= new-buf b) + (not (y-or-n-p + (format "Buffer `%s' already exists overwrite? " + new-buf)))) + do (setq new-buf (helm-read-string "GrepBufferName: " "*hgrep "))) + (setq buf new-buf)) + (with-current-buffer (get-buffer-create buf) + (setq buffer-read-only t) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert "-*- mode: helm-grep -*-\n\n" + (format "Grep Results for `%s':\n\n" helm-pattern)) + (save-excursion + (insert (with-current-buffer helm-buffer + (goto-char (point-min)) (forward-line 1) + (buffer-substring (point) (point-max)))))) + (helm-grep-mode) (pop-to-buffer buf)) + (message "Helm Grep Results saved in `%s' buffer" buf))) + +;;;###autoload +(define-derived-mode helm-grep-mode + special-mode "helm-grep" + "Major mode to provide actions in helm grep saved buffer. + +Special commands: +\\{helm-grep-mode-map}" + (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)) + +(defun helm-grep-mode--revert-buffer-function (&optional _ignore-auto _noconfirm) + (goto-char (point-min)) + (re-search-forward "^Grep Results for" nil t) + (forward-line 0) + (when (re-search-forward "^$" nil t) + (forward-line 1)) + (let ((inhibit-read-only t)) + (delete-region (point) (point-max))) + (message "Reverting buffer...") + (set-process-sentinel + (start-file-process-shell-command + "hgrep" (generate-new-buffer "*hgrep revert*") helm-grep-last-cmd-line) + (lambda (process event) + (when (string= event "finished\n") + (with-current-buffer (current-buffer) + (let ((inhibit-read-only t)) + (save-excursion + (cl-loop for line in (with-current-buffer (process-buffer process) + (prog1 (split-string (buffer-string) "\n") + (kill-buffer))) + when (string-match helm-grep-split-line-regexp line) + do (insert (propertize + (car (helm-grep-filter-one-by-one line)) + ;; needed for wgrep. + 'helm-realvalue line) + "\n")))) + (message "Reverting buffer done")))))) + +;;;###autoload +(defun helm-gm-next-file () + (interactive) + (helm-goto-next-or-prec-file 1)) + +;;;###autoload +(defun helm-gm-precedent-file () + (interactive) + (helm-goto-next-or-prec-file -1)) + +;;;###autoload +(defun helm-grep-mode-jump () + (interactive) + (let ((candidate (buffer-substring (point-at-bol) (point-at-eol)))) + (condition-case nil + (progn (helm-grep-action candidate) (delete-other-windows)) + (error nil)))) + +(defun helm-grep-mode-jump-other-window-1 (arg) + (let ((candidate (buffer-substring (point-at-bol) (point-at-eol)))) + (condition-case nil + (progn + (save-selected-window + (helm-grep-action candidate 'other-window) + (recenter)) + (forward-line arg)) + (error nil)))) + +;;;###autoload +(defun helm-grep-mode-jump-other-window-forward () + (interactive) + (helm-grep-mode-jump-other-window-1 1)) + +;;;###autoload +(defun helm-grep-mode-jump-other-window-backward () + (interactive) + (helm-grep-mode-jump-other-window-1 -1)) + +;;;###autoload +(defun helm-grep-mode-jump-other-window () + (interactive) + (let ((candidate (buffer-substring (point-at-bol) (point-at-eol)))) + (condition-case nil + (helm-grep-action candidate 'other-window) + (error nil)))) + + +;;; ack-grep types +;; +;; +(defun helm-grep-hack-types () + "Return a list of known ack-grep types." + (with-temp-buffer + ;; "--help-types" works with both 1.96 and 2.1+, while + ;; "--help types" works only with 1.96 Issue #422. + ;; `helm-grep-command' should return the ack executable + ;; when this function is used in the right context + ;; i.e After checking is we are using ack-grep with + ;; `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)))))) + +(defun helm-grep-ack-types-transformer (candidates _source) + (cl-loop for i in candidates + if (stringp i) + collect (rassoc i helm-grep-ack-types-cache) + else + collect i)) + +(defvar helm-grep-ack-types-cache nil) +(defun helm-grep-read-ack-type () + "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)) + (let ((types (helm-comp-read + "Types: " helm-grep-ack-types-cache + :name "*Ack-grep types*" + :marked-candidates t + :must-match t + :fc-transformer '(helm-adaptive-sort + helm-grep-ack-types-transformer) + :buffer "*helm ack-types*"))) + (mapconcat #'(lambda (type) (concat "--type=" type)) types " "))) + + +;;; grep extensions +;; +;; +(defun helm-grep-guess-extensions (files) + "Try to guess file extensions in FILES list when using grep recurse. +These extensions will be added to command line with --include arg of grep." + (cl-loop with ext-list = (list helm-grep-preferred-ext "*") + with lst = (if (file-directory-p (car files)) + (directory-files + (car files) nil + directory-files-no-dot-files-regexp) + files) + for i in lst + for ext = (file-name-extension i 'dot) + for glob = (and ext (not (string= ext "")) + (concat "*" ext)) + unless (or (not glob) + (and glob-list (member glob glob-list)) + (and glob-list (member glob ext-list)) + (and glob-list (member glob grep-find-ignored-files))) + collect glob into glob-list + 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." + (let* ((all-exts (helm-grep-guess-extensions + (mapcar 'expand-file-name files))) + (extensions (helm-comp-read "Search Only in: " all-exts + :marked-candidates t + :fc-transformer 'helm-adaptive-sort + :buffer "*helm grep exts*" + :name "*helm grep extensions*"))) + (when (listp extensions) ; Otherwise it is empty string returned by C-RET. + ;; If extensions is a list of one string containing spaces, + ;; assume user entered more than one glob separated by space(s) and + ;; split this string to pass it later to mapconcat. + ;; e.g '("*.el *.py") + (cl-loop for i in extensions + append (split-string-and-unquote i " "))))) + + +;;; Set up source +;; +;; +(defvar helm-source-grep nil) +(defun helm-do-grep-1 (targets &optional recurse zgrep exts) + "Launch grep on a list of TARGETS files. +When RECURSE is given use -r option of grep and prompt user +to set the --include args of grep. +You can give more than one arg separated by space. +e.g *.el *.py *.tex. +If you are using ack-grep, you will be prompted for --type +instead. +If prompt is empty '--exclude `grep-find-ignored-files' is used instead. +ZGREP when non--nil use zgrep instead, without prompting for a choice +in recurse, search being made on `helm-zgrep-file-extension-regexp'." + (when (and (helm-grep-use-ack-p) + helm-ff-default-directory + (file-remote-p helm-ff-default-directory)) + (error "Error: Remote operation not supported with ack-grep.")) + (let* (non-essential + (exts (and recurse + ;; [FIXME] I could handle this from helm-walk-directory. + (not zgrep) ; zgrep doesn't handle -r opt. + (not (helm-grep-use-ack-p :where 'recursive)) + (or exts (helm-grep-get-file-extensions targets)))) + (include-files (and exts + (mapconcat #'(lambda (x) + (concat "--include=" + (shell-quote-argument x))) + (if (> (length exts) 1) + (remove "*" exts) + exts) " "))) + (types (and (not include-files) + (not zgrep) + recurse + (helm-grep-use-ack-p :where 'recursive) + ;; When %e format spec is not specified + ;; ignore types and do not prompt for choice. + (string-match "%e" helm-grep-default-command) + (helm-grep-read-ack-type))) + (follow (and helm-follow-mode-persistent + (assoc-default 'follow helm-source-grep)))) + ;; When called as action from an other source e.g *-find-files + ;; we have to kill action buffer. + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + ;; If `helm-find-files' haven't already started, + ;; give a default value to `helm-ff-default-directory'. + (unless helm-ff-default-directory + (setq helm-ff-default-directory default-directory)) + ;; We need to store these vars locally + ;; to pass infos later to `helm-resume'. + (helm-set-local-variable 'helm-zgrep-recurse-flag (and recurse zgrep) + 'helm-grep-last-targets targets + 'helm-grep-include-files (or include-files types) + 'helm-grep-in-recurse recurse + 'helm-grep-use-zgrep zgrep + 'helm-grep-default-command + (cond (zgrep helm-default-zgrep-command) + (recurse helm-grep-default-recurse-command) + ;; When resuming the local value of + ;; `helm-grep-default-command' is used, only git-grep + ;; should need this. + (t helm-grep-default-command))) + ;; Setup the source. + (setq helm-source-grep + (helm-build-async-source + (if zgrep "Zgrep" (capitalize (if recurse + (helm-grep-command t) + (helm-grep-command)))) + :header-name (lambda (name) + (concat name "(C-c ? Help)")) + :candidates-process 'helm-grep-collect-candidates + :filter-one-by-one 'helm-grep-filter-one-by-one + :nohighlight t + :candidate-number-limit 9999 + :mode-line helm-grep-mode-line-string + :history 'helm-grep-history + :action (helm-make-actions + "Find File" 'helm-grep-action + "Find file other frame" 'helm-grep-other-frame + (lambda () (and (locate-library "elscreen") + "Find file in Elscreen")) + 'helm-grep-jump-elscreen + "Save results in grep buffer" 'helm-grep-save-results + "Find file other window" 'helm-grep-other-window) + :persistent-action 'helm-grep-persistent-action + :persistent-help "Jump to line (`C-u' Record in mark ring)" + :requires-pattern 2 + :follow follow)) + (helm + :sources 'helm-source-grep + :buffer (format "*helm %s*" (if zgrep "zgrep" (helm-grep-command recurse))) + :default-directory helm-ff-default-directory + :keymap helm-grep-map + :history 'helm-grep-history + :truncate-lines t))) + + + +;;; zgrep +;; +;; +(defun helm-ff-zgrep-1 (flist recursive) + (unwind-protect + (let* ((def-dir (or helm-ff-default-directory + default-directory)) + (only (if recursive + (or (gethash def-dir helm-rzgrep-cache) + (puthash + def-dir + (helm-walk-directory + def-dir + :directories nil + :path 'full + :match helm-zgrep-file-extension-regexp) + helm-rzgrep-cache)) + flist))) + (helm-do-grep-1 only recursive 'zgrep)) + (setq helm-zgrep-recurse-flag nil))) + + +;;; transformers +;; +;; +(defun helm-grep-split-line (line) + "Split a grep output line." + ;; The output of grep may send a truncated line in this chunk, + ;; so don't split until grep line is valid, that is + ;; once the second part of the line comes with next chunk + ;; send by process. + (when (string-match helm-grep-split-line-regexp line) + ;; Don't use split-string because buffer/file name or string + ;; may contain a ":". + (cl-loop for n from 1 to 3 collect (match-string n line)))) + +(defun helm-grep--filter-candidate-1 (candidate &optional dir) + (let* ((root (or dir (and helm-grep-default-directory-fn + (funcall helm-grep-default-directory-fn)))) + ansi-color-context ; seems this avoid non--translated fname entries. + (ansi-p (string-match-p ansi-color-regexp candidate)) + (line (if ansi-p (ansi-color-apply candidate) candidate)) + (split (helm-grep-split-line line)) + (fname (if (and root split) + (expand-file-name (car split) root) + (car-safe split))) + (lineno (nth 1 split)) + (str (nth 2 split))) + (when (and fname lineno str) + (cons (concat (propertize (file-name-nondirectory fname) + 'face 'helm-grep-file + 'help-echo fname) + ":" + (propertize lineno 'face 'helm-grep-lineno) + ":" + (if ansi-p str (helm-grep-highlight-match str))) + line)))) + +(defun helm-grep-filter-one-by-one (candidate) + "`filter-one-by-one' transformer function for `helm-do-grep'." + (let ((helm-grep-default-directory-fn + (or helm-grep-default-directory-fn + (lambda () (or helm-ff-default-directory + helm-default-directory + default-directory))))) + (helm-grep--filter-candidate-1 candidate))) + +(defun helm-grep-highlight-match (str &optional multi-match) + "Highlight in string STR all occurences matching `helm-pattern'." + (require 'helm-match-plugin) + (let (beg end) + (condition-case nil + (with-temp-buffer + (insert str) + (goto-char (point-min)) + (cl-loop for reg in (if multi-match + (cl-loop for r in (helm-mp-split-pattern + helm-pattern) + unless (string-match "\\`!" r) + collect r) + (list helm-pattern)) + do + (while (and (re-search-forward reg nil t) + (> (- (setq end (match-end 0)) + (setq beg (match-beginning 0))) 0)) + (add-text-properties beg end '(face helm-grep-match))) + do (goto-char (point-min))) + (buffer-string)) + (error nil)))) + + +;;; Grep from buffer list +;; +;; +(defun helm-grep-buffers-1 (candidate &optional zgrep) + "Run grep on all file--buffers or CANDIDATE if it is a file--buffer. +If one of selected buffers is not a file--buffer, +it is ignored and grep will run on all others file--buffers. +If only one candidate is selected and it is not a file--buffer, +switch to this buffer and run `helm-occur'. +If a prefix arg is given run grep on all buffers ignoring non--file-buffers." + (let* ((prefarg (or current-prefix-arg helm-current-prefix-arg)) + (helm-ff-default-directory + (if (and helm-ff-default-directory + (file-remote-p helm-ff-default-directory)) + default-directory + helm-ff-default-directory)) + (cands (if prefarg + (buffer-list) + (helm-marked-candidates))) + (win-conf (current-window-configuration)) + ;; Non--fname and remote buffers are ignored. + (bufs (cl-loop for buf in cands + for fname = (buffer-file-name (get-buffer buf)) + when (and fname (not (file-remote-p fname))) + collect (expand-file-name fname)))) + (if bufs + (if zgrep + (helm-do-grep-1 bufs nil 'zgrep) + (helm-do-grep-1 bufs)) + ;; bufs is empty, thats mean we have only CANDIDATE + ;; and it is not a buffer-filename, fallback to occur. + (switch-to-buffer candidate) + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + (helm-occur) + (when (eq helm-exit-status 1) + (set-window-configuration win-conf))))) + +(defun helm-grep-buffers (candidate) + "Action to grep buffers." + (helm-grep-buffers-1 candidate)) + +(defun helm-zgrep-buffers (candidate) + "Action to zgrep buffers." + (helm-grep-buffers-1 candidate 'zgrep)) + + +;;; Helm interface for pdfgrep +;; pdfgrep program +;; and a pdf-reader (e.g xpdf) are needed. +;; +(defvar helm-pdfgrep-default-function 'helm-pdfgrep-init) +(defun helm-pdfgrep-init (only-files) + "Start an asynchronous pdfgrep process in ONLY-FILES list." + (let* ((default-directory (or helm-ff-default-directory + default-directory)) + (fnargs (helm-grep-prepare-candidates + (if (file-remote-p default-directory) + (mapcar #'(lambda (x) + (file-remote-p x 'localname)) + only-files) + only-files) + default-directory)) + (cmd-line (format helm-pdfgrep-default-command + helm-pattern + fnargs)) + process-connection-type) + ;; Start pdf grep process. + (helm-log "Starting Pdf Grep process in directory `%s'" default-directory) + (helm-log "Command line used was:\n\n%s" + (concat ">>> " (propertize cmd-line 'face 'helm-grep-cmd-line) "\n\n")) + (prog1 + (start-file-process-shell-command + "pdfgrep" helm-buffer cmd-line) + (message nil) + (set-process-sentinel + (get-buffer-process helm-buffer) + #'(lambda (_process event) + (if (string= event "finished\n") + (with-helm-window + (setq mode-line-format + '(" " mode-line-buffer-identification " " + (:eval (format "L%s" (helm-candidate-number-at-point))) " " + (:eval (propertize + (format "[Pdfgrep Process Finish - %s result(s)] " + (max (1- (count-lines + (point-min) (point-max))) 0)) + 'face 'helm-grep-finish)))) + (force-mode-line-update)) + (helm-log "Error: Pdf grep %s" + (replace-regexp-in-string "\n" "" event)))))))) + +(defun helm-do-pdfgrep-1 (only) + "Launch pdfgrep with a list of ONLY files." + (unless (executable-find "pdfgrep") + (error "Error: No such program `pdfgrep'.")) + (let* (helm-grep-in-recurse) ; recursion is never used in pdfgrep. + ;; When called as action from an other source e.g *-find-files + ;; we have to kill action buffer. + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + (setq helm-pdfgrep-targets only) + (helm + :sources (helm-build-async-source "PdfGrep" + :init (lambda () + ;; If `helm-find-files' haven't already started, + ;; give a default value to `helm-ff-default-directory'. + (setq helm-ff-default-directory (or helm-ff-default-directory + default-directory))) + :candidates-process (lambda () + (funcall helm-pdfgrep-default-function helm-pdfgrep-targets)) + :filter-one-by-one #'helm-grep-filter-one-by-one + :candidate-number-limit 9999 + :history 'helm-grep-history + :keymap helm-pdfgrep-map + :mode-line helm-pdfgrep-mode-line-string + :action #'helm-pdfgrep-action + :persistent-help "Jump to PDF Page" + :requires-pattern 2) + :buffer "*helm pdfgrep*" + :history 'helm-grep-history))) + +(defun helm-pdfgrep-action (candidate) + (helm-grep-action candidate 'pdf)) + +(defun helm-pdfgrep-action-1 (_split pageno fname) + (save-selected-window + (start-file-process-shell-command + "pdf-reader" nil + (format-spec helm-pdfgrep-default-read-command + (list (cons ?f fname) (cons ?p pageno)))))) + +;;;###autoload +(defun helm-do-grep () + "Preconfigured helm for grep. +Contrarily to Emacs `grep', no default directory is given, but +the full path of candidates in ONLY. +That allow to grep different files not only in `default-directory' but anywhere +by marking them (C-). If one or more directory is selected +grep will search in all files of these directories. +You can also use wildcard in the base name of candidate. +If a prefix arg is given use the -r option of grep (recurse). +The prefix arg can be passed before or after start file selection. +See also `helm-do-grep-1'." + (interactive) + (require 'helm-mode) + (let* ((preselection (or (dired-get-filename nil t) + (buffer-file-name (current-buffer)))) + (only (helm-read-file-name + "Search in file(s): " + :marked-candidates t + :preselect (and helm-do-grep-preselect-candidate + (if helm-ff-transformer-show-only-basename + (helm-basename preselection) + preselection)))) + (prefarg (or current-prefix-arg helm-current-prefix-arg))) + (helm-do-grep-1 only prefarg))) + +;;;###autoload +(defun helm-do-zgrep () + "Preconfigured helm for zgrep." + (interactive) + (require 'helm-mode) + (let* ((prefarg (or current-prefix-arg helm-current-prefix-arg)) + (preselection (or (dired-get-filename nil t) + (buffer-file-name (current-buffer)))) + (ls (helm-read-file-name + "Search in file(s): " + :marked-candidates t + :preselect (and helm-do-grep-preselect-candidate + (if helm-ff-transformer-show-only-basename + (helm-basename preselection) + preselection))))) + (helm-ff-zgrep-1 ls prefarg))) + +;;;###autoload +(defun helm-do-pdfgrep () + "Preconfigured helm for pdfgrep." + (interactive) + (require 'helm-mode) + (let* ((preselection (or (dired-get-filename nil t) + (buffer-file-name (current-buffer)))) + (only (helm-read-file-name + "Search in file(s): " + :marked-candidates t + :test #'(lambda (file) + (or (string= (file-name-extension file) "pdf") + (string= (file-name-extension file) "PDF") + (file-directory-p file))) + :preselect (and helm-do-grep-preselect-candidate + (if helm-ff-transformer-show-only-basename + (helm-basename preselection) + preselection)))) + (helm-grep-default-function 'helm-pdfgrep-init)) + (helm-do-pdfgrep-1 only))) + + +(provide 'helm-grep) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-grep.el ends here diff --git a/elpa/helm-20150403.101/helm-help.el b/elpa/helm-20150403.101/helm-help.el new file mode 100644 index 00000000..682b0fd5 --- /dev/null +++ b/elpa/helm-20150403.101/helm-help.el @@ -0,0 +1,1711 @@ +;;; helm-help.el --- Help messages for Helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'helm) +(require 'helm-org) + + +(defgroup helm-help nil + "Embedded help for `helm'." + :group 'helm) + +(defface helm-helper + '((t :inherit helm-header)) + "Face for helm help string in minibuffer." + :group 'helm-help) + +(defcustom helm-documentation-file "~/.emacs.d/helm-doc.org" + "The file where you want to save helm documentation." + :group 'helm-help + :type 'string) + +(defvar helm-help--string-list '(helm-help-message + helm-buffer-help-message + helm-ff-help-message + helm-read-file-name-help-message + helm-generic-file-help-message + helm-grep-help-message + helm-pdfgrep-help-message + helm-etags-help-message + helm-ucs-help-message + helm-bookmark-help-message + helm-esh-help-message + helm-buffers-ido-virtual-help-message + helm-moccur-help-message + helm-top-help-message + helm-apt-help-message + helm-el-package-help-message + helm-M-x-help-message + helm-imenu-help-message + helm-colors-help-message + helm-semantic-help-message + helm-kmacro-help-message)) + + +;;;###autoload +(defun helm-documentation (arg) + "Helm documentation. +With a prefix arg refresh the documentation. + +Find here the documentation of all sources actually documented." + (interactive "P") + (when arg (delete-file helm-documentation-file) + (helm-aif (get-file-buffer helm-documentation-file) + (kill-buffer it))) + (unless (file-exists-p helm-documentation-file) + (with-temp-file helm-documentation-file + (erase-buffer) + (cl-loop for elm in helm-help--string-list + for str = (symbol-value elm) + do (if (functionp str) + (insert (funcall str)) + (insert str))))) + (let ((helm-org-headings--nofilename t)) + (helm :sources (helm-source-org-headings-for-files + (list helm-documentation-file)) + :candidate-number-limit 99999 + :buffer "*helm documentation*"))) + +;;; Global help message - Used by `helm-help' +;; +;; +(defvar helm-help-message + (lambda () + (concat + "\n* Helm generic help\n" + "\\" + "\n`helm' is an Emacs incremental completion and selection narrowing framework. + +Narrow the list by typing some pattern, +Multiple patterns are allowed by splitting by space. +Select with natural Emacs operations, choose with RET. + +** Help + +C-h m : Run this generic help for helm. +C-c ? : Run specific helm help for current source. + +** Basic Operations + +C-p, Up: Previous Line +C-n, Down : Next Line +M-v, PageUp : Previous Page +C-v, PageDown : Next Page +Enter : Execute first (default) action / Select +M-< : First Line +M-> : Last Line +M-PageUp, C-M-S-v, C-M-y : Previous Page (other-window) +M-PageDown, C-M-v : Next Page (other-window) + +Tab, C-i : Show action list +Left : Previous Source +Right, C-o : Next Source +C-k : Delete pattern (with prefix arg delete from point to end) +C-j or C-z: Persistent Action (Execute action with helm session kept) + +** Shortcuts For nth Action + +f1-12: Execute nth 1 to 12 Action(s). + +** Visible Marks + +Visible marks store candidate. Some actions uses marked candidates. + +\\[helm-toggle-visible-mark] : Toggle Visible Mark +\\[helm-prev-visible-mark] : Previous Mark +\\[helm-next-visible-mark] : Next Mark + +** Miscellaneous Commands + +\\[helm-toggle-resplit-window] : Toggle vertical/horizontal split helm window. +\\[helm-quit-and-find-file] : Drop into `find-file'. +\\[helm-delete-current-selection] : Delete selected item (visually). +\\[helm-kill-selection-and-quit] : Kill display value of candidate and quit (with prefix arg kill the real value). +\\[helm-yank-selection] : Yank selection into pattern. +\\[helm-follow-mode] : Toggle automatical execution of persistent action. +\\[helm-follow-action-forward] : Run persistent action and goto next line. +\\[helm-follow-action-backward] : Run persistent action and goto previous line. +\\[helm-force-update] : Recalculate and redisplay candidates. + +** Global Commands + +\\\\[helm-resume] revives last `helm' session. +It is very useful, so you should bind any key.")) + "Detailed help message string for `helm'. +It also accepts function or variable symbol.") + +(defun helm-help-internal (bufname insert-content-fn) + "Show long message during `helm' session in BUFNAME. +INSERT-CONTENT-FN is the function that insert +text to be displayed in BUFNAME." + (let ((winconf (current-frame-configuration))) + (unwind-protect + (progn + (setq helm-suspend-update-flag t) + (set-buffer (get-buffer-create bufname)) + (switch-to-buffer bufname) + (delete-other-windows) + (delete-region (point-min) (point-max)) + (outline-mode) + (save-excursion + (funcall insert-content-fn)) + (setq cursor-type nil) + (buffer-disable-undo) + (helm-help-event-loop)) + (setq helm-suspend-update-flag nil) + (set-frame-configuration winconf)))) + +(defun helm-help-scroll-up (amount) + (condition-case _err + (scroll-up-command amount) + (beginning-of-buffer nil) + (end-of-buffer nil))) + +(defun helm-help-scroll-down (amount) + (condition-case _err + (scroll-down-command amount) + (beginning-of-buffer nil) + (end-of-buffer nil))) + +(defun helm-help-event-loop () + (let ((prompt (propertize + "[SPC,C-v,down,next:NextPage b,M-v,up,prior:PrevPage C-s/r:Isearch q:Quit]" + 'face 'helm-helper)) + scroll-error-top-bottom) + (cl-loop for event = (read-key prompt) do + (cl-case event + ((?\C-v ? down next) (helm-help-scroll-up helm-scroll-amount)) + ((?\M-v ?b up prior) (helm-help-scroll-down helm-scroll-amount)) + (?\C-s (isearch-forward)) + (?\C-r (isearch-backward)) + (?q (cl-return)) + (t (ignore)))))) + +;;;###autoload +(defun helm-help () + "Help of `helm'." + (interactive) + (with-helm-alive-p + (save-selected-window + (helm-help-internal + "*Helm Help*" + (lambda () + (insert (substitute-command-keys + (helm-interpret-value (or (assoc-default + 'help-message + (helm-get-current-source)) + helm-help-message))))))))) + +;;; `helm-buffer-list' help +;; +;; +(defvar helm-buffer-help-message + "\n* Helm Buffer\n + +** Helm buffers tips: + +*** Completion: + +**** Major-mode: + +You can enter a partial name of major-mode (e.g lisp, sh) to narrow down buffers. +To specify the major-mode, prefix it with \"*\" e.g \"*lisp\". +If you want to match all buffers but the ones with a specific major-mode (negation), +prefix the major-mode with \"!\" e.g \"*!lisp\". +If you want to specify more than one major-mode, separate them with \",\", +e.g \"*!lisp,!sh,!fun\" will list all buffers but the ones in lisp-mode, sh-mode and +fundamental-mode. + +Enter then a space and a pattern to narrow down to buffers matching this pattern. + +**** Search inside buffers: + +If you enter a space and a pattern prefixed by \"@\" helm will search for text matching +this pattern INSIDE the buffer (i.e not in the name of buffer). +NOTE that if you enter your pattern prefixed with \"@\" but escaped, helm will search a buffer +matching \"@pattern\" but will not search inside. + +**** Search by directory name: + +If you prefix the beginning of pattern with \"/\" the match will occur on directory name +of buffer, it is interesting to narrow down to one directory for example, subsequent string +entered after a space will match on buffer-name only. +Note that negation is not supported for matching on buffer-file-name. +You can specify more than one directory starting from helm v1.6.8 + +**** Fuzzy matching: + +Note that if `helm-buffers-fuzzy-matching' is non--nil you will have +fuzzy matching on buffer names (not on directory name matching and major-mode though). +A pattern starting with \"^\" will disable fuzzy matching and will match by exact regexp. + +**** Examples: + +if I enter in pattern prompt: +\"*lisp ^helm @moc\" +helm will narrow down the list by selecting only buffers that are in lisp mode, start by helm +and match \"moc\" in their contents. + +if I enter in pattern prompt: +\"*lisp ^helm moc\" +Notice there is no \"@\" this time +helm will look for lisp mode buffers starting by \"helm\" and have \"moc\" in their name. + +if I enter in pattern prompt: +\"*!lisp !helm\" +helm will narrow down to buffers that are not in \"lisp\" mode and that do not match \"helm\" + +if I enter in pattern prompt: +/helm/ w3 +helm will narrow down to buffers that are in any \"helm\" subdirectory and matching w3. + + +*** Creating buffers + +When creating a new buffer use \\[universal-argument] to choose a mode for your buffer in a list. +This list is customizable, see `helm-buffers-favorite-modes'. + +*** Killing buffers + +You have a command to kill buffer(s) and quit emacs and a command to kill buffers one by one +\(no marked\) without quitting helm. +You can run this persistent kill buffer command either with the regular +`helm-execute-persistent-action' called with a prefix arg (C-u C-j) or with its specific command +`helm-buffer-run-kill-persistent' see binding below. + +*** Meaning of colors and prefixes for buffers: + +Remote buffers are prefixed with '@'. +Red => Buffer have its file modified on disk by an external process. +Indianred2 => Buffer exists but its file have been deleted. +Orange => Buffer is modified and its file not saved to disk. +Italic => A non--file buffer. + +\n** Specific commands for `helm-buffers-list': +\\ +\\[helm-buffer-run-zgrep]\t\t->Grep Buffer(s) works as zgrep too (C-u grep all buffers but non--file buffers). +\\[helm-buffers-run-multi-occur]\t\t->Multi Occur buffer or marked buffers. (C-u toggle force searching current-buffer). +\\[helm-buffer-switch-other-window]\t\t->Switch other window. +\\[helm-buffer-switch-other-frame]\t\t->Switch other frame. +\\[helm-buffer-run-query-replace-regexp]\t\t->Query replace regexp in marked buffers. +\\[helm-buffer-run-query-replace]\t\t->Query replace in marked buffers. +\\[helm-buffer-run-ediff]\t\t->Ediff current buffer with candidate. If two marked buffers ediff those buffers. +\\[helm-buffer-run-ediff-merge]\t\t->Ediff merge current buffer with candidate. If two marked buffers ediff merge those buffers. +\\[helm-buffer-diff-persistent]\t\t->Toggle Diff buffer with saved file without quitting. +\\[helm-buffer-revert-persistent]\t\t->Revert buffer without quitting. +\\[helm-buffer-save-persistent]\t\t->Save buffer without quitting. +\\[helm-buffer-run-kill-buffers]\t\t->Delete marked buffers and quit. +\\[helm-buffer-run-kill-persistent]\t\t->Delete buffer without quitting helm. +\\[helm-toggle-all-marks]\t\t->Toggle all marks. +\\[helm-mark-all]\t\t->Mark all. +\\[helm-toggle-buffers-details]\t\t->Toggle details. +\\[helm-buffers-toggle-show-hidden-buffers]\t\t->Show hidden buffers. +\\[helm-buffers-mark-similar-buffers]\t\t->Mark all buffers with same type (color) than current. +\\[helm-buffer-help]\t\t->Display this help. +\n** Helm Map +\\{helm-map}") + +;;;###autoload +(defun helm-buffer-help () + "Help command for helm buffers." + (interactive) + (let ((helm-help-message helm-buffer-help-message)) + (helm-help))) + +;;; Find files help (`helm-find-files') +;; +;; +(defvar helm-ff-help-message + "\n* Helm Find Files\n + +** Helm find files tips: +\n*** Enter `~/' at end of pattern to quickly reach home directory. + +*** Enter `/' at end of pattern to quickly reach root of your file system. + +*** Enter `./' at end of pattern to quickly reach `default-directory' (initial start of session). + If you are already in `default-directory' this will move cursor on top. + +*** Enter `../' at end of pattern will reach upper directory, moving cursor on top. + NOTE: This different to using `C-l' in that `C-l' don't move cursor on top but stay on previous + subdir name. + +*** You can complete with partial basename (start on third char entered) + + e.g \"fob\" or \"fbr\" will complete \"foobar\" + but \"fb\" will wait for a third char for completing. + +*** Use `C-u C-j' to watch an image. + +*** `C-j' on a filename will expand in helm-buffer to this filename. + Second hit on `C-j' will display buffer filename. + Third hit on `C-j' will kill buffer filename. + NOTE: `C-u C-j' will display buffer directly. + +*** To browse images directories turn on `helm-follow-mode' and navigate with arrow keys. + You can also use `helm-follow-action-forward' and `helm-follow-action-backward' + (`C-'). + +*** You can turn off/on (toggle) autoupdate completion at any moment with `C-DEL'. + NOTE: On a terminal C- may not work, use in this case C-c . + +*** You can create a new directory and a new file at the same time. + just write the path in prompt and press `'. + e.g You can create \"~/new/newnew/newnewnew/my_newfile.txt\". + +*** To create a new directory, add a \"/\" at end of new name and press . + +*** To create a new file just write the filename not ending with \"/\". + +*** Recursive search from helm find files + +**** You can use helm browse project (see binding below). + +- With no prefix arg + If your current directory is under version control + with one of git or hg and you have installed helm-ls-git and/or helm-ls-hg + https://github.com/emacs-helm/helm-ls-git.git + https://github.com/emacs-helm/helm-ls-hg + you will see all your files under version control, otherwise + you will be back to helm-find-files. +- With one prefix arg + You will see all the files under this directory + and other subdirectories (recursion) and this list of files will be cached. +- With two prefix args + same but the cache will be refreshed. + +**** You can start a recursive search with Locate of Find (See commands below). + With Locate you can use a local db with a prefix arg; If the localdb doesn't already + exists, you will be prompted for its creation, if it exists and you want to refresh it, + give two prefix args. + +*** Insert filename at point or complete filename at point + +On insertion (no completion, i.e nothing at point): + +- `C-c i' => insert absolute file name. +- `C-u C-c i' => insert abbreviate file name. +- `C-u C-u C-c i' => insert relative file name. + +On completion: + +- target starts by ~/ => insert abbreviate file name. +- target starts by / or [a-z]:/ => insert full path. +- otherwise => insert relative file name. + +*** Using wildcard to select multiple files + +Use of wilcard is supported to give a set of files to an action: + +e.g +You can copy all the files with \".el\" extension by using \"*.el\" +and then run your copy action. + +You can do the same but with \"**.el\" (note the two stars), +this will select recursively all \".el\" files under current directory. + +NOTE: When using an action that involve an external backend (e.g grep), using \"**\" +is not advised (even if it works fine) because it will be slower to select all your files, +you have better time letting the backend doing it, it will be faster. +However, if you know you have not many files it is reasonable to use this, +also using not recursive wilcard (e.g \"*.el\") is perfectly fine for this. + +This feature (\"**\") is activated by default with the option `helm-file-globstar'. +The directory selection with \"**foo/\" like bash shopt globstar option is not supported yet. + +\n** Specific commands for `helm-find-files':\n +\\ +\\[helm-ff-run-locate]\t\t->Run Locate (C-u to specify locate db, M-n insert basename of candidate) +\\[helm-ff-run-browse-project]\t\t->Browse project (`C-u' recurse, `C-u C-u' recurse and refresh db) +\\[helm-ff-run-find-sh-command]\t\t->Run Find shell command from this directory. +\\[helm-ff-run-grep]\t\t->Run Grep (C-u Recursive). +\\[helm-ff-run-pdfgrep]\t\t->Run Pdfgrep on marked files. +\\[helm-ff-run-zgrep]\t\t->Run zgrep (C-u Recursive). +\\[helm-ff-run-etags]\t\t->Run Etags (C-u use thing-at-point `C-u C-u' reload cache) +\\[helm-ff-run-rename-file]\t\t->Rename File (C-u Follow). +\\[helm-ff-run-query-replace-on-marked]\t\t->Query replace on marked files. +\\[helm-ff-run-copy-file]\t\t->Copy File (C-u Follow). +\\[helm-ff-run-byte-compile-file]\t\t->Byte Compile File (C-u Load). +\\[helm-ff-run-load-file]\t\t->Load File. +\\[helm-ff-run-symlink-file]\t\t->Symlink File. +\\[helm-ff-run-hardlink-file]\t\t->Hardlink file. +\\[helm-ff-run-delete-file]\t\t->Delete File. +\\[helm-ff-run-kill-buffer-persistent]\t\t->Kill buffer candidate without quitting. +\\[helm-ff-persistent-delete]\t\t->Delete file without quitting. +\\[helm-ff-run-switch-to-eshell]\t\t->Switch to Eshell. +\\[helm-ff-run-eshell-command-on-file]\t\t->Eshell command on file (C-u Apply on marked files, otherwise treat them sequentially). +\\[helm-ff-run-ediff-file]\t\t->Ediff file. +\\[helm-ff-run-ediff-merge-file]\t\t->Ediff merge file. +\\[helm-ff-run-complete-fn-at-point]\t\t->Complete file name at point. +\\[helm-ff-run-switch-other-window]\t\t->Switch other window. +\\[helm-ff-run-switch-other-frame]\t\t->Switch other frame. +\\[helm-ff-run-open-file-externally]\t\t->Open file with external program (C-u to choose). +\\[helm-ff-run-open-file-with-default-tool]\t\t->Open file externally with default tool. +\\[helm-ff-rotate-left-persistent]\t\t->Rotate Image Left. +\\[helm-ff-rotate-right-persistent]\t\t->Rotate Image Right. +\\[helm-find-files-up-one-level]\t\t->Go down precedent directory. +\\[helm-ff-run-switch-to-history]\t\t->Switch to last visited directories history. +\\[helm-ff-file-name-history]\t\t->Switch to file name history. +\\[helm-ff-properties-persistent]\t\t->Show file properties in a tooltip. +\\[helm-mark-all]\t\t->Mark all visibles candidates. +\\[helm-ff-run-toggle-auto-update]\t\t->Toggle auto expansion of directories. +\\[helm-unmark-all]\t\t->Unmark all candidates, visibles and invisibles. +\\[helm-ff-run-gnus-attach-files]\t\t->Gnus attach files to message buffer. +\\[helm-ff-run-print-file]\t\t->Print file, (C-u to refresh printers list). +\\[helm-enlarge-window]\t\t->Enlarge helm window. +\\[helm-narrow-window]\t\t->Narrow helm window. +\\[helm-ff-run-toggle-basename]\t\t->Toggle basename/fullpath. +\\[helm-ff-run-find-file-as-root]\t\t->Find file as root. +\\[helm-ff-run-insert-org-link]\t\t->Insert org link. +\\[helm-ff-help]\t\t->Display this help info. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-ff-help () + "Help command for `helm-find-files'." + (interactive) + (let ((helm-help-message helm-ff-help-message)) + (helm-help))) + +;;; Help for `helm-read-file-name' +;; +;; +(defvar helm-read-file-name-help-message + "\n* Helm read file name\n + +** Helm read file name tips: + +\n*** Enter `~/' at end of pattern to quickly reach home directory. + +*** Enter `/' at end of pattern to quickly reach root of your file system. + +*** Enter `./' at end of pattern to quickly reach `default-directory' (initial start of session). + If you are in `default-directory' move cursor on top. + +*** Enter `../' at end of pattern will reach upper directory, moving cursor on top. + NOTE: This different to using `C-l' in that `C-l' don't move cursor on top but stay on previous + subdir name. + +*** You can complete with partial basename (start on third char entered) + + e.g \"fob\" or \"fbr\" will complete \"foobar\" + but \"fb\" will wait for a third char for completing. + +*** Persistent actions: + +By default `helm-read-file-name' use the persistent actions of `helm-find-files'. + +**** Use `C-u C-j' to watch an image. + +**** `C-j' on a filename will expand in helm-buffer to this filename. + Second hit on `C-j' will display buffer filename. + Third hit on `C-j' will kill buffer filename. + NOTE: `C-u C-j' will display buffer directly. + +**** To browse images directories turn on `helm-follow-mode' and navigate with arrow keys. + +**** When you want to delete backward characters to e.g creating a new file or directory, + autoupdate may keep updating to an existent directory + preventing you to do so, in this case just hit C- and then . + This should not needed when copying/renaming files because autoupdate is disabled + by default in this case. + NOTE: On a terminal C- may not work, use in this case C-c . + +**** You can create a new directory and a new file at the same time, just write the path in prompt + and press . + e.g You can create \"~/new/newnew/newnewnew/my_newfile.txt\". + +**** To create a new directory, add a \"/\" at end of new name and press . + +**** To create a new file just write the filename not ending with \"/\". + +\n** Specific commands for helm-read-file-name:\n +\\ +\\[helm-find-files-up-one-level]\t\t->Go down precedent directory. +\\[helm-ff-run-toggle-auto-update]\t\t->Toggle auto expansion of directories. +\\[helm-ff-run-toggle-basename]\t\t->Toggle basename. +\\[helm-ff-file-name-history]\t\t->File name history. +C/\\[helm-cr-empty-string]\t\t->Maybe return empty string (unless `must-match'). +\\[helm-next-source]\t\t->Goto next source. +\\[helm-previous-source]\t->Goto previous source. +\\[helm-read-file-name-help]\t\t->Display this help info. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-read-file-name-help () + (interactive) + (let ((helm-help-message helm-read-file-name-help-message)) + (helm-help))) + +;;; Generic file help - Used by locate. +;; +;; +(defvar helm-generic-file-help-message + "\n* Helm Generic files\n + +** Helm generic file tips:\n + +*** Locate +You can add after writing search pattern any of the locate command line options. +e.g -b, -e, -n ...etc. +See Man locate for more infos. + +Some other sources (at the moment recentf and file in current directory sources) +support the -b flag for compatibility with locate when they are used with it. + +*** Browse project + +When your directory is not under version control, +don't forget to refresh your cache when files have been added/removed in your directory. + +*** Find command + +Recursively search files using \"find\" shell command. + +Candidates are all filenames that match all given globbing patterns. +This respects the options `helm-case-fold-search' and +`helm-findutils-search-full-path'. + +You can pass arbitrary options directly to find after a \"*\" separator. +For example, this would find all files matching \"book\" that are larger +than 1 megabyte: + +book * -size +1M + +\n** Specific commands for helm locate and others files sources: + +\\ +\\[helm-ff-run-toggle-basename]\t\t->Toggle basename. +\\[helm-ff-run-grep]\t\t->Run grep (C-u recurse). +\\[helm-ff-run-pdfgrep]\t\t->Run Pdfgrep on marked files. +\\[helm-ff-run-delete-file]\t\t->Delete file. +\\[helm-ff-run-ediff-file]\t\t->Ediff file. +\\[helm-ff-run-ediff-merge-file]\t\t->Ediff merge file. +\\[helm-ff-run-switch-other-window]\t\t->Switch other window. +\\[helm-ff-properties-persistent]\t\t->Show file properties. +\\[helm-ff-run-etags]\t\t->Run etags (C-u use tap, C-u C-u reload DB). +\\[helm-yank-text-at-point]\t\t->Yank text at point. +\\[helm-ff-run-open-file-externally]\t\t->Open file with external program (C-u to choose). +\\[helm-ff-run-open-file-with-default-tool]\t\t->Open file externally with default tool. +\\[helm-ff-run-insert-org-link]\t\t->Insert org link. +\\[helm-generic-file-help]\t\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-generic-file-help () + (interactive) + (let ((helm-help-message helm-generic-file-help-message)) + (helm-help))) + +;;; Grep help +;; +;; +(defvar helm-grep-help-message + "\n* Helm Grep\n +** Helm grep tips:\n +*** You can start grep with a prefix arg to recurse in subdirectories. +*** You can use wild card when selecting files (e.g *.el) +*** You can grep in many differents directories by marking files or wild cards. +*** You can save your results in a grep-mode buffer, see commands below. + +*** Important:\n +Grepping on remote file will work only with grep, not ack-grep, but it is +anyway bad supported as tramp doesn't support multiple process running in a +short delay (less than 5s actually) among other things, +so I strongly advice hitting `C-!' (i.e suspend process) +before entering anything in pattern, and hit again `C-!' when +your regexp is ready to send to remote process, even if helm is handling +this by delaying each process at 5s. +Or even better don't use tramp at all and mount your remote file system on SSHFS. + +\n** Specific commands for Helm Grep:\n +\\ +\\[helm-goto-next-file]\t->Next File. +\\[helm-goto-precedent-file]\t\t->Precedent File. +\\[helm-yank-text-at-point]\t\t->Yank Text at point in minibuffer. +\\[helm-grep-run-other-window-action]\t\t->Jump other window. +\\[helm-grep-run-other-frame-action]\t\t->Jump other frame. +\\[helm-grep-run-persistent-action]\t\t->Run persistent action (Same as `C-j'). +\\[helm-grep-run-default-action]\t\t->Run default action (Same as RET). +\\[helm-grep-run-save-buffer]\t\t->Save to a `grep-mode' enabled buffer. +\\[helm-grep-help]\t\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-grep-help () + (interactive) + (let ((helm-help-message helm-grep-help-message)) + (helm-help))) + +;;; Pdf grep help +;; +;; +(defvar helm-pdfgrep-help-message + "\n* Helm PdfGrep Map\n +\n** Specific commands for Pdf Grep:\n +\\ +\\[helm-goto-next-file]\t->Next File. +\\[helm-goto-precedent-file]\t\t->Precedent File. +\\[helm-yank-text-at-point]\t\t->Yank Text at point in minibuffer. +\\[helm-pdfgrep-help]\t\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-pdfgrep-help () + (interactive) + (let ((helm-help-message helm-pdfgrep-help-message)) + (helm-help))) + +;;; Etags help +;; +;; +(defvar helm-etags-help-message + "\n* Helm Etags Map\n +\n** Specific commands for Etags:\n +\\ +\\[helm-goto-next-file]\t->Next File. +\\[helm-goto-precedent-file]\t\t->Precedent File. +\\[helm-yank-text-at-point]\t\t->Yank Text at point in minibuffer. +\\[helm-etags-help]\t\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-etags-help () + "The help function for etags." + (interactive) + (let ((helm-help-message helm-etags-help-message)) + (helm-help))) + +;;; Ucs help +;; +;; +(defvar helm-ucs-help-message + "\n* Helm Ucs\n +\n** Specific commands for `helm-ucs':\n +\\ +\\[helm-ucs-persistent-insert]\t->Insert char. +\\[helm-ucs-persistent-forward]\t->Forward char. +\\[helm-ucs-persistent-backward]\t->Backward char. +\\[helm-ucs-persistent-delete]\t->Delete char backward. +\\[helm-ucs-help]\t\t->Show this help. + +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-ucs-help () + "Help command for `helm-ucs'." + (interactive) + (let ((helm-help-message helm-ucs-help-message)) + (helm-help))) + +;;; Bookmark help +;; +;; +(defvar helm-bookmark-help-message + "\n* Helm bookmark name\n +\n** Specific commands for bookmarks:\n +\\ +\\[helm-bookmark-run-jump-other-window]\t\t->Jump other window. +\\[helm-bookmark-run-delete]\t\t->Delete bookmark. +\\[helm-bookmark-run-edit]\t\t->Edit bookmark. +\\[helm-bookmark-toggle-filename]\t\t->Toggle bookmark location visibility. +\\[helm-bookmark-help]\t\t->Run this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-bookmark-help () + "Help command for bookmarks." + (interactive) + (let ((helm-help-message helm-bookmark-help-message)) + (helm-help))) + +;;; Eshell command on file help +;; +;; +(defvar helm-esh-help-message + "\n* Helm eshell on file\n +** Helm eshell on file tips: + +*** Passing extra args after filename: + +Normally your command or alias will be called with file as argument. + +e.g 'candidate_file' + +But you can also pass an argument or more after 'candidate_file' like this: + + %s [extra_args]\n + +'candidate_file' will be added at '%s' and your command will look at this: + + 'candidate_file' [extra_args] + +*** Specify many files as args (marked files): + +e.g file1 file2 ... + +Call `helm-find-files-eshell-command-on-file' with one prefix-arg +Otherwise you can pass one prefix-arg from the command selection buffer. +NOTE: This is not working on remote files. + +With two prefix-arg before starting or from the command selection buffer +the output is printed to your `current-buffer'. + +Note that with no prefix-arg or a prefix-arg value of '(16) (C-u C-u) +the command is called once for each file like this: + + file1 file2 etc... + +\n** Specific commands for `helm-find-files-eshell-command-on-file':\n +\\ +\\[helm-esh-help]\t\t->Display this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-esh-help () + "Help command for `helm-find-files-eshell-command-on-file'." + (interactive) + (let ((helm-help-message helm-esh-help-message)) + (helm-help))) + +;;; Ido virtual buffer help +;; +;; +(defvar helm-buffers-ido-virtual-help-message + "\n* Helm ido virtual buffers\n +\n** Specific commands for ido virtuals buffers:\n +\\ +\\[helm-ff-run-switch-other-window]\t\t->Switch other window. +\\[helm-ff-run-switch-other-frame]\t\t->Switch other frame. +\\[helm-ff-run-grep]\t\t->Grep file. +\\[helm-ff-run-zgrep]\t\t->Zgrep file. +\\[helm-ff-run-delete-file]\t\t->Delete file. +\\[helm-ff-run-open-file-externally]\t\t->Open file externally. +\\[helm-buffers-ido-virtual-help]\t\t->Display this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-buffers-ido-virtual-help () + "Help command for ido virtual buffers." + (interactive) + (let ((helm-help-message helm-buffers-ido-virtual-help-message)) + (helm-help))) + +;;; Moccur help +;; +;; +(defvar helm-moccur-help-message + "\n* Helm Moccur\n +** Helm Moccur tips: + +*** Matching +Multiple regexp matching is allowed, just enter a space to separate your regexps. + +Matching empty lines is supported with the regexp \"^$\", you will get the results +with only the buffer-name and the line number, you can of course save and edit these +results. + +*** Jump to the corresponding line in the searched buffer +You can do this with `C-j' (persistent-action), to do it repetitively +you can use `C-' and `C-' or enable `helm-follow-mode' with `C-c C-f'. + +*** Saving results +Same as with helm-grep, you can save the results with `C-x C-s'. +Of course if you don't save your results, you can get back your session +with `helm-resume'. + +*** Refreshing the resumed session. +When the buffer(s) where you ran helm-(m)occur have been modified, you will be +warned of this with the buffer flashing to red, you can refresh the buffer by running +`C-c C-u'. +This can be done automatically by customizing `helm-moccur-auto-update-on-resume'. + +*** Refreshing a saved buffer +Just hit `g' to update your buffer. + +*** Edit a saved buffer + +To do so you have to install wgrep +https://github.com/mhayashi1120/Emacs-wgrep +and then: + +1) C-c C-p to edit the buffer(s). +2) C-x C-s to save your changes. + +Tip: Use the excellent iedit https://github.com/tsdh/iedit +to modify occurences in your buffer. + +\n** Specific commands for Helm Moccur:\n +\\ +\\[helm-goto-next-file]\t->Next Buffer. +\\[helm-goto-precedent-file]\t\t->Precedent Buffer. +\\[helm-yank-text-at-point]\t\t->Yank Text at point in minibuffer. +\\[helm-moccur-run-goto-line-ow]\t\t->Goto line in other window. +\\[helm-moccur-run-goto-line-of]\t\t->Goto line in new frame. +\\[helm-moccur-help]\t\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-moccur-help () + (interactive) + (let ((helm-help-message helm-moccur-help-message)) + (helm-help))) + +;;; Helm Top +;; +;; +(defvar helm-top-help-message + "\n* Helm Top\n +\n** Helm Top tips: + +\n** Specific commands for Helm Top:\n +\\ +\\[helm-top-run-sort-by-com]\t->Sort by commands. +\\[helm-top-run-sort-by-cpu]\t->Sort by cpu usage. +\\[helm-top-run-sort-by-user]\t->Sort alphabetically by user. +\\[helm-top-run-sort-by-mem]\t->Sort by memory. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-top-help () + (interactive) + (let ((helm-help-message helm-top-help-message)) + (helm-help))) + +;;; Helm Apt +;; +;; +(defvar helm-apt-help-message + "\n* Helm Apt\n +\n** Helm Apt tips: + +\n** Specific commands for Helm Apt:\n +\\ +\\[helm-apt-show-all]\t->Show all packages. +\\[helm-apt-show-only-installed]\t->Show installed packages only. +\\[helm-apt-show-only-not-installed]\t->Show not installed packages only. +\\[helm-apt-show-only-deinstalled]\t-Show deinstalled (not purged yet) packages only.> +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-apt-help () + (interactive) + (let ((helm-help-message helm-apt-help-message)) + (helm-help))) + +;;; Helm elisp package +;; +;; +(defvar helm-el-package-help-message + "\n* Helm elisp package\n +\n** Helm elisp package tips: +*** Upgrade elisp packages + +To see upgradables packages hit . + +Then you can install all upgradables packages with the upgrade all action, +or upgrade only the specific packages by marking them (the new ones) and running +the upgrade action (visible only when there is upgradables packages). +Of course you can upgrade a single package by just running the upgrade action +without marking it. + +*** Meaning of flags prefixing packages (Emacs-25) + +- The flag \"S\" that prefix package names mean that this package is one of `package-selected-packages'. +This feature is only available with emacs-25. + +- The flag \"U\" that prefix package names mean that this package is no more needed. +This feature is only available with emacs-25. + +\n** Specific commands for Helm elisp package:\n +\\ +\\[helm-el-package-show-all]\t->Show all packages. +\\[helm-el-package-show-installed]\t->Show installed packages only. +\\[helm-el-package-show-uninstalled]\t->Show not installed packages only. +\\[helm-el-package-help]\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-el-package-help () + (interactive) + (let ((helm-help-message helm-el-package-help-message)) + (helm-help))) + +;;; Helm M-x +;; +;; +(defvar helm-M-x-help-message + "\n* Helm M-x\n +\n** Helm M-x tips: + +*** You can get help on any command with persistent action (C-j). + +*** All the prefix args passed BEFORE running `helm-M-x' are ignored, +you should have an error message if you do so. +When you want to pass prefix args, pass them AFTER starting `helm-M-x', +you will have a prefix arg counter appearing in mode-line notifying you +the amount of prefix args entered. + +\n** Specific commands for Helm M-x:\n +\\ +\\[helm-M-x-help]\t\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-M-x-help () + (interactive) + (let ((helm-help-message helm-M-x-help-message)) + (helm-help))) + +;;; helm-imenu +;; +;; +(defvar helm-imenu-help-message + "\n* Helm imenu\n +\n** Helm imenu tips: + +\n** Specific commands for Helm imenu:\n +\\ +\\[helm-imenu-help]\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-imenu-help () + (interactive) + (let ((helm-help-message helm-imenu-help-message)) + (helm-help))) + +;;; helm-colors +;; +;; +(defvar helm-colors-help-message + "\n* Helm colors\n +\n** Specific commands for Helm colors:\n +\\ +\\[helm-color-run-insert-name]\t\tInsert the entry'name. +\\[helm-color-run-kill-name]\t\tKill the entry's name. +\\[helm-color-run-insert-rgb]\t\tInsert entry in RGB format. +\\[helm-color-run-kill-rgb]\t\tKill entry in RGB format. +\\[helm-color-help]\t\tShow this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-color-help () + (interactive) + (let ((helm-help-message helm-colors-help-message)) + (helm-help))) + +;;; helm semantic +;; +;; +(defvar helm-semantic-help-message + "\n* Helm semantic\n +\n** Helm semantic tips: + +\n** Specific commands for Helm semantic:\n +\\ +\\[helm-semantic-help]\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-semantic-help () + (interactive) + (let ((helm-help-message helm-semantic-help-message)) + (helm-help))) + +;;; helm kmacro +;; +;; +(defvar helm-kmacro-help-message + "\n* Helm kmacro\n +\n** Helm kmacro tips: +- Start recording some keys with `f3' +- Record new kmacro with `f4' +- Start `helm-execute-kmacro' to list all your macros. + +Use persistent action to run your kmacro as many time as needed, +you can change of kmacro with `helm-next-line' `helm-previous-line'. + +NOTE: You can't record keys running helm commands. + +\n** Specific commands for Helm kmacro:\n +\\ +\\[helm-kmacro-help]\t->Show this help. +\n** Helm Map\n +\\{helm-map}") + +;;;###autoload +(defun helm-kmacro-help () + (interactive) + (let ((helm-help-message helm-kmacro-help-message)) + (helm-help))) + + +;;; Mode line strings +;; +;; +;;;###autoload +(defvar helm-buffer-mode-line-string + '("Buffer(s)" "\ +\\\ +\\[helm-buffer-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "String displayed in mode-line in `helm-source-buffers-list'")) + +;;;###autoload +(defvar helm-color-mode-line-string + '("Colors" "\ +\\\ +\\[helm-color-help]:Help/\ +\\[helm-color-run-insert-name]:Insert name/\ +\\[helm-color-run-insert-rgb]:Insert RGB/\ +with shift: Kill")) + +;;;###autoload +(defvar helm-buffers-ido-virtual-mode-line-string + '("Killed Buffer(s)" "\ +\\\ +\\[helm-buffers-ido-virtual-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "String displayed in mode-line in `helm-source-buffers-list'")) + +;;;###autoload +(defvar helm-ff-mode-line-string "\ +\\\ +\\[helm-ff-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "String displayed in mode-line in `helm-source-find-files'") + +;;;###autoload +(defvar helm-read-file-name-mode-line-string "\ +\\\ +\\[helm-read-file-name-help]:Help \ +C/\\[helm-cr-empty-string]:Empty \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "String displayed in mode-line in `helm-source-find-files'.") + +;;;###autoload +(defvar helm-generic-file-mode-line-string "\ +\\\ +\\[helm-generic-file-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend" + "String displayed in mode-line in Locate.") + +;;;###autoload +(defvar helm-grep-mode-line-string"\ +\\\ +\\[helm-grep-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend" + "String displayed in mode-line in `helm-do-grep'.") + +;;;###autoload +(defvar helm-pdfgrep-mode-line-string "\ +\\\ +\\[helm-pdfgrep-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend" + "String displayed in mode-line in `helm-do-pdfgrep'.") + +;;;###autoload +(defvar helm-etags-mode-line-string "\ +\\\ +\\[helm-etags-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "String displayed in mode-line in `helm-etags-select'.") + +;;;###autoload +(defvar helm-ucs-mode-line-string "\ +\\\ +\\[helm-ucs-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "String displayed in mode-line in `helm-ucs'.") + +;;;###autoload +(defvar helm-bookmark-mode-line-string + '("Bookmark(s)" "\ +\\\ +\\[helm-bookmark-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct") + "String displayed in mode-line in `helm-source-buffers-list'") + +;;;###autoload +(defvar helm-occur-mode-line "\ +\\\ +\\[helm-help]:Help \ +\\\ +\\[helm-occur-run-query-replace-regexp]:Query replace regexp \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-moccur-mode-line "\ +\\\ +\\[helm-moccur-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-comp-read-mode-line "\ +\\\ +C/\\[helm-cr-empty-string]:Empty \ +\\\ +\\[helm-help]:Help \ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct") + +;;;###autoload +(defvar helm-top-mode-line "\ +\\\ +\\[helm-top-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-apt-mode-line "\ +\\\ +\\[helm-apt-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-el-package-mode-line "\ +\\\ +\\[helm-el-package-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-M-x-mode-line "\ +\\\ +\\[helm-M-x-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-imenu-mode-line "\ +\\\ +\\[helm-imenu-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + +;;;###autoload +(defvar helm-semantic-mode-line "\ +\\\ +\\[helm-semantic-help]:Help \ +\\\ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct \ +\\[helm-toggle-suspend-update]:Tog.suspend") + + +;;; Attribute Documentation +;; +;; +;;;###autoload +(defun helm-describe-helm-attribute (helm-attribute) + "Display the full documentation of HELM-ATTRIBUTE. +HELM-ATTRIBUTE should be a symbol." + (interactive (list (intern + (completing-read + "Describe helm attribute: " + (mapcar 'symbol-name helm-attributes) + nil t)))) + (with-output-to-temp-buffer "*Help*" + (princ (get helm-attribute 'helm-attrdoc)))) + +(helm-document-attribute 'name "mandatory" + " The name of the source. It is also the heading which appears + above the list of matches from the source. Must be unique.") + +(helm-document-attribute 'header-name "optional" + " A function returning the display string of the header. Its + argument is the name of the source. This attribute is useful to + add an additional information with the source name.") + +(helm-document-attribute 'candidates "mandatory if candidates-in-buffer attribute is not provided" + " Specifies how to retrieve candidates from the source. It can + either be a variable name, a function called with no parameters + or the actual list of candidates. + + The list must be a list whose members are strings, symbols + or (DISPLAY . REAL) pairs. + + In case of (DISPLAY . REAL) pairs, the DISPLAY string is shown + in the Helm buffer, but the REAL one is used as action + argument when the candidate is selected. This allows a more + readable presentation for candidates which would otherwise be, + for example, too long or have a common part shared with other + candidates which can be safely replaced with an abbreviated + string for display purposes. + + Note that if the (DISPLAY . REAL) form is used then pattern + matching is done on the displayed string, not on the real + value. + + If the candidates have to be retrieved asynchronously (for + example, by an external command which takes a while to run) + then the function should start the external command + asynchronously and return the associated process object. + Helm will take care of managing the process (receiving the + output from it, killing it if necessary, etc.). The process + should return candidates matching the current pattern (see + variable `helm-pattern'.) + You should use instead `candidates-process' attribute for + async processes, a warning will popup when using async process + in a `candidates' attribute. + + Note that currently results from asynchronous sources appear + last in the helm buffer regardless of their position in + `helm-sources'.") + +(helm-document-attribute 'candidates-process + "Same as `candidates' attributes but for process function." + " You should use this attribute when using a function involving + an async process instead of `candidates'.") + +(helm-document-attribute 'action "mandatory if type attribute is not provided" + " It is a list of (DISPLAY . FUNCTION) pairs or FUNCTION. + FUNCTION is called with one parameter: the selected candidate. + + An action other than the default can be chosen from this list + of actions for the currently selected candidate (by default + with TAB). The DISPLAY string is shown in the completions + buffer and the FUNCTION is invoked when an action is + selected. The first action of the list is the default.") + +(helm-document-attribute 'coerce "optional" + " It's a function called with one argument: the selected + candidate. + + This function is intended for type convertion. In normal case, + the selected candidate (string) is passed to action + function. If coerce function is specified, it is called just + before action function. + + Example: converting string to symbol + (coerce . intern)") + +(helm-document-attribute 'type "optional if action attribute is provided" + " Indicates the type of the items the source returns. + + Merge attributes not specified in the source itself from + `helm-type-attributes'. + + This attribute is implemented by plug-in.") + +(helm-document-attribute 'init "optional" + " Function called with no parameters when helm is started. It + is useful for collecting current state information which can be + used to create the list of candidates later. + + For example, if a source needs to work with the current + directory then it can store its value here, because later + helm does its job in the minibuffer and in the + `helm-buffer' and the current directory can be different + there.") + +(helm-document-attribute 'match "optional" + " List of functions called with one parameter: a candidate. The + function should return non-nil if the candidate matches the + current pattern (see variable `helm-pattern'). + + This attribute allows the source to override the default + pattern matching based on `string-match'. It can be used, for + example, to implement a source for file names and do the + pattern matching on the basename of files, since it's more + likely one is typing part of the basename when searching for a + file, instead of some string anywhere else in its path. + + If the list contains more than one function then the list of + matching candidates from the source is constructed by appending + the results after invoking the first function on all the + potential candidates, then the next function, and so on. The + matching candidates supplied by the first function appear first + in the list of results and then results from the other + functions, respectively. + + This attribute has no effect for asynchronous sources (see + attribute `candidates'), since they perform pattern matching + themselves.") + +(helm-document-attribute 'candidate-transformer "optional" + " It's a function or a list of functions called with one argument + when the completion list from the source is built. The argument + is the list of candidates retrieved from the source. The + function should return a transformed list of candidates which + will be used for the actual completion. If it is a list of + functions, it calls each function sequentially. + + This can be used to transform or remove items from the list of + candidates. + + Note that `candidates' is run already, so the given transformer + function should also be able to handle candidates with (DISPLAY + . REAL) format.") + +(helm-document-attribute 'filtered-candidate-transformer "optional" + " It has the same format as `candidate-transformer', except the + function is called with two parameters: the candidate list and + the source. + + This transformer is run on the candidate list which is already + filtered by the current pattern. While `candidate-transformer' + is run only once, it is run every time the input pattern is + changed. + + It can be used to transform the candidate list dynamically, for + example, based on the current pattern. + + In some cases it may also be more efficent to perform candidate + transformation here, instead of with `candidate-transformer' + even if this transformation is done every time the pattern is + changed. For example, if a candidate set is very large then + `candidate-transformer' transforms every candidate while only + some of them will actually be dislpayed due to the limit + imposed by `helm-candidate-number-limit'. + + Note that `candidates' and `candidate-transformer' is run + already, so the given transformer function should also be able + to handle candidates with (DISPLAY . REAL) format. + + This option has no effect for asynchronous sources. (Not yet, + at least.") + +(helm-document-attribute 'action-transformer "optional" + " It's a function or a list of functions called with two + arguments when the action list from the source is + assembled. The first argument is the list of actions, the + second is the current selection. If it is a list of functions, + it calls each function sequentially. + + The function should return a transformed action list. + + This can be used to customize the list of actions based on the + currently selected candidate.") + +(helm-document-attribute 'pattern-transformer "optional" + " It's a function or a list of functions called with one argument + before computing matches. Its argument is `helm-pattern'. + Functions should return transformed `helm-pattern'. + + It is useful to change interpretation of `helm-pattern'.") + +(helm-document-attribute 'delayed "optional" + " Candidates from the source are shown only if the user stops + typing and is idle for `helm-idle-delay' seconds. + If a value is given to delayed attr, this value is used instead only + if it is > to `helm-idle-delay'.") + +(helm-document-attribute 'volatile "optional" + " Indicates the source assembles the candidate list dynamically, + so it shouldn't be cached within a single Helm + invocation. It is only applicable to synchronous sources, + because asynchronous sources are not cached.") + +(helm-document-attribute 'requires-pattern "optional" + " If present matches from the source are shown only if the + pattern is not empty. Optionally, it can have an integer + parameter specifying the required length of input which is + useful in case of sources with lots of candidates.") + +(helm-document-attribute 'persistent-action "optional" + " Can be a either a Function called with one parameter (the + selected candidate) or a cons cell where first element is this + same function and second element a symbol (e.g never-split) + that inform `helm-execute-persistent-action'to not split his + window to execute this persistent action.") + +(helm-document-attribute 'candidates-in-buffer "optional" + " Shortcut attribute for making and narrowing candidates using + buffers. This newly-introduced attribute prevents us from + forgetting to add volatile and match attributes. + + See docstring of `helm-candidates-in-buffer'. + + (candidates-in-buffer) is equivalent of three attributes: + (candidates . helm-candidates-in-buffer) + (volatile) + (match identity) + + (candidates-in-buffer . candidates-function) is equivalent of: + (candidates . candidates-function) + (volatile) + (match identity) + + This attribute is implemented by plug-in.") + +(helm-document-attribute 'search "optional" + " List of functions like `re-search-forward' or `search-forward'. + Buffer search function used by `helm-candidates-in-buffer'. + By default, `helm-candidates-in-buffer' uses + `re-search-forward'. This attribute is meant to be used with + (candidates . helm-candidates-in-buffer) or + (candidates-in-buffer) in short.") + +(helm-document-attribute 'get-line "optional" + " A function like `buffer-substring-no-properties' or `buffer-substring'. + This function converts point of line-beginning and point of line-end, + which represents a candidate computed by `helm-candidates-in-buffer'. + By default, `helm-candidates-in-buffer' uses + `buffer-substring-no-properties'.") + +(helm-document-attribute 'display-to-real "optional" + " Function called with one parameter; the selected candidate. + + The function transforms the selected candidate, and the result + is passed to the action function. The display-to-real + attribute provides another way to pass other string than one + shown in Helm buffer. + + Traditionally, it is possible to make candidates, + candidate-transformer or filtered-candidate-transformer + function return a list with (DISPLAY . REAL) pairs. But if REAL + can be generated from DISPLAY, display-to-real is more + convenient and faster.") + +(helm-document-attribute 'real-to-display "optional" + " Function called with one parameter; the selected candidate. + + The inverse of display-to-real attribute. + + The function transforms the selected candidate, which is passed + to the action function, for display. The real-to-display + attribute provides the other way to pass other string than one + shown in Helm buffer. + + Traditionally, it is possible to make candidates, + candidate-transformer or filtered-candidate-transformer + function return a list with (DISPLAY . REAL) pairs. But if + DISPLAY can be generated from REAL, real-to-display is more + convenient. + + Note that DISPLAY parts returned from candidates / + candidate-transformer are IGNORED as the name `display-to-real' + says.") + +(helm-document-attribute 'cleanup "optional" + " Function called with no parameters when *helm* buffer is + closed. It is useful for killing unneeded candidates buffer. + + Note that the function is executed BEFORE performing action.") + +(helm-document-attribute 'candidate-number-limit "optional" + " Override `helm-candidate-number-limit' only for this source.") + +(helm-document-attribute 'accept-empty "optional" + " Pass empty string \"\" to action function.") + +(helm-document-attribute 'dummy "optional" + " Set `helm-pattern' to candidate. If this attribute is + specified, The candidates attribute is ignored. + + This attribute is implemented by plug-in.") + +(helm-document-attribute 'multiline "optional" + " Enable to selection multiline candidates.") + +(helm-document-attribute 'update "optional" + (substitute-command-keys + " Function called with no parameters at before \"init\" function when \ +\\\\[helm-force-update] is pressed.")) + +(helm-document-attribute 'mode-line "optional" + " Source local `helm-mode-line-string' (included in + `mode-line-format'). It accepts also variable/function name.") + +(helm-document-attribute 'header-line "optional" + " Source local `header-line-format'. + It accepts also variable/function name. ") + +(helm-document-attribute + 'resume "optional" + " 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 + `helm-buffer' is ready.") + +(helm-document-attribute 'keymap "optional" + " Specific keymap for this source. + It is useful to have a keymap per source when using more than + one source. Otherwise, a keymap can be set per command with + `helm' argument KEYMAP. NOTE: when a source have `helm-map' as + keymap attr, the global value of `helm-map' will override the + actual local one.") + +(helm-document-attribute 'help-message "optional" + " Help message for this source. + If not present, `helm-help-message' value will be used.") + +(helm-document-attribute 'match-part "optional" + " Allow matching candidate in the line with `candidates-in-buffer'. + In candidates-in-buffer sources, match is done with + `re-search-forward' which allow matching only a regexp on the + `helm-buffer'; when this search is done, match-part allow + matching only a specific part of the current line e.g with a + line like this: + + filename:candidate-containing-the-word-filename + + What you want is to ignore \"filename\" part and match only + \"candidate-containing-the-word-filename\" + + So give a function matching only the part of candidate after \":\" + + If source contain match-part attribute, match is computed only + on part of candidate returned by the call of function provided + by this attribute. The function should have one arg, candidate, + and return only a specific part of candidate. + + NOTE: This have effect only on sources using + `candidates-in-buffer'.") + +(helm-document-attribute 'match-strict "optional" + " When specifying a match function within a source and + helm-match-plugin is enabled, the result of all matching + functions will be concatened, which in some cases is not what + is wanted. When using `match-strict' only this or these + functions will be used. You can specify those functions as a + list of functions or a single symbol function. For anonymous + function don't add the dot, e.g: + + \(match-strict (lambda () (foo))).") + +(helm-document-attribute 'nohighlight "optional" + " Disable highlight match in this source.") + +(helm-document-attribute 'no-matchplugin "optional" + " Disable matchplugin for this source.") + +(helm-document-attribute 'history "optional" + " Allow passing history variable to helm from source. + It should be a quoted symbol evaluated from source, i.e: + (history . ,'history-var)") + +(helm-document-attribute 'follow "optional" + " Enable `helm-follow-mode' for this source only. + You must give it a value of 1 or -1, though giving a -1 value + is surely not what you want, e.g: (follow . 1) + + See `helm-follow-mode' for more infos") + +(helm-document-attribute 'follow-delay "optional" + " `helm-follow-mode' will execute persistent-action after this delay. +Otherwise value of `helm-follow-input-idle-delay' is used if non--nil, +If none of these are found fallback to `helm-input-idle-delay'.") + +(helm-document-attribute 'allow-dups "optional" + " Allow helm collecting duplicates candidates.") + +(helm-document-attribute 'filter-one-by-one "optional" + " A transformer function that treat candidates one by one. + It is called with one arg the candidate. + It is faster than `filtered-candidate-transformer' or `candidates-transformer', + but should be used only in sources that recompute constantly their candidates, + e.g `helm-source-find-files'. + Filtering happen early and candidates are treated + one by one instead of re-looping on the whole list. + If used with `filtered-candidate-transformer' or `candidates-transformer' + these functions should treat the candidates transformed by the `filter-one-by-one' + function in consequence.") + +(helm-document-attribute 'nomark "optional" + " Don't allow marking candidates when this attribute is present.") + +(provide 'helm-help) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-help.el ends here diff --git a/elpa/helm-20150403.101/helm-imenu.el b/elpa/helm-20150403.101/helm-imenu.el new file mode 100644 index 00000000..2bf44c42 --- /dev/null +++ b/elpa/helm-20150403.101/helm-imenu.el @@ -0,0 +1,183 @@ +;;; helm-imenu.el --- Helm interface for Imenu -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'imenu) +(require 'helm-utils) +(require 'helm-help) + + +(defgroup helm-imenu nil + "Imenu related libraries and applications for helm." + :group 'helm) + +(defcustom helm-imenu-delimiter " / " + "Delimit types of candidates and his value in `helm-buffer'." + :group 'helm-imenu + :type 'string) + +(defcustom helm-imenu-execute-action-at-once-if-one t + "Goto the candidate when only one is remaining." + :group 'helm-imenu + :type 'boolean) + +(defcustom helm-imenu-lynx-style-map t + "Use Arrow keys to jump to occurences." + :group 'helm-imenu + :type 'boolean) + + +;;; keymap +(defvar helm-imenu-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-imenu-help) + (when helm-imenu-lynx-style-map + (define-key map (kbd "") 'helm-maybe-exit-minibuffer) + (define-key map (kbd "") 'helm-execute-persistent-action)) + (delq nil map))) + + +;;; Internals +(defvar helm-cached-imenu-alist nil) +(make-variable-buffer-local 'helm-cached-imenu-alist) + +(defvar helm-cached-imenu-candidates nil) +(make-variable-buffer-local 'helm-cached-imenu-candidates) + +(defvar helm-cached-imenu-tick nil) +(make-variable-buffer-local 'helm-cached-imenu-tick) + + +(defvar helm-source-imenu nil "See (info \"(emacs)Imenu\")") + +(defclass helm-imenu-source (helm-source-sync) + ((candidates :initform 'helm-imenu-candidates) + (candidate-transformer :initform 'helm-imenu-transformer) + (persistent-action :initform 'helm-imenu-persistent-action) + (persistent-help :initform "Show this entry") + (keymap :initform helm-imenu-map) + (mode-line :initform helm-imenu-mode-line) + (action :initform 'helm-imenu-action))) + +(defcustom helm-imenu-fuzzy-match nil + "Enable fuzzy matching in `helm-source-imenu'." + :group 'helm-imenu + :type 'boolean + :set (lambda (var val) + (set var val) + (setq helm-source-imenu + (helm-make-source "Imenu" 'helm-imenu-source + :fuzzy-match helm-imenu-fuzzy-match)))) + +(defun helm-imenu-action (candidate) + "Default action for `helm-source-imenu'." + (imenu candidate) + ;; If semantic is supported in this buffer + ;; imenu used `semantic-imenu-goto-function' + ;; and position have been highlighted, + ;; no need to highlight again. + (unless (eq imenu-default-goto-function + 'semantic-imenu-goto-function) + (helm-highlight-current-line nil nil nil nil 'pulse))) + +(defun helm-imenu-persistent-action (candidate) + "Default persistent action for `helm-source-imenu'." + (imenu candidate) + (helm-highlight-current-line)) + +(defun helm-imenu-candidates () + (with-helm-current-buffer + (let ((tick (buffer-modified-tick))) + (if (eq helm-cached-imenu-tick tick) + helm-cached-imenu-candidates + (setq imenu--index-alist nil) + (prog1 (setq helm-cached-imenu-candidates + (let ((index (imenu--make-index-alist))) + (helm-imenu--candidates-1 + (delete (assoc "*Rescan*" index) index)))) + (setq helm-cached-imenu-tick tick)))))) + +(defun helm-imenu--candidates-1 (alist) + (cl-loop for elm in alist + append (if (imenu--subalist-p elm) + (helm-imenu--candidates-1 + (cl-loop for (e . v) in (cdr elm) collect + (cons (propertize + e 'helm-imenu-type (car elm)) + v))) + (and (cdr elm) ; bug in imenu, should not be needed. + (list elm))))) + +(defun helm-imenu--get-prop (item) + ;; property value of ITEM can have itself + ;; a property value which have itself a property value + ;; ...and so on; Return a list of all these + ;; properties values starting at ITEM. + (let* ((prop (get-text-property 0 'helm-imenu-type item)) + (lst (list prop item))) + (when prop + (while prop + (setq prop (get-text-property 0 'helm-imenu-type prop)) + (and prop (push prop lst))) + lst))) + +(defun helm-imenu-transformer (candidates) + (cl-loop for (k . v) in candidates + for types = (or (helm-imenu--get-prop k) + (list "Function" k)) + collect + (cons (mapconcat (lambda (x) + (propertize + x 'face (cond ((string= x "Variables") + 'font-lock-variable-name-face) + ((string= x "Function") + 'font-lock-function-name-face) + ((string= x "Types") + 'font-lock-type-face)))) + types helm-imenu-delimiter) + (cons k v)))) + +;;;###autoload +(defun helm-imenu () + "Preconfigured `helm' for `imenu'." + (interactive) + (unless helm-source-imenu + (setq helm-source-imenu + (helm-make-source "Imenu" 'helm-imenu-source + :fuzzy-match helm-imenu-fuzzy-match))) + (let ((imenu-auto-rescan t) + (str (thing-at-point 'symbol)) + (helm-execute-action-at-once-if-one + helm-imenu-execute-action-at-once-if-one)) + (helm :sources 'helm-source-imenu + :default (list (concat "\\_<" str "\\_>") str) + :candidate-number-limit 9999 + :buffer "*helm imenu*"))) + +(provide 'helm-imenu) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-imenu.el ends here diff --git a/elpa/helm-20150403.101/helm-info.el b/elpa/helm-20150403.101/helm-info.el new file mode 100644 index 00000000..e38e64d3 --- /dev/null +++ b/elpa/helm-20150403.101/helm-info.el @@ -0,0 +1,183 @@ +;;; helm-info.el --- Browse info index with helm -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-plugin) + +(declare-function Info-index-nodes "info" (&optional file)) +(declare-function Info-goto-node "info" (&optional fork)) +(declare-function Info-find-node "info.el" (filename nodename &optional no-going-back)) +(defvar Info-history) + + +(defgroup helm-info nil + "Info related Applications and libraries for Helm." + :group 'helm) + +;;; Build info-index sources with `helm-info-source' class. +;; +;; +(cl-defun helm-info-init (&optional (file (helm-attr 'info-file))) + ;; Allow reinit candidate buffer when using edebug. + (helm-aif (and debug-on-error + (helm-candidate-buffer)) + (kill-buffer it)) + (unless (helm-candidate-buffer) + (save-window-excursion + (info file) + (let ((tobuf (helm-candidate-buffer 'global)) + (infobuf (current-buffer)) + Info-history + start end) + (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) + end (point-at-eol)) + (with-current-buffer tobuf + (insert-buffer-substring infobuf start end) + (insert "\n"))))))))) + +(defun helm-info-goto (node-line) + (Info-goto-node (car node-line)) + (helm-goto-line (cdr node-line))) + +(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-attr 'info-file) (match-string 2 line)) + (string-to-number (or (match-string 3 line) "1"))))) + +(defclass helm-info-source (helm-source-in-buffer) + ((info-file :initarg :info-file + :initform nil + :custom 'string) + (init :initform #'helm-info-init) + (display-to-real :initform #'helm-info-display-to-real) + (get-line :initform #'buffer-substring) + (action :initform '(("Goto node" . helm-info-goto))))) + +(defmacro helm-build-info-source (fname &rest args) + `(helm-make-source (concat "Info Index: " ,fname) 'helm-info-source + :info-file ,fname ,@args)) + +(defun helm-build-info-index-command (name doc source buffer) + "Define an helm command NAME with documentation DOC. +Arg SOURCE will be an existing helm source named +`helm-source-info-' and BUFFER a string buffer name." + (defalias (intern (concat "helm-info-" name)) + (lambda () + (interactive) + (helm :sources source + :buffer buffer + :candidate-number-limit 1000)) + doc)) + +(defun helm-define-info-index-sources (var-value &optional commands) + "Define helm sources named helm-source-info-. +Sources are generated for all entries of `helm-default-info-index-list'. +If COMMANDS arg is non--nil build also commands named `helm-info'. +Where NAME is one of `helm-default-info-index-list'." + (cl-loop for str in var-value + for sym = (intern (concat "helm-source-info-" str)) + do (set sym (helm-build-info-source str)) + when commands + do (helm-build-info-index-command + str (format "Predefined helm for %s info." str) + sym (format "*helm info %s*" str)))) + +(defun helm-info-index-set (var value) + (set var value) + (helm-define-info-index-sources value t)) + +(defcustom helm-default-info-index-list + '("elisp" "cl" "org" "gnus" "tramp" "ratpoison" + "zsh" "bash" "coreutils" "fileutils" + "find" "sh-utils" "textutils" "libc" + "make" "automake" "autoconf" "eintr" + "emacs" "elib" "eieio" "gauche-refe" "guile" + "guile-tut" "goops" "screen" "latex" "gawk" + "sed" "m4" "wget" "binutils" "as" "bfd" "gprof" + "ld" "diff" "flex" "grep" "gzip" "libtool" + "texinfo" "info" "gdb" "stabs" "cvsbook" "cvs" + "bison" "id-utils" "global") + "Info Manual entries to use for building helm info index commands." + :group 'helm-info + :type '(repeat (choice string)) + :set 'helm-info-index-set) + +(defcustom helm-info-default-sources + '(helm-source-info-elisp + helm-source-info-cl + helm-source-info-eieio + helm-source-info-pages) + "The default sources to use in `helm-info-at-point'." + :group 'helm-info + :type '(repeat (choice symbol))) + + +;;; Info pages +(defvar helm-info--pages-cache nil + "Cache for all info pages on system.") + +(defun helm-info-pages-init () + "Collect candidates for initial Info node Top." + (if helm-info--pages-cache + helm-info--pages-cache + (let ((info-topic-regexp "\\* +\\([^:]+: ([^)]+)[^.]*\\)\\.") + topics) + (require 'info) + (with-temp-buffer + (Info-find-node "dir" "top") + (goto-char (point-min)) + (while (re-search-forward info-topic-regexp nil t) + (push (match-string-no-properties 1) topics)) + (kill-buffer)) + (setq helm-info--pages-cache topics)))) + +(defvar helm-source-info-pages + (helm-build-sync-source "Info Pages" + :init #'helm-info-pages-init + :candidates (lambda () helm-info--pages-cache) + :action '(("Show with Info" .(lambda (node-str) + (info (replace-regexp-in-string + "^[^:]+: " "" node-str))))) + :requires-pattern 2)) + +;;;###autoload +(defun helm-info-at-point () + "Preconfigured `helm' for searching info at point. +With a prefix-arg insert symbol at point." + (interactive) + (helm :sources helm-info-default-sources + :buffer "*helm info*")) + +(provide 'helm-info) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-info.el ends here diff --git a/elpa/helm-20150403.101/helm-locate.el b/elpa/helm-20150403.101/helm-locate.el new file mode 100644 index 00000000..2c50ea64 --- /dev/null +++ b/elpa/helm-20150403.101/helm-locate.el @@ -0,0 +1,345 @@ +;;; helm-locate.el --- helm interface for locate. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;; NOTE for WINDOZE users: +;; You have to install Everything with his command line interface here: +;; http://www.voidtools.com/download.php + +;;; Code: + +(require 'cl-lib) +(require 'helm) + + +(defgroup helm-locate nil + "Locate related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-locate-db-file-regexp "m?locate\.db$" + "Default regexp to match locate database. +If nil Search in all files." + :type 'string + :group 'helm-locate) + +(defcustom helm-ff-locate-db-filename "locate.db" + "The basename of the locatedb file you use locally in your directories. +When this is set and `helm' find such a file in the directory from +where you launch locate, it will use this file and will not prompt you +for a db file. +Note that this happen only when locate is launched with a prefix arg." + :group 'helm-locate + :type 'string) + +(defcustom helm-locate-command nil + "A list of arguments for locate program. +Normally you should not have to modify this yourself. + +If nil it will be calculated when `helm-locate' startup +with these default values for different systems: + +Gnu/linux: \"locate %s -e -A %s\" +berkeley-unix: \"locate %s %s\" +windows-nt: \"es %s %s\" +Others: \"locate %s %s\" + +This string will be passed to format so it should end with `%s'. +The first format spec is used for the \"-i\" value of locate/es, +So don't set it directly but use `helm-locate-case-fold-search' +for this. +The \"-r\" option must be the last option, however if not specified you will +be able to specify it during helm invocation by prefixing the pattern +you enter with \"-r\"." + :type 'string + :group 'helm-locate) + +(defcustom helm-locate-create-db-command + "updatedb -l 0 -o %s -U %s" + "Command used to create a locale locate db file." + :type 'string + :group 'helm-locate) + +(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. +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 +the opposite of \"locate\" command." + :group 'helm-locate + :type 'symbol) + +(defcustom helm-locate-fuzzy-match nil + "Enable fuzzy matching in `helm-locate'." + :group 'helm-locate + :type 'boolean) + + +(defvar helm-generic-files-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-]") 'helm-ff-run-toggle-basename) + (define-key map (kbd "C-s") 'helm-ff-run-grep) + (define-key map (kbd "M-g s") 'helm-ff-run-grep) + (define-key map (kbd "M-g z") 'helm-ff-run-zgrep) + (define-key map (kbd "M-g p") 'helm-ff-run-pdfgrep) + (define-key map (kbd "M-D") 'helm-ff-run-delete-file) + (define-key map (kbd "C-=") 'helm-ff-run-ediff-file) + (define-key map (kbd "C-c =") 'helm-ff-run-ediff-merge-file) + (define-key map (kbd "C-c o") 'helm-ff-run-switch-other-window) + (define-key map (kbd "C-c C-o") 'helm-ff-run-switch-other-frame) + (define-key map (kbd "M-i") 'helm-ff-properties-persistent) + (define-key map (kbd "C-c C-x") 'helm-ff-run-open-file-externally) + (define-key map (kbd "C-c X") 'helm-ff-run-open-file-with-default-tool) + (define-key map (kbd "M-.") 'helm-ff-run-etags) + (define-key map (kbd "C-w") 'helm-yank-text-at-point) + (define-key map (kbd "C-c @") 'helm-ff-run-insert-org-link) + (define-key map (kbd "C-c ?") 'helm-generic-file-help) + map) + "Generic Keymap for files.") + + +(defface helm-locate-finish + '((t (:foreground "Green"))) + "Face used in mode line when locate process is finish." + :group 'helm-locate) + + +(defun helm-ff-find-locatedb (&optional from-ff) + "Try to find if a local locatedb file is available. +The search is done in `helm-ff-default-directory' or +fall back to `default-directory' if FROM-FF is nil." + (when helm-ff-locate-db-filename + (cond ((and helm-ff-default-directory + from-ff + (file-exists-p (expand-file-name + helm-ff-locate-db-filename + helm-ff-default-directory)) + (expand-file-name + helm-ff-locate-db-filename + helm-ff-default-directory))) + ((and (not from-ff) + (file-exists-p (expand-file-name + helm-ff-locate-db-filename + default-directory)) + (expand-file-name + helm-ff-locate-db-filename + default-directory)))))) + +(defun helm-locate-1 (&optional localdb init from-ff default) + "Generic function to run Locate. +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 have 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) + (helm-locate-set-command) + (let ((pfn #'(lambda (candidate) + (if (file-directory-p candidate) + (message "Error: The locate Db should be a file") + (if (= (shell-command + (format helm-locate-create-db-command + candidate + helm-ff-default-directory)) + 0) + (message "New locatedb file `%s' created" candidate) + (error "Failed to create locatedb file `%s'" candidate))))) + (locdb (and localdb + (not (string-match "^es" helm-locate-command)) + (or (and (equal '(4) localdb) + (helm-ff-find-locatedb from-ff)) + (helm-read-file-name + "Create Locate Db file: " + :initial-input (expand-file-name "locate.db" + (or helm-ff-default-directory + default-directory)) + :preselect helm-locate-db-file-regexp + :test #'(lambda (x) + (if helm-locate-db-file-regexp + ;; Select only locate db files and directories + ;; to allow navigation. + (or (string-match + helm-locate-db-file-regexp x) + (file-directory-p x)) + x))))))) + (when (and locdb (or (equal localdb '(16)) + (not (file-exists-p locdb)))) + (funcall pfn locdb)) + (helm-locate-with-db (and localdb locdb) init default))) + +(defun helm-locate-set-command () + "Setup `helm-locate-command' if not already defined." + (unless helm-locate-command + (setq helm-locate-command + (cl-case system-type + (gnu/linux "locate %s -e -r %s") + (berkeley-unix "locate %s %s") + (windows-nt "es %s %s") + (t "locate %s %s"))))) + +(defvar helm-file-name-history nil) +(defun helm-locate-with-db (&optional db initial-input default) + "Run locate -d DB. +If DB is not given or nil use locate without -d option. +Argument DB can be given as a string or list of db files. +Argument INITIAL-INPUT is a string to use as initial-input. +See also `helm-locate'." + (when (and db (stringp db)) (setq db (list db))) + (helm-locate-set-command) + (let ((helm-ff-transformer-show-only-basename nil) + (helm-locate-command + (if db + (replace-regexp-in-string + "locate" + (format "locate -d %s" + (mapconcat 'identity + ;; Remove eventually + ;; marked directories by error. + (cl-loop for i in db + unless (file-directory-p i) + collect i) ":")) + helm-locate-command) + helm-locate-command))) + (setq helm-file-name-history (mapcar 'helm-basename file-name-history)) + (helm :sources 'helm-source-locate + :buffer "*helm locate*" + :input initial-input + :default default + :history 'helm-file-name-history))) + +(defun helm-locate-init () + "Initialize async locate process for `helm-source-locate'." + (let* ((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 + (not real-locate)) "" "-i")) + (args (split-string helm-pattern " ")) + (cmd (format helm-locate-command + (cl-case helm-locate-case-fold-search + (smart (let ((case-fold-search nil)) + (if (string-match "[[:upper:]]" helm-pattern) + case-sensitive-flag + ignore-case-flag))) + (t (if helm-locate-case-fold-search + ignore-case-flag + case-sensitive-flag))) + (concat + ;; The pattern itself. + (shell-quote-argument (car args)) " " + ;; Possible locate args added + ;; after pattern, don't quote them. + (mapconcat 'identity (cdr args) " "))))) + (helm-log "Starting helm-locate process") + (helm-log "Command line used was:\n\n%s" + (concat ">>> " (propertize cmd 'face 'font-lock-comment-face) "\n\n")) + (prog1 + (start-process-shell-command + "locate-process" helm-buffer + cmd) + (set-process-sentinel + (get-buffer-process helm-buffer) + #'(lambda (_process event) + (if (string= event "finished\n") + (with-helm-window + (setq mode-line-format + '(" " mode-line-buffer-identification " " + (:eval (format "L%s" (helm-candidate-number-at-point))) " " + (:eval (propertize + (format "[Locate process finished - (%s results)]" + (max (1- (count-lines + (point-min) (point-max))) + 0)) + 'face 'helm-locate-finish)))) + (force-mode-line-update)) + (helm-log "Error: Locate %s" + (replace-regexp-in-string "\n" "" event)))))))) + +(defclass helm-locate-source (helm-source-async helm-type-file) + ((init :initform 'helm-locate-set-command) + (candidates-process :initform 'helm-locate-init) + (requires-pattern :initform 3) + (history :initform 'helm-file-name-history) + (keymap :initform helm-generic-files-map) + (help-message :initform helm-generic-file-help-message) + (candidate-number-limit :initform 9999) + (mode-line :initform helm-generic-file-mode-line-string))) + +(defvar helm-source-locate + (helm-make-source "Locate" 'helm-locate-source + :pattern-transformer 'helm-locate-pattern-transformer)) + +(defun helm-locate-pattern-transformer (pattern) + (if helm-locate-fuzzy-match + (cond ((string-match + " " (replace-regexp-in-string " -b" "" pattern)) pattern) + ((string-match "\\([^ ]*\\) -b" pattern) + (concat (helm--mapconcat-pattern + (match-string 1 pattern)) " -b")) + (t (helm--mapconcat-pattern pattern))) + pattern)) + +;;;###autoload +(defun helm-locate-read-file-name (prompt) + (let* (helm-ff-transformer-show-only-basename + (src `((name . "Locate read fname") + (init . helm-locate-set-command) + (candidates-process . helm-locate-init) + (action . identity) + (requires-pattern . 3) + (history . ,'helm-file-name-history) + (candidate-transformer . (helm-skip-boring-files + helm-highlight-files)) + (candidate-number-limit . 9999) + (no-matchplugin)))) + (or (helm :sources src + :prompt prompt + :buffer "*helm locate read fname*" + :resume 'noresume) + (keyboard-quit)))) + +;;;###autoload +(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'. + +You can specify a local database with prefix argument ARG. +With two prefix arg, refresh the current local db or create it +if it doesn't exists. +Many databases can be used: navigate and mark them. +See also `helm-locate-with-db'. + +To create a user specific db, use +\"updatedb -l 0 -o db_path -U directory\". +Where db_path is a filename matched by +`helm-locate-db-file-regexp'." + (interactive "P") + (setq helm-ff-default-directory default-directory) + (helm-locate-1 arg)) + +(provide 'helm-locate) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-locate.el ends here diff --git a/elpa/helm-20150403.101/helm-man.el b/elpa/helm-20150403.101/helm-man.el new file mode 100644 index 00000000..cdf7c2aa --- /dev/null +++ b/elpa/helm-20150403.101/helm-man.el @@ -0,0 +1,102 @@ +;;; helm-man.el --- Man and woman UI -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) + +(declare-function woman-file-name-all-completions "woman.el" (topic)) +(declare-function Man-getpage-in-background "man.el" (topic)) +(declare-function helm-generic-sort-fn "helm-utils.el" (S1 S2)) + +(defgroup helm-man nil + "Man and Woman applications for helm." + :group 'helm) + +(defcustom helm-man-or-woman-function 'Man-getpage-in-background + "Default command to display a man page." + :group 'helm-man + :type '(radio :tag "Preferred command to display a man page" + (const :tag "Man" Man-getpage-in-background) + (const :tag "Woman" woman))) + +;; Internal +(defvar helm-man-pages nil + "All man pages on system. +Will be calculated the first time you invoke helm with this +source.") + +(defun helm-man-default-action (candidate) + "Default action for jumping to a woman or man page from helm." + (let ((wfiles (mapcar + 'car (woman-file-name-all-completions candidate)))) + (condition-case nil + (if (> (length wfiles) 1) + (let ((file (helm-comp-read + "ManFile: " wfiles :must-match t))) + (if (eq helm-man-or-woman-function 'Man-getpage-in-background) + (manual-entry (format "-l %s" file)) + (woman-find-file file))) + (funcall helm-man-or-woman-function candidate)) + ;; If woman is unable to format correctly + ;; use man instead. + (error (kill-buffer) ; Kill woman buffer. + (Man-getpage-in-background candidate))))) + +(defvar helm-source-man-pages + '((name . "Manual Pages") + (init . (lambda () + (require 'woman) + (require 'helm-utils) + (unless helm-man-pages + (setq helm-man-pages + (ignore-errors + (woman-file-name "" t) + (sort (mapcar 'car woman-topic-all-completions) + 'string-lessp)))) + (helm-init-candidates-in-buffer 'global helm-man-pages))) + (candidates-in-buffer) + (persistent-action . ignore) + (filtered-candidate-transformer + . (lambda (candidates _source) + (sort candidates #'helm-generic-sort-fn))) + (action . (("Display Man page" . helm-man-default-action))) + ;; Woman does not work OS X + ;; http://xahlee.org/emacs/modernization_man_page.html + (action-transformer . (lambda (actions candidate) + (if (eq system-type 'darwin) + '(("Display Man page" . man)) + actions))))) + +;;;###autoload +(defun helm-man-woman (arg) + "Preconfigured `helm' for Man and Woman pages. +With a prefix arg reinitialize the cache." + (interactive "P") + (when arg (setq helm-man-pages nil)) + (helm-other-buffer 'helm-source-man-pages "*Helm man woman*")) + +(provide 'helm-man) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-man.el ends here diff --git a/elpa/helm-20150403.101/helm-match-plugin.el b/elpa/helm-20150403.101/helm-match-plugin.el new file mode 100644 index 00000000..c9226036 --- /dev/null +++ b/elpa/helm-20150403.101/helm-match-plugin.el @@ -0,0 +1,368 @@ +;;; helm-match-plugin.el --- Multiple regexp matching methods for helm -*- lexical-binding: t -*- + +;; Original Author: rubikitch + +;; Copyright (C) 2008 ~ 2011 rubikitch +;; Copyright (C) 2011 ~ 2015 Thierry Volpiatto + +;; Author: Thierry Volpiatto +;; URL: http://github.com/emacs-helm/helm + +;; 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 . + +;;; Code: + +(require 'helm) +(require 'cl-lib) + + +(defgroup helm-match-plugin nil + "Helm match plugin." + :group 'helm) + +(defcustom helm-mp-matching-method 'multi3 + "Matching method for helm match plugin. +You can set here different methods to match candidates in helm. +Here are the possible value of this symbol and their meaning: +- multi1: Respect order, prefix of pattern must match. +- multi2: Same but with partial match. +- multi3: The best, multiple regexp match, allow negation. +- multi3p: Same but prefix must match. +Default is multi3." + :type '(radio :tag "Matching methods for helm" + (const :tag "Multiple regexp 1 ordered with prefix match" multi1) + (const :tag "Multiple regexp 2 ordered with partial match" multi2) + (const :tag "Multiple regexp 3 matching no order, partial, best." multi3) + (const :tag "Multiple regexp 3p matching with prefix match" multi3p)) + :group 'helm-match-plugin) + + +;; Internal +(defconst helm-mp-default-match-functions + '(helm-mp-exact-match helm-mp-match)) +(defconst helm-mp-default-search-functions + '(helm-mp-exact-search helm-mp-search)) +(defconst helm-mp-default-search-backward-functions + '(helm-mp-exact-search-backward + helm-mp-search-backward)) + + +;;; Build regexps +;; +;; +(defvar helm-mp-space-regexp "[\\ ] " + "Regexp to represent space itself in multiple regexp match.") + +(defun helm-mp-split-pattern (pattern) + "Split PATTERN if it contain spaces and return resulting list. +If spaces in PATTERN are escaped, don't split at this place. +i.e \"foo bar\"=> (\"foo\" \"bar\") +but \"foo\ bar\"=> (\"foobar\")." + (if (string= pattern "") + '("") + (cl-loop for s in (split-string + (replace-regexp-in-string helm-mp-space-regexp + "\000\000" pattern) + " " t) + collect (replace-regexp-in-string "\000\000" " " s)))) + +(defun helm-mp-1-make-regexp (pattern) + "Replace spaces in PATTERN with \"\.*\"." + (mapconcat 'identity (helm-mp-split-pattern pattern) ".*")) + + +;;; Exact match. +;; +;; +;; Internal. +(defvar helm-mp-exact-pattern-str nil) +(defvar helm-mp-exact-pattern-real nil) + +(defun helm-mp-exact-get-pattern (pattern) + (unless (equal pattern helm-mp-exact-pattern-str) + (setq helm-mp-exact-pattern-str pattern + helm-mp-exact-pattern-real (concat "\n" pattern "\n"))) + helm-mp-exact-pattern-real) + + +(defun helm-mp-exact-match (str &optional pattern) + (string= str (or pattern helm-pattern))) + +(defun helm-mp-exact-search (pattern &rest _ignore) + (and (search-forward (helm-mp-exact-get-pattern pattern) nil t) + (forward-line -1))) + +(defun helm-mp-exact-search-backward (pattern &rest _ignore) + (and (search-backward (helm-mp-exact-get-pattern pattern) nil t) + (forward-line 1))) + + +;;; Prefix match +;; +;; +;; Internal +(defvar helm-mp-prefix-pattern-str nil) +(defvar helm-mp-prefix-pattern-real nil) + +(defun helm-mp-prefix-get-pattern (pattern) + (unless (equal pattern helm-mp-prefix-pattern-str) + (setq helm-mp-prefix-pattern-str pattern + helm-mp-prefix-pattern-real (concat "\n" pattern))) + helm-mp-prefix-pattern-real) + +(defun helm-mp-prefix-match (str &optional pattern) + (setq pattern (or pattern helm-pattern)) + (let ((len (length pattern))) + (and (<= len (length str)) + (string= (substring str 0 len) pattern )))) + +(defun helm-mp-prefix-search (pattern &rest _ignore) + (search-forward (helm-mp-prefix-get-pattern pattern) nil t)) + +(defun helm-mp-prefix-search-backward (pattern &rest _ignore) + (and (search-backward (helm-mp-prefix-get-pattern pattern) nil t) + (forward-line 1))) + + +;;; Multiple regexp patterns 1 (order is preserved / prefix). +;; +;; +;; Internal +(defvar helm-mp-1-pattern-str nil) +(defvar helm-mp-1-pattern-real nil) + +(defun helm-mp-1-get-pattern (pattern) + (unless (equal pattern helm-mp-1-pattern-str) + (setq helm-mp-1-pattern-str pattern + helm-mp-1-pattern-real + (concat "^" (helm-mp-1-make-regexp pattern)))) + helm-mp-1-pattern-real) + +(cl-defun helm-mp-1-match (str &optional (pattern helm-pattern)) + (string-match (helm-mp-1-get-pattern pattern) str)) + +(defun helm-mp-1-search (pattern &rest _ignore) + (re-search-forward (helm-mp-1-get-pattern pattern) nil t)) + +(defun helm-mp-1-search-backward (pattern &rest _ignore) + (re-search-backward (helm-mp-1-get-pattern pattern) nil t)) + + +;;; Multiple regexp patterns 2 (order is preserved / partial). +;; +;; +;; Internal +(defvar helm-mp-2-pattern-str nil) +(defvar helm-mp-2-pattern-real nil) + +(defun helm-mp-2-get-pattern (pattern) + (unless (equal pattern helm-mp-2-pattern-str) + (setq helm-mp-2-pattern-str pattern + helm-mp-2-pattern-real + (concat "^.*" (helm-mp-1-make-regexp pattern)))) + helm-mp-2-pattern-real) + +(cl-defun helm-mp-2-match (str &optional (pattern helm-pattern)) + (string-match (helm-mp-2-get-pattern pattern) str)) + +(defun helm-mp-2-search (pattern &rest _ignore) + (re-search-forward (helm-mp-2-get-pattern pattern) nil t)) + +(defun helm-mp-2-search-backward (pattern &rest _ignore) + (re-search-backward (helm-mp-2-get-pattern pattern) nil t)) + + +;;; Multiple regexp patterns 3 (permutation). +;; +;; +;; Internal +(defvar helm-mp-3-pattern-str nil) +(defvar helm-mp-3-pattern-list nil) + +(defun helm-mp-3-get-patterns (pattern) + "Return `helm-mp-3-pattern-list', a list of predicate/regexp cons cells. +e.g ((identity . \"foo\") (identity . \"bar\")). +This is done only if `helm-mp-3-pattern-str' is same as PATTERN." + (unless (equal pattern helm-mp-3-pattern-str) + (setq helm-mp-3-pattern-str pattern + helm-mp-3-pattern-list + (helm-mp-3-get-patterns-internal pattern))) + helm-mp-3-pattern-list) + +(defun helm-mp-3-get-patterns-internal (pattern) + "Return a list of predicate/regexp cons cells. +e.g ((identity . \"foo\") (identity . \"bar\"))." + (unless (string= pattern "") + (cl-loop for pat in (helm-mp-split-pattern pattern) + collect (if (string= "!" (substring pat 0 1)) + (cons 'not (substring pat 1)) + (cons 'identity pat))))) + +(cl-defun helm-mp-3-match (str &optional (pattern helm-pattern)) + "Check if PATTERN match STR. +When PATTERN contain a space, it is splitted and matching is done +with the several resulting regexps against STR. +e.g \"bar foo\" will match \"foobar\" and \"barfoo\". +Argument PATTERN, a string, is transformed in a list of +cons cell with `helm-mp-3-get-patterns' if it contain a space. +e.g \"foo bar\"=>((identity . \"foo\") (identity . \"bar\")). +Then each predicate of cons cell(s) is called with regexp of same +cons cell against STR (a candidate). +i.e (identity (string-match \"foo\" \"foo bar\")) => t." + (let ((pat (helm-mp-3-get-patterns pattern))) + (cl-loop for (predicate . regexp) in pat + always (funcall predicate + (condition-case _err + ;; FIXME: Probably do nothing when + ;; using fuzzy leaving the job + ;; to the fuzzy fn. + (string-match regexp str) + (invalid-regexp nil)))))) + +(defun helm-mp-3-search-base (pattern searchfn1 searchfn2) + "Try to find PATTERN in `helm-buffer' with SEARCHFN1 and SEARCHFN2. +This is the search function for `candidates-in-buffer' enabled sources. +Use the same method as `helm-mp-3-match' except it search in buffer +instead of matching on a string. +i.e (identity (re-search-forward \"foo\" (point-at-eol) t)) => t." + (cl-loop with pat = (if (stringp pattern) + (helm-mp-3-get-patterns pattern) + pattern) + 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) + (invalid-regexp nil)) + for bol = (point-at-bol) + for eol = (point-at-eol) + if (cl-loop for (pred . str) in (cdr pat) always + (progn (goto-char bol) + (funcall pred (condition-case _err + (funcall searchfn2 str eol t) + (invalid-regexp nil))))) + do (goto-char eol) and return t + else do (goto-char eol) + finally return nil)) + +(defun helm-mp-3-search (pattern &rest _ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 're-search-forward 're-search-forward)) + +(defun helm-mp-3-search-backward (pattern &rest _ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 're-search-backward 're-search-backward)) + + +;;; mp-3p- (multiple regexp pattern 3 with prefix search) +;; +;; +(defun helm-mp-3p-match (str &optional pattern) + "Check if PATTERN match STR. +Same as `helm-mp-3-match' but more strict, matching against prefix also. +e.g \"bar foo\" will match \"barfoo\" but not \"foobar\" contrarily to +`helm-mp-3-match'." + (let* ((pat (helm-mp-3-get-patterns (or pattern helm-pattern))) + (first (car pat))) + (and (funcall (car first) (helm-mp-prefix-match str (cdr first))) + (cl-loop for (predicate . regexp) in (cdr pat) + always (funcall predicate (string-match regexp str)))))) + +(defun helm-mp-3p-search (pattern &rest _ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 'helm-mp-prefix-search 're-search-forward)) + +(defun helm-mp-3p-search-backward (pattern &rest _ignore) + (when (stringp pattern) + (setq pattern (helm-mp-3-get-patterns pattern))) + (helm-mp-3-search-base + pattern 'helm-mp-prefix-search-backward 're-search-backward)) + + +;;; Generic multi-match/search functions +;; +;; +(cl-defun helm-mp-match (str &optional (pattern helm-pattern)) + (let ((fun (cl-ecase helm-mp-matching-method + (multi1 #'helm-mp-1-match) + (multi2 #'helm-mp-2-match) + (multi3 #'helm-mp-3-match) + (multi3p #'helm-mp-3p-match)))) + (funcall fun str pattern))) + +(defun helm-mp-search (pattern &rest _ignore) + (let ((fun (cl-ecase helm-mp-matching-method + (multi1 #'helm-mp-1-search) + (multi2 #'helm-mp-2-search) + (multi3 #'helm-mp-3-search) + (multi3p #'helm-mp-3p-search)))) + (funcall fun pattern))) + +(defun helm-mp-search-backward (pattern &rest _ignore) + (let ((fun (cl-ecase helm-mp-matching-method + (multi1 #'helm-mp-1-search-backward) + (multi2 #'helm-mp-2-search-backward) + (multi3 #'helm-mp-3-search-backward) + (multi3p #'helm-mp-3p-search-backward)))) + (funcall fun pattern))) + + +;;; source compiler +;; This is used only in old sources defined without helm-source. +;; +(defun helm-compile-source--match-plugin (source) + (if (assoc 'no-matchplugin source) + source + (let* ((searchers helm-mp-default-search-functions) + (defmatch (helm-aif (assoc-default 'match source) + (helm-mklist it))) + (defmatch-strict (helm-aif (assoc-default 'match-strict source) + (helm-mklist it))) + (defsearch (helm-aif (assoc-default 'search source) + (helm-mklist it))) + (defsearch-strict (helm-aif (assoc-default 'search-strict source) + (helm-mklist it))) + (matchfns (cond (defmatch-strict) + (defmatch + (append helm-mp-default-match-functions defmatch)) + (t helm-mp-default-match-functions))) + (searchfns (cond (defsearch-strict) + (defsearch + (append searchers defsearch)) + (t searchers)))) + `(,(if (assoc 'candidates-in-buffer source) + `(search ,@searchfns) `(match ,@matchfns)) + ,@source)))) + + +;; Enable match-plugin by default in old sources. +(add-to-list 'helm-compile-source-functions 'helm-compile-source--match-plugin) + +(provide 'helm-match-plugin) + + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-match-plugin.el ends here diff --git a/elpa/helm-20150403.101/helm-misc.el b/elpa/helm-20150403.101/helm-misc.el new file mode 100644 index 00000000..5659c7ed --- /dev/null +++ b/elpa/helm-20150403.101/helm-misc.el @@ -0,0 +1,331 @@ +;;; helm-misc.el --- Various functions for helm -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) + + +(defgroup helm-misc nil + "Various Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-time-zone-home-location "Paris" + "The time zone of your home" + :group 'helm-misc + :type 'string) + +(defcustom helm-mini-default-sources '(helm-source-buffers-list + helm-source-recentf + helm-source-buffer-not-found) + "Default sources list used in `helm-mini'." + :group 'helm-misc + :type '(repeat (choice symbol))) + +(defface helm-time-zone-current + '((t (:foreground "green"))) + "Face used to colorize current time in `helm-world-time'." + :group 'helm-misc) + +(defface helm-time-zone-home + '((t (:foreground "red"))) + "Face used to colorize home time in `helm-world-time'." + :group 'helm-misc) + + +;;; Latex completion +(defvar LaTeX-math-menu) +(defun helm-latex-math-candidates () + "Collect candidates for latex math completion." + (cl-loop for i in (cddr LaTeX-math-menu) + for elm = (cl-loop for s in i when (vectorp s) + collect (cons (aref s 0) (aref s 1))) + append elm)) + +(defvar helm-source-latex-math + '((name . "Latex Math Menu") + (init . (lambda () + (with-helm-current-buffer + (LaTeX-math-mode 1)))) + (candidate-number-limit . 9999) + (candidates . helm-latex-math-candidates) + (action . (lambda (candidate) + (call-interactively candidate))))) + + +;;; Jabber Contacts (jabber.el) +(defun helm-jabber-online-contacts () + "List online Jabber contacts." + (with-no-warnings + (cl-loop for item in (jabber-concat-rosters) + when (get item 'connected) + collect + (if (get item 'name) + (cons (get item 'name) item) + (cons (symbol-name item) item))))) + +(defvar helm-source-jabber-contacts + '((name . "Jabber Contacts") + (init . (lambda () (require 'jabber))) + (candidates . (lambda () (mapcar 'car (helm-jabber-online-contacts)))) + (action . (lambda (x) + (jabber-chat-with + (jabber-read-account) + (symbol-name + (cdr (assoc x (helm-jabber-online-contacts))))))))) + +;;; World time +;; +(defun helm-time-zone-transformer (candidates _source) + (cl-loop for i in candidates + collect + (cond ((string-match (format-time-string "%H:%M" (current-time)) i) + (propertize i 'face 'helm-time-zone-current)) + ((string-match helm-time-zone-home-location i) + (propertize i 'face 'helm-time-zone-home)) + (t i)))) + +(defvar helm-source-time-world + '((name . "Time World List") + (init . (lambda () + (require 'time) + (let ((helm-buffer (helm-candidate-buffer 'global))) + (with-current-buffer helm-buffer + (display-time-world-display display-time-world-list))))) + (candidates-in-buffer) + (filtered-candidate-transformer . helm-time-zone-transformer))) + +;;; LaCarte +;; +;; +(declare-function lacarte-get-overall-menu-item-alist "ext:lacarte.el" (&optional MAPS)) + +(defun helm-lacarte-candidate-transformer (cands) + (mapcar (lambda (cand) + (let* ((item (car cand)) + (match (string-match "[^>] \\((.*)\\)$" item))) + (when match + (put-text-property (match-beginning 1) (match-end 1) + 'face 'helm-M-x-key item)) + cand)) + cands)) + +(defclass helm-lacarte (helm-source-sync helm-type-command) + ((init :initform (lambda () (require 'lacarte))) + (candidates :initform 'helm-lacarte-get-candidates) + (candidate-transformer :initform 'helm-lacarte-candidate-transformer) + (candidate-number-limit :initform 9999))) + +(defun helm-lacarte-get-candidates (&optional maps) + "Extract candidates for menubar using lacarte.el. +See http://www.emacswiki.org/cgi-bin/wiki/download/lacarte.el. +Optional argument MAPS is a list specifying which keymaps to use: it +can contain the symbols `local', `global', and `minor', mean the +current local map, current global map, and all current minor maps." + (with-helm-current-buffer + ;; FIXME: do we still need to remove possible '(nil) candidates. + (lacarte-get-overall-menu-item-alist maps))) + +;;;###autoload +(defun helm-browse-menubar () + "Helm interface to the menubar using lacarte.el." + (interactive) + (require 'lacarte) + (helm :sources (mapcar + (lambda (spec) (helm-make-source (car spec) 'helm-lacarte + :candidates (lambda () (helm-lacarte-get-candidates (cdr spec))))) + '(("Major Mode" . (local)) + ("Minor Modes" . (minor)) + ("Global Map" . (global)))) + :buffer "*helm lacarte*")) + +(defun helm-call-interactively (cmd-or-name) + "Execute CMD-OR-NAME as Emacs command. +It is added to `extended-command-history'. +`helm-current-prefix-arg' is used as the command's prefix argument." + (setq extended-command-history + (cons (helm-stringify cmd-or-name) + (delete (helm-stringify cmd-or-name) extended-command-history))) + (let ((current-prefix-arg helm-current-prefix-arg) + (cmd (helm-symbolify cmd-or-name))) + (if (stringp (symbol-function cmd)) + (execute-kbd-macro (symbol-function cmd)) + (setq this-command cmd) + (call-interactively cmd)))) + +;;; Minibuffer History +;; +;; +(defvar helm-source-minibuffer-history + '((name . "Minibuffer History") + (header-name . (lambda (name) + (format "%s (%s)" name minibuffer-history-variable))) + (candidates + . (lambda () + (let ((history (cl-loop for i in + (symbol-value minibuffer-history-variable) + unless (string= "" i) collect i))) + (if (consp (car history)) + (mapcar 'prin1-to-string history) + history)))) + (migemo) + (multiline) + (action . (lambda (candidate) + (delete-minibuffer-contents) + (insert candidate))))) + +;;; Shell history +;; +;; +(defun helm-comint-input-ring-action (candidate) + "Default action for comint history." + (with-helm-current-buffer + (delete-region (comint-line-beginning-position) (point-max)) + (insert candidate))) + +(defvar helm-source-comint-input-ring + '((name . "Comint history") + (candidates . (lambda () + (with-helm-current-buffer + (ring-elements comint-input-ring)))) + (action . helm-comint-input-ring-action)) + "Source that provide helm completion against `comint-input-ring'.") + + +;;; Helm ratpoison UI +;; +;; +(defvar helm-source-ratpoison-commands + '((name . "Ratpoison Commands") + (init . helm-ratpoison-commands-init) + (candidates-in-buffer) + (action ("Execute the command" . helm-ratpoison-commands-execute)) + (display-to-real . helm-ratpoison-commands-display-to-real) + (candidate-number-limit))) + +(defun helm-ratpoison-commands-init () + (unless (helm-candidate-buffer) + (with-current-buffer (helm-candidate-buffer 'global) + ;; with ratpoison prefix key + (save-excursion + (call-process "ratpoison" nil (current-buffer) nil "-c" "help")) + (while (re-search-forward "^\\([^ ]+\\) \\(.+\\)$" nil t) + (replace-match " \\1: \\2")) + (goto-char (point-max)) + ;; direct binding + (save-excursion + (call-process "ratpoison" nil (current-buffer) nil "-c" "help top")) + (while (re-search-forward "^\\([^ ]+\\) \\(.+\\)$" nil t) + (replace-match "\\1: \\2"))))) + +(defun helm-ratpoison-commands-display-to-real (display) + (and (string-match ": " display) + (substring display (match-end 0)))) + +(defun helm-ratpoison-commands-execute (candidate) + (call-process "ratpoison" nil nil nil "-ic" candidate)) + +;;; Helm stumpwm UI +;; +;; +(defvar helm-source-stumpwm-commands + '((name . "Stumpwm Commands") + (init . helm-stumpwm-commands-init) + (candidates-in-buffer) + (action ("Execute the command" . helm-stumpwm-commands-execute)) + (candidate-number-limit))) + +(defun helm-stumpwm-commands-init () + (with-current-buffer (helm-candidate-buffer 'global) + (save-excursion + (call-process "stumpish" nil (current-buffer) nil "commands")) + (while (re-search-forward "[ ]*\\([^ ]+\\)[ ]*\n?" nil t) + (replace-match "\n\\1\n")) + (delete-blank-lines) + (sort-lines nil (point-min) (point-max)) + (goto-char (point-max)))) + +(defun helm-stumpwm-commands-execute (candidate) + (call-process "stumpish" nil nil nil candidate)) + +;;;###autoload +(defun helm-world-time () + "Preconfigured `helm' to show world time." + (interactive) + (helm-other-buffer 'helm-source-time-world "*helm world time*")) + +;;;###autoload +(defun helm-insert-latex-math () + "Preconfigured helm for latex math symbols completion." + (interactive) + (helm-other-buffer 'helm-source-latex-math "*helm latex*")) + +;;;###autoload +(defun helm-ratpoison-commands () + "Preconfigured `helm' to execute ratpoison commands." + (interactive) + (helm-other-buffer 'helm-source-ratpoison-commands + "*helm ratpoison commands*")) + +;;;###autoload +(defun helm-stumpwm-commands() + (interactive) + (helm-other-buffer 'helm-source-stumpwm-commands + "*helm stumpwm commands*")) + + +;;;###autoload +(defun helm-mini () + "Preconfigured `helm' lightweight version \(buffer -> recentf\)." + (interactive) + (require 'helm-files) + (unless helm-source-buffers-list + (setq helm-source-buffers-list + (helm-make-source "Buffers" 'helm-source-buffers))) + (let ((helm-ff-transformer-show-only-basename nil)) + (helm :sources helm-mini-default-sources + :buffer "*helm mini*" + :truncate-lines t))) + +;;;###autoload +(defun helm-minibuffer-history () + "Preconfigured `helm' for `minibuffer-history'." + (interactive) + (let ((enable-recursive-minibuffers t)) + (helm-other-buffer 'helm-source-minibuffer-history + "*helm minibuffer-history*"))) + +;;;###autoload +(defun helm-comint-input-ring () + "Predefined `helm' that provide completion of `comint' history." + (interactive) + (when (derived-mode-p 'comint-mode) + (helm :sources 'helm-source-comint-input-ring + :input (buffer-substring-no-properties (comint-line-beginning-position) + (point-at-eol)) + :buffer "*helm comint history*"))) + + +(provide 'helm-misc) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-misc.el ends here diff --git a/elpa/helm-20150403.101/helm-mode.el b/elpa/helm-20150403.101/helm-mode.el new file mode 100644 index 00000000..992a360e --- /dev/null +++ b/elpa/helm-20150403.101/helm-mode.el @@ -0,0 +1,1096 @@ +;;; helm-mode.el --- Enable helm completion everywhere. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-files) + + +(defgroup helm-mode nil + "Enable helm completion." + :group 'helm) + +(defcustom helm-completing-read-handlers-alist + '((describe-function . helm-completing-read-symbols) + (describe-variable . helm-completing-read-symbols) + (debug-on-entry . helm-completing-read-symbols) + (find-function . helm-completing-read-symbols) + (trace-function . helm-completing-read-symbols) + (trace-function-foreground . helm-completing-read-symbols) + (trace-function-background . helm-completing-read-symbols) + (find-tag . helm-completing-read-with-cands-in-buffer) + (ffap-alternate-file . nil) + (tmm-menubar . nil)) + "Alist of handlers to replace `completing-read', `read-file-name' in `helm-mode'. +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'. + +Each value maybe an helm function that take same arguments as +`completing-read' plus NAME and BUFFER, where NAME is the name of the new +helm source and BUFFER the name of the buffer we will use. +This function prefix name must start by \"helm\". + +See `helm-completing-read-symbols' for example. + +Note that this function will be reused for ALL the `completing-read' +of this command, so it should handle all cases, e.g +If first `completing-read' complete against symbols and +second `completing-read' should handle only buffer, +your specialized function should handle the both. + +If the value of an entry is nil completion will fall back to +emacs vanilla behavior. +e.g If you want to disable helm completion for `describe-function': +\(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. +e.g ido completion for `find-file': +\(find-file . ido\) +same as +\(find-file . ido-read-file-name\) +Note that you don't need to enable `ido-mode' for this to work." + :group 'helm-mode + :type '(alist :key-type symbol :value-type symbol)) + +(defcustom helm-comp-read-case-fold-search helm-case-fold-search + "Default Local setting of `helm-case-fold-search' for `helm-comp-read'. +See `helm-case-fold-search' for more info." + :group 'helm-mode + :type 'symbol) + +(defcustom helm-mode-handle-completion-in-region t + "Whether to replace or not `completion-in-region-function'. +This enable support for `completing-read-multiple' and `completion-at-point' +when non--nil." + :group 'helm-mode + :type 'boolean) + +(defcustom helm-mode-reverse-history t + "Display history source after current source in `helm-mode' handled commands." + :group 'helm-mode + :type 'boolean) + +(defcustom helm-mode-no-completion-in-region-in-modes nil + "A list of modes that do not want helm for `completion-in-region'." + :group 'helm-mode + :type 'boolean) + +(defcustom helm-completion-in-region-fuzzy-match nil + "Whether `helm-completion-in-region' use fuzzy matching or not. +Affect among others `completion-at-point', `completing-read-multiple'." + :group 'helm-mode + :type 'boolean) + + +(defvar helm-comp-read-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "") 'helm-cr-empty-string) + (define-key map (kbd "") 'helm-cr-empty-string) + map) + "Keymap for `helm-comp-read'.") + + +;;; Internal +;; +;; +;; Flag to know if `helm-pattern' have been added +;; to candidate list in `helm-comp-read'. +(defvar helm-cr-unknown-pattern-flag nil) + + +;;; Helm `completing-read' replacement +;; +;; +(defun helm-cr-empty-string () + "Return empty string." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action + #'(lambda (_candidate) + (identity ""))))) + +(defun helm-mode--keyboard-quit () + ;; Use this instead of `keyboard-quit' + ;; to avoid deactivating mark in current-buffer. + (let ((debug-on-quit nil)) + (signal 'quit nil))) + +(defun helm-comp-read-get-candidates (collection &optional test sort-fn alistp) + "Convert COLLECTION to list removing elements that don't match TEST. +See `helm-comp-read' about supported COLLECTION arguments. + +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\), +so we return the alist as it is with no transformation by all-completions. + +e.g + +\(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 + :initial-input \"a\") +==>\"a\" Which is not what we expect. + +\(helm-comp-read \"test: \" A :alistp t + :exec-when-only-one t + :initial-input \"1\") +==>\"1\" + +See docstring of `all-completions' for more info. + +If COLLECTION is an `obarray', a TEST should be needed. See `obarray'." + + (let ((cands + (cond ((vectorp collection) + (all-completions "" collection test)) + ((and (symbolp collection) (boundp collection) + ;; Issue #324 history is let-bounded and given + ;; quoted as hist argument of completing-read. + ;; See example in `rcirc-browse-url'. + (symbolp (symbol-value collection))) + nil) + ;; When collection is a symbol, most of the time + ;; it should be a symbol used as a minibuffer-history. + ;; The value of this symbol in this case return a list + ;; of string which maybe are converted later as symbol + ;; in special cases. + ;; we treat here commandp as a special case as it return t + ;; also with a string unless its last arg is provided. + ;; Also, the history collections generally collect their + ;; elements as string, so intern them to call predicate. + ((and (symbolp collection) (boundp collection) test) + (let ((predicate `(lambda (elm) + (condition-case err + (if (eq (quote ,test) 'commandp) + (funcall (quote ,test) (intern elm)) + (funcall (quote ,test) elm)) + (wrong-type-argument + (funcall (quote ,test) (intern elm))))))) + (all-completions "" (symbol-value collection) predicate))) + ((and (symbolp collection) (boundp collection)) + (all-completions "" (symbol-value collection))) + ((and alistp test) + (cl-loop for i in collection when (funcall test i) collect i)) + (alistp collection) + (t (all-completions "" collection test))))) + (if sort-fn (sort cands sort-fn) cands))) + +(defun helm-cr-default-transformer (candidates _source) + "Default filter candidate function for `helm-comp-read'." + (cl-loop for c in candidates + for cand = (if (stringp c) (replace-regexp-in-string "\\s\\" "" c) c) + for pat = (replace-regexp-in-string "\\s\\" "" helm-pattern) + if (and (equal cand pat) helm-cr-unknown-pattern-flag) + collect + (cons (concat (propertize + " " 'display + (propertize "[?]" 'face 'helm-ff-prefix)) + c) + c) + into lst + else collect (if (and (stringp c) + (string-match "\n" c)) + (cons (replace-regexp-in-string "\n" "->" c) c) + c) + into lst + finally return (helm-fast-remove-dups lst :test 'equal))) + +(defun helm-comp-read--move-to-first-real-candidate () + (helm-aif (helm-get-selection nil 'withprop) + (when (string= (get-text-property 0 'display it) "[?]") + (helm-next-line)))) + +;;;###autoload +(cl-defun helm-comp-read (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) + (keymap helm-comp-read-map) + (name "Helm Completions") + candidates-in-buffer + exec-when-only-one + quit-when-no-cand + (volatile t) + sort + (fc-transformer 'helm-cr-default-transformer) + hist-fc-transformer + marked-candidates + nomark + (alistp t)) + "Read a string in the minibuffer, with helm completion. + +It is helm `completing-read' equivalent. + +- PROMPT is the prompt name to use. + +- COLLECTION can be a list, vector, obarray or hash-table. + It can be also a function that receives three arguments: + the values string, predicate and t. See `all-completions' for more details. + +Keys description: + +- TEST: A predicate called with one arg i.e candidate. + +- INITIAL-INPUT: Same as input arg in `helm'. + +- PRESELECT: See preselect arg of `helm'. + +- DEFAULT: This option is used only for compatibility with regular + Emacs `completing-read' (Same as DEFAULT arg of `completing-read'). + +- BUFFER: Name of helm-buffer. + +- MUST-MATCH: Candidate selected must be one of COLLECTION. + +- REVERSE-HISTORY: When non--nil display history source after current + source completion. + +- 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. + +- INPUT-HISTORY: A symbol. the minibuffer input history will be + stored there, if nil or not provided, `minibuffer-history' + will be used instead. + +- 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. + +- MODE-LINE: A string or list to display in mode line. + Default is `helm-comp-read-mode-line'. + +- KEYMAP: A keymap to use in this `helm-comp-read'. + (the keymap will be shared with history source) + +- NAME: The name related to this local source. + +- EXEC-WHEN-ONLY-ONE: Bound `helm-execute-action-at-once-if-one' + to non--nil. (possibles values are t or nil). + +- VOLATILE: Use volatile attribute \(enabled by default\). + +- SORT: A predicate to give to `sort' e.g `string-lessp'. + +- FC-TRANSFORMER: A `filtered-candidate-transformer' function. + +- 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. + +- NOMARK: When non--nil don't allow marking candidates. + +- ALISTP: \(default is non--nil\) See `helm-comp-read-get-candidates'. + +- CANDIDATES-IN-BUFFER: when non--nil use a source build with + `helm-candidates-in-buffer' which is much faster. + Argument VOLATILE have no effect when CANDIDATES-IN-BUFFER is non--nil. + +Any prefix args passed during `helm-comp-read' invocation will be recorded +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's mean you can pass prefix args before or after calling a command +that use `helm-comp-read' See `helm-M-x' for example." + + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + (let ((action-fn `(("Sole action (Identity)" + . (lambda (candidate) + (if ,marked-candidates + (helm-marked-candidates) + (identity candidate))))))) + ;; Assume completion have been already required, + ;; so always use 'confirm. + (when (eq must-match 'confirm-after-completion) + (setq must-match 'confirm)) + (let* ((minibuffer-completion-confirm must-match) + (must-match-map (when must-match + (let ((map (make-sparse-keymap))) + (define-key map (kbd "RET") + 'helm-confirm-and-exit-minibuffer) + map))) + (loc-map (if must-match-map + (make-composed-keymap + must-match-map (or keymap helm-map)) + (or keymap helm-map))) + (minibuffer-completion-predicate test) + (minibuffer-completion-table collection) + (helm-read-file-name-mode-line-string + (replace-regexp-in-string "helm-maybe-exit-minibuffer" + "helm-confirm-and-exit-minibuffer" + helm-read-file-name-mode-line-string)) + (get-candidates (lambda () + (let ((cands (helm-comp-read-get-candidates + collection test sort alistp))) + (setq helm-cr-unknown-pattern-flag nil) + (unless (or (eq must-match t) + (string= helm-pattern "") + (assoc helm-pattern cands) + (assoc (intern helm-pattern) cands) + (member helm-pattern cands)) + (setq cands (append (list + ;; Unquote helm-pattern + ;; when it is added + ;; as candidate. + (replace-regexp-in-string + "\\s\\" "" helm-pattern)) + cands)) + (setq helm-cr-unknown-pattern-flag t)) + (if (and default (not (string= default ""))) + (delq nil (cons default (delete default cands))) + cands)))) + (history-get-candidates (lambda () + (let ((all (helm-comp-read-get-candidates + history test nil alistp))) + (when all + (delete + "" + (helm-fast-remove-dups + (if (and default (not (string= default ""))) + (delq nil (cons default + (delete default all))) + all) + :test 'equal)))))) + (src-hist (helm-build-sync-source (format "%s History" name) + :candidates history-get-candidates + :fuzzy-match fuzzy + :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. + for cand = (replace-regexp-in-string "\\s\\" "" i) + collect cand))) + (and hist-fc-transformer (helm-mklist hist-fc-transformer))) + :persistent-action persistent-action + :persistent-help persistent-help + :mode-line mode-line + :action action-fn)) + (src (helm-build-sync-source name + :candidates get-candidates + :filtered-candidate-transformer fc-transformer + :requires-pattern requires-pattern + :persistent-action persistent-action + :persistent-help persistent-help + :fuzzy-match fuzzy + :mode-line mode-line + :action action-fn)) + (src-1 (helm-build-in-buffer-source name + :data get-candidates + :filtered-candidate-transformer fc-transformer + :requires-pattern requires-pattern + :persistent-action persistent-action + :fuzzy-match fuzzy + :persistent-help persistent-help + :mode-line mode-line + :action action-fn)) + (src-list (list src-hist + (if candidates-in-buffer + src-1 + (if volatile + (append src '((volatile))) + src)))) + (helm-execute-action-at-once-if-one exec-when-only-one) + (helm-quit-if-no-candidate quit-when-no-cand) + result) + (when nomark + (setq src-list (cl-loop for src in src-list + collect (cons '(nomark) src)))) + (when reverse-history (setq src-list (nreverse src-list))) + (add-hook 'helm-after-update-hook 'helm-comp-read--move-to-first-real-candidate) + (unwind-protect + (setq result (helm + :sources src-list + :input initial-input + :default default + :preselect preselect + :prompt prompt + :resume 'noresume + :case-fold-search case-fold + :keymap loc-map + :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 Issue #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))))) + (or + result + (when (and (eq helm-exit-status 0) + (eq must-match 'confirm)) + ;; Return empty string only if it is the DEFAULT + ;; value and helm-pattern is empty. + ;; otherwise return helm-pattern + (if (and (string= helm-pattern "") default) + default (identity helm-pattern))) + (unless (or (eq helm-exit-status 1) + must-match) ; FIXME this should not be needed now. + default) + (helm-mode--keyboard-quit))))) + +;; Generic completing-read +;; +;; Support also function as collection. +;; e.g M-x man is supported. +;; Support hash-table and vectors as collection. +;; NOTE: +;; Some crap emacs functions may not be supported +;; like ffap-alternate-file (bad use of completing-read) +;; and maybe others. +;; Provide a mode `helm-mode' which turn on +;; helm in all `completing-read' and `read-file-name' in Emacs. +;; +(defvar helm-completion-mode-string " Helm") + +(defvar helm-completion-mode-quit-message + "Helm completion disabled") + +(defvar helm-completion-mode-start-message + "Helm completion enabled") + +;;; Specialized handlers +;; +;; +(defun helm-completing-read-symbols + (prompt _collection test _require-match init + hist default _inherit-input-method name buffer) + "Specialized function for fast symbols completion in `helm-mode'." + (or + (helm + :sources (helm-build-in-buffer-source name + :init (lambda () + (require 'helm-elisp) + (helm-apropos-init (lambda (x) + (and (funcall test x) + (not (keywordp x)))) + default)) + :filtered-candidate-transformer 'helm-apropos-default-sort-fn + :persistent-action 'helm-lisp-completion-persistent-action + :persistent-help "Show brief doc in mode-line") + :prompt prompt + :buffer buffer + :input init + :history hist + :resume 'noresume + :default (or default "")) + (helm-mode--keyboard-quit))) + + +;;; Generic completing read +;; +;; +(defun helm-completing-read-default-1 + (prompt collection test require-match + init hist default _inherit-input-method + name buffer &optional cands-in-buffer exec-when-only-one) + "Call `helm-comp-read' with same args as `completing-read'. +Extra optional arg CANDS-IN-BUFFER mean use `candidates-in-buffer' +method which is faster. +It should be used when candidate list don't need to rebuild dynamically." + (let ((history (or (car-safe hist) hist))) + (when (and default (listp default)) + ;; When DEFAULT is a list move the list on head of COLLECTION + ;; and set it to its car. #bugfix `grep-read-files'. + (setq collection (if (listp collection) + (append default collection) + ;; Else COLLECTION is maybe a function or a table. + (append default (all-completions "" collection)))) + (setq default (car default))) + (helm-comp-read + prompt collection + :test test + :history history + :reverse-history helm-mode-reverse-history + :input-history history + :must-match require-match + :alistp nil ; Be sure `all-completions' is used. + :name name + :requires-pattern (if (and (string= default "") + (or (eq require-match 'confirm) + (eq require-match + 'confirm-after-completion))) + 1 0) + :candidates-in-buffer cands-in-buffer + :exec-when-only-one exec-when-only-one + :buffer buffer + ;; If DEF is not provided, fallback to empty string + ;; to avoid `thing-at-point' to be appended on top of list + :default (or default "") + ;; Fail with special characters (e.g in gnus "nnimap+gmail:") + ;; if regexp-quote is not used. + ;; when init is added to history, it will be unquoted by + ; helm-comp-read. + :initial-input (and (stringp init) (regexp-quote init))))) + +(defun helm-completing-read-with-cands-in-buffer + (prompt collection test require-match + init hist default inherit-input-method + name buffer) + "Same as `helm-completing-read-default-1' but use candidates-in-buffer." + ;; Some commands like find-tag may use `read-file-name' from inside + ;; the calculation of collection. in this case it clash with + ;; candidates-in-buffer that reuse precedent data (files) which is wrong. + ;; So (re)calculate collection outside of main helm-session. + (let ((cands (all-completions "" collection))) + (helm-completing-read-default-1 prompt cands test require-match + init hist default inherit-input-method + name buffer t))) + +(cl-defun helm--completing-read-default + (prompt collection &optional + predicate require-match + initial-input hist def + inherit-input-method) + "An helm replacement of `completing-read'. +This function should be used only as a `completing-read-function'. + +Don't use it directly, use instead `helm-comp-read' in your programs. + +See documentation of `completing-read' and `all-completions' for details." + (let* ((current-command (or (helm-this-command) this-command)) + (str-command (helm-symbol-name current-command)) + (buf-name (format "*helm-mode-%s*" str-command)) + (entry (assq current-command + helm-completing-read-handlers-alist)) + (def-com (cdr-safe entry)) + (str-defcom (and def-com (symbol-name def-com))) + (def-args (list prompt collection predicate require-match + initial-input hist def inherit-input-method)) + ;; Append the two extra args needed to set the buffer and source name + ;; in helm specialized functions. + (any-args (append def-args (list str-command buf-name))) + helm-completion-mode-start-message ; Be quiet + helm-completion-mode-quit-message + ;; Be sure this pesty *completion* buffer doesn't popup. + ;; Note: `minibuffer-with-setup-hook' may setup a lambda + ;; calling `minibuffer-completion-help' or other minibuffer + ;; functions we DONT WANT here, in these cases removing the hook + ;; (a symbol) have no effect. Issue #448. + ;; But because `minibuffer-completion-table' and + ;; `minibuffer-completion-predicate' are not bound + ;; anymore here, these functions should have no effect now. + (minibuffer-setup-hook (remove 'minibuffer-completion-help + minibuffer-setup-hook)) + ;; Disable hack that could be used before `completing-read'. + ;; i.e (push ?\t unread-command-events). + unread-command-events) + (when (eq def-com 'ido) (setq def-com 'ido-completing-read)) + (unless (or (not entry) def-com) + ;; An entry in *read-handlers-alist exists but have + ;; a nil value, so we exit from here, disable `helm-mode' + ;; and run the command again with it original behavior. + ;; `helm-mode' will be restored on exit. + (cl-return-from helm--completing-read-default + (unwind-protect + (progn + (helm-mode -1) + (apply completing-read-function def-args)) + (helm-mode 1)))) + ;; If we use now `completing-read' we MUST turn off `helm-mode' + ;; to avoid infinite recursion and CRASH. It will be reenabled on exit. + (when (or (eq def-com 'completing-read) + ;; All specialized functions are prefixed by "helm" + (and (stringp str-defcom) + (not (string-match "^helm" str-defcom)))) + (helm-mode -1)) + (unwind-protect + (cond (;; An helm specialized function exists, run it. + (and def-com helm-mode) + (apply def-com any-args)) + (;; Try to handle `ido-completing-read' everywhere. + (and def-com (eq def-com 'ido-completing-read)) + (setcar (memq collection def-args) + (all-completions "" collection predicate)) + (apply def-com def-args)) + (;; User set explicitely `completing-read' or something similar + ;; in *read-handlers-alist, use this with exactly the same + ;; args as in `completing-read'. + ;; If we are here `helm-mode' is now disabled. + def-com + (apply def-com def-args)) + (t ; Fall back to classic `helm-comp-read'. + (helm-completing-read-default-1 + prompt collection predicate require-match + initial-input hist def inherit-input-method + str-command buf-name))) + (helm-mode 1) + ;; When exiting minibuffer, `this-command' is set to + ;; `helm-exit-minibuffer', which is unwanted when starting + ;; on another `completing-read', so restore `this-command' to + ;; initial value when exiting. + (setq this-command current-command)))) + +;;; Generic read-file-name +;; +;; +(cl-defun helm-read-file-name + (prompt + &key + (name "Read File Name") + (initial-input (expand-file-name default-directory)) + (buffer "*Helm file completions*") + test + (case-fold helm-file-name-case-fold-search) + preselect + history + must-match + default + marked-candidates + nomark + (alistp t) + (persistent-action 'helm-find-files-persistent-action) + (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. + +Keys description: + +- NAME: Source name, default to \"Read File Name\". + +- INITIAL-INPUT: Where to start read file name, default to `default-directory'. + +- BUFFER: `helm-buffer' name default to \"*Helm Completions*\". + +- TEST: A predicate called with one arg 'candidate'. + +- CASE-FOLD: Same as `helm-case-fold-search'. + +- PRESELECT: helm preselection. + +- HISTORY: Display HISTORY in a special source. + +- MUST-MATCH: Can be 'confirm, nil, or t. + +- MARKED-CANDIDATES: When non--nil return a list of marked candidates. + +- NOMARK: When non--nil don't allow marking candidates. + +- ALISTP: Don't use `all-completions' in history (take effect only on history). + +- PERSISTENT-ACTION: a persistent action function. + +- PERSISTENT-HELP: persistent help message. + +- MODE-LINE: A mode line message, default is `helm-read-file-name-mode-line-string'." + + (when (get-buffer helm-action-buffer) + (kill-buffer helm-action-buffer)) + ;; Assume completion have been already required, + ;; so always use 'confirm. + (when (eq must-match 'confirm-after-completion) + (setq must-match 'confirm)) + (let* ((action-fn `(("Sole action (Identity)" + . (lambda (candidate) + (if ,marked-candidates + (helm-marked-candidates :with-wildcard t) + (identity candidate)))))) + ;; Be sure we don't erase the underlying minibuffer if some. + (helm-ff-auto-update-initial-value + (and helm-ff-auto-update-initial-value + (not (minibuffer-window-active-p (minibuffer-window))))) + helm-full-frame + (hist (and history (helm-comp-read-get-candidates + history nil nil alistp))) + (minibuffer-completion-confirm must-match) + (must-match-map (when must-match + (let ((map (make-sparse-keymap))) + (define-key map (kbd "RET") + 'helm-confirm-and-exit-minibuffer) + map))) + (cmap (if must-match-map + (make-composed-keymap + must-match-map helm-read-file-map) + helm-read-file-map)) + (minibuffer-completion-predicate test) + (minibuffer-completing-file-name t) + (helm-read-file-name-mode-line-string + (replace-regexp-in-string "helm-maybe-exit-minibuffer" + "helm-confirm-and-exit-minibuffer" + helm-read-file-name-mode-line-string)) + (src-list + (list + ;; History source. + (helm-build-sync-source (format "%s History" name) + :header-name (lambda (hname) + (concat hname helm-find-files-doc-header)) + :mode-line mode-line + :candidates hist + :nohighlight t + :persistent-action persistent-action + :persistent-help persistent-help + :nomark nomark + :action action-fn) + ;; Other source. + (helm-build-sync-source name + :header-name (lambda (hname) + (concat hname helm-find-files-doc-header)) + :init (lambda () + (setq helm-ff-auto-update-flag + helm-ff-auto-update-initial-value) + (setq helm-ff--auto-update-state + helm-ff-auto-update-flag)) + :mode-line mode-line + :nohighlight t + :candidates + (lambda () + (append (and (not (file-exists-p helm-pattern)) + (list helm-pattern)) + (if test + (cl-loop with hn = (helm-ff-tramp-hostnames) + for i in (helm-find-files-get-candidates + must-match) + when (or (member i hn) ; A tramp host + (funcall test i)) ; Test ok + collect i) + (helm-find-files-get-candidates must-match)))) + :filtered-candidate-transformer 'helm-ff-sort-candidates + :filter-one-by-one 'helm-ff-filter-candidate-one-by-one + :persistent-action persistent-action + :candidate-number-limit 9999 + :persistent-help persistent-help + :volatile t + :nomark nomark + :action action-fn))) + ;; Helm result. + (result (helm + :sources src-list + :input initial-input + :prompt prompt + :keymap cmap + :resume 'noresume + :case-fold-search case-fold + :default default + :buffer buffer + :preselect preselect))) + (or + (cond ((and result (stringp result) + (string= result "") "")) + ((and result + (stringp result) + (file-equal-p result initial-input) + default) + (if (listp default) (car default) default)) + ((and result (stringp result)) + (expand-file-name result)) + ((and result (listp result)) + (mapcar #'expand-file-name result)) + (t result)) + (when (and (not (string= helm-pattern "")) + (eq helm-exit-status 0) + (eq must-match 'confirm)) + (identity helm-pattern)) + (helm-mode--keyboard-quit)))) + +(defun helm-mode--default-filename (fname dir initial) + (unless dir (setq dir default-directory)) + (unless (file-name-absolute-p dir) + (setq dir (expand-file-name dir))) + (unless (or fname (consp fname)) + (setq fname (expand-file-name + (or initial buffer-file-name dir) + dir))) + (if (and fname (consp fname)) + (setq fname (cl-loop for f in fname + collect (expand-file-name f dir))) + (if (file-name-absolute-p fname) + fname (expand-file-name fname dir)))) + +(cl-defun helm--generic-read-file-name + (prompt &optional dir default-filename mustmatch initial predicate) + "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)) + (current-command (or (helm-this-command) this-command)) + (str-command (helm-symbol-name current-command)) + (helm--file-completion-sources + (cons str-command + (remove str-command helm--file-completion-sources))) + (buf-name (format "*helm-mode-%s*" str-command)) + (entry (assq current-command + helm-completing-read-handlers-alist)) + (def-com (cdr-safe entry)) + (str-defcom (and def-com (symbol-name def-com))) + (def-args (list prompt dir default-filename mustmatch initial predicate)) + ;; Append the two extra args needed to set the buffer and source name + ;; in helm specialized functions. + (any-args (append def-args (list str-command buf-name))) + (ido-state ido-mode) + helm-completion-mode-start-message ; Be quiet + helm-completion-mode-quit-message ; Same here + fname) + (setq default-filename (helm-mode--default-filename + default-filename dir initial)) + ;; Some functions that normally call `completing-read' can switch + ;; brutally to `read-file-name' (e.g find-tag), in this case + ;; the helm specialized function will fail because it is build + ;; for `completing-read', so set it to 'incompatible to be sure + ;; we switch to `helm-read-file-name' and don't try to call it + ;; with wrong number of args. + (when (eq def-com 'ido) + (setq def-com 'ido-read-file-name) (ido-mode 1)) + (when (and def-com (> (length (help-function-arglist def-com)) 8)) + (setq def-com 'incompatible)) + (unless (or (not entry) def-com) + (cl-return-from helm--generic-read-file-name + (unwind-protect + (progn + (helm-mode -1) + (apply read-file-name-function def-args)) + (helm-mode 1)))) + ;; If we use now `read-file-name' we MUST turn off `helm-mode' + ;; to avoid infinite recursion and CRASH. It will be reenabled on exit. + (when (or (eq def-com 'read-file-name) + (eq def-com 'ido-read-file-name) + (and (stringp str-defcom) + (not (string-match "^helm" str-defcom)))) + (helm-mode -1)) + (unwind-protect + (setq fname + (cond (;; A specialized function exists, run it + ;; with the two extra args specific to helm.. + (and def-com helm-mode + (not (eq def-com 'ido-read-file-name)) + (not (eq def-com 'incompatible))) + (apply def-com any-args)) + (;; Def-com value is `ido-read-file-name' + ;; run it with default args. + (and def-com (eq def-com 'ido-read-file-name)) + (ido-mode 1) + (apply def-com def-args)) + (;; Def-com value is `read-file-name' + ;; run it with default args. + (eq def-com 'read-file-name) + (apply def-com def-args)) + (t ; Fall back to classic `helm-read-file-name'. + (helm-read-file-name + prompt + :name str-command + :buffer buf-name + :default default-filename + :initial-input (expand-file-name init dir) + :alistp nil + :must-match mustmatch + :test predicate)))) + (helm-mode 1) + (ido-mode (if ido-state 1 -1)) + ;; Same comment as in `helm--completing-read-default'. + (setq this-command current-command)) + fname)) + +(defun helm-mode--advice-lisp--local-variables (old--fn &rest args) + (ignore-errors + (apply old--fn args))) + +(defun helm--completion-in-region (start end collection &optional predicate) + "[EXPERIMENTAL] Helm replacement of `completion--in-region'. +Can be used as value for `completion-in-region-function'." + (cl-declare (special require-match prompt)) + (if (memq major-mode helm-mode-no-completion-in-region-in-modes) + (funcall helm--old-completion-in-region-function + start end collection predicate) + (advice-add + 'lisp--local-variables + :around #'helm-mode--advice-lisp--local-variables) + (unwind-protect + (let* ((enable-recursive-minibuffers t) + (input (buffer-substring-no-properties start end)) + (current-command (or (helm-this-command) this-command)) + (str-command (symbol-name current-command)) + (buf-name (format "*helm-mode-%s*" str-command)) + (require-match (or (and (boundp 'require-match) require-match) + minibuffer-completion-confirm + ;; If prompt have not been propagated here, that's + ;; probably mean we have no prompt and we are in + ;; completion-at-point or friend, so use a non--nil + ;; value for require-match. + (not (boundp 'prompt)))) + ;; `completion-extra-properties' is let-bounded in `completion-at-point'. + ;; `afun' is a closure to call against each string in `data'. + ;; it provide the annotation info for each string. + ;; e.g "foo" => "foo " where foo is a function. + ;; See Issue #407. + (afun (plist-get completion-extra-properties :annotation-function)) + (data (all-completions input collection predicate)) + (init-space-suffix (unless helm-completion-in-region-fuzzy-match " ")) + ;; Assume that when `afun' and `predicate' are null + ;; we are in filename completion. + (file-comp-p (or (helm-mode--in-file-completion-p) + (and (null afun) (null predicate)))) + ;; Completion-at-point and friends have no prompt. + (result (if (stringp data) + data + (helm-comp-read + (or (and (boundp 'prompt) prompt) "Pattern: ") + (if file-comp-p + (cl-loop for f in data unless + (string-match "\\`\\.\\{1,2\\}/\\'" f) + collect f) + (if afun + (mapcar (lambda (s) + (let ((ann (funcall afun s))) + (if ann + (cons + (concat + s + (propertize + " " 'display + (propertize + ann + 'face 'completions-annotations))) + s) + s))) + data) + data)) + :name str-command + :fuzzy helm-completion-in-region-fuzzy-match + :nomark t + :initial-input + (cond ((and file-comp-p + (not (string-match "/\\'" input))) + (concat (helm-basename input) + (unless (string= input "") + init-space-suffix))) + ((string-match "/\\'" input) nil) + ((or (null require-match) + (stringp require-match)) + input) + (t (concat input init-space-suffix))) + :buffer buf-name + :fc-transformer (append (list 'helm-cr-default-transformer) + (list (lambda (candidates _source) + (sort candidates 'helm-generic-sort-fn)))) + :exec-when-only-one t + :quit-when-no-cand + #'(lambda () + ;; Delay message to overwrite "Quit". + (run-with-timer + 0.01 nil + #'(lambda () + (message "[No matches]"))) + t) ; exit minibuffer immediately. + :must-match require-match)))) + (when result + (delete-region (if (and file-comp-p + (save-excursion + (re-search-backward "~?/" start t))) + (match-end 0) start) + end) + (insert result))) + (advice-remove 'lisp--local-variables + #'helm-mode--advice-lisp--local-variables)))) + +(defun helm-mode--in-file-completion-p () + (with-helm-current-buffer + (run-hook-with-args-until-success 'file-name-at-point-functions))) + +(when (boundp 'completion-in-region-function) + (defconst helm--old-completion-in-region-function completion-in-region-function)) + +;;;###autoload +(define-minor-mode helm-mode + "Toggle generic helm completion. + +All functions in Emacs that use `completing-read' +or `read-file-name' and friends will use helm interface +when this mode is turned on. +However you can modify this behavior for functions of your choice +with `helm-completing-read-handlers-alist'. + +Called with a positive arg, turn on unconditionally, with a +negative arg turn off. +You can turn it on with `helm-mode'. + +Some crap emacs functions may not be supported, +e.g `ffap-alternate-file' and maybe others +You can add such functions to `helm-completing-read-handlers-alist' +with a nil value. + +Note: This mode is incompatible with Emacs23." + :group 'helm-mode + :global t + :lighter helm-completion-mode-string + (cl-assert (boundp 'completing-read-function) nil + "`helm-mode' not available, upgrade to Emacs-24") + (if helm-mode + (progn + (setq completing-read-function 'helm--completing-read-default + read-file-name-function 'helm--generic-read-file-name) + (when (and (boundp 'completion-in-region-function) + helm-mode-handle-completion-in-region) + (setq completion-in-region-function #'helm--completion-in-region)) + (message helm-completion-mode-start-message)) + (setq completing-read-function (and (fboundp 'completing-read-default) + 'completing-read-default) + read-file-name-function (and (fboundp 'read-file-name-default) + 'read-file-name-default)) + (when (and (boundp 'completion-in-region-function) + (boundp 'helm--old-completion-in-region-function)) + (setq completion-in-region-function helm--old-completion-in-region-function)) + (message helm-completion-mode-quit-message))) + +(provide 'helm-mode) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-mode.el ends here diff --git a/elpa/helm-20150403.101/helm-net.el b/elpa/helm-20150403.101/helm-net.el new file mode 100644 index 00000000..702a3aa6 --- /dev/null +++ b/elpa/helm-20150403.101/helm-net.el @@ -0,0 +1,607 @@ +;;; helm-net.el --- helm browse url and search web. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'url) +(require 'xml) +(require 'browse-url) + + +(defgroup helm-net nil + "Net related applications and libraries for Helm." + :group 'helm) + +(defcustom helm-google-suggest-default-browser-function nil + "The browse url function you prefer to use with google suggest. +When nil, use the first browser function available +See `helm-browse-url-default-browser-alist'." + :group 'helm-net + :type 'symbol) + +(defcustom helm-home-url "http://www.google.fr" + "Default url to use as home url." + :group 'helm-net + :type 'string) + +(defcustom helm-surfraw-default-browser-function nil + "The browse url function you prefer to use with surfraw. +When nil, fallback to `browse-url-browser-function'." + :group 'helm-net + :type 'symbol) + +(defcustom helm-google-suggest-url + "http://google.com/complete/search?output=toolbar&q=" + "URL used for looking up Google suggestions." + :type 'string + :group 'helm-net) + +(defcustom helm-google-suggest-search-url + "http://www.google.com/search?ie=utf-8&oe=utf-8&q=%s" + "URL used for Google searching." + :type 'string + :group 'helm-net) + +(defcustom helm-google-suggest-use-curl-p nil + "When non--nil use CURL to get info from `helm-google-suggest-url'. +Otherwise `url-retrieve-synchronously' is used." + :type 'boolean + :group 'helm-net) + +(defcustom helm-yahoo-suggest-url + "http://search.yahooapis.com/WebSearchService/V1/relatedSuggestion?appid=Generic&query=" + "Url used for looking up Yahoo suggestions." + :type 'string + :group 'helm-net) + +(defcustom helm-yahoo-suggest-search-url + "http://search.yahoo.com/search?&ei=UTF-8&fr&h=c&p=%s" + "Url used for Yahoo searching." + :type 'string + :group 'helm-net) + +(defcustom helm-surfraw-duckduckgo-url + "https://duckduckgo.com/lite/?q=%s&kp=1" + "The duckduckgo url. +This is a format string, don't forget the `%s'. +If you have personal settings saved on duckduckgo you should have +a personal url, see your settings on duckduckgo." + :type 'string + :group 'helm-net) + +(defcustom helm-wikipedia-suggest-url + "http://en.wikipedia.org/w/api.php?action=opensearch&search=" + "Url used for looking up Wikipedia suggestions." + :type 'string + :group 'helm-net) + +(defcustom helm-search-suggest-action-wikipedia-url + "https://en.wikipedia.org/wiki/Special:Search?search=%s" + "The Wikipedia search url. +This is a format string, don't forget the `%s'." + :type 'string + :group 'helm-net) + +(defcustom helm-wikipedia-summary-url + "http://en.wikipedia.org/w/api.php?action=parse&format=json&prop=text§ion=0&page=" + "URL for getting the summary of a Wikipedia topic." + :type 'string + :group 'helm-net) + +(defcustom helm-wikipedia-follow-delay 2 + "Delay before wikipedia summary popup." + :type 'number + :group 'helm-net) + +(defcustom helm-search-suggest-action-youtube-url + "http://www.youtube.com/results?aq=f&search_query=%s" + "The Youtube search url. +This is a format string, don't forget the `%s'." + :type 'string + :group 'helm-net) + +(defcustom helm-search-suggest-action-imdb-url + "http://www.imdb.com/find?s=all&q=%s" + "The IMDb search url. +This is a format string, don't forget the `%s'." + :type 'string + :group 'helm-net) + +(defcustom helm-search-suggest-action-google-maps-url + "http://maps.google.com/maps?f=q&source=s_q&q=%s" + "The Google Maps search url. +This is a format string, don't forget the `%s'." + :type 'string + :group 'helm-net) + +(defcustom helm-search-suggest-action-google-news-url + "http://www.google.com/search?safe=off&prmd=nvlifd&source=lnms&tbs=nws:1&q=%s" + "The Google News search url. +This is a format string, don't forget the `%s'." + :type 'string + :group 'helm-net) + + +;;; Additional actions for search suggestions +;; +;; +;; Internal + +(defun helm-search-suggest-perform-additional-action (url query) + "Perform the search via URL using QUERY as input." + (browse-url (format url (url-hexify-string query)))) + +(defvar helm-search-suggest-additional-actions + '(("Wikipedia" . (lambda (candidate) + (helm-search-suggest-perform-additional-action + helm-search-suggest-action-wikipedia-url + candidate))) + ("Youtube" . (lambda (candidate) + (helm-search-suggest-perform-additional-action + helm-search-suggest-action-youtube-url + candidate))) + ("IMDb" . (lambda (candidate) + (helm-search-suggest-perform-additional-action + helm-search-suggest-action-imdb-url + candidate))) + ("Google Maps" . (lambda (candidate) + (helm-search-suggest-perform-additional-action + helm-search-suggest-action-google-maps-url + candidate))) + ("Google News" . (lambda (candidate) + (helm-search-suggest-perform-additional-action + helm-search-suggest-action-google-news-url + candidate)))) + "List of additional actions for suggest sources.") + + +;;; Google Suggestions +;; +;; +;; Internal +(defvar helm-ggs-max-length-real-flag 0) +(defvar helm-ggs-max-length-num-flag 0) + +(defun helm-google-suggest-fetch (input) + "Fetch suggestions for INPUT from XML buffer. +Return an alist with elements like (data . number_results)." + (setq helm-ggs-max-length-real-flag 0 + helm-ggs-max-length-num-flag 0) + (let ((request (concat helm-google-suggest-url + (url-hexify-string input))) + (fetch #'(lambda () + (cl-loop + with result-alist = (xml-get-children + (car (xml-parse-region + (point-min) (point-max))) + 'CompleteSuggestion) + for i in result-alist + for data = (cdr (cl-caadr (assoc 'suggestion i))) + for nqueries = (cdr (cl-caadr (assoc 'num_queries i))) + for lqueries = (length (helm-ggs-set-number-result + nqueries)) + for ldata = (length data) + do + (progn + (when (> ldata helm-ggs-max-length-real-flag) + (setq helm-ggs-max-length-real-flag ldata)) + (when (> lqueries helm-ggs-max-length-num-flag) + (setq helm-ggs-max-length-num-flag lqueries))) + collect (cons data nqueries) into cont + finally return cont)))) + (if helm-google-suggest-use-curl-p + (with-temp-buffer + (call-process "curl" nil t nil request) + (funcall fetch)) + (with-current-buffer + (url-retrieve-synchronously request) + (funcall fetch))))) + +(defun helm-google-suggest-set-candidates (&optional request-prefix) + "Set candidates with result and number of google results found." + (let ((suggestions + (cl-loop with suggested-results = (helm-google-suggest-fetch + (or (and request-prefix + (concat request-prefix + " " helm-pattern)) + helm-pattern)) + for (real . numresult) in suggested-results + ;; Prepare number of results with "," + for fnumresult = (helm-ggs-set-number-result numresult) + ;; Calculate number of spaces to add before fnumresult + ;; if it is smaller than longest result + ;; `helm-ggs-max-length-num-flag'. + ;; e.g 1,234,567 + ;; 345,678 + ;; To be sure it is aligned properly. + for nspaces = (if (< (length fnumresult) + helm-ggs-max-length-num-flag) + (- helm-ggs-max-length-num-flag + (length fnumresult)) + 0) + ;; Add now the spaces before fnumresult. + for align-fnumresult = (concat (make-string nspaces ? ) + fnumresult) + for interval = (- helm-ggs-max-length-real-flag + (length real)) + for spaces = (make-string (+ 2 interval) ? ) + for display = (format "%s%s(%s results)" + real spaces align-fnumresult) + collect (cons display real)))) + (if (cl-loop for (_disp . dat) in suggestions + thereis (equal dat helm-pattern)) + suggestions + ;; if there is no suggestion exactly matching the input then + ;; prepend a Search on Google item to the list + (append + suggestions + (list (cons (concat "Search for " "'" helm-input "'" " on Google") + helm-input)))))) + +(defun helm-ggs-set-number-result (num) + (if num + (progn + (and (numberp num) (setq num (number-to-string num))) + (cl-loop for i in (reverse (split-string num "" t)) + for count from 1 + append (list i) into C + when (= count 3) + append (list ",") into C + and do (setq count 0) + finally return + (replace-regexp-in-string + "^," "" (mapconcat 'identity (reverse C) "")))) + "?")) + +(defun helm-google-suggest-action (candidate) + "Default action to jump to a google suggested candidate." + (let ((arg (format helm-google-suggest-search-url + (url-hexify-string candidate)))) + (helm-aif helm-google-suggest-default-browser-function + (funcall it arg) + (helm-browse-url arg)))) + +(defvar helm-google-suggest-default-function + 'helm-google-suggest-set-candidates + "Default function to use in helm google suggest.") + +(defvar helm-source-google-suggest + `((name . "Google Suggest") + (candidates . (lambda () + (funcall helm-google-suggest-default-function))) + (action . ,(cons '("Google Search" . helm-google-suggest-action) + helm-search-suggest-additional-actions)) + (volatile) + (keymap . ,helm-map) + (requires-pattern . 3))) + +(defun helm-google-suggest-emacs-lisp () + "Try to emacs lisp complete with google suggestions." + (helm-google-suggest-set-candidates "emacs lisp")) + + +;;; Yahoo suggestions +;; +;; +(defun helm-yahoo-suggest-fetch (input) + "Fetch Yahoo suggestions for INPUT from XML buffer. +Return an alist with elements like (data . number_results)." + (let ((request (concat helm-yahoo-suggest-url + (url-hexify-string input)))) + (with-current-buffer + (url-retrieve-synchronously request) + (cl-loop with result-alist = + (xml-get-children + (car (xml-parse-region + (point-min) (point-max))) + 'Result) + for i in result-alist + collect (cl-caddr i))))) + +(defun helm-yahoo-suggest-set-candidates () + "Set candidates with Yahoo results found." + (let ((suggestions (helm-yahoo-suggest-fetch helm-input))) + (or suggestions + (append + suggestions + (list (cons (concat "Search for " "'" helm-input "'" " on Yahoo") + helm-input)))))) + +(defun helm-yahoo-suggest-action (candidate) + "Default action to jump to a Yahoo suggested candidate." + (helm-browse-url (format helm-yahoo-suggest-search-url + (url-hexify-string candidate)))) + +(defvar helm-source-yahoo-suggest + `((name . "Yahoo Suggest") + (candidates . helm-yahoo-suggest-set-candidates) + (action . (("Yahoo Search" . helm-yahoo-suggest-action))) + (volatile) + (keymap . ,helm-map) + (requires-pattern . 3))) + +;;; Wikipedia suggestions +;; +;; +(declare-function json-read-from-string "json" (string)) +(defun helm-wikipedia-suggest-fetch () + "Fetch Wikipedia suggestions and return them as a list." + (require 'json) + (let ((request (concat helm-wikipedia-suggest-url + (url-hexify-string helm-pattern)))) + (if helm-google-suggest-use-curl-p + (with-temp-buffer + (call-process "curl" nil t nil request) + (helm-wikipedia--parse-buffer)) + (with-current-buffer + (url-retrieve-synchronously request) + (helm-wikipedia--parse-buffer))))) + +(defun helm-wikipedia--parse-buffer () + (goto-char (point-min)) + (when (re-search-forward "^\\[.+\\[\\(.*\\)\\]\\]" nil t) + (cl-loop for i across (aref (json-read-from-string (match-string 0)) 1) + collect i into result + finally return (or result + (append + result + (list (cons (format "Search for '%s' on wikipedia" + helm-pattern) + helm-pattern))))))) + +(defvar helm-wikipedia--summary-cache (make-hash-table :test 'equal)) +(defun helm-wikipedia-persistent-action (candidate) + (unless (string= (format "Search for '%s' on wikipedia" + helm-pattern) + (helm-get-selection nil t)) + (message "Fetching summary from Wikipedia...") + (let ((buf (get-buffer-create "*helm wikipedia summary*")) + result mess) + (while (progn + (setq result (or (gethash candidate helm-wikipedia--summary-cache) + (puthash candidate + (prog1 + (helm-wikipedia-fetch-summary candidate) + (setq mess "Done")) + helm-wikipedia--summary-cache))) + (when (and result + (listp result)) + (setq candidate (cdr result)) + (message "Redirected to %s" candidate) + t))) + (if (not result) + (message "Error when getting summary.") + (with-current-buffer buf + (erase-buffer) + (setq cursor-type nil) + (insert result) + (fill-region (point-min) (point-max)) + (goto-char (point-min))) + (display-buffer buf) + (message mess))))) + + +(defun helm-wikipedia-fetch-summary (input) + (let* ((request (concat helm-wikipedia-summary-url (url-hexify-string input)))) + (if helm-google-suggest-use-curl-p + (with-temp-buffer + (call-process "curl" nil t nil request) + (helm-wikipedia--parse-summary)) + (with-current-buffer + (url-retrieve-synchronously request) + (helm-wikipedia--parse-summary))))) + + +(defun helm-wikipedia--parse-summary () + (goto-char (point-min)) + (when (search-forward "{" nil t) + (let ((result (cdr (assoc '* + (assoc 'text + (assoc 'parse + (json-read-from-string + (buffer-substring-no-properties + (1- (point)) (point-max))))))))) + (when result + (if (string-match "]+>\\([^<]+\\)" result) + (cons 'redirect (match-string 1 result)) + + ;; find the beginning of the summary text in the result + + ;; check if there is a table before the summary and skip that + (when (or (string-match "\\(\n\\)?\n

" result) + ;; otherwise just find the first paragraph + (string-match "

" result)) + ;; remove cruft and do a simple formatting + (replace-regexp-in-string + "Cite error: .*" "" + (replace-regexp-in-string + " " "" + (replace-regexp-in-string + "\\[[^\]]+\\]" "" + (replace-regexp-in-string + "<[^>]*>" "" + (replace-regexp-in-string + "

\n

" "\n\n" + (substring result (match-end 0))))))))))))) + + +(defvar helm-source-wikipedia-suggest + `((name . "Wikipedia Suggest") + (candidates . helm-wikipedia-suggest-fetch) + (action . (("Wikipedia" . (lambda (candidate) + (helm-search-suggest-perform-additional-action + helm-search-suggest-action-wikipedia-url + candidate))))) + (persistent-action . helm-wikipedia-persistent-action) + (volatile) + (keymap . ,helm-map) + (follow . 1) + (follow-delay . ,helm-wikipedia-follow-delay) + (requires-pattern . 3))) + + +;;; Web browser functions. +;; +;; +;; If default setting of `w3m-command' is not +;; what you want and you modify it, you will have to reeval +;; also `helm-browse-url-default-browser-alist'. + +(defvar helm-browse-url-chromium-program "chromium-browser") +(defvar helm-browse-url-uzbl-program "uzbl-browser") +(defvar helm-browse-url-conkeror-program "conkeror") +(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-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-mosaic-program . browse-url-mosaic) + (,browse-url-xterm-program . browse-url-text-xterm) + ("emacs" . eww-browse-url)) + "*Alist of \(executable . function\) to try to find a suitable url browser.") + +(cl-defun helm-generic-browser (url cmd-name &rest args) + "Browse URL with NAME browser." + (let ((proc (concat cmd-name " " url))) + (message "Starting %s..." cmd-name) + (apply 'start-process proc nil cmd-name + (append args (list url))) + (set-process-sentinel + (get-process proc) + #'(lambda (process event) + (when (string= event "finished\n") + (message "%s process %s" process event)))))) + +(defun helm-browse-url-chromium (url &optional _ignore) + "Browse URL with google chrome browser." + (interactive "sURL: ") + (helm-generic-browser + url helm-browse-url-chromium-program)) + +(defun helm-browse-url-uzbl (url &optional _ignore) + "Browse URL with uzbl browser." + (interactive "sURL: ") + (helm-generic-browser url helm-browse-url-uzbl-program "-u")) + +(defun helm-browse-url-conkeror (url &optional _ignore) + "Browse URL with conkeror browser." + (interactive "sURL: ") + (helm-generic-browser url helm-browse-url-conkeror-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)))) + (if default-browser-fn + (apply default-browser-fn url args) + (error "No usable browser found")))) + +(defun helm-browse-url (url &rest args) + "Default command to browse URL." + (if browse-url-browser-function + (browse-url url args) + (helm-browse-url-default-browser url args))) + + +;;; Surfraw +;; +;; Need external program surfraw. +;; + +;; Internal +(defvar helm-surfraw-engines-history nil) +(defvar helm-surfraw-input-history nil) +(defvar helm-surfraw--elvi-cache nil) + +(defun helm-build-elvi-list () + "Return list of all engines and descriptions handled by surfraw." + (or helm-surfraw--elvi-cache + (setq helm-surfraw--elvi-cache + (cdr (with-temp-buffer + (call-process "surfraw" nil t nil "-elvi") + (split-string (buffer-string) "\n")))))) + +;;;###autoload +(defun helm-surfraw (pattern engine) + "Preconfigured `helm' to search PATTERN with search ENGINE." + (interactive (list (read-string "SearchFor: " + nil 'helm-surfraw-input-history + (thing-at-point 'symbol)) + (helm-comp-read + "Engine: " + (helm-build-elvi-list) + :must-match t + :name "Surfraw Search Engines" + :del-input nil + :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. + (format helm-surfraw-duckduckgo-url + (url-hexify-string pattern)) + (with-temp-buffer + (apply 'call-process "surfraw" nil t nil + (append (list engine-nodesc "-p") (split-string pattern))) + (replace-regexp-in-string + "\n" "" (buffer-string))))) + (browse-url-browser-function (or helm-surfraw-default-browser-function + 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)))))) + +;;;###autoload +(defun helm-google-suggest () + "Preconfigured `helm' for google search with google suggest." + (interactive) + (helm-other-buffer 'helm-source-google-suggest "*helm google*")) + +;;;###autoload +(defun helm-yahoo-suggest () + "Preconfigured `helm' for Yahoo searching with Yahoo suggest." + (interactive) + (helm-other-buffer 'helm-source-yahoo-suggest "*helm yahoo*")) + +;;;###autoload +(defun helm-wikipedia-suggest () + "Preconfigured `helm' for Wikipedia lookup with Wikipedia suggest." + (interactive) + (helm :sources 'helm-source-wikipedia-suggest + :buffer "*helm wikipedia*")) + + +(provide 'helm-net) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-net.el ends here diff --git a/elpa/helm-20150403.101/helm-org.el b/elpa/helm-20150403.101/helm-org.el new file mode 100644 index 00000000..22696dec --- /dev/null +++ b/elpa/helm-20150403.101/helm-org.el @@ -0,0 +1,145 @@ +;;; helm-org.el --- Helm for org headlines and keywords completion -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: +(require 'cl-lib) +(require 'helm) +(require 'org) + +(defgroup helm-org nil + "Org related functions for helm." + :group 'helm) + +(defcustom helm-org-headings-fontify nil + "Fontify org buffers before parsing them. +This reflect fontification in helm-buffer when non--nil. +NOTE: This will be slow on large org buffers." + :group 'helm-org + :type 'boolean) + +;; Internal +(defvar helm-org-headings--nofilename nil) + +;;; Org capture templates +;; +;; +(defvar org-capture-templates) +(defun helm-source-org-capture-templates () + (helm-build-sync-source "Org Capture Templates:" + :candidates (cl-loop for template in org-capture-templates + collect `(,(nth 1 template) . ,(nth 0 template))) + :action '(("Do capture" . (lambda (template-shortcut) + (org-capture nil template-shortcut)))))) + +;;; Org headings +;; +;; +(defun helm-org-goto-marker (marker) + (switch-to-buffer (marker-buffer marker)) + (goto-char (marker-position marker)) + (org-show-context) + (org-show-entry)) + +(cl-defun helm-source-org-headings-for-files (filenames + &optional (min-depth 1) (max-depth 8)) + (helm-build-sync-source "Org Headings" + :candidates (helm-org-get-candidates filenames min-depth max-depth) + :action '(("Go to line" . helm-org-goto-marker) + ("Refile to this heading" . helm-org-heading-refile) + ("Insert link to this heading" + . helm-org-insert-link-to-heading-at-marker)))) + +(defun helm-org-insert-link-to-heading-at-marker (marker) + (with-current-buffer (marker-buffer marker) + (let ((heading-name (save-excursion (goto-char (marker-position marker)) + (nth 4 (org-heading-components)))) + (file-name (buffer-file-name))) + (with-helm-current-buffer + (org-insert-link + file-name (concat "file:" file-name "::*" heading-name)))))) + +(defun helm-org-heading-refile (marker) + (with-helm-current-buffer + (org-cut-subtree)) + (let ((target-level (with-current-buffer (marker-buffer marker) + (goto-char (marker-position marker)) + (org-current-level)))) + (helm-org-goto-marker marker) + (org-end-of-subtree t t) + (org-paste-subtree (+ target-level 1)))) + +(defun helm-org-get-candidates (filenames min-depth max-depth) + (apply #'append + (mapcar (lambda (filename) + (helm-get-org-candidates-in-file + filename min-depth max-depth + helm-org-headings-fontify + helm-org-headings--nofilename)) + filenames))) + +(defun helm-get-org-candidates-in-file (filename min-depth max-depth + &optional fontify nofname) + (with-current-buffer (find-file-noselect filename) + (and fontify (jit-lock-fontify-now)) + (let ((match-fn (if fontify 'match-string 'match-string-no-properties))) + (save-excursion + (goto-char (point-min)) + (cl-loop with width = (window-width) + while (re-search-forward org-complex-heading-regexp nil t) + if (let ((num-stars (length (match-string-no-properties 1)))) + (and (>= num-stars min-depth) (<= num-stars max-depth))) + collect `(,(let ((heading (funcall match-fn 4)) + (file (unless nofname + (concat (helm-basename filename) ":"))) + (level (length (match-string-no-properties 1)))) + (org-format-outline-path + (append (org-get-outline-path t level heading) + (list heading)) width file)) + . ,(point-marker))))))) + +;;;###autoload +(defun helm-org-agenda-files-headings () + (interactive) + (helm :sources (helm-source-org-headings-for-files (org-agenda-files)) + :candidate-number-limit 99999 + :buffer "*helm org headings*")) + +;;;###autoload +(defun helm-org-in-buffer-headings () + (interactive) + (helm :sources (helm-source-org-headings-for-files + (list (buffer-file-name (current-buffer)))) + :candidate-number-limit 99999 + :buffer "*helm org inbuffer*")) + +;;;###autoload +(defun helm-org-capture-templates () + (interactive) + (helm :sources (helm-source-org-capture-templates) + :candidate-number-limit 99999 + :buffer "*helm org capture templates*")) + + +(provide 'helm-org) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-org.el ends here diff --git a/elpa/helm-20150403.101/helm-pkg.el b/elpa/helm-20150403.101/helm-pkg.el new file mode 100644 index 00000000..9e258761 --- /dev/null +++ b/elpa/helm-20150403.101/helm-pkg.el @@ -0,0 +1,8 @@ +(define-package "helm" "20150403.101" "Helm is an Emacs incremental and narrowing framework" + '((emacs "24") + (cl-lib "0.5") + (async "1.2")) + :url "https://emacs-helm.github.io/helm/") +;; Local Variables: +;; no-byte-compile: t +;; End: diff --git a/elpa/helm-20150403.101/helm-plugin.el b/elpa/helm-20150403.101/helm-plugin.el new file mode 100644 index 00000000..976a7349 --- /dev/null +++ b/elpa/helm-20150403.101/helm-plugin.el @@ -0,0 +1,137 @@ +;;; helm-plugin.el --- Helm plugins -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) + + +;;; Plug-in: `info-index' +;; +;; +(defun helm-make-info-source (source file) + `(,@source + (name . ,(concat "Info Index: " file)) + (info-file . ,file) + (init . helm-info-init) + (display-to-real . helm-info-display-to-real) + (get-line . buffer-substring) + (candidates-in-buffer) + (action ("Goto node" . helm-info-goto)))) + +(defun helm-compile-source--info-index (source) + (helm-aif (helm-interpret-value (assoc-default 'info-index source)) + (helm-make-info-source source it) + source)) + +(add-to-list 'helm-compile-source-functions 'helm-compile-source--info-index) + +(helm-document-attribute 'info-index "info-index plugin" + " Create a source of info index very easily. + + Example: + + (defvar helm-source-info-wget '((info-index . \"wget\"))") + + +;;; Plug-in: `candidates-file' +;; +;; List all lines in a file. +(defun helm-compile-source--candidates-file (source) + (if (assoc-default 'candidates-file source) + `((init helm-p-candidates-file-init + ,@(let ((orig-init (assoc-default 'init source))) + (cond ((null orig-init) nil) + ((functionp orig-init) (list orig-init)) + (t orig-init)))) + (candidates-in-buffer) + ,@source) + source)) +(add-to-list 'helm-compile-source-functions 'helm-compile-source--candidates-file) + +(defun helm-p-candidates-file-init () + (cl-destructuring-bind (file &optional updating) + (helm-mklist (helm-attr 'candidates-file)) + (setq file (helm-interpret-value file)) + (with-current-buffer (helm-candidate-buffer 'global) + (insert-file-contents file) + (when updating + (buffer-disable-undo) + (font-lock-mode -1) + (auto-revert-mode 1))))) + +(helm-document-attribute 'candidates-file "candidates-file plugin" + " Use a file as the candidates buffer. + + 1st argument is a filename, string or function name or variable + name. If optional 2nd argument is non-nil, the file is opened with + `auto-revert-mode' enabled. + + Example: + + \(defvar helm-source-test-file + '((name . \"test1\") + (candidates-file \"~/.emacs.el\" t))) + + Will list all lines in .emacs.el.") + + +;;; Plug-in: `persistent-help' +;; +;; Add help about persistent action in `helm-buffer' header. +(defun helm-compile-source--persistent-help (source) + (if (assoc 'header-line source) + source + (append source '((header-line . helm-persistent-help-string))))) +(add-to-list 'helm-compile-source-functions 'helm-compile-source--persistent-help) + +(defun helm-persistent-help-string () + (substitute-command-keys + (concat "\\\\[helm-execute-persistent-action]: " + (or (helm-interpret-value (helm-attr 'persistent-help)) + (helm-aif (or (assoc-default + 'persistent-action + (helm-get-current-source)) + (assoc-default + 'action (helm-get-current-source))) + (cond ((symbolp it) + (symbol-name it)) + ((listp it) + (or (ignore-errors (caar it)) "")))) + "") + " (keeping session)"))) + + +;;; Document new attributes +;; +;; +(helm-document-attribute 'persistent-help "persistent-help plug-in" + " A string to explain persistent-action of this source. It also + accepts a function or a variable name.") + + +(provide 'helm-plugin) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-plugin ends here diff --git a/elpa/helm-20150403.101/helm-regexp.el b/elpa/helm-20150403.101/helm-regexp.el new file mode 100644 index 00000000..62e10752 --- /dev/null +++ b/elpa/helm-20150403.101/helm-regexp.el @@ -0,0 +1,624 @@ +;;; helm-regexp.el --- In buffer regexp searching and replacement for helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'helm-plugin) + + +(defgroup helm-regexp nil + "Regexp related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-moccur-always-search-in-current nil + "Helm multi occur always search in current buffer when non--nil." + :group 'helm-regexp + :type 'boolean) + +(defcustom helm-moccur-use-ioccur-style-keys t + "Similar to `helm-grep-use-ioccur-style-keys' but for multi occur." + :group 'helm-regexp + :type 'boolean) + +(defcustom helm-moccur-auto-update-on-resume nil + "Allow auto updating helm-(m)occur buffer when outdated. +noask => Always update without asking +nil => Don't update but signal buffer needs update +never => Never update and do not signal buffer needs update +Any other non--nil value update after confirmation." + :group 'helm-regexp + :type '(radio :tag "Allow auto updating helm-(m)occur buffer when outdated." + (const :tag "Always update without asking" noask) + (const :tag "Never update and do not signal buffer needs update" never) + (const :tag "Don't update but signal buffer needs update" nil) + (const :tag "Update after confirmation" t))) + + +(defface helm-moccur-buffer + '((t (:foreground "DarkTurquoise" :underline t))) + "Face used to highlight moccur buffer names." + :group 'helm-regexp) + +(defface helm-resume-need-update + '((t (:background "red"))) + "Face used to flash moccur buffer when it needs update." + :group 'helm-regexp) + + +(defvar helm-moccur-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-") 'helm-goto-next-file) + (define-key map (kbd "M-") 'helm-goto-precedent-file) + (define-key map (kbd "C-w") 'helm-yank-text-at-point) + (define-key map (kbd "C-c ?") 'helm-moccur-help) + (define-key map (kbd "C-c o") 'helm-moccur-run-goto-line-ow) + (define-key map (kbd "C-c C-o") 'helm-moccur-run-goto-line-of) + (define-key map (kbd "C-x C-s") 'helm-moccur-run-save-buffer) + (when helm-moccur-use-ioccur-style-keys + (define-key map (kbd "") 'helm-execute-persistent-action) + (define-key map (kbd "") 'helm-moccur-run-default-action)) + (delq nil map)) + "Keymap used in Moccur source.") + + +(defvar helm-build-regexp-history nil) +(defun helm-query-replace-regexp (_candidate) + "Query replace regexp from `helm-regexp'. +With a prefix arg replace only matches surrounded by word boundaries, +i.e Don't replace inside a word, regexp is surrounded with \\bregexp\\b." + (let ((regexp (funcall (helm-attr 'regexp)))) + (apply 'query-replace-regexp + (helm-query-replace-args regexp)))) + +(defun helm-kill-regexp-as-sexp (_candidate) + "Kill regexp in a format usable in lisp code." + (helm-regexp-kill-new + (prin1-to-string (funcall (helm-attr 'regexp))))) + +(defun helm-kill-regexp (_candidate) + "Kill regexp as it is in `helm-pattern'." + (helm-regexp-kill-new (funcall (helm-attr 'regexp)))) + +(defun helm-query-replace-args (regexp) + "create arguments of `query-replace-regexp' action in `helm-regexp'." + (let ((region-only (helm-region-active-p))) + (list + regexp + (query-replace-read-to regexp + (format "Query replace %sregexp %s" + (if helm-current-prefix-arg "word " "") + (if region-only "in region " "")) + t) + helm-current-prefix-arg + (when region-only (region-beginning)) + (when region-only (region-end))))) + +(defvar helm-source-regexp + '((name . "Regexp Builder") + (init . (lambda () + (helm-init-candidates-in-buffer + 'global (with-temp-buffer + (insert-buffer-substring helm-current-buffer) + (buffer-string))))) + (candidates-in-buffer) + (get-line . helm-regexp-get-line) + (persistent-action . helm-regexp-persistent-action) + (persistent-help . "Show this line") + (multiline) + (no-matchplugin) + (requires-pattern . 2) + (mode-line . "Press TAB to select action.") + (regexp . (lambda () helm-input)) + (action . (("Kill Regexp as sexp" . helm-kill-regexp-as-sexp) + ("Query Replace Regexp (C-u Not inside word.)" + . helm-query-replace-regexp) + ("Kill Regexp" . helm-kill-regexp))))) + +(defun helm-regexp-get-line (s e) + (let ((matches (match-data)) + (line (buffer-substring s e))) + (propertize + (cl-loop with ln = (format "%5d: %s" (line-number-at-pos s) line) + for i from 0 to (1- (/ (length matches) 2)) + concat (format "\n %s'%s'" (format "Group %d: " i) + (match-string i)) + into ln1 + finally return (concat ln ln1)) + 'helm-realvalue s))) + +(defun helm-regexp-persistent-action (pt) + (helm-goto-char pt) + (helm-highlight-current-line)) + +(defun helm-regexp-kill-new (input) + (kill-new input) + (message "Killed: %s" input)) + +(defun helm-quote-whitespace (candidate) + "Quote whitespace, if some, in string CANDIDATE." + (replace-regexp-in-string " " "\\\\ " candidate)) + + +;;; Occur +;; +;; +(defvar helm-source-occur nil) +(defun helm-occur-init-source () + (unless helm-source-occur + (setq helm-source-occur + (helm-make-source "Occur" 'helm-source-multi-occur)))) + + +;;; Multi occur +;; +;; + +;; Internal +(defvar helm-multi-occur-buffer-list nil) +(defvar helm-multi-occur-buffer-tick nil) +(defun helm-moccur-init () + "Create the initial helm multi occur buffer." + (helm-init-candidates-in-buffer + 'global + (cl-loop with buffers = (helm-attr 'moccur-buffers) + for buf in buffers + for bufstr = (with-current-buffer buf (buffer-string)) + do (add-text-properties + 0 (length bufstr) + `(buffer-name ,(buffer-name (get-buffer buf))) + bufstr) + concat bufstr))) + +(defun helm-moccur--next-or-previous-char () + (save-excursion + (or (re-search-forward "^." nil t) + (re-search-backward "^." nil t)))) + +(defun helm-moccur-get-line (beg end) + "Format line for `helm-source-moccur'." + (prog1 + (format "%s:%d:%s" + (get-text-property (if (= beg end) + (helm-moccur--next-or-previous-char) + beg) + 'buffer-name) + (save-restriction + (narrow-to-region (or (previous-single-property-change + (point) 'buffer-name) 1) + (or (next-single-property-change + (if (= beg end) + (helm-moccur--next-or-previous-char) + (point)) + 'buffer-name) + (point-max))) + (line-number-at-pos beg)) + ;; When matching empty line, use empty string + ;; to allow saving and modifying with wgrep. + (if (= beg end) "" (buffer-substring beg end))) + ;; When matching empty line, forward char ("\n") + ;; to not be blocked forever here. + (when (= beg end) (forward-char 1)))) + +(cl-defun helm-moccur-action (candidate + &optional (method (quote buffer)) mark) + "Jump to CANDIDATE with METHOD. +arg METHOD can be one of buffer, buffer-other-window, buffer-other-frame." + (require 'helm-grep) + (let* ((split (helm-grep-split-line candidate)) + (buf (car split)) + (lineno (string-to-number (nth 1 split))) + (split-pat (helm-mp-split-pattern helm-pattern))) + (cl-case method + (buffer (switch-to-buffer buf)) + (buffer-other-window (switch-to-buffer-other-window buf)) + (buffer-other-frame (switch-to-buffer-other-frame buf))) + (helm-goto-line lineno) + ;; Move point to the nearest matching regexp from bol. + (cl-loop for reg in split-pat + when (save-excursion + (condition-case _err + (re-search-forward reg (point-at-eol) t) + (invalid-regexp nil))) + collect (match-beginning 0) into pos-ls + finally (when pos-ls (goto-char (apply #'min pos-ls)))) + (when mark + (set-marker (mark-marker) (point)) + (push-mark (point) 'nomsg)))) + +(defun helm-moccur-persistent-action (candidate) + (helm-moccur-goto-line candidate) + (helm-highlight-current-line)) + +(defun helm-moccur-goto-line (candidate) + "From multi occur, switch to buffer and go to nth 1 CANDIDATE line." + (helm-moccur-action + candidate 'buffer (or current-prefix-arg ; persistent. + helm-current-prefix-arg))) ; exit. + +(defun helm-moccur-goto-line-ow (candidate) + "Go to CANDIDATE line in other window. +Same as `helm-moccur-goto-line' but go in other window." + (helm-moccur-action + candidate 'buffer-other-window + (or current-prefix-arg ; persistent. + helm-current-prefix-arg))) ; exit. + +(defun helm-moccur-goto-line-of (candidate) + "Go to CANDIDATE line in new frame. +Same as `helm-moccur-goto-line' but go in new frame." + (helm-moccur-action + candidate 'buffer-other-frame + (or current-prefix-arg ; persistent. + helm-current-prefix-arg))) ; exit. + +(defun helm-moccur-run-goto-line-ow () + "Run goto line other window action from `helm-source-moccur'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-moccur-goto-line-ow))) + +(defun helm-moccur-run-goto-line-of () + "Run goto line new frame action from `helm-source-moccur'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-moccur-goto-line-of))) + +(defun helm-moccur-run-default-action () + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-moccur-goto-line))) + +(defvar helm-source-moccur nil) +(defclass helm-source-multi-occur (helm-source-in-buffer) + ((init :initform (lambda () + (require 'helm-grep) + (helm-moccur-init))) + (filter-one-by-one :initform 'helm-moccur-filter-one-by-one) + (get-line :initform helm-moccur-get-line) + (nohighlight :initform t) + (migemo :initform t) + (action :initform '(("Go to Line" . helm-moccur-goto-line) + ("Goto line other window" . helm-moccur-goto-line-ow) + ("Goto line new frame" . helm-moccur-goto-line-of))) + (persistent-action :initform 'helm-moccur-persistent-action) + (persistent-help :initform "Go to line") + (recenter :initform t) + (resume :initform 'helm-moccur-resume-fn) + (candidate-number-limit :initform 9999) + (mode-line :initform helm-moccur-mode-line) + (keymap :initform helm-moccur-map) + (history :initform 'helm-grep-history) + (requires-pattern :initform 2))) + +(defun helm-moccur-resume-fn () + (with-helm-buffer + (let (new-tick-ls buffer-is-modified) + (set (make-local-variable 'helm-multi-occur-buffer-list) + (cl-loop for b in helm-multi-occur-buffer-list + when (buffer-live-p (get-buffer b)) + collect b)) + (setq buffer-is-modified (/= (length helm-multi-occur-buffer-list) + (length (helm-attr 'moccur-buffers)))) + (helm-attrset 'moccur-buffers helm-multi-occur-buffer-list) + (setq new-tick-ls (cl-loop for b in helm-multi-occur-buffer-list + collect (buffer-chars-modified-tick (get-buffer b)))) + (when buffer-is-modified + (setq helm-multi-occur-buffer-tick new-tick-ls)) + (cl-assert (> (length helm-multi-occur-buffer-list) 0) nil + "helm-resume error: helm-(m)occur buffer list is empty") + (unless (eq helm-moccur-auto-update-on-resume 'never) + (when (or buffer-is-modified + (cl-loop for b in helm-multi-occur-buffer-list + for new-tick = (buffer-chars-modified-tick (get-buffer b)) + for tick in helm-multi-occur-buffer-tick + thereis (/= tick new-tick))) + (helm-aif helm-moccur-auto-update-on-resume + (when (or (eq it 'noask) + (y-or-n-p "Helm (m)occur Buffer outdated, update? ")) + (run-with-idle-timer 0.1 nil (lambda () + (with-helm-buffer + (helm-force-update) + (message "Helm (m)occur Buffer have been udated") + (sit-for 1) (message nil)))) + (unless buffer-is-modified (setq helm-multi-occur-buffer-tick new-tick-ls))) + (run-with-idle-timer 0.1 nil (lambda () + (with-helm-buffer + (let ((ov (make-overlay (save-excursion + (goto-char (point-min)) + (forward-line 1) + (point)) + (point-max)))) + (overlay-put ov 'face 'helm-resume-need-update) + (sit-for 0.3) (delete-overlay ov) + (message "[Helm occur Buffer outdated (C-c C-u to update)]"))))) + (unless buffer-is-modified + (with-helm-after-update-hook + (setq helm-multi-occur-buffer-tick new-tick-ls) + (message "Helm (m)occur Buffer have been udated"))))))))) + +(defun helm-moccur-filter-one-by-one (candidate) + "`filter-one-by-one' function for `helm-source-moccur'." + (require 'helm-grep) + (let* ((split (helm-grep-split-line candidate)) + (buf (car split)) + (lineno (nth 1 split)) + (str (nth 2 split))) + (cons (concat (propertize + buf + 'face 'helm-moccur-buffer + 'help-echo (buffer-file-name + (get-buffer buf)) + 'buffer-name buf) + ":" + (propertize lineno 'face 'helm-grep-lineno) + ":" + (helm-grep-highlight-match str t)) + candidate))) + +(defun helm-multi-occur-1 (buffers &optional input) + "Main function to call `helm-source-moccur' with BUFFERS list." + (let ((bufs (if helm-moccur-always-search-in-current + (cons + ;; will become helm-current-buffer later. + (buffer-name (current-buffer)) + (remove helm-current-buffer buffers)) + buffers))) + (unless helm-source-moccur + (setq helm-source-moccur + (helm-make-source "Moccur" 'helm-source-multi-occur))) + (helm-attrset 'moccur-buffers bufs helm-source-moccur) + (helm-set-local-variable 'helm-multi-occur-buffer-list bufs) + (helm-set-local-variable + 'helm-multi-occur-buffer-tick + (cl-loop for b in bufs + collect (buffer-chars-modified-tick (get-buffer b))))) + (helm :sources 'helm-source-moccur + :buffer "*helm multi occur*" + :history 'helm-grep-history + :input input + :truncate-lines t)) + +;;;###autoload +(defun helm-moccur-run-save-buffer () + "Run grep save results action from `helm-do-grep-1'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action 'helm-moccur-save-results))) + + +;;; helm-moccur-mode +;; +;; +(defvar helm-moccur-mode-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "RET") 'helm-moccur-mode-goto-line) + (define-key map (kbd "C-o") 'helm-moccur-mode-goto-line-ow) + (define-key map (kbd "") 'undefined) + (define-key map (kbd "") 'undefined) + (define-key map (kbd "") 'helm-gm-next-file) + (define-key map (kbd "") 'helm-gm-precedent-file) + map)) + +(defun helm-moccur-mode-goto-line () + (interactive) + (helm-moccur-goto-line + (buffer-substring (point-at-bol) (point-at-eol)))) + +(defun helm-moccur-mode-goto-line-ow () + (interactive) + (helm-moccur-goto-line-ow + (buffer-substring (point-at-bol) (point-at-eol)))) + +(defun helm-moccur-save-results (_candidate) + "Save helm moccur results in a `helm-moccur-mode' buffer." + (let ((buf "*hmoccur*") + new-buf) + (when (get-buffer buf) + (setq new-buf (helm-read-string "OccurBufferName: " buf)) + (cl-loop for b in (helm-buffer-list) + when (and (string= new-buf b) + (not (y-or-n-p + (format "Buffer `%s' already exists overwrite? " + new-buf)))) + do (setq new-buf (helm-read-string "OccurBufferName: " "*hmoccur "))) + (setq buf new-buf)) + (with-current-buffer (get-buffer-create buf) + (setq buffer-read-only t) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert "-*- mode: helm-moccur -*-\n\n" + (format "Moccur Results for `%s':\n\n" helm-pattern)) + (save-excursion + (insert (with-current-buffer helm-buffer + (goto-char (point-min)) (forward-line 1) + (buffer-substring (point) (point-max)))))) + (helm-moccur-mode) (pop-to-buffer buf)) + (message "Helm Moccur Results saved in `%s' buffer" buf))) + +;;;###autoload +(define-derived-mode helm-moccur-mode + special-mode "helm-moccur" + "Major mode to provide actions in helm moccur saved buffer. + +Special commands: +\\{helm-moccur-mode-map}" + (set (make-local-variable 'helm-multi-occur-buffer-list) + (with-helm-buffer helm-multi-occur-buffer-list)) + (set (make-local-variable 'revert-buffer-function) + #'helm-moccur-mode--revert-buffer-function)) + +(defun helm-moccur-mode--revert-buffer-function (&optional _ignore-auto _noconfirm) + (goto-char (point-min)) + (let (pattern) + (when (re-search-forward "^Moccur Results for `\\(.*\\)'" nil t) + (setq pattern (match-string 1)) + (forward-line 0) + (when (re-search-forward "^$" nil t) + (forward-line 1)) + (let ((inhibit-read-only t) + (buffer (current-buffer)) + (buflst helm-multi-occur-buffer-list)) + (delete-region (point) (point-max)) + (message "Reverting buffer...") + (save-excursion + (with-temp-buffer + (insert + "\n" + (cl-loop for buf in buflst + for bufstr = (or (and (buffer-live-p (get-buffer buf)) + (with-current-buffer buf + (buffer-string))) + "") + unless (string= bufstr "") + do (add-text-properties + 0 (length bufstr) + `(buffer-name ,(buffer-name (get-buffer buf))) + bufstr) + concat bufstr) + "\n") + (goto-char (point-min)) + (cl-loop while (re-search-forward pattern nil t) + for line = (helm-moccur-get-line (point-at-bol) (point-at-eol)) + when line + do (with-current-buffer buffer + (insert + (propertize + (car (helm-moccur-filter-one-by-one line)) + 'helm-real-value line) + "\n"))))) + (message "Reverting buffer done"))))) + + +;;; Predefined commands +;; +;; + +;;;###autoload +(defun helm-regexp () + "Preconfigured helm to build regexps. +`query-replace-regexp' can be run from there against found regexp." + (interactive) + (save-restriction + (when (and (helm-region-active-p) + ;; Don't narrow to region if buffer is already narrowed. + (not (helm-current-buffer-narrowed-p (current-buffer)))) + (narrow-to-region (region-beginning) (region-end))) + (helm :sources helm-source-regexp + :buffer "*helm regexp*" + :prompt "Regexp: " + :history 'helm-build-regexp-history))) + +;;;###autoload +(defun helm-occur () + "Preconfigured helm for Occur." + (interactive) + (helm-occur-init-source) + (let ((bufs (list (buffer-name (current-buffer))))) + (helm-attrset 'moccur-buffers bufs helm-source-occur) + (helm-set-local-variable 'helm-multi-occur-buffer-list bufs) + (helm-set-local-variable + 'helm-multi-occur-buffer-tick + (cl-loop for b in bufs + collect (buffer-chars-modified-tick (get-buffer b))))) + (helm :sources 'helm-source-occur + :buffer "*helm occur*" + :history 'helm-grep-history + :preselect (and (memq 'helm-source-occur helm-sources-using-default-as-input) + (format "%s:%d:" (buffer-name) (line-number-at-pos (point)))) + :truncate-lines t)) + +;;;###autoload +(defun helm-occur-from-isearch () + "Invoke `helm-occur' from isearch." + (interactive) + (let ((input (if isearch-regexp + isearch-string + (regexp-quote isearch-string))) + (bufs (list (buffer-name (current-buffer))))) + (isearch-exit) + (helm-occur-init-source) + (helm-attrset 'moccur-buffers bufs helm-source-occur) + (helm-set-local-variable 'helm-multi-occur-buffer-list bufs) + (helm-set-local-variable + 'helm-multi-occur-buffer-tick + (cl-loop for b in bufs + collect (buffer-chars-modified-tick (get-buffer b)))) + (helm :sources 'helm-source-occur + :buffer "*helm occur*" + :history 'helm-grep-history + :input input + :truncate-lines t))) + +;;;###autoload +(defun helm-multi-occur (buffers) + "Preconfigured helm for multi occur. + + BUFFERS is a list of buffers to search through. +With a prefix arg, reverse the behavior of +`helm-moccur-always-search-in-current'. +The prefix arg can be set before calling `helm-multi-occur' +or during the buffer selection." + (interactive (list (helm-comp-read + "Buffers: " (helm-buffer-list) + :marked-candidates t))) + (let ((helm-moccur-always-search-in-current + (if (or current-prefix-arg + helm-current-prefix-arg) + (not helm-moccur-always-search-in-current) + helm-moccur-always-search-in-current))) + (helm-multi-occur-1 buffers))) + +;;;###autoload +(defun helm-multi-occur-from-isearch (&optional _arg) + "Invoke `helm-multi-occur' from isearch. + +With a prefix arg, reverse the behavior of +`helm-moccur-always-search-in-current'. +The prefix arg can be set before calling +`helm-multi-occur-from-isearch' or during the buffer selection." + (interactive "p") + (let (buf-list + helm-moccur-always-search-in-current + (input (if isearch-regexp + isearch-string + (regexp-quote isearch-string)))) + (isearch-exit) + (setq buf-list (helm-comp-read "Buffers: " + (helm-buffer-list) + :name "Occur in buffer(s)" + :marked-candidates t)) + (setq helm-moccur-always-search-in-current + (if (or current-prefix-arg + helm-current-prefix-arg) + (not helm-moccur-always-search-in-current) + helm-moccur-always-search-in-current)) + (helm-multi-occur-1 buf-list input))) + + +(provide 'helm-regexp) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-regexp.el ends here diff --git a/elpa/helm-20150403.101/helm-ring.el b/elpa/helm-20150403.101/helm-ring.el new file mode 100644 index 00000000..a43895c6 --- /dev/null +++ b/elpa/helm-20150403.101/helm-ring.el @@ -0,0 +1,416 @@ +;;; helm-ring.el --- kill-ring, mark-ring, and register browsers for helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) +(require 'helm-elisp) + +(declare-function undo-tree-restore-state-from-register "ext:undo-tree.el" (register)) + + +(defgroup helm-ring nil + "Ring related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-kill-ring-threshold 3 + "Minimum length of a candidate to be listed by `helm-source-kill-ring'." + :type 'integer + :group 'helm-ring) + +(defcustom helm-kill-ring-max-lines-number 5 + "Max number of lines displayed per candidate in kill-ring browser. +If nil or zero (disabled), don't truncate candidate, show all." + :type '(choice (const :tag "Disabled" nil) + (integer :tag "Max number of lines")) + :group 'helm-ring) + +(defcustom helm-register-max-offset 160 + "Max size of string register entries before truncating." + :group 'helm-ring + :type 'integer) + + +;;; Kill ring +;; +;; +(defvar helm-kill-ring-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-y") 'helm-next-line) + (define-key map (kbd "M-u") 'helm-previous-line) + map) + "Keymap for `helm-show-kill-ring'.") + +(defvar helm-source-kill-ring + (helm-build-sync-source "Kill Ring" + :init (lambda () (helm-attrset 'last-command last-command)) + :candidates #'helm-kill-ring-candidates + :filtered-candidate-transformer #'helm-kill-ring-transformer + :action '(("Yank" . helm-kill-ring-action) + ("Delete" . (lambda (candidate) + (cl-loop for cand in (helm-marked-candidates) + do (setq kill-ring + (delete cand kill-ring)))))) + :persistent-action (lambda (_candidate) (ignore)) + :persistent-help "DoNothing" + :keymap helm-kill-ring-map + :migemo t + :multiline t) + "Source for browse and insert contents of kill-ring.") + +(defun helm-kill-ring-candidates () + (cl-loop for kill in (helm-fast-remove-dups kill-ring :test 'equal) + unless (or (< (length kill) helm-kill-ring-threshold) + (string-match "\\`[\n[:blank:]]+\\'" kill)) + collect kill)) + +(defun helm-kill-ring-transformer (candidates _source) + "Display only the `helm-kill-ring-max-lines-number' lines of candidate." + (cl-loop for i in candidates + when (get-text-property 0 'read-only i) + do (set-text-properties 0 (length i) '(read-only nil) i) + for nlines = (with-temp-buffer (insert i) (count-lines (point-min) (point-max))) + if (and helm-kill-ring-max-lines-number + (> nlines helm-kill-ring-max-lines-number)) + collect (cons + (with-temp-buffer + (insert i) + (goto-char (point-min)) + (concat + (buffer-substring + (point-min) + (save-excursion + (forward-line helm-kill-ring-max-lines-number) + (point))) + "[...]")) i) + else collect i)) + +(defun helm-kill-ring-action (str) + "Insert STR in `kill-ring' and set STR to the head. +If this action is executed just after `yank', +replace with STR as yanked string." + (with-helm-current-buffer + (setq kill-ring (delete str kill-ring)) + (if (not (eq (helm-attr 'last-command helm-source-kill-ring) 'yank)) + (run-with-timer 0.01 nil `(lambda () (insert-for-yank ,str))) + ;; from `yank-pop' + (let ((inhibit-read-only t) + (before (< (point) (mark t)))) + (if before + (funcall (or yank-undo-function 'delete-region) (point) (mark t)) + (funcall (or yank-undo-function 'delete-region) (mark t) (point))) + (setq yank-undo-function nil) + (set-marker (mark-marker) (point) helm-current-buffer) + (run-with-timer 0.01 nil `(lambda () (insert-for-yank ,str))) + ;; Set the window start back where it was in the yank command, + ;; if possible. + (set-window-start (selected-window) yank-window-start t) + (when before + ;; This is like exchange-point-and-mark, but doesn't activate the mark. + ;; It is cleaner to avoid activation, even though the command + ;; loop would deactivate the mark because we inserted text. + (goto-char (prog1 (mark t) + (set-marker (mark-marker) (point) helm-current-buffer)))))) + (kill-new str))) + + + + +;;;; +;; DO NOT use these sources with other sources use +;; the commands `helm-mark-ring', `helm-global-mark-ring' or +;; `helm-all-mark-rings' instead. + +(defun helm-mark-ring-get-marks (pos) + (save-excursion + (goto-char pos) + (forward-line 0) + (let ((line (car (split-string (thing-at-point 'line) "[\n\r]")))) + (when (string= "" line) + (setq line "")) + (format "%7d: %s" (line-number-at-pos) line)))) + +(defun helm-mark-ring-get-candidates () + (with-helm-current-buffer + (cl-loop with marks = (if (mark t) (cons (mark-marker) mark-ring) mark-ring) + for i in marks + for m = (helm-mark-ring-get-marks i) + unless (and recip (member m recip)) + collect m into recip + finally return recip))) + +(defvar helm-source-mark-ring + (helm-build-sync-source "mark-ring" + :candidates #'helm-mark-ring-get-candidates + :action '(("Goto line" + . (lambda (candidate) + (helm-goto-line (string-to-number candidate))))) + :persistent-action (lambda (candidate) + (helm-goto-line (string-to-number candidate)) + (helm-highlight-current-line)) + :persistent-help "Show this line")) + + +;;; Global-mark-ring +(defvar helm-source-global-mark-ring + (helm-build-sync-source "global-mark-ring" + :candidates #'helm-global-mark-ring-get-candidates + :action '(("Goto line" + . (lambda (candidate) + (let ((items (split-string candidate ":"))) + (switch-to-buffer (cl-second items)) + (helm-goto-line (string-to-number (car items))))))) + :persistent-action (lambda (candidate) + (let ((items (split-string candidate ":"))) + (switch-to-buffer (cl-second items)) + (helm-goto-line (string-to-number (car items))) + (helm-highlight-current-line))) + :persistent-help "Show this line")) + +(defun helm-global-mark-ring-format-buffer (marker) + (with-current-buffer (marker-buffer marker) + (goto-char marker) + (forward-line 0) + (let (line) + (if (string= "" line) + (setq line "") + (setq line (car (split-string (thing-at-point 'line) + "[\n\r]")))) + (format "%7d:%s: %s" + (line-number-at-pos) (marker-buffer marker) line)))) + +(defun helm-global-mark-ring-get-candidates () + (let ((marks global-mark-ring)) + (when marks + (cl-loop for i in marks + for gm = (unless (or (string-match + "^ " (format "%s" (marker-buffer i))) + (null (marker-buffer i))) + (helm-global-mark-ring-format-buffer i)) + when (and gm (not (member gm recip))) + collect gm into recip + finally return recip)))) + + +;;;; +;;; Insert from register +(defvar helm-source-register + (helm-build-sync-source "Registers" + :candidates #'helm-register-candidates + :action-transformer #'helm-register-action-transformer + :multiline t + :action nil) + "See (info \"(emacs)Registers\")") + +(defun helm-register-candidates () + "Collecting register contents and appropriate commands." + (cl-loop for (char . val) in register-alist + for key = (single-key-description char) + for string-actions = + (cond + ((numberp val) + (list (int-to-string val) + 'insert-register + 'increment-register)) + ((markerp val) + (let ((buf (marker-buffer val))) + (if (null buf) + (list "a marker in no buffer") + (list (concat + "a buffer position:" + (buffer-name buf) + ", position " + (int-to-string (marker-position val))) + 'jump-to-register + 'insert-register)))) + ((and (consp val) (window-configuration-p (car val))) + (list "window configuration." + 'jump-to-register)) + ((and (vectorp val) + (fboundp 'undo-tree-register-data-p) + (undo-tree-register-data-p (elt val 1))) + (list + "Undo-tree entry." + 'undo-tree-restore-state-from-register)) + ((or (and (vectorp val) (eq 'registerv (aref val 0))) + (and (consp val) (frame-configuration-p (car val)))) + (list "frame configuration." + 'jump-to-register)) + ((and (consp val) (eq (car val) 'file)) + (list (concat "file:" + (prin1-to-string (cdr val)) + ".") + 'jump-to-register)) + ((and (consp val) (eq (car val) 'file-query)) + (list (concat "file:a file-query reference: file " + (car (cdr val)) + ", position " + (int-to-string (car (cdr (cdr val)))) + ".") + 'jump-to-register)) + ((consp val) + (let ((lines (format "%4d" (length val)))) + (list (format "%s: %s\n" lines + (truncate-string-to-width + (mapconcat 'identity (list (car val)) + "^J") (- (window-width) 15))) + 'insert-register))) + ((stringp val) + (list + ;; without properties + (concat (substring-no-properties + val 0 (min (length val) helm-register-max-offset)) + (if (> (length val) helm-register-max-offset) + "[...]" "")) + 'insert-register + 'append-to-register + 'prepend-to-register)) + (t + "GARBAGE!")) + collect (cons (format "Register %3s:\n %s" key (car string-actions)) + (cons char (cdr string-actions))))) + +(defun helm-register-action-transformer (_actions register-and-functions) + "Decide actions by the contents of register." + (cl-loop with func-actions = + '((insert-register + "Insert Register" . + (lambda (c) (insert-register (car c)))) + (jump-to-register + "Jump to Register" . + (lambda (c) (jump-to-register (car c)))) + (append-to-register + "Append Region to Register" . + (lambda (c) (append-to-register + (car c) (region-beginning) (region-end)))) + (prepend-to-register + "Prepend Region to Register" . + (lambda (c) (prepend-to-register + (car c) (region-beginning) (region-end)))) + (increment-register + "Increment Prefix Arg to Register" . + (lambda (c) (increment-register + helm-current-prefix-arg (car c)))) + (undo-tree-restore-state-from-register + "Restore Undo-tree register" + (lambda (c) (and (fboundp 'undo-tree-restore-state-from-register) + (undo-tree-restore-state-from-register (car c)))))) + for func in (cdr register-and-functions) + for cell = (assq func func-actions) + when cell + collect (cdr cell))) + +;;;###autoload +(defun helm-mark-ring () + "Preconfigured `helm' for `helm-source-mark-ring'." + (interactive) + (helm :sources 'helm-source-mark-ring + :resume 'noresume + :buffer "*helm mark*")) + +;;;###autoload +(defun helm-global-mark-ring () + "Preconfigured `helm' for `helm-source-global-mark-ring'." + (interactive) + (helm :sources 'helm-source-global-mark-ring + :resume 'noresume + :buffer "*helm global mark*")) + +;;;###autoload +(defun helm-all-mark-rings () + "Preconfigured `helm' for `helm-source-global-mark-ring' and \ +`helm-source-mark-ring'." + (interactive) + (helm :sources '(helm-source-mark-ring + helm-source-global-mark-ring) + :resume 'noresume + :buffer "*helm mark ring*")) + +;;;###autoload +(defun helm-register () + "Preconfigured `helm' for Emacs registers." + (interactive) + (helm :sources 'helm-source-register + :resume 'noresume + :buffer "*helm register*")) + +;;;###autoload +(defun helm-show-kill-ring () + "Preconfigured `helm' for `kill-ring'. +It is drop-in replacement of `yank-pop'. + +First call open the kill-ring browser, next calls move to next line." + (interactive) + (let ((enable-recursive-minibuffers t)) + (helm :sources helm-source-kill-ring + :buffer "*helm kill ring*" + :resume 'noresume + :allow-nest t))) + +(defvar helm-kmacro-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-kmacro-help) + map)) + +;;;###autoload +(defun helm-execute-kmacro () + "Keyboard macros with helm interface. +Define your macros with `f3' and `f4'. +See (info \"(emacs) Keyboard Macros\") for detailed infos. +This command is useful when used with persistent action." + (interactive) + (helm :sources + (helm-build-sync-source "Kmacro" + :candidates (lambda () + (helm-fast-remove-dups + (cons (kmacro-ring-head) + kmacro-ring) + :test 'equal)) + :multiline t + :keymap helm-kmacro-map + :candidate-transformer + (lambda (candidates) + (cl-loop for c in candidates collect + (propertize (help-key-description (car c) nil) + 'helm-realvalue c))) + :persistent-help "Execute kmacro" + :action + (helm-make-actions + "Execute kmacro (`C-u ' to execute times)" + (lambda (candidate) + (interactive) + ;; Move candidate on top of list for next use. + (setq kmacro-ring (delete candidate kmacro-ring)) + (kmacro-push-ring) + (kmacro-split-ring-element candidate) + (kmacro-exec-ring-item + candidate helm-current-prefix-arg)))) + :buffer "*helm kmacro*")) + +(provide 'helm-ring) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-ring.el ends here diff --git a/elpa/helm-20150403.101/helm-semantic.el b/elpa/helm-20150403.101/helm-semantic.el new file mode 100644 index 00000000..db68f013 --- /dev/null +++ b/elpa/helm-20150403.101/helm-semantic.el @@ -0,0 +1,209 @@ +;;; helm-semantic.el --- Helm interface for Semantic -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 Daniel Hackney +;; Author: Daniel Hackney + +;; 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: + +;; Uses `candidates-in-buffer' for speed. + +;;; Code: + +(require 'cl-lib) +(require 'semantic) +(require 'helm-imenu) + +(declare-function pulse-momentary-highlight-one-line "pulse.el" (point &optional face)) + +(defgroup helm-semantic nil + "Semantic tags related libraries and applications for helm." + :group 'helm) + +(defcustom helm-semantic-lynx-style-map t + "Use Arrow keys to jump to occurences." + :group 'helm-semantic + :type 'boolean) + +;;; keymap +(defvar helm-semantic-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-semantic-help) + (when helm-imenu-lynx-style-map + (define-key map (kbd "") 'helm-maybe-exit-minibuffer) + (define-key map (kbd "") 'helm-execute-persistent-action)) + (delq nil map))) + +;; Internals vars +(defvar helm-semantic--tags-cache nil) + +(defcustom helm-semantic-display-style 'semantic-format-tag-summarize + "Function to present a semantic tag." + :group 'helm-semantic + :type '(radio + (const :tag "Default" semantic-format-tag-summarize) + (const :tag "Prototype" semantic-format-tag-prototype))) + +(defun helm-semantic--fetch-candidates (tags depth &optional class) + "Write the contents of TAGS to the current buffer." + (let ((class class) cur-type) + (cl-dolist (tag tags) + (when (listp tag) + (cl-case (setq cur-type (semantic-tag-class tag)) + ((function variable type) + (let ((spaces (make-string (* depth 2) ?\s)) + (type-p (eq cur-type 'type))) + (unless (and (> depth 0) (not type-p)) + (setq class nil)) + (insert + (if (and class (not type-p)) + (format "%s%s(%s) " + spaces (if (< depth 2) "" "├►") class) + spaces) + ;; Save the tag for later + (propertize (funcall helm-semantic-display-style tag nil t) + 'semantic-tag tag) + "\n") + (and type-p (setq class (car tag))) + ;; Recurse to children + (unless (eq cur-type 'function) + (helm-semantic--fetch-candidates + (semantic-tag-components tag) (1+ depth) class)))) + + ;; Don't do anything with packages or includes for now + ((package include) + (insert + (propertize (funcall helm-semantic-display-style tag nil t) + 'semantic-tag tag) + "\n") + ) + ;; Catch-all + (t)))))) + +(defun helm-semantic-default-action (_candidate &optional persistent) + ;; By default, helm doesn't pass on the text properties of the selection. + ;; Fix this. + (helm-log-run-hook 'helm-goto-line-before-hook) + (with-current-buffer helm-buffer + (when (looking-at " ") + (goto-char (next-single-property-change + (point-at-bol) 'semantic-tag nil (point-at-eol)))) + (let ((tag (get-text-property (point) 'semantic-tag))) + (semantic-go-to-tag tag) + (unless persistent + (pulse-momentary-highlight-one-line (point)))))) + +(defun helm-semantic--maybe-set-needs-update () + (with-helm-current-buffer + (let ((tick (buffer-modified-tick))) + (unless (eq helm-cached-imenu-tick tick) + (setq helm-cached-imenu-tick tick) + (semantic-parse-tree-set-needs-update))))) + +(defvar helm-source-semantic nil) + +(defclass helm-semantic-source (helm-source-in-buffer) + ((init :initform (lambda () + (helm-semantic--maybe-set-needs-update) + (setq helm-semantic--tags-cache (semantic-fetch-tags)) + (with-current-buffer (helm-candidate-buffer 'global) + (let ((major-mode (with-helm-current-buffer major-mode))) + (helm-semantic--fetch-candidates helm-semantic--tags-cache 0))))) + (get-line :initform 'buffer-substring) + (persistent-help :initform "Show this entry") + (keymap :initform 'helm-semantic-map) + (mode-line :initform helm-semantic-mode-line) + (persistent-action :initform (lambda (elm) + (helm-semantic-default-action elm t) + (helm-highlight-current-line))) + (action :initform 'helm-semantic-default-action))) + +(defcustom helm-semantic-fuzzy-match nil + "Enable fuzzy matching in `helm-source-semantic'." + :group 'helm-semantic + :type 'boolean + :set (lambda (var val) + (set var val) + (setq helm-source-semantic + (helm-make-source "Semantic Tags" 'helm-semantic-source + :fuzzy-match helm-semantic-fuzzy-match)))) + +;;;###autoload +(defun helm-semantic (arg) + "Preconfigured `helm' for `semantic'. +If ARG is supplied, pre-select symbol at point instead of current" + (interactive "P") + (let ((tag (helm-aif (semantic-current-tag-parent) + (cons (format "\\_<%s\\_>" (car it)) + (format "\\_<%s\\_>" (car (semantic-current-tag)))) + (format "\\_<%s\\_>" (car (semantic-current-tag)))))) + (unless helm-source-semantic + (setq helm-source-semantic + (helm-make-source "Semantic Tags" 'helm-semantic-source + :fuzzy-match helm-semantic-fuzzy-match))) + (helm :sources 'helm-source-semantic + :candidate-number-limit 9999 + :preselect (if arg + (thing-at-point 'symbol) + tag) + :buffer "*helm semantic*"))) + +;;;###autoload +(defun helm-semantic-or-imenu (arg) + "Run `helm' with `semantic' or `imenu'. +If ARG is supplied, pre-select symbol at point instead of current +semantic tag in scope. + +If `semantic-mode' is active in the current buffer, then use +semantic for generating tags, otherwise fall back to `imenu'. +Fill in the symbol at point by default." + (interactive "P") + (unless helm-source-semantic + (setq helm-source-semantic + (helm-make-source "Semantic Tags" 'helm-semantic-source + :fuzzy-match helm-semantic-fuzzy-match))) + (unless helm-source-imenu + (setq helm-source-imenu + (helm-make-source "Imenu" 'helm-imenu-source + :fuzzy-match helm-imenu-fuzzy-match))) + (let* ((source (if (semantic-active-p) + 'helm-source-semantic + 'helm-source-imenu)) + (imenu-p (eq source 'helm-source-imenu)) + (imenu-auto-rescan imenu-p) + (helm-execute-action-at-once-if-one + (and imenu-p + helm-imenu-execute-action-at-once-if-one)) + (tag (helm-aif (semantic-current-tag-parent) + (cons (format "\\_<%s\\_>" (car it)) + (format "\\_<%s\\_>" (car (semantic-current-tag)))) + (format "\\_<%s\\_>" (car (semantic-current-tag)))))) + (helm :sources source + :candidate-number-limit 9999 + :preselect (if (or arg imenu-p) + (thing-at-point 'symbol) + tag) + :buffer "*helm semantic/imenu*"))) + +(provide 'helm-semantic) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-semantic.el ends here diff --git a/elpa/helm-20150403.101/helm-source.el b/elpa/helm-20150403.101/helm-source.el new file mode 100644 index 00000000..e229dcec --- /dev/null +++ b/elpa/helm-20150403.101/helm-source.el @@ -0,0 +1,1109 @@ +;;; helm-source.el --- Helm source creation. -*- lexical-binding: t -*- + +;; Copyright (C) 2015 Thierry Volpiatto + +;; Author: Thierry Volpiatto +;; URL: http://github.com/emacs-helm/helm + +;; 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: + +;; Interface to create helm sources easily. +;; Actually the eieo objects are transformed in alist for compatibility. +;; In the future this package should allow creating source as eieo objects +;; without conversion to alist, teaching helm to read such a structure. +;; The compatibility with alists would be kept. + +;;; Code: + +(require 'cl-lib) +(require 'eieio) + + +(defgeneric helm--setup-source (source) + "Prepare slots and handle slot errors before creating a helm source.") + +(defgeneric helm-setup-user-source (source) + "Allow users modifying slots in SOURCE just before creation.") + + +;;; Classes for sources +;; +;; +(defclass helm-source () + ((name + :initarg :name + :initform nil + :custom string + :documentation + " The name of the source. + A string which is also the heading which appears + above the list of matches from the source. Must be unique.") + + (header-name + :initarg :header-name + :initform nil + :custom function + :documentation + " A function returning the display string of the header. + Its argument is the name of the source. This attribute is useful to + add an additional information with the source name. + It doesn't modify the name of the source.") + + (init + :initarg :init + :initform nil + :custom function + :documentation + " Function called with no parameters when helm is started. + It is useful for collecting current state information which can be + used to create the list of candidates later. + Initialization of `candidates-in-buffer' is done here + with `helm-init-candidates-in-buffer'.") + + (candidates + :initarg :candidates + :initform nil + :custom (choice function list) + :documentation + " Specifies how to retrieve candidates from the source. + It can either be a variable name, a function called with no parameters + or the actual list of candidates. + + The list must be a list whose members are strings, symbols + or (DISPLAY . REAL) pairs. + + In case of (DISPLAY . REAL) pairs, the DISPLAY string is shown + in the Helm buffer, but the REAL one is used as action + argument when the candidate is selected. This allows a more + readable presentation for candidates which would otherwise be, + for example, too long or have a common part shared with other + candidates which can be safely replaced with an abbreviated + string for display purposes. + + Note that if the (DISPLAY . REAL) form is used then pattern + matching is done on the displayed string, not on the real + value.") + + (update + :initarg :update + :initform nil + :custom function + :documentation + " Function called with no parameters at before \"init\" function + when `helm-force-update' is called.") + + (cleanup + :initarg :cleanup + :initform nil + :custom function + :documentation + " Function called with no parameters when *helm* buffer is + closed. It is useful for killing unneeded candidates buffer. + + Note that the function is executed BEFORE performing action.") + + (delayed + :initarg :delayed + :initform nil + :custom (choice null integer) + :documentation + " Candidates from the source are shown only if the user stops + typing and is idle for `helm-idle-delay' seconds. + If a value is given to delayed attr, this value is used instead only + if it is > to `helm-idle-delay'.") + + (keymap + :initarg :keymap + :initform nil + :custom sexp + :documentation + " Specific keymap for this source. + It is useful to have a keymap per source when using more than + one source. Otherwise, a keymap can be set per command with + `helm' argument KEYMAP. NOTE: when a source have `helm-map' as + keymap attr, the global value of `helm-map' will override the + actual local one.") + + (action + :initarg :action + :initform 'identity + :custom (alist :key-type string + :value-type function) + :documentation + " It is a list of (DISPLAY . FUNCTION) pairs or FUNCTION. + FUNCTION is called with one parameter: the selected candidate. + + An action other than the default can be chosen from this list + of actions for the currently selected candidate (by default + with TAB). The DISPLAY string is shown in the completions + buffer and the FUNCTION is invoked when an action is + selected. The first action of the list is the default. + + You should use `helm-make-actions' to build this alist easily.") + + (persistent-action + :initarg :persistent-action + :initform nil + :custom function + :documentation + " Can be a either a Function called with one parameter (the + selected candidate) or a cons cell where first element is this + same function and second element a symbol (e.g never-split) + that inform `helm-execute-persistent-action'to not split his + window to execute this persistent action.") + + (persistent-help + :initarg :persistent-help + :initform nil + :custom string + :documentation + " A string to explain persistent-action of this source. It also + accepts a function or a variable name. + It will be displayed in source header.") + + (help-message + :initarg :help-message + :initform nil + :custom (choice string function) + :documentation + " Help message for this source. + If not present, `helm-help-message' value will be used.") + + (multiline + :initarg :multiline + :initform nil + :custom boolean + :documentation + " Enable to selection multiline candidates.") + + (requires-pattern + :initarg :requires-pattern + :initform nil + :custom integer + :documentation + " If present matches from the source are shown only if the + pattern is not empty. Optionally, it can have an integer + parameter specifying the required length of input which is + useful in case of sources with lots of candidates.") + + (candidate-transformer + :initarg :candidate-transformer + :initform nil + :custom (choice function list) + :documentation + " It's a function or a list of functions called with one argument + when the completion list from the source is built. The argument + is the list of candidates retrieved from the source. The + function should return a transformed list of candidates which + will be used for the actual completion. If it is a list of + functions, it calls each function sequentially. + + This can be used to transform or remove items from the list of + candidates. + + Note that `candidates' is run already, so the given transformer + function should also be able to handle candidates with (DISPLAY + . REAL) format.") + + (filtered-candidate-transformer + :initarg :filtered-candidate-transformer + :initform nil + :custom (choice function list) + :documentation + " It has the same format as `candidate-transformer', except the + function is called with two parameters: the candidate list and + the source. + + This transformer is run on the candidate list which is already + filtered by the current pattern. While `candidate-transformer' + is run only once, it is run every time the input pattern is + changed. + + It can be used to transform the candidate list dynamically, for + example, based on the current pattern. + + In some cases it may also be more efficent to perform candidate + transformation here, instead of with `candidate-transformer' + even if this transformation is done every time the pattern is + changed. For example, if a candidate set is very large then + `candidate-transformer' transforms every candidate while only + some of them will actually be displayed due to the limit + imposed by `helm-candidate-number-limit'. + + Note that `candidates' and `candidate-transformer' is run + already, so the given transformer function should also be able + to handle candidates with (DISPLAY . REAL) format.") + + (filter-one-by-one + :initarg :filter-one-by-one + :initform nil + :custom (choice function list) + :documentation + " A transformer function that treat candidates one by one. + It is called with one arg the candidate. + It is faster than `filtered-candidate-transformer' or + `candidates-transformer', but should be used only in sources + that recompute constantly their candidates, e.g `helm-source-find-files'. + Filtering happen early and candidates are treated + one by one instead of re-looping on the whole list. + If used with `filtered-candidate-transformer' or `candidates-transformer' + these functions should treat the candidates transformed by the + `filter-one-by-one' function in consequence.") + + (display-to-real + :initarg :display-to-real + :initform nil + :custom function + :documentation + " Function called with one parameter; the selected candidate. + + The function transforms the selected candidate, and the result + is passed to the action function. The display-to-real + attribute provides another way to pass to action other string than + the one shown in Helm buffer. + + Traditionally, it is possible to make candidates, + candidate-transformer or filtered-candidate-transformer + function return a list with (DISPLAY . REAL) pairs. But if REAL + can be generated from DISPLAY, display-to-real is more + convenient and faster. + + NOTE: This is deprecated and you have better time using `filter-one-by-one'.") + + (real-to-display + :initarg :real-to-display + :initform nil + :custom function + :documentation + " Function called with one parameter; the selected candidate. + The real value of candidates will be shown in display. + See `display-to-real'.") + + (action-transformer + :initarg :action-transformer + :initform nil + :custom (choice function list) + :documentation + " It's a function or a list of functions called with two + arguments when the action list from the source is + assembled. The first argument is the list of actions, the + second is the current selection. If it is a list of functions, + it calls each function sequentially. + + The function should return a transformed action list. + + This can be used to customize the list of actions based on the + currently selected candidate.") + + (pattern-transformer + :initarg :pattern-transformer + :initform nil + :custom (choice function list) + :documentation + " It's a function or a list of functions called with one argument + before computing matches. Its argument is `helm-pattern'. + Functions should return transformed `helm-pattern'. + + It is useful to change interpretation of `helm-pattern'.") + + (candidate-number-limit + :initarg :candidate-number-limit + :initform nil + :custom integer + :documentation + " Override `helm-candidate-number-limit' only for this source.") + + (volatile + :initarg :volatile + :initform nil + :custom boolean + :documentation + " Indicates the source assembles the candidate list dynamically, + so it shouldn't be cached within a single Helm + invocation. It is only applicable to synchronous sources, + because asynchronous sources are not cached.") + + (match + :initarg :match + :initform nil + :custom (choice function list) + :documentation + " List of functions called with one parameter: a candidate. The + function should return non-nil if the candidate matches the + current pattern (see variable `helm-pattern'). + + When using `candidates-in-buffer' its default value is `identity' and + don't have to be changed, use the `search' slot instead. + + This attribute allows the source to override the default + pattern matching based on `string-match'. It can be used, for + example, to implement a source for file names and do the + pattern matching on the basename of files, since it's more + likely one is typing part of the basename when searching for a + file, instead of some string anywhere else in its path. + + If the list contains more than one function then the list of + matching candidates from the source is constructed by appending + the results after invoking the first function on all the + potential candidates, then the next function, and so on. The + matching candidates supplied by the first function appear first + in the list of results and then results from the other + functions, respectively. + + This attribute has no effect for asynchronous sources (see + attribute `candidates'), since they perform pattern matching + themselves. + + Note that FUZZY-MATCH slot will overhide value of this slot.") + + (fuzzy-match + :initarg :fuzzy-match + :initform nil + :custom boolean + :documentation + " Enable fuzzy matching in this source. + This will overwrite settings in MATCH slot, and for + sources built with child class `helm-source-in-buffer' the SEARCH slot. + This is an easy way of enabling fuzzy matching, but you can use the MATCH + or SEARCH slots yourself if you want something more elaborated, mixing + different type of match (See `helm-source-buffers' class for example).") + + (nomark + :initarg :nomark + :initform nil + :custom boolean + :documentation + " Don't allow marking candidates when this attribute is present.") + + (nohighlight + :initarg :nohighlight + :initform nil + :custom boolean + :documentation + " Disable highlighting matches in this source. + This will disable generic highlighting of matches, + but some specialized highlighting can be done from elsewhere, + i.e from `filtered-candidate-transformer' or `filter-one-by-one' slots. + So use this to either disable completely highlighting in your source, + or to disable highlighting and use a specialized highlighting matches + function for this source. + Remember that this function should run AFTER all filter functions if those + filter functions are modifying face properties, though it is possible to + avoid this by using new `add-face-text-property' in your filter functions.") + + (allow-dups + :initarg :allow-dups + :initform nil + :custom boolean + :documentation + " Allow helm collecting duplicates candidates.") + + (recenter + :initarg :recenter + :initform nil + :custom boolean + :documentation + " `recenter' after jumping to candidate.") + + (history + :initarg :history + :initform nil + :custom symbol + :documentation + " Allow passing history variable to helm from source. + It should be a quoted symbol.") + + (coerce + :initarg :coerce + :initform nil + :custom function + :documentation + " It's a function called with one argument: the selected candidate. + This function is intended for type convertion. In normal case, + the selected candidate (string) is passed to action + function. If coerce function is specified, it is called just + before action function. + + Example: converting string to symbol + (coerce . intern)") + + (mode-line + :initarg :mode-line + :initform nil + :custom (choice string sexp) + :documentation + " Source local `helm-mode-line-string' (included in + `mode-line-format'). It accepts also variable/function name.") + + (header-line + :initarg :header-line + :initform nil + :custom (choice string function) + :documentation + " Source local `header-line-format'. + It accepts also variable/function name.") + + (resume + :initarg :resume + :initform nil + :custom function + :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 + `helm-buffer' is ready.") + + (follow + :initarg :follow + :initform nil + :custom integer + :documentation + " Enable `helm-follow-mode' for this source only. + You must give it a value of 1 or -1, though giving a -1 value + is surely not what you want, e.g: (follow . 1) + + See `helm-follow-mode' for more infos.") + + (follow-delay + :initarg :follow-delay + :initform nil + :custom integer + :documentation + " `helm-follow-mode' will execute persistent-action after this delay. + Otherwise value of `helm-follow-input-idle-delay' is used if non--nil, + If none of these are found fallback to `helm-input-idle-delay'.") + + (dont-plug + :initarg :dont-plug + :initform '(helm-compile-source--persistent-help) + :custom list + :documentation + " A list of compile functions plugin to ignore.") + + (migemo + :initarg :migemo + :initform nil + :custom boolean + :documentation + " Needed for Japanese input with helm-migemo.el. + If you are not Japanese, ignore this.") + + (matchplugin + :initarg :matchplugin + :initform t + :custom boolean) + + (match-part + :initarg :match-part + :initform nil + :custom function + :documentation + " Allow matching only one part of candidate. + If source contain match-part attribute, match is computed only + on part of candidate returned by the call of function provided + by this attribute. The function should have one arg, candidate, + and return only a specific part of candidate.") + + (before-init-hook + :initarg :before-init-hook + :initform nil + :custom symbol + :documentation + " A local hook that run at beginning of initilization of this source. + i.e Before the creation of `helm-buffer'.") + + (after-init-hook + :initarg :after-init-hook + :initform nil + :custom symbol + :documentation + " A local hook that run at end of initilization of this source. + i.e After the creation of `helm-buffer'.")) + + "Main interface to define helm sources." + :abstract t) + +(defclass helm-source-sync (helm-source) + ((candidates + :initform '("ERROR: You must specify the `candidates' slot, either with a list or a function")) + + (dont-plug + :initform '(helm-compile-source--match-plugin + helm-compile-source--persistent-help)) + + (match-strict + :initarg :match-strict + :initform nil + :custom function + :documentation + " When specifying a match function within a source and + helm-match-plugin is enabled, the result of all matching + functions will be concatened, which in some cases is not what + is wanted. When using `match-strict' only this or these + functions will be used. You can specify those functions as a + list of functions or a single symbol function. + + NOTE: This have the same effect as using :MATCHPLUGIN nil.")) + + "Use this class to make helm sources using a list of candidates. +This list should be given as a normal list, a variable handling a list +or a function returning a list. +Matching is done basically with `string-match' against each candidate.") + +(defclass helm-source-async (helm-source) + ((candidates-process + :initarg :candidates-process + :initform nil + :custom function + :documentation + " You should use this attribute when using a function involving + an async process instead of `candidates'. + The function must return a process.") + + (matchplugin :initform nil) + (dont-plug :initform '(helm-compile-source--match-plugin + helm-compile-source--persistent-help))) + + "Use this class to define a helm source calling an external process. +The :candidates slot is not allowed even if described because this class +inherit from `helm-source'.") + +(defclass helm-source-in-buffer (helm-source) + ((init + :initform 'helm-default-init-source-in-buffer-function) + + (data + :initarg :data + :initform nil + :custom (choice list string) + :documentation + " A string or a list that will be used to feed the `helm-candidates-buffer'. + This data will be passed in a function added to the init slot and + the buffer will be build with `helm-init-candidates-in-buffer'. + This is an easy and fast method to build a `candidates-in-buffer' source.") + + (dont-plug + :initform '(helm-compile-source--candidates-in-buffer + helm-compile-source--match-plugin + helm-compile-source--persistent-help)) + + (candidates + :initform 'helm-candidates-in-buffer) + + (volatile + :initform t) + + (match + :initform '(identity)) + + (get-line + :initarg :get-line + :initform 'buffer-substring-no-properties + :custom function + :documentation + " A function like `buffer-substring-no-properties' or `buffer-substring'. + This function converts point of line-beginning and point of line-end, + which represents a candidate computed by `helm-candidates-in-buffer'. + By default, `helm-candidates-in-buffer' uses + `buffer-substring-no-properties'.") + + (search + :initarg :search + :initform '(helm-candidates-in-buffer-search-default-fn) + :custom (choice function list) + :documentation + " List of functions like `re-search-forward' or `search-forward'. + Buffer search function used by `helm-candidates-in-buffer'. + By default, `helm-candidates-in-buffer' uses `re-search-forward'. + The function should take one arg PATTERN. + If your search function needs to handle negation like matchplugin, + this function should returns in such case a cons cell of two integers defining + the beg and end positions to match in the line previously matched by + `re-search-forward' or similar, and move point to next line + (See how the `helm-mp-3-search-base' and `helm-fuzzy-search' functions are working). + + NOTE: FUZZY-MATCH slot will overhide value of this slot.") + + (search-strict + :initarg :search-strict + :initform nil + :custom function + :documentation + " When specifying a search function within a source and + helm-match-plugin is enabled, the result of all searching + functions will be concatened, which in some cases is not what + is wanted. When using `search-strict' only this or these + functions will be used. You can specify those functions as a + list of functions or a single symbol function. + + NOTE: This have the same effect as using a nil value for + :MATCHPLUGIN slot.")) + + "Use this source to make helm sources storing candidates inside a buffer. +Contrarily to `helm-source-sync' candidates are matched using a function +like `re-search-forward', see below documentation of :search slot.") + +(defclass helm-source-dummy (helm-source) + ((candidates + :initform '("dummy")) + + (filtered-candidate-transformer + :initform 'helm-dummy-candidate) + + (matchplugin + :initform nil) + + (accept-empty + :initarg :accept-empty + :initform t + :custom boolean + :documentation + " Allow exiting with an empty string. + You should keep the default value.") + + (match + :initform 'identity) + + (volatile + :initform t))) + +(defclass helm-source-in-file (helm-source-in-buffer) + ((init :initform (lambda () + (let ((file (helm-attr 'candidates-file))) + (with-current-buffer (helm-candidate-buffer 'global) + (insert-file-contents file))))) + (candidates-file + :initarg :candidates-file + :initform nil + :custom string + :documentation "A filename.")) + + "The contents of the file will be used as candidates in buffer.") + + +;;; Classes for types. +;; +;; Files +(defclass helm-type-file (helm-source) () + "A class to define helm type file.") + +(defmethod helm--setup-source :primary ((_source helm-type-file))) + +(defmethod helm--setup-source :before ((source helm-type-file)) + (set-slot-value source 'action + (helm-make-actions + "Find file" 'helm-find-many-files + "Find file as root" 'helm-find-file-as-root + "Find file other window" 'find-file-other-window + "Find file other frame" 'find-file-other-frame + "Open dired in file's directory" 'helm-open-dired + "Grep File(s) `C-u recurse'" 'helm-find-files-grep + "Zgrep File(s) `C-u Recurse'" 'helm-ff-zgrep + "Pdfgrep File(s)" 'helm-ff-pdfgrep + "Insert as org link" 'helm-files-insert-as-org-link + "Checksum File" 'helm-ff-checksum + "Ediff File" 'helm-find-files-ediff-files + "Ediff Merge File" 'helm-find-files-ediff-merge-files + "Etags `M-., C-u tap, C-u C-u reload tag file'" + 'helm-ff-etags-select + "View file" 'view-file + "Insert file" 'insert-file + "Add marked files to file-cache" 'helm-ff-cache-add-file + "Delete file(s)" 'helm-delete-marked-files + "Open file externally (C-u to choose)" 'helm-open-file-externally + "Open file with default tool" 'helm-open-file-with-default-tool + "Find file in hex dump" 'hexl-find-file)) + (set-slot-value source 'persistent-help "Show this file") + (set-slot-value source 'action-transformer '(helm-transform-file-load-el + helm-transform-file-browse-url + helm-transform-file-cache)) + (set-slot-value source 'candidate-transformer '(helm-skip-boring-files + helm-highlight-files + helm-w32-pathname-transformer))) + +;; Bookmarks +(defclass helm-type-bookmark (helm-source) () + "A class to define type bookmarks.") + +(defmethod helm--setup-source :primary ((_source helm-type-bookmark))) + +(defmethod helm--setup-source :before ((source helm-type-bookmark)) + (set-slot-value source 'action (helm-make-actions + "Jump to bookmark" 'helm-bookmark-jump + "Jump to BM other window" 'helm-bookmark-jump-other-window + "Bookmark edit annotation" 'bookmark-edit-annotation + "Bookmark show annotation" 'bookmark-show-annotation + "Delete bookmark(s)" 'helm-delete-marked-bookmarks + "Edit Bookmark" 'helm-bookmark-edit-bookmark + "Rename bookmark" 'helm-bookmark-rename + "Relocate bookmark" 'bookmark-relocate)) + (set-slot-value source 'keymap helm-bookmark-map) + (set-slot-value source 'mode-line helm-bookmark-mode-line-string)) + +;; Buffers +(defclass helm-type-buffer (helm-source) () + "A class to define type buffer.") + +(defmethod helm--setup-source :primary ((_source helm-type-buffer))) + +(defmethod helm--setup-source :before ((source helm-type-buffer)) + (set-slot-value source 'action (helm-make-actions + "Switch to buffer(s)" 'helm-switch-to-buffers + (lambda () (and (locate-library "popwin") "Switch to buffer in popup window")) + 'popwin:popup-buffer + "Switch to buffer(s) other window `C-c o'" + 'helm-switch-to-buffers-other-window + "Switch to buffer other frame `C-c C-o'" 'switch-to-buffer-other-frame + (lambda () (and (locate-library "elscreen") "Display buffer in Elscreen")) + 'helm-find-buffer-on-elscreen + "Query replace regexp `C-M-%'" 'helm-buffer-query-replace-regexp + "Query replace `M-%'" 'helm-buffer-query-replace + "View buffer" 'view-buffer + "Display buffer" 'display-buffer + "Grep buffers `M-g s' (C-u grep all buffers)" 'helm-zgrep-buffers + "Multi occur buffer(s) `C-s'" 'helm-multi-occur-as-action + "Revert buffer(s) `M-U'" 'helm-revert-marked-buffers + "Insert buffer" 'insert-buffer + "Kill buffer(s) `M-D'" 'helm-kill-marked-buffers + "Diff with file `C-='" 'diff-buffer-with-file + "Ediff Marked buffers `C-c ='" 'helm-ediff-marked-buffers + "Ediff Merge marked buffers `M-='" (lambda (candidate) + (helm-ediff-marked-buffers candidate t)))) + (set-slot-value source 'persistent-help "Show this buffer") + (set-slot-value source 'filtered-candidate-transformer '(helm-skip-boring-buffers + helm-buffers-sort-transformer + helm-highlight-buffers))) + +;; Functions +(defclass helm-type-function (helm-source) () + "A class to define helm type function.") + +(defmethod helm--setup-source :primary ((_source helm-type-function))) + +(defmethod helm--setup-source :before ((source helm-type-function)) + (set-slot-value source 'action (helm-make-actions + "Describe command" 'describe-function + "Add command to kill ring" 'helm-kill-new + "Go to command's definition" 'find-function + "Debug on entry" 'debug-on-entry + "Cancel debug on entry" 'cancel-debug-on-entry + "Trace function" 'trace-function + "Trace function (background)" 'trace-function-background + "Untrace function" 'untrace-function)) + (set-slot-value source 'action-transformer 'helm-transform-function-call-interactively) + (set-slot-value source 'candidate-transformer 'helm-mark-interactive-functions) + (set-slot-value source 'coerce 'helm-symbolify)) + +;; Commands +(defclass helm-type-command (helm-source) () + "A class to define helm type command.") + +(defmethod helm--setup-source :primary ((_source helm-type-command))) + +(defmethod helm--setup-source :before ((source helm-type-command)) + (set-slot-value source 'action (append (helm-make-actions + "Call interactively" 'helm-call-interactively) + (helm-actions-from-type-function))) + (set-slot-value source 'coerce 'helm-symbolify) + (set-slot-value source 'persistent-action 'describe-function)) + + +;;; Error functions +;; +;; +(defun helm-default-init-source-in-buffer-function () + (helm-init-candidates-in-buffer 'global + '("ERROR: No buffer handling your data, use either the `init' slot or the `data' slot."))) + + +;;; Internal Builder functions. +;; +;; +(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) + for slot-val = (slot-value object s) + when slot-val + collect (cons s (unless (eq t slot-val) slot-val)))) + +(defun helm-make-source (name class &rest args) + "Build a `helm' source named NAME with ARGS for CLASS. +Argument NAME is a string which define the source name, so no need to use +the keyword :name in your source, NAME will be used instead. +Argument CLASS is an eieio class object. +Arguments ARGS are keyword value pairs as defined in CLASS." + (declare (indent 2)) + (let ((source (apply #'make-instance class name args))) + (set-slot-value source 'name name) + (helm--setup-source source) + (helm-setup-user-source source) + (helm--create-source source))) + +(defun helm-make-type (class &rest args) + (let ((source (apply #'make-instance class args))) + (set-slot-value source 'name nil) + (helm--setup-source source) + (helm--create-source source))) + +(defun helm-source-mp-get-search-or-match-fns (source method) + (require 'helm-match-plugin) + (let ((searchers (and (eq method 'search) + helm-mp-default-search-functions)) + (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)))) + (cl-case method + (match (cond (defmatch-strict) + (defmatch + (append helm-mp-default-match-functions defmatch)) + (t helm-mp-default-match-functions))) + (search (cond (defsearch-strict) + (defsearch + (append searchers defsearch)) + (t searchers)))))) + + +;;; Modifiers +;; +(cl-defun helm-source-add-action-to-source-if (name fn source predicate + &optional (index 4)) + "Same as `helm-add-action-to-source-if' but for SOURCE defined as eieio object. +You can use this inside a `helm--setup-source' method for a SOURCE defined as +an eieio class." + (let* ((actions (slot-value source 'action)) + (action-transformers (slot-value source 'action-transformer)) + (new-action (list (cons name fn))) + (transformer `(lambda (actions candidate) + (cond ((funcall (quote ,predicate) candidate) + (helm-append-at-nth + actions (quote ,new-action) ,index)) + (t actions))))) + (when (symbolp actions) + (set-slot-value source 'action (list (cons "Default action" actions)))) + (when (symbolp action-transformers) + (setq action-transformers (list action-transformers))) + (set-slot-value + source + 'action-transformer + (delq nil (append (list transformer) action-transformers))))) + +;;; Methods to access types slots. +;; +;; +(defmethod helm-source-get-action-from-type ((object helm-type-file)) + (slot-value object 'action)) + +(defmethod helm-source-get-action-from-type ((object helm-type-buffer)) + (slot-value object 'action)) + +(defmethod helm-source-get-action-from-type ((object helm-type-bookmark)) + (slot-value object 'action)) + +(defmethod helm-source-get-action-from-type ((object helm-type-function)) + (slot-value object 'action)) + + +;;; Methods to build sources. +;; +;; +(defun helm-source--persistent-help-string (string source) + (substitute-command-keys + (concat "\\\\[helm-execute-persistent-action]: " + (or (format "%s (keeping session)" string) + (slot-value source 'header-line))))) + +(defun helm-source--header-line (source) + (substitute-command-keys + (concat "\\\\[helm-execute-persistent-action]: " + (helm-aif (or (slot-value source 'persistent-action) + (slot-value source 'action)) + (cond ((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 "")) + "") + " (keeping session)"))) + +(defmethod helm--setup-source :primary ((_source helm-source))) + +(defmethod helm--setup-source :before ((source helm-source)) + (helm-aif (slot-value source 'keymap) + (and (symbolp it) (set-slot-value source 'keymap (symbol-value it)))) + (set-slot-value source 'header-line (helm-source--header-line source)) + (helm-aif (slot-value source 'persistent-help) + (set-slot-value source 'header-line (helm-source--persistent-help-string it source))) + (when (and (slot-value source 'fuzzy-match) helm-fuzzy-sort-fn) + (set-slot-value source 'filtered-candidate-transformer + (helm-aif (slot-value source 'filtered-candidate-transformer) + (append (helm-mklist it) + (list helm-fuzzy-sort-fn)) + (list helm-fuzzy-sort-fn)))) + (unless (slot-value source 'nohighlight) + (set-slot-value source 'filtered-candidate-transformer + (helm-aif (slot-value source 'filtered-candidate-transformer) + (append (helm-mklist it) + (list #'helm-fuzzy-highlight-matches)) + (list #'helm-fuzzy-highlight-matches))))) + +(defmethod helm-setup-user-source ((_source helm-source))) + +(defmethod helm--setup-source ((source helm-source-sync)) + (when (slot-value source 'fuzzy-match) + (helm-aif (slot-value source 'match) + (set-slot-value source 'match (append (helm-mklist it) + (list helm-fuzzy-match-fn))) + (set-slot-value source 'match helm-fuzzy-match-fn))) + (when (slot-value source 'matchplugin) + (set-slot-value source 'match + (helm-source-mp-get-search-or-match-fns source 'match)))) + +(defmethod helm--setup-source ((source helm-source-in-buffer)) + (let ((cur-init (slot-value source 'init))) + (helm-aif (slot-value source 'data) + (set-slot-value + source + 'init (delq + nil + (list + (and (null (eq 'helm-default-init-source-in-buffer-function + cur-init)) + cur-init) + (lambda () + (helm-init-candidates-in-buffer + 'global + (if (functionp it) (funcall it) it)))))))) + (when (slot-value source 'fuzzy-match) + (helm-aif (slot-value source 'search) + (set-slot-value source 'search (append (helm-mklist it) + (list helm-fuzzy-search-fn))) + (set-slot-value source 'search (list helm-fuzzy-search-fn)))) + (when (slot-value source 'matchplugin) + (set-slot-value source 'search (helm-source-mp-get-search-or-match-fns source 'search))) + (let ((mtc (slot-value source 'match))) + (cl-assert (or (equal '(identity) mtc) + (eq 'identity mtc)) + nil "Invalid slot value for `match'") + (cl-assert (eq (slot-value source 'volatile) t) + nil "Invalid slot value for `volatile'"))) + +(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 'matchplugin)) + nil "`matchplugin' not allowed in async sources.")) + +(defmethod helm--setup-source ((source helm-source-dummy)) + (let ((mtc (slot-value source 'match))) + (cl-assert (or (equal '(identity) mtc) + (eq 'identity mtc)) + nil "Invalid slot value for `match'") + (cl-assert (eq (slot-value source 'volatile) t) + nil "Invalid slot value for `volatile'") + (cl-assert (equal (slot-value source 'candidates) '("dummy")) + nil "Invalid slot value for `candidates'") + (cl-assert (eq (slot-value source 'accept-empty) t) + nil "Invalid slot value for `accept-empty'"))) + + +;;; User functions +;; +;; Sources +(defmacro helm-build-sync-source (name &rest args) + "Build a synchronous helm source with name NAME. +Args ARGS are keywords provided by `helm-source-sync'." + (declare (indent 1)) + `(helm-make-source ,name 'helm-source-sync ,@args)) + +(defmacro helm-build-async-source (name &rest args) + "Build a asynchronous helm source with name NAME. +Args ARGS are keywords provided by `helm-source-async'." + (declare (indent 1)) + `(helm-make-source ,name 'helm-source-async ,@args)) + +(defmacro helm-build-in-buffer-source (name &rest args) + "Build a helm source with name NAME using `candidates-in-buffer' method. +Args ARGS are keywords provided by `helm-source-in-buffer'." + (declare (indent 1)) + `(helm-make-source ,name 'helm-source-in-buffer ,@args)) + +(defmacro helm-build-dummy-source (name &rest args) + "Build a helm source with name NAME using `dummy' method. +Args ARGS are keywords provided by `helm-source-dummy'." + (declare (indent 1)) + `(helm-make-source ,name 'helm-source-dummy ,@args)) + +(defmacro helm-build-in-file-source (name file &rest args) + "Build a helm source with NAME name using `candidates-in-files' method. +Arg FILE is a filename, the contents of this file will be +used as candidates in buffer. +Args ARGS are keywords provided by `helm-source-in-file'." + (declare (indent 1)) + `(helm-make-source ,name 'helm-source-in-file + :candidates-file ,file ,@args)) + +;; Types +(defun helm-actions-from-type-file () + (let ((source (make-instance 'helm-type-file))) + (helm--setup-source source) + (helm-source-get-action-from-type source))) + +(defun helm-build-type-file () + (helm-make-type 'helm-type-file)) + +(defun helm-actions-from-type-function () + (let ((source (make-instance 'helm-type-function))) + (helm--setup-source source) + (helm-source-get-action-from-type source))) + +(defun helm-build-type-function () + (helm-make-type 'helm-type-function)) + +(defun helm-actions-from-type-command () + (let ((source (make-instance 'helm-type-command))) + (helm--setup-source source) + (helm-source-get-action-from-type source))) + +(defun helm-build-type-command () + (helm-make-type 'helm-type-command)) + +(provide 'helm-source) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-source ends here diff --git a/elpa/helm-20150403.101/helm-sys.el b/elpa/helm-20150403.101/helm-sys.el new file mode 100644 index 00000000..2c3ce071 --- /dev/null +++ b/elpa/helm-20150403.101/helm-sys.el @@ -0,0 +1,299 @@ +;;; helm-sys.el --- System related functions for helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) + + +(defgroup helm-sys nil + "System related helm library." + :group 'helm) + +(defface helm-top-columns + '((t :inherit helm-header)) + "Face for helm help string in minibuffer." + :group 'helm-sys) + + +(defun helm-top-command-set-fn (var _value) + (set var + (cl-case system-type + (darwin "env COLUMNS=%s ps -axo pid,user,pri,nice,ucomm,tty,start,vsz,%%cpu,%%mem,etime,command") + (t "env COLUMNS=%s top -b -n 1")))) + +(defcustom helm-top-command "env COLUMNS=%s top -b -n 1" + "Top command used to display output of top. +To use top command, a version supporting batch mode (-b option) is needed. +On Mac OSX top command doesn't support this, so ps command +is used by default instead. +If you modify this the number and order of elements displayed +should be the same as top command to have the sort commands +working properly, that is 12 elements with the 2 first being +PID and USER and the last 4 being %CPU, %MEM, TIME and COMMAND. +A format string where %s will be replaced with `frame-width'." + :group 'helm-sys + :type 'string + :set 'helm-top-command-set-fn) + + +;;; Top (process) +;; +;; +(defvar helm-top-sort-fn nil) +(defvar helm-top-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "C-c ?") 'helm-top-help) + (define-key map (kbd "M-P") 'helm-top-run-sort-by-cpu) + (define-key map (kbd "M-C") 'helm-top-run-sort-by-com) + (define-key map (kbd "M-M") 'helm-top-run-sort-by-mem) + (define-key map (kbd "M-U") 'helm-top-run-sort-by-user) + map)) + +(defvar helm-source-top + (helm-build-in-buffer-source "Top" + :header-name (lambda (name) (concat name " (Press C-c C-u to refresh)")) + :init #'helm-top-init + :nomark t + :display-to-real #'helm-top-display-to-real + :persistent-action #'helm-top-sh-persistent-action + :persistent-help "SIGTERM" + :mode-line helm-top-mode-line + :follow 'never + :keymap helm-top-map + :filtered-candidate-transformer #'helm-top-sort-transformer + :action-transformer #'helm-top-action-transformer)) + +(defun helm-top-transformer (candidates _source) + "Transformer for `helm-top'. +Return empty string for non--valid candidates." + (cl-loop for disp in candidates collect + (cond ((string-match "^ *[0-9]+" disp) disp) + ((string-match "^ *PID" disp) + (cons (propertize disp 'face 'helm-top-columns) "")) + (t (cons disp ""))))) + +(defun helm-top-action-transformer (actions _candidate) + "Action transformer for `top'. +Show actions only on line starting by a PID." + (let ((disp (helm-get-selection nil t))) + (cond ((string-match "^ *[0-9]+" disp) + (list '("kill (SIGTERM)" . (lambda (pid) (helm-top-sh "TERM" pid))) + '("kill (SIGKILL)" . (lambda (pid) (helm-top-sh "KILL" pid))) + '("kill (SIGINT)" . (lambda (pid) (helm-top-sh "INT" pid))) + '("kill (Choose signal)" + . (lambda (pid) + (helm-top-sh + (helm-comp-read (format "Kill [%s] with signal: " pid) + '("ALRM" "HUP" "INT" "KILL" "PIPE" "POLL" + "PROF" "TERM" "USR1" "USR2" "VTALRM" + "STKFLT" "PWR" "WINCH" "CHLD" "URG" + "TSTP" "TTIN" "TTOU" "STOP" "CONT" + "ABRT" "FPE" "ILL" "QUIT" "SEGV" + "TRAP" "SYS" "EMT" "BUS" "XCPU" "XFSZ") + :must-match t) + pid))))) + (t actions)))) + +(defun helm-top-sh (sig pid) + "Run kill shell command with signal SIG on PID for `helm-top'." + (let ((cmd (format "kill -%s %s" sig pid))) + (message "Executed %s\n%s" cmd (shell-command-to-string cmd)))) + +(defun helm-top-sh-persistent-action (pid) + (delete-other-windows) + (helm-top-sh "TERM" pid) + (helm-force-update)) + +(defun helm-top-init () + "Insert output of top command in candidate buffer." + (unless helm-top-sort-fn (helm-top-set-mode-line "CPU")) + (with-current-buffer (helm-candidate-buffer 'global) + (call-process-shell-command + (format helm-top-command (frame-width)) + nil (current-buffer)))) + +(defun helm-top-display-to-real (line) + "Return pid only from LINE." + (car (split-string line))) + +;; Sort top command + +(defun helm-top-set-mode-line (str) + (if (string-match "Sort:\\[\\(.*\\)\\] " helm-top-mode-line) + (setq helm-top-mode-line (replace-match str nil nil helm-top-mode-line 1)) + (setq helm-top-mode-line (concat (format "Sort:[%s] " str) helm-top-mode-line)))) + +(defun helm-top-sort-transformer (candidates source) + (helm-top-transformer + (if helm-top-sort-fn + (cl-loop for c in candidates + if (string-match "^ *[0-9]+" c) + collect c into pid-cands + else collect c into header-cands + finally return (append + header-cands + (sort pid-cands helm-top-sort-fn))) + candidates) + source)) + +(defun helm-top-sort-by-com (s1 s2) + (let* ((split-1 (split-string s1)) + (split-2 (split-string s2)) + (com-1 (nth 11 split-1)) + (com-2 (nth 11 split-2))) + (string< com-1 com-2))) + +(defun helm-top-sort-by-mem (s1 s2) + (let* ((split-1 (split-string s1)) + (split-2 (split-string s2)) + (mem-1 (string-to-number (nth 9 split-1))) + (mem-2 (string-to-number (nth 9 split-2)))) + (> mem-1 mem-2))) + +(defun helm-top-sort-by-user (s1 s2) + (let* ((split-1 (split-string s1)) + (split-2 (split-string s2)) + (user-1 (nth 1 split-1)) + (user-2 (nth 1 split-2))) + (string< user-1 user-2))) + +(defun helm-top-run-sort-by-com () + (interactive) + (helm-top-set-mode-line "COM") + (setq helm-top-sort-fn 'helm-top-sort-by-com) + (helm-force-update)) + +(defun helm-top-run-sort-by-cpu () + (interactive) + (helm-top-set-mode-line "CPU") + (setq helm-top-sort-fn nil) + (helm-force-update)) + +(defun helm-top-run-sort-by-mem () + (interactive) + (helm-top-set-mode-line "MEM") + (setq helm-top-sort-fn 'helm-top-sort-by-mem) + (helm-force-update)) + +(defun helm-top-run-sort-by-user () + (interactive) + (helm-top-set-mode-line "USER") + (setq helm-top-sort-fn 'helm-top-sort-by-user) + (helm-force-update)) + + +;;; X RandR resolution change +;; +;; +;;; FIXME I do not care multi-display. + +(defun helm-xrandr-info () + "Return a pair with current X screen number and current X display name." + (with-temp-buffer + (call-process "xrandr" nil (current-buffer) nil + "--current") + (let (screen output) + (goto-char (point-min)) + (save-excursion + (when (re-search-forward "\\(^Screen \\)\\([0-9]\\):" nil t) + (setq screen (match-string 2)))) + (when (re-search-forward "^\\(.*\\) connected" nil t) + (setq output (match-string 1))) + (list screen output)))) + +(defun helm-xrandr-screen () + "Return current X screen number." + (car (helm-xrandr-info))) + +(defun helm-xrandr-output () + "Return current X display name." + (cadr (helm-xrandr-info))) + +(defvar helm-source-xrandr-change-resolution + '((name . "Change Resolution") + (candidates + . (lambda () + (with-temp-buffer + (call-process "xrandr" nil (current-buffer) nil + "--screen" (helm-xrandr-screen) "-q") + (goto-char 1) + (cl-loop with modes = nil + while (re-search-forward " \\([0-9]+x[0-9]+\\)" nil t) + for mode = (match-string 1) + unless (member mode modes) + collect mode into modes + finally return modes)))) + (action + ("Change Resolution" + . (lambda (mode) + (call-process "xrandr" nil nil nil + "--screen" (helm-xrandr-screen) + "--output" (helm-xrandr-output) + "--mode" mode)))))) + + +;;; Emacs process +;; +;; +(defvar helm-source-emacs-process + '((name . "Emacs Process") + (init . (lambda () (list-processes--refresh))) + (candidates . (lambda () (mapcar #'process-name (process-list)))) + (persistent-action . (lambda (elm) + (delete-process (get-process elm)) + (helm-delete-current-selection))) + (persistent-help . "Kill Process") + (action ("Kill Process" . (lambda (elm) + (delete-process (get-process elm))))))) + + +;;;###autoload +(defun helm-top () + "Preconfigured `helm' for top command." + (interactive) + (save-window-excursion + (unless helm-alive-p (delete-other-windows)) + (helm :sources 'helm-source-top + :buffer "*helm top*" :full-frame t + :candidate-number-limit 9999 + :preselect "^\\s-*[0-9]+"))) + +;;;###autoload +(defun helm-list-emacs-process () + "Preconfigured `helm' for emacs process." + (interactive) + (helm-other-buffer 'helm-source-emacs-process "*helm process*")) + +;;;###autoload +(defun helm-xrandr-set () + (interactive) + (helm :sources 'helm-source-xrandr-change-resolution + :buffer "*helm xrandr*")) + +(provide 'helm-sys) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-sys.el ends here diff --git a/elpa/helm-20150403.101/helm-tags.el b/elpa/helm-20150403.101/helm-tags.el new file mode 100644 index 00000000..e6ba1792 --- /dev/null +++ b/elpa/helm-20150403.101/helm-tags.el @@ -0,0 +1,360 @@ +;;; helm-tags.el --- Helm for Etags and Ctags. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'helm-utils) + + +(defgroup helm-tags nil + "Tags related Applications and libraries for Helm." + :group 'helm) + +(defcustom helm-etags-tag-file-name "TAGS" + "Etags tag file name." + :type 'string + :group 'helm-tags) + +(defcustom helm-etags-tag-file-search-limit 10 + "The limit level of directory to search tag file. +Don't search tag file deeply if outside this value." + :type 'number + :group 'helm-tags) + +(defcustom helm-etags-match-part-only t + "Whether to match only the tag part of CANDIDATE in +helm-source-ctags-select." + :type 'boolean + :group 'helm-tags) + +(defcustom helm-etags-execute-action-at-once-if-one t + "Whether to jump straight to the selected tag if there's only +one match." + :type 'boolean + :group 'helm-tags) + + +(defgroup helm-tags-faces nil + "Customize the appearance of helm-tags faces." + :prefix "helm-" + :group 'helm-tags + :group 'helm-faces) + +(defface helm-etags-file + '((t (:foreground "Lightgoldenrod4" + :underline t))) + "Face used to highlight etags filenames." + :group 'helm-tags-faces) + + +(defun helm-etags-run-switch-other-window () + "Run switch to other window action from `helm-source-etags-select'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action + (lambda (c) + (helm-etags-action-goto 'find-file-other-window c))))) + +(defun helm-etags-run-switch-other-frame () + "Run switch to other frame action from `helm-source-etags-select'." + (interactive) + (with-helm-alive-p + (helm-quit-and-execute-action + (lambda (c) + (helm-etags-action-goto 'find-file-other-frame c))))) + +(defvar helm-etags-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map helm-map) + (define-key map (kbd "M-") 'helm-goto-next-file) + (define-key map (kbd "M-") 'helm-goto-precedent-file) + (define-key map (kbd "C-w") 'helm-yank-text-at-point) + (define-key map (kbd "C-c ?") 'helm-etags-help) + (define-key map (kbd "C-c o") 'helm-etags-run-switch-other-window) + (define-key map (kbd "C-c C-o") 'helm-etags-run-switch-other-frame) + map) + "Keymap used in Etags.") + + +;;; Ctags +;; +;; +(defvar helm-ctags-modes + '( c-mode c++-mode awk-mode csharp-mode java-mode javascript-mode lua-mode + makefile-mode pascal-mode perl-mode cperl-mode php-mode python-mode + scheme-mode sh-mode slang-mode sql-mode tcl-mode )) + +(defun helm-ctags-init () + (when (and buffer-file-name + (memq major-mode helm-ctags-modes) + (helm-current-buffer-is-modified)) + (with-current-buffer (helm-candidate-buffer 'local) + (call-process-shell-command + (if (string-match "\\.el\\.gz$" helm-buffer-file-name) + (format "ctags -e -u -f- --language-force=lisp --fields=n =(zcat %s) " + helm-buffer-file-name) + (format "ctags -e -u -f- --fields=n %s " helm-buffer-file-name)) + nil (current-buffer)) + (goto-char (point-min)) + (forward-line 2) + (delete-region (point-min) (point)) + (cl-loop while (and (not (eobp)) (search-forward "\001" (point-at-eol) t)) + for lineno-start = (point) + for lineno = (buffer-substring + lineno-start + (1- (search-forward "," (point-at-eol) t))) + do + (forward-line 0) + (insert (format "%5s:" lineno)) + (search-forward "\177" (point-at-eol) t) + (delete-region (1- (point)) (point-at-eol)) + (forward-line 1))))) + +(defvar helm-source-ctags + '((name . "Exuberant ctags") + (init . helm-ctags-init) + (candidates-in-buffer) + (adjust) + (type . line)) + "Needs Exuberant Ctags. + +http://ctags.sourceforge.net/") + + +;;; Etags +;; +;; +(defvar helm-etags-mtime-alist nil + "Store the last modification time of etags files here.") +(defvar helm-etags-cache (make-hash-table :test 'equal) + "Cache content of etags files used here for faster access.") + +(defun helm-etags-get-tag-file (&optional directory) + "Return the path of etags file if found. +Lookes recursively in parents directorys for a +`helm-etags-tag-file-name' file." + ;; Get tag file from `default-directory' or upper directory. + (let ((current-dir (helm-etags-find-tag-file-directory + (or directory default-directory)))) + ;; Return nil if not find tag file. + (when current-dir + (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'. + 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 + (delq nil + (append (list (helm-etags-get-tag-file) + tags-file-name) + tags-table-list)) + :test 'equal)) + +(defun helm-etags-find-tag-file-directory (current-dir) + "Try to find the directory containing tag file. +If not found in CURRENT-DIR search in upper directory." + (let ((file-exists? #'(lambda (dir) + (let ((tag-path (expand-file-name + helm-etags-tag-file-name dir))) + (and (stringp tag-path) + (file-regular-p tag-path) + (file-readable-p tag-path)))))) + (cl-loop with count = 0 + until (funcall file-exists? current-dir) + ;; Return nil if outside the value of + ;; `helm-etags-tag-file-search-limit'. + if (= count helm-etags-tag-file-search-limit) + do (cl-return nil) + ;; Or search upper directories. + else + do (cl-incf count) + (setq current-dir (expand-file-name (concat current-dir "../"))) + finally return current-dir))) + +(defun helm-etags-get-header-name (_x) + "Create header name for this helm etags session." + (concat "Etags in " + (with-helm-current-buffer + (helm-etags-get-tag-file)))) + +(defun helm-etags-create-buffer (file) + "Create the `helm-buffer' based on contents of etags tag FILE." + (let* ((tag-fname file) + max + (split (with-current-buffer (find-file-noselect tag-fname) + (prog1 + (split-string (buffer-string) "\n" 'omit-nulls) + (setq max (line-number-at-pos (point-max))) + (kill-buffer)))) + (progress-reporter (make-progress-reporter "Loading tag file..." 0 max))) + (cl-loop + with fname + with cand + for i in split for count from 0 + for elm = (unless (string-match "^\x0c" i) + (helm-aif (string-match "\177" i) + (substring i 0 it) + i)) + do (cond ((and elm (string-match "^\\([^,]+\\),[0-9]+$" elm)) + (setq fname (propertize (match-string 1 elm) + 'face 'helm-etags-file))) + (elm (setq cand (concat fname ": " elm))) + (t (setq cand nil))) + when cand do (progn + (insert (concat cand "\n")) + (progress-reporter-update progress-reporter count))))) + +(defun helm-etags-init () + "Feed `helm-buffer' using `helm-etags-cache' or tag file. +If no entry in cache, create one." + (let ((tagfiles (helm-etags-all-tag-files))) + (when tagfiles + (with-current-buffer (helm-candidate-buffer 'global) + (dolist (f tagfiles) + (helm-aif (gethash f helm-etags-cache) + ;; An entry is present in cache, insert it. + (insert it) + ;; No entry, create a new buffer using content of tag file (slower). + (helm-etags-create-buffer f) + ;; Store content of buffer in cache. + (puthash f (buffer-string) helm-etags-cache) + ;; Store or set the last modification of tag file. + (helm-aif (assoc f helm-etags-mtime-alist) + ;; If an entry exists modify it. + (setcdr it (helm-etags-mtime f)) + ;; No entry create a new one. + (add-to-list 'helm-etags-mtime-alist + (cons f (helm-etags-mtime f)))))))))) + +(defun helm-etags-split-line (line) + (let ((regexp "\\`\\([[:lower:][:upper:]]?:?.*?\\): \\(.*\\)")) + (when (string-match regexp line) + (cl-loop for n from 1 to 2 collect (match-string n line))))) + +(defvar helm-source-etags-select nil + "Helm source for Etags.") + +(defun helm-etags-build-source () + (helm-build-in-buffer-source "Etags" + :header-name 'helm-etags-get-header-name + :init 'helm-etags-init + :get-line 'buffer-substring + :match-part (lambda (candidate) + ;; Match only the tag part of CANDIDATE + ;; and not the filename. + (if helm-etags-match-part-only + (cadr (helm-etags-split-line candidate)) + candidate)) + :mode-line helm-etags-mode-line-string + :keymap helm-etags-map + :action '(("Go to tag" . (lambda (c) + (helm-etags-action-goto 'find-file c))) + ("Go to tag in other window" . (lambda (c) + (helm-etags-action-goto + 'find-file-other-window + c))) + ("Go to tag in other frame" . (lambda (c) + (helm-etags-action-goto + 'find-file-other-frame + c)))) + :persistent-help "Go to line" + :persistent-action (lambda (candidate) + (helm-etags-action-goto 'find-file candidate) + (helm-highlight-current-line)))) + +(defvar find-tag-marker-ring) + +(defun helm-etags-action-goto (switcher candidate) + "Helm default action to jump to an etags entry in other window." + (require 'etags) + (helm-log-run-hook 'helm-goto-line-before-hook) + (let* ((split (helm-etags-split-line candidate)) + (fname (cl-loop for tagf being the hash-keys of helm-etags-cache + for f = (expand-file-name + (car split) (file-name-directory tagf)) + when (file-exists-p f) + return f)) + (elm (cadr split))) + (if (null fname) + (error "file %s not found" fname) + (ring-insert find-tag-marker-ring (point-marker)) + (funcall switcher fname) + (goto-char (point-min)) + (search-forward elm nil t) + (goto-char (match-beginning 0))))) + +(defun helm-etags-mtime (file) + "Last modification time of etags tag FILE." + (cadr (nth 5 (file-attributes file)))) + +(defun helm-etags-file-modified-p (file) + "Check if tag FILE have been modified in this session. +If FILE is nil return nil." + (let ((last-modif (and file + (assoc-default file helm-etags-mtime-alist)))) + (and last-modif + (/= last-modif (helm-etags-mtime file))))) + + +;;;###autoload +(defun helm-etags-select (arg) + "Preconfigured helm for etags. +If called with a prefix argument or if any of the tag files have +been modified, reinitialize cache. + +This function aggregates three sources of tag files: + + 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." + (interactive "P") + (let ((tag-files (helm-etags-all-tag-files)) + (helm-execute-action-at-once-if-one helm-etags-execute-action-at-once-if-one) + (str (if (region-active-p) (buffer-substring-no-properties (region-beginning) (region-end)) + (thing-at-point 'symbol)))) + (if (cl-notany 'file-exists-p tag-files) + (message "Error: No tag file found. Create with etags shell command, or visit with `find-tag' or `visit-tags-table'.") + (cl-loop for k being the hash-keys of helm-etags-cache + unless (member k tag-files) + do (remhash k helm-etags-cache)) + (mapc (lambda (f) + (when (or (equal arg '(4)) + (and helm-etags-mtime-alist + (helm-etags-file-modified-p f))) + (remhash f helm-etags-cache))) + tag-files) + (unless helm-source-etags-select + (setq helm-source-etags-select + (helm-etags-build-source))) + (helm :sources 'helm-source-etags-select + :keymap helm-etags-map + :default (list (concat "\\_<" str "\\_>") str) + :buffer "*helm etags*")))) + +(provide 'helm-tags) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm-tags.el ends here diff --git a/elpa/helm-20150403.101/helm-utils.el b/elpa/helm-20150403.101/helm-utils.el new file mode 100644 index 00000000..e3f5b937 --- /dev/null +++ b/elpa/helm-20150403.101/helm-utils.el @@ -0,0 +1,871 @@ +;;; helm-utils.el --- Utilities Functions for helm. -*- lexical-binding: t -*- + +;; Copyright (C) 2012 ~ 2015 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 +;; 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 . + +;;; Code: + +(require 'cl-lib) +(require 'helm) +(require 'compile) ; Fixme: Is this needed? +(require 'dired) + +(declare-function helm-find-files-1 "helm-files.el" (fname &optional preselect)) +(defvar winner-boring-buffers) + + +(defgroup helm-utils nil + "Utilities routines for Helm." + :group 'helm) + +(defcustom helm-su-or-sudo "sudo" + "What command to use for root access." + :type 'string + :group 'helm-utils) + +(defcustom helm-yank-symbol-first nil + "`helm-yank-text-at-point' yanks symbol at point on first +invocation if this is non-nil." + :type 'boolean + :group 'helm-utils) + +(defcustom helm-default-kbsize 1024.0 + "Default Kbsize to use for showing files size. +It is a float, usually 1024.0 but could be 1000.0 on some systems." + :group 'helm-utils + :type 'float) + +(defcustom helm-highlight-number-lines-around-point 15 + "Number of lines around point where matched items are highlighted." + :group 'helm-utils + :type 'integer) + +(defcustom helm-buffers-to-resize-on-pa nil + "A list of helm buffers where the helm-window should be reduced on persistent actions." + :group 'helm-utils + :type '(repeat (choice string))) + +(defcustom helm-resize-on-pa-text-height 12 + "The size of the helm-window when resizing on persistent action." + :group 'helm-utils + :type 'integer) + + +(defvar helm-goto-line-before-hook '(helm-save-current-pos-to-mark-ring) + "Run before jumping to line. +This hook run when jumping from `helm-goto-line', `helm-etags-default-action', +and `helm-imenu-default-action'.") + +(defvar helm-save-pos-before-jump-register ?_ + "The register where `helm-save-pos-to-register-before-jump' save position.") + + +;;; Faces. +;; +(defface helm-selection-line + '((t (:inherit highlight :distant-foreground "black"))) + "Face used in the `helm-current-buffer' when jumping to candidate." + :group 'helm-faces) + +(defface helm-match-item + '((t (:inherit isearch))) + "Face used to highlight item matched in a selected line." + :group 'helm-faces) + + +;; CUA workaround +(defadvice cua-delete-region (around helm-avoid-cua activate) + (ignore-errors ad-do-it)) + +(defadvice copy-region-as-kill (around helm-avoid-cua activate) + (if cua-mode + (ignore-errors ad-do-it) + ad-do-it)) + + +;;; Utils functions +;; +;; +(defun helm-ff-find-printers () + "Return a list of available printers on Unix systems." + (when (executable-find "lpstat") + (let ((printer-list (with-temp-buffer + (call-process "lpstat" nil t nil "-a") + (split-string (buffer-string) "\n")))) + (cl-loop for p in printer-list + for printer = (car (split-string p)) + when printer + collect printer)))) + +(defun helm-switch-to-buffers (buffer-or-name &optional other-window) + "Switch to buffer BUFFER-OR-NAME. +If more than one buffer marked switch to these buffers in separate windows. +If OTHER-WINDOW is specified keep current-buffer and switch to others buffers +in separate windows." + (let* ((mkds (helm-marked-candidates)) + (size (/ (window-height) (length mkds)))) + (or (<= window-min-height size) + (error "Too many buffers to visit simultaneously.")) + (helm-aif (cdr mkds) + (progn + (if other-window + (switch-to-buffer-other-window (car mkds)) + (switch-to-buffer (car mkds))) + (save-selected-window + (cl-loop for b in it + do (progn + (select-window (split-window)) + (switch-to-buffer b))))) + (if other-window + (switch-to-buffer-other-window buffer-or-name) + (switch-to-buffer buffer-or-name))))) + +(defun helm-switch-to-buffers-other-window (buffer-or-name) + "switch to buffer BUFFER-OR-NAME in other window. +See `helm-switch-to-buffers' for switching to marked buffers." + (helm-switch-to-buffers buffer-or-name t)) + +(cl-defmacro helm-position (item seq &key (test 'eq) all) + "A simple and faster replacement of CL `position'. +Return position of first occurence of ITEM found in SEQ. +Argument SEQ can be a string, in this case ITEM have to be a char. +Argument ALL, if non--nil specify to return a list of positions of +all ITEM found in SEQ." + (let ((key (if (stringp seq) 'across 'in))) + `(cl-loop for c ,key ,seq + for index from 0 + when (funcall ,test c ,item) + if ,all collect index into ls + else return index + finally return ls))) + +(defun helm-substring (str width) + "Return the substring of string STR from 0 to WIDTH. +Handle multibyte characters by moving by columns." + (with-temp-buffer + (save-excursion + (insert str)) + (move-to-column width) + (buffer-substring (point-at-bol) (point)))) + +(cl-defun helm-substring-by-width (str width &optional (endstr "...")) + "Truncate string STR to end at column WIDTH. +Similar to `truncate-string-to-width'. +Add ENDSTR (default \"...\") at end of truncated STR. +Add spaces at end if needed to reach WIDTH when STR is shorter than WIDTH." + (cl-loop for ini-str = str + then (substring ini-str 0 (1- (length ini-str))) + for sw = (string-width ini-str) + when (<= sw width) return + (concat ini-str endstr (make-string (- width sw) ? )))) + +(defun helm-string-multibyte-p (str) + "Check if string STR contains multibyte characters." + (cl-loop for c across str + thereis (> (char-width c) 1))) + +(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)) + +(cl-defun helm-current-buffer-narrowed-p (&optional + (buffer helm-current-buffer)) + "Check if BUFFER is narrowed. +Default is `helm-current-buffer'." + (with-current-buffer buffer + (let ((beg (point-min)) + (end (point-max)) + (total (buffer-size))) + (or (/= beg 1) (/= end (1+ total)))))) + +(defun helm-region-active-p () + (and transient-mark-mode mark-active (/= (mark) (point)))) + +(defun helm-goto-char (loc) + "Go to char, revealing if necessary." + (goto-char loc) + (when (or (eq major-mode 'org-mode) + (and (boundp 'outline-minor-mode) + outline-minor-mode)) + (require 'org) ; On some old Emacs versions org may not be loaded. + (org-reveal))) + +(defun helm-goto-line (lineno &optional noanim) + "Goto LINENO opening only outline headline if needed. +Animation is used unless NOANIM is non--nil." + (helm-log-run-hook 'helm-goto-line-before-hook) + (goto-char (point-min)) + (helm-goto-char (point-at-bol lineno)) + (unless noanim + (helm-highlight-current-line nil nil nil nil 'pulse))) + +(defun helm-save-pos-to-register-before-jump () + "Save current buffer position to `helm-save-pos-before-jump-register'. +To use this add it to `helm-goto-line-before-hook'." + (with-helm-current-buffer + (unless helm-in-persistent-action + (point-to-register helm-save-pos-before-jump-register)))) + +(defun helm-save-current-pos-to-mark-ring () + "Save current buffer position to mark ring. +To use this add it to `helm-goto-line-before-hook'." + (with-helm-current-buffer + (unless helm-in-persistent-action + (set-marker (mark-marker) (point)) + (push-mark (point) 'nomsg)))) + +;;;###autoload +(defun helm-show-all-in-this-source-only (arg) + "Show only current source of this helm session with all its candidates. +With a numeric prefix arg show only the ARG number of candidates." + (interactive "p") + (with-helm-window + (with-helm-default-directory helm-default-directory + (let ((helm-candidate-number-limit (and (> arg 1) arg))) + (helm-set-source-filter + (list (assoc-default 'name (helm-get-current-source)))))))) + +;;;###autoload +(defun helm-display-all-sources () + "Display all sources previously hidden by `helm-set-source-filter'." + (interactive) + (helm-set-source-filter nil)) + +(defun helm-displaying-source-names () + "Return the list of sources name for this helm session." + (with-current-buffer helm-buffer + (goto-char (point-min)) + (cl-loop with pos + while (setq pos (next-single-property-change (point) 'helm-header)) + do (goto-char pos) + collect (buffer-substring-no-properties (point-at-bol)(point-at-eol)) + do (forward-line 1)))) + +(defun helm-skip-entries (seq regexp-list) + "Remove entries which matches one of REGEXP-LIST from SEQ." + (cl-loop for i in seq + unless (cl-loop for regexp in regexp-list + thereis (and (stringp i) + (string-match regexp i))) + collect i)) + +(defun helm-shadow-entries (seq regexp-list) + "Put shadow property on entries in SEQ matching a regexp in REGEXP-LIST." + (let ((face 'italic)) + (cl-loop for i in seq + if (cl-loop for regexp in regexp-list + thereis (and (stringp i) + (string-match regexp i))) + collect (propertize i 'face face) + else collect i))) + +(defun helm-describe-function (func) + "FUNC is symbol or string." + (describe-function (helm-symbolify func)) + (message nil)) + +(defun helm-describe-variable (var) + "VAR is symbol or string." + (describe-variable (helm-symbolify var)) + (message nil)) + +(defun helm-find-function (func) + "FUNC is symbol or string." + (find-function (helm-symbolify func))) + +(defun helm-find-variable (var) + "VAR is symbol or string." + (find-variable (helm-symbolify var))) + +(defun helm-kill-new (candidate &optional replace) + "CANDIDATE is symbol or string. +See `kill-new' for argument REPLACE." + (kill-new (helm-stringify candidate) replace)) + +(cl-defun helm-fast-remove-dups (seq &key (test 'eq)) + "Remove duplicates elements in list SEQ. +This is same as `remove-duplicates' but with memoisation. +It is much faster, especially in large lists. +A test function can be provided with TEST argument key. +Default is `eq'." + (cl-loop with cont = (make-hash-table :test test) + for elm in seq + unless (gethash elm cont) + do (puthash elm elm cont) + finally return + (cl-loop for i being the hash-values in cont collect i))) + +(defun helm-remove-if-not-match (regexp seq) + "Remove all elements of SEQ that don't match REGEXP." + (cl-loop for s in seq + for str = (cond ((symbolp s) + (symbol-name s)) + ((consp s) + (car s)) + (t s)) + when (string-match-p regexp str) + collect s)) + +(defun helm-remove-if-match (regexp seq) + "Remove all elements of SEQ that match REGEXP." + (cl-loop for s in seq + for str = (cond ((symbolp s) + (symbol-name s)) + ((consp s) + (car s)) + (t s)) + unless (string-match-p regexp str) + collect s)) + +(defun helm-handle-winner-boring-buffers () + "Add `helm-buffer' to `winner-boring-buffers' when quitting/exiting helm. +Add this function to `helm-cleanup-hook' when you don't want to see helm buffers +after running winner-undo/redo." + (require 'winner) + (cl-pushnew helm-buffer winner-boring-buffers :test 'equal)) +(add-hook 'helm-cleanup-hook #'helm-handle-winner-boring-buffers) + +;;;###autoload +(defun helm-quit-and-find-file () + "Drop into `helm-find-files' from `helm'. +If current selection is a buffer or a file, `helm-find-files' +from its directory." + (interactive) + (require 'helm-grep) + (helm-run-after-quit + (lambda (f) + (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)))) + (helm-find-files-1 f))) + (let* ((sel (helm-get-selection)) + (grep-line (and (stringp sel) + (helm-grep-split-line sel))) + (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 (get-buffer sel) (buffer-name it))) + (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 default-directory))) + ;; Bookmark. + (bmk (helm-aif (bookmark-get-filename bmk) + (if (and ffap-url-regexp + (string-match ffap-url-regexp it)) + it (expand-file-name it)) + default-directory)) + ((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. + (grep-line + (with-current-buffer (get-buffer (car grep-line)) + (or (buffer-file-name) default-directory))) + ;; Url. + ((and ffap-url-regexp (string-match ffap-url-regexp sel)) sel) + ;; Default. + (t default-preselection))))) + +;; Same as `vc-directory-exclusion-list'. +(defvar helm-walk-ignore-directories + '("SCCS" "RCS" "CVS" "MCVS" ".svn" ".git" ".hg" ".bzr" + "_MTN" "_darcs" "{arch}" ".gvfs")) + +(cl-defun helm-walk-directory (directory &key (path 'basename) + (directories t) + match skip-subdirs) + "Walk through DIRECTORY tree. +Argument PATH can be one of basename, relative, full, or a function +called on file name, default to basename. +Argument DIRECTORIES when non--nil (default) return also directories names, +otherwise skip directories names. +Argument MATCH can be a predicate or a regexp. +Argument SKIP-SUBDIRS when non--nil will skip `helm-walk-ignore-directories' +unless it is given as a list of directories, in this case this list will be used +instead of `helm-walk-ignore-directories'." + (let* ((result '()) + (fn (cl-case path + (basename 'file-name-nondirectory) + (relative 'file-relative-name) + (full 'identity) + (t path)))) + (cl-labels ((ls-rec (dir) + (unless (and skip-subdirs + (member (helm-basename dir) + (if (listp skip-subdirs) + skip-subdirs + helm-walk-ignore-directories))) + (cl-loop with ls = (sort (file-name-all-completions "" dir) + 'string-lessp) + for f in ls + ;; Use `directory-file-name' to remove the final slash. + ;; Needed to avoid infloop on symlinks symlinking + ;; a directory inside it [1]. + for file = (directory-file-name + (expand-file-name f dir)) + unless (member f '("./" "../")) + ;; A directory. + if (char-equal (aref f (1- (length f))) ?/) + do (progn (when directories + (push (funcall fn file) result)) + ;; Don't recurse in symlinks. + ;; `file-symlink-p' have to be called + ;; on the directory with its final + ;; slash removed [1]. + (and (not (file-symlink-p file)) + (ls-rec file))) + else do + (if match + (and (if (functionp match) + (funcall match f) + (and (stringp match) + (string-match match f))) + (push (funcall fn file) result)) + (push (funcall fn file) result)))))) + (ls-rec directory) + (nreverse result)))) + +(defun helm-generic-sort-fn (s1 s2) + "Sort predicate function for helm candidates. +Args S1 and S2 can be single or \(display . real\) candidates, +that is sorting is done against real value of candidate." + (let* ((reg1 (concat "\\_<" helm-pattern "\\_>")) + (reg2 (concat "\\_<" helm-pattern)) + (split (split-string helm-pattern)) + (str1 (if (consp s1) (cdr s1) s1)) + (str2 (if (consp s2) (cdr s2) s2)) + (score #'(lambda (str r1 r2 lst) + (cond ((string-match r1 str) 4) + ((and (string-match " " helm-pattern) + (string-match (concat "\\_<" (car lst)) str) + (cl-loop for r in (cdr lst) + always (string-match r str))) 3) + ((and (string-match " " helm-pattern) + (cl-loop for r in lst always (string-match r str))) 2) + ((string-match r2 str) 1) + (t 0)))) + (sc1 (funcall score str1 reg1 reg2 split)) + (sc2 (funcall score str2 reg1 reg2 split))) + (cond ((or (zerop (string-width helm-pattern)) + (and (zerop sc1) (zerop sc2))) + (string-lessp str1 str2)) + ((= sc1 sc2) + (< (length str1) (length str2))) + (t (> sc1 sc2))))) + +(defun helm-basename (fname &optional ext) + "Print FNAME with any leading directory components removed. +If specified, also remove filename extension EXT." + (let ((non-essential t)) + (if (and ext (or (string= (file-name-extension fname) ext) + (string= (file-name-extension fname t) ext)) + (not (file-directory-p fname))) + (file-name-sans-extension (file-name-nondirectory fname)) + (file-name-nondirectory (directory-file-name fname))))) + +(defun helm-basedir (fname) + "Return the base directory of filename." + (helm-aif (and fname (file-name-directory fname)) + (file-name-as-directory it))) + +(defun helm-ff-get-host-from-tramp-invalid-fname (fname) + "Extract hostname from an incomplete tramp file name. +Return nil on valid file name remote or not." + (let* ((str (helm-basename fname)) + (split (split-string str ":")) + (meth (car (member (car split) (mapcar 'car tramp-methods))))) + (when (and meth (<= (length split) 2)) + (cadr split)))) + +(cl-defun helm-file-human-size (size &optional (kbsize helm-default-kbsize)) + "Return a string showing SIZE of a file in human readable form. +SIZE can be an integer or a float depending it's value. +`file-attributes' will take care of that to avoid overflow error. +KBSIZE if a floating point number, defaulting to `helm-default-kbsize'." + (let ((M (cons "M" (/ size (expt kbsize 2)))) + (G (cons "G" (/ size (expt kbsize 3)))) + (K (cons "K" (/ size kbsize))) + (B (cons "B" size))) + (cl-loop with result = B + for (a . b) in + (cl-loop for (x . y) in (list M G K B) + unless (< y 1) collect (cons x y)) + when (< b (cdr result)) do (setq result (cons a b)) + finally return (if (string= (car result) "B") + (format "%s" size) + (format "%.1f%s" (cdr result) (car result)))))) + +(cl-defun helm-file-attributes + (file &key type links uid gid access-time modif-time + status size mode gid-change inode device-num dired human-size + mode-type mode-owner mode-group mode-other (string t)) + "Return `file-attributes' elements of FILE separately according to key value. +Availables keys are: +- TYPE: Same as nth 0 `files-attributes' if STRING is nil + otherwise return either symlink, directory or file (default). +- LINKS: See nth 1 `files-attributes'. +- UID: See nth 2 `files-attributes'. +- GID: See nth 3 `files-attributes'. +- ACCESS-TIME: See nth 4 `files-attributes', however format time + when STRING is non--nil (the default). +- MODIF-TIME: See nth 5 `files-attributes', same as above. +- STATUS: See nth 6 `files-attributes', same as above. +- SIZE: See nth 7 `files-attributes'. +- MODE: See nth 8 `files-attributes'. +- 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. +- 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. +However when STRING is non--nil, time and type value are different from what +you have in `file-attributes'." + (let* ((all (cl-destructuring-bind + (type links uid gid access-time modif-time + status size mode gid-change inode device-num) + (file-attributes file string) + (list :type (if string + (cond ((stringp type) "symlink") ; fname + (type "directory") ; t + (t "file")) ; nil + type) + :links links + :uid uid + :gid gid + :access-time (if string + (format-time-string + "%Y-%m-%d %R" access-time) + access-time) + :modif-time (if string + (format-time-string + "%Y-%m-%d %R" modif-time) + modif-time) + :status (if string + (format-time-string + "%Y-%m-%d %R" status) + status) + :size size + :mode mode + :gid-change gid-change + :inode inode + :device-num device-num))) + (modes (helm-split-mode-file-attributes (cl-getf all :mode)))) + (cond (type (cl-getf all :type)) + (links (cl-getf all :links)) + (uid (cl-getf all :uid)) + (gid (cl-getf all :gid)) + (access-time (cl-getf all :access-time)) + (modif-time (cl-getf all :modif-time)) + (status (cl-getf all :status)) + (size (cl-getf all :size)) + (mode (cl-getf all :mode)) + (gid-change (cl-getf all :gid-change)) + (inode (cl-getf all :inode)) + (device-num (cl-getf all :device-num)) + (dired + (concat + (helm-split-mode-file-attributes (cl-getf all :mode) t) " " + (number-to-string (cl-getf all :links)) " " + (cl-getf all :uid) ":" + (cl-getf all :gid) " " + (if human-size + (helm-file-human-size (cl-getf all :size)) + (int-to-string (cl-getf all :size))) " " + (cl-getf all :modif-time))) + (human-size (helm-file-human-size (cl-getf all :size))) + (mode-type (cl-getf modes :mode-type)) + (mode-owner (cl-getf modes :user)) + (mode-group (cl-getf modes :group)) + (mode-other (cl-getf modes :other)) + (t (append all modes))))) + +(defun helm-split-mode-file-attributes (str &optional string) + "Split mode file attributes STR into a proplist. +If STRING is non--nil return instead a space separated string." + (cl-loop with type = (substring str 0 1) + with cdr = (substring str 1) + for i across cdr + for count from 1 + if (<= count 3) + concat (string i) into user + if (and (> count 3) (<= count 6)) + concat (string i) into group + if (and (> count 6) (<= count 9)) + concat (string i) into other + finally return + (if string + (mapconcat 'identity (list type user group other) " ") + (list :mode-type type :user user :group group :other other)))) + +(defun helm-current-directory () + "Return current-directory name at point. +Useful in dired buffers when there is inserted subdirs." + (if (eq major-mode 'dired-mode) + (dired-current-directory) + default-directory)) + +(defmacro with-helm-display-marked-candidates (buffer-or-name candidates &rest body) + (declare (indent 0) (debug t)) + (helm-with-gensyms (buffer window) + `(let* ((,buffer (temp-buffer-window-setup ,buffer-or-name)) + ,window) + (unwind-protect + (with-current-buffer ,buffer + (dired-format-columns-of-files ,candidates) + (select-window + (setq ,window (temp-buffer-window-show + ,buffer + '(display-buffer-below-selected + (window-height . fit-window-to-buffer))))) + (progn ,@body)) + (quit-window 'kill ,window))))) + +;;; Persistent Action Helpers +;; +;; +;; Internal +(defvar helm-match-line-overlay nil) +(defvar helm--match-item-overlays nil) + +(defun helm-highlight-current-line (&optional start end buf face pulse) + "Highlight and underline current position" + (let* ((start (or start (line-beginning-position))) + (end (or end (1+ (line-end-position)))) + (start-match (if (or (zerop helm-highlight-number-lines-around-point) + (null helm-highlight-number-lines-around-point)) + start + (save-excursion + (forward-line + (- helm-highlight-number-lines-around-point)) + (point-at-bol)))) + (end-match (if (or (zerop helm-highlight-number-lines-around-point) + (null helm-highlight-number-lines-around-point)) + end + (save-excursion + (forward-line + helm-highlight-number-lines-around-point) + (point-at-eol)))) + (args (list start end buf))) + (if (not helm-match-line-overlay) + (setq helm-match-line-overlay (apply 'make-overlay args)) + (apply 'move-overlay helm-match-line-overlay args)) + (overlay-put helm-match-line-overlay + 'face (or face 'helm-selection-line)) + (catch 'empty-line + (cl-loop with ov + for r in (helm-remove-if-match + "\\`!" (split-string helm-pattern)) + do (save-excursion + (goto-char start-match) + (while (condition-case _err + (re-search-forward r end-match t) + (invalid-regexp nil)) + (let ((s (match-beginning 0)) + (e (match-end 0))) + (if (= s e) + (throw 'empty-line nil) + (push (setq ov (make-overlay s e)) + helm--match-item-overlays) + (overlay-put ov 'face 'helm-match-item) + (overlay-put ov 'priority 1))))))) + (recenter) + (when pulse + (sit-for 0.3) + (helm-match-line-cleanup)))) + +(defun helm-match-line-cleanup () + (when helm-match-line-overlay + (delete-overlay helm-match-line-overlay) + (setq helm-match-line-overlay nil)) + (when helm--match-item-overlays + (mapc 'delete-overlay helm--match-item-overlays))) + +(defun helm-match-line-update () + (when helm-match-line-overlay + (delete-overlay helm-match-line-overlay) + (helm-highlight-current-line))) + +(defun helm-persistent-autoresize-hook () + (when (and helm-buffers-to-resize-on-pa + (member helm-buffer helm-buffers-to-resize-on-pa) + (eq helm-split-window-state 'vertical)) + (set-window-text-height (helm-window) helm-resize-on-pa-text-height))) + +(add-hook 'helm-after-persistent-action-hook 'helm-persistent-autoresize-hook) +(add-hook 'helm-cleanup-hook 'helm-match-line-cleanup) +(add-hook 'helm-after-persistent-action-hook 'helm-match-line-update) + +(defun helm-w32-prepare-filename (file) + "Convert filename FILE to something usable by external w32 executables." + (replace-regexp-in-string ; For UNC paths + "/" "\\" + (replace-regexp-in-string ; Strip cygdrive paths + "/cygdrive/\\(.\\)" "\\1:" + file nil nil) nil t)) + +;;;###autoload +(defun helm-w32-shell-execute-open-file (file) + (interactive "fOpen file:") + (with-no-warnings + (w32-shell-execute "open" (helm-w32-prepare-filename file)))) + +(defun helm-open-file-with-default-tool (file) + "Open FILE with the default tool on this platform." + (let (process-connection-type) + (if (eq system-type 'windows-nt) + (helm-w32-shell-execute-open-file file) + (start-process "helm-open-file-with-default-tool" + nil + (cond ((eq system-type 'gnu/linux) + "xdg-open") + ((or (eq system-type 'darwin) ;; Mac OS X + (eq system-type 'macos)) ;; Mac OS 9 + "open")) + file)))) + +(defun helm-open-dired (file) + "Opens a dired buffer in FILE's directory. If FILE is a +directory, open this directory." + (if (file-directory-p file) + (dired file) + (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)) + (remote-path (format "/%s:%s:%s" + helm-su-or-sudo + (or host "") + (expand-file-name + (if host + (file-remote-p candidate 'localname) + candidate)))) + non-essential) + (if (buffer-live-p (get-buffer buf)) + (progn + (set-buffer buf) + (find-alternate-file remote-path)) + (find-file remote-path)))) + +(defun helm-find-many-files (_ignore) + (let ((helm--reading-passwd-or-string t)) + (mapc 'find-file (helm-marked-candidates)))) + +(defun helm-quit-and-execute-action (action) + "Quit current helm session and execute ACTION." + (setq helm-saved-action action) + (helm-exit-minibuffer)) + +;; Yank text at point. +;; +;; +;; Internal +(defvar helm-yank-point nil) + +;;;###autoload +(defun helm-yank-text-at-point () + "Yank text at point in `helm-current-buffer' into minibuffer. +If `helm-yank-symbol-first' is non--nil the first yank +grabs the entire symbol." + (interactive) + (with-helm-current-buffer + (let ((fwd-fn (if helm-yank-symbol-first + 'forward-symbol 'forward-word))) + ;; Start to initial point if C-w have never been hit. + (unless helm-yank-point (setq helm-yank-point (point))) + (save-excursion + (goto-char helm-yank-point) + (funcall fwd-fn 1) + (helm-set-pattern + (concat + helm-pattern (replace-regexp-in-string + "\\`\n" "" + (buffer-substring-no-properties + helm-yank-point (point))))) + (setq helm-yank-point (point)))))) + +(defun helm-reset-yank-point () + (setq helm-yank-point nil)) + +(defun helm-read-repeat-string (prompt &optional count) + "Prompt as many time PROMPT is not empty. +If COUNT is non--nil add a number after each prompt." + (cl-loop with elm + while (not (string= elm "")) + for n from 1 + do (when count + (setq prompt (concat prompt (int-to-string n) ": "))) + collect (setq elm (helm-read-string prompt)) into lis + finally return (remove "" lis))) + +(add-hook 'helm-cleanup-hook 'helm-reset-yank-point) +(add-hook 'helm-after-initialize-hook 'helm-reset-yank-point) + +(defun helm-html-bookmarks-to-alist (file url-regexp bmk-regexp) + "Parse html bookmark FILE and return an alist with (title . url) as elements." + (let (bookmarks-alist url title) + (with-temp-buffer + (insert-file-contents file) + (goto-char (point-min)) + (while (re-search-forward "href=\\|^ *

q\" '(foo bar baz) 2) + +Each time \" q\" is pressed the next function is executed, if you wait +More than 2 seconds, next hit will run again the first function and so on." + (define-key keymap key (helm-make-multi-command functions delay))) + +;;;###autoload +(defmacro helm-multi-key-defun (name docstring funs &optional delay) + "Define NAME as a multi-key command running FUNS. +After DELAY seconds the FUNS list is reinitialised. +See `helm-define-multi-key'." + (declare (indent 2)) + (setq docstring (if docstring (concat docstring "\n\n") + "This is a helmish multi-key command.")) + `(defalias (quote ,name) (helm-make-multi-command ,funs ,delay) ,docstring)) + +(defun helm-make-multi-command (functions &optional delay) + "Return an anonymous multi-key command running FUNCTIONS. +Run each function of FUNCTIONS list in turn when called within DELAY seconds." + (declare (indent 1)) + (let ((funs functions) + (iter (cl-gensym "helm-iter-key")) + (timeout delay)) + (eval (list 'defvar iter nil)) + #'(lambda () (interactive) (helm-run-multi-key-command funs iter timeout)))) + +(defun helm-run-multi-key-command (functions iterator delay) + (let ((fn #'(lambda () + (cl-loop for count from 1 to (length functions) + collect count))) + next) + (unless (and (symbol-value iterator) + ;; Reset iterator when another key is pressed. + (eq this-command real-last-command)) + (set iterator (helm-iter-list (funcall fn)))) + (setq next (helm-iter-next (symbol-value iterator))) + (unless next + (set iterator (helm-iter-list (funcall fn))) + (setq next (helm-iter-next (symbol-value iterator)))) + (and next (symbol-value iterator) (call-interactively (nth (1- next) functions))) + (when delay (run-with-idle-timer delay nil `(lambda () + (setq ,iterator nil)))))) + +(defun helm-iter-list (seq) + "Return an iterator object from SEQ." + (let ((lis seq)) + (lambda () + (let ((elm (car lis))) + (setq lis (cdr lis)) + elm)))) + +(defun helm-iter-next (iterator) + "Return next elm of ITERATOR." + (funcall iterator)) + +(helm-multi-key-defun helm-toggle-resplit-and-swap-windows + "Multi key command to resplit and swap helm window. +First call run `helm-toggle-resplit-window', +second call within 0.5s run `helm-swap-windows'." + '(helm-toggle-resplit-window helm-swap-windows) 1) + +;;;###autoload +(defun helm-define-key-with-subkeys (map key subkey command + &optional other-subkeys menu exit-fn) + "Allow defining in MAP a KEY and SUBKEY to COMMAND. + +This allow typing KEY to call COMMAND the first time and +type only SUBKEY on subsequent calls. + +Arg MAP is the keymap to use, SUBKEY is the initial short keybinding to +call COMMAND. + +Arg OTHER-SUBKEYS is an alist specifying other short keybindings +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))\) + + +In this example, `C-x v n' will run `git-gutter:next-hunk' +subsequent hits on \"n\" will run this command again +and subsequent hits on \"p\" will run `git-gutter:previous-hunk'. + +Arg MENU is a string to display in minibuffer +to describe SUBKEY and OTHER-SUBKEYS. +Arg EXIT-FN specify a function to run on exit. + +Any other keys pressed run their assigned command defined in MAP +and exit the loop running EXIT-FN if specified. + +NOTE: SUBKEY and OTHER-SUBKEYS bindings support +only char syntax actually (e.g ?n) +so don't use strings, vectors or whatever to define them." + (declare (indent 1)) + (define-key map key + (lambda () + (interactive) + (unwind-protect + (progn + (call-interactively command) + (while (let ((input (read-key menu)) 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)))))) + + +;;; Keymap +;; +;; +(defvar helm-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map minibuffer-local-map) + (define-key map (kbd "") 'helm-next-line) + (define-key map (kbd "") 'helm-previous-line) + (define-key map (kbd "C-n") 'helm-next-line) + (define-key map (kbd "C-p") 'helm-previous-line) + (define-key map (kbd "") 'helm-follow-action-forward) + (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-<") 'helm-beginning-of-buffer) + (define-key map (kbd "M->") 'helm-end-of-buffer) + (define-key map (kbd "C-g") 'helm-keyboard-quit) + (define-key map (kbd "") 'helm-next-source) + (define-key map (kbd "") 'helm-previous-source) + (define-key map (kbd "") 'helm-maybe-exit-minibuffer) + (define-key map (kbd "C-i") 'helm-select-action) + (define-key map (kbd "C-z") 'helm-execute-persistent-action) + (define-key map (kbd "C-j") 'helm-execute-persistent-action) + (define-key map (kbd "C-o") 'helm-next-source) + (define-key map (kbd "C-l") 'helm-recenter-top-bottom-other-window) + (define-key map (kbd "M-C-l") 'helm-reposition-window-other-window) + (define-key map (kbd "C-M-v") 'helm-scroll-other-window) + (define-key map (kbd "M-") 'helm-scroll-other-window) + (define-key map (kbd "C-M-y") 'helm-scroll-other-window-down) + (define-key map (kbd "C-M-S-v") 'helm-scroll-other-window-down) + (define-key map (kbd "M-") 'helm-scroll-other-window-down) + (define-key map (kbd "") 'helm-scroll-other-window) + (define-key map (kbd "") 'helm-scroll-other-window-down) + (define-key map (kbd "C-@") 'helm-toggle-visible-mark) + (define-key map (kbd "C-SPC") 'helm-toggle-visible-mark) + (define-key map (kbd "M-SPC") 'helm-toggle-visible-mark) + (define-key map (kbd "M-[") nil) + (define-key map (kbd "M-(") 'helm-prev-visible-mark) + (define-key map (kbd "M-)") 'helm-next-visible-mark) + (define-key map (kbd "C-k") 'helm-delete-minibuffer-contents) + (define-key map (kbd "C-x C-f") 'helm-quit-and-find-file) + (define-key map (kbd "M-m") 'helm-toggle-all-marks) + (define-key map (kbd "M-a") 'helm-mark-all) + (define-key map (kbd "M-u") 'helm-unmark-all) + (define-key map (kbd "C-w") 'helm-yank-text-at-point) + (define-key map (kbd "C-M-a") 'helm-show-all-in-this-source-only) + (define-key map (kbd "C-M-e") 'helm-display-all-sources) + (define-key map (kbd "C-r") 'undefined) + (define-key map (kbd "C-s") 'undefined) + (define-key map (kbd "M-s") 'undefined) + (define-key map (kbd "C-}") 'helm-narrow-window) + (define-key map (kbd "C-{") 'helm-enlarge-window) + (define-key map (kbd "C-c -") 'helm-swap-windows) + (define-key map (kbd "C-c C-d") 'helm-delete-current-selection) + (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-f") 'helm-follow-mode) + (define-key map (kbd "C-c C-u") 'helm-force-update) + (define-key map (kbd "M-p") 'previous-history-element) + (define-key map (kbd "M-n") 'next-history-element) + (define-key map (kbd "C-!") 'helm-toggle-suspend-update) + (define-key map (kbd "C-x b") 'helm-resume-previous-session-after-quit) + (define-key map (kbd "C-x C-b") 'helm-resume-list-buffers-after-quit) + ;; Disable `file-cache-minibuffer-complete'. + (define-key map (kbd "") 'undefined) + ;; Multi keys + (define-key map (kbd "C-t") 'helm-toggle-resplit-and-swap-windows) + ;; Debugging command + (define-key map (kbd "C-h C-d") 'undefined) + (define-key map (kbd "C-h C-d") 'helm-debug-output) + ;; Use `describe-mode' key in `global-map'. + (define-key map [f1] nil) ; Allow to eval keymap without errors. + (define-key map (kbd "C-h C-h") 'undefined) + (define-key map (kbd "C-h h") 'undefined) + (cl-dolist (k (where-is-internal 'describe-mode global-map)) + (define-key map k 'helm-help)) + ;; Bind all actions from 1 to 12 to their corresponding nth index+1. + (cl-loop for n from 0 to 12 do + (define-key map (kbd (format "" (1+ n))) + `(lambda () + (interactive) + (helm-select-nth-action ,n)))) + map) + "Keymap for helm.") + + +(defgroup helm nil + "Open helm." + :prefix "helm-" :group 'convenience) + +(defcustom helm-completion-window-scroll-margin 5 + " `scroll-margin' to use for helm completion window. +Which see. Set to 0 to disable. +NOTE: This have no effect when `helm-display-source-at-screen-top' +id non--nil." + :group 'helm + :type 'integer) + +(defcustom helm-display-source-at-screen-top t + "Display candidates at the top of screen. +This happen when using `helm-next-source' and `helm-previous-source'. +NOTE: When non--nil (default) disable `helm-completion-window-scroll-margin'." + :group 'helm + :type 'boolean) + +(defcustom helm-candidate-number-limit 100 + "Limit candidate number globally. +Do not show more candidates than this limit from individual sources. +It is usually pointless to show hundreds of matches +when the pattern is empty, because it is much simpler to type a +few characters to narrow down the list of potential candidates. + +Set it to nil if you don't want this limit." + :group 'helm + :type '(choice (const :tag "Disabled" nil) integer)) + +(defcustom helm-idle-delay 0.01 + "Be idle for this many seconds, before updating in delayed sources. +This is useful for sources involving heavy operations +\(like launching external programs\), so that candidates +from the source are not retrieved unnecessarily if the user keeps typing. + +It also can be used to declutter the results helm displays, +so that results from certain sources are not shown with every +character typed, only if the user hesitates a bit. +Be sure to know what you are doing when modifying this." + :group 'helm + :type 'float) + +(defcustom helm-input-idle-delay 0.01 + "Be idle for this many seconds, before updating. + +Unlike `helm-idle-delay', it is also effective for non-delayed sources. +If nil, candidates are collected immediately. + +Note: If this value is too low compared to `helm-idle-delay', +you may have duplicated sources when using multiples sources. +Safe value is always >= `helm-idle-delay'. +Default settings are equal value for both. +Be sure to know what you are doing when modifying this." + :group 'helm + :type 'float) + +(defcustom helm-exit-idle-delay 0 + "Be idle for this many seconds before exiting minibuffer while helm is updating. +Note that this does nothing when helm-buffer is up to date +\(i.e exit without delay in this condition\)." + :group 'helm + :type 'float) + +(defcustom helm-full-frame nil + "Use current window to show the candidates. +If t then Helm doesn't pop up a new window." + :group 'helm + :type 'boolean) + +(defvaralias 'helm-samewindow 'helm-full-frame) +(make-obsolete-variable 'helm-samewindow 'helm-full-frame "1.4.8.1") + +(defcustom helm-quick-update nil + "If non-nil, suppress displaying sources which are out of screen at first. +They are treated as delayed sources at this input. +This flag makes `helm' a bit faster with many sources." + :group 'helm + :type 'boolean) + +(defcustom helm-candidate-separator + "--------------------" + "Candidates separator of `multiline' source." + :group 'helm + :type 'string) + +(defcustom helm-save-configuration-functions + '(set-window-configuration . current-window-configuration) + "The functions used to restore/save window or frame configurations. +It is a pair where the car is the function to restore window or frame config, +and the cdr is the function to save the window or frame config. + +If you want to save and restore frame configuration, set this variable to + '\(set-frame-configuration . current-frame-configuration\) +NOTE: This may not work properly with own-frame minibuffer settings. +Older version saves/restores frame configuration, but the default is changed now +because flickering can occur in some environment." + :group 'helm + :type 'sexp) + +(defcustom helm-persistent-action-use-special-display nil + "If non-nil, use `special-display-function' in persistent action." + :group 'helm + :type 'boolean) + +(defcustom helm-scroll-amount nil + "Scroll amount when scrolling other window in a helm session. +It is used by `helm-scroll-other-window' +and `helm-scroll-other-window-down'. + +If you prefer scrolling line by line, set this value to 1." + :group 'helm + :type 'integer) + +(defcustom helm-display-function 'helm-default-display-buffer + "Function to display *helm* buffer. +It is `helm-default-display-buffer' by default, +which affects `helm-full-frame'." + :group 'helm + :type 'symbol) + +(defcustom helm-case-fold-search 'smart + "Add 'smart' option to `case-fold-search'. +When smart is enabled, ignore case in the search strings +if pattern contains no uppercase characters. +Otherwise, with a nil or t value, the behavior is same as +`case-fold-search'. +Default value is smart, other possible values are nil and t. +NOTE: This have no effect in asynchronous sources, you will +have to implement a similar feature directly in the process. +See in helm-grep.el how it is implemented." + :group 'helm + :type '(choice (const :tag "Ignore case" t) + (const :tag "Respect case" nil) + (other :tag "Smart" 'smart))) + +(defcustom helm-file-name-case-fold-search + (if (memq system-type + '(cygwin windows-nt ms-dos darwin)) + t + helm-case-fold-search) + "Local setting of `helm-case-fold-search' for reading filenames. + +See `helm-case-fold-search' for more info." + :group 'helm + :type 'symbol) + +(defcustom helm-reuse-last-window-split-state nil + "Reuse the last state of window split, vertical or horizontal. +That is when you use `helm-toggle-resplit-window' the next helm session +will reuse the same window scheme than the one of last session unless +`helm-split-window-default-side' is 'same or 'other." + :group 'helm + :type 'boolean) + +(defcustom helm-split-window-preferred-function 'helm-split-window-default-fn + "Default function used for splitting window." + :group 'helm + :type 'function) + +(defcustom helm-split-window-default-side 'below + "The default side to display `helm-buffer'. +Must be one acceptable arg for `split-window' SIDE, +that is 'below, 'above, 'left or 'right. + +Other acceptable values are 'same which always display `helm-buffer' +in current window and 'other that display `helm-buffer' below if only one +window or in `other-window-for-scrolling' if available. + +A nil value as same effect as 'below. +If `helm-full-frame' is non--nil, it take precedence on this. + +See also `helm-split-window-in-side-p' and `helm-always-two-windows' that +take precedence on this. + +NOTE: this have no effect if `helm-split-window-preferred-function' is not +`helm-split-window-default-fn' unless this new function handle this." + :group 'helm + :type 'symbol) + +(defcustom helm-split-window-in-side-p nil + "Force splitting inside selected window when non--nil. +See also `helm-split-window-default-side'. + +NOTE: this have no effect if `helm-split-window-preferred-function' is not +`helm-split-window-default-fn' unless this new function handle this." + :group 'helm + :type 'boolean) + +(defcustom helm-always-two-windows nil + "When non--nil helm will use two windows in this frame. +That is one window to display `helm-buffer' and one to display +`helm-current-buffer'. +Note: this have no effect when `helm-split-window-in-side-p' is non--nil, +or when `helm-split-window-default-side' is set to 'same. +When `helm-autoresize-mode' is enabled, setting this to nil +will have no effect until this mode will be disabled." + :group 'helm + :type 'boolean) + +(defcustom helm-sources-using-default-as-input '(helm-source-imenu + helm-source-info-elisp + helm-source-etags-select) + "List of helm sources that need to use `helm-maybe-use-default-as-input'. +When a source is member of this list, default `thing-at-point' +will be used as input." + :group 'helm + :type '(repeat (choice symbol))) + +(defcustom helm-delete-minibuffer-contents-from-point t + "When non--nil, `helm-delete-minibuffer-contents' delete region from `point'. +Otherwise delete `minibuffer-contents'. +See documentation of `helm-delete-minibuffer-contents'." + :group 'helm + :type 'boolean) + +(defcustom helm-follow-mode-persistent nil + "Retrieve last state of `helm-follow-mode' in next helm session when non--nil. +This will not make it persistent through emacs sessions though, +you will have to set explicitely the `follow' attribute in the source where +you want this mode enabled definitely." + :group 'helm + :type 'boolean) + +(defcustom helm-prevent-escaping-from-minibuffer t + "Prevent escaping from minibuffer during helm session." + :group 'helm + :type 'boolean) + +(defcustom helm-truncate-lines nil + "Truncate long lines when non--nil. +See `truncate-lines'." + :group 'helm + :type 'boolean) + +(defcustom helm-move-to-line-cycle-in-source nil + "Move to end or beginning of source when reaching top or bottom of source. +This happen when using `helm-next/previous-line'." + :group 'helm + :type 'boolean) + +(defcustom helm-fuzzy-match-fn 'helm-fuzzy-match + "The function for fuzzy matching in `helm-source-sync' based sources." + :group 'helm + :type 'function) + +(defcustom helm-fuzzy-search-fn 'helm-fuzzy-search + "The function for fuzzy matching in `helm-source-in-buffer' based sources." + :group 'helm + :type 'function) + +(defcustom helm-fuzzy-sort-fn 'helm-fuzzy-matching-default-sort-fn + "The sort transformer function used in fuzzy matching. +When nil no sorting will be done." + :group 'helm + :type 'function) + +(defcustom helm-fuzzy-matching-highlight-fn 'helm-fuzzy-default-highlight-match + "The function to highlight matches in fuzzy matching. +When nil no highlighting will be done." + :group 'helm + :type 'function) + +(defcustom helm-autoresize-max-height 40 + "Specifies a maximum height and defaults to the height of helm window's frame in percentage. + +See `fit-window-to-buffer' for more infos." + :group 'helm + :type 'integer) + +(defcustom helm-autoresize-min-height 10 + "Specifies a minimum height and defaults to the height of helm window's frame in percentage. + +If nil the default of `window-min-height' is used +See `fit-window-to-buffer' for more infos." + :group 'helm + :type 'integer) + +(defcustom helm-input-method-verbose-flag nil + "The default value of `input-method-verbose-flag' to use in helm minibuffer. +It is nil by default to allow helm updating and exiting without turning off +the input method when complex methods are in use, if you set it to any other +value allowed by `input-method-verbose-flag' you will have at each time you want +to exit or helm update to disable the `current-input-method' with `C-\\'." + :group 'helm + :type '(radio :tag "A flag to control extra guidance given by input methods in helm." + (const :tag "Never provide guidance" nil) + (const :tag "Always provide guidance" t) + (const :tag "Provide guidance only in complex methods" complex-only))) + +(defcustom helm-display-header-line t + "Display header-line when non nil." + :group 'helm + :type 'boolean) + +(defcustom helm-file-globstar t + "Same as globstar bash shopt option. +When non--nil a pattern beginning with two stars will expand recursively. +Directories expansion is not supported yet." + :group 'helm + :type 'boolean) + +(defcustom helm-inherit-input-method t + "Inherit `current-input-method' from `current-buffer' when non--nil. +The default is to enable this by default, the user can toggle the current +input method with `toggle-input-method'." + :group 'helm + :type 'boolean) + +;;; Faces +;; +;; +(defgroup helm-faces nil + "Customize the appearance of helm." + :prefix "helm-" + :group 'faces + :group 'helm) + +(defface helm-source-header + '((((background dark)) + :background "#22083397778B" + :foreground "white" + :weight bold :height 1.3 :family "Sans Serif") + (((background light)) + :background "#abd7f0" + :foreground "black" + :weight bold :height 1.3 :family "Sans Serif")) + "Face for source header in the helm buffer." + :group 'helm-faces) + +(defface helm-visible-mark + '((((min-colors 88) (background dark)) + (:background "green1" :foreground "black")) + (((background dark)) + (:background "green" :foreground "black")) + (((background light)) :background "#d1f5ea") + (((min-colors 88)) + (:background "green1")) + (t (:background "green"))) + "Face for visible mark." + :group 'helm-faces) + +(defface helm-header + '((t (:inherit header-line))) + "Face for header lines in the helm buffer." + :group 'helm-faces) + +(defface helm-candidate-number + '((((background dark)) :background "Yellow" :foreground "black") + (((background light)) :background "#faffb5" :foreground "black")) + "Face for candidate number in mode-line." :group 'helm-faces) + +(defface helm-selection + '((((background dark)) :background "ForestGreen" + :distant-foreground "black") + (((background light)) :background "#b5ffd1" + :distant-foreground "black")) + "Face for currently selected item in the helm buffer." + :group 'helm-faces) + +(defface helm-separator + '((((background dark)) :foreground "red") + (((background light)) :foreground "#ffbfb5")) + "Face for multiline source separator." + :group 'helm-faces) + +(defface helm-action + '((t (:underline t))) + "Face for action lines in the helm action buffer." + :group 'helm-faces) + +(defface helm-prefarg + '((((background dark)) :foreground "green") + (((background light)) :foreground "red")) + "Face for showing prefix arg in mode-line." + :group 'helm-faces) + +(defface helm-match + '((((background light)) :foreground "#b00000") + (((background dark)) :foreground "gold1")) + "Face used to highlight matches." + :group 'helm) + + +;;; Variables. +;; +;; +(defvar helm-type-attributes nil + "It's a list of \(TYPE ATTRIBUTES ...\). +ATTRIBUTES are the same as attributes for `helm-sources'. +TYPE connects the value to the appropriate sources. +Don't set this directly, use instead `define-helm-type-attribute'. + +This allows specifying common attributes for several sources. +For example, sources which provide files can specify +common attributes with a `file' type.") + +(defvar helm-source-filter nil + "A list of source names to be displayed. +Other sources won't appear in the search results. +If nil then there is no filtering. +See also `helm-set-source-filter'.") + +(defvar helm-action-buffer "*helm action*" + "Buffer showing actions.") + +(defvar helm-selection-overlay nil + "Overlay used to highlight the currently selected item.") + +(defvar helm-async-processes nil + "List of information about asynchronous processes managed by helm.") + +(defvar helm-before-initialize-hook nil + "Run before helm initialization. +This hook is run before init functions in `helm-sources', +that is before creation of `helm-buffer'. +Local variables for `helm-buffer' that need a value from `current-buffer' +can be set here with `helm-set-local-variable'.") + +(defvar helm-after-initialize-hook nil + "Run after helm initialization. +This hook run inside `helm-buffer' once created. +Variables are initialized and the `helm-buffer' is created. +But the `helm-buffer' has no contents.") + +(defvar helm-update-hook nil + "Run after the helm buffer was updated according the new input pattern. +This hook is run at the beginning of buffer. +The first candidate is selected after running this hook. +See also `helm-after-update-hook'.") + +(defvar helm-after-update-hook nil + "Run after the helm buffer was updated according the new input pattern. +This is very similar to `helm-update-hook' but selection is not moved. +It is useful to select a particular object instead of the first one.") + +(defvar helm-cleanup-hook nil + "Run after helm minibuffer is closed. +IOW this hook is executed BEFORE performing action.") + +(defvar helm-select-action-hook nil + "Run when opening the action buffer.") + +(defvar helm-before-action-hook nil + "Run before executing action. +Contrarily to `helm-cleanup-hook', +this hook run before helm minibuffer is closed +and before performing action.") + +(defvar helm-after-action-hook nil + "Run after executing action.") + +(defvar helm-exit-minibuffer-hook nil + "Run just before exiting minibuffer.") + +(defvar helm-after-persistent-action-hook nil + "Run after executing persistent action.") + +(defvar helm-move-selection-before-hook nil + "Run before moving selection in `helm-buffer'.") + +(defvar helm-move-selection-after-hook nil + "Run after moving selection in `helm-buffer'.") + +(defvar helm-window-configuration-hook nil + "Run when switching to and back from action buffer.") + +(defconst helm-restored-variables + '(helm-candidate-number-limit + helm-source-filter + helm-source-in-each-line-flag + helm-map + helm-sources) + "Variables which are restored after `helm' invocation.") + +(defvar helm-execute-action-at-once-if-one nil + "Execute default action and exit when only one candidate is remaining.") + +(defvar helm-quit-if-no-candidate nil + "Quit when there is no candidates when non--nil. +This variable accepts a function, which is executed if no candidate.") + +(defvar helm-maybe-use-default-as-input nil + "Use :default arg of `helm' as input to update display. +Note that if also :input is specified as `helm' arg, it will take +precedence on :default.") + +(defvar helm-source-in-each-line-flag nil + "Non-nil means add helm-source text-property in each candidate. +experimental feature.") + +(defvar helm-debug-variables nil + "A list of helm variables to show in `helm-debug-output'. +Otherwise all variables started with `helm-' are shown.") + +(defvar helm-debug-buffer "*Debug Helm Log*") + +(defvar helm-debug nil + "If non-nil, write log message into `helm-debug-buffer' buffer. +It is disabled by default because `helm-debug-buffer' grows quickly.") + +(defvar helm-compile-source-functions + '(helm-compile-source--type + helm-compile-source--dummy + helm-compile-source--candidates-in-buffer) + "Functions to compile elements of `helm-sources' (plug-in).") + +(defvar helm-mode-line-string "\ +\\\ +\\[helm-help]:Help \ +\\[helm-select-action]:Act \ +\\[helm-maybe-exit-minibuffer]/\ +f1/f2/f-n:NthAct" + "Help string displayed in mode-line in `helm'. +It can be a string or a list of two args, in this case, +first arg is a string that will be used as name for candidates number, +second arg any string to display in mode line. +If nil, use default `mode-line-format'.") + + +;;; Internal Variables +;; +;; +(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 + "Value of the current source when the action list is shown.") +(defvar helm-compiled-sources nil + "Compiled version of `helm-sources'.") +(defvar helm-in-persistent-action nil + "Flag whether in persistent-action or not.") +(defvar helm-last-buffer nil + "`helm-buffer' of previously `helm' session.") +(defvar helm-saved-selection nil + "Value of the currently selected object when the action list is shown.") +(defvar helm-sources nil + "[INTERNAL] Value of current sources in use, a list.") +(defvar helm-buffer "*helm*" + "Buffer showing completions.") +(defvar helm-current-buffer nil + "Current buffer when `helm' is invoked.") +(defvar helm-buffer-file-name nil + "Variable `buffer-file-name' when `helm' is invoked.") +(defvar helm-default-directory nil + "The value of `default-directory' when `helm' is initialized.") +(defvar helm-candidate-cache (make-hash-table :test 'equal) + "Holds the available candidate within a single helm invocation.") +(defvar helm-pattern "" + "The input pattern used to update the helm buffer.") +(defvar helm-input "" + "The input typed in the candidates panel.") +(defvar helm-input-local nil + "Internal, store locally `helm-pattern' value for later use in `helm-resume'.") +(defvar helm-source-name nil) +(defvar helm-current-source nil) +(defvar helm-candidate-buffer-alist nil) +(defvar helm-match-hash (make-hash-table :test 'equal)) +(defvar helm-cib-hash (make-hash-table :test 'equal)) +(defvar helm-tick-hash (make-hash-table :test 'equal)) +(defvar helm-issued-errors nil) +(defvar helm-debug-root-directory nil + "When non--nil, save helm log to `helm-last-log-file'. +Be aware that if you set that, you will end up with a huge directory +of log files, so use that only for debugging purpose. +See `helm-log-save-maybe' for more info.") +(defvar helm-last-log-file nil + "The name of the last helm session log file.") +(defvar helm-follow-mode nil) +(defvar helm--local-variables nil) +(defvar helm-split-window-state nil) +(defvar helm--window-side-state nil) +(defvar helm-selection-point nil) +(defvar helm-alive-p nil) +(defvar helm-visible-mark-overlays nil) +(defvar helm-update-blacklist-regexps '("^" "^ *" "$" "!" " " "\\b" + "\\<" "\\>" "\\_<" "\\_>" ".*")) +(defvar helm-suspend-update-flag nil) +(defvar helm-force-updating-p nil) +(defvar helm-exit-status 0 + "Flag to inform whether helm have exited or quitted. +Exit with 0 mean helm have exited executing an action. +Exit with 1 mean helm have quitted with \\[keyboard-quit] +It is useful for example to restore a window config if helm abort +in special cases. +See `helm-exit-minibuffer' and `helm-keyboard-quit'.") +(defvar helm-minibuffer-confirm-state nil) +(defvar helm-quit nil) +(defvar helm-attributes nil "List of all `helm' attributes.") +(defvar helm-buffers nil + "All of `helm-buffer' in most recently used order.") +(defvar helm-current-position nil + "Cons of \(point . window-start\) when `helm' is invoked. +It is needed to restore position in `helm-current-buffer' +when `helm' is keyboard-quitted.") +(defvar helm-last-frame-or-window-configuration nil + "Used to store window or frame configuration when helm start.") +(defvar helm-onewindow-p nil) +(defvar helm-types nil) +(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 candadates. 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.") +(defvar helm--reading-passwd-or-string nil) +(defvar helm--in-update nil) +(defvar helm--in-fuzzy nil) + +;; Utility: logging +(defun helm-log (format-string &rest args) + "Log message `helm-debug' is non-nil. +Messages are written to the `helm-debug-buffer' buffer. + +Argument FORMAT-STRING is a string to use with `format'. +Use optional arguments ARGS like in `format'." + (when helm-debug + (with-current-buffer (get-buffer-create helm-debug-buffer) + (outline-mode) + (buffer-disable-undo) + (set (make-local-variable 'inhibit-read-only) t) + (goto-char (point-max)) + (insert (let ((tm (current-time))) + (format (concat (if (string-match "Start session" format-string) + "* " "** ") + "%s.%06d (%s)\n %s\n") + (format-time-string "%H:%M:%S" tm) + (nth 2 tm) + (helm-log-get-current-function) + (apply #'format (cons format-string args)))))))) + +(defun helm-log-run-hook (hook) + "Run HOOK like `run-hooks' but write these actions to helm log buffer." + (helm-log "Executing %s with value = %S" hook (symbol-value hook)) + (helm-log "Executing %s with global value = %S" hook (default-value hook)) + (run-hooks hook) + (helm-log "executed %s" hook)) + +(defun helm-log-get-current-function () + "Get function name calling `helm-log'. +The original idea is from `tramp-debug-message'." + (cl-loop with exclude-func-re = "^helm-\\(?:interpret\\|log\\|.*funcall\\)" + for btn from 1 to 40 + for btf = (cl-second (backtrace-frame btn)) + for fn = (if (symbolp btf) (symbol-name btf) "") + if (and (string-match "^helm" fn) + (not (string-match exclude-func-re fn))) + return fn)) + +(defun helm-log-error (&rest args) + "Accumulate error messages into `helm-issued-errors'. +ARGS are args given to `format'. +e.g (helm-log-error \"Error %s: %s\" (car err) (cdr err))." + (apply 'helm-log (concat "ERROR: " (car args)) (cdr args)) + (let ((msg (apply 'format args))) + (unless (member msg helm-issued-errors) + (add-to-list 'helm-issued-errors msg)))) + +(defun helm-log-save-maybe () + "May be save log buffer to `helm-last-log-file'. +If `helm-debug-root-directory' is non--nil and a valid directory, +a directory named 'helm-debug-' +will be created there and the log recorded in a file named +at the date and time of today in this directory." + (when (and (stringp helm-debug-root-directory) + (file-directory-p helm-debug-root-directory) + helm-debug) + (let ((logdir (expand-file-name (concat "helm-debug-" + (format-time-string "%Y%m%d")) + helm-debug-root-directory))) + (make-directory logdir t) + (with-current-buffer (get-buffer-create helm-debug-buffer) + (write-region (point-min) (point-max) + (setq helm-last-log-file + (expand-file-name + (format-time-string "%Y%m%d-%H%M%S") + logdir)) + nil 'silent) + (kill-buffer))))) + +;;;###autoload +(defun helm-debug-open-last-log () + "Open helm log file of last helm session. +If `helm-last-log-file' is nil, switch to `helm-debug-buffer' ." + (interactive) + (if helm-last-log-file + (view-file helm-last-log-file) + (switch-to-buffer helm-debug-buffer) + (view-mode 1) (visual-line-mode 1))) + +(defun helm-print-error-messages () + "Print error messages in `helm-issued-errors'." + (and helm-issued-errors + (message "Helm issued errors: %s" + (mapconcat 'identity (reverse helm-issued-errors) "\n")))) + + +;; Programming Tools +(defmacro helm-aif (test-form then-form &rest else-forms) + "Like `if' but set the result of TEST-FORM in a temprary variable called `it'. +THEN-FORM and ELSE-FORMS are then excuted just like in `if'." + (declare (indent 2) (debug t)) + `(let ((it ,test-form)) + (if it ,then-form ,@else-forms))) + +(defun helm-mklist (obj) + "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 + (list obj))) + +(defun helm-this-command () + "Return the actual command in action. +Like `this-command' but return the real command, +not `exit-minibuffer' or 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 + 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). + (symbolp fn) + (commandp fn) + (not (memq fn bl))) + return fn + else + if (and (eq fn 'call-interactively) + (> (length btf) 2)) + return (cadr (cdr btf)))) + +(defun helm-flatten-list (seq &optional omit-nulls) + "Return a list of all single elements of sublists in SEQ." + (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)))) + (flatten seq)) + (nreverse result))) + + +;; Test tools +(defmacro with-helm-time-after-update (&rest body) + (helm-with-gensyms (start-time time-elapsed) + `(let ((,start-time (float-time)) ,time-elapsed) + (add-hook 'helm-after-update-hook + (lambda () + (setq ,time-elapsed (- (float-time) ,start-time)) + (keyboard-quit))) + (unwind-protect ,@body + (remove-hook 'helm-after-update-hook + (lambda () + (setq ,time-elapsed (- (float-time) ,start-time)) + (keyboard-quit)))) + ,time-elapsed))) + + +;; Helm API + +(defun helm-buffer-get () + "Return `helm-action-buffer' if shown otherwise `helm-buffer'." + (if (helm-action-window) + helm-action-buffer + helm-buffer)) + +(defun helm-window () + "Window of `helm-buffer'." + (get-buffer-window (helm-buffer-get) 0)) + +(defun helm-action-window () + "Window of `helm-action-buffer'." + (get-buffer-window helm-action-buffer 'visible)) + +(defmacro with-helm-window (&rest body) + "Be sure BODY is excuted in the helm window." + (declare (indent 0) (debug t)) + `(with-selected-window (helm-window) + ,@body)) + +(defmacro with-helm-current-buffer (&rest body) + "Eval BODY inside `helm-current-buffer'." + (declare (indent 0) (debug t)) + `(with-current-buffer (or (and (buffer-live-p helm-current-buffer) + helm-current-buffer) + (setq helm-current-buffer + (current-buffer))) + ,@body)) + +(defmacro with-helm-buffer (&rest body) + "Eval BODY inside `helm-buffer'." + (declare (indent 0) (debug t)) + `(with-current-buffer (helm-buffer-get) + ,@body)) + +(defmacro with-helm-restore-variables (&rest body) + "Restore `helm-restored-variables' after executing BODY." + (declare (indent 0) (debug t)) + (helm-with-gensyms (orig-vars) + `(let ((,orig-vars (mapcar (lambda (v) + (cons v (symbol-value v))) + helm-restored-variables))) + (unwind-protect (progn ,@body) + (cl-loop for (var . value) in ,orig-vars + do (set var value)) + (helm-log "restore variables"))))) + +(defmacro with-helm-default-directory (directory &rest body) + (declare (indent 2) (debug t)) + `(let ((default-directory (or (and ,directory + (file-name-as-directory ,directory)) + default-directory))) + ,@body)) + +(defun helm-default-directory () + "Return the value of `helm-default-directory'." + (buffer-local-value 'helm-default-directory (get-buffer helm-buffer))) + +(defmacro with-helm-temp-hook (hook &rest body) + "Execute temporarily BODY as a function for HOOK." + (declare (indent 1) (debug t)) + (helm-with-gensyms (fun) + `(progn + (defun ,fun () + (unwind-protect + (progn ,@body) + (remove-hook ,hook (quote ,fun)))) + (add-hook ,hook (quote ,fun))))) + +(defmacro with-helm-after-update-hook (&rest body) + "Execute BODY at end of `helm-update'." + (declare (indent 0) (debug t)) + `(with-helm-temp-hook 'helm-after-update-hook ,@body)) + +(defmacro with-helm-alive-p (&rest body) + "Return error when BODY run outside helm context." + (declare (indent 0) (debug t)) + `(progn + (if helm-alive-p + (progn ,@body) + (error "Running helm command outside of context")))) + +(cl-defun helm-attr (attribute-name + &optional (src (helm-get-current-source)) compute) + "Get the value of ATTRIBUTE-NAME of SRC. +If SRC is omitted, use current source. +If COMPUTE is non--nil compute value of ATTRIBUTE-NAME +with `helm-interpret-value'." + (helm-aif (or (assq attribute-name src) + (helm-get-attribute-from-source-type attribute-name src)) + (if compute (helm-interpret-value (cdr it)) (cdr it)))) + +(cl-defun helm-attr-defined (attribute-name + &optional (src (helm-get-current-source))) + "Return non-nil if ATTRIBUTE-NAME of SRC is defined. +if SRC is omitted, use current source." + (and (helm-attr attribute-name src) t)) + +(cl-defun helm-attrset (attribute-name value + &optional + (src (helm-get-current-source)) + alter-type) + "Set the value of ATTRIBUTE-NAME of source SRC to VALUE. +If ATTRIBUTE-NAME doesn't exists in source it is created with value VALUE. +If ALTER-TYPE is non--nil alter the value of ATTRIBUTE-NAME in `helm-attributes' +if it exists. +If SRC is omitted, use current source. +If operation succeed, return value, otherwise nil." + (let ((from-type (helm-get-attribute-from-source-type attribute-name src)) + done) + (helm-aif (or (assq attribute-name src) + (and alter-type from-type)) + (prog1 (setcdr it value) (setq done t)) + (unless from-type + (setcdr src (cons (cons attribute-name value) (cdr src))) + (setq done t))) + (and done value))) + +(defun helm-get-attribute-from-source-type (attribute source) + "Get ATTRIBUTE from type attribute of SOURCE." + (when (assq 'type source) + (assq attribute + (assq (cdr (assq 'type source)) + helm-type-attributes)))) + +(defun helm-get-attribute-from-type (attribute type) + "Get ATTRIBUTE from TYPE. +arg TYPE is an existing type defined in `helm-type-attributes'." + (assq attribute (assq type helm-type-attributes))) + +(defun helm-get-actions-from-type (source) + "Get actions list from type attribute of SOURCE." + (when (assq 'type source) + (helm-get-attribute-from-source-type 'action source))) + +(defun helm-inherit-attribute-from-source (attribute source) + "Get the ATTRIBUTE of SOURCE." + (helm-aif (assq attribute source) + it + (helm-get-attribute-from-source-type attribute source))) + +(defun helm-append-at-nth (seq elm index) + "Append ELM at INDEX in SEQ." + (let ((len (length seq))) + (when (> index len) (setq index len)) + (cl-loop for i in seq + for count from 1 collect i + when (= count index) + if (listp elm) append elm + else collect elm))) + +(defun helm-add-action-to-source (name fn source &optional index) + "Add new action NAME linked to function FN to SOURCE. +Function FN should be a valid function that take one arg i.e candidate, +argument NAME is a string that will appear in action menu +and SOURCE should be an existing helm source already loaded. +If INDEX is specified, action is added in action list at INDEX, +otherwise it is added at end. +This allow user to add a specific action to an existing source +without modifying source code." + (let ((actions (helm-attr 'action source)) + (new-action (list (cons name fn)))) + (when (symbolp actions) + (setq actions (list (cons "Default action" actions)))) + (helm-attrset 'action + (if index + (helm-append-at-nth actions new-action index) + (append actions new-action)) + source))) + +(defun helm-delete-action-from-source (action-or-name source) + "Delete ACTION-OR-NAME from SOURCE. +ACTION-OR-NAME can either be the name of action or the symbol function +associated to name." + (let* ((actions (helm-attr 'action source)) + (del-action (if (symbolp action-or-name) + (rassoc action-or-name actions) + (assoc action-or-name actions)))) + (helm-attrset 'action (delete del-action actions) source))) + +(cl-defun helm-add-action-to-source-if (name fn source predicate + &optional (index 4) test-only) + "Add new action NAME linked to function FN to SOURCE. +Action NAME will be available when the current candidate matches PREDICATE. +This function add an entry in the `action-transformer' attribute +of SOURCE (or create one if not found). +Function PREDICATE should take one arg candidate. +Function FN should be a valid function that take one arg i.e candidate, +argument NAME is a string that will appear in action menu +and SOURCE should be an existing helm source already loaded. +If INDEX is specified, action is added in action list at INDEX. +Value of INDEX should be always >=1, default to 4. +This allow user to add a specific `action-tranformer' +to an existing source 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 when predicate helm-ff-candidates-lisp-p return non--nil: + +\(helm-add-action-to-source-if \"Byte compile file async\" + 'async-byte-compile-file + helm-source-find-files + 'helm-ff-candidates-lisp-p\)." + (let* ((actions (helm-attr 'action source)) + (action-transformers (helm-attr 'action-transformer source)) + (new-action (list (cons name fn))) + (transformer `(lambda (actions candidate) + (cond ((funcall (quote ,predicate) candidate) + (helm-append-at-nth + actions (quote ,new-action) ,index)) + (t actions))))) + (when (symbolp actions) + (helm-attrset 'action (list (cons "Default action" actions)) source)) + (when (symbolp action-transformers) + (setq action-transformers (list action-transformers))) + (if test-only ; debug + (delq nil (append (list transformer) action-transformers)) + (helm-attrset 'action-transformer + (helm-fast-remove-dups + (delq nil (append (list transformer) action-transformers)) + :test 'equal) + source)))) + +(defun helm-set-source-filter (sources) + "Set the value of `helm-source-filter' to SOURCES and update. + +This function sets a filter for helm sources and it may be +called while helm is running. It can be used to toggle +displaying of sources dynamically. For example, additional keys +can be bound into `helm-map' to display only the file-related +results if there are too many matches from other sources and +you're after files only: + +Shift+F shows only file results from some sources: + +\(define-key helm-map \"F\" 'helm-my-show-files-only) + +\(defun helm-my-show-files-only () + (interactive) + (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) + +\(defun helm-my-show-all () + (interactive) + (helm-set-source-filter nil)) + +The -my- part is added to avoid collisions with +existing Helm function names." + (let ((cur-disp-sel (with-current-buffer helm-buffer + (helm-get-selection nil t)))) + (setq helm-source-filter (helm--normalize-filter-sources sources)) + (helm-log "helm-source-filter = %S" helm-source-filter) + ;; Use force-update to run init/update functions. + (helm-force-update (and (stringp cur-disp-sel) + (regexp-quote cur-disp-sel))))) + +(defun helm--normalize-filter-sources (sources) + (cl-loop for s in sources collect + (cond ((symbolp s) + (assoc-default 'name (symbol-value s))) + ((listp s) + (assoc-default 'name s)) + ((stringp s) s)))) + +(defun helm-set-sources (sources &optional no-init no-update) + "Set SOURCES during `helm' invocation. +If NO-INIT is non-nil, skip executing init functions of SOURCES. +If NO-UPDATE is non-nil, skip executing `helm-update'." + (with-current-buffer helm-buffer + (setq helm-compiled-sources nil + helm-sources sources) + (helm-log "helm-compiled-sources = %S" helm-compiled-sources) + (helm-log "helm-sources = %S" helm-sources)) + (unless no-init (helm-funcall-foreach 'init)) + (unless no-update (helm-update))) + +(defun helm-get-sources () + "Return compiled `helm-sources', which is memoized. + +Attributes: + +- type + `helm-type-attributes' are merged in. +- candidates-buffer + candidates, volatile and match attribute are created." + (cond + ;; action + ((helm-action-window) + helm-sources) + ;; memoized + (helm-compiled-sources) + ;; first time + (t + (prog1 + (setq helm-compiled-sources + (helm-compile-sources + helm-sources helm-compile-source-functions)) + (helm-log "helm-compiled-sources = %S" helm-compiled-sources))))) + +(cl-defun helm-get-selection (&optional (buffer nil buffer-s) + force-display-part) + "Return the currently selected item or nil. +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 (if (and buffer buffer-s) buffer helm-buffer)) + (unless (helm-empty-buffer-p buffer) + (with-current-buffer buffer + (let* ((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 ((disp (funcall + disp-fn + (overlay-start helm-selection-overlay) + (1- (overlay-end helm-selection-overlay)))) + (source (helm-get-current-source))) + (helm-aif (and (not force-display-part) + (assoc-default 'display-to-real source)) + (helm-funcall-with-source source it disp) + disp))))) + (unless (equal selection "") + (helm-log "selection = %S" selection) + selection))))) + +(defun helm-get-actions-from-current-source () + "Return the associated action for the selected candidate. +It is a function symbol \(sole action\) or list +of \(action-display . function\)." + (unless (helm-empty-buffer-p (helm-buffer-get)) + (helm-aif (helm-attr 'action-transformer) + (helm-composed-funcall-with-source + (helm-get-current-source) it + (helm-attr 'action) (helm-get-selection)) + (helm-attr 'action)))) + +(defun helm-get-current-source () + "Return the source for the current selection. +Allow also checking if helm-buffer contain candidates." + (or helm-current-source + (with-current-buffer (helm-buffer-get) + (or + ;; This happen only when `helm-source-in-each-line-flag' + ;; is non--nil and there is candidates in buffer. + (get-text-property (point) 'helm-source) + ;; Return nil when no--candidates. + (cl-block exit + ;; This goto-char shouldn't be necessary, but point is moved to + ;; point-min somewhere else which shouldn't happen. + (goto-char (overlay-start helm-selection-overlay)) + (let* ((header-pos (or (helm-get-previous-header-pos) + (helm-get-next-header-pos))) + (source-name + (save-excursion + (unless header-pos + (cl-return-from exit nil)) + (goto-char header-pos) + (helm-current-line-contents)))) + (cl-loop for source in (helm-get-sources) thereis + (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* ((b (get-buffer buffer)) + (key (concat (buffer-name b) "/" (helm-attr 'name))) + (source-tick (or (gethash key helm-tick-hash) 0)) + (buffer-tick (buffer-chars-modified-tick b)) + (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-quit (function &rest args) + "Perform an action after quitting `helm'. +The action is to call FUNCTION with arguments ARGS." + (setq helm-quit t) + (helm-kill-async-processes) + (helm-log "function = %S" function) + (helm-log "args = %S" args) + (apply 'run-with-timer 0.1 nil function args) + (helm-exit-minibuffer)) + + +(defun define-helm-type-attribute (type definition &optional doc) + "Register type attribute of TYPE as DEFINITION with DOC. +DOC is displayed in `helm-type-attributes' docstring. + +Use this function is better than setting `helm-type-attributes' directly." + (cl-loop for i in definition do + ;; without `ignore-errors', error at emacs22 + (ignore-errors (setf i (delete nil i)))) + (helm-add-type-attribute type definition) + (and doc (helm-document-type-attribute type doc)) + nil) + +(defun helm-document-attribute (attribute short-doc &optional long-doc) + "Register ATTRIBUTE documentation introduced by plug-in. +SHORT-DOC is displayed beside attribute name. +LONG-DOC is displayed below attribute name and short documentation." + (if long-doc + (setq short-doc (concat "(" short-doc ")")) + (setq long-doc short-doc + short-doc "")) + (add-to-list 'helm-attributes attribute t) + (put attribute 'helm-attrdoc + (concat "- " (symbol-name attribute) + " " short-doc "\n\n" long-doc "\n"))) + +(put 'helm-document-attribute 'lisp-indent-function 2) + +(defun helm-interpret-value (value &optional source) + "Interpret VALUE as variable, function or literal and return it. +If VALUE is a function, call it with no arguments and return the value. +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. +Otherwise, return VALUE itself." + (cond ((and source (functionp value)) + (helm-funcall-with-source source value)) + ((functionp value) + (funcall value)) + ((and (symbolp value) (boundp value)) + (symbol-value value)) + ((symbolp value) + (error + "helm-interpret-value: Symbol must be a function or a variable")) + (t + value))) + +(defun helm-set-local-variable (&rest args) + "Bind each pair in ARGS locally to `helm-buffer'. +Use this to set local vars before calling helm. +Usage: helm-set-local-variable ([VAR VALUE]...) +Just like `setq' except that the vars are not set sequentially. +IOW Don't use VALUE of previous VAR to eval the VALUE of next VAR. +When helm is alive use `make-local-variable' as usual on `helm-buffer'. + +\(fn VAR VALUE ...)" + (setq helm--local-variables + (append (cl-loop for i on args by #'cddr + collect (cons (car i) (cadr i))) + helm--local-variables))) + +(defun helm-make-actions (&rest args) + "Build an alist with (NAME . ACTION) elements with each pairs in ARGS. +Where NAME is a string or a function returning a string or nil and ACTION +a function. +If NAME returns nil the pair is skipped. + +\(fn NAME ACTION ...)" + (cl-loop for i on args by #'cddr + for name = (car i) + when (functionp name) + do (setq name (funcall name)) + when name + collect (cons name (cadr i)))) + +;; Core: API helper +(cl-defun helm-empty-buffer-p (&optional (buffer helm-buffer)) + "Check if BUFFER have candidates. +Default value for BUFFER is `helm-buffer'." + (zerop (buffer-size (and buffer (get-buffer buffer))))) + +(defun helm-empty-source-p () + "Check if current source contains candidates. +This happen only in certains cases when e.g the last element +of a source is deleted without updating the source." + (with-helm-window + (or (helm-empty-buffer-p) + (and (helm-end-of-source-p) + (eq (point-at-bol) (point-at-eol)) + (or + (save-excursion + (forward-line -1) + (helm-pos-header-line-p)) + (bobp)))))) + +(defun helm-symbol-name (obj) + (if (or (consp obj) (byte-code-function-p obj)) + "Anonymous" + (symbol-name obj))) + + +;; Core: tools +(defun helm-current-line-contents () + "Current line string without properties." + (buffer-substring-no-properties (point-at-bol) (point-at-eol))) + +(defun helm-funcall-with-source (source functions &rest args) + "Call from SOURCE FUNCTIONS list or single function FUNCTIONS with ARGS. +FUNCTIONS can be a symbol or a list of functions. +Return the result of last function call." + (let ((helm-source-name (assoc-default 'name source)) + (helm-current-source source) + (funs (if (functionp functions) (list functions) functions))) + (helm-log "helm-source-name = %S" helm-source-name) + (helm-log "functions = %S" functions) + (helm-log "args = %S" args) + (cl-loop with result for fn in funs + do (setq result (apply fn args)) finally return result))) + +(defun helm-funcall-foreach (sym &optional sources) + "Call the associated function to SYM for each source if any." + (let ((sources (or sources (helm-get-sources)))) + (cl-dolist (source sources) + (helm-aif (assoc-default sym source) + (helm-funcall-with-source source it))))) + +(defun helm-normalize-sources (sources) + "If SOURCES is only one source, make a list of one element." + (cond ((or (and sources + (symbolp sources)) + (and (listp sources) (assq 'name sources))) + (list sources)) + (sources) + (t helm-sources))) + +(defun helm-get-candidate-number (&optional in-current-source) + "Return candidates number in `helm-buffer'. +If IN-CURRENT-SOURCE is provided return number of candidates +in the source where point is." + (with-current-buffer (helm-buffer-get) + (if (or (helm-empty-buffer-p) + (helm-empty-source-p)) + 0 + (save-excursion + (if in-current-source + (goto-char (helm-get-previous-header-pos)) + (goto-char (point-min))) + (forward-line 1) + (if (helm-pos-multiline-p) + (save-excursion + (cl-loop with count-multi = 1 + while (and (not (if in-current-source + (save-excursion + (forward-line 2) + (or (helm-pos-header-line-p) (eobp))) + (eobp))) + (search-forward helm-candidate-separator nil t)) + do (cl-incf count-multi) + finally return count-multi)) + (save-excursion + (cl-loop with ln = 0 + while (not (if in-current-source + (or (helm-pos-header-line-p) (eobp)) + (eobp))) + unless (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 occur in execution of BODY, quit helm safely." + (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))))) + +(defun helm-compose (arg-lst func-lst) + "Apply arguments specified in ARG-LST with each function of FUNC-LST. +The result of each function will be the new `car' of ARG-LST. +Each function in FUNC-LST must accept (length ARG-LST) arguments +\(See examples below) . +This function allows easy sequencing of transformer functions. +Where generally, ARG-LST is '(candidates-list source) and FUNC-LST a +list of transformer functions that take one or two arguments depending +we are using 'filtered-candidate-transformer' or 'candidate-transformer'. +e.g +filtered-candidate-transformer: +\(helm-compose '((1 2 3 4 5 6 7) + '((name . \"A helm source\") (candidates . (a b c)))) + '((lambda (candidates _source) + (cl-loop for i in candidates + when (cl-oddp i) collect i)) + (lambda (candidates _source) + (cl-loop for i in candidates collect (1+ i))))) +=>(2 4 6 8) + +candidate-transformer: +\(helm-compose '((1 2 3 4 5 6 7)) + '((lambda (candidates) + (cl-loop for i in candidates + when (cl-oddp i) collect i)) + (lambda (candidates) + (cl-loop for i in candidates collect (1+ i))))) +=> (2 4 6 8)." + (cl-dolist (func func-lst) + (setcar arg-lst (apply func arg-lst))) + (car arg-lst)) + +(defun helm-composed-funcall-with-source (source funcs &rest args) + "With SOURCE apply `helm-funcall-with-source' with each FUNCS and ARGS. +This is used in transformers to modify candidates list." + (if (functionp funcs) + (apply 'helm-funcall-with-source source funcs args) + (apply 'helm-funcall-with-source source + (lambda (&rest oargs) (helm-compose oargs funcs)) + args))) + +(defun helm-stringify (str-or-sym) + "Get string of STR-OR-SYM." + (if (stringp str-or-sym) + str-or-sym + (symbol-name str-or-sym))) + +(defun helm-symbolify (str-or-sym) + "Get symbol of STR-OR-SYM." + (if (symbolp str-or-sym) + str-or-sym + (intern str-or-sym))) + + +;; Core: entry point +;; `:allow-nest' is not in this list because it is treated before. +(defconst helm-argument-keys + '(:sources :input :prompt :resume + :preselect :buffer :keymap :default :history)) + +;;;###autoload +(defun helm (&rest plist) + "Main function to execute helm sources. + +Keywords supported: +:sources :input :prompt :resume :preselect +:buffer :keymap :default :history :allow-nest + +Extra LOCAL-VARS keywords are supported, see below. + +PLIST is a list like \(:key1 val1 :key2 val2 ...\) or +\(&optional sources input prompt resume + preselect buffer keymap default history\). + +Basic keywords are the following: + +\:sources + +A list of sources used for this session. It also accepts a +symbol, interpreted as a variable of a helm source +i.e (a symbol can be passed instead of a list of sources). +It also accepts an alist representing a helm source, which is +detected by \(assq 'name ANY-SOURCES\). +NOTE: In this case the source is embedded in the helm command and +have no symbol name, so it is not reachable from outside. +It will be referenced in `helm-sources' as a whole alist. + +\:input + +Temporary value of `helm-pattern', ie. initial input of minibuffer. + +\:prompt + +Prompt other than \"pattern: \". + +\:resume + +If t, Resurrect previously instance of `helm'. Skip the initialization. +If 'noresume, this instance of `helm' cannot be resumed. + +\:preselect + +Initially selected candidate. Specified by exact candidate or a regexp. + +\:buffer + +`helm-buffer' instead of *helm*. + +\:keymap + +`helm-map' for current `helm' session. + +\:default + +A default argument that will be inserted in minibuffer \ +with \\\\[next-history-element]. +When nil or not present `thing-at-point' will be used instead. +If `helm-maybe-use-default-as-input' is non--nil display will be +updated using :default arg as input unless :input is specified, +which in this case will take precedence on :default +This is a string or a list, in this case the car of the list will +be used as initial default input, but you will be able to cycle in this +list with \\\\[next-history-element]. + +\:history + +By default all minibuffer input is pushed to `minibuffer-history', +if an argument HISTORY is provided, input will be pushed to HISTORY. +History element should be a symbol. + +\:allow-nest + +Allow running this helm command within a running helm session. + +Of course, conventional arguments are supported, the two are same. + +\(helm :sources sources :input input :prompt prompt :resume resume + :preselect preselect :buffer buffer :keymap keymap :default default + :history history\) + +and + +\(helm sources input prompt resume preselect buffer keymap default history\) + +are the same. + +However the use of non keyword args is deprecated and should not be used. + +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 + :buffer \"*buffers*\" :candidate-number-limit 10\) + +means starting helm session with `helm-source-buffers' +source in *buffers* buffer and set variable `helm-candidate-number-limit' +to 10 as session local variable. + +\(fn &key SOURCES INPUT PROMPT RESUME PRESELECT BUFFER KEYMAP DEFAULT HISTORY ALLOW-NEST OTHER-LOCAL-VARS)" + (let ((fn (cond ((or (and helm-alive-p (plist-get plist :allow-nest)) + (and helm-alive-p (memq 'allow-nest plist))) + #'helm-nest) + ((keywordp (car plist)) + #'helm) + (t #'helm-internal)))) + (if (and helm-alive-p (eq fn #'helm)) + (if (helm-alive-p) + ;; A helm session is normally running. + (error "Error: Trying to run helm within a running helm session") + ;; A helm session is already running and user jump somewhere else + ;; without desactivating it. + (with-helm-buffer + (prog1 + (message "Aborting an helm session running in background") + ;; `helm-alive-p' will be reset in unwind-protect forms. + (helm-keyboard-quit)))) + (if (keywordp (car plist)) + ;; Parse `plist' and move not regular `helm-argument-keys' + ;; to `helm--local-variables', then calling helm on itself + ;; with normal arguments (the non--arguments-keys removed) + ;; will end up in [1]. + (progn + (setq helm--local-variables + (append helm--local-variables + ;; Vars passed by keyword on helm call + ;; take precedence on same vars + ;; that may have been passed before helm call. + (helm-parse-keys plist))) + (apply fn (mapcar #'(lambda (key) (plist-get plist key)) + helm-argument-keys))) + (apply fn plist))))) ; [1] fn == helm-internal. + +(defun helm-alive-p () + "Check if `helm' is alive. +An `helm' session is considered alive if `helm-alive-p' is non--nil, +the `helm-buffer' is visible, and cursor is in minibuffer." + (and helm-alive-p + (get-buffer-window helm-buffer 'visible) + (minibuffer-window-active-p (minibuffer-window)) + (minibufferp (current-buffer)))) + +(defun helm-parse-keys (keys) + "Parse the KEYS arguments of `helm'. +Return only the keys that are not in `helm-argument-keys', +prefix them with \"helm\" and convert them to alist. +This allow to add arguments that are not part of `helm-argument-keys', +but are valid helm variables. +e.g :candidate-number-limit will be bound to `helm-candidate-number-limit' +in source. + + (helm-parse-keys '(:sources ((name . \"test\") + (candidates . (a b c))) + :buffer \"toto\" + :candidate-number-limit 4)) + ==> ((helm-candidate-number-limit . 4))." + + (cl-loop for (key value) on keys by #'cddr + for symname = (substring (symbol-name key) 1) + for sym = (intern (if (string-match "^helm-" symname) + symname + (concat "helm-" symname))) + unless (memq key helm-argument-keys) + collect (cons sym value))) + +;;; Core: entry point helper +(defun helm-internal (&optional + any-sources any-input + any-prompt any-resume + any-preselect any-buffer + any-keymap any-default any-history) + "The internal helm function called by `helm'. +For ANY-SOURCES ANY-INPUT ANY-PROMPT ANY-RESUME ANY-PRESELECT ANY-BUFFER and +ANY-KEYMAP ANY-DEFAULT ANY-HISTORY See `helm'." + ;; Activate the advice for `tramp-read-passwd'. + (if (fboundp 'advice-add) + (progn + (advice-add 'tramp-read-passwd :around #'helm--advice-tramp-read-passwd) + (advice-add 'ange-ftp-get-passwd :around #'helm--advice-ange-ftp-get-passwd)) + (ad-activate 'tramp-read-passwd) + (ad-activate 'ange-ftp-get-passwd)) + (helm-log (concat "[Start session] " (make-string 41 ?+))) + (helm-log "any-prompt = %S" any-prompt) + (helm-log "any-preselect = %S" any-preselect) + (helm-log "any-buffer = %S" any-buffer) + (helm-log "any-keymap = %S" any-keymap) + (helm-log "any-default = %S" any-default) + (helm-log "any-history = %S" any-history) + (let ((non-essential t) + (input-method-verbose-flag helm-input-method-verbose-flag) + (old--cua cua-mode) + (helm-maybe-use-default-as-input + (or helm-maybe-use-default-as-input ; it is let-bounded so use it. + (cl-loop for s in (helm-normalize-sources any-sources) + thereis (memq s helm-sources-using-default-as-input))))) + ;; cua-mode overhide local helm bindings. + ;; disable this stupid thing if enabled. + (and cua-mode (cua-mode -1)) + (unwind-protect + (condition-case-unless-debug _v + (let ( ;; `helm-source-name' is non-nil + ;; when `helm' is invoked by action, reset it. + helm-source-name + helm-current-source + helm-in-persistent-action + helm-quit + (helm-buffer (or any-buffer helm-buffer))) + (with-helm-restore-variables + (helm-initialize + any-resume any-input any-default any-sources) + (helm-display-buffer helm-buffer) + (when helm-prevent-escaping-from-minibuffer + (helm--remap-mouse-mode 1)) ; Disable mouse bindings. + (add-hook 'post-command-hook 'helm--maybe-update-keymap) + (helm-log "show prompt") + (unwind-protect + (helm-read-pattern-maybe + any-prompt any-input any-preselect + any-resume any-keymap any-default any-history) + (helm-cleanup))) + (prog1 + (unless helm-quit (helm-execute-selection-action)) + (helm-log (concat "[End session] " (make-string 41 ?-))))) + (quit + (helm-restore-position-on-quit) + (helm-log (concat "[End session (quit)] " (make-string 34 ?-))) + nil)) + (remove-hook 'post-command-hook 'helm--maybe-update-keymap) + (if (fboundp 'advice-add) + (progn + (advice-remove 'tramp-read-passwd + #'helm--advice-tramp-read-passwd) + (advice-remove 'ange-ftp-get-passwd + #'helm--advice-ange-ftp-get-passwd)) + (ad-deactivate 'tramp-read-passwd) + (ad-deactivate 'ange-ftp-get-passwd)) + (helm-log "helm-alive-p = %S" (setq helm-alive-p nil)) + (helm--remap-mouse-mode -1) ; Reenable mouse bindings. + (setq helm-alive-p nil) + ;; Reset helm-pattern so that lambda's using it + ;; before running helm will not start with its old value. + (setq helm-pattern "") + (and old--cua (cua-mode 1)) + (helm-log-save-maybe)))) + + +;;; Helm resume +;; +;; +(defun helm-resume (arg) + "Resurrect previously invoked `helm'. +Called with a prefix arg, allow choosing among all existing +helm buffers. i.e choose among various helm sessions. +Called from lisp, you can specify a buffer-name as a string with ARG." + (interactive "P") + (let (any-buffer helm-full-frame cur-dir) + (if arg + (if (and (stringp arg) (bufferp (get-buffer arg))) + (setq any-buffer arg) + (setq any-buffer (helm-resume-select-buffer))) + (setq any-buffer helm-last-buffer)) + (cl-assert any-buffer nil + "helm-resume: No helm buffers found to resume") + ;; Reset `cursor-type' to nil as it have been set to t + ;; when quitting previous session. + (with-current-buffer any-buffer (setq cursor-type nil)) + (setq helm-full-frame (buffer-local-value + 'helm-full-frame (get-buffer any-buffer))) + (setq helm-compiled-sources nil) + (setq cur-dir (buffer-local-value + 'helm-default-directory (get-buffer any-buffer))) + (unless (buffer-live-p helm-current-buffer) + ;; `helm-current-buffer' may have been killed. + (setq helm-current-buffer (current-buffer))) + ;; Restart with same `default-directory' value this session + ;; was initially started with. + (with-helm-default-directory cur-dir + (helm + :sources (buffer-local-value + 'helm-sources (get-buffer any-buffer)) + :input (buffer-local-value 'helm-input-local (get-buffer any-buffer)) + :resume t + :buffer any-buffer)))) + +(defun helm-resume-previous-session-after-quit (arg) + "Resume previous helm session within running helm." + (interactive "p") + (if (and helm-alive-p (> (length helm-buffers) arg)) + (helm-run-after-quit `(lambda () (helm-resume (nth ,arg helm-buffers)))) + (message "No previous helm sessions to resume yet!"))) + +(defun helm-resume-list-buffers-after-quit () + "List resumable helm buffers within running helm." + (interactive) + (if (and helm-alive-p (> (length helm-buffers) 0)) + (helm-run-after-quit #'(lambda () (helm-resume t))) + (message "No previous helm sessions to resume yet!"))) + +(defun helm-resume-p (any-resume) + "Whether current helm session is resumed or not." + (eq any-resume t)) + +(defun helm-resume-select-buffer () + "Select an `helm-buffer' in `helm-buffers' list to resume a helm session. +Return nil if no `helm-buffer' found." + (when helm-buffers + (or (helm :sources '(((name . "Resume helm buffer") + (candidates . helm-buffers) + (action . identity))) + :resume 'noresume + :buffer "*helm resume*") + (keyboard-quit)))) + + +;;;###autoload +(defun helm-other-buffer (any-sources any-buffer) + "Simplified interface of `helm' with other `helm-buffer'. +Call `helm' with only ANY-SOURCES and ANY-BUFFER as args." + (helm :sources any-sources :buffer any-buffer)) + +(defun helm-nest (&rest same-as-helm) + "Allow calling `helm' whithin a running helm session. +Arguments SAME-AS-HELM are the same as `helm', which see." + (with-helm-window + (let ((orig-helm-current-buffer helm-current-buffer) + (orig-helm-buffer helm-buffer) + (orig-helm--in-fuzzy helm--in-fuzzy) + (orig-helm-last-frame-or-window-configuration + helm-last-frame-or-window-configuration) + (orig-one-window-p helm-onewindow-p)) + (unwind-protect + (let (helm-current-position + helm-current-buffer + helm-pattern + (helm-buffer (or (cl-getf same-as-helm :buffer) + (nth 5 same-as-helm) + "*Helm*")) + helm-sources + helm-compiled-sources + (helm-full-frame t) + (enable-recursive-minibuffers t)) + (apply #'helm same-as-helm)) + (with-current-buffer orig-helm-buffer + (setq helm-alive-p t) ; Nested session set this to nil on exit. + (setq helm-buffer orig-helm-buffer) + (setq helm--in-fuzzy orig-helm--in-fuzzy) + (helm-initialize-overlays helm-buffer) + (unless (helm-empty-buffer-p) (helm-mark-current-line t)) + (setq helm-last-frame-or-window-configuration + orig-helm-last-frame-or-window-configuration) + (setq cursor-type nil) + (setq helm-current-buffer orig-helm-current-buffer) + (setq helm-onewindow-p orig-one-window-p)))))) + + +;;; Core: Accessors +;; +(defun helm-current-position (save-or-restore) + "Restore or save current position in `helm-current-buffer'. +Argument SAVE-OR-RESTORE is one of save or restore." + (cl-case save-or-restore + (save + (helm-log "Save position at %S" (cons (point) (window-start))) + (setq helm-current-position (cons (point) (window-start)))) + (restore + (helm-log "Restore position at %S in buffer %s" + helm-current-position + (buffer-name (current-buffer))) + (goto-char (car helm-current-position)) + ;; Fix this position with the NOFORCE arg of `set-window-start' + ;; otherwise, if there is some other buffer than `helm-current-buffer' + ;; one, position will be lost. + (set-window-start (selected-window) (cdr helm-current-position) t)))) + + +(defun helm-frame-or-window-configuration (save-or-restore) + "Save or restore last frame or window configuration. +Possible value of SAVE-OR-RESTORE are 'save and 'restore. +window or frame configuration is saved/restored according to values of +`helm-save-configuration-functions'." + (helm-log "helm-save-configuration-functions = %S" + helm-save-configuration-functions) + (let ((window-persistent-parameters (append '((no-other-window . t)) + window-persistent-parameters))) + (cl-case save-or-restore + (save (setq helm-last-frame-or-window-configuration + (funcall (cdr helm-save-configuration-functions)))) + (restore (funcall (car helm-save-configuration-functions) + helm-last-frame-or-window-configuration) + ;; Restore frame focus. + ;; This is needed for minibuffer own-frame config + ;; when recursive minibuffers are in use. + ;; e.g M-: + helm-minibuffer-history. + (let ((frame (if (minibufferp helm-current-buffer) + (selected-frame) + (last-nonminibuffer-frame)))) + (select-frame-set-input-focus frame)))))) + +(defun helm-split-window-default-fn (window) + (let (split-width-threshold) + (if (and (fboundp 'window-in-direction) + ;; Don't try to split when starting in a minibuffer + ;; e.g M-: and try to use helm-show-kill-ring. + (not (minibufferp helm-current-buffer))) + (if (or (one-window-p t) + helm-split-window-in-side-p) + (split-window + (selected-window) nil (if (eq helm-split-window-default-side 'other) + 'below helm-split-window-default-side)) + ;; If more than one window reuse one of them. + (cl-case helm-split-window-default-side + (left (or (helm-window-in-direction 'left) + (helm-window-in-direction 'above) + (selected-window))) + (above (or (helm-window-in-direction 'above) + (helm-window-in-direction 'left) + (selected-window))) + (right (or (helm-window-in-direction 'right) + (helm-window-in-direction 'below) + (selected-window))) + (below (or (helm-window-in-direction 'below) + (helm-window-in-direction 'right) + (selected-window))) + (same (selected-window)) + (other (other-window-for-scrolling)) + (t (or (window-next-sibling) (selected-window))))) + (split-window-sensibly window)))) + +(defun helm-window-in-direction (direction) + "Same as `window-in-direction' but check if window is dedicated." + (helm-aif (window-in-direction direction) + (and (not (window-dedicated-p it)) it))) + + +;;; Display helm buffer +;; +;; +(defun helm-display-buffer (buffer) + "Display BUFFER. +The function used to display `helm-buffer'." + (let (pop-up-frames + (split-window-preferred-function + helm-split-window-preferred-function) + (helm-split-window-default-side + (if (and (not helm-full-frame) + helm-reuse-last-window-split-state) + (cond ((eq helm-split-window-default-side 'same) 'same) + ((eq helm-split-window-default-side 'other) 'other) + (helm--window-side-state) + (t helm-split-window-default-side)) + helm-split-window-default-side))) + (prog1 + (funcall (with-current-buffer buffer helm-display-function) buffer) + (setq helm-onewindow-p (one-window-p t)) + ;; Don't allow other-window and friends switching out of minibuffer. + (when helm-prevent-escaping-from-minibuffer + (helm-prevent-switching-other-window))))) + +(cl-defun helm-prevent-switching-other-window (&key (enabled t)) + "Allow setting `no-other-window' window parameter in all windows. +Arg ENABLE will be the value of the `no-other-window' window property." + (walk-windows + #'(lambda (w) + (unless (window-dedicated-p w) + (set-window-parameter w 'no-other-window enabled))) + 0)) + +(defun helm-default-display-buffer (buffer) + "Default function to display `helm-buffer' BUFFER. +It uses `switch-to-buffer' or `pop-to-buffer' depending of value of +`helm-full-frame' and/or `helm-split-window-default-side'." + (if (or (buffer-local-value 'helm-full-frame (get-buffer buffer)) + (and (eq helm-split-window-default-side 'same) + (one-window-p t))) + (progn (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-in-side-p)) + (delete-other-windows)) + (pop-to-buffer buffer))) + + +;;; Core: initialize +;; +(defun helm-initialize (any-resume any-input any-default any-sources) + "Start initialization of `helm' session. +For ANY-RESUME ANY-INPUT ANY-DEFAULT and ANY-SOURCES See `helm'." + (helm-log "start initialization: any-resume=%S any-input=%S" + any-resume any-input) + (helm-frame-or-window-configuration 'save) + (setq helm-sources (helm-normalize-sources any-sources)) + (setq helm--in-fuzzy + (cl-loop for s in helm-sources + for matchfns = (helm-match-functions + (if (symbolp s) (symbol-value s) s)) + for searchfns = (helm-search-functions + (if (symbolp s) (symbol-value s) s)) + when (or (member 'helm-fuzzy-match matchfns) + (member 'helm-fuzzy-search searchfns)) + return t)) + (helm-log "sources = %S" helm-sources) + (helm-current-position 'save) + (if (helm-resume-p any-resume) + (helm-initialize-overlays (helm-buffer-get)) + (helm-initial-setup any-default)) + (setq helm-alive-p t) + (unless (eq any-resume 'noresume) + (helm-recent-push helm-buffer 'helm-buffers) + (setq helm-last-buffer helm-buffer)) + (when any-input + (setq helm-input any-input + helm-pattern any-input) + (helm--fuzzy-match-maybe-set-pattern)) + ;; If a `resume' attribute is present `helm-funcall-foreach' + ;; will run its function. + (when (helm-resume-p any-resume) + (helm-funcall-foreach 'resume)) + (helm-log "end initialization")) + +(defun helm-initialize-overlays (buffer) + "Initialize helm overlays in BUFFER." + (helm-log "overlay setup") + (if helm-selection-overlay + ;; make sure the overlay belongs to the helm buffer if + ;; it's newly created + (move-overlay helm-selection-overlay (point-min) (point-min) + (get-buffer buffer)) + + (setq helm-selection-overlay + (make-overlay (point-min) (point-min) (get-buffer buffer))) + (overlay-put helm-selection-overlay 'face 'helm-selection) + (overlay-put helm-selection-overlay 'priority 1))) + +(defun helm-restore-position-on-quit () + "Restore position in `helm-current-buffer' when quitting." + (helm-current-position 'restore)) + +(defun helm-recent-push (elt list-var) + "Add ELT to the value of LIST-VAR as most recently used value." + (let ((m (member elt (symbol-value list-var)))) + (and m (set list-var (delq (car m) (symbol-value list-var)))) + (push elt (symbol-value list-var)))) + +(defun helm--current-buffer () + "[internal] Return `current-buffer' BEFORE `helm-buffer' is initialized. +Note that this will return the minibuffer in use after helm have started, +so to get the buffer where helm started while in a helm session, +use `helm-current-buffer'. +It is intended to use this only in `helm-initial-setup'." + (if (minibuffer-window-active-p (minibuffer-window)) + ;; If minibuffer is active be sure to use it's buffer + ;; as `helm-current-buffer', this allow to use helm + ;; from an already active minibuffer (M-: etc...) + (window-buffer (active-minibuffer-window)) + ;; Fix Issue #456 + ;; Use this instead of `current-buffer' to ensure + ;; helm session started in helm-mode from a completing-read + ;; Use really the buffer where we started and not the one + ;; where the completing-read is wrapped. i.e + ;; (with-current-buffer SOME-OTHER-BUFFER (completing-read [...]) + (window-buffer (with-selected-window (minibuffer-window) + (minibuffer-selected-window))))) + +(defun helm-initial-setup (any-default) + "Initialize helm settings and set up the helm buffer." + (helm-log-run-hook 'helm-before-initialize-hook) + (cl-loop for s in (helm-get-sources) + for hook = (assoc-default 'before-init-hook s) + when hook do (helm-log-run-hook hook)) + ;; For initialization of helm locals vars that need + ;; a value from current buffer, it is here. + (helm-set-local-variable 'current-input-method current-input-method) + (setq helm-current-prefix-arg nil) + (setq helm-suspend-update-flag nil) + (setq helm-current-buffer (helm--current-buffer)) + (setq helm-buffer-file-name buffer-file-name) + (setq helm-issued-errors nil) + (setq helm-compiled-sources nil) + (setq helm-saved-current-source nil) + (unless (and (or helm-split-window-state + helm--window-side-state) + helm-reuse-last-window-split-state) + (setq helm-split-window-state + (if (or (null split-width-threshold) + (and (integerp split-width-threshold) + (>= split-width-threshold (+ (frame-width) 4)))) + 'vertical 'horizontal)) + (setq helm--window-side-state + (or helm-split-window-default-side 'below))) + ;; Call the init function for sources where appropriate + (helm-funcall-foreach + 'init (and helm-source-filter + (cl-remove-if-not #'(lambda (s) + (member (assoc-default 'name s) + helm-source-filter)) + (helm-get-sources)))) + (setq helm-pattern (or (and helm-maybe-use-default-as-input + (or (if (listp any-default) + (car any-default) any-default) + (with-helm-current-buffer + (thing-at-point 'symbol)))) + "")) + (setq helm-input "") + (clrhash helm-candidate-cache) + (helm-create-helm-buffer) + (helm-clear-visible-mark) + (helm-log-run-hook 'helm-after-initialize-hook) + (cl-loop for s in (helm-get-sources) + for hook = (assoc-default 'after-init-hook s) + when hook do (helm-log-run-hook hook))) + +(defun helm-create-helm-buffer () + "Create and setup `helm-buffer'." + (let ((root-dir default-directory)) + (with-current-buffer (get-buffer-create helm-buffer) + (helm-log "kill local variables: %S" (buffer-local-variables)) + (kill-all-local-variables) + (set (make-local-variable 'inhibit-read-only) t) + (buffer-disable-undo) + (erase-buffer) + (set (make-local-variable 'helm-map) helm-map) + (make-local-variable 'helm-sources) + (set (make-local-variable 'helm-follow-mode) nil) + (set (make-local-variable 'helm-display-function) helm-display-function) + (set (make-local-variable 'helm-selection-point) nil) + (set (make-local-variable 'scroll-margin) + (if helm-display-source-at-screen-top + 0 helm-completion-window-scroll-margin)) + (set (make-local-variable 'helm-default-directory) root-dir) + (set (make-local-variable 'default-directory) root-dir) + (set (make-local-variable 'helm-marked-candidates) nil) + (helm-initialize-persistent-action) + (helm-log "helm-display-function = %S" helm-display-function) + (helm-log "helm--local-variables = %S" helm--local-variables) + (cl-loop for (var . val) in helm--local-variables + do (set (make-local-variable var) val) + finally (setq helm--local-variables nil)) + (setq truncate-lines helm-truncate-lines) ; already local. + (setq cursor-type nil) + (setq mode-name "Helm")) + (helm-initialize-overlays helm-buffer) + (get-buffer helm-buffer))) + +(define-minor-mode helm--minor-mode + "[INTERNAL] Enable keymap in helm minibuffer. +This mode have no effect when run outside of helm context. +Please don't use it. + +\\{helm-map}" + :group 'helm + :keymap (and helm-alive-p helm-map) + (unless helm-alive-p (setq helm--minor-mode nil))) + +(defun helm-read-pattern-maybe (any-prompt any-input + any-preselect any-resume any-keymap + any-default any-history) + "Read pattern with prompt ANY-PROMPT and initial input ANY-INPUT. +For ANY-PRESELECT ANY-RESUME ANY-KEYMAP ANY-DEFAULT ANY-HISTORY, See `helm'." + (if (and (helm-resume-p any-resume) + ;; When no source, helm-buffer is empty + ;; or contain non--candidate lines (e.g grep exit status) + (helm-get-current-source)) + (helm-mark-current-line t) + (helm-update any-preselect)) + (with-current-buffer (helm-buffer-get) + (let* ((src (helm-get-current-source)) + (src-keymap (assoc-default 'keymap src)) + (hist (or (and any-history (symbolp any-history) any-history) + ;; Needed for resuming. + (assoc-default 'history src))) + (timer nil) + blink-matching-paren + (first-src (car helm-sources)) + (source-delayed-p (or (assq 'delayed src) + (assq 'delayed (if (symbolp first-src) + (symbol-value first-src) + first-src))))) + ;; Startup with the first keymap found either in current source + ;; or helm arg, otherwise use global value of `helm-map'. + ;; This map will be used as a `minibuffer-local-map'. + ;; Maybe it will be overriden when changing source + ;; by `helm--maybe-update-keymap'. + ;; Note that helm-map have been made buffer-local + ;; in `helm-create-helm-buffer'. + (setq helm-map (or src-keymap any-keymap helm-map)) + (helm-log "helm-get-candidate-number => %S" + (helm-get-candidate-number)) + (helm-log "helm-execute-action-at-once-if-one = %S" + helm-execute-action-at-once-if-one) + (helm-log "helm-quit-if-no-candidate = %S" helm-quit-if-no-candidate) + ;; If source is delayed `helm-execute-action-at-once-if-one' + ;; and `helm-quit-if-no-candidate' are handled after update finish. + (when source-delayed-p + ;; Note that we quickly add the hook now when `helm-update' + ;; is already started, but because source is delayed the hook + ;; should have the time to be passed !!! + ;; the hook will remove itself once done. + (with-helm-after-update-hook (helm-exit-or-quit-maybe))) + ;; Reset `helm-pattern' for non--delayed sources and update + ;; display if no result found with precedent value of `helm-pattern' + ;; unless `helm-quit-if-no-candidate' is non--nil, in this case + ;; Don't force update with an empty pattern. + ;; Reset also `helm-maybe-use-default-as-input' as this checking + ;; happen only on startup. + (when (and helm-maybe-use-default-as-input (not source-delayed-p)) + (setq helm-pattern "") + (setq helm-maybe-use-default-as-input nil) + (and (helm-empty-buffer-p) + (null helm-quit-if-no-candidate) + (helm-force-update))) + ;; Handle `helm-execute-action-at-once-if-one' and + ;; `helm-quit-if-no-candidate' now only for not--delayed sources. + (cond ((and helm-execute-action-at-once-if-one + (not source-delayed-p) + (= (helm-get-candidate-number) 1)) + (ignore)) ; Don't enter the minibuffer loop. + ((and helm-quit-if-no-candidate + (not source-delayed-p) + (= (helm-get-candidate-number) 0)) + (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. + (let ((tap (or any-default + (with-helm-current-buffer + (thing-at-point 'symbol))))) + (unwind-protect + (minibuffer-with-setup-hook + #'(lambda () + ;; Start minor-mode with global value of helm-map. + (helm--minor-mode 1) + ;; Now overhide the global value of helm-map with + ;; the local one. + (setq minor-mode-overriding-map-alist + `((helm--minor-mode + . ,(with-helm-buffer helm-map)))) + (setq timer (run-with-idle-timer + (max helm-input-idle-delay 0.001) 'repeat + #'(lambda () + ;; Stop updating when in persistent action + ;; or when `helm-suspend-update-flag' is + ;; non--nil. + (unless (or helm-in-persistent-action + helm-suspend-update-flag) + (save-selected-window + (helm-check-minibuffer-input) + (helm-print-error-messages))))))) + (read-from-minibuffer (or any-prompt "pattern: ") + any-input helm-map + nil hist tap helm-inherit-input-method)) + (when timer (cancel-timer timer) (setq timer nil))))))))) + +(defun helm-exit-or-quit-maybe () + "Exit and run default action if only one candidate, quit if no candidates. +This function is handling `helm-execute-action-at-once-if-one' and +`helm-quit-if-no-candidate' in delayed sources." + (with-helm-window + (cond ((and helm-execute-action-at-once-if-one + (= (helm-get-candidate-number) 1)) + (helm-exit-minibuffer)) + ((and helm-quit-if-no-candidate + (= (helm-get-candidate-number) 0)) + (setq helm-quit t) + (and (functionp helm-quit-if-no-candidate) + (funcall helm-quit-if-no-candidate)) + (keyboard-quit))))) + +(defun helm-toggle-suspend-update () + "Enable or disable update of display in helm. +This can be useful for e.g writing quietly a complex regexp." + (interactive) + (when (setq helm-suspend-update-flag (not helm-suspend-update-flag)) + (helm-kill-async-processes) + (setq helm-pattern "")) + (message (if helm-suspend-update-flag + "Helm update suspended!" + "Helm update reenabled!"))) + +(defadvice tramp-read-passwd (around disable-helm-update) + ;; Suspend update when prompting for a tramp password. + (setq helm-suspend-update-flag t) + (setq overriding-terminal-local-map nil) + (setq helm--reading-passwd-or-string t) + (let (stimers) + (unwind-protect + (progn + (setq stimers (with-timeout-suspend)) + ad-do-it) + (with-timeout-unsuspend stimers) + (setq helm--reading-passwd-or-string nil) + (setq helm-suspend-update-flag nil)))) + +(defun helm--advice-tramp-read-passwd (old--fn &rest args) + ;; Suspend update when prompting for a tramp password. + (setq helm-suspend-update-flag t) + (setq overriding-terminal-local-map nil) + (setq helm--reading-passwd-or-string t) + (unwind-protect + ;; No need to suspend timer in emacs-24.4 + ;; it is fixed upstream. + (apply old--fn args) + (setq helm--reading-passwd-or-string nil) + (setq helm-suspend-update-flag nil))) + +(defun helm--advice-ange-ftp-get-passwd (old--fn &rest args) + ;; Suspend update when prompting for a ange password. + (setq helm-suspend-update-flag t) + (setq overriding-terminal-local-map nil) + (setq helm--reading-passwd-or-string t) + (unwind-protect + (apply old--fn args) + (setq helm--reading-passwd-or-string nil) + (setq helm-suspend-update-flag nil))) + +(defadvice ange-ftp-get-passwd (around disable-helm-update) + ;; Suspend update when prompting for a ange password. + (setq helm-suspend-update-flag t) + (setq overriding-terminal-local-map nil) + (setq helm--reading-passwd-or-string t) + (unwind-protect + ad-do-it + (setq helm--reading-passwd-or-string nil) + (setq helm-suspend-update-flag nil))) + +(defun helm--maybe-update-keymap () + "Handle differents keymaps in multiples sources. + +It will override `helm-map' with the local map of current source. +If no map is found in current source do nothing (keep previous map)." + (with-helm-buffer + (helm-aif (assoc-default 'keymap (helm-get-current-source)) + ;; We need the timer to leave enough time + ;; to helm to setup its buffer when changing source + ;; from a recursive minibuffer. + ;; e.g C-x C-f M-y C-g + ;; => *find-files have now the bindings of *kill-ring. + (run-with-idle-timer + 0.01 nil + (lambda () + (with-current-buffer (window-buffer (minibuffer-window)) + (setq minor-mode-overriding-map-alist `((helm--minor-mode . ,it))))))))) + +;;; Prevent loosing focus when using mouse. +;; +(defvar helm--remap-mouse-mode-map + (let ((map (make-sparse-keymap))) + (cl-loop for k in '([mouse-1] [mouse-2] [mouse-3] + [down-mouse-1] [down-mouse-2] [down-mouse-3] + [drag-mouse-1] [drag-mouse-2] [drag-mouse-3] + [double-mouse-1] [double-mouse-2] [double-mouse-3] + [triple-mouse-1] [triple-mouse-2] [triple-mouse-3]) + do (define-key map k 'undefined)) + map)) + +(define-minor-mode helm--remap-mouse-mode + "[INTERNAL] Prevent escaping helm minibuffer with mouse clicks. +Do nothing when used outside of helm context. + +WARNING: Do not use this mode yourself, it is internal to helm." + :group 'helm + :global t + :keymap helm--remap-mouse-mode-map + (unless helm-alive-p + (setq helm--remap-mouse-mode-map nil))) + +;; Core: clean up + +(defun helm-cleanup () + "Clean up the mess when helm exit or quit." + (helm-log "start cleanup") + (with-current-buffer helm-buffer + ;; bury-buffer from this window. + (bury-buffer) ;[1] + ;; Be sure we call this from helm-buffer. + (helm-funcall-foreach 'cleanup)) + (helm-kill-async-processes) + ;; 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 + ;; the `no-other-window' prop there. + (helm-prevent-switching-other-window :enabled nil) + (helm-log-run-hook 'helm-cleanup-hook) + (helm-frame-or-window-configuration 'restore) + ;; [1] now bury-buffer from underlying windows otherwise, + ;; if this window is killed the underlying buffer will + ;; be a helm buffer. + (replace-buffer-in-windows helm-buffer) + (setq helm-alive-p nil) + ;; This is needed in some cases where last input + ;; is yielded infinitely in minibuffer after helm session. + (helm-clean-up-minibuffer)) + +(defun helm-clean-up-minibuffer () + "Remove contents of minibuffer." + (let ((miniwin (minibuffer-window))) + ;; Clean only current minibuffer used by helm. + ;; i.e The precedent one is active. + (unless (minibuffer-window-active-p miniwin) + (with-current-buffer (window-buffer miniwin) + (delete-minibuffer-contents))))) + + +;;; Core: input handling +;; +;; +(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))))) + +(defun helm-check-new-input (input) + "Check INPUT string and update the helm buffer if necessary." + ;; First time minibuffer is entered + ;; we check value of `helm-pattern' that have been set + ;; in `helm-initial-setup' when `helm-maybe-use-default-as-input' + ;; is non--nil. After this initial check, reset + ;; `helm-maybe-use-default-as-input' and ignore this. + ;; This happen only when source is `delayed'. + (when helm-maybe-use-default-as-input ; nil when non--delayed. + (setq input helm-pattern) + (with-helm-after-update-hook (setq helm-pattern "")) + (setq helm-maybe-use-default-as-input nil)) + ;; In delayed sources `helm-pattern' have not been resat yet. + (unless (equal input helm-pattern) + (setq helm-pattern input) + (unless (helm-action-window) + (setq helm-input helm-pattern)) + (helm-log "helm-pattern = %S" helm-pattern) + (helm-log "helm-input = %S" helm-input) + (setq helm--in-update t) + (helm-update))) + +(defun helm--reset-update-flag () + (run-with-idle-timer + helm-exit-idle-delay nil + (lambda () (setq helm--in-update nil)))) + +(add-hook 'helm-after-update-hook #'helm--reset-update-flag) + + +;;; Core: source compiler +;; +;; +(defun helm-compile-sources (sources funcs) + "Compile SOURCES with FUNCS. +See `helm-compile-source-functions'. +Helm plug-ins are realized by this function." + (mapcar + (lambda (source) + (cl-loop with src = (if (listp source) source (symbol-value source)) + for noplug = (assoc 'dont-plug src) + for f in funcs + unless (and noplug (memq f (cdr noplug))) + do (setq src (funcall f src)) + finally (cl-return src))) + sources)) + + +;; Core: all candidates + +(defun helm-get-candidates (source) + "Retrieve and return the list of candidates from SOURCE." + (let* (inhibit-quit + (candidate-fn (assoc-default 'candidates source)) + (candidate-proc (assoc-default 'candidates-process source)) + (type-error (lambda () + (error + "`%s' must either be a function, a variable or a list" + (or candidate-fn candidate-proc)))) + (candidates (condition-case-unless-debug err + ;; Process candidates-(process) function + ;; It may return a process or a list of candidates. + (if candidate-proc + (helm-interpret-value candidate-proc source) + (helm-interpret-value candidate-fn source)) + (error (helm-log "Error: %S" err) nil)))) + (when (and (processp candidates) (not candidate-proc)) + (warn "Candidates function `%s' should be called in a `candidates-process' attribute" + candidate-fn)) + (cond ((processp candidates) + ;; Candidates will be filtered later in process filter. + candidates) + ((or (null candidates) + ;; 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). + ;; e.g (completing-read "test: " '("")) + (equal candidates '(""))) + nil) + ((listp candidates) + ;; Transform candidates with `candidate-transformer' functions if + ;; some, otherwise return candidates. + (helm-transform-candidates candidates source)) + (t (funcall type-error))))) + +(defmacro helm-while-no-input (&rest body) + "Same as `while-no-input' but without testing with `input-pending-p'." + (declare (debug t) (indent 0)) + (let ((catch-sym (make-symbol "input")) + inhibit-quit) + `(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 not yet a cached value." + (let* ((name (assoc-default 'name source)) + (candidate-cache (gethash name helm-candidate-cache))) + (helm-aif candidate-cache + (prog1 it (helm-log "Use cached candidates")) + (helm-log "No cached candidates, calculate candidates") + (let ((candidates (helm-get-candidates source))) + (cond ((processp candidates) + (push (cons candidates + (append source + (list (cons 'item-count 0) + (cons 'incomplete-line "")))) + helm-async-processes) + (set-process-filter candidates 'helm-output-filter) + (setq candidates nil)) + ((not (assoc 'volatile source)) + (puthash name candidates helm-candidate-cache))) + candidates)))) + + +;;; Core: candidate transformers +(defun helm-transform-mapcar (function args) + "`mapcar' for candidate-transformer. + +ARGS is (cand1 cand2 ...) or ((disp1 . real1) (disp2 . real2) ...) + +\(helm-transform-mapcar 'upcase '(\"foo\" \"bar\")) +=> (\"FOO\" \"BAR\") +\(helm-transform-mapcar 'upcase '((\"1st\" . \"foo\") (\"2nd\" . \"bar\"))) +=> ((\"1st\" . \"FOO\") (\"2nd\" . \"BAR\")) +" + (cl-loop for arg in args + if (consp arg) + collect (cons (car arg) (funcall function (cdr arg))) + else + collect (funcall function arg))) + +(defun helm-process-candidate-transformer (candidates source) + "Execute `candidate-transformer' function(s) on CANDIDATES in SOURCE." + (helm-aif (assoc-default 'candidate-transformer source) + (helm-composed-funcall-with-source source it candidates) + candidates)) + +(defun helm-process-filtered-candidate-transformer (candidates source) + "Execute `filtered-candidate-transformer' function(s) on CANDIDATES in SOURCE." + (helm-aif (assoc-default 'filtered-candidate-transformer source) + (helm-composed-funcall-with-source source it candidates source) + candidates)) + +(defmacro helm--maybe-process-filter-one-by-one-candidate (candidate source) + "Execute `filter-one-by-one' function(s) on CANDIDATE in SOURCE." + `(helm-aif (assoc-default 'filter-one-by-one ,source) + (if (and (listp it) + (not (functionp it))) ;; Don't treat lambda's as list. + (cl-loop for f in it + do (setq ,candidate (funcall f ,candidate))) + (setq ,candidate (funcall it ,candidate))))) + +(defun helm--initialize-one-by-one-candidates (candidates source) + "Process the CANDIDATES with the `filter-one-by-one' function in SOURCE. +Return CANDIDATES when pattern is empty." + (helm-aif (and (string= helm-pattern "") + (assoc-default 'filter-one-by-one source)) + (cl-loop for cand in candidates + do (helm--maybe-process-filter-one-by-one-candidate cand source) + collect cand) + candidates)) + +(defun helm-process-filtered-candidate-transformer-maybe + (candidates source process-p) + "Execute `filtered-candidate-transformer' function(s) on CANDIDATES in SOURCE. +When PROCESS-P is non-nil execute `filtered-candidate-transformer' +functions if some, otherwise return CANDIDATES." + (if process-p + ;; When no filter return CANDIDATES unmodified. + (helm-process-filtered-candidate-transformer candidates source) + candidates)) + +(defun helm-process-real-to-display (candidates source) + "Execute real-to-display function on all CANDIDATES of SOURCE." + (helm-aif (assoc-default 'real-to-display source) + (setq candidates (helm-funcall-with-source + source 'mapcar + (lambda (cand_) + (if (consp cand_) + ;; override DISPLAY from candidate-transformer + (cons (funcall it (cdr cand_)) (cdr cand_)) + (cons (funcall it cand_) cand_))) + candidates)) + candidates)) + +(defun helm-transform-candidates (candidates source &optional process-p) + "Transform CANDIDATES of SOURCE according to candidate transformers. +When PROCESS-P is non-nil execute the `filtered-candidate-transformer' functions +otherwise only the `candidate-transformer' functions are processed. +When attribute `real-to-display' is present, execute its function on all maybe +filtered CANDIDATES." + (helm-process-real-to-display + (helm-process-filtered-candidate-transformer-maybe + (helm-process-candidate-transformer + (helm--initialize-one-by-one-candidates candidates source) source) + source process-p) + source)) + + +;; Core: narrowing candidates +(defun helm-candidate-number-limit (source) + "Apply candidate-number-limit attribute value. +This overhide variable `helm-candidate-number-limit'. + +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." + (helm-aif (assq 'candidate-number-limit source) + (or (cdr it) 99999999) + (or helm-candidate-number-limit 99999999))) + +(defun helm-candidate-get-display (candidate) + "Get searched display part from CANDIDATE. +CANDIDATE is a string, a symbol, or \(DISPLAY . REAL\) cons cell." + (cond ((car-safe candidate)) + ((symbolp candidate) + (symbol-name candidate)) + ((numberp candidate) + (number-to-string candidate)) + (t candidate))) + +(defun helm-process-pattern-transformer (pattern source) + "Execute pattern-transformer attribute PATTERN function in SOURCE." + (helm-aif (assoc-default 'pattern-transformer source) + (helm-composed-funcall-with-source source it pattern) + pattern)) + +(defun helm-default-match-function (candidate) + "Check if `helm-pattern' match CANDIDATE. +Default function to match candidates according to `helm-pattern'." + (string-match helm-pattern candidate)) + + +;;; Fuzzy matching +;; +;; +(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$\" + ^helm.el$ + => \"helm[.]el$\"." + (let ((ls (split-string-and-unquote pattern ""))) + (if (string= "^" (car ls)) + ;; Exact match. + (mapconcat (lambda (c) + (if (and (string= c "$") + (string-match "$\\'" pattern)) + c (regexp-quote c))) + (cdr ls) "") + ;; Fuzzy match. + (mapconcat (lambda (c) + (if (and (string= c "$") + (string-match "$\\'" pattern)) + c (format "[^%s]*%s" c (regexp-quote c)))) + ls "")))) + +(defvar helm--fuzzy-regexp-cache (make-hash-table :test 'eq)) +(defun helm--fuzzy-match-maybe-set-pattern () + ;; Computing helm-pattern with helm--mapconcat-pattern + ;; is costly, so cache it once time for all and reuse it + ;; until pattern change. + (when helm--in-fuzzy + (let ((fun (if (string-match "\\`\\^" helm-pattern) + #'identity + #'helm--mapconcat-pattern))) + (clrhash helm--fuzzy-regexp-cache) + ;; FIXME: Splitted part are not handled here, + ;; I must compute them in `helm-search-match-part' + ;; when negation and in-buffer are used. + (if (string-match "\\`!" helm-pattern) + (puthash 'helm-pattern + (if (> (length helm-pattern) 1) + (list (funcall fun (substring helm-pattern 1 2)) + (funcall fun (substring helm-pattern 1))) + '("" "")) + helm--fuzzy-regexp-cache) + (puthash 'helm-pattern + (if (> (length helm-pattern) 0) + (list (funcall fun (substring helm-pattern 0 1)) + (funcall fun helm-pattern)) + '("" "")) + helm--fuzzy-regexp-cache))))) + +(defun helm-fuzzy-match (candidate) + "Check if `helm-pattern' fuzzy match CANDIDATE. +This function is used with sources build with `helm-source-sync'." + (unless (string-match " " helm-pattern) + ;; When pattern have one or more spaces, let + ;; match-plugin doing the job with no fuzzy matching.[1] + (let ((regexp (cadr (gethash 'helm-pattern helm--fuzzy-regexp-cache)))) + (if (string-match "\\`!" helm-pattern) + (not (string-match regexp candidate)) + (string-match regexp candidate))))) + +(defun helm-fuzzy-search (pattern) + "Same as `helm-fuzzy-match' but for sources build with `helm-source-in-buffer'." + (unless (string-match " " helm-pattern) + ;; Same as in `helm-fuzzy-match' ref[1]. + (let* ((regexps (gethash 'helm-pattern helm--fuzzy-regexp-cache)) + (partial-regexp (car regexps)) + (regexp (cadr regexps))) + (if (string-match "\\`!" pattern) + ;; Don't try to search here, just return + ;; the position of line and go ahead, + ;; letting `helm-search-match-part' checking if + ;; pattern match against this line. + (prog1 (list (point-at-bol) (point-at-eol)) + (forward-line 1)) + ;; We could use here directly `re-search-forward' + ;; on the regexp produced by `helm--mapconcat-pattern', + ;; but it is very slow because emacs have to do an incredible + ;; amount of loops to match e.g "[^f]*o[^o]..." in the whole buffer, + ;; more the regexp is long more the amount of loops grow. + ;; (Probably leading to a max-lisp-eval-depth error if both + ;; regexp and buffer are too big) + ;; So just search the first bit of pattern e.g "[^f]*f", and + ;; then search the corresponding line with the whole regexp, + ;; which increase dramatically the speed of the search. + (cl-loop while (re-search-forward partial-regexp nil t) + for bol = (point-at-bol) + for eol = (point-at-eol) + if (progn (goto-char bol) + (re-search-forward regexp eol t)) + do (goto-char eol) and return t + else do (goto-char eol) + finally return nil))))) + +(defsubst helm--collect-pairs-in-string (string) + (cl-loop for str on (split-string string "" t) by 'cdr + when (cdr str) + collect (list (car str) (cadr str)))) + +(defun helm-score-candidate-for-pattern (candidate pattern) + "Give a score to CANDIDATE according to PATTERN. +Score is calculated against number of contiguous matches found with PATTERN. +If PATTERN is fully matched in CANDIDATE a maximal score (100) is given. +A bonus of one point is given when PATTERN prefix match CANDIDATE. +Contiguous matches have a coefficient of 2." + (let* ((pat-lookup (helm--collect-pairs-in-string pattern)) + (str-lookup (helm--collect-pairs-in-string candidate)) + (bonus (if (equal (car pat-lookup) (car str-lookup)) 1 0)) + (bonus1 (and (string-match (concat "\\<" (regexp-quote pattern) "\\>") + candidate) + 100))) + (+ bonus (or bonus1 + ;; Give a coefficient of 2 for contiguous matches. + ;; That's mean that "wiaaaki" will not take precedence + ;; on "aaawiki" when matching on "wiki" even if "wiaaaki" + ;; starts by "wi". + (* (length (cl-nintersection + pat-lookup str-lookup :test 'equal)) + 2))))) + +(defun helm-fuzzy-matching-default-sort-fn (candidates _source &optional use-real) + "The transformer for sorting candidates in fuzzy matching. +It is sorting on the display part of by default. + +Sort CANDIDATES according to their score calculated by +`helm-score-candidate-for-pattern'. When two candidates have the +same score sort is made by length. Set USE-REAL to non-nil to +sort on the real part." + (if (string= helm-pattern "") + candidates + (let ((table-scr (make-hash-table :test 'equal))) + (sort candidates + (lambda (s1 s2) + ;; Score and measure the length on real or display part of candidate + ;; according to `use-real'. + (let* ((real-or-disp-fn (if use-real #'cdr #'car)) + (cand1 (if (consp s1) + (funcall real-or-disp-fn s1) + s1)) + (cand2 (if (consp s2) + (funcall real-or-disp-fn s2) + s2)) + (data1 (or (gethash cand1 table-scr) + (puthash cand1 (list (helm-score-candidate-for-pattern + cand1 helm-pattern) + (length cand1)) + table-scr))) + (data2 (or (gethash cand2 table-scr) + (puthash cand2 (list (helm-score-candidate-for-pattern + cand2 helm-pattern) + (length cand2)) + table-scr))) + (len1 (cadr data1)) + (len2 (cadr data2)) + (scr1 (car data1)) + (scr2 (car data2))) + (cond ((= scr1 scr2) + (< len1 len2)) + ((> scr1 scr2))))))))) + +(defun helm-fuzzy-default-highlight-match (candidate) + "The default function to highlight matches in fuzzy matching. +It is meant to use with `filter-one-by-one' slot." + (let* ((pair (and (consp candidate) candidate)) + (display (helm-stringify (if pair (car pair) candidate))) + (real (cdr pair))) + (with-temp-buffer + (insert display) + (goto-char (point-min)) + (if (search-forward helm-pattern nil t) + (add-text-properties + (match-beginning 0) (match-end 0) '(face helm-match)) + (cl-loop with pattern = (if (string-match-p " " helm-pattern) + (split-string helm-pattern) + (split-string helm-pattern "" t)) + for p in pattern + do + (when (search-forward p nil t) + (add-text-properties + (match-beginning 0) (match-end 0) '(face helm-match))))) + (setq display (buffer-string))) + (if real (cons display real) display))) + +(defun helm-fuzzy-highlight-matches (candidates _source) + "The filtered-candidate-transformer function to highlight matches in fuzzy. +See helm-fuzzy-default-highlight-match." + (cl-loop for c in candidates + collect (helm-fuzzy-default-highlight-match c))) + +(defun helm-match-functions (source) + (let ((matchfns (or (assoc-default 'match source) + (assoc-default 'match-strict source) + #'helm-default-match-function))) + (if (and (listp matchfns) (not (functionp matchfns))) + matchfns (list matchfns)))) + +(defun helm-search-functions (source) + (let ((searchfns (assoc-default 'search source))) + (if (and (listp searchfns) (not (functionp searchfns))) + searchfns (list searchfns)))) + +(defmacro helm--accumulate-candidates (candidate newmatches + hash item-count limit source) + "Add CAND into NEWMATCHES and use HASH to uniq NEWMATCHES. +Argument ITEM-COUNT count the matches. +if ITEM-COUNT reaches LIMIT, exit from inner loop." + `(unless (gethash ,candidate ,hash) + (unless (assq 'allow-dups ,source) + (puthash ,candidate t ,hash)) + (helm--maybe-process-filter-one-by-one-candidate ,candidate ,source) + (push ,candidate ,newmatches) + (cl-incf ,item-count) + (when (= ,item-count ,limit) (cl-return)))) + +(defun helm-take-first-elements (seq n) + "Return the N first element of SEQ if SEQ is longer than N. +It is used to narrow down list of candidates to `helm-candidate-number-limit'." + (if (> (length seq) n) (cl-subseq seq 0 n) seq)) + +(cl-defun helm-set-case-fold-search (&optional (pattern helm-pattern)) + "Used to set the value of `case-fold-search' in helm. +Return t or nil depending of value of `helm-case-fold-search' +and `helm-pattern'." + (let ((helm-case-fold-search + (helm-aif (assq 'case-fold-search (helm-get-current-source)) + (cdr it) + helm-case-fold-search)) + ;; Only parse basename for filenames + ;; to avoid setting case sensitivity + ;; when expanded directories contains upcase + ;; characters. + (bn-or-pattern (if (string-match "[~/]*" pattern) + ;; `helm-basename' is not available yet. + (file-name-nondirectory + (directory-file-name pattern)) + pattern))) + (helm-set-case-fold-search-1 bn-or-pattern))) + +(defun helm-set-case-fold-search-1 (pattern) + (cl-case helm-case-fold-search + (smart (let ((case-fold-search nil)) + (if (string-match "[[:upper:]]" pattern) nil t))) + (t helm-case-fold-search))) + +(defun helm-match-from-candidates (cands matchfns match-part-fn limit source) + (let (matches) + (condition-case-unless-debug err + (let ((item-count 0) + (case-fold-search (helm-set-case-fold-search))) + (clrhash helm-match-hash) + (cl-dolist (match matchfns) + (let (newmatches) + (cl-dolist (candidate cands) + (unless (gethash candidate helm-match-hash) + (let ((target (helm-candidate-get-display candidate))) + (when (funcall match + (if match-part-fn + (funcall match-part-fn target) target)) + (helm--accumulate-candidates + candidate newmatches + helm-match-hash item-count limit source))))) + ;; filter-one-by-one may return nil candidates, so delq them if some. + (setq matches (nconc matches (nreverse (delq nil newmatches))))))) + (error (unless (eq (car err) 'invalid-regexp) ; Always ignore regexps errors. + (helm-log-error "helm-match-from-candidates in source `%s': %s %s" + (assoc-default 'name source) (car err) (cdr err))) + (setq matches nil))) + matches)) + +(defun helm-compute-matches (source) + "Start computing candidates in SOURCE." + (save-current-buffer + (let ((matchfns (helm-match-functions source)) + (matchpartfn (assoc-default 'match-part source)) + (helm-source-name (assoc-default 'name source)) + (helm-current-source source) + (limit (helm-candidate-number-limit source)) + (helm-pattern (helm-process-pattern-transformer + helm-pattern source))) + (helm--fuzzy-match-maybe-set-pattern) + ;; If source have a `filtered-candidate-transformer' attr + ;; Filter candidates with this func, otherwise just compute + ;; candidates. + (helm-process-filtered-candidate-transformer + (if (or (equal helm-pattern "") + (equal matchfns '(identity))) + ;; Compute all candidates up to LIMIT. + (helm-take-first-elements + (helm-get-cached-candidates source) limit) + ;; Compute candidates according to pattern with their match fns. + (helm-match-from-candidates + (helm-get-cached-candidates source) matchfns matchpartfn limit source)) + source)))) + +(defun helm-render-source (source matches) + "Display MATCHES from SOURCE according to its settings." + (helm-log "Source name = %S" (assoc-default 'name source)) + (when matches + (helm-insert-header-from-source source) + (if (not (assq 'multiline source)) + (cl-loop for m in matches + for count from 1 + do (helm-insert-match m 'insert source count)) + (let ((start (point)) + (count 0) + separate) + (cl-dolist (match matches) + (cl-incf count) + (if separate + (helm-insert-candidate-separator) + (setq separate t)) + (helm-insert-match match 'insert source count)) + (put-text-property start (point) 'helm-multiline t))))) + +(defmacro helm--maybe-use-while-no-input (&rest body) + "Wrap BODY in `helm-while-no-input' unless initializing a remote connection." + `(progn + (if (and (file-remote-p helm-pattern) + (not (file-remote-p helm-pattern nil t))) + ;; 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)))) + +(defun helm--compute-sources (src-list) + (cl-loop with matches = (helm--maybe-use-while-no-input + (cl-loop for src in src-list + collect (helm-compute-matches src))) + when (eq matches t) do (setq matches nil) + for src in src-list + for mtc in matches + do (helm-render-source src mtc))) + +(cl-defun helm-process-delayed-sources (delayed-sources &optional preselect source) + "Process helm DELAYED-SOURCES. +Move selection to string or regexp PRESELECT if non--nil. +This function is called in `helm-process-delayed-sources-timer' +when emacs is idle for `helm-idle-delay'." + (with-helm-quittable + (helm-log "Delayed sources = %S" + (mapcar (lambda (s) + (assoc-default 'name s)) + delayed-sources)) + (with-current-buffer (helm-buffer-get) + (save-excursion + (goto-char (point-max)) + (helm--compute-sources delayed-sources) + (when (and (not (helm-empty-buffer-p)) + ;; No selection yet. + (= (overlay-start helm-selection-overlay) + (overlay-end helm-selection-overlay))) + (helm-update-move-first-line 'without-hook))) + (save-excursion + (goto-char (point-min)) + (helm-log-run-hook 'helm-update-hook)) + (setq helm-force-updating-p nil) + (unless (assoc 'candidates-process source) + (helm-display-mode-line (helm-get-current-source)) + (helm-log-run-hook 'helm-after-update-hook)) + (when preselect (helm-preselect preselect source))))) + + +;;; Core: helm-update +;; +(defun helm-update (&optional preselect source) + "Update candidates list in `helm-buffer' according to `helm-pattern'. +Argument PRESELECT is a string or regexp used to move selection to a particular +place once updating is done. It should be used on single source because search +is done on whole `helm-buffer' and not on current source." + (helm-log "Start updating") + (helm-kill-async-processes) + ;; When persistent action have been called + ;; we have two windows even with `helm-full-frame'. + ;; So go back to one window when updating if `helm-full-frame' + ;; is non--nil. + (with-helm-window + (when helm-onewindow-p (delete-other-windows))) + (with-current-buffer (helm-buffer-get) + (set (make-local-variable 'helm-input-local) helm-pattern) + (let (normal-sources + delayed-sources) + (unwind-protect + (progn + ;; Iterate over all the sources + (cl-loop for source in (cl-remove-if-not + 'helm-update-source-p (helm-get-sources)) + if (helm-delayed-source-p source) + ;; Delayed sources just get collected for later + ;; processing + collect source into ds + else + ;; Collect the normal sources + collect source into ns + ;; Export the variables from cl-loop + finally (setq delayed-sources ds + normal-sources ns)) + (erase-buffer) + ;; Render all the sources into the helm buffer after + ;; calculating all candidates. + ;; Candidates must be computed AFTER erasing buffer + ;; even if it cause flickering; Doing so avoid + ;; unexpected results when executing actions. + (helm--compute-sources normal-sources)) + (helm-log "Delayed sources = %S" + (mapcar (lambda (s) (assoc-default 'name s)) + delayed-sources)) + (cond ((and preselect delayed-sources normal-sources) + ;; Preselection run here when there is + ;; normal AND delayed sources. + (helm-log "Update preselect candidate %s" preselect) + (helm-preselect preselect source)) + (delayed-sources ; Preselection and hooks will run later. + (helm-update-move-first-line 'without-hook)) + (t ; No delayed sources, run the hooks now. + (helm-update-move-first-line) + (unless (assoc 'candidates-process source) + (helm-display-mode-line (helm-get-current-source)) + (helm-log-run-hook 'helm-after-update-hook)) + (when preselect + (helm-log "Update preselect candidate %s" preselect) + (helm-preselect preselect source)) + (setq helm-force-updating-p nil))) + (when delayed-sources + ;; Allow giving a value to `delayed' attr from inside source. + ;; Retain the biggest value (the slower) found in DELAYED-SOURCES. + (let ((helm-idle-delay (cl-loop with delay = helm-idle-delay + for s in delayed-sources + for d = (assoc-default 'delayed s) + when d do (setq delay (max delay d)) + finally return delay))) + (run-with-idle-timer + ;; Be sure helm-idle-delay is > + ;; to helm-input-idle-delay + ;; otherwise use value of helm-input-idle-delay + ;; or 0.01 if == to 0. + (max helm-idle-delay helm-input-idle-delay 0.001) nil + 'helm-process-delayed-sources delayed-sources preselect source))) + (helm-log "end update"))))) + +;; Update keymap after updating. +;; Putting this in a hook allow users to disable it. +(add-hook 'helm-after-update-hook 'helm--maybe-update-keymap) + +(defun helm-update-source-p (source) + "Whether SOURCE need updating or not." + (let ((len (string-width + (if (or (assoc 'matchplugin source) + (null (assoc 'no-matchplugin source))) + ;; Don't count spaces entered when using + ;; match-plugin. + (replace-regexp-in-string " " "" helm-pattern) + helm-pattern)))) + (and (or (not helm-source-filter) + (member (assoc-default 'name source) helm-source-filter)) + (>= len + (helm-aif (assoc 'requires-pattern source) (or (cdr it) 1) 0)) + ;; These incomplete regexps hang helm forever + ;; so defer update. Maybe replace spaces quoted when using + ;; match-plugin-mode. + (not (member (replace-regexp-in-string "\\s\\ " " " helm-pattern) + helm-update-blacklist-regexps))))) + +(defun helm-delayed-source-p (source) + "Wheter SOURCE is a delayed source or not." + (or (assoc 'delayed source) + (and helm-quick-update + (> (length helm-sources) 1) + (< (window-height (get-buffer-window (current-buffer))) + (line-number-at-pos (point-max)))))) + +(defun helm-update-move-first-line (&optional without-hook) + "Goto first line of `helm-buffer'." + (goto-char (point-min)) + (unless without-hook + (save-excursion (helm-log-run-hook 'helm-update-hook))) + (helm-next-line)) + +(defun helm-force-update (&optional preselect) + "Force recalculation and update of candidates. +The difference with `helm-update' is this function is reevaling +the `init' and `update' attributes functions when present +before updating candidates according to pattern i.e calling `helm-update'. +Selection is preserved to current candidate or moved to PRESELECT +if specified." + (interactive) + (let ((source (helm-get-current-source)) + (selection (helm-get-selection nil t)) + ;; `helm-goto-source' need to have all sources displayed + ;; So disable `helm-quick-update'. + helm-quick-update) + (setq helm-force-updating-p t) + (when source + (mapc 'helm-force-update--reinit + (helm-get-sources))) + (helm-update (or preselect selection) source) + (with-helm-window (recenter)))) + +(defun helm-force-update--reinit (source) + "Reinit SOURCE by calling his update and/or init functions." + (helm-aif (helm-funcall-with-source + source 'helm-candidate-buffer) + (kill-buffer it)) + (cl-dolist (attr '(update init)) + (helm-aif (assoc-default attr source) + (helm-funcall-with-source source it))) + (helm-remove-candidate-cache source)) + +(defun helm-remove-candidate-cache (source) + "Remove SOURCE from `helm-candidate-cache'." + (remhash (assoc-default 'name source) helm-candidate-cache)) + +(defun helm-insert-match (match insert-function source &optional num) + "Insert MATCH into `helm-buffer' with INSERT-FUNCTION for SOURCE. +If MATCH is a list then insert the string intended to appear on the display +and store the real value in a text property." + (let ((start (point-at-bol (point))) + (dispvalue (helm-candidate-get-display match)) + (realvalue (cdr-safe match))) + (when (and (stringp dispvalue) + (not (zerop (length dispvalue)))) + (funcall insert-function dispvalue) + ;; Some sources with candidates-in-buffer have already added + ;; 'helm-realvalue property when creating candidate buffer. + (unless (get-text-property start 'helm-realvalue) + (and realvalue + (put-text-property start (point-at-eol) + 'helm-realvalue realvalue))) + (when num + (put-text-property start (point-at-eol) 'helm-cand-num num)) + (when helm-source-in-each-line-flag + (put-text-property start (point-at-eol) 'helm-source source)) + (funcall insert-function "\n")))) + +(defun helm-insert-header-from-source (source) + "Insert SOURCE name in `helm-buffer' header. +Maybe insert by overlay additional info after source name if SOURCE have +header-name attribute." + (let ((name (assoc-default 'name source))) + (helm-insert-header + name + (helm-aif (assoc-default 'header-name source) + (helm-funcall-with-source source it name))))) + +(defun helm-insert-header (name &optional display-string) + "Insert header of source NAME into the helm buffer. +If DISPLAY-STRING is non--nil and a string, display this additional info +after the source name by overlay." + (unless (bobp) + (let ((start (point))) + (insert "\n") + (put-text-property start (point) 'helm-header-separator t))) + (let ((start (point))) + (insert name) + (put-text-property (point-at-bol) + (point-at-eol) 'helm-header t) + (when display-string + (overlay-put (make-overlay (point-at-bol) (point-at-eol)) + 'display display-string)) + (insert "\n") + (put-text-property start (point) 'face 'helm-source-header))) + +(defun helm-insert-candidate-separator () + "Insert separator of candidates into the helm buffer." + (insert (propertize helm-candidate-separator 'face 'helm-separator)) + (put-text-property (point-at-bol) + (point-at-eol) 'helm-candidate-separator t) + (insert "\n")) + + +;;; Core: async process +;; +(defun helm-output-filter (process output-string) + "The `process-filter' function for helm async sources." + (with-helm-quittable + (helm-output-filter-1 (assoc process helm-async-processes) output-string))) + +(defun helm-output-filter-1 (process-assoc output-string) + (helm-log "output-string = %S" output-string) + (with-current-buffer helm-buffer + (let ((source (cdr process-assoc))) + (save-excursion + (helm-aif (assoc-default 'insertion-marker source) + (goto-char it) + (goto-char (point-max)) + (helm-insert-header-from-source source) + (setcdr process-assoc + (append source `((insertion-marker . ,(point-marker)))))) + (helm-output-filter--process-source + (car process-assoc) output-string source + (helm-candidate-number-limit source)))) + (helm-output-filter--post-process))) + +(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") + (assoc 'incomplete-line source) + source) + source t)) + (when candidate ; filter-one-by-one may return nil candidates. + (if (assq 'multiline source) + (let ((start (point))) + (helm-insert-candidate-separator) + (helm-insert-match candidate 'insert-before-markers source + (1+ (cdr (assoc 'item-count source)))) + (put-text-property start (point) 'helm-multiline t)) + (helm-insert-match candidate 'insert-before-markers source + (1+ (cdr (assoc 'item-count source))))) + (cl-incf (cdr (assoc 'item-count source))) + (when (>= (assoc-default 'item-count source) limit) + (helm-kill-async-process process) + (cl-return))))) + +(defun helm-output-filter--collect-candidates (lines incomplete-line-info source) + "Collect LINES maybe completing the truncated first and last lines." + ;; The output of process may come in chunks of any size, + ;; so the last line of LINES come truncated, this truncated line is + ;; stored in INCOMPLETE-LINE-INFO and will be concated with the first + ;; incomplete line of next chunk arriving. + ;; INCOMPLETE-LINE-INFO is an attribute of source which is created + ;; with an empty string when the source is computed => (incomplete-line . "") + (helm-log "incomplete-line-info = %S" (cdr incomplete-line-info)) + (butlast + (cl-loop for line in lines + ;; On start `incomplete-line-info' value is empty string. + for newline = (helm-aif (cdr incomplete-line-info) + (prog1 + (concat it line) + (setcdr incomplete-line-info nil)) + line) + do (helm--maybe-process-filter-one-by-one-candidate newline source) + collect newline + ;; Store last incomplete line (last chunk truncated) + ;; until new output arrives. + finally do (setcdr incomplete-line-info line)))) + +(defun helm-output-filter--post-process () + (let ((src (helm-get-current-source))) + (helm-log-run-hook 'helm-update-hook) + (helm-aif (get-buffer-window helm-buffer 'visible) + (with-selected-window it + (helm-skip-noncandidate-line 'next) + (helm-mark-current-line) + (helm-display-mode-line src) + (helm-log-run-hook 'helm-after-update-hook))))) + +(defun helm-process-deferred-sentinel-hook (process event file) + "Defer remote processes in sentinels. +Meant to be called at beginning of a sentinel process function." + (when (and (string= event "finished\n") + (or (file-remote-p file) + ;; `helm-suspend-update-flag' + ;; is non--nil here only during a + ;; running process, this will never be called + ;; when user set it explicitely with `C-!'. + helm-suspend-update-flag)) + (setq helm-suspend-update-flag t) + ;; Kill the process but don't delete entry in + ;; `helm-async-processes'. + (helm-kill-async-process process) + ;; When tramp tries to open the same connection twice in a + ;; short time frame (less than 5s) it throw 'suppress which + ;; call the real-handler on the main "Emacs", so we wait + ;; 5s before updating to avoid this [1], but allowing user to + ;; enter input during this delay. + ;; [1] On last Emacs versions, this is fixed and tramp return + ;; nil in this situation. + ;; Note: It is difficult to have a value < to 5 for + ;; `tramp-connection-min-time-diff', because the process die + ;; when calling too quickly same process. + (run-at-time (or (and (boundp 'tramp-connection-min-time-diff) + tramp-connection-min-time-diff) + 5) + nil #'(lambda () + (when helm-alive-p ; Don't run timer fn after quit. + (setq helm-suspend-update-flag nil) + (helm-check-minibuffer-input)))))) + +(defun helm-kill-async-processes () + "Kill all asynchronous processes registered in `helm-async-processes'." + (while helm-async-processes + (helm-kill-async-process (caar helm-async-processes)) + (setq helm-async-processes (cdr helm-async-processes)))) + +(defun helm-kill-async-process (process) + "Stop output from `helm-output-filter' and kill associated PROCESS." + (set-process-filter process nil) + (delete-process process)) + + +;;; Core: action +;; +(defun helm-execute-selection-action () + "Execute current action and kill the action buffer if present." + (helm-log-run-hook 'helm-before-action-hook) + ;; Position can be different when `helm-current-buffer' + ;; is splitted, so jump to this position before executing action. + (helm-current-position 'restore) + (unwind-protect + (helm-execute-selection-action-1) + (helm-aif (get-buffer helm-action-buffer) + (kill-buffer it)) + (helm-log-run-hook 'helm-after-action-hook))) + +(defun helm-execute-selection-action-1 (&optional + selection action + preserve-saved-action) + "Execute ACTION on current SELECTION. +If PRESERVE-SAVED-ACTION is non--nil save action." + (helm-log "executing action") + (setq action (helm-get-default-action + (or action + helm-saved-action + (if (get-buffer helm-action-buffer) + (helm-get-selection helm-action-buffer) + (helm-get-actions-from-current-source))))) + (let ((source (or helm-saved-current-source + (helm-get-current-source))) + non-essential) + (setq selection (or selection + (helm-get-selection) + (and (assoc 'accept-empty source) ""))) + (unless preserve-saved-action (setq helm-saved-action nil)) + (when (and selection action) + (helm-funcall-with-source + source action + (helm-coerce-selection selection source))))) + +(defun helm-coerce-selection (selection source) + "Apply coerce attribute function to SELECTION in SOURCE. +Coerce source with coerce function." + (helm-aif (assoc-default 'coerce source) + (helm-funcall-with-source source it selection) + selection)) + +(defun helm-get-default-action (action) + "Get the first ACTION value of action list in source." + (if (and (listp action) (not (functionp action))) + (cdar action) + action)) + +(defun helm-select-action () + "Select an action for the currently selected candidate. +If action buffer is selected, back to the helm buffer." + (interactive) + (helm-log-run-hook 'helm-select-action-hook) + (setq helm-saved-selection (helm-get-selection)) + (with-selected-frame (with-helm-window (selected-frame)) + (prog1 + (cond ((get-buffer-window helm-action-buffer 'visible) + (set-window-buffer (get-buffer-window helm-action-buffer) + helm-buffer) + (kill-buffer helm-action-buffer) + (helm-display-mode-line (helm-get-current-source)) + (helm-set-pattern helm-input 'noupdate)) + (helm-saved-selection + (setq helm-saved-current-source (helm-get-current-source)) + (let ((actions (helm-get-actions-from-current-source))) + (if (functionp actions) + (message "Sole action: %s" actions) + (helm-show-action-buffer actions) + ;; Be sure the minibuffer is entirely deleted (#907). + (helm--delete-minibuffer-contents-from "") + ;; Make `helm-pattern' differs from the previous value. + (setq helm-pattern 'dummy) + (helm-check-minibuffer-input)))) + (t (message "No Actions available"))) + (run-hooks 'helm-window-configuration-hook)))) + +(defun helm-show-action-buffer (actions) + (with-current-buffer (get-buffer-create helm-action-buffer) + (erase-buffer) + (buffer-disable-undo) + (set-window-buffer (get-buffer-window helm-buffer) helm-action-buffer) + (set (make-local-variable 'helm-sources) + `(((name . "Actions") + (volatile) + (nomark) + (candidates . ,actions) + (mode-line . ("Action(s)" "TAB:BackToCands RET/f1/f2/fn:NthAct")) + (candidate-transformer + . (lambda (candidates) + (cl-loop for (i . j) in candidates + for count from 1 + collect + (cons (concat (cond ((> count 12) + " ") + ((< count 10) + (format "[f%s] " count)) + (t (format "[f%s] " count))) + (propertize i 'face 'helm-action)) + j)))) + (candidate-number-limit)))) + (set (make-local-variable 'helm-source-filter) nil) + (set (make-local-variable 'helm-selection-overlay) nil) + (helm-initialize-overlays helm-action-buffer))) + + +;; Core: selection + +(defun helm-display-source-at-screen-top-maybe (unit) + "Display source at top of screen when UNIT value is 'source. +With any other value of UNIT return nil." + (when (and helm-display-source-at-screen-top (eq unit 'source)) + (set-window-start (selected-window) + (save-excursion (forward-line -1) (point))))) + +(defun helm-skip-noncandidate-line (direction) + "Skip source header or candidates separator when going in DIRECTION. +Possible value of DIRECTION are 'next or 'previous. +Same as `helm-skip-header-and-separator-line' but ensure +point is moved to the right place when at bop or eob." + (helm-skip-header-and-separator-line direction) + (and (bobp) (forward-line 1)) ; Skip first header. + (and (eobp) (forward-line -1))) ; Avoid last empty line. + +(defun helm-skip-header-and-separator-line (direction) + "Skip source header or candidate separator when going to next/previous line. +Possible value of DIRECTION are 'next or 'previous." + (let ((fn (cl-ecase direction + (next 'eobp) + (previous 'bobp)))) + (while (and (not (funcall fn)) + (or (helm-pos-header-line-p) + (helm-pos-candidate-separator-p))) + (forward-line (if (and (eq direction 'previous) + (not (eq (point-at-bol) (point-min)))) + -1 1))))) + +(defun helm-display-mode-line (source &optional force) + "Setup mode-line and header-line for `helm-buffer'." + (set (make-local-variable 'helm-mode-line-string) + (helm-interpret-value (or (and (listp source) ; Check if source is empty. + (assoc-default 'mode-line source)) + (default-value 'helm-mode-line-string)) + source)) + (let ((follow (and (eq (cdr (assq 'follow source)) 1) "(HF) "))) + ;; Setup mode-line. + (if helm-mode-line-string + (setq mode-line-format + `(" " mode-line-buffer-identification " " + (:eval (format "L%d" (helm-candidate-number-at-point))) + " " ,follow + (:eval (when ,helm--mode-line-display-prefarg + (let ((arg (prefix-numeric-value + (or prefix-arg current-prefix-arg)))) + (unless (= arg 1) + (propertize (format "[prefarg:%s] " arg) + 'face 'helm-prefarg))))) + (:eval (helm-show-candidate-number + (car-safe helm-mode-line-string))) + " " helm--mode-line-string-real " " mode-line-end-spaces) + helm--mode-line-string-real + (substitute-command-keys (if (listp helm-mode-line-string) + (cadr helm-mode-line-string) + helm-mode-line-string))) + (setq mode-line-format (default-value 'mode-line-format))) + ;; Setup header-line. + (when helm-display-header-line + (let* ((hlstr (helm-interpret-value + (and (listp source) + (assoc-default 'header-line source)) + source)) + (hlend (make-string (max 0 (- (window-width) (length hlstr))) ? ))) + (setq header-line-format + (propertize (concat " " hlstr hlend) 'face 'helm-header))))) + (when force (force-mode-line-update))) + +(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." + (when helm-alive-p + (unless (helm-empty-source-p) + (propertize + (format "[%s %s]" + (helm-get-candidate-number 'in-current-source) + (or name "Candidate(s)")) + 'face 'helm-candidate-number)))) + +(cl-defun helm-move-selection-common (&key where direction) + "Move the selection marker to a new position. +Position is determined by WHERE and DIRECTION. +Key arg WHERE can be one of: + - line + - page + - edge + - source +Key arg DIRECTION can be one of: + - previous + - next + - 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) + (next 'helm-move--next-line-fn))) + (page (cl-ecase direction + (previous 'helm-move--previous-page-fn) + (next 'helm-move--next-page-fn))) + (edge (cl-ecase direction + (previous 'helm-move--beginning-of-buffer-fn) + (next 'helm-move--end-of-buffer-fn))) + (source (cl-case direction + (previous 'helm-move--previous-source-fn) + (next 'helm-move--next-source-fn) + (t (lambda () ; A source is passed as DIRECTION arg. + (helm-move--goto-source-fn direction)))))))) + (unless (or (helm-empty-buffer-p (helm-buffer-get)) + (not (helm-window))) + (with-helm-window + (helm-log-run-hook 'helm-move-selection-before-hook) + (funcall move-func) + (and (memq direction '(next previous)) + (helm-skip-noncandidate-line direction)) + (when (helm-pos-multiline-p) + (helm-move--beginning-of-multiline-candidate)) + (helm-display-source-at-screen-top-maybe where) + (when (helm-get-previous-header-pos) + (helm-mark-current-line)) + (helm-display-mode-line (helm-get-current-source)) + (helm-log-run-hook 'helm-move-selection-after-hook))))) + +(defun helm-move--beginning-of-multiline-candidate () + (let ((header-pos (helm-get-previous-header-pos)) + (separator-pos (helm-get-previous-candidate-separator-pos))) + (when header-pos + (goto-char (if (or (null separator-pos) + (< separator-pos header-pos)) + header-pos + separator-pos)) + (forward-line 1)))) + +(defun helm-move--previous-multi-line-fn () + (forward-line -1) + (unless (helm-pos-header-line-p) + (helm-skip-header-and-separator-line 'previous) + (helm-move--beginning-of-multiline-candidate))) + +(defun helm-move--previous-line-fn () + (if (not (helm-pos-multiline-p)) + (forward-line -1) + (helm-move--previous-multi-line-fn)) + (when (and helm-move-to-line-cycle-in-source + (helm-pos-header-line-p)) + (forward-line 1) + (helm-move--end-of-source) + ;; We are at end of helm-buffer + ;; check if last candidate is a multiline candidate + ;; and jump to it + (when (and (eobp) + (save-excursion (forward-line -1) (helm-pos-multiline-p))) + (helm-move--previous-multi-line-fn)))) + +(defun helm-move--next-multi-line-fn () + (let ((header-pos (helm-get-next-header-pos)) + (separator-pos (helm-get-next-candidate-separator-pos))) + (cond ((and separator-pos + (or (null header-pos) (< separator-pos header-pos))) + (goto-char separator-pos)) + (header-pos + (goto-char header-pos))))) + +(defun helm-move--next-line-fn () + (if (not (helm-pos-multiline-p)) + (forward-line 1) + (helm-move--next-multi-line-fn)) + (when (and helm-move-to-line-cycle-in-source + (or (save-excursion (and (helm-pos-multiline-p) + (goto-char (overlay-end + helm-selection-overlay)) + (helm-end-of-source-p t))) + (helm-end-of-source-p t))) + (helm-move--beginning-of-source))) + +(defun helm-move--previous-page-fn () + (condition-case nil + (scroll-down) + (beginning-of-buffer (goto-char (point-min))))) + +(defun helm-move--next-page-fn () + (condition-case nil + (scroll-up) + (end-of-buffer (goto-char (point-max))))) + +(defun helm-move--beginning-of-buffer-fn () + (goto-char (point-min))) + +(defun helm-move--end-of-buffer-fn () + (goto-char (point-max))) + +(defun helm-move--end-of-source () + (goto-char (or (helm-get-next-header-pos) (point-max))) + (when (helm-pos-header-line-p) (forward-line -2))) + +(defun helm-move--beginning-of-source () + (goto-char (helm-get-previous-header-pos)) + (forward-line 1)) + +(defun helm-move--previous-source-fn () + (forward-line -1) + (if (bobp) + (goto-char (point-max)) + (helm-skip-header-and-separator-line 'previous)) + (goto-char (helm-get-previous-header-pos)) + (forward-line 1)) + +(defun helm-move--next-source-fn () + (goto-char (or (helm-get-next-header-pos) (point-min)))) + +(defun helm-move--goto-source-fn (source-or-name) + (goto-char (point-min)) + (let ((name (if (stringp source-or-name) source-or-name + (assoc-default 'name source-or-name)))) + (condition-case err + (while (not (string= name (helm-current-line-contents))) + (goto-char (helm-get-next-header-pos))) + (error (helm-log "%S" err))))) + +(defun helm-candidate-number-at-point () + (with-helm-buffer + (or (get-text-property (point) 'helm-cand-num) 1))) + +(defun helm--next-or-previous-line (direction &optional arg) + ;; Be sure to not use this in non--interactives calls. + (let ((helm-move-to-line-cycle-in-source + (and helm-move-to-line-cycle-in-source arg))) + (if (and arg (> arg 1)) + (cl-loop with pos = (helm-candidate-number-at-point) + with cand-num = (helm-get-candidate-number t) + with iter = (min arg (- cand-num pos)) + for count from 1 + while (<= count iter) + do + (helm-move-selection-common :where 'line :direction direction)) + (helm-move-selection-common :where 'line :direction direction)))) + +(defun helm-previous-line (&optional arg) + "Move selection to the ARG previous line(s). +Same behavior than `helm-next-line' when called with a numeric prefix arg." + (interactive "p") + (helm--next-or-previous-line 'previous arg)) + +(defun helm-next-line (&optional arg) + "Move selection to the next ARG line(s). +When a numeric prefix arg is given and this numeric arg +is > to the number of candidates, move to last candidate of +current source (i.e don't move to next source if some)." + (interactive "p") + (helm--next-or-previous-line 'next arg)) + +(defun helm-previous-page () + "Move selection back with a pageful." + (interactive) + (helm-move-selection-common :where 'page :direction 'previous)) + +(defun helm-next-page () + "Move selection forward with a pageful." + (interactive) + (helm-move-selection-common :where 'page :direction 'next)) + +(defun helm-beginning-of-buffer () + "Move selection at the top." + (interactive) + (helm-move-selection-common :where 'edge :direction 'previous)) + +(defun helm-end-of-buffer () + "Move selection at the bottom." + (interactive) + (helm-move-selection-common :where 'edge :direction 'next)) + +(defun helm-previous-source () + "Move selection to the previous source." + (interactive) + (helm-move-selection-common :where 'source :direction 'previous)) + +(defun helm-next-source () + "Move selection to the next source." + (interactive) + (helm-move-selection-common :where 'source :direction 'next)) + +(defun helm-goto-source (source-or-name) + "Move the selection to the source SOURCE-OR-NAME." + (helm-move-selection-common :where 'source :direction source-or-name)) + +(defun helm--follow-action (arg) + (let ((helm--temp-follow-flag t)) + (when (or (eq last-command 'helm-follow-action-forward) + (eq last-command 'helm-follow-action-backward) + (eq last-command 'helm-execute-persistent-action)) + (if (> arg 0) + (helm-next-line) + (helm-previous-line))) + (helm-execute-persistent-action))) + +(defun helm-follow-action-forward () + "Go to next line and execute persistent action." + (interactive) + (helm--follow-action 1)) + +(defun helm-follow-action-backward () + "Go to previous line and execute persistent action." + (interactive) + (helm--follow-action -1)) + +(defun helm-mark-current-line (&optional resumep) + "Move `helm-selection-overlay' to current line. +Note that this is not related with visibles marks, which are used +to mark candidates." + (with-helm-window + (when resumep + (goto-char helm-selection-point)) + (move-overlay + helm-selection-overlay (point-at-bol) + (if (helm-pos-multiline-p) + (let ((header-pos (helm-get-next-header-pos)) + (separator-pos (helm-get-next-candidate-separator-pos))) + (or (and (null header-pos) separator-pos) + (and header-pos separator-pos + (< separator-pos header-pos) + separator-pos) + header-pos + (point-max))) + (1+ (point-at-eol)))) + (setq helm-selection-point (overlay-start helm-selection-overlay))) + (helm-follow-execute-persistent-action-maybe)) + +(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 in minibuffer confirm message and exit on next hit. +If `minibuffer-completion-confirm' value is t, +don't exit and send message 'no match'." + (interactive) + (if (and (helm--updating-p) + (null helm--reading-passwd-or-string)) + (progn (message "[Display not ready]") + (sit-for 0.5) (message nil)) + (let* ((empty-buffer-p (with-current-buffer helm-buffer + (eq (point-min) (point-max)))) + (sel (helm-get-selection)) + (unknown (and (not empty-buffer-p) + (string= (get-text-property + 0 'display + (helm-get-selection nil 'withprop)) + "[?]")))) + (cond ((and (or empty-buffer-p unknown) + (eq minibuffer-completion-confirm 'confirm)) + (setq helm-minibuffer-confirm-state + 'confirm) + (setq minibuffer-completion-confirm nil) + (minibuffer-message " [confirm]")) + ((and (or empty-buffer-p + (unless (if minibuffer-completing-file-name + (and minibuffer-completion-predicate + (funcall minibuffer-completion-predicate sel)) + (and (stringp sel) + ;; SEL may be a cons cell when helm-comp-read + ;; is called directly with a collection composed + ;; of (display . real) and real is a cons cell. + (try-completion sel minibuffer-completion-table + minibuffer-completion-predicate))) + unknown)) + (eq minibuffer-completion-confirm t)) + (minibuffer-message " [No match]")) + (t + (setq helm-minibuffer-confirm-state nil) + (helm-exit-minibuffer)))))) +(add-hook 'helm-after-update-hook 'helm-confirm-and-exit-hook) + +(defun helm-confirm-and-exit-hook () + "Restore `minibuffer-completion-confirm' when helm update." + (unless (or (eq minibuffer-completion-confirm t) + (not helm-minibuffer-confirm-state)) + (setq minibuffer-completion-confirm + helm-minibuffer-confirm-state))) + +(defun helm-read-string (prompt &optional initial-input history + default-value inherit-input-method) + "Same as `read-string' but for reading string from a helm session." + (let ((helm--reading-passwd-or-string t)) + (read-string + prompt initial-input history default-value inherit-input-method))) + +(defun helm--updating-p () + ;; helm timer is between two cycles. + ;; IOW `helm-check-minibuffer-input' haven't yet compared input + ;; and `helm-pattern'. + (or (not (equal (minibuffer-contents) helm-pattern)) + ;; `helm-check-minibuffer-input' have launched `helm-update'. + helm--in-update)) + +(defun helm-maybe-exit-minibuffer () + (interactive) + (if (and (helm--updating-p) + (null helm--reading-passwd-or-string)) + (progn (message "[Display not ready]") + (sit-for 0.5) (message nil)) + (helm-exit-minibuffer))) + +(defun helm-exit-minibuffer () + "Select the current candidate by exiting the minibuffer." + (unless helm-current-prefix-arg + (setq helm-current-prefix-arg current-prefix-arg)) + (setq helm-exit-status 0) + (helm-log-run-hook 'helm-exit-minibuffer-hook) + (exit-minibuffer)) + +(defun helm-keyboard-quit () + "Quit minibuffer in helm. +If action buffer is displayed, kill it." + (interactive) + (when (get-buffer-window helm-action-buffer 'visible) + (kill-buffer helm-action-buffer)) + (setq helm-exit-status 1) + (abort-recursive-edit)) + +(defun helm-get-next-header-pos () + "Return the position of the next header from point." + (next-single-property-change (point) 'helm-header)) + +(defun helm-get-previous-header-pos () + "Return the position of the previous header from point." + (previous-single-property-change (point) 'helm-header)) + +(defun helm-pos-multiline-p () + "Return non-nil if the current position is in the multiline source region." + (get-text-property (point) 'helm-multiline)) + +(defun helm-get-next-candidate-separator-pos () + "Return the position of the next candidate separator from point." + (let ((hp (helm-get-next-header-pos))) + (helm-aif (next-single-property-change (point) 'helm-candidate-separator) + (or + ;; Be sure we don't catch + ;; the separator of next source. + (and hp (< it hp) it) + ;; The separator found is in next source + ;; we are at last cand, so use the header pos. + (and hp (< hp it) hp) + ;; A single source, just try next separator. + it)))) + +(defun helm-get-previous-candidate-separator-pos () + "Return the position of the previous candidate separator from point." + (previous-single-property-change (point) 'helm-candidate-separator)) + +(defun helm-pos-header-line-p () + "Return t if the current line is a header line." + (or (get-text-property (point-at-bol) 'helm-header) + (get-text-property (point-at-bol) 'helm-header-separator))) + +(defun helm-pos-candidate-separator-p () + "Return t if the current line is a candidate separator." + (get-text-property (point-at-bol) 'helm-candidate-separator)) + + +;;; Debugging +;; +;; +(defun helm-debug-output () + "Show all helm-related variables at this time." + (interactive) + (helm-help-internal " *Helm Debug*" 'helm-debug-output-function)) + +(defun helm-debug-output-function (&optional vars) + (message "Calculating all helm-related values...") + (insert "If you debug some variables or forms, set `helm-debug-variables' +to a list of forms.\n\n") + (cl-dolist (v (or vars + helm-debug-variables + (apropos-internal "^helm-" 'boundp))) + (insert "** " + (pp-to-string v) "\n" + (pp-to-string (with-current-buffer helm-buffer (eval v))) "\n")) + (message "Calculating all helm-related values...Done")) + + +;; Core: 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 `helm-selection-overlay' to CANDIDATE-OR-REGEXP on startup. +Arg CANDIDATE-OR-REGEXP can be a string or a cons cell of two strings. +When it is a cons cell helm will try to jump first to first element of cons cell +and then to second, allowing a finer preselection when possible duplicates are +before the candidate we want to preselect." + (with-helm-window + (when candidate-or-regexp + (if (and helm-force-updating-p source) + (helm-goto-source source) + (goto-char (point-min)) + (forward-line 1)) + (let ((start (point))) + (or + (if (consp candidate-or-regexp) + (and (re-search-forward (car candidate-or-regexp) nil t) + (re-search-forward (cdr candidate-or-regexp) nil t)) + (re-search-forward candidate-or-regexp nil t)) + (goto-char start)))) + (forward-line 0) ; Avoid scrolling right on long lines. + (when (helm-pos-multiline-p) + (helm-move--beginning-of-multiline-candidate)) + (when (helm-pos-header-line-p) (forward-line 1)) + (helm-mark-current-line))) + +(defun helm-delete-current-selection () + "Delete the currently selected item." + (interactive) + (with-helm-window + (cond ((helm-pos-multiline-p) + (helm-aif (helm-get-next-candidate-separator-pos) + (delete-region (point-at-bol) + (1+ (progn (goto-char it) (point-at-eol)))) + ;; last candidate + (goto-char (helm-get-previous-candidate-separator-pos)) + (delete-region (point-at-bol) (point-max))) + (when (helm-end-of-source-p) + (goto-char (or (helm-get-previous-candidate-separator-pos) + (point-min))) + (forward-line 1))) + (t + (delete-region (point-at-bol) (1+ (point-at-eol))) + (when (helm-end-of-source-p t) + (let ((headp (save-excursion + (forward-line -1) + (not (helm-pos-header-line-p))))) + (and headp (forward-line -1)))))) + (unless (helm-end-of-source-p t) + (helm-mark-current-line)))) + +(defun helm-end-of-source-p (&optional at-point) + "Return non--nil if we are at eob or end of source." + (save-excursion + (if (and (helm-pos-multiline-p) (null at-point)) + (null (helm-get-next-candidate-separator-pos)) + (forward-line (if at-point 0 1)) + (or (eq (point-at-bol) (point-at-eol)) + (helm-pos-header-line-p) + (eobp))))) + +(defun helm-edit-current-selection-internal (func) + (with-helm-window + (forward-line 0) + (let ((realvalue (get-text-property (point) 'helm-realvalue)) + (multiline (get-text-property (point) 'helm-multiline))) + (funcall func) + (forward-line 0) + (and realvalue + (put-text-property (point) (point-at-eol) + 'helm-realvalue realvalue)) + (and multiline + (put-text-property (point) (point-at-eol) + 'helm-multiline multiline)) + (helm-mark-current-line)))) + +(defmacro helm-edit-current-selection (&rest forms) + "Evaluate FORMS at current selection in the helm buffer. +Used generally to modify current selection." + (declare (indent 0) (debug t)) + `(helm-edit-current-selection-internal + (lambda () ,@forms))) + +(defun helm-set-pattern (pattern &optional noupdate) + "Set minibuffer contents to PATTERN. +if optional NOUPDATE is non-nil, helm buffer is not changed." + (with-selected-window (or (active-minibuffer-window) (minibuffer-window)) + (delete-minibuffer-contents) + (insert pattern)) + (when noupdate + (setq helm-pattern pattern))) + +(defun helm-minibuffer-completion-contents () + "Return the user input in a minibuffer before point as a string. +That is what completion commands operate on." + (buffer-substring (field-beginning) (point))) + +(defun helm--delete-minibuffer-contents-from (from-str) + ;; Giving an empty string value to FROM-STR delete all. + (require 'helm-utils) + (let ((input (minibuffer-contents))) + (helm-reset-yank-point) + (if (> (length input) 0) + ;; minibuffer is not empty, delete contents from end + ;; of FROM-STR and update. + (helm-set-pattern from-str) + ;; minibuffer is already empty, force update. + (helm-force-update)))) + +(defun helm-delete-minibuffer-contents (&optional arg) + "Delete minibuffer contents. +When `helm-delete-minibuffer-contents-from-point' is non--nil, +delete minibuffer contents from point instead of deleting all. +Giving a prefix arg reverse this behavior. +When at 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))) + + +;;; Plugins +;; +;; Built-in plug-in: type +(defun helm-compile-source--type (source) + (helm-aif (assoc-default 'type source) + (append source (assoc-default it helm-type-attributes) nil) + source)) + +;; `define-helm-type-attribute' is public API. + +(defun helm-add-type-attribute (type definition) + (helm-aif (assq type helm-type-attributes) + (setq helm-type-attributes (delete it helm-type-attributes))) + (push (cons type definition) helm-type-attributes)) + +(defun helm-document-type-attribute (type doc) + (add-to-list 'helm-types type t) + (put type 'helm-typeattrdoc + (concat "- " (symbol-name type) "\n\n" doc "\n"))) + +;; Built-in plug-in: dummy +(defun helm-dummy-candidate (_candidate _source) + "Use `helm-pattern' as CANDIDATE in SOURCE." + ;; `source' is defined in filtered-candidate-transformer + (list helm-pattern)) + +(defun helm-compile-source--dummy (source) + (if (assoc 'dummy source) + (progn + (unless (helm-attr-defined + 'filtered-candidate-transformer source) + (helm-attrset 'filtered-candidate-transformer + 'helm-dummy-candidate source)) + (append source + '((candidates "dummy") + (accept-empty) + (match identity) + (volatile)))) + source)) + +;; Built-in plug-in: candidates-in-buffer +(defun helm-candidates-in-buffer (&optional source) + "Get candidates from the candidates buffer according to `helm-pattern'. + +BUFFER is `helm-candidate-buffer' by default. Each +candidate must be placed in one line. This function is meant to +be used in candidates-in-buffer or candidates attribute of an +helm source. Especially fast for many (1000+) candidates. + +eg. + '((name . \"many files\") + (init . (lambda () (with-current-buffer (helm-candidate-buffer 'local) + (insert-many-filenames)))) + (search re-search-forward) ; optional + (candidates-in-buffer) + (type . file)) + ++===============================================================+ +| The new way of making and narrowing candidates: Using buffers | ++===============================================================+ + +By default, `helm' makes candidates by evaluating the +candidates function, then narrows them by `string-match' for each +candidate. + +But this way is very slow for many candidates. The new way is +storing all candidates in a buffer and narrowing them by +`re-search-forward'. Search function is customizable by search +attribute. The important point is that buffer processing is MUCH +FASTER than string list processing and is the Emacs way. + +The init function writes all candidates to a newly-created +candidate buffer. The candidates buffer is created or specified +by `helm-candidate-buffer'. Candidates are stored in a line. + +The candidates function narrows all candidates, IOW creates a +subset of candidates dynamically. It is the task of +`helm-candidates-in-buffer'. As long as +`helm-candidate-buffer' is used,`(candidates-in-buffer)' is +sufficient in most cases. + +Note that `(candidates-in-buffer)' is shortcut of three attributes: + (candidates . helm-candidates-in-buffer) + (volatile) + (match identity) +And `(candidates-in-buffer . func)' is shortcut of three attributes: + (candidates . func) + (volatile) + (match identity) +The expansion is performed in `helm-get-sources'. + +The candidates-in-buffer attribute implies the volatile attribute. +The volatile attribute is needed because `helm-candidates-in-buffer' +creates candidates dynamically and need to be called everytime +`helm-pattern' changes. + +Because `helm-candidates-in-buffer' plays the role of `match' attribute +function, specifying `(match identity)' makes the source slightly faster. + +However if source contain match-part attribute, match is computed only +on part of candidate returned by the call of function provided by this attribute. +The function should have one arg, candidate, and return only +a specific part of candidate. + +To customize `helm-candidates-in-buffer' behavior, use `search', +`get-line' and `match-part' attributes." + (let ((src (or source (helm-get-current-source)))) + (helm-candidates-in-buffer-1 + (helm-candidate-buffer) + helm-pattern + (or (assoc-default 'get-line src) + #'buffer-substring-no-properties) + (or (assoc-default 'search src) + '(helm-candidates-in-buffer-search-default-fn)) + (helm-candidate-number-limit src) + (helm-attr 'match-part) + src))) + +(defun helm-candidates-in-buffer-search-default-fn (pattern) + "Search PATTERN with `re-search-forward' with bound and noerror args." + (condition-case _err + (re-search-forward pattern nil t) + (invalid-regexp nil))) + +(defun helm-candidates-in-buffer-1 (buffer pattern get-line-fn + search-fns limit + match-part-fn source) + "Return the list of candidates inserted in BUFFER matching PATTERN." + ;; buffer == nil when candidates buffer does not exist. + (when buffer + (with-current-buffer buffer + (let ((inhibit-point-motion-hooks t) + (start-point (1- (point-min)))) + (goto-char start-point) + (if (string= pattern "") + (helm-initial-candidates-from-candidate-buffer + get-line-fn limit) + (helm-search-from-candidate-buffer + pattern get-line-fn search-fns limit + start-point match-part-fn source)))))) + +(defun helm-search-from-candidate-buffer (pattern get-line-fn search-fns + limit start-point match-part-fn source) + (let (buffer-read-only + matches + newmatches + (case-fold-search (helm-set-case-fold-search))) + (helm--search-from-candidate-buffer-1 + (lambda () + (clrhash helm-cib-hash) + (cl-dolist (searcher search-fns) + (goto-char start-point) + (setq newmatches nil) + (cl-loop with pos-lst + with item-count = 0 + while (and (setq pos-lst (funcall searcher pattern)) + (not (eobp))) + for cand = (apply get-line-fn + (if (and pos-lst (listp pos-lst)) + pos-lst + (list (point-at-bol) (point-at-eol)))) + when (and (not (gethash cand helm-cib-hash)) + (or + ;; Always collect when cand is matched by searcher funcs + ;; and match-part attr is not present. + (and (not match-part-fn) + (not (consp pos-lst))) + ;; If match-part attr is present, or if SEARCHER fn + ;; 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 (or match-part-fn #'identity)))) + do (helm--accumulate-candidates + cand newmatches helm-cib-hash item-count limit source)) + (setq matches (append matches (nreverse newmatches)))) + (delq nil matches))))) + +(defun helm-search-match-part (candidate pattern match-part-fn) + "Match PATTERN only on part of CANDIDATE returned by MATCH-PART-FN. +Because `helm-search-match-part' maybe called even if unspecified +in source (negation), MATCH-PART-FN default to `identity' to match whole candidate. +When using fuzzy matching and negation (i.e \"!\"), this function is always called." + (let ((part (funcall match-part-fn candidate)) + (fuzzy-regexp (cadr (gethash 'helm-pattern helm--fuzzy-regexp-cache)))) + (if (string-match " " pattern) + (cl-loop for i in (split-string pattern) always + (if (string-match "\\`!" i) + (not (string-match (substring i 1) part)) + (string-match i part))) + (if (string-match "\\`!" pattern) + (not (string-match (if helm--in-fuzzy + ;; Fuzzy regexp have already been + ;; computed with substring 1. + fuzzy-regexp + (substring 1 pattern)) + part)) + (string-match (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)))) + +(defun helm--search-from-candidate-buffer-1 (search-fn) + ;; Previously we were adding a newline at bob and at eol + ;; and removing these newlines afterward, it seems it is no more + ;; needed, thus when searching for empty line ("^$") + ;; it was adding the first line as a matched line + ;; which is wrong. + (unwind-protect + (funcall search-fn) + (set-buffer-modified-p nil))) + +(defun helm-candidate-buffer (&optional create-or-buffer) + "Register and return a buffer containing candidates of current source. +`helm-candidate-buffer' searches buffer-local candidates buffer first, +then global candidates buffer. + +Acceptable values of CREATE-OR-BUFFER: + +- nil (omit) + Only return the candidates buffer. +- a buffer + Register a buffer as a candidates buffer. +- 'global + Create a new global candidates buffer, + named \" *helm candidates:SOURCE*\". +- other non-nil value + Create a new local candidates buffer, + named \" *helm candidates:SOURCE*HELM-CURRENT-BUFFER\"." + (let* ((global-bname (format " *helm candidates:%s*" + helm-source-name)) + (local-bname (format " *helm candidates:%s*%s" + helm-source-name + (buffer-name helm-current-buffer))) + (register-func #'(lambda () + (setq helm-candidate-buffer-alist + (cons (cons helm-source-name create-or-buffer) + (delete (assoc helm-source-name + helm-candidate-buffer-alist) + helm-candidate-buffer-alist))))) + (kill-buffers-func #'(lambda () + (cl-loop for b in (buffer-list) + if (string-match (format "^%s" (regexp-quote global-bname)) + (buffer-name b)) + do (kill-buffer b)))) + (create-func #'(lambda () + (with-current-buffer + (get-buffer-create (if (eq create-or-buffer 'global) + global-bname + local-bname)) + (buffer-disable-undo) + (erase-buffer) + (font-lock-mode -1)))) + (return-func #'(lambda () + (or (get-buffer local-bname) + (get-buffer global-bname) + (helm-aif (assoc-default helm-source-name + helm-candidate-buffer-alist) + (and (buffer-live-p it) it)))))) + (when create-or-buffer + (funcall register-func) + (unless (bufferp create-or-buffer) + (and (eq create-or-buffer 'global) (funcall kill-buffers-func)) + (funcall create-func))) + (funcall return-func))) + +(defun helm-init-candidates-in-buffer (buffer data) + "Register BUFFER with DATA for a helm candidates-in-buffer session. +Arg BUFFER can be a string, a buffer object (bufferp), or a symbol, +either 'local or 'global which is passed to `helm-candidate-buffer'. +Arg DATA can be either a list or a plain string. +Returns the resulting buffer." + (declare (indent 1)) + (let ((buf (helm-candidate-buffer + (if (or (stringp buffer) + (bufferp buffer)) + (get-buffer-create buffer) + buffer)))) ; a symbol. + (with-current-buffer buf + (erase-buffer) + (if (listp data) + (insert (mapconcat (lambda (i) + (cond ((symbolp i) (symbol-name i)) + ((numberp i) (number-to-string i)) + (t i))) + data "\n")) + (and (stringp data) (insert data)))) + buf)) + +(defun helm-compile-source--candidates-in-buffer (source) + (helm-aif (assoc 'candidates-in-buffer source) + (append source + `((candidates . ,(or (cdr it) + (lambda () + (helm-candidates-in-buffer source)))) + (volatile) (match identity))) + source)) + + +;;; Resplit helm window +;; +;; +(defun helm-toggle-resplit-window () + "Toggle resplit helm window, vertically or horizontally." + (interactive) + (when helm-prevent-escaping-from-minibuffer + (helm-prevent-switching-other-window :enabled nil)) + (unwind-protect + (with-helm-window + (if (or helm-full-frame (one-window-p t)) + (message "Error: Attempt to resplit a single window") + (let ((before-height (window-height))) + (delete-window) + (set-window-buffer + (select-window + (if (= (window-height) before-height) ; initial split was horizontal. + ;; Split window vertically with `helm-buffer' placed + ;; on the good side according to actual value of + ;; `helm-split-window-default-side'. + (prog1 + (cond ((or (eq helm-split-window-default-side 'above) + (eq helm-split-window-default-side 'left)) + (split-window + (selected-window) nil 'above)) + (t (split-window-vertically))) + (setq helm-split-window-state 'vertical)) + ;; Split window vertically, same comment as above. + (setq helm-split-window-state 'horizontal) + (cond ((or (eq helm-split-window-default-side 'left) + (eq helm-split-window-default-side 'above)) + (split-window (selected-window) nil 'left)) + (t (split-window-horizontally))))) + helm-buffer))) + (setq helm--window-side-state (helm--get-window-side-state))) + (when helm-prevent-escaping-from-minibuffer + (helm-prevent-switching-other-window :enabled t)))) + +;; Utility: Resize helm window. +(defun helm-enlarge-window-1 (n) + "Enlarge or narrow helm window. +If N is positive enlarge, if negative narrow." + (unless helm-full-frame + (let ((horizontal-p (eq helm-split-window-state 'horizontal))) + (with-helm-window + (enlarge-window n horizontal-p))))) + +(defun helm-narrow-window () + "Narrow helm window." + (interactive) + (helm-enlarge-window-1 -1)) + +(defun helm-enlarge-window () + "Enlarge helm window." + (interactive) + (helm-enlarge-window-1 1)) + +(defun helm-swap-windows () + "Swap window holding `helm-buffer' with other window." + (interactive) + (if (and helm-full-frame (one-window-p t)) + (error "Error: Can't swap windows in a single window") + (let* ((w1 (helm-window)) + (split-state (eq helm-split-window-state 'horizontal)) + (w1size (window-total-size w1 split-state)) + (b1 (window-buffer w1)) ; helm-buffer + (s1 (window-start w1)) + (cur-frame (window-frame w1)) + (w2 (with-selected-window (helm-window) + ;; Don't try to display helm-buffer + ;; in a dedicated window. + (get-window-with-predicate + (lambda (w) (not (window-dedicated-p w))) + 1 cur-frame))) + (w2size (window-total-size w2 split-state)) + (b2 (window-buffer w2)) ; probably helm-current-buffer + (s2 (window-start w2)) + resize) + (with-selected-frame (window-frame w1) + (helm-replace-buffer-in-window w1 b1 b2) + (helm-replace-buffer-in-window w2 b2 b1) + (setq resize + (cond ( ;; helm-window is smaller than other window. + (< w1size w2size) + (- (- (max w2size w1size) + (min w2size w1size)))) + ( ;; helm-window is larger than other window. + (> w1size w2size) + (- (max w2size w1size) + (min w2size w1size))) + ( ;; windows have probably same size. + t nil))) + ;; Maybe resize the window holding helm-buffer. + (and resize (window-resize w2 resize split-state)) + (set-window-start w1 s2 t) + (set-window-start w2 s1 t)) + (setq helm--window-side-state (helm--get-window-side-state))))) + +(defun helm--get-window-side-state () + "Return the position of `helm-window' from `helm-current-buffer'. +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) + (window-in-direction + side (get-buffer-window helm-current-buffer t) + t)) + side)))) + +(defun helm-replace-buffer-in-window (window buffer1 buffer2) + "Replace BUFFER1 by BUFFER2 in WINDOW registering BUFFER1." + (when (get-buffer-window buffer1) + (unrecord-window-buffer window buffer1) + (set-window-buffer window buffer2))) + +;; Utility: select another action by key +(defun helm-select-nth-action (n) + "Select the N nth action for the currently selected candidate." + (setq helm-saved-selection (helm-get-selection)) + (unless helm-saved-selection + (error "Nothing is selected")) + (setq helm-saved-action + (helm-get-nth-action + n + (if (get-buffer-window helm-action-buffer 'visible) + (assoc-default 'candidates (helm-get-current-source)) + (helm-get-actions-from-current-source)))) + (helm-maybe-exit-minibuffer)) + +(defun helm-get-nth-action (n action) + (cond ((and (zerop n) (functionp action)) + action) + ((listp action) + (or (cdr (elt action n)) + (error "No such action"))) + ((and (functionp action) (< 0 n)) + (error "Sole action")) + (t + (error "Error in `helm-select-nth-action'")))) + +;; Utility: Persistent Action +(defmacro with-helm-display-same-window (&rest body) + "Execute BODY in the window used for persistent action. +Make `pop-to-buffer' and `display-buffer' display in the same window." + (declare (indent 0) (debug t)) + `(let ((display-buffer-function 'helm-persistent-action-display-buffer)) + ,@body)) + +(defun helm-initialize-persistent-action () + (set (make-local-variable 'helm-persistent-action-display-window) nil)) + +(cl-defun helm-execute-persistent-action + (&optional (attr 'persistent-action) split-onewindow) + "Perform the associated action ATTR without quitting helm. +ATTR default is 'persistent-action', but it can be anything else. +In this case you have to add this new attribute to your source. + +When `helm-full-frame' or SPLIT-ONEWINDOW are non--nil, +and `helm-buffer' is displayed in only one window, +the helm window is splitted to display +`helm-select-persistent-action-window' in other window +and keep its visibility." + (interactive) + (helm-log "executing persistent-action") + (let* ((attr-val (assoc-default attr (helm-get-current-source))) + ;; If attr value is a cons, use its car as persistent function + ;; and its car to decide if helm window should be splitted. + (fn (if (and (consp attr-val) + ;; maybe a lambda. + (not (functionp attr-val))) + (car attr-val) attr-val)) + (no-split (and (consp attr-val) + (not (functionp attr-val)) + (cdr attr-val)))) + (with-helm-window + (save-selected-window + (if no-split + (helm-select-persistent-action-window) + (helm-select-persistent-action-window + (or split-onewindow helm-onewindow-p))) + (helm-log "current-buffer = %S" (current-buffer)) + (let ((helm-in-persistent-action t)) + (with-helm-display-same-window + (helm-execute-selection-action-1 + nil (or fn (helm-get-actions-from-current-source)) t) + (helm-log-run-hook 'helm-after-persistent-action-hook)) + ;; A typical case is when a persistent action delete + ;; the buffer already displayed in + ;; `helm-persistent-action-display-window' and `helm-full-frame' + ;; is enabled, we end up with the `helm-buffer' + ;; displayed in two windows. + (when (and helm-onewindow-p + (> (length (window-list)) 1) + (equal (buffer-name + (window-buffer + helm-persistent-action-display-window)) + (helm-buffer-get))) + (delete-other-windows))))))) + +(defun helm-persistent-action-display-window (&optional split-onewindow) + "Return the window that will be used for persistent action. +If SPLIT-ONEWINDOW is non--nil window will be splitted in persistent action." + (with-helm-window + (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) + (split-onewindow (split-window)) + ((get-buffer-window helm-current-buffer)) + (t (next-window (selected-window) 1)))))) + +(defun helm-select-persistent-action-window (&optional split-onewindow) + "Select the window that will be used for persistent action. +See `helm-persistent-action-display-window' for how to use SPLIT-ONEWINDOW." + (select-window (get-buffer-window (helm-buffer-get))) + (select-window + (setq minibuffer-scroll-window + (helm-persistent-action-display-window split-onewindow)))) + +(defun helm-persistent-action-display-buffer (buf &optional action) + "Make `pop-to-buffer' and `display-buffer' display in the same window. +If `helm-persistent-action-use-special-display' is non-nil and +BUF is to be displayed by `special-display-function', use it. +Otherwise ignores `special-display-buffer-names' and `special-display-regexps'. +Argument ACTION if present will be used as second argument of `display-buffer'." + (let* ((name (buffer-name buf)) + display-buffer-function pop-up-windows pop-up-frames + ;; Disable `special-display-regexps' and `special-display-buffer-names' + ;; unless `helm-persistent-action-use-special-display' is non--nil. + (special-display-buffer-names + (and helm-persistent-action-use-special-display + special-display-buffer-names)) + (special-display-regexps + (and helm-persistent-action-use-special-display + special-display-regexps)) + (same-window-regexps + (unless (and helm-persistent-action-use-special-display + (or (member name + (mapcar (lambda (x) (or (car-safe x) x)) + special-display-buffer-names)) + (cl-loop for x in special-display-regexps + thereis (string-match (or (car-safe x) x) + name)))) + '(".")))) + ;; Don't loose minibuffer when displaying persistent window in + ;; another frame. + ;; This happen when the displayed persistent buffer-name is one of + ;; `special-display-buffer-names' or match `special-display-regexps' + ;; and `helm-persistent-action-use-special-display' is enabled. + (with-selected-window (if (or special-display-regexps + special-display-buffer-names) + (minibuffer-window) + (selected-window)) + ;; Be sure window of BUF is not dedicated. + (set-window-dedicated-p (get-buffer-window buf) nil) + (display-buffer buf action)))) + +;; scroll-other-window(-down)? for persistent-action +(defun helm-other-window-base (command &optional scroll-amount) + (setq scroll-amount (unless (eq scroll-amount 'noscroll) + helm-scroll-amount)) + (with-selected-window (helm-persistent-action-display-window) + (funcall command scroll-amount))) + +(defun helm-scroll-other-window () + "Scroll other window (not *Helm* window) upward." + (interactive) + (helm-other-window-base 'scroll-up)) + +(defun helm-scroll-other-window-down () + "Scroll other window (not *Helm* window) downward." + (interactive) + (helm-other-window-base 'scroll-down)) + +(defun helm-recenter-top-bottom-other-window () + "`recenter-top-bottom' in other window (not *Helm* window)." + (interactive) + (helm-other-window-base 'recenter-top-bottom 'noscroll)) + +(defun helm-reposition-window-other-window () + "`helm-reposition-window' in other window (not *Helm* window)." + (interactive) + (helm-other-window-base 'reposition-window 'noscroll)) + + + +;; Utility: Visible Mark + +(defun helm-clear-visible-mark () + (with-current-buffer (helm-buffer-get) + (mapc 'delete-overlay helm-visible-mark-overlays) + (set (make-local-variable 'helm-visible-mark-overlays) nil))) + +(defun helm-this-visible-mark () + (cl-loop for o in helm-visible-mark-overlays + when (equal (point-at-bol) (overlay-start o)) + return o)) + +(defun helm-delete-visible-mark (overlay) + (setq helm-marked-candidates + (remove + (cons (helm-get-current-source) (helm-get-selection)) + helm-marked-candidates)) + (delete-overlay overlay) + (setq helm-visible-mark-overlays + (delq overlay helm-visible-mark-overlays))) + +(defun helm-make-visible-mark () + (let ((o (make-overlay (point-at-bol) + (if (helm-pos-multiline-p) + (or (helm-get-next-candidate-separator-pos) + (point-max)) + (1+ (point-at-eol)))))) + (overlay-put o 'priority 0) + (overlay-put o 'face 'helm-visible-mark) + (overlay-put o 'source (assoc-default 'name (helm-get-current-source))) + (overlay-put o 'string (buffer-substring (overlay-start o) (overlay-end o))) + (overlay-put o 'real (helm-get-selection)) + (add-to-list 'helm-visible-mark-overlays o)) + (push (cons (helm-get-current-source) (helm-get-selection)) + helm-marked-candidates)) + +(defun helm-toggle-visible-mark () + "Toggle helm visible mark at point." + (interactive) + (with-helm-window + (let ((nomark (assq 'nomark (helm-get-current-source)))) + (if nomark + (message "Marking not allowed in this source") + (helm-aif (helm-this-visible-mark) + (helm-delete-visible-mark it) + (helm-make-visible-mark)) + (unless (helm-end-of-source-p) + (helm-next-line)))))) + +(defun helm-mark-all () + "Mark all visible unmarked candidates in current source." + (interactive) + (require 'helm-files) + (with-helm-window + (let ((nomark (assq 'nomark (helm-get-current-source))) + (follow (if helm-follow-mode 1 -1))) + (helm-follow-mode -1) + (unwind-protect + (if nomark + (message "Marking not allowed in this source") + (save-excursion + (goto-char (helm-get-previous-header-pos)) + (helm-next-line) + (let* ((next-head (helm-get-next-header-pos)) + (end (and next-head + (save-excursion + (goto-char next-head) + (forward-line -1) + (point)))) + (maxpoint (or end (point-max)))) + (while (< (point) maxpoint) + (helm-mark-current-line) + (let* ((prefix (get-text-property (point-at-bol) 'display)) + (cand (helm-get-selection)) + (bn (and (helm-file-completion-source-p) + (helm-basename cand))) + (src-name (assoc-default 'name + (helm-get-current-source)))) + (when (and (not (helm-this-visible-mark)) + (not (or (string= prefix "[?]") + (string= prefix "[@]")))) + ;; Don't mark possibles directories ending with . or .. + ;; autosave files/links and non--existent file. + (unless + (and (or (helm-file-completion-source-p) + (string= + src-name "Files from Current Directory")) + (or (string-match + "^[.]?#.*#?$\\|[^#]*[.]\\{1,2\\}$" bn) + ;; We need to test here when not using + ;; a transformer that tag prefix + ;; (i.e on tramp). + (not (file-exists-p cand)))) + (helm-make-visible-mark)))) + (if (helm-pos-multiline-p) + (progn + (goto-char + (or (helm-get-next-candidate-separator-pos) + (point-max))) + (forward-line 1)) + (forward-line 1)) + (end-of-line)))) + (helm-mark-current-line) + (message "%s candidates marked" (length helm-marked-candidates))) + (helm-follow-mode follow) (message nil))))) + +(defun helm-unmark-all () + "Unmark all candidates in all sources of current helm session." + (interactive) + (with-helm-window + (let ((len (length helm-marked-candidates))) + (save-excursion + (helm-clear-visible-mark)) + (setq helm-marked-candidates nil) + (helm-mark-current-line) + (message "%s candidates unmarked" len)))) + +(defun helm-toggle-all-marks () + "Toggle all marks. +Mark all visible candidates of current source or unmark all candidates +visible or invisible in all sources of current helm session" + (interactive) + (let ((marked (helm-marked-candidates))) + (if (and (>= (length marked) 1) + (with-helm-window helm-visible-mark-overlays)) + (helm-unmark-all) + (helm-mark-all)))) + +(cl-defun helm-marked-candidates (&key with-wildcard) + "Return marked candidates of current source if any. +Otherwise one element list of current selection. +When key WITH-WILDCARD is specified try to expand a wilcard if some." + (with-current-buffer helm-buffer + (cl-loop with current-src = (helm-get-current-source) + for (source . real) in + (or (reverse helm-marked-candidates) + (list (cons current-src (helm-get-selection)))) + when (equal (assoc 'name current-src) + (assoc 'name source)) + ;; When real is a normal filename without wildcard + ;; file-expand-wildcards returns a list of one file. + ;; When real is a non--existent file it return nil. + append (let* ((elm (helm-coerce-selection real source)) + (c (and with-wildcard + (condition-case nil + (helm-file-expand-wildcards elm t) + (error nil))))) + (or c (list elm))) + into cands + finally do (prog1 (cl-return cands) + (helm-log "Marked candidates = %S" cands))))) + +(defun helm-file-expand-wildcards (pattern &optional full) + "Same as `file-expand-wildcards' but allow recursion. +Recursion happen when PATTERN starts with two stars. +Directories expansion is not supported." + (require 'helm-utils) + (let ((bn (helm-basename pattern))) + (if (and helm-file-globstar + (string-match "\\`\\*\\{2\\}\\(.*\\)" bn)) + (helm-walk-directory (helm-basedir pattern) + :path (cl-case full + (full 'full) + (relative 'relative) + ((basename nil) 'basename) + (t 'full)) + :directories nil + :match (wildcard-to-regexp bn) + :skip-subdirs t) + (file-expand-wildcards pattern full)))) + +(defun helm-current-source-name= (name) + (save-excursion + (goto-char (helm-get-previous-header-pos)) + (equal name (helm-current-line-contents)))) + +(defun helm-revive-visible-mark () + "Restore marked candidates when helm update display." + (with-current-buffer helm-buffer + (cl-dolist (o helm-visible-mark-overlays) + (goto-char (point-min)) + (while (and (search-forward (overlay-get o 'string) nil t) + (helm-current-source-name= (overlay-get o 'source))) + ;; 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))) + (if real + ;; Check if real value of current candidate is the same + ;; 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) + (move-overlay o (point-at-bol 0) (1+ (point-at-eol 0)))) + (move-overlay o (point-at-bol 0) (1+ (point-at-eol 0))))))))) +(add-hook 'helm-update-hook 'helm-revive-visible-mark) + +(defun helm-next-point-in-list (curpos points &optional prev) + (cond + ;; rule out special cases. + ((null points) curpos) + ((and prev (<= curpos (car points))) + (nth (1- (length points)) points)) + ((< (car (last points)) curpos) + (if prev (car (last points)) (nth 0 points))) + ((and (not prev) (>= curpos (car (last points)))) + (nth 0 points)) + (t + (nth (if prev + (cl-loop for pt in points + for i from 0 + if (<= curpos pt) return (1- i)) + (cl-loop for pt in points + for i from 0 + if (< curpos pt) return i)) + points)))) + +(defun helm-next-visible-mark (&optional prev) + "Move next helm visible mark. +If PREV is non-nil move to precedent." + (interactive) + (with-helm-window + (ignore-errors + (goto-char (helm-next-point-in-list + (point) + (sort (mapcar 'overlay-start helm-visible-mark-overlays) '<) + prev))) + (helm-mark-current-line))) + +(defun helm-prev-visible-mark () + "Move previous helm visible mark." + (interactive) + (helm-next-visible-mark t)) + +;;; Utility: Selection Paste +;; +(defun helm-yank-selection (arg) + "Set minibuffer contents to current display selection. +With a prefix arg set to real value of current selection." + (interactive "P") + (let ((str (helm-get-selection nil (not arg)))) + (kill-new str) + (helm-set-pattern str))) + +(defun helm-kill-selection-and-quit (arg) + "Store display value of current selection to kill ring. +With a prefix arg set to real value of current selection. +Display value is what you see in `helm-buffer' and real value +is what is used to perform actions." + (interactive "P") + (helm-run-after-quit + (lambda (sel) + (kill-new sel) + (message "Killed: %s" sel)) + (helm-get-selection nil (not arg)))) + +(defun helm-copy-to-buffer () + "Copy selection or marked candidates to `helm-current-buffer'." + (interactive) + (with-helm-buffer + (cl-loop for cand in (helm-marked-candidates) + do (with-helm-current-buffer + (insert cand "\n"))))) + + +;;; Follow-mode: Automatical execution of persistent-action +;; +;; +(defun helm-follow-mode (&optional arg) + "Execute persistent action everytime the cursor is moved when enabled. +The mode is enabled for the current source only, you will have to turn it +on again when you go to next source if you want it there also. +This mode can be enabled or disabled interactively at anytime during +helm session or enabled specifically by source by adding the `follow' +attribute to this source. +Even when the attribute `follow' exists in source, it is still possible +to disable/enable this mode interactively. +Note that when you disable it interactively and `follow' attribute exists, +`helm-follow-mode' will be disabled on next helm session even if `follow' +attribute is specified in source. To avoid this set your `follow' attribute +in source in `helm-before-initialize-hook'. + +e.g: + +\(add-hook 'helm-before-initialize-hook + #'(lambda () (helm-attrset 'follow 1 helm-source-buffers-list))) + +This will enable `helm-follow-mode' automatically in `helm-source-buffers-list'." + (interactive "p") + (with-current-buffer helm-buffer + (let* ((src (helm-get-current-source)) + (name (assoc-default 'name src)) + (sym (cl-loop for s in helm-sources + for sname = (and (symbolp s) + (assoc-default + 'name (symbol-value s))) + thereis (and sname (string= sname name) s))) + (fol-attr (assq 'follow src)) + (enabled (or + ;; If `helm-follow-mode' is called with a negative + ;; ARG, assume follow is already enabled. + ;; i.e turn it off now. + (< arg 0) + (eq (cdr fol-attr) 1) + helm-follow-mode))) + (if src + (progn + (if (eq (cdr fol-attr) 'never) + (message "helm-follow-mode not allowed in this source") + ;; Make follow attr persistent for this emacs session. + (helm-attrset 'follow (if enabled -1 1) src) + (setq helm-follow-mode (not enabled)) + (message "helm-follow-mode is %s" + (if helm-follow-mode + "enabled" "disabled")) + (helm-display-mode-line src)) + (unless helm-follow-mode-persistent + (and sym (set sym (remove (assq 'follow src) src))))) + (message "Not enough candidates for helm-follow-mode"))))) + +(defvar helm-follow-input-idle-delay nil + "`helm-follow-mode' will execute its persistent action after this delay. +Note that if the `follow-delay' attr is present in source, +it will take precedence on this.") +(defun helm-follow-execute-persistent-action-maybe () + "Execute persistent action in mode `helm-follow-mode'. +This happen after `helm-input-idle-delay' secs." + (let ((src (helm-get-current-source))) + (and (not (get-buffer-window helm-action-buffer 'visible)) + (eq (assoc-default 'follow src) 1) + (sit-for (or (assoc-default 'follow-delay src) + helm-follow-input-idle-delay + (and helm-input-idle-delay + (max helm-input-idle-delay 0.01)))) + (helm-window) + (helm-get-selection) + (save-excursion + (helm-execute-persistent-action))))) + + +;;; Auto-resize mode +;; +(defun helm--autoresize-hook (&optional max-height min-height) + (with-helm-window + (fit-window-to-buffer nil + (/ (* (frame-height) + (or max-height helm-autoresize-max-height)) + 100) + (/ (* (frame-height) + (or min-height helm-autoresize-min-height)) + 100)))) + +(define-minor-mode helm-autoresize-mode + "Auto resize helm window when enabled. +Helm window is resized according to values of `helm-autoresize-max-height' +and `helm-autoresize-min-height'. +Note that when this mode is enabled, helm behave like when +`helm-always-two-windows' is enabled. + +See `fit-window-to-buffer' for more infos." + :group 'helm + :global t + (if helm-autoresize-mode + (progn (add-hook 'helm-after-update-hook 'helm--autoresize-hook) + (add-hook 'helm-window-configuration-hook 'helm--autoresize-hook)) + (remove-hook 'helm-after-update-hook 'helm--autoresize-hook) + (remove-hook 'helm-window-configuration-hook 'helm--autoresize-hook))) + + +(provide 'helm) + +;; Local Variables: +;; byte-compile-warnings: (not cl-functions obsolete) +;; coding: utf-8 +;; indent-tabs-mode: nil +;; End: + +;;; helm.el ends here -- 2.47.3