diff --git a/core/autoload/files.el b/core/autoload/files.el index ed84330c3..2bd07579d 100644 --- a/core/autoload/files.el +++ b/core/autoload/files.el @@ -1,5 +1,104 @@ ;;; core/autoload/files.el -*- lexical-binding: t; -*- +(defun doom--path (&rest segments) + (let (file-name-handler-alist) + (let ((dir (pop segments))) + (unless segments + (setq dir (expand-file-name dir))) + (while segments + (setq dir (expand-file-name (car segments) dir) + segments (cdr segments))) + dir))) + +;;;###autoload +(defun doom-glob (&rest segments) + "Construct a path from SEGMENTS and expand glob patterns. +Returns nil if the path doesn't exist." + (let* (case-fold-search + file-name-handler-alist + (dir (apply #'doom--path segments))) + (if (string-match-p "[[*?]" dir) + (file-expand-wildcards dir t) + (if (file-exists-p dir) + dir)))) + +;;;###autoload +(defun doom-path (&rest segments) + "Constructs a file path from SEGMENTS." + (if segments + (apply #'doom--path segments) + (file!))) + +;;;###autoload +(defun doom-dir (&rest segments) + "Constructs a path from SEGMENTS. +See `doom-path'." + (when-let (path (apply #'doom-path segments)) + (directory-file-name (file-name-directory path)))) + +;;;###autoload +(cl-defun doom-files-in + (paths &rest rest + &key + filter + map + (full t) + (follow-symlinks t) + (type 'files) + (relative-to (unless full default-directory)) + (depth 99999) + (mindepth 0) + (match "/[^._][^/]+")) + "Return a list of files/directories in PATHS (one string or a list of them). + +FILTER is a function or symbol that takes one argument (the path). If it returns +non-nil, the entry will be excluded. + +MAP is a function or symbol which will be used to transform each entry in the +results. + +TYPE determines what kind of path will be included in the results. This can be t +(files and folders), 'files or 'dirs. + +By default, this function returns paths relative to PATH-OR-PATHS if it is a +single path. If it a list of paths, this function returns absolute paths. +Otherwise, by setting RELATIVE-TO to a path, the results will be transformed to +be relative to it. + +The search recurses up to DEPTH and no further. DEPTH is an integer. + +MATCH is a string regexp. Only entries that match it will be included." + (let (file-name-handler-alist + result) + (dolist (file (mapcan (doom-rpartial #'doom-glob "*") (doom-enlist paths))) + (cond ((file-directory-p file) + (nconcq! result + (and (memq type '(t dirs)) + (string-match-p match file) + (not (and filter (funcall filter file))) + (not (and (file-symlink-p file) + (not follow-symlinks))) + (<= mindepth 0) + (list (cond (map (funcall map file)) + (relative-to (file-relative-name file relative-to)) + (file)))) + (and (>= depth 1) + (apply #'doom-files-in file + (append (list :mindepth (1- mindepth) + :depth (1- depth) + :relative-to relative-to) + rest))))) + ((and (memq type '(t files)) + (string-match-p match file) + (not (and filter (funcall filter file))) + (<= mindepth 0)) + (push (if relative-to + (file-relative-name file relative-to) + file) + result)))) + result)) + + ;; ;;; Helpers diff --git a/core/core-lib.el b/core/core-lib.el index ffa092609..25cd7b6c3 100644 --- a/core/core-lib.el +++ b/core/core-lib.el @@ -119,16 +119,6 @@ list is returned as-is." (intern (format "doom--setq-%s-for-%s-h" var mode)))))) -(defun doom--path (&rest segments) - (let (file-name-handler-alist) - (let ((dir (pop segments))) - (unless segments - (setq dir (expand-file-name dir))) - (while segments - (setq dir (expand-file-name (car segments) dir) - segments (cdr segments))) - dir))) - ;; ;;; Public library @@ -157,29 +147,6 @@ list is returned as-is." (cl-check-type :test keyword) (substring (symbol-name keyword) 1)) -(defun doom-glob (&rest segments) - "Construct a path from SEGMENTS and expand glob patterns. -Returns nil if the path doesn't exist." - (let* (case-fold-search - file-name-handler-alist - (dir (apply #'doom--path segments))) - (if (string-match-p "[[*?]" dir) - (file-expand-wildcards dir t) - (if (file-exists-p dir) - dir)))) - -(defun doom-path (&rest segments) - "Constructs a file path from SEGMENTS." - (if segments - (apply #'doom--path segments) - (file!))) - -(defun doom-dir (&rest segments) - "Constructs a path from SEGMENTS. -See `doom-path'." - (when-let (path (apply #'doom-path segments)) - (directory-file-name (file-name-directory path)))) - (defmacro doom-log (format-string &rest args) "Log to *Messages* if `doom-debug-mode' is on. Does not interrupt the minibuffer if it is in use, but still logs to *Messages*. @@ -208,67 +175,6 @@ at the values with which this function was called." (lambda (&rest pre-args) (apply fn (append pre-args args)))) -(cl-defun doom-files-in - (paths &rest rest - &key - filter - map - (full t) - (follow-symlinks t) - (type 'files) - (relative-to (unless full default-directory)) - (depth 99999) - (mindepth 0) - (match "/[^._][^/]+")) - "Return a list of files/directories in PATHS (one string or a list of them). - -FILTER is a function or symbol that takes one argument (the path). If it returns -non-nil, the entry will be excluded. - -MAP is a function or symbol which will be used to transform each entry in the -results. - -TYPE determines what kind of path will be included in the results. This can be t -(files and folders), 'files or 'dirs. - -By default, this function returns paths relative to PATH-OR-PATHS if it is a -single path. If it a list of paths, this function returns absolute paths. -Otherwise, by setting RELATIVE-TO to a path, the results will be transformed to -be relative to it. - -The search recurses up to DEPTH and no further. DEPTH is an integer. - -MATCH is a string regexp. Only entries that match it will be included." - (let (file-name-handler-alist - result) - (dolist (file (mapcan (doom-rpartial #'doom-glob "*") (doom-enlist paths))) - (cond ((file-directory-p file) - (nconcq! result - (and (memq type '(t dirs)) - (string-match-p match file) - (not (and filter (funcall filter file))) - (not (and (file-symlink-p file) - (not follow-symlinks))) - (<= mindepth 0) - (list (cond (map (funcall map file)) - (relative-to (file-relative-name file relative-to)) - (file)))) - (and (>= depth 1) - (apply #'doom-files-in file - (append (list :mindepth (1- mindepth) - :depth (1- depth) - :relative-to relative-to) - rest))))) - ((and (memq type '(t files)) - (string-match-p match file) - (not (and filter (funcall filter file))) - (<= mindepth 0)) - (push (if relative-to - (file-relative-name file relative-to) - file) - result)))) - result)) - ;; ;;; Sugars