[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Functional argument for `directory-files' and `directory-files-and-attri
From: |
Dmitry Antipov |
Subject: |
Functional argument for `directory-files' and `directory-files-and-attributes' |
Date: |
Mon, 03 Aug 2009 18:42:54 +0400 |
User-agent: |
Thunderbird 2.0.0.21 (X11/20090320) |
Hello all,
this patch illustrates an idea to provide functional argument for
both `directory-files' and `directory-files-and-attributes'.
The goal is to implement more advanced matching techniques than it's
may be done with plain regular expressions. For example:
1) (directory-files "." nil "\\.c$") is equal to
(directory-files "." nil '(lambda (name) (if (string-match "\\.c$" name) t
nil));
2) (directory-files "." nil '(lambda (name) (if (string-match "\\.c$" name) nil
t))
inverts the matching, i.e. matches everything except those names ends with
.c;
3) Match those ends with .c or .h and it's > 300K in size:
(directory-files
"."
nil
'(lambda (name) (if (and (< 307200 (nth 7 (file-attributes name)))
(string-match "\\.[ch]$" name)) t nil)))
Dmitry
Index: dired.c
===================================================================
RCS file: /sources/emacs/emacs/src/dired.c,v
retrieving revision 1.166
diff -u -r1.166 dired.c
--- dired.c 13 Jul 2009 20:22:45 -0000 1.166
+++ dired.c 3 Aug 2009 14:17:21 -0000
@@ -152,7 +152,7 @@
Lisp_Object list, dirfilename, encoded_directory;
struct re_pattern_buffer *bufp = NULL;
int needsep = 0;
- int count = SPECPDL_INDEX ();
+ int matchtype, count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
DIRENTRY *dp;
#ifdef WINDOWSNT
@@ -165,10 +165,10 @@
GCPRO5 (match, directory, list, dirfilename, encoded_directory);
dirfilename = Fdirectory_file_name (directory);
- if (!NILP (match))
+ if (NILP (match))
+ matchtype = 0;
+ else if (STRINGP (match))
{
- CHECK_STRING (match);
-
/* MATCH might be a flawed regular expression. Rather than
catching and signaling our own errors, we just call
compile_pattern to do the work for us. */
@@ -181,7 +181,12 @@
# else /* !WINDOWSNT */
bufp = compile_pattern (match, 0, Qnil, 0, 1);
# endif /* !WINDOWSNT */
+ matchtype = 1;
}
+ else if (FUNCTIONP (match))
+ matchtype = 2;
+ else
+ wrong_type_argument (intern ("string-or-function-p"), match);
/* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
run_pre_post_conversion_on_str which calls Lisp directly and
@@ -191,7 +196,7 @@
encoded_directory = (STRING_MULTIBYTE (directory)
? ENCODE_FILE (directory) : directory);
- /* Now *bufp is the compiled form of MATCH; don't call anything
+ /* Now *bufp may be a compiled form of MATCH; if so, don't call anything
which might compile a new regexp until we're done with the loop! */
BLOCK_INPUT;
@@ -277,9 +282,20 @@
immediate_quit = 1;
QUIT;
- if (NILP (match)
- || (0 <= re_search (bufp, SDATA (name), len, 0, len, 0)))
- wanted = 1;
+ switch (matchtype)
+ {
+ case 0:
+ wanted = 1;
+ break;
+ case 1:
+ wanted = (0 <= re_search (bufp, SDATA (name), len, 0, len, 0));
+ break;
+ case 2:
+ wanted = EQ (call1 (match, name), Qt);
+ break;
+ default:
+ abort ();
+ }
immediate_quit = 0;
@@ -366,7 +382,10 @@
There are three optional arguments:
If FULL is non-nil, return absolute file names. Otherwise return names
that are relative to the specified directory.
-If MATCH is non-nil, mention only file names that match the regexp MATCH.
+If MATCH is nil, all file names are matched.
+If MATCH is a string, mention only file names that match the regexp MATCH.
+If MATCH is a function, it should accept file name as the only string
+argument and return t whether the name matches, or nil otherwise.
If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
Otherwise, the list returned is sorted with `stringp-lessp'.
NOSORT is useful if you plan to sort the result yourself. */)
@@ -392,7 +411,10 @@
There are four optional arguments:
If FULL is non-nil, return absolute file names. Otherwise return names
that are relative to the specified directory.
-If MATCH is non-nil, mention only file names that match the regexp MATCH.
+If MATCH is nil, all file names are matched.
+If MATCH is a string, mention only file names that match the regexp MATCH.
+If MATCH is a function, it should accept file name as the only string
+argument and return t whether the name matches, or nil otherwise.
If NOSORT is non-nil, the list is not sorted--its order is unpredictable.
NOSORT is useful if you plan to sort the result yourself.
ID-FORMAT specifies the preferred format of attributes uid and gid, see
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Functional argument for `directory-files' and `directory-files-and-attributes',
Dmitry Antipov <=