comparison lisp/files.el @ 280:7df0dd720c89 r21-0b38

Import from CVS: tag r21-0b38
author cvs
date Mon, 13 Aug 2007 10:32:22 +0200
parents 6330739388db
children c42ec1d1cded
comparison
equal deleted inserted replaced
279:c20b2fb5bb0a 280:7df0dd720c89
21 ;; You should have received a copy of the GNU General Public License 21 ;; You should have received a copy of the GNU General Public License
22 ;; along with XEmacs; see the file COPYING. If not, write to the Free 22 ;; along with XEmacs; see the file COPYING. If not, write to the Free
23 ;; Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 23 ;; Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA
24 ;; 02111-1307, USA. 24 ;; 02111-1307, USA.
25 25
26 ;;; Synched up with: FSF 19.34 [Partial]. 26 ;;; Synched up with: FSF 20.3 (but diverging)
27 ;;; Warning: Merging this file is tough. Beware. 27 ;;; Warning: Merging this file is tough. Beware.
28 28
29 ;;; Commentary: 29 ;;; Commentary:
30 30
31 ;; This file is dumped with XEmacs. 31 ;; This file is dumped with XEmacs.
494 494
495 ;; XEmacs change block 495 ;; XEmacs change block
496 ; We have this in C and use the realpath() system call. 496 ; We have this in C and use the realpath() system call.
497 497
498 ;(defun file-truename (filename &optional counter prev-dirs) 498 ;(defun file-truename (filename &optional counter prev-dirs)
499 ; "Return the truename of FILENAME, which should be absolute. 499 ; [... lots of code snipped ...]
500 ;The truename of a file name is found by chasing symbolic links
501 ;both at the level of the file and at the level of the directories
502 ;containing it, until no links are left at any level.
503 ;
504 ;The arguments COUNTER and PREV-DIRS are used only in recursive calls.
505 ;Do not specify them in other calls."
506 ; ;; COUNTER can be a cons cell whose car is the count of how many more links
507 ; ;; to chase before getting an error.
508 ; ;; PREV-DIRS can be a cons cell whose car is an alist
509 ; ;; of truenames we've just recently computed.
510 ; ;; The last test looks dubious, maybe `+' is meant here? --simon.
511 ; (if (or (string= filename "") (string= filename "~")
512 ; (and (string= (substring filename 0 1) "~")
513 ; (string-match "~[^/]*" filename)))
514 ; (progn
515 ; (setq filename (expand-file-name filename))
516 ; (if (string= filename "")
517 ; (setq filename "/"))))
518 ; (or counter (setq counter (list 100)))
519 ; (let (done
520 ; ;; For speed, remove the ange-ftp completion handler from the list.
521 ; ;; We know it's not needed here.
522 ; ;; For even more speed, do this only on the outermost call.
523 ; (file-name-handler-alist
524 ; (if prev-dirs file-name-handler-alist
525 ; (let ((tem (copy-sequence file-name-handler-alist)))
526 ; (delq (rassq 'ange-ftp-completion-hook-function tem) tem)))))
527 ; (or prev-dirs (setq prev-dirs (list nil)))
528 ; ;; If this file directly leads to a link, process that iteratively
529 ; ;; so that we don't use lots of stack.
530 ; (while (not done)
531 ; (setcar counter (1- (car counter)))
532 ; (if (< (car counter) 0)
533 ; (error "Apparent cycle of symbolic links for %s" filename))
534 ; (let ((handler (find-file-name-handler filename 'file-truename)))
535 ; ;; For file name that has a special handler, call handler.
536 ; ;; This is so that ange-ftp can save time by doing a no-op.
537 ; (if handler
538 ; (setq filename (funcall handler 'file-truename filename)
539 ; done t)
540 ; (let ((dir (or (file-name-directory filename) default-directory))
541 ; target dirfile)
542 ; ;; Get the truename of the directory.
543 ; (setq dirfile (directory-file-name dir))
544 ; ;; If these are equal, we have the (or a) root directory.
545 ; (or (string= dir dirfile)
546 ; ;; If this is the same dir we last got the truename for,
547 ; ;; save time--don't recalculate.
548 ; (if (assoc dir (car prev-dirs))
549 ; (setq dir (cdr (assoc dir (car prev-dirs))))
550 ; (let ((old dir)
551 ; (new (file-name-as-directory (file-truename dirfile counter prev-dirs))))
552 ; (setcar prev-dirs (cons (cons old new) (car prev-dirs)))
553 ; (setq dir new))))
554 ; (if (equal ".." (file-name-nondirectory filename))
555 ; (setq filename
556 ; (directory-file-name (file-name-directory (directory-file-name dir)))
557 ; done t)
558 ; (if (equal "." (file-name-nondirectory filename))
559 ; (setq filename (directory-file-name dir)
560 ; done t)
561 ; ;; Put it back on the file name.
562 ; (setq filename (concat dir (file-name-nondirectory filename)))
563 ; ;; Is the file name the name of a link?
564 ; (setq target (file-symlink-p filename))
565 ; (if target
566 ; ;; Yes => chase that link, then start all over
567 ; ;; since the link may point to a directory name that uses links.
568 ; ;; We can't safely use expand-file-name here
569 ; ;; since target might look like foo/../bar where foo
570 ; ;; is itself a link. Instead, we handle . and .. above.
571 ; (setq filename
572 ; (if (file-name-absolute-p target)
573 ; target
574 ; (concat dir target))
575 ; done nil)
576 ; ;; No, we are done!
577 ; (setq done t))))))))
578 ; filename)) 500 ; filename))
579 501
580 ;; XEmacs addition. Called from `insert-file-contents-internal' 502 ;; XEmacs addition. Called from `insert-file-contents-internal'
581 ;; at the appropriate time. 503 ;; at the appropriate time.
582 (defun compute-buffer-file-truename (&optional buffer) 504 (defun compute-buffer-file-truename (&optional buffer)
608 "Chase links in FILENAME until a name that is not a link. 530 "Chase links in FILENAME until a name that is not a link.
609 Does not examine containing directories for links, 531 Does not examine containing directories for links,
610 unlike `file-truename'." 532 unlike `file-truename'."
611 (let (tem (count 100) (newname filename)) 533 (let (tem (count 100) (newname filename))
612 (while (setq tem (file-symlink-p newname)) 534 (while (setq tem (file-symlink-p newname))
613 (if (= count 0) 535 (save-match-data
614 (error "Apparent cycle of symbolic links for %s" filename)) 536 (if (= count 0)
615 ;; In the context of a link, `//' doesn't mean what XEmacs thinks. 537 (error "Apparent cycle of symbolic links for %s" filename))
616 (while (string-match "//+" tem) 538 ;; In the context of a link, `//' doesn't mean what XEmacs thinks.
617 (setq tem (concat (substring tem 0 (1+ (match-beginning 0))) 539 (while (string-match "//+" tem)
618 (substring tem (match-end 0))))) 540 (setq tem (concat (substring tem 0 (1+ (match-beginning 0)))
619 ;; Handle `..' by hand, since it needs to work in the 541 (substring tem (match-end 0)))))
620 ;; target of any directory symlink. 542 ;; Handle `..' by hand, since it needs to work in the
621 ;; This code is not quite complete; it does not handle 543 ;; target of any directory symlink.
622 ;; embedded .. in some cases such as ./../foo and foo/bar/../../../lose. 544 ;; This code is not quite complete; it does not handle
623 (while (string-match "\\`\\.\\./" tem) ;#### Unix specific 545 ;; embedded .. in some cases such as ./../foo and foo/bar/../../../lose.
624 (setq tem (substring tem 3)) 546 (while (string-match "\\`\\.\\./" tem) ;#### Unix specific
625 (setq newname (file-name-as-directory 547 (setq tem (substring tem 3))
626 ;; Do the .. by hand. 548 (setq newname (file-name-as-directory
627 (directory-file-name 549 ;; Do the .. by hand.
628 (file-name-directory 550 (directory-file-name
629 ;; Chase links in the default dir of the symlink. 551 (file-name-directory
630 (file-chase-links 552 ;; Chase links in the default dir of the symlink.
631 (directory-file-name 553 (file-chase-links
632 (file-name-directory newname)))))))) 554 (directory-file-name
633 (setq newname (expand-file-name tem (file-name-directory newname))) 555 (file-name-directory newname))))))))
634 (setq count (1- count))) 556 (setq newname (expand-file-name tem (file-name-directory newname)))
557 (setq count (1- count))))
635 newname)) 558 newname))
636 559
637 (defun switch-to-other-buffer (arg) 560 (defun switch-to-other-buffer (arg)
638 "Switch to the previous buffer. With a numeric arg, n, switch to the nth 561 "Switch to the previous buffer. With a numeric arg, n, switch to the nth
639 most recent buffer. With an arg of 0, buries the current buffer at the 562 most recent buffer. With an arg of 0, buries the current buffer at the
911 :type '(repeat (string :tag "Name")) 834 :type '(repeat (string :tag "Name"))
912 :group 'find-file) 835 :group 'find-file)
913 836
914 ;; This function is needed by FSF vc.el. I hope somebody can make it 837 ;; This function is needed by FSF vc.el. I hope somebody can make it
915 ;; work for XEmacs. -sb. 838 ;; work for XEmacs. -sb.
839 ;; #### In what way does it not work? --hniksic
916 (defun find-buffer-visiting (filename) 840 (defun find-buffer-visiting (filename)
917 "Return the buffer visiting file FILENAME (a string). 841 "Return the buffer visiting file FILENAME (a string).
918 This is like `get-file-buffer', except that it checks for any buffer 842 This is like `get-file-buffer', except that it checks for any buffer
919 visiting the same file, possibly under a different name. 843 visiting the same file, possibly under a different name.
920 If there is no such live buffer, return nil." 844 If there is no such live buffer, return nil."
972 (defun find-file-noselect (filename &optional nowarn rawfile) 896 (defun find-file-noselect (filename &optional nowarn rawfile)
973 "Read file FILENAME into a buffer and return the buffer. 897 "Read file FILENAME into a buffer and return the buffer.
974 If a buffer exists visiting FILENAME, return that one, but 898 If a buffer exists visiting FILENAME, return that one, but
975 verify that the file has not changed since visited or saved. 899 verify that the file has not changed since visited or saved.
976 The buffer is not selected, just returned to the caller. 900 The buffer is not selected, just returned to the caller.
977 If NOWARN is non-nil, warning messages about several potential 901 If NOWARN is non-nil, warning messages will be suppressed.
978 problems will be suppressed." 902 If RAWFILE is non-nil, the file is read literally."
979 (setq filename (abbreviate-file-name (expand-file-name filename))) 903 (setq filename (abbreviate-file-name (expand-file-name filename)))
980 (if (file-directory-p filename) 904 (if (file-directory-p filename)
981 (if (and (fboundp 'dired-noselect) find-file-run-dired) 905 (if (and (fboundp 'dired-noselect) find-file-run-dired)
982 (dired-noselect (if find-file-use-truenames 906 (dired-noselect (if find-file-use-truenames
983 (abbreviate-file-name (file-truename filename)) 907 (abbreviate-file-name (file-truename filename))
984 filename)) 908 filename))
985 (error "%s is a directory." filename)) 909 (error "%s is a directory" filename))
986 (let* ((buf (get-file-buffer filename)) 910 (let* ((buf (get-file-buffer filename))
987 (truename (abbreviate-file-name (file-truename filename))) 911 (truename (abbreviate-file-name (file-truename filename)))
988 (number (nthcdr 10 (file-attributes (file-truename filename)))) 912 (number (nthcdr 10 (file-attributes truename)))
989 ; (number (and buffer-file-truename
990 ; (nthcdr 10 (file-attributes buffer-file-truename))))
991 ; ;; Find any buffer for a file which has same truename. 913 ; ;; Find any buffer for a file which has same truename.
992 ; (other (and (not buf) (find-buffer-visiting filename))) 914 ; (other (and (not buf) (find-buffer-visiting filename)))
993 (error nil)) 915 (error nil))
994 916
995 ; ;; Let user know if there is a buffer with the same truename. 917 ; ;; Let user know if there is a buffer with the same truename.
1020 (cond ((not (file-exists-p filename)) 942 (cond ((not (file-exists-p filename))
1021 (error "File %s no longer exists!" filename)) 943 (error "File %s no longer exists!" filename))
1022 ;; Certain files should be reverted automatically 944 ;; Certain files should be reverted automatically
1023 ;; if they have changed on disk and not in the buffer. 945 ;; if they have changed on disk and not in the buffer.
1024 ((and (not (buffer-modified-p buf)) 946 ((and (not (buffer-modified-p buf))
1025 (let (found) 947 (dolist (rx revert-without-query nil)
1026 (dolist (rx revert-without-query found) 948 (when (string-match rx filename)
1027 (when (string-match rx filename) 949 (return t))))
1028 (setq found t)))))
1029 (with-current-buffer buf 950 (with-current-buffer buf
1030 (message "Reverting file %s..." filename) 951 (message "Reverting file %s..." filename)
1031 (revert-buffer t t) 952 (revert-buffer t t)
1032 (message "Reverting file %s... done" filename))) 953 (message "Reverting file %s... done" filename)))
1033 ((yes-or-no-p 954 ((yes-or-no-p
1042 (if (buffer-modified-p buf) 963 (if (buffer-modified-p buf)
1043 (gettext "File %s changed on disk. Discard your edits in %s? ") 964 (gettext "File %s changed on disk. Discard your edits in %s? ")
1044 (gettext "File %s changed on disk. Reread from disk into %s? ")) 965 (gettext "File %s changed on disk. Reread from disk into %s? "))
1045 (file-name-nondirectory filename) 966 (file-name-nondirectory filename)
1046 (buffer-name buf)))) 967 (buffer-name buf))))
1047 (save-excursion 968 (with-current-buffer buf
1048 (set-buffer buf)
1049 (revert-buffer t t))))) 969 (revert-buffer t t)))))
1050 ;; Else: we must create a new buffer for filename 970 ;; Else: we must create a new buffer for filename
1051 (save-excursion 971 (save-excursion
1052 ;;; The truename stuff makes this obsolete. 972 ;;; The truename stuff makes this obsolete.
1053 ;;; (let* ((link-name (car (file-attributes filename))) 973 ;;; (let* ((link-name (car (file-attributes filename)))
1062 (erase-buffer) 982 (erase-buffer)
1063 (if rawfile 983 (if rawfile
1064 (condition-case () 984 (condition-case ()
1065 (insert-file-contents-literally filename t) 985 (insert-file-contents-literally filename t)
1066 (file-error 986 (file-error
987 (when (and (file-exists-p filename)
988 (not (file-readable-p filename)))
989 (kill-buffer buf)
990 (signal 'file-error (list "File is not readable" filename)))
1067 ;; Unconditionally set error 991 ;; Unconditionally set error
1068 (setq error t))) 992 (setq error t)))
1069 (condition-case e 993 (condition-case ()
1070 (insert-file-contents filename t) 994 (insert-file-contents filename t)
1071 (file-error 995 (file-error
996 (when (and (file-exists-p filename)
997 (not (file-readable-p filename)))
998 (kill-buffer buf)
999 (signal 'file-error (list "File is not readable" filename)))
1072 ;; Run find-file-not-found-hooks until one returns non-nil. 1000 ;; Run find-file-not-found-hooks until one returns non-nil.
1073 (or (run-hook-with-args-until-success 'find-file-not-found-hooks) 1001 (or (run-hook-with-args-until-success 'find-file-not-found-hooks)
1074 ;; If they fail too, set error. 1002 ;; If they fail too, set error.
1075 (setq error e))))) 1003 (setq error t)))))
1076 ;; Find the file's truename, and maybe use that as visited name. 1004 ;; Find the file's truename, and maybe use that as visited name.
1077 ;; automatically computed in XEmacs, unless jka-compr was used! 1005 ;; automatically computed in XEmacs, unless jka-compr was used!
1078 (unless buffer-file-truename 1006 (unless buffer-file-truename
1079 (setq buffer-file-truename truename)) 1007 (setq buffer-file-truename truename))
1080 (setq buffer-file-number number) 1008 (setq buffer-file-number number)
1085 (if (string-match ":" (file-name-directory filename)) 1013 (if (string-match ":" (file-name-directory filename))
1086 (setq logical (substring (file-name-directory filename) 1014 (setq logical (substring (file-name-directory filename)
1087 0 (match-beginning 0)))) 1015 0 (match-beginning 0))))
1088 (not (member logical find-file-not-true-dirname-list))) 1016 (not (member logical find-file-not-true-dirname-list)))
1089 (setq buffer-file-name buffer-file-truename)) 1017 (setq buffer-file-name buffer-file-truename))
1090 ; (if find-file-visit-truename
1091 ; (setq buffer-file-name
1092 ; (setq filename
1093 ; (expand-file-name buffer-file-truename))))
1094 (and find-file-use-truenames 1018 (and find-file-use-truenames
1095 ;; This should be in C. Put pathname abbreviations that have 1019 ;; This should be in C. Put pathname abbreviations that have
1096 ;; been explicitly requested back into the pathname. Most 1020 ;; been explicitly requested back into the pathname. Most
1097 ;; importantly, strip out automounter /tmp_mnt directories so 1021 ;; importantly, strip out automounter /tmp_mnt directories so
1098 ;; that auto-save will work 1022 ;; that auto-save will work
1104 (and (not (funcall backup-enable-predicate buffer-file-name)) 1028 (and (not (funcall backup-enable-predicate buffer-file-name))
1105 (progn 1029 (progn
1106 (make-local-variable 'backup-inhibited) 1030 (make-local-variable 'backup-inhibited)
1107 (setq backup-inhibited t))) 1031 (setq backup-inhibited t)))
1108 (if rawfile 1032 (if rawfile
1033 ;; #### FSF 20.3 sets buffer-file-coding-system to
1034 ;; `no-conversion' here. Should we copy? It also makes
1035 ;; `find-file-literally' a local variable and sets it to t.
1109 nil 1036 nil
1110 (after-find-file error (not nowarn)) 1037 (after-find-file error (not nowarn))
1111 (setq buf (current-buffer))))) 1038 (setq buf (current-buffer)))))
1112 buf))) 1039 buf)))
1113 1040
1041 ;; FSF has `insert-file-literally' and `find-file-literally' here.
1042
1114 (defvar after-find-file-from-revert-buffer nil) 1043 (defvar after-find-file-from-revert-buffer nil)
1115 1044
1116 (defun after-find-file (&optional error warn noauto 1045 (defun after-find-file (&optional error warn noauto
1117 after-find-file-from-revert-buffer 1046 after-find-file-from-revert-buffer
1118 nomodes) 1047 nomodes)
1193 (error (message "File mode specification error: %s" 1122 (error (message "File mode specification error: %s"
1194 (prin1-to-string err)) 1123 (prin1-to-string err))
1195 nil)) 1124 nil))
1196 (condition-case err 1125 (condition-case err
1197 (hack-local-variables (not find-file)) 1126 (hack-local-variables (not find-file))
1198 (error (message "File local-variables error: %s" 1127 (error (lwarn 'local-variables 'warning
1199 (prin1-to-string err)))))) 1128 "File local-variables error: %s"
1129 (error-message-string err))))))
1200 1130
1201 (defvar auto-mode-alist 1131 (defvar auto-mode-alist
1202 '(("\\.te?xt\\'" . text-mode) 1132 '(("\\.te?xt\\'" . text-mode)
1203 ("\\.[ch]\\'" . c-mode) 1133 ("\\.[ch]\\'" . c-mode)
1204 ("\\.el\\'" . emacs-lisp-mode) 1134 ("\\.el\\'" . emacs-lisp-mode)
1286 1216
1287 If the element has the form (REGEXP FUNCTION NON-NIL), then after 1217 If the element has the form (REGEXP FUNCTION NON-NIL), then after
1288 calling FUNCTION (if it's not nil), we delete the suffix that matched 1218 calling FUNCTION (if it's not nil), we delete the suffix that matched
1289 REGEXP and search the list again for another match.") 1219 REGEXP and search the list again for another match.")
1290 1220
1291 (defconst interpreter-mode-alist 1221 (defvar interpreter-mode-alist
1292 '(("^#!.*csh" . sh-mode) 1222 '(("^#!.*csh" . sh-mode)
1293 ("^#!.*sh\\b" . sh-mode) 1223 ("^#!.*sh\\b" . sh-mode)
1294 ("^#!.*\\b\\(scope\\|wish\\|tcl\\|expect\\)" . tcl-mode) 1224 ("^#!.*\\b\\(scope\\|wish\\|tcl\\|expect\\)" . tcl-mode)
1295 ("perl" . perl-mode) 1225 ("perl" . perl-mode)
1296 ("python" . python-mode) 1226 ("python" . python-mode)
1310 Each alist element looks like (INTERPRETER . MODE). 1240 Each alist element looks like (INTERPRETER . MODE).
1311 The car of each element is a regular expression which is compared 1241 The car of each element is a regular expression which is compared
1312 with the name of the interpreter specified in the first line. 1242 with the name of the interpreter specified in the first line.
1313 If it matches, mode MODE is selected.") 1243 If it matches, mode MODE is selected.")
1314 1244
1315 (defconst inhibit-first-line-modes-regexps (purecopy '("\\.tar\\'")) 1245 (defvar inhibit-first-line-modes-regexps (purecopy '("\\.tar\\'" "\\.tgz\\'"))
1316 "List of regexps; if one matches a file name, don't look for `-*-'.") 1246 "List of regexps; if one matches a file name, don't look for `-*-'.")
1317 1247
1318 (defconst inhibit-first-line-modes-suffixes nil 1248 (defvar inhibit-first-line-modes-suffixes nil
1319 "List of regexps for what to ignore, for `inhibit-first-line-modes-regexps'. 1249 "List of regexps for what to ignore, for `inhibit-first-line-modes-regexps'.
1320 When checking `inhibit-first-line-modes-regexps', we first discard 1250 When checking `inhibit-first-line-modes-regexps', we first discard
1321 from the end of the file name anything that matches one of these regexps.") 1251 from the end of the file name anything that matches one of these regexps.")
1322 1252
1323 (defvar user-init-file 1253 (defvar user-init-file
1324 "" ; set by command-line 1254 "" ; set by command-line
1325 "File name including directory of user's initialization file.") 1255 "File name including directory of user's initialization file.")
1326 1256
1327 (defun set-auto-mode () 1257 (defun set-auto-mode (&optional just-from-file-name)
1328 "Select major mode appropriate for current buffer. 1258 "Select major mode appropriate for current buffer.
1329 This checks for a -*- mode tag in the buffer's text, 1259 This checks for a -*- mode tag in the buffer's text,
1330 compares the filename against the entries in `auto-mode-alist', 1260 compares the filename against the entries in `auto-mode-alist',
1331 or checks the interpreter that runs this file against 1261 or checks the interpreter that runs this file against
1332 `interpreter-mode-alist'. 1262 `interpreter-mode-alist'.
1333 1263
1334 It does not check for the `mode:' local variable in the 1264 It does not check for the `mode:' local variable in the
1335 Local Variables section of the file; for that, use `hack-local-variables'. 1265 Local Variables section of the file; for that, use `hack-local-variables'.
1336 1266
1337 If `enable-local-variables' is nil, this function does not check for a 1267 If `enable-local-variables' is nil, this function does not check for a
1338 -*- mode tag." 1268 -*- mode tag.
1269
1270 If the optional argument JUST-FROM-FILE-NAME is non-nil,
1271 then we do not set anything but the major mode,
1272 and we don't even do that unless it would come from the file name."
1339 (save-excursion 1273 (save-excursion
1340 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*- 1274 ;; Look for -*-MODENAME-*- or -*- ... mode: MODENAME; ... -*-
1341 ;; Do this by calling the hack-local-variables helper to avoid redundancy. 1275 ;; Do this by calling the hack-local-variables helper to avoid redundancy.
1342 ;; We bind enable-local-variables to nil this time because we're going to 1276 ;; We bind enable-local-variables to nil this time because we're going to
1343 ;; call hack-local-variables-prop-line again later, "for real." Note that 1277 ;; call hack-local-variables-prop-line again later, "for real." Note that
1368 name (substring name 0 (match-beginning 0)) 1302 name (substring name 0 (match-beginning 0))
1369 keep-going t)) 1303 keep-going t))
1370 (setq mode (cdr (car alist)) 1304 (setq mode (cdr (car alist))
1371 keep-going nil))) 1305 keep-going nil)))
1372 (setq alist (cdr alist)))) 1306 (setq alist (cdr alist))))
1373 ;; If we can't deduce a mode from the file name, 1307 (unless just-from-file-name
1374 ;; look for an interpreter specified in the first line. 1308 ;; If we can't deduce a mode from the file name,
1375 (if (and (null mode) 1309 ;; look for an interpreter specified in the first line.
1376 (save-excursion ; XEmacs 1310 (if (and (null mode)
1377 (goto-char (point-min)) 1311 (save-excursion ; XEmacs
1378 (looking-at "#!"))) 1312 (goto-char (point-min))
1379 (let ((firstline 1313 (looking-at "#!")))
1380 (buffer-substring 1314 (let ((firstline
1381 (point-min) 1315 (buffer-substring
1382 (save-excursion 1316 (point-min)
1383 (goto-char (point-min)) (end-of-line) (point))))) 1317 (save-excursion
1384 (setq alist interpreter-mode-alist) 1318 (goto-char (point-min)) (end-of-line) (point)))))
1385 (while alist 1319 (setq alist interpreter-mode-alist)
1386 (if (string-match (car (car alist)) firstline) 1320 (while alist
1387 (progn 1321 (if (string-match (car (car alist)) firstline)
1388 (setq mode (cdr (car alist))) 1322 (progn
1389 (setq alist nil)) 1323 (setq mode (cdr (car alist)))
1390 (setq alist (cdr alist)))))) 1324 (setq alist nil))
1325 (setq alist (cdr alist)))))))
1391 (if mode 1326 (if mode
1392 (if (not (fboundp mode)) 1327 (if (not (fboundp mode))
1393 (progn 1328 (progn
1394 (if (or (not (boundp 'package-get-base)) 1329 (if (or (not (boundp 'package-get-base))
1395 (not package-get-base)) 1330 (not package-get-base))
1399 (if name 1334 (if name
1400 (message "Mode %s is not installed. Download package %s" mode name) 1335 (message "Mode %s is not installed. Download package %s" mode name)
1401 (message "Mode %s either doesn't exist or is not a known package" mode)) 1336 (message "Mode %s either doesn't exist or is not a known package" mode))
1402 (sit-for 2) 1337 (sit-for 2)
1403 (error "%s" mode))) 1338 (error "%s" mode)))
1404 (funcall mode))) 1339 (unless (and just-from-file-name
1405 )))))) 1340 (or
1341 ;; Don't reinvoke major mode.
1342 (eq mode major-mode)
1343 ;; Don't lose on minor modes.
1344 (assq mode minor-mode-alist)))
1345 (funcall mode))))))))))
1406 1346
1407 (defvar hack-local-variables-hook nil 1347 (defvar hack-local-variables-hook nil
1408 "Normal hook run after processing a file's local variables specs. 1348 "Normal hook run after processing a file's local variables specs.
1409 Major modes can use this to examine user-specified local variables 1349 Major modes can use this to examine user-specified local variables
1410 in order to initialize other data structure based on them. 1350 in order to initialize other data structure based on them.
1716 (message "Ignoring `eval:' in file's local variables"))) 1656 (message "Ignoring `eval:' in file's local variables")))
1717 ;; Ordinary variable, really set it. 1657 ;; Ordinary variable, really set it.
1718 (t (make-local-variable var) 1658 (t (make-local-variable var)
1719 (set var val)))) 1659 (set var val))))
1720 1660
1721 (defun set-visited-file-name (filename) 1661 (defcustom change-major-mode-with-file-name t
1662 "*Non-nil means \\[write-file] should set the major mode from the file name.
1663 However, the mode will not be changed if
1664 \(1) a local variables list or the `-*-' line specifies a major mode, or
1665 \(2) the current major mode is a \"special\" mode,
1666 \ not suitable for ordinary files, or
1667 \(3) the new file name does not particularly specify any mode."
1668 :type 'boolean
1669 :group 'editing-basics)
1670
1671 (defun set-visited-file-name (filename &optional no-query along-with-file)
1722 "Change name of file visited in current buffer to FILENAME. 1672 "Change name of file visited in current buffer to FILENAME.
1723 The next time the buffer is saved it will go in the newly specified file. 1673 The next time the buffer is saved it will go in the newly specified file.
1724 nil or empty string as argument means make buffer not be visiting any file. 1674 nil or empty string as argument means make buffer not be visiting any file.
1725 Remember to delete the initial contents of the minibuffer 1675 Remember to delete the initial contents of the minibuffer
1726 if you wish to pass an empty string as the argument." 1676 if you wish to pass an empty string as the argument.
1677
1678 The optional second argument NO-QUERY, if non-nil, inhibits asking for
1679 confirmation in the case where another buffer is already visiting FILENAME.
1680
1681 The optional third argument ALONG-WITH-FILE, if non-nil, means that
1682 the old visited file has been renamed to the new name FILENAME."
1727 (interactive "FSet visited file name: ") 1683 (interactive "FSet visited file name: ")
1728 (if (buffer-base-buffer) 1684 (if (buffer-base-buffer)
1729 (error "An indirect buffer cannot visit a file")) 1685 (error "An indirect buffer cannot visit a file"))
1730 (let (truename) 1686 (let (truename)
1731 (if filename 1687 (if filename
1737 (progn 1693 (progn
1738 (setq truename (file-truename filename)) 1694 (setq truename (file-truename filename))
1739 ;; #### Do we need to check if truename is non-nil? 1695 ;; #### Do we need to check if truename is non-nil?
1740 (if find-file-use-truenames 1696 (if find-file-use-truenames
1741 (setq filename truename)))) 1697 (setq filename truename))))
1698 (let ((buffer (and filename (find-buffer-visiting filename))))
1699 (and buffer (not (eq buffer (current-buffer)))
1700 (not no-query)
1701 (not (y-or-n-p (message "A buffer is visiting %s; proceed? "
1702 filename)))
1703 (error "Aborted")))
1742 (or (equal filename buffer-file-name) 1704 (or (equal filename buffer-file-name)
1743 (progn 1705 (progn
1744 (and filename (lock-buffer filename)) 1706 (and filename (lock-buffer filename))
1745 (unlock-buffer))) 1707 (unlock-buffer)))
1746 (setq buffer-file-name filename) 1708 (setq buffer-file-name filename)
1752 (setq new-name (downcase new-name))) 1714 (setq new-name (downcase new-name)))
1753 (setq default-directory (file-name-directory buffer-file-name)) 1715 (setq default-directory (file-name-directory buffer-file-name))
1754 (or (string= new-name (buffer-name)) 1716 (or (string= new-name (buffer-name))
1755 (rename-buffer new-name t)))) 1717 (rename-buffer new-name t))))
1756 (setq buffer-backed-up nil) 1718 (setq buffer-backed-up nil)
1757 (clear-visited-file-modtime) 1719 (or along-with-file
1720 (clear-visited-file-modtime))
1758 (compute-buffer-file-truename) ; insert-file-contents does this too. 1721 (compute-buffer-file-truename) ; insert-file-contents does this too.
1759 ; ;; Abbreviate the file names of the buffer. 1722 ; ;; Abbreviate the file names of the buffer.
1760 ; (if truename 1723 ; (if truename
1761 ; (progn 1724 ; (progn
1762 ; (setq buffer-file-truename (abbreviate-file-name truename)) 1725 ; (setq buffer-file-truename (abbreviate-file-name truename))
1775 (kill-local-variable 'write-file-data-hooks) 1738 (kill-local-variable 'write-file-data-hooks)
1776 (kill-local-variable 'revert-buffer-function) 1739 (kill-local-variable 'revert-buffer-function)
1777 (kill-local-variable 'backup-inhibited) 1740 (kill-local-variable 'backup-inhibited)
1778 ;; If buffer was read-only because of version control, 1741 ;; If buffer was read-only because of version control,
1779 ;; that reason is gone now, so make it writable. 1742 ;; that reason is gone now, so make it writable.
1780 (if (and (boundp 'vc-mode) vc-mode) 1743 (when (boundp 'vc-mode)
1781 (setq buffer-read-only nil)) 1744 (if vc-mode
1782 (kill-local-variable 'vc-mode) 1745 (setq buffer-read-only nil))
1746 (kill-local-variable 'vc-mode))
1783 ;; Turn off backup files for certain file names. 1747 ;; Turn off backup files for certain file names.
1784 ;; Since this is a permanent local, the major mode won't eliminate it. 1748 ;; Since this is a permanent local, the major mode won't eliminate it.
1785 (and (not (funcall backup-enable-predicate buffer-file-name)) 1749 (and buffer-file-name
1750 (not (funcall backup-enable-predicate buffer-file-name))
1786 (progn 1751 (progn
1787 (make-local-variable 'backup-inhibited) 1752 (make-local-variable 'backup-inhibited)
1788 (setq backup-inhibited t))) 1753 (setq backup-inhibited t)))
1789 (let ((oauto buffer-auto-save-file-name)) 1754 (let ((oauto buffer-auto-save-file-name))
1790 ;; If auto-save was not already on, turn it on if appropriate. 1755 ;; If auto-save was not already on, turn it on if appropriate.
1801 ;; Rename the old auto save file if any. 1766 ;; Rename the old auto save file if any.
1802 (and oauto buffer-auto-save-file-name 1767 (and oauto buffer-auto-save-file-name
1803 (file-exists-p oauto) 1768 (file-exists-p oauto)
1804 (rename-file oauto buffer-auto-save-file-name t))) 1769 (rename-file oauto buffer-auto-save-file-name t)))
1805 (if buffer-file-name 1770 (if buffer-file-name
1771 (not along-with-file)
1806 (set-buffer-modified-p t)) 1772 (set-buffer-modified-p t))
1773 ;; Update the major mode, if the file name determines it.
1774 (condition-case nil
1775 ;; Don't change the mode if it is special.
1776 (or (not change-major-mode-with-file-name)
1777 (get major-mode 'mode-class)
1778 ;; Don't change the mode if the local variable list specifies it.
1779 (hack-local-variables t)
1780 (set-auto-mode t))
1781 (error nil))
1807 ;; #### ?? 1782 ;; #### ??
1808 (run-hooks 'after-set-visited-file-name-hooks)) 1783 (run-hooks 'after-set-visited-file-name-hooks))
1809 1784
1810 (defun write-file (filename &optional confirm codesys) 1785 (defun write-file (filename &optional confirm codesys)
1811 "Write current buffer into file FILENAME. 1786 "Write current buffer into file FILENAME.
1992 (expand-file-name (substring file 0 (match-beginning 0)) 1967 (expand-file-name (substring file 0 (match-beginning 0))
1993 directory) 1968 directory)
1994 (substring file 0 (match-beginning 0))) 1969 (substring file 0 (match-beginning 0)))
1995 filename)))) 1970 filename))))
1996 1971
1972 (defun file-name-extension (filename &optional period)
1973 "Return FILENAME's final \"extension\".
1974 The extension, in a file name, is the part that follows the last `.'.
1975 Return nil for extensionless file names such as `foo'.
1976 Return the empty string for file names such as `foo.'.
1977
1978 If PERIOD is non-nil, then the returned value includes the period
1979 that delimits the extension, and if FILENAME has no extension,
1980 the value is \"\"."
1981 (save-match-data
1982 (let ((file (file-name-sans-versions (file-name-nondirectory filename))))
1983 (if (string-match "\\.[^.]*\\'" file)
1984 (substring file (+ (match-beginning 0) (if period 0 1)))
1985 (if period
1986 "")))))
1987
1997 (defun make-backup-file-name (file) 1988 (defun make-backup-file-name (file)
1998 "Create the non-numeric backup file name for FILE. 1989 "Create the non-numeric backup file name for FILE.
1999 This is a separate function so you can redefine it for customization." 1990 This is a separate function so you can redefine it for customization."
2000 (if (eq system-type 'ms-dos) 1991 (if (eq system-type 'ms-dos)
2001 (let ((fn (file-name-nondirectory file))) 1992 (let ((fn (file-name-nondirectory file)))
2079 (defun file-nlinks (filename) 2070 (defun file-nlinks (filename)
2080 "Return number of names file FILENAME has." 2071 "Return number of names file FILENAME has."
2081 (car (cdr (file-attributes filename)))) 2072 (car (cdr (file-attributes filename))))
2082 2073
2083 (defun file-relative-name (filename &optional directory) 2074 (defun file-relative-name (filename &optional directory)
2084 "Convert FILENAME to be relative to DIRECTORY (default: default-directory)." 2075 "Convert FILENAME to be relative to DIRECTORY (default: default-directory).1
2085 (setq filename (expand-file-name filename) 2076 This function returns a relative file name which is equivalent to FILENAME
2086 directory (file-name-as-directory (expand-file-name 2077 when used with that default directory as the default.
2087 (or directory default-directory)))) 2078 If this is impossible (which can happen on MSDOS and Windows
2088 (let ((ancestor "")) 2079 when the file name and directory use different drive names)
2089 (while (not (string-match (concat "^" (regexp-quote directory)) filename)) 2080 then it returns FILENAME."
2090 (setq directory (file-name-directory (substring directory 0 -1)) 2081 (save-match-data
2091 ancestor (concat "../" ancestor))) 2082 (let ((fname (expand-file-name filename)))
2092 (concat ancestor (substring filename (match-end 0))))) 2083 (setq directory (file-name-as-directory
2084 (expand-file-name (or directory default-directory))))
2085 ;; On Microsoft OSes, if FILENAME and DIRECTORY have different
2086 ;; drive names, they can't be relative, so return the absolute name.
2087 (if (and (or (eq system-type 'ms-dos)
2088 (eq system-type 'windows-nt))
2089 (not (string-equal (substring fname 0 2)
2090 (substring directory 0 2))))
2091 filename
2092 (let ((ancestor ".")
2093 (fname-dir (file-name-as-directory fname)))
2094 (while (and (not (string-match (concat "^" (regexp-quote directory)) fname-dir))
2095 (not (string-match (concat "^" (regexp-quote directory)) fname)))
2096 (setq directory (file-name-directory (substring directory 0 -1))
2097 ancestor (if (equal ancestor ".")
2098 ".."
2099 (concat "../" ancestor))))
2100 ;; Now ancestor is empty, or .., or ../.., etc.
2101 (if (string-match (concat "^" (regexp-quote directory)) fname)
2102 ;; We matched within FNAME's directory part.
2103 ;; Add the rest of FNAME onto ANCESTOR.
2104 (let ((rest (substring fname (match-end 0))))
2105 (if (and (equal ancestor ".")
2106 (not (equal rest "")))
2107 ;; But don't bother with ANCESTOR if it would give us `./'.
2108 rest
2109 (concat (file-name-as-directory ancestor) rest)))
2110 ;; We matched FNAME's directory equivalent.
2111 ancestor))))))
2093 2112
2094 (defun save-buffer (&optional args) 2113 (defun save-buffer (&optional args)
2095 "Save current buffer in visited file if modified. Versions described below. 2114 "Save current buffer in visited file if modified. Versions described below.
2096 2115
2097 By default, makes the previous version into a backup file 2116 By default, makes the previous version into a backup file
2417 ;;"save only this buffer" "save no more buffers") 2436 ;;"save only this buffer" "save no more buffers")
2418 ;; this is rather bogus. --ben 2437 ;; this is rather bogus. --ben
2419 ;; (it makes the dialog box too big, and you get an error 2438 ;; (it makes the dialog box too big, and you get an error
2420 ;; "wrong type argument: framep, nil" when you hit q after 2439 ;; "wrong type argument: framep, nil" when you hit q after
2421 ;; choosing the option from the dialog box) 2440 ;; choosing the option from the dialog box)
2422 ; (list (list ?\C-r (lambda (buf) 2441
2423 ; (view-buffer buf) 2442 ;; We should fix the dialog box rather than disabling
2424 ; (setq view-exit-action 2443 ;; this! --hniksic
2425 ; '(lambda (ignore) 2444 (list (list ?\C-r (lambda (buf)
2426 ; (exit-recursive-edit))) 2445 ;; FSF has an EXIT-ACTION argument to
2427 ; (recursive-edit) 2446 ;; `view-buffer'.
2428 ; ;; Return nil to ask about BUF again. 2447 (view-buffer buf)
2429 ; nil) 2448 (setq view-exit-action
2430 ; "display the current buffer")) 2449 (lambda (ignore)
2431 )) 2450 (exit-recursive-edit)))
2451 (recursive-edit)
2452 ;; Return nil to ask about BUF again.
2453 nil)
2454 "display the current buffer"))))
2432 (abbrevs-done 2455 (abbrevs-done
2433 (and save-abbrevs abbrevs-changed 2456 (and save-abbrevs abbrevs-changed
2434 (progn 2457 (progn
2435 (if (or arg 2458 (if (or arg
2436 (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name))) 2459 (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name)))
2478 \(Its calling sequence is different; see its documentation)." 2501 \(Its calling sequence is different; see its documentation)."
2479 (interactive "*fInsert file: \nZCoding system: ") 2502 (interactive "*fInsert file: \nZCoding system: ")
2480 (if (file-directory-p filename) 2503 (if (file-directory-p filename)
2481 (signal 'file-error (list "Opening input file" "file is a directory" 2504 (signal 'file-error (list "Opening input file" "file is a directory"
2482 filename))) 2505 filename)))
2483 (let* (format-alist ; format.el only confuses people in this context 2506 (let ((tem
2484 (tem
2485 (if codesys 2507 (if codesys
2486 (let ((coding-system-for-read 2508 (let ((coding-system-for-read
2487 (get-coding-system codesys))) 2509 (get-coding-system codesys)))
2488 (insert-file-contents filename)) 2510 (insert-file-contents filename))
2489 (insert-file-contents filename)))) 2511 (insert-file-contents filename))))
2621 2643
2622 Optional third argument PRESERVE-MODES non-nil means don't alter 2644 Optional third argument PRESERVE-MODES non-nil means don't alter
2623 the files modes. Normally we reinitialize them using `normal-mode'. 2645 the files modes. Normally we reinitialize them using `normal-mode'.
2624 2646
2625 If the value of `revert-buffer-function' is non-nil, it is called to 2647 If the value of `revert-buffer-function' is non-nil, it is called to
2626 do the work. 2648 do all the work for this command. Otherwise, the hooks
2627 2649 `before-revert-hook' and `after-revert-hook' are run at the beginning
2628 The default revert function runs the hook `before-revert-hook' at the 2650 and the end, and if `revert-buffer-insert-file-contents-function' is
2629 beginning and `after-revert-hook' at the end." 2651 non-nil, it is called instead of rereading visited file contents."
2652
2630 ;; I admit it's odd to reverse the sense of the prefix argument, but 2653 ;; I admit it's odd to reverse the sense of the prefix argument, but
2631 ;; there is a lot of code out there which assumes that the first 2654 ;; there is a lot of code out there which assumes that the first
2632 ;; argument should be t to avoid consulting the auto-save file, and 2655 ;; argument should be t to avoid consulting the auto-save file, and
2633 ;; there's no straightforward way to encourage authors to notice a 2656 ;; there's no straightforward way to encourage authors to notice a
2634 ;; reversal of the argument sense. So I'm just changing the user 2657 ;; reversal of the argument sense. So I'm just changing the user
2750 To choose one, move point to the proper line and then type C-c C-c. 2773 To choose one, move point to the proper line and then type C-c C-c.
2751 Then you'll be asked about a number of files to recover." 2774 Then you'll be asked about a number of files to recover."
2752 (interactive) 2775 (interactive)
2753 (unless (fboundp 'dired) 2776 (unless (fboundp 'dired)
2754 (error "recover-session requires dired")) 2777 (error "recover-session requires dired"))
2778 (if (null auto-save-list-file-prefix)
2779 (error
2780 "You set `auto-save-list-file-prefix' to disable making session files"))
2755 (dired (concat auto-save-list-file-prefix "*")) 2781 (dired (concat auto-save-list-file-prefix "*"))
2756 (goto-char (point-min)) 2782 (goto-char (point-min))
2757 (or (looking-at "Move to the session you want to recover,") 2783 (or (looking-at "Move to the session you want to recover,")
2758 (let ((inhibit-read-only t)) 2784 (let ((inhibit-read-only t))
2759 (insert "Move to the session you want to recover,\n" 2785 (insert "Move to the session you want to recover,\n"
2837 files 2863 files
2838 '("file" "files" "recover")) 2864 '("file" "files" "recover"))
2839 (message "No files can be recovered from this session now"))) 2865 (message "No files can be recovered from this session now")))
2840 (kill-buffer buffer)))) 2866 (kill-buffer buffer))))
2841 2867
2842 (defun kill-some-buffers () 2868 (defun kill-some-buffers (&optional list)
2843 "For each buffer, ask whether to kill it." 2869 "For each buffer in LIST, ask whether to kill it.
2870 LIST defaults to all existing live buffers."
2844 (interactive) 2871 (interactive)
2845 (let ((list (buffer-list))) 2872 (if (null list)
2846 (while list 2873 (setq list (buffer-list)))
2847 (let* ((buffer (car list)) 2874 (while list
2848 (name (buffer-name buffer))) 2875 (let* ((buffer (car list))
2849 (and (not (string-equal name "")) 2876 (name (buffer-name buffer)))
2850 (/= (aref name 0) ? ) 2877 (and (not (string-equal name ""))
2851 (yes-or-no-p 2878 (/= (aref name 0) ?\ )
2852 (format 2879 (yes-or-no-p
2853 (if (buffer-modified-p buffer) 2880 (format
2854 (gettext "Buffer %s HAS BEEN EDITED. Kill? ") 2881 (if (buffer-modified-p buffer)
2855 (gettext "Buffer %s is unmodified. Kill? ")) 2882 (gettext "Buffer %s HAS BEEN EDITED. Kill? ")
2856 name)) 2883 (gettext "Buffer %s is unmodified. Kill? "))
2857 (kill-buffer buffer))) 2884 name))
2858 (setq list (cdr list))))) 2885 (kill-buffer buffer)))
2886 (setq list (cdr list))))
2859 2887
2860 (defun auto-save-mode (arg) 2888 (defun auto-save-mode (arg)
2861 "Toggle auto-saving of contents of current buffer. 2889 "Toggle auto-saving of contents of current buffer.
2862 With prefix argument ARG, turn auto-saving on if positive, else off." 2890 With prefix argument ARG, turn auto-saving on if positive, else off."
2863 (interactive "P") 2891 (interactive "P")
3225 (cond ((not allow-remote-paths) nil) 3253 (cond ((not allow-remote-paths) nil)
3226 ((featurep 'ange-ftp) (ange-ftp-ftp-path file-name)) 3254 ((featurep 'ange-ftp) (ange-ftp-ftp-path file-name))
3227 ((fboundp 'efs-ftp-path) (efs-ftp-path file-name)) 3255 ((fboundp 'efs-ftp-path) (efs-ftp-path file-name))
3228 (t nil))) 3256 (t nil)))
3229 3257
3258 ;; #### FSF has file-name-non-special here.
3259
3230 ;;; files.el ends here 3260 ;;; files.el ends here