diff options
| author | Stefan Monnier | 2008-04-10 03:12:49 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-04-10 03:12:49 +0000 |
| commit | 34b67b0f6be8b2a0f62e3691be03e1dc5564a772 (patch) | |
| tree | f94a2861f9349f22a61179c510be285f42555d79 | |
| parent | d2925a49b44e0c95c2078dc365379480f0ff448b (diff) | |
| download | emacs-34b67b0f6be8b2a0f62e3691be03e1dc5564a772.tar.gz emacs-34b67b0f6be8b2a0f62e3691be03e1dc5564a772.zip | |
* 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.
| -rw-r--r-- | lisp/ChangeLog | 3 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 54 | ||||
| -rw-r--r-- | src/ChangeLog | 6 | ||||
| -rw-r--r-- | src/fileio.c | 130 |
4 files changed, 63 insertions, 130 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4497176527f..3e9320cfcee 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | 2008-04-10 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2008-04-10 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * minibuffer.el (minibuffer--double-dollars, read-file-name-internal): | ||
| 4 | New functions. | ||
| 5 | |||
| 3 | * minibuffer.el (minibuffer--do-completion): Don't forget to propagate | 6 | * minibuffer.el (minibuffer--do-completion): Don't forget to propagate |
| 4 | the arg to recursive calls. | 7 | the arg to recursive calls. |
| 5 | 8 | ||
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index dbf78e05679..98d28824adf 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -450,5 +450,59 @@ during running `completion-setup-hook'." | |||
| 450 | (ding)) | 450 | (ding)) |
| 451 | (exit-minibuffer)) | 451 | (exit-minibuffer)) |
| 452 | 452 | ||
| 453 | (defun minibuffer--double-dollars (str) | ||
| 454 | (replace-regexp-in-string "\\$" "$$" str)) | ||
| 455 | |||
| 456 | (defun read-file-name-internal (string dir action) | ||
| 457 | "Internal subroutine for read-file-name. Do not call this." | ||
| 458 | (setq dir (expand-file-name dir)) | ||
| 459 | (if (and (zerop (length string)) (eq 'lambda action)) | ||
| 460 | nil ; FIXME: why? | ||
| 461 | (let* ((str (substitute-in-file-name string)) | ||
| 462 | (name (file-name-nondirectory str)) | ||
| 463 | (specdir (file-name-directory str)) | ||
| 464 | (realdir (if specdir (expand-file-name specdir dir) | ||
| 465 | (file-name-as-directory dir)))) | ||
| 466 | |||
| 467 | (cond | ||
| 468 | ((null action) | ||
| 469 | (let ((comp (file-name-completion name realdir | ||
| 470 | read-file-name-predicate))) | ||
| 471 | (if (stringp comp) | ||
| 472 | ;; Requote the $s before returning the completion. | ||
| 473 | (minibuffer--double-dollars (concat specdir comp)) | ||
| 474 | ;; Requote the $s before checking for changes. | ||
| 475 | (setq str (minibuffer--double-dollars str)) | ||
| 476 | (if (string-equal string str) | ||
| 477 | comp | ||
| 478 | ;; If there's no real completion, but substitute-in-file-name | ||
| 479 | ;; changed the string, then return the new string. | ||
| 480 | str)))) | ||
| 481 | |||
| 482 | ((eq action t) | ||
| 483 | (let ((all (file-name-all-completions name realdir))) | ||
| 484 | (if (memq read-file-name-predicate '(nil file-exists-p)) | ||
| 485 | all | ||
| 486 | (let ((comp ()) | ||
| 487 | (pred | ||
| 488 | (if (eq read-file-name-predicate 'file-directory-p) | ||
| 489 | ;; Brute-force speed up for directory checking: | ||
| 490 | ;; Discard strings which don't end in a slash. | ||
| 491 | (lambda (s) | ||
| 492 | (let ((len (length s))) | ||
| 493 | (and (> len 0) (eq (aref s (1- len)) ?/)))) | ||
| 494 | ;; Must do it the hard (and slow) way. | ||
| 495 | read-file-name-predicate))) | ||
| 496 | (let ((default-directory realdir)) | ||
| 497 | (dolist (tem all) | ||
| 498 | (if (funcall pred tem) (push tem comp)))) | ||
| 499 | (nreverse comp))))) | ||
| 500 | |||
| 501 | (t | ||
| 502 | ;; Only other case actually used is ACTION = lambda. | ||
| 503 | (let ((default-directory dir)) | ||
| 504 | (funcall (or read-file-name-predicate 'file-exists-p) str))))))) | ||
| 505 | |||
| 506 | |||
| 453 | (provide 'minibuffer) | 507 | (provide 'minibuffer) |
| 454 | ;;; minibuffer.el ends here | 508 | ;;; minibuffer.el ends here |
diff --git a/src/ChangeLog b/src/ChangeLog index 88a86246728..29b0e0c5ab1 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,9 @@ | |||
| 1 | 2008-04-10 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * fileio.c (read_file_name_cleanup, Fread_file_name_internal): | ||
| 4 | Move functions to minibuffer.el. | ||
| 5 | (syms_of_fileio): Don't declare them. | ||
| 6 | |||
| 1 | 2008-04-09 Stefan Monnier <monnier@iro.umontreal.ca> | 7 | 2008-04-09 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 8 | ||
| 3 | * minibuf.c (Vcompletion_auto_help): Move to minibuffer.el. | 9 | * minibuf.c (Vcompletion_auto_help): Move to minibuffer.el. |
diff --git a/src/fileio.c b/src/fileio.c index 70b72f52553..6433fe93231 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -6119,135 +6119,6 @@ double_dollars (val) | |||
| 6119 | return val; | 6119 | return val; |
| 6120 | } | 6120 | } |
| 6121 | 6121 | ||
| 6122 | static Lisp_Object | ||
| 6123 | read_file_name_cleanup (arg) | ||
| 6124 | Lisp_Object arg; | ||
| 6125 | { | ||
| 6126 | return (current_buffer->directory = arg); | ||
| 6127 | } | ||
| 6128 | |||
| 6129 | DEFUN ("read-file-name-internal", Fread_file_name_internal, Sread_file_name_internal, | ||
| 6130 | 3, 3, 0, | ||
| 6131 | doc: /* Internal subroutine for read-file-name. Do not call this. */) | ||
| 6132 | (string, dir, action) | ||
| 6133 | Lisp_Object string, dir, action; | ||
| 6134 | /* action is nil for complete, t for return list of completions, | ||
| 6135 | lambda for verify final value */ | ||
| 6136 | { | ||
| 6137 | Lisp_Object name, specdir, realdir, val, orig_string; | ||
| 6138 | int changed; | ||
| 6139 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | ||
| 6140 | |||
| 6141 | CHECK_STRING (string); | ||
| 6142 | |||
| 6143 | realdir = dir; | ||
| 6144 | name = string; | ||
| 6145 | orig_string = Qnil; | ||
| 6146 | specdir = Qnil; | ||
| 6147 | changed = 0; | ||
| 6148 | /* No need to protect ACTION--we only compare it with t and nil. */ | ||
| 6149 | GCPRO5 (string, realdir, name, specdir, orig_string); | ||
| 6150 | |||
| 6151 | if (SCHARS (string) == 0) | ||
| 6152 | { | ||
| 6153 | if (EQ (action, Qlambda)) | ||
| 6154 | { | ||
| 6155 | UNGCPRO; | ||
| 6156 | return Qnil; | ||
| 6157 | } | ||
| 6158 | } | ||
| 6159 | else | ||
| 6160 | { | ||
| 6161 | orig_string = string; | ||
| 6162 | string = Fsubstitute_in_file_name (string); | ||
| 6163 | changed = NILP (Fstring_equal (string, orig_string)); | ||
| 6164 | name = Ffile_name_nondirectory (string); | ||
| 6165 | val = Ffile_name_directory (string); | ||
| 6166 | if (! NILP (val)) | ||
| 6167 | realdir = Fexpand_file_name (val, realdir); | ||
| 6168 | } | ||
| 6169 | |||
| 6170 | if (NILP (action)) | ||
| 6171 | { | ||
| 6172 | specdir = Ffile_name_directory (string); | ||
| 6173 | val = Ffile_name_completion (name, realdir, Vread_file_name_predicate); | ||
| 6174 | UNGCPRO; | ||
| 6175 | if (!STRINGP (val)) | ||
| 6176 | { | ||
| 6177 | if (changed) | ||
| 6178 | return double_dollars (string); | ||
| 6179 | return val; | ||
| 6180 | } | ||
| 6181 | |||
| 6182 | if (!NILP (specdir)) | ||
| 6183 | val = concat2 (specdir, val); | ||
| 6184 | #ifndef VMS | ||
| 6185 | return double_dollars (val); | ||
| 6186 | #else /* not VMS */ | ||
| 6187 | return val; | ||
| 6188 | #endif /* not VMS */ | ||
| 6189 | } | ||
| 6190 | UNGCPRO; | ||
| 6191 | |||
| 6192 | if (EQ (action, Qt)) | ||
| 6193 | { | ||
| 6194 | Lisp_Object all = Ffile_name_all_completions (name, realdir); | ||
| 6195 | Lisp_Object comp; | ||
| 6196 | int count; | ||
| 6197 | |||
| 6198 | if (NILP (Vread_file_name_predicate) | ||
| 6199 | || EQ (Vread_file_name_predicate, Qfile_exists_p)) | ||
| 6200 | return all; | ||
| 6201 | |||
| 6202 | #ifndef VMS | ||
| 6203 | if (EQ (Vread_file_name_predicate, Qfile_directory_p)) | ||
| 6204 | { | ||
| 6205 | /* Brute-force speed up for directory checking: | ||
| 6206 | Discard strings which don't end in a slash. */ | ||
| 6207 | for (comp = Qnil; CONSP (all); all = XCDR (all)) | ||
| 6208 | { | ||
| 6209 | Lisp_Object tem = XCAR (all); | ||
| 6210 | int len; | ||
| 6211 | if (STRINGP (tem) && | ||
| 6212 | (len = SBYTES (tem), len > 0) && | ||
| 6213 | IS_DIRECTORY_SEP (SREF (tem, len-1))) | ||
| 6214 | comp = Fcons (tem, comp); | ||
| 6215 | } | ||
| 6216 | } | ||
| 6217 | else | ||
| 6218 | #endif | ||
| 6219 | { | ||
| 6220 | /* Must do it the hard (and slow) way. */ | ||
| 6221 | Lisp_Object tem; | ||
| 6222 | GCPRO3 (all, comp, specdir); | ||
| 6223 | count = SPECPDL_INDEX (); | ||
| 6224 | record_unwind_protect (read_file_name_cleanup, current_buffer->directory); | ||
| 6225 | current_buffer->directory = realdir; | ||
| 6226 | for (comp = Qnil; CONSP (all); all = XCDR (all)) | ||
| 6227 | { | ||
| 6228 | tem = call1 (Vread_file_name_predicate, XCAR (all)); | ||
| 6229 | if (!NILP (tem)) | ||
| 6230 | comp = Fcons (XCAR (all), comp); | ||
| 6231 | } | ||
| 6232 | unbind_to (count, Qnil); | ||
| 6233 | UNGCPRO; | ||
| 6234 | } | ||
| 6235 | return Fnreverse (comp); | ||
| 6236 | } | ||
| 6237 | |||
| 6238 | /* Only other case actually used is ACTION = lambda */ | ||
| 6239 | #ifdef VMS | ||
| 6240 | /* Supposedly this helps commands such as `cd' that read directory names, | ||
| 6241 | but can someone explain how it helps them? -- RMS */ | ||
| 6242 | if (SCHARS (name) == 0) | ||
| 6243 | return Qt; | ||
| 6244 | #endif /* VMS */ | ||
| 6245 | string = Fexpand_file_name (string, dir); | ||
| 6246 | if (!NILP (Vread_file_name_predicate)) | ||
| 6247 | return call1 (Vread_file_name_predicate, string); | ||
| 6248 | return Ffile_exists_p (string); | ||
| 6249 | } | ||
| 6250 | |||
| 6251 | DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p, | 6122 | DEFUN ("next-read-file-uses-dialog-p", Fnext_read_file_uses_dialog_p, |
| 6252 | Snext_read_file_uses_dialog_p, 0, 0, 0, | 6123 | Snext_read_file_uses_dialog_p, 0, 0, 0, |
| 6253 | doc: /* Return t if a call to `read-file-name' will use a dialog. | 6124 | doc: /* Return t if a call to `read-file-name' will use a dialog. |
| @@ -6803,7 +6674,6 @@ A non-nil value may result in data loss! */); | |||
| 6803 | defsubr (&Sclear_buffer_auto_save_failure); | 6674 | defsubr (&Sclear_buffer_auto_save_failure); |
| 6804 | defsubr (&Srecent_auto_save_p); | 6675 | defsubr (&Srecent_auto_save_p); |
| 6805 | 6676 | ||
| 6806 | defsubr (&Sread_file_name_internal); | ||
| 6807 | defsubr (&Sread_file_name); | 6677 | defsubr (&Sread_file_name); |
| 6808 | defsubr (&Snext_read_file_uses_dialog_p); | 6678 | defsubr (&Snext_read_file_uses_dialog_p); |
| 6809 | 6679 | ||