/* Lisp functions for making directory listings.
Copyright (C) 1985, 1986, 1993, 1994, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005 Free Software Foundation, Inc.
+ 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "systime.h"
#include "buffer.h"
#include "commands.h"
+#include "character.h"
#include "charset.h"
#include "coding.h"
#include "regex.h"
+#include "blockinput.h"
/* Returns a search buffer, with a fastmap allocated and ready to go. */
extern struct re_pattern_buffer *compile_pattern ();
Lisp_Object dh;
{
DIR *d = (DIR *) XSAVE_VALUE (dh)->pointer;
+ BLOCK_INPUT;
closedir (d);
+ UNBLOCK_INPUT;
return Qnil;
}
#ifdef VMS
bufp = compile_pattern (match, 0,
buffer_defaults.downcase_table, 0, 1);
-#else
+#else /* !VMS */
+# ifdef WINDOWSNT
+ /* Windows users want case-insensitive wildcards. */
+ bufp = compile_pattern (match, 0,
+ buffer_defaults.case_canon_table, 0, 1);
+# else /* !WINDOWSNT */
bufp = compile_pattern (match, 0, Qnil, 0, 1);
-#endif
+# endif /* !WINDOWSNT */
+#endif /* !VMS */
}
/* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
/* Now *bufp is the compiled form of MATCH; don't call anything
which might compile a new regexp until we're done with the loop! */
+ BLOCK_INPUT;
d = opendir (SDATA (dirfilename));
+ UNBLOCK_INPUT;
if (d == NULL)
report_file_error ("Opening directory", Fcons (directory, Qnil));
}
}
+ BLOCK_INPUT;
closedir (d);
+ UNBLOCK_INPUT;
/* Discard the unwind protect. */
specpdl_ptr = specpdl + count;
Lisp_Object file_name_completion ();
DEFUN ("file-name-completion", Ffile_name_completion, Sfile_name_completion,
- 2, 2, 0,
+ 2, 3, 0,
doc: /* Complete file name FILE in directory DIRECTORY.
Returns the longest string
common to all file names in DIRECTORY that start with FILE.
If there is only one and FILE matches it exactly, returns t.
Returns nil if DIRECTORY contains no name starting with FILE.
+If PREDICATE is non-nil, call PREDICATE with each possible
+completion (in absolute form) and ignore it if PREDICATE returns nil.
+
This function ignores some of the possible completions as
determined by the variable `completion-ignored-extensions', which see. */)
- (file, directory)
- Lisp_Object file, directory;
+ (file, directory, predicate)
+ Lisp_Object file, directory, predicate;
{
Lisp_Object handler;
call the corresponding file handler. */
handler = Ffind_file_name_handler (directory, Qfile_name_completion);
if (!NILP (handler))
- return call3 (handler, Qfile_name_completion, file, directory);
+ return call4 (handler, Qfile_name_completion, file, directory, predicate);
/* If the file name has special constructs in it,
call the corresponding file handler. */
handler = Ffind_file_name_handler (file, Qfile_name_completion);
if (!NILP (handler))
- return call3 (handler, Qfile_name_completion, file, directory);
+ return call4 (handler, Qfile_name_completion, file, directory, predicate);
- return file_name_completion (file, directory, 0, 0);
+ return file_name_completion (file, directory, 0, 0, predicate);
}
DEFUN ("file-name-all-completions", Ffile_name_all_completions,
if (!NILP (handler))
return call3 (handler, Qfile_name_all_completions, file, directory);
- return file_name_completion (file, directory, 1, 0);
+ return file_name_completion (file, directory, 1, 0, Qnil);
}
static int file_name_completion_stat ();
Lisp_Object
-file_name_completion (file, dirname, all_flag, ver_flag)
+file_name_completion (file, dirname, all_flag, ver_flag, predicate)
Lisp_Object file, dirname;
int all_flag, ver_flag;
+ Lisp_Object predicate;
{
DIR *d;
int bestmatchsize = 0, skip;
register int compare, matchsize;
unsigned char *p1, *p2;
int matchcount = 0;
+ /* If ALL_FLAG is 1, BESTMATCH is the list of all matches, decoded.
+ If ALL_FLAG is 0, BESTMATCH is either nil
+ or the best match so far, not decoded. */
Lisp_Object bestmatch, tem, elt, name;
Lisp_Object encoded_file;
Lisp_Object encoded_dir;
{
int inner_count = SPECPDL_INDEX ();
+ BLOCK_INPUT;
d = opendir (SDATA (Fdirectory_file_name (encoded_dir)));
+ UNBLOCK_INPUT;
if (!d)
report_file_error ("Opening directory", Fcons (dirname, Qnil));
#ifndef TRIVIAL_DIRECTORY_ENTRY
#define TRIVIAL_DIRECTORY_ENTRY(n) (!strcmp (n, ".") || !strcmp (n, ".."))
#endif
- /* "." and ".." are never interesting as completions, but are
- actually in the way in a directory contains only one file. */
+ /* "." and ".." are never interesting as completions, and are
+ actually in the way in a directory with only one file. */
if (!passcount && TRIVIAL_DIRECTORY_ENTRY (dp->d_name))
continue;
if (!passcount && len > SCHARS (encoded_file))
continue;
}
- /* Update computation of how much all possible completions match */
+ /* This is a possible completion */
+ if (directoryp)
+ {
+ /* This completion is a directory; make it end with '/' */
+ name = Ffile_name_as_directory (make_string (dp->d_name, len));
+ }
+ else
+ name = make_string (dp->d_name, len);
+
+ /* Test the predicate, if any. */
+
+ if (!NILP (predicate))
+ {
+ Lisp_Object decoded;
+ decoded = Fexpand_file_name (DECODE_FILE (name), dirname);
+ if (NILP (call1 (predicate, decoded)))
+ continue;
+ }
+
+ /* Suitably record this match. */
matchcount++;
- if (all_flag || NILP (bestmatch))
+ if (all_flag)
{
- /* This is a possible completion */
- if (directoryp)
- {
- /* This completion is a directory; make it end with '/' */
- name = Ffile_name_as_directory (make_string (dp->d_name, len));
- }
- else
- name = make_string (dp->d_name, len);
- if (all_flag)
- {
- name = DECODE_FILE (name);
- bestmatch = Fcons (name, bestmatch);
- }
- else
- {
- bestmatch = name;
- bestmatchsize = SCHARS (name);
- }
+ name = DECODE_FILE (name);
+ bestmatch = Fcons (name, bestmatch);
+ }
+ else if (NILP (bestmatch))
+ {
+ bestmatch = name;
+ bestmatchsize = SCHARS (name);
}
else
{
== SCHARS (bestmatch)))
&& !bcmp (p2, SDATA (encoded_file), SCHARS (encoded_file))
&& bcmp (p1, SDATA (encoded_file), SCHARS (encoded_file))))
- {
- bestmatch = make_string (dp->d_name, len);
- if (directoryp)
- bestmatch = Ffile_name_as_directory (bestmatch);
- }
+ bestmatch = name;
}
/* If this dirname all matches, see if implicit following
(file, directory)
Lisp_Object file, directory;
{
- return file_name_completion (file, directory, 1, 1);
+ return file_name_completion (file, directory, 1, 1, Qnil);
}
DEFUN ("file-version-limit", Ffile_version_limit, Sfile_version_limit, 1, 1, 0,
}
else
{
+ BLOCK_INPUT;
pw = (struct passwd *) getpwuid (s.st_uid);
values[2] = (pw ? build_string (pw->pw_name) : make_number (s.st_uid));
gr = (struct group *) getgrgid (s.st_gid);
values[3] = (gr ? build_string (gr->gr_name) : make_number (s.st_gid));
+ UNBLOCK_INPUT;
}
values[4] = make_time (s.st_atime);
values[5] = make_time (s.st_mtime);