ambrevar/shell: Add match-directory and walk.

master
Pierre Neidhardt 2020-11-18 11:38:09 +01:00
parent 3a59bf0486
commit d84761789b
1 changed files with 31 additions and 4 deletions

View File

@ -37,9 +37,28 @@ Useful for `finder'."
(string= ext (pathname-type file)))
(cons extension more-extensions))))
(export-always 'finder)
(defun finder (root &rest predicates)
"List files in directory that satisfy all PREDICATES.
(export-always 'match-directory)
(defun match-directory (&key (empty? t) (non-empty? t) (files? t))
"Return a predicate that matches on directories.
If target is a file, return FILES?.
Useful for `walk'."
(lambda (directory)
(if (uiop:directory-exists-p directory)
(let ((recursive-files? (or (uiop:directory-files directory)
(uiop:subdirectories directory))))
(or (and empty?
(not files-or-dirs?))
(and non-empty?
files-or-dirs?)))
files?)))
(export-always '*finder-include-directories*)
(defvar *finder-include-directories* t
"When non-nil `walk' include directories.")
(export-always 'walk)
(defun walk (root &rest predicates)
"List files and directories that satisfy all PREDICATES.
Without PREDICATES, list all files."
(let ((result '()))
(uiop:collect-sub*directories
@ -47,7 +66,8 @@ Without PREDICATES, list all files."
(constantly t) (constantly t)
(lambda (subdirectory)
(setf result (nconc result
(let ((subfiles (uiop:directory-files subdirectory)))
(let ((subfiles (append (if *finder-include-directories* (list subdirectory) nil)
(uiop:directory-files subdirectory))))
(if predicates
(delete-if (lambda (file)
(notany (lambda (pred) (funcall pred file))
@ -56,6 +76,13 @@ Without PREDICATES, list all files."
subfiles))))))
result))
(export-always 'finder)
(defun finder (root &rest predicates)
"List files in ROOT that satisfy all PREDICATES.
Without PREDICATES, list all files."
(let ((*finder-include-directories* nil))
(apply #'walk root predicates)))
(export-always 'make-directory)
(defun make-directory (path)
"Including parents."