# HG changeset patch # User Stefan Monnier # Date 1207797169 0 # Node ID 76ebfa5df8a269d680eb81836a20427f0c0857f4 # Parent a5df3c8bf64adbb1bd3b99a5149e63ba8fb05520 * 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. diff -r a5df3c8bf64a -r 76ebfa5df8a2 lisp/ChangeLog --- 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 + * 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. diff -r a5df3c8bf64a -r 76ebfa5df8a2 lisp/minibuffer.el --- 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 diff -r a5df3c8bf64a -r 76ebfa5df8a2 src/ChangeLog --- 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 + + * 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 * minibuf.c (Vcompletion_auto_help): Move to minibuffer.el. diff -r a5df3c8bf64a -r 76ebfa5df8a2 src/fileio.c --- 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);