1 ;;; files.el --- file input and output commands for SXEmacs.
3 ;; Copyright (C) 1985-1987, 1992-1995, 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) 1995 Sun Microsystems.
6 ;; Maintainer: SXEmacs Development Team
7 ;; Keywords: extensions, dumped
9 ;; This file is part of SXEmacs.
11 ;; SXEmacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
16 ;; SXEmacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
24 ;;; Synched up with: FSF 20.3 (but diverging)
25 ;;; Warning: Merging this file is tough. Beware.
29 ;; This file is dumped with SXEmacs.
31 ;; Defines most of XEmacs's file- and directory-handling functions,
32 ;; including basic file visiting, backup generation, link handling,
33 ;; ITS-id version control, load- and write-hook handling, and the like.
37 ;; XEmacs: Avoid compilation warnings.
38 (defvar coding-system-for-read)
39 (defvar buffer-file-coding-system)
41 (globally-declare-fboundp '(dired-noselect dired)))
45 "Support editing files."
49 "Backups of edited data files."
52 (defgroup find-file nil
53 "Finding and editing files."
57 ;; XEmacs: In buffer.c
58 ;(defconst delete-auto-save-files t
59 ; "*Non-nil means delete auto-save file when a buffer is saved or killed.")
61 ;; FSF has automount-dir-prefix. Our directory-abbrev-alist is more general.
62 ;; note: tmp_mnt bogosity conversion is established in paths.el.
63 (defcustom directory-abbrev-alist nil
64 "*Alist of abbreviations for file directories.
65 A list of elements of the form (FROM . TO), each meaning to replace
66 FROM with TO when it appears in a directory name.
67 This replacement is done when setting up the default directory of a
68 newly visited file. *Every* FROM string should start with \\\\` or ^.
70 Use this feature when you have directories which you normally refer to
71 via absolute symbolic links or to eliminate automounter mount points
72 from the beginning of your filenames. Make TO the name of the link,
73 and FROM the name it is linked to."
74 :type '(repeat (cons :format "%v"
80 (defcustom make-backup-files t
81 "*Non-nil means make a backup of a file the first time it is saved.
82 This can be done by renaming the file or by copying.
84 Renaming means that XEmacs renames the existing file so that it is a
85 backup file, then writes the buffer into a new file. Any other names
86 that the old file had will now refer to the backup file. The new file
87 is owned by you and its group is defaulted.
89 Copying means that XEmacs copies the existing file into the backup
90 file, then writes the buffer on top of the existing file. Any other
91 names that the old file had will now refer to the new (edited) file.
92 The file's owner and group are unchanged.
94 The choice of renaming or copying is controlled by the variables
95 `backup-by-copying', `backup-by-copying-when-linked' and
96 `backup-by-copying-when-mismatch'. See also `backup-inhibited'."
100 ;; Do this so that local variables based on the file name
101 ;; are not overridden by the major mode.
102 (defvar backup-inhibited nil
103 "Non-nil means don't make a backup, regardless of the other parameters.
104 This variable is intended for use by making it local to a buffer.
105 But it is local only if you make it local.")
106 (put 'backup-inhibited 'permanent-local t)
108 (defcustom backup-by-copying nil
109 "*Non-nil means always use copying to create backup files.
110 See documentation of variable `make-backup-files'."
114 (defcustom backup-by-copying-when-linked nil
115 "*Non-nil means use copying to create backups for files with multiple names.
116 This causes the alternate names to refer to the latest version as edited.
117 This variable is relevant only if `backup-by-copying' is nil."
121 (defcustom backup-by-copying-when-mismatch nil
122 "*Non-nil means create backups by copying if this preserves owner or group.
123 Renaming may still be used (subject to control of other variables)
124 when it would not result in changing the owner or group of the file;
125 that is, for files which are owned by you and whose group matches
126 the default for a new file created there by you.
127 This variable is relevant only if `backup-by-copying' is nil."
131 (defvar backup-enable-predicate
134 (string-match "^/tmp/" name)
135 (let ((tmpdir (temp-directory)))
137 (string-match (concat "\\`" (regexp-quote tmpdir) "/")
139 "Predicate that looks at a file name and decides whether to make backups.
140 Called with an absolute file name as argument, it returns t to enable backup.")
142 (defcustom buffer-offer-save nil
143 "*Non-nil in a buffer means offer to save the buffer on exit
144 even if the buffer is not visiting a file.
145 Automatically local in all buffers."
148 (make-variable-buffer-local 'buffer-offer-save)
150 ;; FSF uses normal defconst
151 (defvaralias 'find-file-visit-truename 'find-file-use-truenames)
152 (defvaralias 'find-file-existing-other-name 'find-file-compare-truenames)
154 (defcustom revert-without-query nil
155 "*Specify which files should be reverted without query.
156 The value is a list of regular expressions.
157 If the file name matches one of these regular expressions,
158 then `revert-buffer' reverts the file without querying
159 if the file has changed on disk and you have not edited the buffer."
160 :type '(repeat (regexp ""))
163 (defvar buffer-file-number nil
164 "The device number and file number of the file visited in the current buffer.
165 The value is a list of the form (FILENUM DEVNUM).
166 This pair of numbers uniquely identifies the file.
167 If the buffer is visiting a new file, the value is nil.")
168 (make-variable-buffer-local 'buffer-file-number)
169 (put 'buffer-file-number 'permanent-local t)
171 (defvar buffer-file-numbers-unique (not (memq system-type '(windows-nt)))
172 "Non-nil means that buffer-file-number uniquely identifies files.")
174 (defcustom file-precious-flag nil
175 "*Non-nil means protect against I/O errors while saving files.
176 Some modes set this non-nil in particular buffers.
178 This feature works by writing the new contents into a temporary file
179 and then renaming the temporary file to replace the original.
180 In this way, any I/O error in writing leaves the original untouched,
181 and there is never any instant where the file is nonexistent.
183 Note that this feature forces backups to be made by copying.
184 Yet, at the same time, saving a precious file
185 breaks any hard links between it and other files."
189 (defcustom version-control nil
190 "*Control use of version numbers for backup files.
191 t means make numeric backup versions unconditionally.
192 nil means make them for files that have some already.
193 `never' means do not make them."
198 ;; This is now defined in efs.
199 ;(defvar dired-kept-versions 2
200 ; "*When cleaning directory, number of versions to keep.")
202 (defcustom delete-old-versions (when noninteractive 'leave)
203 "*If t, delete excess backup versions silently.
204 If nil, ask confirmation. Any other value prevents any trimming."
205 :type '(choice (const :tag "Delete" t)
206 (const :tag "Ask" nil)
207 (sexp :tag "Leave" :format "%t\n" other))
210 (defcustom kept-old-versions 2
211 "*Number of oldest versions to keep when a new numbered backup is made."
215 (defcustom kept-new-versions 2
216 "*Number of newest versions to keep when a new numbered backup is made.
217 Includes the new backup. Must be > 0"
221 (defcustom require-final-newline nil
222 "*Value of t says silently ensure a file ends in a newline when it is saved.
223 Non-nil but not t says ask user whether to add a newline when there isn't one.
224 nil means don't add newlines."
225 :type '(choice (const :tag "Off" nil)
227 (sexp :tag "Ask" :format "%t\n" ask))
228 :group 'editing-basics)
230 (defcustom auto-save-default t
231 "*Non-nil says by default do auto-saving of every file-visiting buffer."
235 (defcustom auto-save-visited-file-name nil
236 "*Non-nil says auto-save a buffer in the file it is visiting, when practical.
237 Normally auto-save files are written under other names."
241 (defcustom save-abbrevs nil
242 "*Non-nil means save word abbrevs too when files are saved.
243 Loading an abbrev file sets this to t."
247 (defcustom find-file-run-dired t
248 "*Non-nil says run dired if `find-file' is given the name of a directory."
252 ;;;It is not useful to make this a local variable.
253 ;;;(put 'find-file-not-found-hooks 'permanent-local t)
254 (defvar find-file-not-found-hooks nil
255 "List of functions to be called for `find-file' on nonexistent file.
256 These functions are called as soon as the error is detected.
257 `buffer-file-name' is already set up.
258 The functions are called in the order given until one of them returns non-nil.")
260 ;;;It is not useful to make this a local variable.
261 ;;;(put 'find-file-hooks 'permanent-local t)
262 (defvar find-file-hooks nil
263 "List of functions to be called after a buffer is loaded from a file.
264 The buffer's local variables (if any) will have been processed before the
265 functions are called.")
267 (defvar write-file-hooks nil
268 "List of functions to be called before writing out a buffer to a file.
269 If one of them returns non-nil, the file is considered already written
270 and the rest are not called.
271 These hooks are considered to pertain to the visited file.
272 So this list is cleared if you change the visited file name.
273 See also `write-contents-hooks' and `continue-save-buffer'.")
274 ;;; However, in case someone does make it local...
275 (put 'write-file-hooks 'permanent-local t)
277 (defvar local-write-file-hooks nil
278 "Just like `write-file-hooks', except intended for per-buffer use.
279 The functions in this list are called before the ones in
282 This variable is meant to be used for hooks that have to do with a
283 particular visited file. Therefore, it is a permanent local, so that
284 changing the major mode does not clear it. However, calling
285 `set-visited-file-name' does clear it.")
286 (make-variable-buffer-local 'local-write-file-hooks)
287 (put 'local-write-file-hooks 'permanent-local t)
290 ;; #### think about this (added by Sun).
291 (put 'after-set-visited-file-name-hooks 'permanent-local t)
292 (defvar after-set-visited-file-name-hooks nil
293 "List of functions to be called after \\[set-visited-file-name]
294 or during \\[write-file].
295 You can use this hook to restore local values of `write-file-hooks',
296 `after-save-hook', and `revert-buffer-function', which pertain
297 to a specific file and therefore are normally killed by a rename.
298 Put hooks pertaining to the buffer contents on `write-contents-hooks'
299 and `revert-buffer-insert-file-contents-function'.")
301 (defvar write-contents-hooks nil
302 "List of functions to be called before writing out a buffer to a file.
303 If one of them returns non-nil, the file is considered already written
304 and the rest are not called.
305 These hooks are considered to pertain to the buffer's contents,
306 not to the particular visited file; thus, `set-visited-file-name' does
307 not clear this variable, but changing the major mode does clear it.
308 See also `write-file-hooks' and `continue-save-buffer'.")
311 ;; Energize needed this to hook into save-buffer at a lower level; we need
312 ;; to provide a new output method, but don't want to have to duplicate all
313 ;; of the backup file and file modes logic.that does not occur if one uses
314 ;; a write-file-hook which returns non-nil.
315 (put 'write-file-data-hooks 'permanent-local t)
316 (defvar write-file-data-hooks nil
317 "List of functions to be called to put the bytes on disk.
318 These functions receive the name of the file to write to as argument.
319 The default behavior is to call
320 (write-region (point-min) (point-max) filename nil t)
321 If one of them returns non-nil, the file is considered already written
322 and the rest are not called.
323 These hooks are considered to pertain to the visited file.
324 So this list is cleared if you change the visited file name.
325 See also `write-file-hooks'.")
327 (defcustom enable-local-variables t
328 "*Control use of local-variables lists in files you visit.
329 The value can be t, nil or something else.
330 A value of t means local-variables lists are obeyed;
331 nil means they are ignored; anything else means query.
333 The command \\[normal-mode] always obeys local-variables lists
334 and ignores this variable."
335 :type '(choice (const :tag "Obey" t)
336 (const :tag "Ignore" nil)
337 (sexp :tag "Query" :format "%t\n" other))
340 (defcustom enable-local-eval 'maybe
341 "*Control processing of the \"variable\" `eval' in a file's local variables.
342 The value can be t, nil or something else.
343 A value of t means obey `eval' variables;
344 nil means ignore them; anything else means query.
346 The command \\[normal-mode] always obeys local-variables lists
347 and ignores this variable."
348 :type '(choice (const :tag "Obey" t)
349 (const :tag "Ignore" nil)
350 (sexp :tag "Query" :format "%t\n" other))
354 (defcustom find-file-magic-files-alist
355 '((file-directory-p . find-file-try-dired-noselect))
356 "Alist where each element is in form \(PREDICATE . FUNCTION-OF-ONE-ARGUMENT\).
357 FUNCTION-OF-ONE-ARGUMENT must return some buffer."
361 ;; Avoid losing in versions where CLASH_DETECTION is disabled.
362 (or (fboundp 'lock-buffer)
363 (defalias 'lock-buffer 'ignore))
364 (or (fboundp 'unlock-buffer)
365 (defalias 'unlock-buffer 'ignore))
367 ;;FSFmacs bastardized ange-ftp cruft
368 ;; This hook function provides support for ange-ftp host name
369 ;; completion. It runs the usual ange-ftp hook, but only for
370 ;; completion operations. Having this here avoids the need
371 ;; to load ange-ftp when it's not really in use.
372 ;(defun ange-ftp-completion-hook-function (op &rest args)
373 ; (if (memq op '(file-name-completion file-name-all-completions))
374 ; (apply 'ange-ftp-hook-function op args)
375 ; (let ((inhibit-file-name-handlers
376 ; (cons 'ange-ftp-completion-hook-function
377 ; (and (eq inhibit-file-name-operation op)
378 ; inhibit-file-name-handlers)))
379 ; (inhibit-file-name-operation op))
382 (defun convert-standard-filename (filename)
383 "Convert a standard file's name to something suitable for the current OS."
384 (if (eq system-type 'windows-nt)
385 (let ((name (copy-sequence filename))
387 ;; leave ':' if part of drive specifier
388 (if (and (> (length name) 1)
389 (eq (aref name 1) ?:))
391 ;; destructively replace invalid filename characters with !
392 (while (string-match "[?*:<>|\"\000-\037]" name start)
393 (aset name (match-beginning 0) ?!)
394 (setq start (match-end 0)))
395 ;; FSF: [convert directory separators to Windows format ...]
396 ;; unneeded in XEmacs.
402 "Show the current default directory."
404 (message "Directory %s" default-directory))
407 "Value of the CDPATH environment variable, as a list.
408 Not actually set up until the first time you use it.")
410 (defvar cdpath-previous nil
411 "Prior value of the CDPATH environment variable.")
413 (defun parse-colon-path (cd-path)
414 "Explode a colon-separated search path into a list of directory names.
416 If you think you want to use this, you probably don't. This function
417 is provided for backward compatibility. A more robust implementation
418 of the same functionality is available as `split-path', which see."
420 (let (cd-list (cd-start 0) cd-colon)
421 (setq cd-path (concat cd-path path-separator))
422 (while (setq cd-colon (string-match path-separator cd-path cd-start))
425 (list (if (= cd-start cd-colon)
427 (substitute-in-file-name
428 (file-name-as-directory
429 (substring cd-path cd-start cd-colon)))))))
430 (setq cd-start (+ cd-colon 1)))
433 (defun cd-absolute (dir)
434 "Change current directory to given absolute file name DIR."
435 ;; Put the name into directory syntax now,
436 ;; because otherwise expand-file-name may give some bad results.
437 (setq dir (file-name-as-directory dir))
438 ;; XEmacs change: stig@hackvan.com
439 (if find-file-use-truenames
440 (setq dir (file-truename dir)))
441 (setq dir (abbreviate-file-name (expand-file-name dir)))
442 (cond ((not (file-directory-p dir))
443 (error "%s is not a directory" dir))
444 ;; this breaks ange-ftp, which doesn't (can't?) overload `file-executable-p'.
445 ;;((not (file-executable-p dir))
446 ;; (error "Cannot cd to %s: Permission denied" dir))
448 (setq default-directory dir))))
451 "Make DIR become the current buffer's default directory.
452 If your environment includes a `CDPATH' variable, try each one of that
453 colon-separated list of directories when resolving a relative directory name."
455 ;; XEmacs change? (read-file-name => read-directory-name)
456 (list (read-directory-name "Change default directory: "
457 default-directory default-directory
458 (and (member cd-path '(nil ("./")))
459 (null (getenv "CDPATH"))))))
460 (if (file-name-absolute-p dir)
461 (cd-absolute (expand-file-name dir))
463 (unless (and cd-path (equal (getenv "CDPATH") cdpath-previous))
465 (let ((trypath (parse-colon-path
466 (setq cdpath-previous (getenv "CDPATH")))))
467 (setq cd-path (or trypath (list "./")))))
469 (mapcar #'(lambda (x)
470 (let ((f (expand-file-name (concat x dir))))
471 (if (file-directory-p f)
477 ;; jwz: give a better error message to those of us with the
478 ;; good taste not to use a kludge like $CDPATH.
479 (if (equal cd-path '("./"))
480 (error "No such directory: %s" (expand-file-name dir))
481 (error "Directory not found in $CDPATH: %s" dir)))))
483 (defun load-file (file)
484 "Load the Lisp file named FILE."
485 (interactive "fLoad file: ")
486 (load (expand-file-name file) nil nil t))
488 ; We now dump utils/lib-complete.el which has improved versions of this.
489 ;(defun load-library (library)
490 ; "Load the library named LIBRARY.
491 ;This is an interface to the function `load'."
492 ; (interactive "sLoad library: ")
495 ;(defun find-library (library)
496 ; "Find the library of Lisp code named LIBRARY.
497 ;This searches `load-path' for a file named either \"LIBRARY\" or \"LIBRARY.el\"."
498 ; (interactive "sFind library file: ")
499 ; (let ((f (locate-file library load-path ":.el:")))
502 ; (error "Couldn't locate library %s" library))))
504 (defun file-local-copy (file &optional buffer)
505 "Copy the file FILE into a temporary file on this machine.
506 Returns the name of the local copy, or nil, if FILE is directly
508 (let ((handler (find-file-name-handler file 'file-local-copy)))
510 (funcall handler 'file-local-copy file)
513 ;; XEmacs change block
514 ; We have this in C and use the realpath() system call.
516 ;(defun file-truename (filename &optional counter prev-dirs)
517 ; [... lots of code snipped ...]
520 ;; XEmacs addition. Called from `insert-file-contents-internal'
521 ;; at the appropriate time.
522 (defun compute-buffer-file-truename (&optional buffer)
523 "Recompute BUFFER's value of `buffer-file-truename'
524 based on the current value of `buffer-file-name'.
525 BUFFER defaults to the current buffer if unspecified."
527 (set-buffer (or buffer (current-buffer)))
528 (cond ((null buffer-file-name)
529 (setq buffer-file-truename nil))
530 ((setq buffer-file-truename (file-truename buffer-file-name))
531 ;; it exists, we're done.
534 ;; the file doesn't exist, but maybe the directory does.
535 (let* ((dir (file-name-directory buffer-file-name))
536 (truedir (file-truename dir)))
537 (if truedir (setq dir truedir))
538 (setq buffer-file-truename
539 (expand-file-name (file-name-nondirectory buffer-file-name)
541 (if (and find-file-use-truenames buffer-file-truename)
542 (setq buffer-file-name (abbreviate-file-name buffer-file-truename)
543 default-directory (file-name-directory buffer-file-name)))
544 buffer-file-truename))
545 ;; End XEmacs change block
547 (defun file-chase-links (filename)
548 "Chase links in FILENAME until a name that is not a link.
549 Does not examine containing directories for links,
550 unlike `file-truename'."
551 (let (tem (count 100) (newname filename))
552 (while (setq tem (file-symlink-p newname))
555 (error "Apparent cycle of symbolic links for %s" filename))
556 ;; In the context of a link, `//' doesn't mean what XEmacs thinks.
557 (while (string-match "//+" tem)
558 (setq tem (concat (substring tem 0 (1+ (match-beginning 0)))
559 (substring tem (match-end 0)))))
560 ;; Handle `..' by hand, since it needs to work in the
561 ;; target of any directory symlink.
562 ;; This code is not quite complete; it does not handle
563 ;; embedded .. in some cases such as ./../foo and foo/bar/../../../lose.
564 (while (string-match #r"\`\.\./" tem) ;#### Unix specific
565 (setq tem (substring tem 3))
566 (setq newname (file-name-as-directory
567 ;; Do the .. by hand.
570 ;; Chase links in the default dir of the symlink.
573 (file-name-directory newname))))))))
574 (setq newname (expand-file-name tem (file-name-directory newname)))
575 (setq count (1- count))))
578 (defun switch-to-other-buffer (arg)
579 "Switch to the previous buffer. With a numeric arg, n, switch to the nth
580 most recent buffer. With an arg of 0, buries the current buffer at the
581 bottom of the buffer stack."
584 (bury-buffer (current-buffer)))
586 (if (<= arg 1) (other-buffer (current-buffer))
587 (nth (1+ arg) (buffer-list)))))
589 (defun switch-to-buffer-other-window (buffer)
590 "Select buffer BUFFER in another window."
591 (interactive "BSwitch to buffer in other window: ")
592 (let ((pop-up-windows t))
593 ;; XEmacs: this used to have (selected-frame) as the third argument,
594 ;; but this is obnoxious. If the user wants the buffer in a
595 ;; different frame, then it should be this way.
597 ;; Change documented above undone --mrb
598 (pop-to-buffer buffer t (selected-frame))))
600 (defun switch-to-buffer-other-frame (buffer)
601 "Switch to buffer BUFFER in a newly-created frame."
602 (interactive "BSwitch to buffer in other frame: ")
603 (let* ((name (get-frame-name-for-buffer buffer))
604 (frame (make-frame (if name
605 (list (cons 'name (symbol-name name)))))))
606 (pop-to-buffer buffer t frame)
607 (make-frame-visible frame)
610 (defun find-file (filename &optional codesys)
612 Switch to a buffer visiting file FILENAME,
613 creating one if none already exists.
614 Under XEmacs/Mule, optional second argument specifies the
615 coding system to use when decoding the file. Interactively,
616 with a prefix argument, you will be prompted for the coding system."
617 (interactive "FFind file: \nZCoding system: ")
619 (let ((coding-system-for-read
620 (get-coding-system codesys)))
621 (switch-to-buffer (find-file-noselect filename)))
622 (switch-to-buffer (find-file-noselect filename))))
624 (defun find-file-other-window (filename &optional codesys)
625 "Edit file FILENAME, in another window.
626 May create a new window, or reuse an existing one.
627 See the function `display-buffer'.
628 Under XEmacs/Mule, optional second argument specifies the
629 coding system to use when decoding the file. Interactively,
630 with a prefix argument, you will be prompted for the coding system."
631 (interactive "FFind file in other window: \nZCoding system: ")
633 (let ((coding-system-for-read
634 (get-coding-system codesys)))
635 (switch-to-buffer-other-window (find-file-noselect filename)))
636 (switch-to-buffer-other-window (find-file-noselect filename))))
638 (defun find-file-other-frame (filename &optional codesys)
639 "Edit file FILENAME, in a newly-created frame.
640 Under XEmacs/Mule, optional second argument specifies the
641 coding system to use when decoding the file. Interactively,
642 with a prefix argument, you will be prompted for the coding system."
643 (interactive "FFind file in other frame: \nZCoding system: ")
645 (let ((coding-system-for-read
646 (get-coding-system codesys)))
647 (switch-to-buffer-other-frame (find-file-noselect filename)))
648 (switch-to-buffer-other-frame (find-file-noselect filename))))
650 (defun find-file-read-only (filename &optional codesys)
651 "Edit file FILENAME but don't allow changes.
652 Like \\[find-file] but marks buffer as read-only.
653 Use \\[toggle-read-only] to permit editing.
654 Under XEmacs/Mule, optional second argument specifies the
655 coding system to use when decoding the file. Interactively,
656 with a prefix argument, you will be prompted for the coding system."
657 (interactive "fFind file read-only: \nZCoding system: ")
659 (let ((coding-system-for-read
660 (get-coding-system codesys)))
661 (find-file filename))
662 (find-file filename))
663 (setq buffer-read-only t)
666 (defun find-file-read-only-other-window (filename &optional codesys)
667 "Edit file FILENAME in another window but don't allow changes.
668 Like \\[find-file-other-window] but marks buffer as read-only.
669 Use \\[toggle-read-only] to permit editing.
670 Under XEmacs/Mule, optional second argument specifies the
671 coding system to use when decoding the file. Interactively,
672 with a prefix argument, you will be prompted for the coding system."
673 (interactive "fFind file read-only other window: \nZCoding system: ")
675 (let ((coding-system-for-read
676 (get-coding-system codesys)))
677 (find-file-other-window filename))
678 (find-file-other-window filename))
679 (setq buffer-read-only t)
682 (defun find-file-read-only-other-frame (filename &optional codesys)
683 "Edit file FILENAME in another frame but don't allow changes.
684 Like \\[find-file-other-frame] but marks buffer as read-only.
685 Use \\[toggle-read-only] to permit editing.
686 Under XEmacs/Mule, optional second argument specifies the
687 coding system to use when decoding the file. Interactively,
688 with a prefix argument, you will be prompted for the coding system."
689 (interactive "fFind file read-only other frame: \nZCoding system: ")
691 (let ((coding-system-for-read
692 (get-coding-system codesys)))
693 (find-file-other-frame filename))
694 (find-file-other-frame filename))
695 (setq buffer-read-only t)
698 (defun find-alternate-file-other-window (filename &optional codesys)
699 "Find file FILENAME as a replacement for the file in the next window.
700 This command does not select that window.
701 Under XEmacs/Mule, optional second argument specifies the
702 coding system to use when decoding the file. Interactively,
703 with a prefix argument, you will be prompted for the coding system."
705 (save-selected-window
707 (let ((file buffer-file-name)
711 (setq file-name (file-name-nondirectory file)
712 file-dir (file-name-directory file)))
713 (list (read-file-name
714 "Find alternate file: " file-dir nil nil file-name)
715 (if (and current-prefix-arg (featurep 'mule))
716 (read-coding-system "Coding-system: "))))))
718 (find-file-other-window filename)
719 (save-selected-window
721 (find-alternate-file filename codesys))))
723 (defun find-alternate-file (filename &optional codesys)
724 "Find file FILENAME, select its buffer, kill previous buffer.
725 If the current buffer now contains an empty file that you just visited
726 \(presumably by mistake), use this command to visit the file you really want.
727 Under XEmacs/Mule, optional second argument specifies the
728 coding system to use when decoding the file. Interactively,
729 with a prefix argument, you will be prompted for the coding system."
731 (let ((file buffer-file-name)
735 (setq file-name (file-name-nondirectory file)
736 file-dir (file-name-directory file)))
737 (list (read-file-name
738 "Find alternate file: " file-dir nil nil file-name)
739 (if (and current-prefix-arg (featurep 'mule))
740 (read-coding-system "Coding-system: ")))))
741 (and (buffer-modified-p) (buffer-file-name)