changeset 93945:76ebfa5df8a2

* minibuffer.el (minibuffer--double-dollars, read-file-name-internal): New functions. * fileio.c (read_file_name_cleanup, Fread_file_name_internal): Move functions to minibuffer.el. (syms_of_fileio): Don't declare them.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Thu, 10 Apr 2008 03:12:49 +0000
parents a5df3c8bf64a
children 9699b2470e1b
files lisp/ChangeLog lisp/minibuffer.el src/ChangeLog src/fileio.c
diffstat 4 files changed, 63 insertions(+), 130 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Thu Apr 10 00:48:10 2008 +0000
+++ b/lisp/ChangeLog	Thu Apr 10 03:12:49 2008 +0000
@@ -1,5 +1,8 @@
 2008-04-10  Stefan Monnier  <monnier@iro.umontreal.ca>
 
+	* minibuffer.el (minibuffer--double-dollars, read-file-name-internal):
+	New functions.
+
 	* minibuffer.el (minibuffer--do-completion): Don't forget to propagate
 	the arg to recursive calls.
 
--- a/lisp/minibuffer.el	Thu Apr 10 00:48:10 2008 +0000
+++ b/lisp/minibuffer.el	Thu Apr 10 03:12:49 2008 +0000
@@ -450,5 +450,59 @@
     (ding))
   (exit-minibuffer))
 
+(defun minibuffer--double-dollars (str)
+  (replace-regexp-in-string "\\$" "$$" str))
+
+(defun read-file-name-internal (string dir action)
+  "Internal subroutine for read-file-name.  Do not call this."
+  (setq dir (expand-file-name dir))
+  (if (and (zerop (length string)) (eq 'lambda action))
+      nil                               ; FIXME: why?
+    (let* ((str (substitute-in-file-name string))
+           (name (file-name-nondirectory str))
+           (specdir (file-name-directory str))
+           (realdir (if specdir (expand-file-name specdir dir)
+                      (file-name-as-directory dir))))
+      
+      (cond
+       ((null action)
+        (let ((comp (file-name-completion name realdir
+                                          read-file-name-predicate)))
+          (if (stringp comp)
+              ;; Requote the $s before returning the completion.
+              (minibuffer--double-dollars (concat specdir comp))
+            ;; Requote the $s before checking for changes.
+            (setq str (minibuffer--double-dollars str))
+            (if (string-equal string str)
+                comp
+              ;; If there's no real completion, but substitute-in-file-name
+              ;; changed the string, then return the new string.
+              str))))
+       
+       ((eq action t)
+        (let ((all (file-name-all-completions name realdir)))
+          (if (memq read-file-name-predicate '(nil file-exists-p))
+              all
+            (let ((comp ())
+                  (pred
+                   (if (eq read-file-name-predicate 'file-directory-p)
+                       ;; Brute-force speed up for directory checking:
+                       ;; Discard strings which don't end in a slash.
+                       (lambda (s)
+                         (let ((len (length s)))
+                           (and (> len 0) (eq (aref s (1- len)) ?/))))
+                     ;; Must do it the hard (and slow) way.
+                     read-file-name-predicate)))
+              (let ((default-directory realdir))
+                (dolist (tem all)
+                  (if (funcall pred tem) (push tem comp))))
+              (nreverse comp)))))
+
+       (t
+        ;; Only other case actually used is ACTION = lambda.
+        (let ((default-directory dir))
+          (funcall (or read-file-name-predicate 'file-exists-p) str)))))))
+
+
 (provide 'minibuffer)
 ;;; minibuffer.el ends here
--- a/src/ChangeLog	Thu Apr 10 00:48:10 2008 +0000
+++ b/src/ChangeLog	Thu Apr 10 03:12:49 2008 +0000
@@ -1,3 +1,9 @@
+2008-04-10  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* fileio.c (read_file_name_cleanup, Fread_file_name_internal):
+	Move functions to minibuffer.el.
+	(syms_of_fileio): Don't declare them.
+
 2008-04-09  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* minibuf.c (Vcompletion_auto_help): Move to minibuffer.el.
--- a/src/fileio.c	Thu Apr 10 00:48:10 2008 +0000
+++ b/src/fileio.c	Thu Apr 10 03:12:49 2008 +0000
@@ -6119,135 +6119,6 @@
   return val;
 }
 
-static Lisp_Object
-read_file_name_cleanup (arg)
-     Lisp_Object arg;
-{
-  return (current_buffer->directory = arg);
-}
-
-DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal,
-       3, 3, 0,
-       doc: /* Internal subroutine for read-file-name.  Do not call this.  */)
-     (string, dir, action)
-     Lisp_Object string, dir, action;
-  /* action is nil for complete, t for return list of completions,
-     lambda for verify final value */
-{
-  Lisp_Object name, specdir, realdir, val, orig_string;
-  int changed;
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
-
-  CHECK_STRING (string);
-
-  realdir = dir;
-  name = string;
-  orig_string = Qnil;
-  specdir = Qnil;
-  changed = 0;
-  /* No need to protect ACTION--we only compare it with t and nil.  */
-  GCPRO5 (string, realdir, name, specdir, orig_string);
-
-  if (SCHARS (string) == 0)
-    {
-      if (EQ (action, Qlambda))
-	{
-	  UNGCPRO;
-	  return Qnil;
-	}
-    }
-  else
-    {
-      orig_string = string;
-      string = Fsubstitute_in_file_name (string);
-      changed = NILP (Fstring_equal (string, orig_string));
-      name = Ffile_name_nondirectory (string);
-      val = Ffile_name_directory (string);
-      if (! NILP (val))
-	realdir = Fexpand_file_name (val, realdir);
-    }
-
-  if (NILP (action))
-    {
-      specdir = Ffile_name_directory (string);
-      val = Ffile_name_completion (name, realdir, Vread_file_name_predicate);
-      UNGCPRO;
-      if (!STRINGP (val))
-	{
-	  if (changed)
-	    return double_dollars (string);
-	  return val;
-	}
-
-      if (!NILP (specdir))
-	val = concat2 (specdir, val);
-#ifndef VMS
-      return double_dollars (val);
-#else /* not VMS */
-      return val;
-#endif /* not VMS */
-    }
-  UNGCPRO;
-
-  if (EQ (action, Qt))
-    {
-      Lisp_Object all = Ffile_name_all_completions (name, realdir);
-      Lisp_Object comp;
-      int count;
-
-      if (NILP (Vread_file_name_predicate)
-	  || EQ (Vread_file_name_predicate, Qfile_exists_p))
-	return all;
-
-#ifndef VMS
-      if (EQ (Vread_file_name_predicate, Qfile_directory_p))
-	{
-	  /* Brute-force speed up for directory checking:
-	     Discard strings which don't end in a slash.  */
-	  for (comp = Qnil; CONSP (all); all = XCDR (all))
-	    {
-	      Lisp_Object tem = XCAR (all);
-	      int len;
-	      if (STRINGP (tem) &&
-		  (len = SBYTES (tem), len > 0) &&
-		  IS_DIRECTORY_SEP (SREF (tem, len-1)))
-		comp = Fcons (tem, comp);
-	    }
-	}
-      else
-#endif
-	{
-	  /* Must do it the hard (and slow) way.  */
-	  Lisp_Object tem;
-	  GCPRO3 (all, comp, specdir);
-	  count = SPECPDL_INDEX ();
-	  record_unwind_protect (read_file_name_cleanup, current_buffer->directory);
-	  current_buffer->directory = realdir;
-	  for (comp = Qnil; CONSP (all); all = XCDR (all))
-	    {
-	      tem = call1 (Vread_file_name_predicate, XCAR (all));
-	      if (!NILP (tem))
-		comp = Fcons (XCAR (all), comp);
-	    }
-	  unbind_to (count, Qnil);
-	  UNGCPRO;
-	}
-      return Fnreverse (comp);
-    }
-
-  /* Only other case actually used is ACTION = lambda */
-#ifdef VMS
-  /* Supposedly this helps commands such as `cd' that read directory names,
-     but can someone explain how it helps them? -- RMS */
-  if (SCHARS (name) == 0)
-    return Qt;
-#endif /* VMS */
-  string = Fexpand_file_name (string, dir);
-  if (!NILP (Vread_file_name_predicate))
-    return call1 (Vread_file_name_predicate, string);
-  return Ffile_exists_p (string);
-}
-
 DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p,
        Snext_read_file_uses_dialog_p, 0, 0, 0,
        doc: /* Return t if a call to `read-file-name' will use a dialog.
@@ -6803,7 +6674,6 @@
   defsubr (&Sclear_buffer_auto_save_failure);
   defsubr (&Srecent_auto_save_p);
 
-  defsubr (&Sread_file_name_internal);
   defsubr (&Sread_file_name);
   defsubr (&Snext_read_file_uses_dialog_p);