diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/fileio.c | 273 |
2 files changed, 18 insertions, 262 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index c346bb9f31d..e75d3267888 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,10 @@ | |||
| 1 | 2008-04-23 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * fileio.c (Vread_file_name_function, Vread_file_name_predicate) | ||
| 4 | (read_file_name_completion_ignore_case, insert_default_directory) | ||
| 5 | (Qdefault_directory): Move to minibuffer.el. | ||
| 6 | (Fread_file_name): Call the new `read-file-name' instead. | ||
| 7 | |||
| 1 | 2008-04-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 8 | 2008-04-19 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> |
| 2 | 9 | ||
| 3 | * mac.c (create_apple_event) [TARGET_API_MAC_CARBON]: | 10 | * mac.c (create_apple_event) [TARGET_API_MAC_CARBON]: |
diff --git a/src/fileio.c b/src/fileio.c index 738dd266780..a78388895b3 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -207,19 +207,6 @@ Lisp_Object Vwrite_region_annotations_so_far; | |||
| 207 | /* File name in which we write a list of all our auto save files. */ | 207 | /* File name in which we write a list of all our auto save files. */ |
| 208 | Lisp_Object Vauto_save_list_file_name; | 208 | Lisp_Object Vauto_save_list_file_name; |
| 209 | 209 | ||
| 210 | /* Function to call to read a file name. */ | ||
| 211 | Lisp_Object Vread_file_name_function; | ||
| 212 | |||
| 213 | /* Current predicate used by read_file_name_internal. */ | ||
| 214 | Lisp_Object Vread_file_name_predicate; | ||
| 215 | |||
| 216 | /* Nonzero means completion ignores case when reading file name. */ | ||
| 217 | int read_file_name_completion_ignore_case; | ||
| 218 | |||
| 219 | /* Nonzero means, when reading a filename in the minibuffer, | ||
| 220 | start out by inserting the default directory into the minibuffer. */ | ||
| 221 | int insert_default_directory; | ||
| 222 | |||
| 223 | /* On VMS, nonzero means write new files with record format stmlf. | 210 | /* On VMS, nonzero means write new files with record format stmlf. |
| 224 | Zero means use var format. */ | 211 | Zero means use var format. */ |
| 225 | int vms_stmlf_recfm; | 212 | int vms_stmlf_recfm; |
| @@ -6156,218 +6143,22 @@ before any other event (mouse or keypress) is handeled. */) | |||
| 6156 | return Qnil; | 6143 | return Qnil; |
| 6157 | } | 6144 | } |
| 6158 | 6145 | ||
| 6159 | Lisp_Object Qdefault_directory; | 6146 | Lisp_Object |
| 6160 | 6147 | Fread_file_name (prompt, dir, default_filename, mustmatch, initial, predicate) | |
| 6161 | DEFUN ("read-file-name", Fread_file_name, Sread_file_name, 1, 6, 0, | ||
| 6162 | doc: /* Read file name, prompting with PROMPT and completing in directory DIR. | ||
| 6163 | Value is not expanded---you must call `expand-file-name' yourself. | ||
| 6164 | Default name to DEFAULT-FILENAME if user exits the minibuffer with | ||
| 6165 | the same non-empty string that was inserted by this function. | ||
| 6166 | (If DEFAULT-FILENAME is omitted, the visited file name is used, | ||
| 6167 | except that if INITIAL is specified, that combined with DIR is used.) | ||
| 6168 | If the user exits with an empty minibuffer, this function returns | ||
| 6169 | an empty string. (This can only happen if the user erased the | ||
| 6170 | pre-inserted contents or if `insert-default-directory' is nil.) | ||
| 6171 | Fourth arg MUSTMATCH non-nil means require existing file's name. | ||
| 6172 | Non-nil and non-t means also require confirmation after completion. | ||
| 6173 | Fifth arg INITIAL specifies text to start with. | ||
| 6174 | If optional sixth arg PREDICATE is non-nil, possible completions and | ||
| 6175 | the resulting file name must satisfy (funcall PREDICATE NAME). | ||
| 6176 | DIR should be an absolute directory name. It defaults to the value of | ||
| 6177 | `default-directory'. | ||
| 6178 | |||
| 6179 | If this command was invoked with the mouse, use a file dialog box if | ||
| 6180 | `use-dialog-box' is non-nil, and the window system or X toolkit in use | ||
| 6181 | provides a file dialog box. | ||
| 6182 | |||
| 6183 | See also `read-file-name-completion-ignore-case' | ||
| 6184 | and `read-file-name-function'. */) | ||
| 6185 | (prompt, dir, default_filename, mustmatch, initial, predicate) | ||
| 6186 | Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate; | 6148 | Lisp_Object prompt, dir, default_filename, mustmatch, initial, predicate; |
| 6187 | { | 6149 | { |
| 6188 | Lisp_Object val, insdef, tem; | ||
| 6189 | struct gcpro gcpro1, gcpro2; | 6150 | struct gcpro gcpro1, gcpro2; |
| 6190 | register char *homedir; | 6151 | Lisp_Object args[7]; |
| 6191 | Lisp_Object decoded_homedir; | ||
| 6192 | int replace_in_history = 0; | ||
| 6193 | int add_to_history = 0; | ||
| 6194 | int count; | ||
| 6195 | |||
| 6196 | if (NILP (dir)) | ||
| 6197 | dir = current_buffer->directory; | ||
| 6198 | if (NILP (Ffile_name_absolute_p (dir))) | ||
| 6199 | dir = Fexpand_file_name (dir, Qnil); | ||
| 6200 | if (NILP (default_filename)) | ||
| 6201 | default_filename | ||
| 6202 | = (!NILP (initial) | ||
| 6203 | ? Fexpand_file_name (initial, dir) | ||
| 6204 | : current_buffer->filename); | ||
| 6205 | |||
| 6206 | /* If dir starts with user's homedir, change that to ~. */ | ||
| 6207 | homedir = (char *) egetenv ("HOME"); | ||
| 6208 | #ifdef DOS_NT | ||
| 6209 | /* homedir can be NULL in temacs, since Vglobal_environment is not | ||
| 6210 | yet set up. We shouldn't crash in that case. */ | ||
| 6211 | if (homedir != 0) | ||
| 6212 | { | ||
| 6213 | homedir = strcpy (alloca (strlen (homedir) + 1), homedir); | ||
| 6214 | CORRECT_DIR_SEPS (homedir); | ||
| 6215 | } | ||
| 6216 | #endif | ||
| 6217 | if (homedir != 0) | ||
| 6218 | decoded_homedir | ||
| 6219 | = DECODE_FILE (make_unibyte_string (homedir, strlen (homedir))); | ||
| 6220 | if (homedir != 0 | ||
| 6221 | && STRINGP (dir) | ||
| 6222 | && !strncmp (SDATA (decoded_homedir), SDATA (dir), | ||
| 6223 | SBYTES (decoded_homedir)) | ||
| 6224 | && IS_DIRECTORY_SEP (SREF (dir, SBYTES (decoded_homedir)))) | ||
| 6225 | { | ||
| 6226 | dir = Fsubstring (dir, make_number (SCHARS (decoded_homedir)), Qnil); | ||
| 6227 | dir = concat2 (build_string ("~"), dir); | ||
| 6228 | } | ||
| 6229 | /* Likewise for default_filename. */ | ||
| 6230 | if (homedir != 0 | ||
| 6231 | && STRINGP (default_filename) | ||
| 6232 | && !strncmp (SDATA (decoded_homedir), SDATA (default_filename), | ||
| 6233 | SBYTES (decoded_homedir)) | ||
| 6234 | && IS_DIRECTORY_SEP (SREF (default_filename, SBYTES (decoded_homedir)))) | ||
| 6235 | { | ||
| 6236 | default_filename | ||
| 6237 | = Fsubstring (default_filename, | ||
| 6238 | make_number (SCHARS (decoded_homedir)), Qnil); | ||
| 6239 | default_filename = concat2 (build_string ("~"), default_filename); | ||
| 6240 | } | ||
| 6241 | if (!NILP (default_filename)) | ||
| 6242 | { | ||
| 6243 | CHECK_STRING (default_filename); | ||
| 6244 | default_filename = double_dollars (default_filename); | ||
| 6245 | } | ||
| 6246 | |||
| 6247 | if (insert_default_directory && STRINGP (dir)) | ||
| 6248 | { | ||
| 6249 | insdef = dir; | ||
| 6250 | if (!NILP (initial)) | ||
| 6251 | { | ||
| 6252 | Lisp_Object args[2], pos; | ||
| 6253 | |||
| 6254 | args[0] = insdef; | ||
| 6255 | args[1] = initial; | ||
| 6256 | insdef = Fconcat (2, args); | ||
| 6257 | pos = make_number (SCHARS (double_dollars (dir))); | ||
| 6258 | insdef = Fcons (double_dollars (insdef), pos); | ||
| 6259 | } | ||
| 6260 | else | ||
| 6261 | insdef = double_dollars (insdef); | ||
| 6262 | } | ||
| 6263 | else if (STRINGP (initial)) | ||
| 6264 | insdef = Fcons (double_dollars (initial), make_number (0)); | ||
| 6265 | else | ||
| 6266 | insdef = Qnil; | ||
| 6267 | |||
| 6268 | if (!NILP (Vread_file_name_function)) | ||
| 6269 | { | ||
| 6270 | Lisp_Object args[7]; | ||
| 6271 | |||
| 6272 | GCPRO2 (insdef, default_filename); | ||
| 6273 | args[0] = Vread_file_name_function; | ||
| 6274 | args[1] = prompt; | ||
| 6275 | args[2] = dir; | ||
| 6276 | args[3] = default_filename; | ||
| 6277 | args[4] = mustmatch; | ||
| 6278 | args[5] = initial; | ||
| 6279 | args[6] = predicate; | ||
| 6280 | RETURN_UNGCPRO (Ffuncall (7, args)); | ||
| 6281 | } | ||
| 6282 | |||
| 6283 | count = SPECPDL_INDEX (); | ||
| 6284 | specbind (Qdefault_directory, | ||
| 6285 | Ffile_name_as_directory (Fexpand_file_name (dir, Qnil))); | ||
| 6286 | specbind (Qcompletion_ignore_case, | ||
| 6287 | read_file_name_completion_ignore_case ? Qt : Qnil); | ||
| 6288 | specbind (intern ("minibuffer-completing-file-name"), Qt); | ||
| 6289 | specbind (intern ("read-file-name-predicate"), | ||
| 6290 | (NILP (predicate) ? Qfile_exists_p : predicate)); | ||
| 6291 | 6152 | ||
| 6292 | GCPRO2 (insdef, default_filename); | 6153 | GCPRO2 (insdef, default_filename); |
| 6293 | 6154 | args[0] = intern ("read-file-name"); | |
| 6294 | #if defined (USE_MOTIF) || defined (HAVE_NTGUI) || defined (USE_GTK) || defined (HAVE_CARBON) | 6155 | args[1] = prompt; |
| 6295 | if (! NILP (Fnext_read_file_uses_dialog_p ())) | 6156 | args[2] = dir; |
| 6296 | { | 6157 | args[3] = default_filename; |
| 6297 | /* If DIR contains a file name, split it. */ | 6158 | args[4] = mustmatch; |
| 6298 | Lisp_Object file; | 6159 | args[5] = initial; |
| 6299 | file = Ffile_name_nondirectory (dir); | 6160 | args[6] = predicate; |
| 6300 | if (SCHARS (file) && NILP (default_filename)) | 6161 | RETURN_UNGCPRO (Ffuncall (7, args)); |
| 6301 | { | ||
| 6302 | default_filename = file; | ||
| 6303 | dir = Ffile_name_directory (dir); | ||
| 6304 | } | ||
| 6305 | if (!NILP(default_filename)) | ||
| 6306 | default_filename = Fexpand_file_name (default_filename, dir); | ||
| 6307 | val = Fx_file_dialog (prompt, dir, default_filename, mustmatch, | ||
| 6308 | EQ (predicate, Qfile_directory_p) ? Qt : Qnil); | ||
| 6309 | add_to_history = 1; | ||
| 6310 | } | ||
| 6311 | else | ||
| 6312 | #endif | ||
| 6313 | val = Fcompleting_read (prompt, intern ("read-file-name-internal"), | ||
| 6314 | Qnil, mustmatch, insdef, | ||
| 6315 | Qfile_name_history, default_filename, Qnil); | ||
| 6316 | |||
| 6317 | tem = Fsymbol_value (Qfile_name_history); | ||
| 6318 | if (CONSP (tem) && EQ (XCAR (tem), val)) | ||
| 6319 | replace_in_history = 1; | ||
| 6320 | |||
| 6321 | /* If Fcompleting_read returned the inserted default string itself | ||
| 6322 | (rather than a new string with the same contents), | ||
| 6323 | it has to mean that the user typed RET with the minibuffer empty. | ||
| 6324 | In that case, we really want to return "" | ||
| 6325 | so that commands such as set-visited-file-name can distinguish. */ | ||
| 6326 | if (EQ (val, default_filename)) | ||
| 6327 | { | ||
| 6328 | /* In this case, Fcompleting_read has not added an element | ||
| 6329 | to the history. Maybe we should. */ | ||
| 6330 | if (! replace_in_history) | ||
| 6331 | add_to_history = 1; | ||
| 6332 | |||
| 6333 | val = empty_unibyte_string; | ||
| 6334 | } | ||
| 6335 | |||
| 6336 | unbind_to (count, Qnil); | ||
| 6337 | UNGCPRO; | ||
| 6338 | if (NILP (val)) | ||
| 6339 | error ("No file name specified"); | ||
| 6340 | |||
| 6341 | tem = Fstring_equal (val, CONSP (insdef) ? XCAR (insdef) : insdef); | ||
| 6342 | |||
| 6343 | if (!NILP (tem) && !NILP (default_filename)) | ||
| 6344 | val = default_filename; | ||
| 6345 | val = Fsubstitute_in_file_name (val); | ||
| 6346 | |||
| 6347 | if (replace_in_history) | ||
| 6348 | /* Replace what Fcompleting_read added to the history | ||
| 6349 | with what we will actually return. */ | ||
| 6350 | { | ||
| 6351 | Lisp_Object val1 = double_dollars (val); | ||
| 6352 | tem = Fsymbol_value (Qfile_name_history); | ||
| 6353 | if (history_delete_duplicates) | ||
| 6354 | XSETCDR (tem, Fdelete (val1, XCDR(tem))); | ||
| 6355 | XSETCAR (tem, val1); | ||
| 6356 | } | ||
| 6357 | else if (add_to_history) | ||
| 6358 | { | ||
| 6359 | /* Add the value to the history--but not if it matches | ||
| 6360 | the last value already there. */ | ||
| 6361 | Lisp_Object val1 = double_dollars (val); | ||
| 6362 | tem = Fsymbol_value (Qfile_name_history); | ||
| 6363 | if (! CONSP (tem) || NILP (Fequal (XCAR (tem), val1))) | ||
| 6364 | { | ||
| 6365 | if (history_delete_duplicates) tem = Fdelete (val1, tem); | ||
| 6366 | Fset (Qfile_name_history, Fcons (val1, tem)); | ||
| 6367 | } | ||
| 6368 | } | ||
| 6369 | |||
| 6370 | return val; | ||
| 6371 | } | 6162 | } |
| 6372 | 6163 | ||
| 6373 | 6164 | ||
| @@ -6488,8 +6279,6 @@ of file names regardless of the current language environment. */); | |||
| 6488 | 6279 | ||
| 6489 | Qformat_decode = intern ("format-decode"); | 6280 | Qformat_decode = intern ("format-decode"); |
| 6490 | staticpro (&Qformat_decode); | 6281 | staticpro (&Qformat_decode); |
| 6491 | Qdefault_directory = intern ("default-directory"); | ||
| 6492 | staticpro (&Qdefault_directory); | ||
| 6493 | Qformat_annotate_function = intern ("format-annotate-function"); | 6282 | Qformat_annotate_function = intern ("format-annotate-function"); |
| 6494 | staticpro (&Qformat_annotate_function); | 6283 | staticpro (&Qformat_annotate_function); |
| 6495 | Qafter_insert_file_set_coding = intern ("after-insert-file-set-coding"); | 6284 | Qafter_insert_file_set_coding = intern ("after-insert-file-set-coding"); |
| @@ -6513,45 +6302,6 @@ of file names regardless of the current language environment. */); | |||
| 6513 | Fput (Qfile_date_error, Qerror_message, | 6302 | Fput (Qfile_date_error, Qerror_message, |
| 6514 | build_string ("Cannot set file date")); | 6303 | build_string ("Cannot set file date")); |
| 6515 | 6304 | ||
| 6516 | DEFVAR_LISP ("read-file-name-function", &Vread_file_name_function, | ||
| 6517 | doc: /* If this is non-nil, `read-file-name' does its work by calling this function. */); | ||
| 6518 | Vread_file_name_function = Qnil; | ||
| 6519 | |||
| 6520 | DEFVAR_LISP ("read-file-name-predicate", &Vread_file_name_predicate, | ||
| 6521 | doc: /* Current predicate used by `read-file-name-internal'. */); | ||
| 6522 | Vread_file_name_predicate = Qnil; | ||
| 6523 | |||
| 6524 | DEFVAR_BOOL ("read-file-name-completion-ignore-case", &read_file_name_completion_ignore_case, | ||
| 6525 | doc: /* *Non-nil means when reading a file name completion ignores case. */); | ||
| 6526 | #if defined VMS || defined DOS_NT || defined MAC_OS | ||
| 6527 | read_file_name_completion_ignore_case = 1; | ||
| 6528 | #else | ||
| 6529 | read_file_name_completion_ignore_case = 0; | ||
| 6530 | #endif | ||
| 6531 | |||
| 6532 | DEFVAR_BOOL ("insert-default-directory", &insert_default_directory, | ||
| 6533 | doc: /* *Non-nil means when reading a filename start with default dir in minibuffer. | ||
| 6534 | |||
| 6535 | When the initial minibuffer contents show a name of a file or a directory, | ||
| 6536 | typing RETURN without editing the initial contents is equivalent to typing | ||
| 6537 | the default file name. | ||
| 6538 | |||
| 6539 | If this variable is non-nil, the minibuffer contents are always | ||
| 6540 | initially non-empty, and typing RETURN without editing will fetch the | ||
| 6541 | default name, if one is provided. Note however that this default name | ||
| 6542 | is not necessarily the same as initial contents inserted in the minibuffer, | ||
| 6543 | if the initial contents is just the default directory. | ||
| 6544 | |||
| 6545 | If this variable is nil, the minibuffer often starts out empty. In | ||
| 6546 | that case you may have to explicitly fetch the next history element to | ||
| 6547 | request the default name; typing RETURN without editing will leave | ||
| 6548 | the minibuffer empty. | ||
| 6549 | |||
| 6550 | For some commands, exiting with an empty minibuffer has a special meaning, | ||
| 6551 | such as making the current buffer visit no file in the case of | ||
| 6552 | `set-visited-file-name'. */); | ||
| 6553 | insert_default_directory = 1; | ||
| 6554 | |||
| 6555 | DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm, | 6305 | DEFVAR_BOOL ("vms-stmlf-recfm", &vms_stmlf_recfm, |
| 6556 | doc: /* *Non-nil means write new files with record format `stmlf'. | 6306 | doc: /* *Non-nil means write new files with record format `stmlf'. |
| 6557 | nil means use format `var'. This variable is meaningful only on VMS. */); | 6307 | nil means use format `var'. This variable is meaningful only on VMS. */); |
| @@ -6698,7 +6448,6 @@ A non-nil value may result in data loss! */); | |||
| 6698 | defsubr (&Sclear_buffer_auto_save_failure); | 6448 | defsubr (&Sclear_buffer_auto_save_failure); |
| 6699 | defsubr (&Srecent_auto_save_p); | 6449 | defsubr (&Srecent_auto_save_p); |
| 6700 | 6450 | ||
| 6701 | defsubr (&Sread_file_name); | ||
| 6702 | defsubr (&Snext_read_file_uses_dialog_p); | 6451 | defsubr (&Snext_read_file_uses_dialog_p); |
| 6703 | 6452 | ||
| 6704 | #ifdef HAVE_SYNC | 6453 | #ifdef HAVE_SYNC |