From 653bc3943482783b646a00aa90f5e0e3c2d4c58a Mon Sep 17 00:00:00 2001 From: Drew Adams Date: Tue, 6 Sep 2022 12:53:50 +0200 Subject: [PATCH] Add some new find-lisp commands * lisp/find-lisp.el (find-lisp-find-dired-other-window): New command. (find-lisp-find-dired): Improve the doc string. (find-lisp-find-dired-subdirectories): Clarify doc string. (find-lisp-find-dired-subdirs-other-window): New command. (find-lisp-find-dired-internal): Adjust to allow being called by the new command. (find-lisp-format): Make symlink output more regular. --- lisp/find-lisp.el | 77 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/lisp/find-lisp.el b/lisp/find-lisp.el index e825d9cba04..62b4ef625db 100644 --- a/lisp/find-lisp.el +++ b/lisp/find-lisp.el @@ -166,7 +166,8 @@ It is a function which takes two arguments, the directory and its parent." ;;;###autoload (defun find-lisp-find-dired (dir regexp) - "Find files in DIR, matching REGEXP." + "Find the files within DIR whose names match REGEXP. +A Dired buffer with the results will be opened." (interactive "DFind files in directory: \nsMatching regexp: ") (let ((find-lisp-regexp regexp)) (find-lisp-find-dired-internal @@ -175,34 +176,54 @@ It is a function which takes two arguments, the directory and its parent." 'find-lisp-default-directory-predicate "*Find Lisp Dired*"))) +(defun find-lisp-find-dired-other-window (dir regexp) + "Same as `find-lisp-find-dired', but use another window." + (interactive "DFind files in directory: \nsMatching regexp: ") + (let ((find-lisp-regexp regexp)) + (find-lisp-find-dired-internal + dir + 'find-lisp-default-file-predicate + 'find-lisp-default-directory-predicate + "*Find Lisp Dired*" + 'OTHER-WINDOW))) + ;; Just the subdirectories ;;;###autoload (defun find-lisp-find-dired-subdirectories (dir) "Find all subdirectories of DIR." - (interactive "DFind subdirectories of directory: ") + (interactive "DFind dired subdirectories of directory: ") (find-lisp-find-dired-internal dir 'find-lisp-file-predicate-is-directory 'find-lisp-default-directory-predicate "*Find Lisp Dired Subdirectories*")) +;;;###autoload +(defun find-lisp-find-dired-subdirs-other-window (dir) + "Same as `find-lisp-find-dired-subdirectories', but use another window." + (interactive "DDired descendent dirs of directory: ") + (find-lisp-find-dired-internal dir + 'find-lisp-file-predicate-is-directory + 'find-lisp-default-directory-predicate + "*Find Lisp Dired Subdirectories*" + 'OTHER-WINDOW)) + ;; Most of this is lifted from find-dired.el ;; (defun find-lisp-find-dired-internal (dir file-predicate - directory-predicate buffer-name) + directory-predicate buffer-name + &optional other-window) "Run find (Lisp version) and go into Dired mode on a buffer of the output." - (let ((dired-buffers dired-buffers) - (regexp find-lisp-regexp)) - ;; Expand DIR ("" means default-directory), and make sure it has a - ;; trailing slash. + (let ((dired-buffers dired-buffers) + (regexp find-lisp-regexp)) + ;; Expand DIR ("" means `default-directory'), ensuring a trailing slash. (setq dir (file-name-as-directory (expand-file-name dir))) ;; Check that it's really a directory. (or (file-directory-p dir) (error "find-dired needs a directory: %s" dir)) - (or - (and (buffer-name) - (string= buffer-name (buffer-name))) - (switch-to-buffer (get-buffer-create buffer-name))) + (unless (and (buffer-name) (string= buffer-name (buffer-name))) + (let ((buf (get-buffer-create buffer-name))) + (if other-window (pop-to-buffer buf) (switch-to-buffer buf)))) (widen) (kill-all-local-variables) (setq buffer-read-only nil) @@ -278,10 +299,19 @@ It is a function which takes two arguments, the directory and its parent." (revert-buffer)) (defun find-lisp-find-dired-insert-file (file buffer) + "Insert line for FILE in BUFFER. +FILE is a file or a directory name. + +This function heeds `dired-actual-switches'." (set-buffer buffer) (insert find-lisp-line-indent - (find-lisp-format file (file-attributes file 'string) (list "") - nil))) + (find-lisp-format + (propertize file 'dired-filename t) + (file-attributes file 'string) + (or (and dired-actual-switches + (split-string-and-unquote dired-actual-switches)) + (list "")) + nil))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Lifted from ls-lisp. We don't want to require it, because that @@ -289,15 +319,14 @@ It is a function which takes two arguments, the directory and its parent." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun find-lisp-format (file-name file-attr switches now) - "Format one line of long ls output for file FILE-NAME. + "Format one line of long `ls' output for file or directory FILE-NAME. FILE-ATTR and FILE-SIZE give the file's attributes and size. SWITCHES and TIME-INDEX give the full switch list and time data." (let ((file-type (file-attribute-type file-attr))) - (concat (if (memq ?i switches) ; inode number - (format "%6d " (file-attribute-inode-number file-attr))) - ;; nil is treated like "" in concat - (if (memq ?s switches) ; size in K - (format "%4d " (1+ (/ (file-attribute-size file-attr) 1024)))) + (concat (and (memq ?i switches) ; inode number + (format "%6d " (file-attribute-inode-number file-attr))) + (and (memq ?s switches) ; size in K + (format "%4d " (1+ (/ (file-attribute-size file-attr) 1024)))) (file-attribute-modes file-attr) (format " %3d %-8s %-8s %8d " (file-attribute-link-number file-attr) @@ -309,14 +338,14 @@ SWITCHES and TIME-INDEX give the full switch list and time data." (if (numberp (file-attribute-group-id file-attr)) (int-to-string (file-attribute-group-id file-attr)) (file-attribute-group-id file-attr))) - (file-attribute-size file-attr) - ) + (file-attribute-size file-attr)) (find-lisp-format-time file-attr switches now) " " file-name - (if (stringp file-type) ; is a symbolic link - (concat " -> " file-type) - "") + (and (eq t file-type) (memq ?F switches) + "/") ; Add `/' for dir if `F' switch + (and (stringp file-type) + (concat " -> " file-type)) ; Add " -> " for symbolic link "\n"))) (defun find-lisp-time-index (switches) -- 2.39.2