comparison lisp/prim/files.el @ 4:b82b59fe008d r19-15b3

Import from CVS: tag r19-15b3
author cvs
date Mon, 13 Aug 2007 08:46:56 +0200
parents ac2d302a0011
children 27bc7f280385
comparison
equal deleted inserted replaced
3:30df88044ec6 4:b82b59fe008d
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 ;; General Public License for more details. 16 ;; General Public License for more details.
17 17
18 ;; You should have received a copy of the GNU General Public License 18 ;; You should have received a copy of the GNU General Public License
19 ;; along with XEmacs; see the file COPYING. If not, write to the Free 19 ;; along with XEmacs; see the file COPYING. If not, write to the Free
20 ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 20 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
21 21 ;; 02111-1307, USA.
22 ;;; Synched up with: FSF 19.30. 22
23 ;;; Synched up with: FSF 19.34 [Partial].
23 ;;; Warning: Merging this file is tough. Beware. 24 ;;; Warning: Merging this file is tough. Beware.
24 25
25 ;;; Commentary: 26 ;;; Commentary:
26 27
27 ;; Defines most of XEmacs's file- and directory-handling functions, 28 ;; Defines most of XEmacs's file- and directory-handling functions,
28 ;; including basic file visiting, backup generation, link handling, 29 ;; including basic file visiting, backup generation, link handling,
29 ;; ITS-id version control, load- and write-hook handling, and the like. 30 ;; ITS-id version control, load- and write-hook handling, and the like.
30 31
31 ;;; Code: 32 ;;; Code:
32 33
33 ;; Avoid compilation warnings. 34 ;; XEmacs: Avoid compilation warnings.
34 (defvar overriding-file-coding-system) 35 (defvar overriding-file-coding-system)
35 (defvar file-coding-system) 36 (defvar file-coding-system)
36 37
37 ;; In buffer.c 38 ;; XEmacs: In buffer.c
38 ;(defconst delete-auto-save-files t 39 ;(defconst delete-auto-save-files t
39 ; "*Non-nil means delete auto-save file when a buffer is saved or killed.") 40 ; "*Non-nil means delete auto-save file when a buffer is saved or killed.")
41
42 ;; FSF has automount-dir-prefix. Our directory-abbrev-alist is more general.
43 ;; note: tmp_mnt bogosity conversion is established in paths.el.
44 (defvar directory-abbrev-alist nil
45 "*Alist of abbreviations for file directories.
46 A list of elements of the form (FROM . TO), each meaning to replace
47 FROM with TO when it appears in a directory name.
48 This replacement is done when setting up the default directory of a
49 newly visited file. *Every* FROM string should start with \\\\` or ^.
50
51 Use this feature when you have directories which you normally refer to
52 via absolute symbolic links or to eliminate automounter mount points
53 from the beginning of your filenames. Make TO the name of the link,
54 and FROM the name it is linked to.")
40 55
41 ;;; Turn off backup files on VMS since it has version numbers. 56 ;;; Turn off backup files on VMS since it has version numbers.
42 (defconst make-backup-files (not (eq system-type 'vax-vms)) 57 (defconst make-backup-files (not (eq system-type 'vax-vms))
43 "*Non-nil means make a backup of a file the first time it is saved. 58 "*Non-nil means make a backup of a file the first time it is saved.
44 This can be done by renaming the file or by copying. 59 This can be done by renaming the file or by copying.
93 "*Non-nil in a buffer means offer to save the buffer on exit 108 "*Non-nil in a buffer means offer to save the buffer on exit
94 even if the buffer is not visiting a file. 109 even if the buffer is not visiting a file.
95 Automatically local in all buffers.") 110 Automatically local in all buffers.")
96 (make-variable-buffer-local 'buffer-offer-save) 111 (make-variable-buffer-local 'buffer-offer-save)
97 112
113 ;; FSF uses normal defconst
98 (defvaralias 'find-file-visit-truename 'find-file-use-truenames) 114 (defvaralias 'find-file-visit-truename 'find-file-use-truenames)
99 (defvaralias 'find-file-existing-other-name 'find-file-compare-truenames) 115 (defvaralias 'find-file-existing-other-name 'find-file-compare-truenames)
100 116
101 (defvar buffer-file-number nil 117 (defvar buffer-file-number nil
102 "The device number and file number of the file visited in the current buffer. 118 "The device number and file number of the file visited in the current buffer.
104 This pair of numbers uniquely identifies the file. 120 This pair of numbers uniquely identifies the file.
105 If the buffer is visiting a new file, the value is nil.") 121 If the buffer is visiting a new file, the value is nil.")
106 (make-variable-buffer-local 'buffer-file-number) 122 (make-variable-buffer-local 'buffer-file-number)
107 (put 'buffer-file-number 'permanent-local t) 123 (put 'buffer-file-number 'permanent-local t)
108 124
125 (defvar buffer-file-numbers-unique (not (memq system-type '(windows-nt)))
126 "Non-nil means that buffer-file-number uniquely identifies files.")
127
109 (defconst file-precious-flag nil 128 (defconst file-precious-flag nil
110 "*Non-nil means protect against I/O errors while saving files. 129 "*Non-nil means protect against I/O errors while saving files.
111 Some modes set this non-nil in particular buffers. 130 Some modes set this non-nil in particular buffers.
112 131
113 This feature works by writing the new contents into a temporary file 132 This feature works by writing the new contents into a temporary file
177 "List of functions to be called before writing out a buffer to a file. 196 "List of functions to be called before writing out a buffer to a file.
178 If one of them returns non-nil, the file is considered already written 197 If one of them returns non-nil, the file is considered already written
179 and the rest are not called. 198 and the rest are not called.
180 These hooks are considered to pertain to the visited file. 199 These hooks are considered to pertain to the visited file.
181 So this list is cleared if you change the visited file name. 200 So this list is cleared if you change the visited file name.
182 See also `write-contents-hooks' and `continue-save-buffer'. 201
183 Don't make this variable buffer-local; instead, use `local-write-file-hooks'.") 202 Don't make this variable buffer-local; instead, use `local-write-file-hooks'.
203 See also `write-contents-hooks' and `continue-save-buffer'.")
184 ;;; However, in case someone does make it local... 204 ;;; However, in case someone does make it local...
185 (put 'write-file-hooks 'permanent-local t) 205 (put 'write-file-hooks 'permanent-local t)
186 206
187 (defvar local-write-file-hooks nil 207 (defvar local-write-file-hooks nil
188 "Just like `write-file-hooks', except intended for per-buffer use. 208 "Just like `write-file-hooks', except intended for per-buffer use.
189 The functions in this list are called before the ones in 209 The functions in this list are called before the ones in
190 `write-file-hooks'.") 210 `write-file-hooks'.
211
212 This variable is meant to be used for hooks that have to do with a
213 particular visited file. Therefore, it is a permanent local, so that
214 changing the major mode does not clear it. However, calling
215 `set-visited-file-name' does clear it.")
191 (make-variable-buffer-local 'local-write-file-hooks) 216 (make-variable-buffer-local 'local-write-file-hooks)
192 (put 'local-write-file-hooks 'permanent-local t) 217 (put 'local-write-file-hooks 'permanent-local t)
193 218
194 219
195 ;; #### think about this (added by Sun). 220 ;; XEmacs: #### think about this (added by Sun).
196 (put 'after-set-visited-file-name-hooks 'permanent-local t) 221 (put 'after-set-visited-file-name-hooks 'permanent-local t)
197 (defvar after-set-visited-file-name-hooks nil 222 (defvar after-set-visited-file-name-hooks nil
198 "List of functions to be called after \\[set-visited-file-name] 223 "List of functions to be called after \\[set-visited-file-name]
199 or during \\[write-file]. 224 or during \\[write-file].
200 You can use this hook to restore local values of write-file-hooks, 225 You can use this hook to restore local values of write-file-hooks,
209 and the rest are not called. 234 and the rest are not called.
210 These hooks are considered to pertain to the buffer's contents, 235 These hooks are considered to pertain to the buffer's contents,
211 not to the particular visited file; thus, `set-visited-file-name' does 236 not to the particular visited file; thus, `set-visited-file-name' does
212 not clear this variable, but changing the major mode does clear it. 237 not clear this variable, but changing the major mode does clear it.
213 See also `write-file-hooks' and `continue-save-buffer'.") 238 See also `write-file-hooks' and `continue-save-buffer'.")
214 239 ;(make-variable-buffer-local 'write-contents-hooks)
215 ;; Not in FSF19 240
241 ;; XEmacs addition
216 ;; Energize needed this to hook into save-buffer at a lower level; we need 242 ;; Energize needed this to hook into save-buffer at a lower level; we need
217 ;; to provide a new output method, but don't want to have to duplicate all 243 ;; to provide a new output method, but don't want to have to duplicate all
218 ;; of the backup file and file modes logic.that does not occur if one uses 244 ;; of the backup file and file modes logic.that does not occur if one uses
219 ;; a write-file-hook which returns non-nil. 245 ;; a write-file-hook which returns non-nil.
220 (put 'write-file-data-hooks 'permanent-local t) 246 (put 'write-file-data-hooks 'permanent-local t)
244 A value of t means obey `eval' variables; 270 A value of t means obey `eval' variables;
245 nil means ignore them; anything else means query. 271 nil means ignore them; anything else means query.
246 272
247 The command \\[normal-mode] always obeys local-variables lists 273 The command \\[normal-mode] always obeys local-variables lists
248 and ignores this variable.") 274 and ignores this variable.")
249
250 (defvar hack-local-variables-hook nil
251 "Normal hook run after processing a file's local variables specs.
252 Major modes can use this to examine user-specified local variables
253 in order to initialize other data structure based on them.
254
255 This hook runs even if there were no local variables or if their
256 evaluation was suppressed. See also `enable-local-variables' and
257 `enable-local-eval'.")
258 275
259 ;; Avoid losing in versions where CLASH_DETECTION is disabled. 276 ;; Avoid losing in versions where CLASH_DETECTION is disabled.
260 (or (fboundp 'lock-buffer) 277 (or (fboundp 'lock-buffer)
261 (defalias 'lock-buffer 'ignore)) 278 (defalias 'lock-buffer 'ignore))
262 (or (fboundp 'unlock-buffer) 279 (or (fboundp 'unlock-buffer)
297 "Character used to separate concatenated paths.") 314 "Character used to separate concatenated paths.")
298 315
299 (defun parse-colon-path (cd-path) 316 (defun parse-colon-path (cd-path)
300 "Explode a colon-separated list of paths into a string list." 317 "Explode a colon-separated list of paths into a string list."
301 (and cd-path 318 (and cd-path
302 (let (cd-list (cd-start 0) cd-colon) 319 (let (cd-prefix cd-list (cd-start 0) cd-colon)
303 (setq cd-path (concat cd-path path-separator)) 320 (setq cd-path (concat cd-path path-separator))
304 (while (setq cd-colon (string-match path-separator cd-path cd-start)) 321 (while (setq cd-colon (string-match path-separator cd-path cd-start))
305 (setq cd-list 322 (setq cd-list
306 (nconc cd-list 323 (nconc cd-list
307 (list (if (= cd-start cd-colon) 324 (list (if (= cd-start cd-colon)
332 349
333 (defun cd (dir) 350 (defun cd (dir)
334 "Make DIR become the current buffer's default directory. 351 "Make DIR become the current buffer's default directory.
335 If your environment includes a `CDPATH' variable, try each one of that 352 If your environment includes a `CDPATH' variable, try each one of that
336 colon-separated list of directories when resolving a relative directory name." 353 colon-separated list of directories when resolving a relative directory name."
337 ; (interactive "DChange default directory: ")
338 (interactive 354 (interactive
339 ;; XEmacs change? 355 ;; XEmacs change? (read-file-name => read-directory-name)
340 (list (read-directory-name "Change default directory: " 356 (list (read-directory-name "Change default directory: "
341 default-directory default-directory 357 default-directory default-directory
342 (and (member cd-path '(nil ("./"))) 358 (and (member cd-path '(nil ("./")))
343 (null (getenv "CDPATH")))))) 359 (null (getenv "CDPATH"))))))
344 (if (file-name-absolute-p dir) 360 (if (file-name-absolute-p dir)
345 (cd-absolute (expand-file-name dir)) 361 (cd-absolute (expand-file-name dir))
346 (progn 362 ;; XEmacs
347 (if (null cd-path) 363 (if (null cd-path)
348 ;;#### Unix-specific 364 ;;#### Unix-specific
349 (let ((trypath (parse-colon-path (getenv "CDPATH")))) 365 (let ((trypath (parse-colon-path (getenv "CDPATH"))))
350 (setq cd-path (or trypath (list "./"))))) 366 (setq cd-path (or trypath (list "./")))))
351 (or (catch 'found 367 (or (catch 'found
352 (mapcar #'(lambda (x) 368 (mapcar #'(lambda (x)
353 (let ((f (expand-file-name (concat x dir)))) 369 (let ((f (expand-file-name (concat x dir))))
354 (if (file-directory-p f) 370 (if (file-directory-p f)
355 (progn 371 (progn
356 (cd-absolute f) 372 (cd-absolute f)
357 (throw 'found t))))) 373 (throw 'found t)))))
359 nil) 375 nil)
360 ;; jwz: give a better error message to those of us with the 376 ;; jwz: give a better error message to those of us with the
361 ;; good taste not to use a kludge like $CDPATH. 377 ;; good taste not to use a kludge like $CDPATH.
362 (if (equal cd-path '("./")) 378 (if (equal cd-path '("./"))
363 (error "No such directory: %s" (expand-file-name dir)) 379 (error "No such directory: %s" (expand-file-name dir))
364 (error "Directory not found in $CDPATH: %s" dir)))))) 380 (error "Directory not found in $CDPATH: %s" dir)))))
365 381
366 (defun load-file (file) 382 (defun load-file (file)
367 "Load the Lisp file named FILE." 383 "Load the Lisp file named FILE."
368 (interactive "fLoad file: ") 384 (interactive "fLoad file: ")
369 (load (expand-file-name file) nil nil t)) 385 (load (expand-file-name file) nil nil t))
370 386
371 ; We now dump utils/lib-complete.el which has improved versions of these. 387 ; We now dump utils/lib-complete.el which has an improved version of this.
372 ;(defun load-library (library) 388 ;(defun load-library (library)
373 ; "Load the library named LIBRARY. 389 ; "Load the library named LIBRARY.
374 ;This is an interface to the function `load'." 390 ;This is an interface to the function `load'."
375 ; (interactive "sLoad library: ") 391 ; (interactive "sLoad library: ")
376 ; (load library)) 392 ; (load library))
377 ;
378 ;(defun find-library (library)
379 ; "Find the library of Lisp code named LIBRARY.
380 ;This searches `load-path' for a file named either \"LIBRARY\" or \"LIBRARY.el\"."
381 ; (interactive "sFind library file: ")
382 ; (let ((f (locate-file library load-path ":.el:")))
383 ; (if f
384 ; (find-file f)
385 ; (error "Couldn't locate library %s" library))))
386 393
387 (defun file-local-copy (file &optional buffer) 394 (defun file-local-copy (file &optional buffer)
388 "Copy the file FILE into a temporary file on this machine. 395 "Copy the file FILE into a temporary file on this machine.
389 Returns the name of the local copy, or nil, if FILE is directly 396 Returns the name of the local copy, or nil, if FILE is directly
390 accessible." 397 accessible."
391 (let ((handler (find-file-name-handler file 'file-local-copy))) 398 (let ((handler (find-file-name-handler file 'file-local-copy)))
392 (if handler 399 (if handler
393 (funcall handler 'file-local-copy file) 400 (funcall handler 'file-local-copy file)
394 nil))) 401 nil)))
395 402
403 ;; XEmacs change block
396 ; We have this in C and use the realpath() system call. 404 ; We have this in C and use the realpath() system call.
397 405
398 ;(defun file-truename (filename &optional counter prev-dirs) 406 ;(defun file-truename (filename &optional counter prev-dirs)
399 ; "Return the truename of FILENAME, which should be absolute. 407 ; "Return the truename of FILENAME, which should be absolute.
400 ;The truename of a file name is found by chasing symbolic links 408 ;The truename of a file name is found by chasing symbolic links
500 dir))))) 508 dir)))))
501 (if (and find-file-use-truenames buffer-file-truename) 509 (if (and find-file-use-truenames buffer-file-truename)
502 (setq buffer-file-name (abbreviate-file-name buffer-file-truename) 510 (setq buffer-file-name (abbreviate-file-name buffer-file-truename)
503 default-directory (file-name-directory buffer-file-name))) 511 default-directory (file-name-directory buffer-file-name)))
504 buffer-file-truename)) 512 buffer-file-truename))
513 ;; End XEmacs change block
505 514
506 (defun file-chase-links (filename) 515 (defun file-chase-links (filename)
507 "Chase links in FILENAME until a name that is not a link. 516 "Chase links in FILENAME until a name that is not a link.
508 Does not examine containing directories for links, 517 Does not examine containing directories for links,
509 unlike `file-truename'." 518 unlike `file-truename'."
556 (pop-to-buffer buffer t (selected-frame)))) 565 (pop-to-buffer buffer t (selected-frame))))
557 566
558 (defun switch-to-buffer-other-frame (buffer) 567 (defun switch-to-buffer-other-frame (buffer)
559 "Switch to buffer BUFFER in a newly-created frame." 568 "Switch to buffer BUFFER in a newly-created frame."
560 (interactive "BSwitch to buffer in other frame: ") 569 (interactive "BSwitch to buffer in other frame: ")
570 ;; XEmacs guarantees a new frame
561 (let* ((name (get-frame-name-for-buffer buffer)) 571 (let* ((name (get-frame-name-for-buffer buffer))
562 (frame (make-frame (if name 572 (frame (make-frame (if name
563 (list (cons 'name (symbol-name name))))))) 573 (list (cons 'name (symbol-name name)))))))
564 (pop-to-buffer buffer t frame) 574 (pop-to-buffer buffer t frame)
565 (make-frame-visible frame) 575 (make-frame-visible frame)
578 See the function `display-buffer'." 588 See the function `display-buffer'."
579 (interactive "FFind file in other window: ") 589 (interactive "FFind file in other window: ")
580 (switch-to-buffer-other-window (find-file-noselect filename))) 590 (switch-to-buffer-other-window (find-file-noselect filename)))
581 591
582 (defun find-file-other-frame (filename) 592 (defun find-file-other-frame (filename)
583 "Edit file FILENAME, in a newly-created frame." 593 "Edit file FILENAME, in a newly-created frame.
594 This function will create a new frame.
595 See the function `display-buffer'."
584 (interactive "FFind file in other frame: ") 596 (interactive "FFind file in other frame: ")
585 (switch-to-buffer-other-frame (find-file-noselect filename))) 597 (switch-to-buffer-other-frame (find-file-noselect filename)))
586 598
587 (defun find-file-read-only (filename) 599 (defun find-file-read-only (filename)
588 "Edit file FILENAME but don't allow changes. 600 "Edit file FILENAME but don't allow changes.
622 (file-dir nil)) 634 (file-dir nil))
623 (and file 635 (and file
624 (setq file-name (file-name-nondirectory file) 636 (setq file-name (file-name-nondirectory file)
625 file-dir (file-name-directory file))) 637 file-dir (file-name-directory file)))
626 (list (read-file-name 638 (list (read-file-name
627 "Find alternate file: " file-dir nil nil file-name) 639 "Find alternate file: " file-dir nil nil file-name)))))
628 ))))
629 (if (one-window-p) 640 (if (one-window-p)
630 (find-file-other-window filename) 641 (find-file-other-window filename)
631 (save-selected-window 642 (save-selected-window
632 (other-window 1) 643 (other-window 1)
633 (find-alternate-file filename)))) 644 (find-alternate-file filename))))
645 file-dir (file-name-directory file))) 656 file-dir (file-name-directory file)))
646 (list (read-file-name 657 (list (read-file-name
647 "Find alternate file: " file-dir nil nil file-name)))) 658 "Find alternate file: " file-dir nil nil file-name))))
648 (and (buffer-modified-p) (buffer-file-name) 659 (and (buffer-modified-p) (buffer-file-name)
649 ;; (not buffer-read-only) 660 ;; (not buffer-read-only)
650 (not (yes-or-no-p (format 661 (not (yes-or-no-p (format "Buffer %s is modified; kill anyway? "
651 "Buffer %s is modified; kill anyway? " 662 (buffer-name))))
652 (buffer-name))))
653 (error "Aborted")) 663 (error "Aborted"))
654 (let ((obuf (current-buffer)) 664 (let ((obuf (current-buffer))
655 (ofile buffer-file-name) 665 (ofile buffer-file-name)
656 (onum buffer-file-number) 666 (onum buffer-file-number)
657 (otrue buffer-file-truename) 667 (otrue buffer-file-truename)
658 (oname (buffer-name))) 668 (oname (buffer-name)))
659 (if (get-buffer " **lose**") 669 (if (get-buffer " **lose**")
660 (kill-buffer " **lose**")) 670 (kill-buffer " **lose**"))
661 (rename-buffer " **lose**") 671 (rename-buffer " **lose**")
662 (setq buffer-file-name nil)
663 (setq buffer-file-number nil)
664 (setq buffer-file-truename nil)
665 (unwind-protect 672 (unwind-protect
666 (progn 673 (progn
667 (unlock-buffer) 674 (unlock-buffer)
675 (setq buffer-file-name nil)
676 (setq buffer-file-number nil)
677 (setq buffer-file-truename nil)
668 (find-file filename)) 678 (find-file filename))
669 (cond ((eq obuf (current-buffer)) 679 (cond ((eq obuf (current-buffer))
670 (setq buffer-file-name ofile) 680 (setq buffer-file-name ofile)
671 (setq buffer-file-number onum) 681 (setq buffer-file-number onum)
672 (setq buffer-file-truename otrue) 682 (setq buffer-file-truename otrue)
687 (defun generate-new-buffer (name) 697 (defun generate-new-buffer (name)
688 "Create and return a buffer with a name based on NAME. 698 "Create and return a buffer with a name based on NAME.
689 Choose the buffer's name using `generate-new-buffer-name'." 699 Choose the buffer's name using `generate-new-buffer-name'."
690 (get-buffer-create (generate-new-buffer-name name))) 700 (get-buffer-create (generate-new-buffer-name name)))
691 701
692 ;; FSF has automount-dir-prefix. Our directory-abbrev-alist is more general. 702 ;(defconst automount-dir-prefix "^/tmp_mnt/"
693 ;; note: tmp_mnt bogosity conversion is established in paths.el. 703 ; "Regexp to match the automounter prefix in a directory name.")
694 (defvar directory-abbrev-alist nil
695 "*Alist of abbreviations for file directories.
696 A list of elements of the form (FROM . TO), each meaning to replace
697 FROM with TO when it appears in a directory name.
698 This replacement is done when setting up the default directory of a
699 newly visited file. *Every* FROM string should start with \\\\` or ^.
700
701 Use this feature when you have directories which you normally refer to
702 via absolute symbolic links or to eliminate automounter mount points
703 from the beginning of your filenames. Make TO the name of the link,
704 and FROM the name it is linked to.")
705 704
706 (defvar abbreviated-home-dir nil 705 (defvar abbreviated-home-dir nil
707 "The user's homedir abbreviated according to `directory-abbrev-alist'.") 706 "The user's homedir abbreviated according to `directory-abbrev-alist'.")
708 707
708 ;; XEmacs additional parameter
709 (defun abbreviate-file-name (filename &optional hack-homedir) 709 (defun abbreviate-file-name (filename &optional hack-homedir)
710 "Return a version of FILENAME shortened using `directory-abbrev-alist'. 710 "Return a version of FILENAME shortened using `directory-abbrev-alist'.
711 See documentation of variable `directory-abbrev-alist' for more information. 711 See documentation of variable `directory-abbrev-alist' for more information.
712 If optional argument HACK-HOMEDIR is non-nil, then this also substitutes 712 If optional argument HACK-HOMEDIR is non-nil, then this also substitutes
713 \"~\" for the user's home directory." 713 \"~\" for the user's home directory."
741 ;; make it start with `~' instead. 741 ;; make it start with `~' instead.
742 (if (and (string-match abbreviated-home-dir filename) 742 (if (and (string-match abbreviated-home-dir filename)
743 ;; If the home dir is just /, don't change it. 743 ;; If the home dir is just /, don't change it.
744 (not (and (= (match-end 0) 1) ;#### unix-specific 744 (not (and (= (match-end 0) 1) ;#### unix-specific
745 (= (aref filename 0) ?/))) 745 (= (aref filename 0) ?/)))
746 ;; MS-DOS root directories can come with a drive letter;
747 ;; Novell Netware allows drive letters beyond `Z:'.
746 (not (and (or (eq system-type 'ms-dos) 748 (not (and (or (eq system-type 'ms-dos)
747 (eq system-type 'windows-nt)) 749 (eq system-type 'windows-nt))
748 (save-match-data 750 (save-match-data
749 (string-match "^[a-zA-Z]:/$" filename))))) 751 (string-match "^[a-zA-Z-`]:/$" filename)))))
750 (setq filename 752 (setq filename
751 (concat "~" 753 (concat "~"
752 (substring filename 754 (substring filename
753 (match-beginning 1) (match-end 1)) 755 (match-beginning 1) (match-end 1))
754 (substring filename (match-end 0))))))) 756 (substring filename (match-end 0)))))))
778 ; (setq found (car list)))) 780 ; (setq found (car list))))
779 ; (setq list (cdr list))) 781 ; (setq list (cdr list)))
780 ; found) 782 ; found)
781 ; (let ((number (nthcdr 10 (file-attributes truename))) 783 ; (let ((number (nthcdr 10 (file-attributes truename)))
782 ; (list (buffer-list)) found) 784 ; (list (buffer-list)) found)
783 ; (and number 785 ; (and buffer-file-numbers-unique
786 ; number
784 ; (while (and (not found) list) 787 ; (while (and (not found) list)
785 ; (save-excursion 788 ; (save-excursion
786 ; (set-buffer (car list)) 789 ; (set-buffer (car list))
787 ; (if (and buffer-file-number 790 ; (if (and buffer-file-name
788 ; (equal buffer-file-number number) 791 ; (equal buffer-file-number number)
789 ; ;; Verify this buffer's file number 792 ; ;; Verify this buffer's file number
790 ; ;; still belongs to its file. 793 ; ;; still belongs to its file.
791 ; (file-exists-p buffer-file-name) 794 ; (file-exists-p buffer-file-name)
792 ; (equal (nthcdr 10 (file-attributes buffer-file-name)) 795 ; (equal (nthcdr 10 (file-attributes buffer-file-name))
793 ; number)) 796 ; number))
821 If a buffer exists visiting FILENAME, return that one, but 824 If a buffer exists visiting FILENAME, return that one, but
822 verify that the file has not changed since visited or saved. 825 verify that the file has not changed since visited or saved.
823 The buffer is not selected, just returned to the caller. 826 The buffer is not selected, just returned to the caller.
824 If NOWARN is non-nil warning messages about several potential 827 If NOWARN is non-nil warning messages about several potential
825 problems will be suppressed." 828 problems will be suppressed."
826 (setq filename (abbreviate-file-name (expand-file-name filename))) 829 (setq filename
830 (abbreviate-file-name
831 (expand-file-name filename)))
827 (if (file-directory-p filename) 832 (if (file-directory-p filename)
828 (if find-file-run-dired 833 (if find-file-run-dired
829 (dired-noselect (if find-file-use-truenames 834 (dired-noselect (if find-file-use-truenames ; XEmacs
830 (abbreviate-file-name (file-truename filename)) 835 (abbreviate-file-name (file-truename filename))
831 filename)) 836 filename))
832 (error "%s is a directory." filename)) 837 (error "%s is a directory" filename))
833 (let* ((buf (get-file-buffer filename)) 838 (let* ((buf (get-file-buffer filename))
834 ; (truename (abbreviate-file-name (file-truename filename))) 839 ; (truename (abbreviate-file-name (file-truename filename)))
835 ; (number (nthcdr 10 (file-attributes truename))) 840 ; (number (nthcdr 10 (file-attributes truename)))
836 (number (and buffer-file-truename 841 (number (and buffer-file-truename
837 (nthcdr 10 (file-attributes buffer-file-truename)))) 842 (nthcdr 10 (file-attributes buffer-file-truename))))
838 ; ;; Find any buffer for a file which has same truename. 843 ; ;; Find any buffer for a file which has same truename.
839 ; (other (and (not buf) (find-buffer-visiting filename))) 844 ; (other (and (not buf) (find-buffer-visiting filename)))
840 (error nil)) 845 (error nil))
841 846
842 ; ;; Let user know if there is a buffer with the same truename. 847 ; ;; Let user know if there is a buffer with the same truename.
843 ; (if (and (not buf) same-truename (not nowarn)) 848 ; (if other
844 ; (message "%s and %s are the same file (%s)" 849 ; (progn
845 ; filename (buffer-file-name same-truename) 850 ; (or nowarn
846 ; truename) 851 ; (string-equal filename (buffer-file-name other))
847 ; (if (and (not buf) same-number (not nowarn)) 852 ; (message "%s and %s are the same file"
848 ; (message "%s and %s are the same file" 853 ; filename (buffer-file-name other)))
849 ; filename (buffer-file-name same-number)))) 854 ; ;; Optionally also find that buffer.
850 ; ;; Optionally also find that buffer. 855 ; (if (or find-file-existing-other-name find-file-visit-truename)
851 ; (if (or find-file-existing-other-name find-file-visit-truename) 856 ; (setq buf other))))
852 ; (setq buf (or same-truename same-number)))
853 857
854 (if (and buf 858 (if (and buf
855 (or find-file-compare-truenames find-file-use-truenames) 859 (or find-file-compare-truenames find-file-use-truenames)
856 (not nowarn)) 860 (not nowarn))
857 (save-excursion 861 (save-excursion
899 (condition-case () 903 (condition-case ()
900 (insert-file-contents-literally filename t) 904 (insert-file-contents-literally filename t)
901 (file-error 905 (file-error
902 ;; Unconditionally set error 906 ;; Unconditionally set error
903 (setq error t))) 907 (setq error t)))
904 (condition-case e 908 (condition-case e ; XEmacs - pass error through
905 (insert-file-contents filename t) 909 (insert-file-contents filename t)
906 (file-error 910 (file-error
907 ;; Run find-file-not-found-hooks until one returns non-nil. 911 ;; Run find-file-not-found-hooks until one returns non-nil.
908 (or (run-hook-with-args-until-success 'find-file-not-found-hooks) 912 (or (run-hook-with-args-until-success 'find-file-not-found-hooks)
909 ;; If they fail too, set error. 913 ;; If they fail too, set error.
910 (setq error e))))) 914 (setq error e))))) ; XEmacs
911 ;; Find the file's truename, and maybe use that as visited name. 915 ;; Find the file's truename, and maybe use that as visited name.
912 ;; automatically computed in XEmacs. 916 ;; automatically computed in XEmacs.
913 ; (setq buffer-file-truename truename) 917 ; (setq buffer-file-truename truename)
914 (setq buffer-file-number number) 918 (setq buffer-file-number number)
915 ;; On VMS, we may want to remember which directory in a search list 919 ;; On VMS, we may want to remember which directory in a search list
939 (progn 943 (progn
940 (make-local-variable 'backup-inhibited) 944 (make-local-variable 'backup-inhibited)
941 (setq backup-inhibited t))) 945 (setq backup-inhibited t)))
942 (if rawfile 946 (if rawfile
943 nil 947 nil
944 (after-find-file error (not nowarn))))) 948 (after-find-file error (not nowarn))
949 (setq buf (current-buffer)))))
945 buf))) 950 buf)))
946 951
947 (defvar after-find-file-from-revert-buffer nil) 952 (defvar after-find-file-from-revert-buffer nil)
948 953
949 (defun after-find-file (&optional error warn noauto 954 (defun after-find-file (&optional error warn noauto
950 after-find-file-from-revert-buffer) 955 after-find-file-from-revert-buffer
956 nomodes)
951 "Called after finding a file and by the default revert function. 957 "Called after finding a file and by the default revert function.
952 Sets buffer mode, parses local variables. 958 Sets buffer mode, parses local variables.
953 Optional args ERROR, WARN, and NOAUTO: ERROR non-nil means there was an 959 Optional args ERROR, WARN, and NOAUTO: ERROR non-nil means there was an
954 error in reading the file. WARN non-nil means warn if there 960 error in reading the file. WARN non-nil means warn if there
955 exists an auto-save file more recent than the visited file. 961 exists an auto-save file more recent than the visited file.
956 NOAUTO means don't mess with auto-save mode. 962 NOAUTO means don't mess with auto-save mode.
957 Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil 963 Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil
958 means this call was from `revert-buffer'. 964 means this call was from `revert-buffer'.
959 Finishes by calling the functions in `find-file-hooks'." 965 Finishes by calling the functions in `find-file-hooks'.
966 Fifth arg NOMODES non-nil means don't alter the file's modes.
967 Finishes by calling the functions in `find-file-hooks'
968 unless NOMODES is non-nil."
960 (setq buffer-read-only (not (file-writable-p buffer-file-name))) 969 (setq buffer-read-only (not (file-writable-p buffer-file-name)))
961 (if noninteractive 970 (if noninteractive
962 nil 971 nil
963 (let* (not-serious 972 (let* (not-serious
964 (msg 973 (msg
983 ;; If the directory the buffer is in doesn't exist, 992 ;; If the directory the buffer is in doesn't exist,
984 ;; offer to create it. It's better to do this now 993 ;; offer to create it. It's better to do this now
985 ;; than when we save the buffer, because we want 994 ;; than when we save the buffer, because we want
986 ;; autosaving to work. 995 ;; autosaving to work.
987 (setq buffer-read-only nil) 996 (setq buffer-read-only nil)
997 ;; XEmacs change
988 (or (file-exists-p (file-name-directory buffer-file-name)) 998 (or (file-exists-p (file-name-directory buffer-file-name))
989 (if (yes-or-no-p 999 (if (yes-or-no-p
990 (format 1000 (format
991 "The directory containing %s does not exist. Create? " 1001 "The directory containing %s does not exist. Create? "
992 (abbreviate-file-name buffer-file-name))) 1002 (abbreviate-file-name buffer-file-name)))
998 (progn 1008 (progn
999 (message msg) 1009 (message msg)
1000 (or not-serious (sit-for 1 t))))) 1010 (or not-serious (sit-for 1 t)))))
1001 (if (and auto-save-default (not noauto)) 1011 (if (and auto-save-default (not noauto))
1002 (auto-save-mode t))) 1012 (auto-save-mode t)))
1003 (normal-mode t) 1013 (unless nomodes
1004 (run-hooks 'find-file-hooks)) 1014 (normal-mode t)
1015 (run-hooks 'find-file-hooks)))
1005 1016
1006 (defun normal-mode (&optional find-file) 1017 (defun normal-mode (&optional find-file)
1007 "Choose the major mode for this buffer automatically. 1018 "Choose the major mode for this buffer automatically.
1008 Also sets up any specified local variables of the file. 1019 Also sets up any specified local variables of the file.
1009 Uses the visited file name, the -*- line, and the local variables spec. 1020 Uses the visited file name, the -*- line, and the local variables spec.
1013 `enable-local-variables': if it is t, we do; if it is nil, we don't; 1024 `enable-local-variables': if it is t, we do; if it is nil, we don't;
1014 otherwise, we query. `enable-local-variables' is ignored if you 1025 otherwise, we query. `enable-local-variables' is ignored if you
1015 run `normal-mode' explicitly." 1026 run `normal-mode' explicitly."
1016 (interactive) 1027 (interactive)
1017 (or find-file (funcall (or default-major-mode 'fundamental-mode))) 1028 (or find-file (funcall (or default-major-mode 'fundamental-mode)))
1029 ;; XEmacs change
1018 (and (condition-case err 1030 (and (condition-case err
1019 (progn (set-auto-mode) 1031 (progn (set-auto-mode)
1020 t) 1032 t)
1021 (error (message "File mode specification error: %s" 1033 (error (message "File mode specification error: %s"
1022 (prin1-to-string err)) 1034 (prin1-to-string err))
1029 (defvar auto-mode-alist 1041 (defvar auto-mode-alist
1030 (mapcar 1042 (mapcar
1031 'purecopy 1043 'purecopy
1032 '(("\\.te?xt\\'" . text-mode) 1044 '(("\\.te?xt\\'" . text-mode)
1033 ("\\.[ch]\\'" . c-mode) 1045 ("\\.[ch]\\'" . c-mode)
1046 ("\\.tex\\'" . tex-mode)
1034 ("\\.ltx\\'" . latex-mode) 1047 ("\\.ltx\\'" . latex-mode)
1035 ("\\.el\\'" . emacs-lisp-mode) 1048 ("\\.el\\'" . emacs-lisp-mode)
1036 ("\\.l\\(i?sp\\)?\\'" . lisp-mode) 1049 ("\\.l\\(i?sp\\)?\\'" . lisp-mode)
1037 ("\\.f\\(or\\)?\\'" . fortran-mode) 1050 ("\\.f\\(or\\)?\\'" . fortran-mode)
1038 ("\\.p\\(as\\)?\\'" . pascal-mode) 1051 ("\\.p\\(as\\)?\\'" . pascal-mode)
1053 ("\\.py\\'" . python-mode) 1066 ("\\.py\\'" . python-mode)
1054 ("\\.e\\'" . eiffel-mode) 1067 ("\\.e\\'" . eiffel-mode)
1055 ("\\.mss\\'" . scribe-mode) 1068 ("\\.mss\\'" . scribe-mode)
1056 ("\\.m\\([mes]\\|an\\)\\'" . nroff-mode) 1069 ("\\.m\\([mes]\\|an\\)\\'" . nroff-mode)
1057 ("\\.icn\\'" . icon-mode) 1070 ("\\.icn\\'" . icon-mode)
1071 ("\\.[ck]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode)
1072 ("/\\.\\(bash_profile\\|z?login\\|bash_login\\|z?logout\\)\\'" . sh-mode)
1073 ("/\\.\\(bash_logout\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode)
1074 ("/\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode)
1058 ;;; The following should come after the ChangeLog pattern 1075 ;;; The following should come after the ChangeLog pattern
1059 ;;; for the sake of ChangeLog.1, etc. 1076 ;;; for the sake of ChangeLog.1, etc.
1060 ;;; and after the .scm.[0-9] pattern too. 1077 ;;; and after the .scm.[0-9] pattern too.
1061 ("\\.[12345678]\\'" . nroff-mode) 1078 ("\\.[12345678]\\'" . nroff-mode)
1062 ("\\.[tT]e[xX]\\'" . tex-mode) 1079 ("\\.[tT]e[xX]\\'" . tex-mode)
1072 ("\\.tar\\'" . tar-mode) 1089 ("\\.tar\\'" . tar-mode)
1073 ("\\.\\(arc\\|zip\\|lzh\\|zoo\\)\\'" . archive-mode) 1090 ("\\.\\(arc\\|zip\\|lzh\\|zoo\\)\\'" . archive-mode)
1074 ;; Mailer puts message to be edited in 1091 ;; Mailer puts message to be edited in
1075 ;; /tmp/Re.... or Message 1092 ;; /tmp/Re.... or Message
1076 ("^/tmp/Re" . text-mode) 1093 ("^/tmp/Re" . text-mode)
1094 ("^/tmp/L[0-9]+TMP\\.html" . text-mode) ; Lynx mail mode
1077 ("/Message[0-9]*\\'" . text-mode) 1095 ("/Message[0-9]*\\'" . text-mode)
1078 ("/drafts/[0-9]+\\'" . mh-letter-mode) 1096 ("/drafts/[0-9]+\\'" . mh-letter-mode)
1079 ;; some news reader is reported to use this 1097 ;; some news reader is reported to use this
1080 ("^/tmp/fol/" . text-mode) 1098 ("^/tmp/fol/" . text-mode)
1081 ("\\.y\\'" . c-mode) 1099 ("\\.y\\'" . c-mode)
1102 calling FUNCTION (if it's not nil), we delete the suffix that matched 1120 calling FUNCTION (if it's not nil), we delete the suffix that matched
1103 REGEXP and search the list again for another match.") 1121 REGEXP and search the list again for another match.")
1104 1122
1105 (defconst interpreter-mode-alist 1123 (defconst interpreter-mode-alist
1106 (mapcar 'purecopy 1124 (mapcar 'purecopy
1107 '(("^#!.*csh" . csh-mode) 1125 '(("^#!.*[acjkwz]sh" . sh-mode)
1108 ("^#!.*sh\\b" . ksh-mode) 1126 ("^#!.*sh\\b" . sh-mode)
1109 ("^#!.*\\b\\(scope\\|wish\\|tcl\\|expect\\)" . tcl-mode) 1127 ("^#!.*\\b\\(scope\\|wish\\|tcl\\|expect\\)" . tcl-mode)
1110 ("perl" . perl-mode) 1128 ("perl" . perl-mode)
1111 ("python" . python-mode) 1129 ("python" . python-mode)
1112 ("awk\\b" . awk-mode) 1130 ("awk\\b" . awk-mode)
1113 ("rexx" . rexx-mode) 1131 ("rexx" . rexx-mode)
1114 ("scm" . scheme-mode) 1132 ("scm" . scheme-mode)
1115 ("^:" . ksh-mode) 1133 ("^:" . sh-mode)
1116 )) 1134 ))
1117 "Alist mapping interpreter names to major modes. 1135 "Alist mapping interpreter names to major modes.
1118 This alist is used to guess the major mode of a file based on the 1136 This alist is used to guess the major mode of a file based on the
1119 contents of the first line. This line often contains something like: 1137 contents of the first line. This line often contains something like:
1120 #!/bin/sh 1138 #!/bin/sh
1138 1156
1139 (defvar user-init-file 1157 (defvar user-init-file
1140 "" ; set by command-line 1158 "" ; set by command-line
1141 "File name including directory of user's initialization file.") 1159 "File name including directory of user's initialization file.")
1142 1160
1161 ;; XEmacs (This function is not synched with FSF)
1143 (defun set-auto-mode () 1162 (defun set-auto-mode ()
1144 "Select major mode appropriate for current buffer. 1163 "Select major mode appropriate for current buffer.
1145 This checks for a -*- mode tag in the buffer's text, 1164 This checks for a -*- mode tag in the buffer's text,
1146 compares the filename against the entries in `auto-mode-alist', 1165 compares the filename against the entries in `auto-mode-alist',
1147 or checks the interpreter that runs this file against 1166 or checks the interpreter that runs this file against
1199 (setq alist (cdr alist)))))) 1218 (setq alist (cdr alist))))))
1200 (if mode 1219 (if mode
1201 (funcall mode)) 1220 (funcall mode))
1202 )))))) 1221 ))))))
1203 1222
1204 (defun hack-local-variables (&optional force) 1223 ;; XEmacs: this function is not synched with FSF
1205 "Parse, and bind or evaluate as appropriate, any local variables
1206 for current buffer."
1207 ;; Don't look for -*- if this file name matches any
1208 ;; of the regexps in inhibit-first-line-modes-regexps.
1209 (if (or (null buffer-file-name) ; don't lose if buffer has no file!
1210 (not (let ((temp inhibit-first-line-modes-regexps)
1211 (name (if buffer-file-name
1212 (file-name-sans-versions buffer-file-name)
1213 (buffer-name))))
1214 (while (let ((sufs inhibit-first-line-modes-suffixes))
1215 (while (and sufs (not
1216 (string-match (car sufs) name)))
1217 (setq sufs (cdr sufs)))
1218 sufs)
1219 (setq name (substring name 0 (match-beginning 0))))
1220 (while (and temp
1221 (not (string-match (car temp) name)))
1222 (setq temp (cdr temp))
1223 temp))))
1224 (progn
1225 ;; Look for variables in the -*- line.
1226 (hack-local-variables-prop-line force)
1227 ;; Look for "Local variables:" block in last page.
1228 (hack-local-variables-last-page force)))
1229 (run-hooks 'hack-local-variables-hook))
1230
1231 ;;; Local variables may be specified in the last page of the file (within 3k
1232 ;;; from the end of the file and after the last ^L) in the form
1233 ;;;
1234 ;;; Local variables:
1235 ;;; variable-name: variable-value
1236 ;;; end:
1237 ;;;
1238 ;;; The lines may begin with a common prefix, like ";;; " in the above
1239 ;;; example. They may also have a common suffix (" */" for example). In
1240 ;;; this form, the local variable "mode" can be used to change the major
1241 ;;; mode, and the local variable "eval" can be used to evaluate an arbitrary
1242 ;;; form.
1243 ;;;
1244 ;;; Local variables may also be specified in the first line of the file.
1245 ;;; Embedded in this line are a pair of "-*-" sequences. What lies between
1246 ;;; them are variable-name/variable-value pairs, like:
1247 ;;;
1248 ;;; -*- mode: emacs-lisp -*-
1249 ;;; or -*- mode: postscript; version-control: never -*-
1250 ;;; or -*- tags-file-name: "/foo/bar/TAGS" -*-
1251 ;;;
1252 ;;; The local variable "eval" is not used with this form. For hysterical
1253 ;;; reasons, the syntax "-*- modename -*-" is allowed as well.
1254 ;;;
1255
1256 (defun hack-local-variables-p (modeline)
1257 (or (eq enable-local-variables t)
1258 (and enable-local-variables
1259 (save-window-excursion
1260 (condition-case nil
1261 (switch-to-buffer (current-buffer))
1262 (error
1263 ;; If we fail to switch in the selected window,
1264 ;; it is probably a minibuffer.
1265 ;; So try another window.
1266 (condition-case nil
1267 (switch-to-buffer-other-window (current-buffer))
1268 (error
1269 (switch-to-buffer-other-frame (current-buffer))))))
1270 (or modeline (save-excursion
1271 (beginning-of-line)
1272 (set-window-start (selected-window) (point))))
1273 (y-or-n-p (format
1274 "Set local variables as specified %s of %s? "
1275 (if modeline "in -*- line" "at end")
1276 (if buffer-file-name
1277 (file-name-nondirectory buffer-file-name)
1278 (concat "buffer " (buffer-name)))))))))
1279
1280 (defun hack-local-variables-last-page (&optional force)
1281 ;; Set local variables set in the "Local Variables:" block of the last page.
1282 (save-excursion
1283 (goto-char (point-max))
1284 (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
1285 (if (let ((case-fold-search t))
1286 (and (search-forward "Local Variables:" nil t)
1287 (or force
1288 (hack-local-variables-p nil))))
1289 (let ((continue t)
1290 prefix prefixlen suffix beg
1291 (enable-local-eval enable-local-eval))
1292 ;; The prefix is what comes before "local variables:" in its line.
1293 ;; The suffix is what comes after "local variables:" in its line.
1294 (skip-chars-forward " \t")
1295 (or (eolp)
1296 (setq suffix (buffer-substring (point)
1297 (progn (end-of-line) (point)))))
1298 (goto-char (match-beginning 0))
1299 (or (bolp)
1300 (setq prefix
1301 (buffer-substring (point)
1302 (progn (beginning-of-line) (point)))))
1303 (if prefix (setq prefixlen (length prefix)
1304 prefix (regexp-quote prefix)))
1305 (if suffix (setq suffix (concat (regexp-quote suffix) "$")))
1306 (while continue
1307 ;; Look at next local variable spec.
1308 (if selective-display (re-search-forward "[\n\C-m]")
1309 (forward-line 1))
1310 ;; Skip the prefix, if any.
1311 (if prefix
1312 (if (looking-at prefix)
1313 (forward-char prefixlen)
1314 (error "Local variables entry is missing the prefix")))
1315 ;; Find the variable name; strip whitespace.
1316 (skip-chars-forward " \t")
1317 (setq beg (point))
1318 (skip-chars-forward "^:\n")
1319 (if (eolp) (error "Missing colon in local variables entry"))
1320 (skip-chars-backward " \t")
1321 (let* ((str (buffer-substring beg (point)))
1322 (var (read str))
1323 val)
1324 ;; Setting variable named "end" means end of list.
1325 (if (string-equal (downcase str) "end")
1326 (setq continue nil)
1327 ;; Otherwise read the variable value.
1328 (skip-chars-forward "^:")
1329 (forward-char 1)
1330 (setq val (read (current-buffer)))
1331 (skip-chars-backward "\n")
1332 (skip-chars-forward " \t")
1333 (or (if suffix (looking-at suffix) (eolp))
1334 (error "Local variables entry is terminated incorrectly"))
1335 ;; Set the variable. "Variables" mode and eval are funny.
1336 (hack-one-local-variable var val))))))))
1337
1338
1339 (defun hack-local-variables-prop-line (&optional force) 1224 (defun hack-local-variables-prop-line (&optional force)
1340 ;; Set local variables specified in the -*- line. 1225 ;; Set local variables specified in the -*- line.
1341 ;; Returns t if mode was set. 1226 ;; Returns t if mode was set.
1342 (let ((result nil)) 1227 (let ((result nil))
1343 (save-excursion 1228 (save-excursion
1406 (t 1291 (t
1407 nil))) 1292 nil)))
1408 (setq result (cdr result))) 1293 (setq result (cdr result)))
1409 mode-p))) 1294 mode-p)))
1410 1295
1296 (defvar hack-local-variables-hook nil
1297 "Normal hook run after processing a file's local variables specs.
1298 Major modes can use this to examine user-specified local variables
1299 in order to initialize other data structure based on them.
1300
1301 This hook runs even if there were no local variables or if their
1302 evaluation was suppressed. See also `enable-local-variables' and
1303 `enable-local-eval'.")
1304
1305 ;; XEmacs this function is not synched with FSF
1306 (defun hack-local-variables (&optional force)
1307 "Parse, and bind or evaluate as appropriate, any local variables
1308 for current buffer."
1309 ;; Don't look for -*- if this file name matches any
1310 ;; of the regexps in inhibit-first-line-modes-regexps.
1311 (if (or (null buffer-file-name) ; don't lose if buffer has no file!
1312 (not (let ((temp inhibit-first-line-modes-regexps)
1313 (name (if buffer-file-name
1314 (file-name-sans-versions buffer-file-name)
1315 (buffer-name))))
1316 (while (let ((sufs inhibit-first-line-modes-suffixes))
1317 (while (and sufs (not
1318 (string-match (car sufs) name)))
1319 (setq sufs (cdr sufs)))
1320 sufs)
1321 (setq name (substring name 0 (match-beginning 0))))
1322 (while (and temp
1323 (not (string-match (car temp) name)))
1324 (setq temp (cdr temp))
1325 temp))))
1326 (progn
1327 ;; Look for variables in the -*- line.
1328 (hack-local-variables-prop-line force)
1329 ;; Look for "Local variables:" block in last page.
1330 (hack-local-variables-last-page force)))
1331 (run-hooks 'hack-local-variables-hook))
1332
1333 ;;; Local variables may be specified in the last page of the file (within 3k
1334 ;;; from the end of the file and after the last ^L) in the form
1335 ;;;
1336 ;;; Local variables:
1337 ;;; variable-name: variable-value
1338 ;;; end:
1339 ;;;
1340 ;;; The lines may begin with a common prefix, like ";;; " in the above
1341 ;;; example. They may also have a common suffix (" */" for example). In
1342 ;;; this form, the local variable "mode" can be used to change the major
1343 ;;; mode, and the local variable "eval" can be used to evaluate an arbitrary
1344 ;;; form.
1345 ;;;
1346 ;;; Local variables may also be specified in the first line of the file.
1347 ;;; Embedded in this line are a pair of "-*-" sequences. What lies between
1348 ;;; them are variable-name/variable-value pairs, like:
1349 ;;;
1350 ;;; -*- mode: emacs-lisp -*-
1351 ;;; or -*- mode: postscript; version-control: never -*-
1352 ;;; or -*- tags-file-name: "/foo/bar/TAGS" -*-
1353 ;;;
1354 ;;; The local variable "eval" is not used with this form. For hysterical
1355 ;;; reasons, the syntax "-*- modename -*-" is allowed as well.
1356 ;;;
1357
1358 (defun hack-local-variables-p (modeline)
1359 (or (eq enable-local-variables t)
1360 (and enable-local-variables
1361 (save-window-excursion
1362 (condition-case nil
1363 (switch-to-buffer (current-buffer))
1364 (error
1365 ;; If we fail to switch in the selected window,
1366 ;; it is probably a minibuffer.
1367 ;; So try another window.
1368 (condition-case nil
1369 (switch-to-buffer-other-window (current-buffer))
1370 (error
1371 (switch-to-buffer-other-frame (current-buffer))))))
1372 (or modeline (save-excursion
1373 (beginning-of-line)
1374 (set-window-start (selected-window) (point))))
1375 (y-or-n-p (format
1376 "Set local variables as specified %s of %s? "
1377 (if modeline "in -*- line" "at end")
1378 (if buffer-file-name
1379 (file-name-nondirectory buffer-file-name)
1380 (concat "buffer " (buffer-name)))))))))
1381
1382 (defun hack-local-variables-last-page (&optional force)
1383 ;; Set local variables set in the "Local Variables:" block of the last page.
1384 (save-excursion
1385 (goto-char (point-max))
1386 (search-backward "\n\^L" (max (- (point-max) 3000) (point-min)) 'move)
1387 (if (let ((case-fold-search t))
1388 (and (search-forward "Local Variables:" nil t)
1389 (or force
1390 (hack-local-variables-p nil))))
1391 (let ((continue t)
1392 prefix prefixlen suffix beg
1393 (enable-local-eval enable-local-eval))
1394 ;; The prefix is what comes before "local variables:" in its line.
1395 ;; The suffix is what comes after "local variables:" in its line.
1396 (skip-chars-forward " \t")
1397 (or (eolp)
1398 (setq suffix (buffer-substring (point)
1399 (progn (end-of-line) (point)))))
1400 (goto-char (match-beginning 0))
1401 (or (bolp)
1402 (setq prefix
1403 (buffer-substring (point)
1404 (progn (beginning-of-line) (point)))))
1405 (if prefix (setq prefixlen (length prefix)
1406 prefix (regexp-quote prefix)))
1407 (if suffix (setq suffix (concat (regexp-quote suffix) "$")))
1408 (while continue
1409 ;; Look at next local variable spec.
1410 (if selective-display (re-search-forward "[\n\C-m]")
1411 (forward-line 1))
1412 ;; Skip the prefix, if any.
1413 (if prefix
1414 (if (looking-at prefix)
1415 (forward-char prefixlen)
1416 (error "Local variables entry is missing the prefix")))
1417 ;; Find the variable name; strip whitespace.
1418 (skip-chars-forward " \t")
1419 (setq beg (point))
1420 (skip-chars-forward "^:\n")
1421 (if (eolp) (error "Missing colon in local variables entry"))
1422 (skip-chars-backward " \t")
1423 (let* ((str (buffer-substring beg (point)))
1424 (var (read str))
1425 val)
1426 ;; Setting variable named "end" means end of list.
1427 (if (string-equal (downcase str) "end")
1428 (setq continue nil)
1429 ;; Otherwise read the variable value.
1430 (skip-chars-forward "^:")
1431 (forward-char 1)
1432 (setq val (read (current-buffer)))
1433 (skip-chars-backward "\n")
1434 (skip-chars-forward " \t")
1435 (or (if suffix (looking-at suffix) (eolp))
1436 (error "Local variables entry is terminated incorrectly"))
1437 ;; Set the variable. "Variables" mode and eval are funny.
1438 (hack-one-local-variable var val))))))))
1439
1440
1441
1411 (defconst ignored-local-variables 1442 (defconst ignored-local-variables
1412 (list 'enable-local-eval) 1443 '(enable-local-eval)
1413 "Variables to be ignored in a file's local variable spec.") 1444 "Variables to be ignored in a file's local variable spec.")
1414 1445
1415 ;; Get confirmation before setting these variables as locals in a file. 1446 ;; Get confirmation before setting these variables as locals in a file.
1416 (put 'debugger 'risky-local-variable t) 1447 (put 'debugger 'risky-local-variable t)
1417 (put 'enable-local-eval 'risky-local-variable t) 1448 (put 'enable-local-eval 'risky-local-variable t)
1425 (put 'buffer-file-truename 'risky-local-variable t) 1456 (put 'buffer-file-truename 'risky-local-variable t)
1426 (put 'exec-path 'risky-local-variable t) 1457 (put 'exec-path 'risky-local-variable t)
1427 (put 'load-path 'risky-local-variable t) 1458 (put 'load-path 'risky-local-variable t)
1428 (put 'exec-directory 'risky-local-variable t) 1459 (put 'exec-directory 'risky-local-variable t)
1429 (put 'process-environment 'risky-local-variable t) 1460 (put 'process-environment 'risky-local-variable t)
1461 (put 'dabbrev-case-fold-search 'risky-local-variable t)
1462 (put 'dabbrev-case-replace 'risky-local-variable t)
1430 ;; Don't wait for outline.el to be loaded, for the sake of outline-minor-mode. 1463 ;; Don't wait for outline.el to be loaded, for the sake of outline-minor-mode.
1431 (put 'outline-level 'risky-local-variable t) 1464 (put 'outline-level 'risky-local-variable t)
1432 (put 'rmail-output-file-alist 'risky-local-variable t) 1465 (put 'rmail-output-file-alist 'risky-local-variable t)
1433 1466
1434 ;; This one is safe because the user gets to check it before it is used. 1467 ;; This one is safe because the user gets to check it before it is used.
1435 (put 'compile-command 'safe-local-variable t) 1468 (put 'compile-command 'safe-local-variable t)
1436 1469
1437 ;(defun hack-one-local-variable-quotep (exp) 1470 ;(defun hack-one-local-variable-quotep (exp)
1438 ; (and (consp exp) (eq (car exp) 'quote) (consp (cdr exp)))) 1471 ; (and (consp exp) (eq (car exp) 'quote) (consp (cdr exp))))
1483 (message "Ignoring `eval:' in file's local variables"))) 1516 (message "Ignoring `eval:' in file's local variables")))
1484 ;; Ordinary variable, really set it. 1517 ;; Ordinary variable, really set it.
1485 (t (make-local-variable var) 1518 (t (make-local-variable var)
1486 (set var val)))) 1519 (set var val))))
1487 1520
1488 (defun set-visited-file-name (filename) 1521 (defun set-visited-file-name (filename &optional no-query)
1489 "Change name of file visited in current buffer to FILENAME. 1522 "Change name of file visited in current buffer to FILENAME.
1490 The next time the buffer is saved it will go in the newly specified file. 1523 The next time the buffer is saved it will go in the newly specified file.
1491 nil or empty string as argument means make buffer not be visiting any file. 1524 nil or empty string as argument means make buffer not be visiting any file.
1492 Remember to delete the initial contents of the minibuffer 1525 Remember to delete the initial contents of the minibuffer
1493 if you wish to pass an empty string as the argument." 1526 if you wish to pass an empty string as the argument.
1527
1528 The optional second argument NO-QUERY, if non-nil, inhibits asking for
1529 confirmation in the case where the file FILENAME already exists."
1494 (interactive "FSet visited file name: ") 1530 (interactive "FSet visited file name: ")
1495 (if (buffer-base-buffer) 1531 (if (buffer-base-buffer)
1496 (error "An indirect buffer cannot visit a file")) 1532 (error "An indirect buffer cannot visit a file"))
1497 (let (truename) 1533 (let (truename)
1498 (if filename 1534 (if filename
1502 (expand-file-name filename)))) 1538 (expand-file-name filename))))
1503 (if filename 1539 (if filename
1504 (progn 1540 (progn
1505 (setq truename (file-truename filename)) 1541 (setq truename (file-truename filename))
1506 ;; #### Do we need to check if truename is non-nil? 1542 ;; #### Do we need to check if truename is non-nil?
1543 ;; XEmacs: FSF uses -visit-
1507 (if find-file-use-truenames 1544 (if find-file-use-truenames
1508 (setq filename truename)))) 1545 (setq filename truename))))
1546 ; (let ((buffer (and filename (find-buffer-visiting filename))))
1547 ; (and buffer (not (eq buffer (current-buffer)))
1548 ; (not no-query)
1549 ; (not (y-or-n-p (message "A buffer is visiting %s; proceed? "
1550 ; filename)))
1551 ; (error "Aborted")))
1509 (or (equal filename buffer-file-name) 1552 (or (equal filename buffer-file-name)
1510 (progn 1553 (progn
1511 (and filename (lock-buffer filename)) 1554 (and filename (lock-buffer filename))
1512 (unlock-buffer))) 1555 (unlock-buffer)))
1513 (setq buffer-file-name filename) 1556 (setq buffer-file-name filename)
1521 (or (string= new-name (buffer-name)) 1564 (or (string= new-name (buffer-name))
1522 (rename-buffer new-name t)))) 1565 (rename-buffer new-name t))))
1523 (setq buffer-backed-up nil) 1566 (setq buffer-backed-up nil)
1524 (clear-visited-file-modtime) 1567 (clear-visited-file-modtime)
1525 (compute-buffer-file-truename) ; insert-file-contents does this too. 1568 (compute-buffer-file-truename) ; insert-file-contents does this too.
1569 ;; XEmacs deletion
1526 ; ;; Abbreviate the file names of the buffer. 1570 ; ;; Abbreviate the file names of the buffer.
1527 ; (if truename 1571 ; (if truename
1528 ; (progn 1572 ; (progn
1529 ; (setq buffer-file-truename (abbreviate-file-name truename)) 1573 ; (setq buffer-file-truename (abbreviate-file-name truename))
1530 ; (if find-file-visit-truename 1574 ; (if find-file-visit-truename
1535 nil))) 1579 nil)))
1536 ;; write-file-hooks is normally used for things like ftp-find-file 1580 ;; write-file-hooks is normally used for things like ftp-find-file
1537 ;; that visit things that are not local files as if they were files. 1581 ;; that visit things that are not local files as if they were files.
1538 ;; Changing to visit an ordinary local file instead should flush the hook. 1582 ;; Changing to visit an ordinary local file instead should flush the hook.
1539 (kill-local-variable 'write-file-hooks) 1583 (kill-local-variable 'write-file-hooks)
1540 (kill-local-variable 'after-save-hook) 1584 (kill-local-variable 'after-save-hook) ; XEmacs
1541 (kill-local-variable 'local-write-file-hooks) 1585 (kill-local-variable 'local-write-file-hooks)
1542 (kill-local-variable 'write-file-data-hooks) 1586 (kill-local-variable 'write-file-data-hooks) ; XEmacs
1543 (kill-local-variable 'revert-buffer-function) 1587 (kill-local-variable 'revert-buffer-function)
1544 (kill-local-variable 'backup-inhibited) 1588 (kill-local-variable 'backup-inhibited)
1545 ;; If buffer was read-only because of version control, 1589 ;; If buffer was read-only because of version control,
1546 ;; that reason is gone now, so make it writable. 1590 ;; that reason is gone now, so make it writable.
1547 (if (and (boundp 'vc-mode) vc-mode) 1591 (if (and (boundp 'vc-mode) vc-mode)
1569 (and oauto buffer-auto-save-file-name 1613 (and oauto buffer-auto-save-file-name
1570 (file-exists-p oauto) 1614 (file-exists-p oauto)
1571 (rename-file oauto buffer-auto-save-file-name t))) 1615 (rename-file oauto buffer-auto-save-file-name t)))
1572 (if buffer-file-name 1616 (if buffer-file-name
1573 (set-buffer-modified-p t)) 1617 (set-buffer-modified-p t))
1574 ;; #### ?? 1618 ;; #### ?? (Not in FSF -sb)
1575 (run-hooks 'after-set-visited-file-name-hooks)) 1619 (run-hooks 'after-set-visited-file-name-hooks))
1576 1620
1577 (defun write-file (filename &optional confirm) 1621 (defun write-file (filename &optional confirm)
1578 "Write current buffer into file FILENAME. 1622 "Write current buffer into file FILENAME.
1579 Makes buffer visit that file, and marks it not modified. 1623 Makes buffer visit that file, and marks it not modified.
1580 If the buffer is already visiting a file, you can specify 1624 If the buffer is already visiting a file, you can specify
1581 a directory name as FILENAME, to write a file of the same 1625 a directory name as FILENAME, to write a file of the same
1582 old name in that directory. 1626 old name in that directory.
1627
1583 If optional second arg CONFIRM is non-nil, 1628 If optional second arg CONFIRM is non-nil,
1584 ask for confirmation for overwriting an existing file." 1629 ask for confirmation for overwriting an existing file.
1630 Interactively, confirmation is required unless you supply a prefix argument."
1585 ;; (interactive "FWrite file: ") 1631 ;; (interactive "FWrite file: ")
1586 (interactive 1632 (interactive
1587 (list (if buffer-file-name 1633 (list (if buffer-file-name
1588 (read-file-name "Write file: " 1634 (read-file-name "Write file: "
1589 nil nil nil nil) 1635 nil nil nil nil)
1590 (read-file-name "Write file: " 1636 (read-file-name "Write file: "
1591 (cdr (assq 'default-directory 1637 (cdr (assq 'default-directory
1592 (buffer-local-variables))) 1638 (buffer-local-variables)))
1593 nil nil (buffer-name))) 1639 nil nil (buffer-name)))
1594 t)) 1640 t))
1641 ;; XEmacs
1595 (and (eq (current-buffer) mouse-grabbed-buffer) 1642 (and (eq (current-buffer) mouse-grabbed-buffer)
1596 (error "Can't write minibuffer window")) 1643 (error "Can't write minibuffer window"))
1597 (or (null filename) (string-equal filename "") 1644 (or (null filename) (string-equal filename "")
1598 (progn 1645 (progn
1599 ;; If arg is just a directory, 1646 ;; If arg is just a directory,
1605 (file-exists-p filename) 1652 (file-exists-p filename)
1606 (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) 1653 (or (y-or-n-p (format "File `%s' exists; overwrite? " filename))
1607 (error "Canceled"))) 1654 (error "Canceled")))
1608 (set-visited-file-name filename))) 1655 (set-visited-file-name filename)))
1609 (set-buffer-modified-p t) 1656 (set-buffer-modified-p t)
1610 (setq buffer-read-only nil) 1657 (setq buffer-read-only nil) ; XEmacs
1611 (save-buffer)) 1658 (save-buffer))
1612 1659
1613 (defun backup-buffer () 1660 (defun backup-buffer ()
1614 "Make a backup of the disk file visited by the current buffer, if appropriate. 1661 "Make a backup of the disk file visited by the current buffer, if appropriate.
1615 This is normally done before saving the buffer the first time. 1662 This is normally done before saving the buffer the first time.
1616 If the value is non-nil, it is the result of `file-modes' on the original file; 1663 If the value is non-nil, it is the result of `file-modes' on the original
1617 this means that the caller, after saving the buffer, should change the modes 1664 file; this means that the caller, after saving the buffer, should change
1618 of the new file to agree with the old modes." 1665 the modes of the new file to agree with the old modes."
1619 (if (and make-backup-files 1666 (if (and make-backup-files (not backup-inhibited)
1620 (not backup-inhibited)
1621 (not buffer-backed-up) 1667 (not buffer-backed-up)
1622 (file-exists-p buffer-file-name) 1668 (file-exists-p buffer-file-name)
1623 (memq (aref (elt (file-attributes buffer-file-name) 8) 0) 1669 (memq (aref (elt (file-attributes buffer-file-name) 8) 0)
1624 '(?- ?l))) 1670 '(?- ?l)))
1625 (let ((real-file-name buffer-file-name) 1671 (let ((real-file-name buffer-file-name)
1667 ;; rename-file should delete old backup. 1713 ;; rename-file should delete old backup.
1668 (rename-file real-file-name backupname t) 1714 (rename-file real-file-name backupname t)
1669 (setq setmodes (file-modes backupname))) 1715 (setq setmodes (file-modes backupname)))
1670 (file-error 1716 (file-error
1671 ;; If trouble writing the backup, write it in ~. 1717 ;; If trouble writing the backup, write it in ~.
1672 (setq backupname (expand-file-name "~/%backup%~")) 1718 (setq backupname (expand-file-name
1673 (message "Cannot write backup file; backing up in ~/%%backup%%~") 1719 (convert-standard-filename
1720 "~/%backup%~")))
1721 (message "Cannot write backup file; backing up in %s"
1722 (file-name-nondirectory backupname))
1674 (sleep-for 1) 1723 (sleep-for 1)
1675 (condition-case () 1724 (condition-case ()
1676 (copy-file real-file-name backupname t t) 1725 (copy-file real-file-name backupname t t)
1677 (file-error 1726 (file-error
1678 ;; If copying fails because file BACKUPNAME 1727 ;; If copying fails because file BACKUPNAME
1714 (match-beginning 1)) 1763 (match-beginning 1))
1715 (length name)) 1764 (length name))
1716 (if keep-backup-version 1765 (if keep-backup-version
1717 (length name) 1766 (length name)
1718 (or (string-match "\\.~[0-9.]+~\\'" name) 1767 (or (string-match "\\.~[0-9.]+~\\'" name)
1719 ;; XEmacs - VC uses extensions like ".~tagname~" or ".~1.1.5.2~" 1768 ;; XEmacs - VC uses extensions like ".~tagname~"
1769 ;; or ".~1.1.5.2~"
1720 (let ((pos (string-match "\\.~\\([^.~ \t]+\\|[0-9.]+\\)~\\'" name))) 1770 (let ((pos (string-match "\\.~\\([^.~ \t]+\\|[0-9.]+\\)~\\'" name)))
1721 (and pos 1771 (and pos
1722 ;; #### - is this filesystem check too paranoid? 1772 ;; #### - is this filesystem check too paranoid?
1723 (file-exists-p (substring name 0 pos)) 1773 (file-exists-p (substring name 0 pos))
1724 pos)) 1774 pos))
1750 filename)))) 1800 filename))))
1751 1801
1752 (defun make-backup-file-name (file) 1802 (defun make-backup-file-name (file)
1753 "Create the non-numeric backup file name for FILE. 1803 "Create the non-numeric backup file name for FILE.
1754 This is a separate function so you can redefine it for customization." 1804 This is a separate function so you can redefine it for customization."
1755 (if (eq system-type 'ms-dos) 1805 (if (and (eq system-type 'ms-dos)
1806 (not (msdos-long-file-names)))
1756 (let ((fn (file-name-nondirectory file))) 1807 (let ((fn (file-name-nondirectory file)))
1757 (concat (file-name-directory file) 1808 (concat (file-name-directory file)
1758 (if (string-match "\\([^.]*\\)\\(\\..*\\)?" fn) 1809 (if (string-match "\\([^.]*\\)\\(\\..*\\)?" fn)
1759 (substring fn 0 (match-end 1))) 1810 (substring fn 0 (match-end 1)))
1811 ; (or
1812 ; (and (string-match "\\`[^.]+\\'" fn)
1813 ; (concat (match-string 0 fn) ".~"))
1814 ; (and (string-match "\\`[^.]+\\.\\(..?\\)?" fn)
1815 ; (concat (match-string 0 fn) "~")))))
1760 ".bak")) 1816 ".bak"))
1761 (concat file "~"))) 1817 (concat file "~")))
1762 1818
1763 (defun backup-file-name-p (file) 1819 (defun backup-file-name-p (file)
1764 "Return non-nil if FILE is a backup file name (numeric or not). 1820 "Return non-nil if FILE is a backup file name (numeric or not).
1835 (car (cdr (file-attributes filename)))) 1891 (car (cdr (file-attributes filename))))
1836 1892
1837 (defun file-relative-name (filename &optional directory) 1893 (defun file-relative-name (filename &optional directory)
1838 "Convert FILENAME to be relative to DIRECTORY (default: default-directory)." 1894 "Convert FILENAME to be relative to DIRECTORY (default: default-directory)."
1839 (setq filename (expand-file-name filename) 1895 (setq filename (expand-file-name filename)
1840 directory (file-name-as-directory (if directory 1896 directory (file-name-as-directory (expand-file-name
1841 (expand-file-name directory) 1897 (or directory default-directory))))
1842 default-directory))) 1898 (let ((ancestor ""))
1843 (while directory 1899 (while (not (string-match (concat "^" (regexp-quote directory)) filename))
1844 (let ((up (file-name-directory (directory-file-name directory)))) 1900 (setq directory (file-name-directory (substring directory 0 -1))
1845 (cond ((and (string= directory up) 1901 ancestor (concat "../" ancestor)))
1846 (file-name-absolute-p directory)) 1902 (concat ancestor (substring filename (match-end 0)))))
1847 ;; "/"
1848 (setq directory nil))
1849 ((string-match (concat "\\`" (regexp-quote directory))
1850 filename)
1851 (setq filename (substring filename (match-end 0)))
1852 (setq directory nil))
1853 (t
1854 ;; go up one level
1855 (setq directory up)))))
1856 filename)
1857 1903
1858 (defun save-buffer (&optional args) 1904 (defun save-buffer (&optional args)
1859 "Save current buffer in visited file if modified. Versions described below. 1905 "Save current buffer in visited file if modified. Versions described below.
1860 1906
1861 By default, makes the previous version into a backup file 1907 By default, makes the previous version into a backup file
1862 if previously requested or if this is the first save. 1908 if previously requested or if this is the first save.
1863 With 1 or 3 \\[universal-argument]'s, marks this version 1909 With 1 \\[universal-argument], marks this version
1864 to become a backup when the next save is done. 1910 to become a backup when the next save is done.
1865 With 2 or 3 \\[universal-argument]'s, 1911 With 2 \\[universal-argument]'s,
1866 unconditionally makes the previous version into a backup file. 1912 unconditionally makes the previous version into a backup file.
1913 With 3 \\[universal-argument]'s, marks this version
1914 to become a backup when the next save is done,
1915 and unconditionally makes the previous version into a backup file.
1916
1867 With argument of 0, never makes the previous version into a backup file. 1917 With argument of 0, never makes the previous version into a backup file.
1868 1918
1869 If a file's name is FOO, the names of its numbered backup versions are 1919 If a file's name is FOO, the names of its numbered backup versions are
1870 FOO.~i~ for various integers i. A non-numbered backup file is called FOO~. 1920 FOO.~i~ for various integers i. A non-numbered backup file is called FOO~.
1871 Numeric backups (rather than FOO~) will be made if value of 1921 Numeric backups (rather than FOO~) will be made if value of
1883 (let ((modp (buffer-modified-p)) 1933 (let ((modp (buffer-modified-p))
1884 (large (> (buffer-size) 50000)) 1934 (large (> (buffer-size) 50000))
1885 (make-backup-files (or (and make-backup-files (not (eq args 0))) 1935 (make-backup-files (or (and make-backup-files (not (eq args 0)))
1886 (memq args '(16 64))))) 1936 (memq args '(16 64)))))
1887 (and modp (memq args '(16 64)) (setq buffer-backed-up nil)) 1937 (and modp (memq args '(16 64)) (setq buffer-backed-up nil))
1888 (if (and modp large) (message "Saving file %s..." 1938 (if (and modp large) (message "Saving file %s..." (buffer-file-name)))
1889 (buffer-file-name)))
1890 (basic-save-buffer) 1939 (basic-save-buffer)
1891 (and modp (memq args '(4 64)) (setq buffer-backed-up nil)))) 1940 (and modp (memq args '(4 64)) (setq buffer-backed-up nil))))
1892 1941
1893 (defun delete-auto-save-file-if-necessary (&optional force) 1942 (defun delete-auto-save-file-if-necessary (&optional force)
1894 "Delete auto-save file for current buffer if `delete-auto-save-files' is t. 1943 "Delete auto-save file for current buffer if `delete-auto-save-files' is t.
1939 (save-excursion 1988 (save-excursion
1940 ;; In an indirect buffer, save its base buffer instead. 1989 ;; In an indirect buffer, save its base buffer instead.
1941 (if (buffer-base-buffer) 1990 (if (buffer-base-buffer)
1942 (set-buffer (buffer-base-buffer))) 1991 (set-buffer (buffer-base-buffer)))
1943 (if (buffer-modified-p) 1992 (if (buffer-modified-p)
1944 (let ((recent-save (recent-auto-save-p))) 1993 (let ((recent-save (recent-auto-save-p))
1994 setmodes tempsetmodes)
1945 ;; On VMS, rename file and buffer to get rid of version number. 1995 ;; On VMS, rename file and buffer to get rid of version number.
1946 (if (and (eq system-type 'vax-vms) 1996 (if (and (eq system-type 'vax-vms)
1947 (not (string= buffer-file-name 1997 (not (string= buffer-file-name
1948 (file-name-sans-versions buffer-file-name)))) 1998 (file-name-sans-versions buffer-file-name))))
1949 (let (buffer-new-name) 1999 (let (buffer-new-name)
2025 ;; This does the "real job" of writing a buffer into its visited file 2075 ;; This does the "real job" of writing a buffer into its visited file
2026 ;; and making a backup file. This is what is normally done 2076 ;; and making a backup file. This is what is normally done
2027 ;; but inhibited if one of write-file-hooks returns non-nil. 2077 ;; but inhibited if one of write-file-hooks returns non-nil.
2028 ;; It returns a value to store in setmodes. 2078 ;; It returns a value to store in setmodes.
2029 (defun basic-save-buffer-1 () 2079 (defun basic-save-buffer-1 ()
2030 (let (setmodes tempsetmodes) 2080 (let (tempsetmodes setmodes)
2031 (if (not (file-writable-p buffer-file-name)) 2081 (if (not (file-writable-p buffer-file-name))
2032 (let ((dir (file-name-directory buffer-file-name))) 2082 (let ((dir (file-name-directory buffer-file-name)))
2033 (if (not (file-directory-p dir)) 2083 (if (not (file-directory-p dir))
2034 (error "%s is not a directory" dir) 2084 (error "%s is not a directory" dir)
2035 (if (not (file-exists-p buffer-file-name)) 2085 (if (not (file-exists-p buffer-file-name))
2041 (setq tempsetmodes t) 2091 (setq tempsetmodes t)
2042 (error 2092 (error
2043 "Attempt to save to a file which you aren't allowed to write")))))) 2093 "Attempt to save to a file which you aren't allowed to write"))))))
2044 (or buffer-backed-up 2094 (or buffer-backed-up
2045 (setq setmodes (backup-buffer))) 2095 (setq setmodes (backup-buffer)))
2046 (let ((dir (file-name-directory buffer-file-name))) 2096 (let ((dir (file-name-directory buffer-file-name)))
2047 (if (and file-precious-flag 2097 (if (and file-precious-flag
2048 (file-writable-p dir)) 2098 (file-writable-p dir))
2049 ;; If file is precious, write temp name, then rename it. 2099 ;; If file is precious, write temp name, then rename it.
2050 ;; This requires write access to the containing dir, 2100 ;; This requires write access to the containing dir,
2051 ;; which is why we don't try it if we don't have that access. 2101 ;; which is why we don't try it if we don't have that access.
2052 (let ((realname buffer-file-name) 2102 (let ((realname buffer-file-name)
2053 tempname nogood i succeed 2103 tempname temp nogood i succeed
2054 (old-modtime (visited-file-modtime))) 2104 (old-modtime (visited-file-modtime)))
2055 (setq i 0) 2105 (setq i 0)
2056 (setq nogood t) 2106 (setq nogood t)
2057 ;; Find the temporary name to write under. 2107 ;; Find the temporary name to write under.
2058 (while nogood 2108 (while nogood
2059 (setq tempname (format "%s#tmp#%d" dir i)) 2109 (setq tempname (format
2110 (if (and (eq system-type 'ms-dos)
2111 (not (msdos-long-file-names)))
2112 "%s#%d.tm#" ; MSDOS limits files to 8+3
2113 "%s#tmp#%d")
2114 dir i))
2060 (setq nogood (file-exists-p tempname)) 2115 (setq nogood (file-exists-p tempname))
2061 (setq i (1+ i))) 2116 (setq i (1+ i)))
2062 (unwind-protect 2117 (unwind-protect
2063 (progn (clear-visited-file-modtime) 2118 (progn (clear-visited-file-modtime)
2064 (write-region (point-min) (point-max) 2119 (write-region (point-min) (point-max)
2065 tempname nil realname 2120 tempname nil realname
2066 buffer-file-truename) 2121 buffer-file-truename)
2067 (setq succeed t)) 2122 (setq succeed t))
2068 ;; If writing the temp file fails, 2123 ;; If writing the temp file fails,
2069 ;; delete the temp file. 2124 ;; delete the temp file.
2070 (or succeed 2125 (or succeed
2071 (progn 2126 (progn
2072 (delete-file tempname) 2127 (delete-file tempname)
2073 (set-visited-file-modtime old-modtime)))) 2128 (set-visited-file-modtime old-modtime))))
2074 ;; Since we have created an entirely new file 2129 ;; Since we have created an entirely new file
2075 ;; and renamed it, make sure it gets the 2130 ;; and renamed it, make sure it gets the
2084 ;; (setmodes is set) because that says we're superseding. 2139 ;; (setmodes is set) because that says we're superseding.
2085 (cond ((and tempsetmodes (not setmodes)) 2140 (cond ((and tempsetmodes (not setmodes))
2086 ;; Change the mode back, after writing. 2141 ;; Change the mode back, after writing.
2087 (setq setmodes (file-modes buffer-file-name)) 2142 (setq setmodes (file-modes buffer-file-name))
2088 (set-file-modes buffer-file-name 511))) 2143 (set-file-modes buffer-file-name 511)))
2144 ;; XEmacs change to end of function
2089 (basic-write-file-data buffer-file-name buffer-file-truename))) 2145 (basic-write-file-data buffer-file-name buffer-file-truename)))
2090 (setq buffer-file-number 2146 (setq buffer-file-number
2091 (if buffer-file-name 2147 (if buffer-file-name
2092 (nth 10 (file-attributes buffer-file-name)) 2148 (nth 10 (file-attributes buffer-file-name))
2093 nil)) 2149 nil))
2127 Optional argument (the prefix) non-nil means save all with no questions. 2183 Optional argument (the prefix) non-nil means save all with no questions.
2128 Optional second argument EXITING means ask about certain non-file buffers 2184 Optional second argument EXITING means ask about certain non-file buffers
2129 as well as about file buffers." 2185 as well as about file buffers."
2130 (interactive "P") 2186 (interactive "P")
2131 (save-window-excursion 2187 (save-window-excursion
2188 ;; XEmacs - do not use queried flag
2132 (let ((files-done 2189 (let ((files-done
2133 (map-y-or-n-p 2190 (map-y-or-n-p
2134 (function 2191 (function
2135 (lambda (buffer) 2192 (lambda (buffer)
2136 (and (buffer-modified-p buffer) 2193 (and (buffer-modified-p buffer)
2237 "Return most recent backup file for FILENAME or nil if no backups exist." 2294 "Return most recent backup file for FILENAME or nil if no backups exist."
2238 (let* ((filename (expand-file-name filename)) 2295 (let* ((filename (expand-file-name filename))
2239 (file (file-name-nondirectory filename)) 2296 (file (file-name-nondirectory filename))
2240 (dir (file-name-directory filename)) 2297 (dir (file-name-directory filename))
2241 (comp (file-name-all-completions file dir)) 2298 (comp (file-name-all-completions file dir))
2242 newest) 2299 newest tem)
2243 (while comp 2300 (while comp
2244 (setq file (concat dir (car comp)) 2301 (setq tem (car comp)
2245 comp (cdr comp)) 2302 comp (cdr comp))
2246 (if (and (backup-file-name-p file) 2303 (cond ((and (backup-file-name-p tem)
2247 (or (null newest) (file-newer-than-file-p file newest))) 2304 (string= (file-name-sans-versions tem) file))
2248 (setq newest file))) 2305 (setq tem (concat dir tem))
2306 (if (or (null newest)
2307 (file-newer-than-file-p tem newest))
2308 (setq newest tem)))))
2249 newest)) 2309 newest))
2250 2310
2251 (defun rename-uniquely () 2311 (defun rename-uniquely ()
2252 "Rename current buffer to a similar name not already taken. 2312 "Rename current buffer to a similar name not already taken.
2253 This function is useful for creating multiple shell process buffers 2313 This function is useful for creating multiple shell process buffers
2268 (name (buffer-name new-buf))) 2328 (name (buffer-name new-buf)))
2269 (kill-buffer new-buf) 2329 (kill-buffer new-buf)
2270 (rename-buffer name) 2330 (rename-buffer name)
2271 (redraw-modeline)))) 2331 (redraw-modeline))))
2272 2332
2333 ;; XEmacs
2273 (defun make-directory-path (path) 2334 (defun make-directory-path (path)
2274 "Create all the directories along path that don't exist yet." 2335 "Create all the directories along path that don't exist yet."
2275 (interactive "Fdirectory path to create: ") 2336 (interactive "Fdirectory path to create: ")
2276 (make-directory path t)) 2337 (make-directory path t))
2277 2338
2281 is the current default directory for file names. 2342 is the current default directory for file names.
2282 That is useful when you have visited a file in a nonexistent directory. 2343 That is useful when you have visited a file in a nonexistent directory.
2283 2344
2284 Noninteractively, the second (optional) argument PARENTS says whether 2345 Noninteractively, the second (optional) argument PARENTS says whether
2285 to create parent directories if they don't exist." 2346 to create parent directories if they don't exist."
2347 ;; XEmacs
2286 (interactive (list (let ((current-prefix-arg current-prefix-arg)) 2348 (interactive (list (let ((current-prefix-arg current-prefix-arg))
2287 (read-directory-name "Create directory: ")) 2349 (read-directory-name "Create directory: "))
2288 current-prefix-arg)) 2350 current-prefix-arg))
2289 (let ((handler (find-file-name-handler dir 'make-directory))) 2351 (let ((handler (find-file-name-handler dir 'make-directory)))
2290 (if handler 2352 (if handler
2324 hook functions. 2386 hook functions.
2325 2387
2326 If `revert-buffer-function' is used to override the normal revert 2388 If `revert-buffer-function' is used to override the normal revert
2327 mechanism, this hook is not used.") 2389 mechanism, this hook is not used.")
2328 2390
2329 (defun revert-buffer (&optional ignore-auto noconfirm) 2391 (defun revert-buffer (&optional ignore-auto noconfirm preserve-modes)
2330 "Replace the buffer text with the text of the visited file on disk. 2392 "Replace the buffer text with the text of the visited file on disk.
2331 This undoes all changes since the file was visited or saved. 2393 This undoes all changes since the file was visited or saved.
2332 With a prefix argument, offer to revert from latest auto-save file, if 2394 With a prefix argument, offer to revert from latest auto-save file, if
2333 that is more recent than the visited file. 2395 that is more recent than the visited file.
2334 When called from Lisp, the first argument is IGNORE-AUTO; only offer 2396 When called from Lisp, the first argument is IGNORE-AUTO; only offer
2354 (interactive (list (not current-prefix-arg))) 2416 (interactive (list (not current-prefix-arg)))
2355 (if revert-buffer-function 2417 (if revert-buffer-function
2356 (funcall revert-buffer-function ignore-auto noconfirm) 2418 (funcall revert-buffer-function ignore-auto noconfirm)
2357 (let* ((opoint (point)) 2419 (let* ((opoint (point))
2358 (auto-save-p (and (not ignore-auto) 2420 (auto-save-p (and (not ignore-auto)
2359 (recent-auto-save-p) 2421 (recent-auto-save-p)
2360 buffer-auto-save-file-name 2422 buffer-auto-save-file-name
2361 (file-readable-p buffer-auto-save-file-name) 2423 (file-readable-p buffer-auto-save-file-name)
2362 (y-or-n-p 2424 (y-or-n-p
2363 "Buffer has been auto-saved recently. Revert from auto-save file? "))) 2425 "Buffer has been auto-saved recently. Revert from auto-save file? ")))
2364 (file-name (if auto-save-p 2426 (file-name (if auto-save-p
2379 (or (eq buffer-undo-list t) 2441 (or (eq buffer-undo-list t)
2380 (setq buffer-undo-list nil)) 2442 (setq buffer-undo-list nil))
2381 ;; Effectively copy the after-revert-hook status, 2443 ;; Effectively copy the after-revert-hook status,
2382 ;; since after-find-file will clobber it. 2444 ;; since after-find-file will clobber it.
2383 (let ((global-hook (default-value 'after-revert-hook)) 2445 (let ((global-hook (default-value 'after-revert-hook))
2446 ;; XEmacs
2384 (local-hook-p (local-variable-p 'after-revert-hook 2447 (local-hook-p (local-variable-p 'after-revert-hook
2385 (current-buffer))) 2448 (current-buffer)))
2386 (local-hook (and (local-variable-p 'after-revert-hook 2449 (local-hook (and (local-variable-p 'after-revert-hook
2387 (current-buffer)) 2450 (current-buffer))
2388 after-revert-hook))) 2451 after-revert-hook)))
2405 (goto-char (min opoint (point-max))) 2468 (goto-char (min opoint (point-max)))
2406 ;; Recompute the truename in case changes in symlinks 2469 ;; Recompute the truename in case changes in symlinks
2407 ;; have changed the truename. 2470 ;; have changed the truename.
2408 ;XEmacs: already done by insert-file-contents 2471 ;XEmacs: already done by insert-file-contents
2409 ;(compute-buffer-file-truename) 2472 ;(compute-buffer-file-truename)
2410 (after-find-file nil nil t t) 2473 (after-find-file nil nil t t preserve-modes)
2411 ;; Run after-revert-hook as it was before we reverted. 2474 ;; Run after-revert-hook as it was before we reverted.
2412 (setq-default revert-buffer-internal-hook global-hook) 2475 (setq-default revert-buffer-internal-hook global-hook)
2413 (if local-hook-p 2476 (if local-hook-p
2414 (progn 2477 (progn
2415 (make-local-variable 'revert-buffer-internal-hook) 2478 (make-local-variable 'revert-buffer-internal-hook)
2423 ;; Actually putting the file name in the minibuffer should be used 2486 ;; Actually putting the file name in the minibuffer should be used
2424 ;; only rarely. 2487 ;; only rarely.
2425 ;; Not just because users often use the default. 2488 ;; Not just because users often use the default.
2426 (interactive "FRecover file: ") 2489 (interactive "FRecover file: ")
2427 (setq file (expand-file-name file)) 2490 (setq file (expand-file-name file))
2428 (if (auto-save-file-name-p file) 2491 (if (auto-save-file-name-p (file-name-nondirectory file))
2429 (error "%s is an auto-save file" file)) 2492 (error "%s is an auto-save file" file))
2430 (let ((file-name (let ((buffer-file-name file)) 2493 (let ((file-name (let ((buffer-file-name file))
2431 (make-auto-save-file-name)))) 2494 (make-auto-save-file-name))))
2432 (cond ((if (file-exists-p file) 2495 (cond ((if (file-exists-p file)
2433 (not (file-newer-than-file-p file-name file)) 2496 (not (file-newer-than-file-p file-name file))
2453 This command first displays a Dired buffer showing you the 2516 This command first displays a Dired buffer showing you the
2454 previous sessions that you could recover from. 2517 previous sessions that you could recover from.
2455 To choose one, move point to the proper line and then type C-c C-c. 2518 To choose one, move point to the proper line and then type C-c C-c.
2456 Then you'll be asked about a number of files to recover." 2519 Then you'll be asked about a number of files to recover."
2457 (interactive) 2520 (interactive)
2458 (dired (concat auto-save-list-file-prefix "*")) 2521 (let ((ls-lisp-support-shell-wildcards t))
2522 (dired (concat auto-save-list-file-prefix "*")))
2459 (goto-char (point-min)) 2523 (goto-char (point-min))
2460 (or (looking-at "Move to the session you want to recover,") 2524 (or (looking-at "Move to the session you want to recover,")
2461 (let ((inhibit-read-only t)) 2525 (let ((inhibit-read-only t))
2462 (insert "Move to the session you want to recover,\n" 2526 (insert "Move to the session you want to recover,\n"
2463 "then type C-c C-c to select it.\n\n" 2527 "then type C-c C-c to select it.\n\n"
2464 "You can also delete some of these files;\n" 2528 "You can also delete some of these files;\n"
2465 "type d on a line to mark that file for deletion.\n\n"))) 2529 "type d on a line to mark that file for deletion.\n\n")))
2530 ;; XEmacs
2466 (use-local-map (let ((map (make-sparse-keymap))) 2531 (use-local-map (let ((map (make-sparse-keymap)))
2467 (set-keymap-parents map (list (current-local-map))) 2532 (set-keymap-parents map (list (current-local-map)))
2468 map)) 2533 map))
2469 (define-key (current-local-map) "\C-c\C-c" 'recover-session-finish)) 2534 (define-key (current-local-map) "\C-c\C-c" 'recover-session-finish))
2470 2535
2530 (if files 2595 (if files
2531 (map-y-or-n-p "Recover %s? " 2596 (map-y-or-n-p "Recover %s? "
2532 (lambda (file) 2597 (lambda (file)
2533 (condition-case nil 2598 (condition-case nil
2534 (save-excursion (recover-file file)) 2599 (save-excursion (recover-file file))
2535 (error 2600 (error
2536 "Failed to recover `%s'" file))) 2601 "Failed to recover `%s'" file)))
2537 files 2602 files
2538 '("file" "files" "recover")) 2603 '("file" "files" "recover"))
2539 (message "No files can be recovered from this session now"))) 2604 (message "No files can be recovered from this session now")))
2540 (kill-buffer buffer)))) 2605 (kill-buffer buffer))))
2547 (let* ((buffer (car list)) 2612 (let* ((buffer (car list))
2548 (name (buffer-name buffer))) 2613 (name (buffer-name buffer)))
2549 (and (not (string-equal name "")) 2614 (and (not (string-equal name ""))
2550 (/= (aref name 0) ? ) 2615 (/= (aref name 0) ? )
2551 (yes-or-no-p 2616 (yes-or-no-p
2617 ;; XEmacs change
2552 (format 2618 (format
2553 (if (buffer-modified-p buffer) 2619 (if (buffer-modified-p buffer)
2554 (gettext "Buffer %s HAS BEEN EDITED. Kill? ") 2620 (gettext "Buffer %s HAS BEEN EDITED. Kill? ")
2555 (gettext "Buffer %s is unmodified. Kill? ")) 2621 (gettext "Buffer %s is unmodified. Kill? "))
2556 name)) 2622 name))
2594 (file-exists-p osave) 2660 (file-exists-p osave)
2595 (recent-auto-save-p)) 2661 (recent-auto-save-p))
2596 (rename-file osave buffer-auto-save-file-name t)))) 2662 (rename-file osave buffer-auto-save-file-name t))))
2597 2663
2598 ;; see also ../packages/auto-save.el 2664 ;; see also ../packages/auto-save.el
2665 ;; XEmacs change
2599 (defun make-auto-save-file-name (&optional filename) 2666 (defun make-auto-save-file-name (&optional filename)
2600 "Return file name to use for auto-saves of current buffer. 2667 "Return file name to use for auto-saves of current buffer.
2601 Does not consider `auto-save-visited-file-name' as that variable is checked 2668 Does not consider `auto-save-visited-file-name' as that variable is checked
2602 before calling this function. You can redefine this for customization. 2669 before calling this function. You can redefine this for customization.
2603 See also `auto-save-file-name-p'." 2670 See also `auto-save-file-name-p'."
2656 name 2723 name
2657 (expand-file-name (concat "~/" (file-name-nondirectory name)))))) 2724 (expand-file-name (concat "~/" (file-name-nondirectory name))))))
2658 2725
2659 (defun auto-save-file-name-p (filename) 2726 (defun auto-save-file-name-p (filename)
2660 "Return non-nil if FILENAME can be yielded by `make-auto-save-file-name'. 2727 "Return non-nil if FILENAME can be yielded by `make-auto-save-file-name'.
2661 FILENAME should lack slashes. 2728 FILENAME should lack slashes. You can redefine this for customization."
2662 You can redefine this for customization."
2663 (string-match "\\`#.*#\\'" filename)) 2729 (string-match "\\`#.*#\\'" filename))
2730
2731 (defun wildcard-to-regexp (wildcard)
2732 "Given a shell file name pattern WILDCARD, return an equivalent regexp.
2733 The generated regexp will match a filename iff the filename
2734 matches that wildcard according to shell rules. Only wildcards known
2735 by `sh' are supported."
2736 (let* ((i (string-match "[[.*+\\^$?]" wildcard))
2737 ;; Copy the initial run of non-special characters.
2738 (result (substring wildcard 0 i))
2739 (len (length wildcard)))
2740 ;; If no special characters, we're almost done.
2741 (if i
2742 (while (< i len)
2743 (let ((ch (aref wildcard i))
2744 j)
2745 (setq
2746 result
2747 (concat result
2748 (cond
2749 ((eq ch ?\[) ; [...] maps to regexp char class
2750 (progn
2751 (setq i (1+ i))
2752 (concat
2753 (cond
2754 ((eq (aref wildcard i) ?!) ; [!...] -> [^...]
2755 (progn
2756 (setq i (1+ i))
2757 (if (eq (aref wildcard i) ?\])
2758 (progn
2759 (setq i (1+ i))
2760 "[^]")
2761 "[^")))
2762 ((eq (aref wildcard i) ?^)
2763 ;; Found "[^". Insert a `\0' character
2764 ;; (which cannot happen in a filename)
2765 ;; into the character class, so that `^'
2766 ;; is not the first character after `[',
2767 ;; and thus non-special in a regexp.
2768 (progn
2769 (setq i (1+ i))
2770 "[\000^"))
2771 ((eq (aref wildcard i) ?\])
2772 ;; I don't think `]' can appear in a
2773 ;; character class in a wildcard, but
2774 ;; let's be general here.
2775 (progn
2776 (setq i (1+ i))
2777 "[]"))
2778 (t "["))
2779 (prog1 ; copy everything upto next `]'.
2780 (substring wildcard
2781 i
2782 (setq j (string-match
2783 "]" wildcard i)))
2784 (setq i (if j (1- j) (1- len)))))))
2785 ((eq ch ?.) "\\.")
2786 ((eq ch ?*) "[^\000]*")
2787 ((eq ch ?+) "\\+")
2788 ((eq ch ?^) "\\^")
2789 ((eq ch ?$) "\\$")
2790 ((eq ch ?\\) "\\\\") ; probably cannot happen...
2791 ((eq ch ??) "[^\000]")
2792 (t (char-to-string ch)))))
2793 (setq i (1+ i)))))
2794 ;; Shell wildcards should match the entire filename,
2795 ;; not its part. Make the regexp say so.
2796 (concat "\\`" result "\\'")))
2664 2797
2665 (defconst list-directory-brief-switches 2798 (defconst list-directory-brief-switches
2666 (if (eq system-type 'vax-vms) "" "-CF") 2799 (if (eq system-type 'vax-vms) "" "-CF")
2667 "*Switches for list-directory to pass to `ls' for brief listing,") 2800 "*Switches for list-directory to pass to `ls' for brief listing,")
2668 2801
2692 (princ "Directory ") 2825 (princ "Directory ")
2693 (princ dirname) 2826 (princ dirname)
2694 (terpri) 2827 (terpri)
2695 (save-excursion 2828 (save-excursion
2696 (set-buffer "*Directory*") 2829 (set-buffer "*Directory*")
2697 (setq default-directory (file-name-directory dirname)) 2830 (setq default-directory
2831 (if (file-directory-p dirname)
2832 (file-name-as-directory dirname)
2833 (file-name-directory dirname)))
2698 (let ((wildcard (not (file-directory-p dirname)))) 2834 (let ((wildcard (not (file-directory-p dirname))))
2699 (insert-directory dirname switches wildcard (not wildcard))))))) 2835 (insert-directory dirname switches wildcard (not wildcard)))))))
2700 2836
2701 (defvar insert-directory-program "ls" 2837 (defvar insert-directory-program "ls"
2702 "Absolute or relative name of the `ls' program used by `insert-directory'.") 2838 "Absolute or relative name of the `ls' program used by `insert-directory'.")
2738 wildcard full-directory-p) 2874 wildcard full-directory-p)
2739 (if (eq system-type 'vax-vms) 2875 (if (eq system-type 'vax-vms)
2740 (vms-read-directory file switches (current-buffer)) 2876 (vms-read-directory file switches (current-buffer))
2741 (if wildcard 2877 (if wildcard
2742 ;; Run ls in the directory of the file pattern we asked for. 2878 ;; Run ls in the directory of the file pattern we asked for.
2743 (let ((default-directory 2879 (let ((default-directory
2744 (if (file-name-absolute-p file) 2880 (if (file-name-absolute-p file)
2745 (file-name-directory file) 2881 (file-name-directory file)
2746 (file-name-directory (expand-file-name file)))) 2882 (file-name-directory (expand-file-name file))))
2747 (pattern (file-name-nondirectory file)) 2883 (pattern (file-name-nondirectory file))
2748 (beg 0)) 2884 (beg 0))
2749 ;; Quote some characters that have special meanings in shells; 2885 ;; Quote some characters that have special meanings in shells;
2750 ;; but don't quote the wildcards--we want them to be special. 2886 ;; but don't quote the wildcards--we want them to be special.
2751 ;; We also currently don't quote the quoting characters 2887 ;; We also currently don't quote the quoting characters
2752 ;; in case people want to use them explicitly to quote 2888 ;; in case people want to use them explicitly to quote
2753 ;; wildcard characters. 2889 ;; wildcard characters.
2754 ;;#### Unix-specific 2890 ;;#### Unix-specific
2755 (while (string-match "[ \t\n;<>&|()#$]" pattern beg) 2891 (while (string-match "[ \t\n;<>&|()#$]" pattern beg)
2756 (setq pattern 2892 (setq pattern
2757 (concat (substring pattern 0 (match-beginning 0)) 2893 (concat (substring pattern 0 (match-beginning 0))
2758 "\\" 2894 "\\"
2759 (substring pattern (match-beginning 0))) 2895 (substring pattern (match-beginning 0)))
2780 ;; so we can pass separate options as separate args. 2916 ;; so we can pass separate options as separate args.
2781 (while (string-match " " switches) 2917 (while (string-match " " switches)
2782 (setq list (cons (substring switches 0 (match-beginning 0)) 2918 (setq list (cons (substring switches 0 (match-beginning 0))
2783 list) 2919 list)
2784 switches (substring switches (match-end 0)))) 2920 switches (substring switches (match-end 0))))
2785 (setq list (cons switches list))))) 2921 (setq list (nreverse (cons switches list))))))
2786 (append list 2922 (append list
2787 (list 2923 (list
2788 (if full-directory-p 2924 (if full-directory-p
2789 (concat (file-name-as-directory file) 2925 (concat (file-name-as-directory file)
2790 ;;#### Unix-specific 2926 ;;#### Unix-specific
2822 (yes-or-no-p "Active processes exist; kill them and exit anyway? ")))) 2958 (yes-or-no-p "Active processes exist; kill them and exit anyway? "))))
2823 ;; Query the user for other things, perhaps. 2959 ;; Query the user for other things, perhaps.
2824 (run-hook-with-args-until-failure 'kill-emacs-query-functions) 2960 (run-hook-with-args-until-failure 'kill-emacs-query-functions)
2825 (kill-emacs))) 2961 (kill-emacs)))
2826 2962
2963 ;; XEmacs
2827 (defun symlink-expand-file-name (filename) 2964 (defun symlink-expand-file-name (filename)
2828 "If FILENAME is a symlink, return its non-symlink equivalent. 2965 "If FILENAME is a symlink, return its non-symlink equivalent.
2829 Unlike `file-truename', this doesn't chase symlinks in directory 2966 Unlike `file-truename', this doesn't chase symlinks in directory
2830 components of the file or expand a relative pathname into an 2967 components of the file or expand a relative pathname into an
2831 absolute one." 2968 absolute one."
2836 (if (> count 0) 2973 (if (> count 0)
2837 filename 2974 filename
2838 (error "Apparently circular symlink path")))) 2975 (error "Apparently circular symlink path"))))
2839 2976
2840 2977
2841 2978 ;; Written in C in FSF
2842 (defun insert-file-contents (filename &optional visit beg end replace) 2979 (defun insert-file-contents (filename &optional visit beg end replace)
2843 "Insert contents of file FILENAME after point. 2980 "Insert contents of file FILENAME after point.
2844 Returns list of absolute file name and length of data inserted. 2981 Returns list of absolute file name and length of data inserted.
2845 If second argument VISIT is non-nil, the buffer's visited filename 2982 If second argument VISIT is non-nil, the buffer's visited filename
2846 and last save file modtime are set, and it is marked unmodified. 2983 and last save file modtime are set, and it is marked unmodified.
2855 with the file contents. This is better than simply deleting and inserting 2992 with the file contents. This is better than simply deleting and inserting
2856 the whole thing because (1) it preserves some marker positions 2993 the whole thing because (1) it preserves some marker positions
2857 and (2) it puts less data in the undo list." 2994 and (2) it puts less data in the undo list."
2858 (insert-file-contents-internal filename visit beg end replace)) 2995 (insert-file-contents-internal filename visit beg end replace))
2859 2996
2997 ;; Written in C in FSF
2860 (defun write-region (start end filename &optional append visit lockname) 2998 (defun write-region (start end filename &optional append visit lockname)
2861 "Write current region into specified file. 2999 "Write current region into specified file.
2862 When called from a program, takes three arguments: 3000 When called from a program, takes three arguments:
2863 START, END and FILENAME. START and END are buffer positions. 3001 START, END and FILENAME. START and END are buffer positions.
2864 Optional fourth argument APPEND if non-nil means 3002 Optional fourth argument APPEND if non-nil means
2876 Kludgy feature: if START is a string, then that string is written 3014 Kludgy feature: if START is a string, then that string is written
2877 to the file, instead of any buffer contents, and END is ignored." 3015 to the file, instead of any buffer contents, and END is ignored."
2878 (interactive "r\nFWrite region to file: ") 3016 (interactive "r\nFWrite region to file: ")
2879 (write-region-internal start end filename append visit lockname)) 3017 (write-region-internal start end filename append visit lockname))
2880 3018
3019 ;; Written in C in FSF
2881 (defun load (file &optional noerror nomessage nosuffix) 3020 (defun load (file &optional noerror nomessage nosuffix)
2882 "Execute a file of Lisp code named FILE. 3021 "Execute a file of Lisp code named FILE.
2883 First try FILE with `.elc' appended, then try with `.el', 3022 First try FILE with `.elc' appended, then try with `.el',
2884 then try FILE unmodified. 3023 then try FILE unmodified.
2885 This function searches the directories in `load-path'. 3024 This function searches the directories in `load-path'.
2890 If optional fourth arg NOSUFFIX is non-nil, don't try adding 3029 If optional fourth arg NOSUFFIX is non-nil, don't try adding
2891 suffixes `.elc' or `.el' to the specified name FILE. 3030 suffixes `.elc' or `.el' to the specified name FILE.
2892 Return t if file exists." 3031 Return t if file exists."
2893 (load-internal file noerror nomessage nosuffix)) 3032 (load-internal file noerror nomessage nosuffix))
2894 3033
3034 ;(define-key ctl-x-map "\C-f" 'find-file)
3035 ;(define-key ctl-x-map "\C-q" 'toggle-read-only)
3036 ;(define-key ctl-x-map "\C-r" 'find-file-read-only)
3037 ;(define-key ctl-x-map "\C-v" 'find-alternate-file)
3038 ;(define-key ctl-x-map "\C-s" 'save-buffer)
3039 ;(define-key ctl-x-map "s" 'save-some-buffers)
3040 ;(define-key ctl-x-map "\C-w" 'write-file)
3041 ;(define-key ctl-x-map "i" 'insert-file)
3042 ;(define-key esc-map "~" 'not-modified)
3043 ;(define-key ctl-x-map "\C-d" 'list-directory)
3044 ;(define-key ctl-x-map "\C-c" 'save-buffers-kill-emacs)
3045
3046 ;(define-key ctl-x-4-map "f" 'find-file-other-window)
3047 ;(define-key ctl-x-4-map "r" 'find-file-read-only-other-window)
3048 ;(define-key ctl-x-4-map "\C-f" 'find-file-other-window)
3049 ;(define-key ctl-x-4-map "b" 'switch-to-buffer-other-window)
3050 ;(define-key ctl-x-4-map "\C-o" 'display-buffer)
3051
3052 ;(define-key ctl-x-5-map "b" 'switch-to-buffer-other-frame)
3053 ;(define-key ctl-x-5-map "f" 'find-file-other-frame)
3054 ;(define-key ctl-x-5-map "\C-f" 'find-file-other-frame)
3055 ;(define-key ctl-x-5-map "r" 'find-file-read-only-other-frame)
3056
2895 ;;; files.el ends here 3057 ;;; files.el ends here