Mercurial > hg > xemacs-beta
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 |