help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: traverse a directory


From: Mike Mattie
Subject: Re: traverse a directory
Date: Tue, 1 Jan 2008 21:43:15 -0800

On Tue, 1 Jan 2008 08:51:33 -0800 (PST)
Xah Lee <xah@xahlee.org> wrote:

> if i want to recurse into a directory, do i have to write my own?
> 
> e.g. i want to apply a file processing function to all files in a dir
> and subdirs. Somethnig like
> 
> (apply 'process-my-file "/Users/xah/emacs/" "\.html$")
> 
> I noticed that directory-files only list the dir file. Someone told me
> there's a directory-files-recur but that doesn't seems to be in emacs.
> 
> thx in advance.

here is something kinda related that I recently hacked up. I needed to be able 
to
filter the results of a directory list. The first hack started off as a plain
defun but I encountered variations so I made a macro. it may duplicate existing
emacs code.

the elisp-in-path defun shows how the form is used. It's uncommented, and
relies upon map-filter-nil which needs to be non-recursive for general use.

It is pretty easy to extend for filtering on either the path or the mode string.
Writing a general tree recursion is trivial, it shouldn't even be file specific.
this defun may help tailor such a recursion towards a fs tree.

(defun filter-ls-attributes ( filter-form )
  "implement the various attribute filters for the filter-ls form"
  (lexical-let
    ((attr-name (symbol-name (car filter-form)))
      (attr-match (cadr filter-form)))

    (cond
      ((string-equal "type" attr-name) (list 'char-equal attr-match  '(aref 
(cdr path-pair) 0)))
      ((string-equal "path" attr-name) (list 'string-match-p attr-match '(car 
path-pair)))
    ;; error path
    )))

(defmacro filter-ls (path path-type &rest filters)
  "a form for flexibly filtering the result of listing a directory with 
attributes"
  `(apply 'map-filter-nil
     (lambda ( path-pair )
       (if ,(cons 'and (mapcar 'filter-ls-attributes filters))
         (car path-pair)))

     ;; reduce the attributes to a pair of the path, and the mode string
     (mapcar (lambda ( attr-list )
               (cons (car attr-list) (nth 9 attr-list)))
       ;; get the list of files.
       (directory-files-and-attributes ,path ,path-type))
     ))

;; path-type is t absolute, nil relative.

(defun elisp-in-path ( path path-type )
  "return a list of elisp files in the path"

  (filter-ls path path-type
    (type ?-)
    (path "\\.el$")))

P.S

here is map-filter-nil. use at your own risk.

(defun map-filter-nil ( func &rest seq )
  "map-filter-nil. apply the function to the arguements ala mapcar.
   Filter any nil elements of the sequence before the function is
   applied, and after the function is applied."

  (if (car seq)
    (let
      ((result (funcall func (car seq))))
      (if result
        (cons result (apply 'map-filter-nil func (cdr seq)))
        (apply 'map-filter-nil func (cdr seq))
        ))
    (if (cdr seq)
      (apply 'map-filter-nil func (cdr seq)))
    ))

>   Xah
>   xah@xahlee.org
> ∑ http://xahlee.org/
> 
> _______________________________________________
> help-gnu-emacs mailing list
> help-gnu-emacs@gnu.org
> http://lists.gnu.org/mailman/listinfo/help-gnu-emacs

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]