summaryrefslogtreecommitdiff
path: root/helm-find.el
diff options
context:
space:
mode:
authorThierry Volpiatto <thierry.volpiatto@gmail.com>2017-09-06 09:56:35 +0200
committerThierry Volpiatto <thierry.volpiatto@gmail.com>2017-09-06 09:57:42 +0200
commit67c9113731f11671d2633062aa2648c53a82c6fe (patch)
treecaf76d9fd30f145e645bc427243f60e67b85b791 /helm-find.el
parente74db422e8dc2308382aefac8afd0ad6eacedf48 (diff)
Move find cmd related code to its own file
* helm-find.el: New file.
Diffstat (limited to 'helm-find.el')
-rw-r--r--helm-find.el163
1 files changed, 163 insertions, 0 deletions
diff --git a/helm-find.el b/helm-find.el
new file mode 100644
index 00000000..3b85a7ac
--- /dev/null
+++ b/helm-find.el
@@ -0,0 +1,163 @@
+;;; helm-find.el --- helm interface for find command. -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012 ~ 2017 Thierry Volpiatto <thierry.volpiatto@gmail.com>
+
+;; 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 <http://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'helm-files)
+
+;;; 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
+ :persistent-action 'helm-ff-kill-or-find-buffer-fname
+ :action 'helm-type-file-actions
+ :keymap helm-generic-files-map
+ :candidate-number-limit 9999
+ :requires-pattern 3))
+
+(defun helm-findutils-transformer (candidates _source)
+ (let (non-essential
+ (default-directory (helm-default-directory)))
+ (cl-loop for i in candidates
+ for abs = (expand-file-name
+ (helm-aif (file-remote-p default-directory)
+ (concat it i) i))
+ for type = (car (file-attributes abs))
+ for disp = (if (and helm-ff-transformer-show-only-basename
+ (not (string-match "[.]\\{1,2\\}$" i)))
+ (helm-basename abs) 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--build-cmd-line ()
+ (require 'find-cmd)
+ (let* ((default-directory (or (file-remote-p default-directory 'localname)
+ default-directory))
+ (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))))
+ (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))))
+
+(defun helm-find-shell-command-fn ()
+ "Asynchronously fetch candidates for `helm-find'.
+Additional find options can be specified after a \"*\"
+separator."
+ (let* (process-connection-type
+ non-essential
+ (cmd (helm-find--build-cmd-line))
+ (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)
+ (let ((default-directory (file-name-as-directory dir)))
+ (helm :sources 'helm-source-findutils
+ :buffer "*helm find*"
+ :ff-transformer-show-only-basename nil
+ :case-fold-search helm-file-name-case-fold-search)))
+
+
+;;; Preconfigured commands
+;;
+;;
+;;;###autoload
+(defun helm-find (arg)
+ "Preconfigured `helm' for the find shell command.
+
+Recursively find files whose names are matched by all specified
+globbing PATTERNs under the current directory using the external
+program specified in `find-program' (usually \"find\"). Every
+input PATTERN is silently wrapped into two stars: *PATTERN*.
+
+With prefix argument, prompt for a directory to search.
+
+When user option `helm-findutils-search-full-path' is non-nil,
+match against complete paths, otherwise, against file names
+without directory part.
+
+The (possibly empty) list of globbing PATTERNs can be followed by
+the separator \"*\" plus any number of additional arguments that
+are passed to \"find\" literally."
+ (interactive "P")
+ (let ((directory
+ (if arg
+ (file-name-as-directory
+ (read-directory-name "DefaultDirectory: "))
+ default-directory)))
+ (helm-find-1 directory)))
+
+(provide 'helm-find)
+
+;; Local Variables:
+;; byte-compile-warnings: (not obsolete)
+;; coding: utf-8
+;; indent-tabs-mode: nil
+;; End:
+
+;;; helm-find.el ends here