From 8b379bbeca9b3765e2b1e948d9d9c90ab92ff4b6 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Thu, 20 Jun 2019 00:55:07 +0300 Subject: [PATCH] Add file sorting options to find-dired and grep-find (bug#36110) * lisp/find-dired.el (find-ls-option-default-ls) (find-ls-option-default-exec, find-ls-option-default-xargs): New variables for values used for options of 'find-ls-option'. (find-ls-option): Use these variables for default values and options. (find-dired-refine-function): Refine :type. * lisp/progmodes/grep.el (grep-find-use-xargs): Use defcustom instead of defvar. Add new value 'gnu-sort'. (grep-compute-defaults): Handle new 'gnu-sort' option of 'grep-find-use-xargs'. --- etc/NEWS | 4 ++++ lisp/find-dired.el | 48 ++++++++++++++++++++++++++++++------------ lisp/progmodes/grep.el | 20 ++++++++++++++++-- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index bf92a551a5c..f880e393c02 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -592,6 +592,8 @@ remapped to these, respectively. *** New customizable variable 'find-dired-refine-function'. The default value is 'find-dired-sort-by-filename'. +*** New sorting options for the variable 'find-ls-option'. + ** Change Logs and VC *** Recording ChangeLog entries doesn't require an actual file. @@ -1112,6 +1114,8 @@ The abbreviation can be disabled by the new option 'grep-find-abbreviate'. The new command 'grep-find-toggle-abbreviation' toggles it interactively. +*** 'grep-find-use-xargs' is now customizable with sorting options. + ** ERT +++ diff --git a/lisp/find-dired.el b/lisp/find-dired.el index 8a283a65c98..9e9fbfcb1a7 100644 --- a/lisp/find-dired.el +++ b/lisp/find-dired.el @@ -51,19 +51,23 @@ than the latter." :group 'find-dired :type 'string) +(defvar find-ls-option-default-ls + (cons "-ls" (if (eq system-type 'berkeley-unix) "-gilsb" "-dilsb"))) + +(defvar find-ls-option-default-exec + (cons (format "-exec ls -ld {} %s" find-exec-terminator) "-ld")) + +(defvar find-ls-option-default-xargs + (cons "-print0 | sort -z | xargs -0 -e ls -ld" "-ld")) + ;; find's -ls corresponds to these switches. ;; Note -b, at least GNU find quotes spaces etc. in filenames (defcustom find-ls-option (if (eq 0 (ignore-errors (process-file find-program nil nil nil null-device "-ls"))) - (cons "-ls" - (if (eq system-type 'berkeley-unix) - "-gilsb" - "-dilsb")) - (cons - (format "-exec ls -ld {} %s" find-exec-terminator) - "-ld")) + find-ls-option-default-ls + find-ls-option-default-exec) "A pair of options to produce and parse an `ls -l'-type list from `find'. This is a cons of two strings (FIND-OPTION . LS-SWITCHES). FIND-OPTION is the option (or options) passed to `find' to produce @@ -77,10 +81,26 @@ For example, to use human-readable file sizes with GNU ls: To use GNU find's inbuilt \"-ls\" option to list files: (\"-ls\" . \"-dilsb\") since GNU find's output has the same format as using GNU ls with -the options \"-dilsb\"." - :version "24.1" ; add tests for -ls and -exec + support - :type '(cons (string :tag "Find Option") - (string :tag "Ls Switches")) +the options \"-dilsb\". + +While the option `find -ls' often produces unsorted output, the option +`find -exec ls -ld' maintains the sorting order only on short output, +whereas `find -print | sort | xargs' produced sorted output even +on the large number of files." + :version "27.1" ; add choice of predefined set of options + :type `(choice + (cons :tag "find -ls" + (string ,(car find-ls-option-default-ls)) + (string ,(cdr find-ls-option-default-ls))) + (cons :tag "find -exec ls -ld" + (string ,(car find-ls-option-default-exec)) + (string ,(cdr find-ls-option-default-exec))) + (cons :tag "find -print | sort | xargs" + (string ,(car find-ls-option-default-xargs)) + (string ,(cdr find-ls-option-default-xargs))) + (cons :tag "Other values" + (string :tag "Find Option") + (string :tag "Ls Switches"))) :group 'find-dired) (defcustom find-ls-subdir-switches @@ -123,8 +143,10 @@ This function takes no arguments. The *Find* buffer is narrowed to the output of `find' (one file per line) when this function is called." :version "27.1" :group 'find-dired - :type '(choice (function :tag "Function") - (const :tag "None" nil))) + :type '(choice (const :tag "Sort file names lexicographically" + find-dired-sort-by-filename) + (function :tag "Refining function") + (const :tag "No refining" nil))) (defvar find-args nil "Last arguments given to `find' by \\[find-dired].") diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 79178c4346e..67222f78627 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -511,14 +511,24 @@ See `grep-find-use-xargs'. This variable's value takes effect when `grep-compute-defaults' is called.") ;;;###autoload -(defvar grep-find-use-xargs nil +(defcustom grep-find-use-xargs nil "How to invoke find and grep. If `exec', use `find -exec {} ;'. If `exec-plus' use `find -exec {} +'. If `gnu', use `find -print0' and `xargs -0'. +If `gnu-sort', use `find -print0', `sort -z' and `xargs -0'. Any other value means to use `find -print' and `xargs'. -This variable's value takes effect when `grep-compute-defaults' is called.") +This variable's value takes effect when `grep-compute-defaults' is called." + :type '(choice (const :tag "find -exec {} ;" exec) + (const :tag "find -exec {} +" exec-plus) + (const :tag "find -print0 | xargs -0" gnu) + (const :tag "find -print0 | sort -z | xargs -0'" gnu-sort) + string + (const :tag "Not Set" nil)) + :set 'grep-apply-setting + :version "27.1" + :group 'grep) ;; History of grep commands. ;;;###autoload @@ -728,6 +738,9 @@ This function is called from `compilation-filter-hook'." ;; forward slashes as directory separators. (format "%s . -type f -print0 | \"%s\" -0 %s" find-program xargs-program grep-command)) + ((eq grep-find-use-xargs 'gnu-sort) + (format "%s . -type f -print0 | sort -z | \"%s\" -0 %s" + find-program xargs-program grep-command)) ((memq grep-find-use-xargs '(exec exec-plus)) (let ((cmd0 (format "%s . -type f -exec %s" find-program grep-command)) @@ -752,6 +765,9 @@ This function is called from `compilation-filter-hook'." (cond ((eq grep-find-use-xargs 'gnu) (format "%s -type f -print0 | \"%s\" -0 %s" find-program xargs-program gcmd)) + ((eq grep-find-use-xargs 'gnu-sort) + (format "%s -type f -print0 | sort -z | \"%s\" -0 %s" + find-program xargs-program gcmd)) ((eq grep-find-use-xargs 'exec) (format "%s -type f -exec %s %s %s%s" find-program gcmd quot-braces null quot-scolon)) -- 2.39.2