Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/lisp/prim/files.el Mon Aug 13 08:46:35 2007 +0200 +++ b/lisp/prim/files.el Mon Aug 13 08:46:56 2007 +0200 @@ -17,9 +17,10 @@ ;; You should have received a copy of the GNU General Public License ;; along with XEmacs; see the file COPYING. If not, write to the Free -;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +;; 02111-1307, USA. -;;; Synched up with: FSF 19.30. +;;; Synched up with: FSF 19.34 [Partial]. ;;; Warning: Merging this file is tough. Beware. ;;; Commentary: @@ -30,14 +31,28 @@ ;;; Code: -;; Avoid compilation warnings. +;; XEmacs: Avoid compilation warnings. (defvar overriding-file-coding-system) (defvar file-coding-system) -;; In buffer.c +;; XEmacs: In buffer.c ;(defconst delete-auto-save-files t ; "*Non-nil means delete auto-save file when a buffer is saved or killed.") +;; FSF has automount-dir-prefix. Our directory-abbrev-alist is more general. +;; note: tmp_mnt bogosity conversion is established in paths.el. +(defvar directory-abbrev-alist nil + "*Alist of abbreviations for file directories. +A list of elements of the form (FROM . TO), each meaning to replace +FROM with TO when it appears in a directory name. +This replacement is done when setting up the default directory of a +newly visited file. *Every* FROM string should start with \\\\` or ^. + +Use this feature when you have directories which you normally refer to +via absolute symbolic links or to eliminate automounter mount points +from the beginning of your filenames. Make TO the name of the link, +and FROM the name it is linked to.") + ;;; Turn off backup files on VMS since it has version numbers. (defconst make-backup-files (not (eq system-type 'vax-vms)) "*Non-nil means make a backup of a file the first time it is saved. @@ -95,6 +110,7 @@ Automatically local in all buffers.") (make-variable-buffer-local 'buffer-offer-save) +;; FSF uses normal defconst (defvaralias 'find-file-visit-truename 'find-file-use-truenames) (defvaralias 'find-file-existing-other-name 'find-file-compare-truenames) @@ -106,6 +122,9 @@ (make-variable-buffer-local 'buffer-file-number) (put 'buffer-file-number 'permanent-local t) +(defvar buffer-file-numbers-unique (not (memq system-type '(windows-nt))) + "Non-nil means that buffer-file-number uniquely identifies files.") + (defconst file-precious-flag nil "*Non-nil means protect against I/O errors while saving files. Some modes set this non-nil in particular buffers. @@ -179,20 +198,26 @@ and the rest are not called. These hooks are considered to pertain to the visited file. So this list is cleared if you change the visited file name. -See also `write-contents-hooks' and `continue-save-buffer'. -Don't make this variable buffer-local; instead, use `local-write-file-hooks'.") + +Don't make this variable buffer-local; instead, use `local-write-file-hooks'. +See also `write-contents-hooks' and `continue-save-buffer'.") ;;; However, in case someone does make it local... (put 'write-file-hooks 'permanent-local t) (defvar local-write-file-hooks nil "Just like `write-file-hooks', except intended for per-buffer use. The functions in this list are called before the ones in -`write-file-hooks'.") +`write-file-hooks'. + +This variable is meant to be used for hooks that have to do with a +particular visited file. Therefore, it is a permanent local, so that +changing the major mode does not clear it. However, calling +`set-visited-file-name' does clear it.") (make-variable-buffer-local 'local-write-file-hooks) (put 'local-write-file-hooks 'permanent-local t) -;; #### think about this (added by Sun). +;; XEmacs: #### think about this (added by Sun). (put 'after-set-visited-file-name-hooks 'permanent-local t) (defvar after-set-visited-file-name-hooks nil "List of functions to be called after \\[set-visited-file-name] @@ -211,8 +236,9 @@ not to the particular visited file; thus, `set-visited-file-name' does not clear this variable, but changing the major mode does clear it. See also `write-file-hooks' and `continue-save-buffer'.") +;(make-variable-buffer-local 'write-contents-hooks) -;; Not in FSF19 +;; XEmacs addition ;; Energize needed this to hook into save-buffer at a lower level; we need ;; to provide a new output method, but don't want to have to duplicate all ;; of the backup file and file modes logic.that does not occur if one uses @@ -247,15 +273,6 @@ The command \\[normal-mode] always obeys local-variables lists and ignores this variable.") -(defvar hack-local-variables-hook nil - "Normal hook run after processing a file's local variables specs. -Major modes can use this to examine user-specified local variables -in order to initialize other data structure based on them. - -This hook runs even if there were no local variables or if their -evaluation was suppressed. See also `enable-local-variables' and -`enable-local-eval'.") - ;; Avoid losing in versions where CLASH_DETECTION is disabled. (or (fboundp 'lock-buffer) (defalias 'lock-buffer 'ignore)) @@ -299,7 +316,7 @@ (defun parse-colon-path (cd-path) "Explode a colon-separated list of paths into a string list." (and cd-path - (let (cd-list (cd-start 0) cd-colon) + (let (cd-prefix cd-list (cd-start 0) cd-colon) (setq cd-path (concat cd-path path-separator)) (while (setq cd-colon (string-match path-separator cd-path cd-start)) (setq cd-list @@ -334,22 +351,21 @@ "Make DIR become the current buffer's default directory. If your environment includes a `CDPATH' variable, try each one of that colon-separated list of directories when resolving a relative directory name." -; (interactive "DChange default directory: ") (interactive - ;; XEmacs change? + ;; XEmacs change? (read-file-name => read-directory-name) (list (read-directory-name "Change default directory: " default-directory default-directory (and (member cd-path '(nil ("./"))) (null (getenv "CDPATH")))))) (if (file-name-absolute-p dir) (cd-absolute (expand-file-name dir)) - (progn - (if (null cd-path) - ;;#### Unix-specific - (let ((trypath (parse-colon-path (getenv "CDPATH")))) - (setq cd-path (or trypath (list "./"))))) - (or (catch 'found - (mapcar #'(lambda (x) + ;; XEmacs + (if (null cd-path) + ;;#### Unix-specific + (let ((trypath (parse-colon-path (getenv "CDPATH")))) + (setq cd-path (or trypath (list "./"))))) + (or (catch 'found + (mapcar #'(lambda (x) (let ((f (expand-file-name (concat x dir)))) (if (file-directory-p f) (progn @@ -361,28 +377,19 @@ ;; good taste not to use a kludge like $CDPATH. (if (equal cd-path '("./")) (error "No such directory: %s" (expand-file-name dir)) - (error "Directory not found in $CDPATH: %s" dir)))))) + (error "Directory not found in $CDPATH: %s" dir))))) (defun load-file (file) "Load the Lisp file named FILE." (interactive "fLoad file: ") (load (expand-file-name file) nil nil t)) -; We now dump utils/lib-complete.el which has improved versions of these. +; We now dump utils/lib-complete.el which has an improved version of this. ;(defun load-library (library) ; "Load the library named LIBRARY. ;This is an interface to the function `load'." ; (interactive "sLoad library: ") ; (load library)) -; -;(defun find-library (library) -; "Find the library of Lisp code named LIBRARY. -;This searches `load-path' for a file named either \"LIBRARY\" or \"LIBRARY.el\"." -; (interactive "sFind library file: ") -; (let ((f (locate-file library load-path ":.el:"))) -; (if f -; (find-file f) -; (error "Couldn't locate library %s" library)))) (defun file-local-copy (file &optional buffer) "Copy the file FILE into a temporary file on this machine. @@ -393,6 +400,7 @@ (funcall handler 'file-local-copy file) nil))) +;; XEmacs change block ; We have this in C and use the realpath() system call. ;(defun file-truename (filename &optional counter prev-dirs) @@ -502,6 +510,7 @@ (setq buffer-file-name (abbreviate-file-name buffer-file-truename) default-directory (file-name-directory buffer-file-name))) buffer-file-truename)) +;; End XEmacs change block (defun file-chase-links (filename) "Chase links in FILENAME until a name that is not a link. @@ -558,6 +567,7 @@ (defun switch-to-buffer-other-frame (buffer) "Switch to buffer BUFFER in a newly-created frame." (interactive "BSwitch to buffer in other frame: ") + ;; XEmacs guarantees a new frame (let* ((name (get-frame-name-for-buffer buffer)) (frame (make-frame (if name (list (cons 'name (symbol-name name))))))) @@ -580,7 +590,9 @@ (switch-to-buffer-other-window (find-file-noselect filename))) (defun find-file-other-frame (filename) - "Edit file FILENAME, in a newly-created frame." + "Edit file FILENAME, in a newly-created frame. +This function will create a new frame. +See the function `display-buffer'." (interactive "FFind file in other frame: ") (switch-to-buffer-other-frame (find-file-noselect filename))) @@ -624,8 +636,7 @@ (setq file-name (file-name-nondirectory file) file-dir (file-name-directory file))) (list (read-file-name - "Find alternate file: " file-dir nil nil file-name) - )))) + "Find alternate file: " file-dir nil nil file-name))))) (if (one-window-p) (find-file-other-window filename) (save-selected-window @@ -647,9 +658,8 @@ "Find alternate file: " file-dir nil nil file-name)))) (and (buffer-modified-p) (buffer-file-name) ;; (not buffer-read-only) - (not (yes-or-no-p (format - "Buffer %s is modified; kill anyway? " - (buffer-name)))) + (not (yes-or-no-p (format "Buffer %s is modified; kill anyway? " + (buffer-name)))) (error "Aborted")) (let ((obuf (current-buffer)) (ofile buffer-file-name) @@ -659,12 +669,12 @@ (if (get-buffer " **lose**") (kill-buffer " **lose**")) (rename-buffer " **lose**") - (setq buffer-file-name nil) - (setq buffer-file-number nil) - (setq buffer-file-truename nil) (unwind-protect (progn (unlock-buffer) + (setq buffer-file-name nil) + (setq buffer-file-number nil) + (setq buffer-file-truename nil) (find-file filename)) (cond ((eq obuf (current-buffer)) (setq buffer-file-name ofile) @@ -689,23 +699,13 @@ Choose the buffer's name using `generate-new-buffer-name'." (get-buffer-create (generate-new-buffer-name name))) -;; FSF has automount-dir-prefix. Our directory-abbrev-alist is more general. -;; note: tmp_mnt bogosity conversion is established in paths.el. -(defvar directory-abbrev-alist nil - "*Alist of abbreviations for file directories. -A list of elements of the form (FROM . TO), each meaning to replace -FROM with TO when it appears in a directory name. -This replacement is done when setting up the default directory of a -newly visited file. *Every* FROM string should start with \\\\` or ^. - -Use this feature when you have directories which you normally refer to -via absolute symbolic links or to eliminate automounter mount points -from the beginning of your filenames. Make TO the name of the link, -and FROM the name it is linked to.") +;(defconst automount-dir-prefix "^/tmp_mnt/" +; "Regexp to match the automounter prefix in a directory name.") (defvar abbreviated-home-dir nil "The user's homedir abbreviated according to `directory-abbrev-alist'.") +;; XEmacs additional parameter (defun abbreviate-file-name (filename &optional hack-homedir) "Return a version of FILENAME shortened using `directory-abbrev-alist'. See documentation of variable `directory-abbrev-alist' for more information. @@ -743,10 +743,12 @@ ;; If the home dir is just /, don't change it. (not (and (= (match-end 0) 1) ;#### unix-specific (= (aref filename 0) ?/))) + ;; MS-DOS root directories can come with a drive letter; + ;; Novell Netware allows drive letters beyond `Z:'. (not (and (or (eq system-type 'ms-dos) (eq system-type 'windows-nt)) (save-match-data - (string-match "^[a-zA-Z]:/$" filename))))) + (string-match "^[a-zA-Z-`]:/$" filename))))) (setq filename (concat "~" (substring filename @@ -780,12 +782,13 @@ ; found) ; (let ((number (nthcdr 10 (file-attributes truename))) ; (list (buffer-list)) found) -; (and number +; (and buffer-file-numbers-unique +; number ; (while (and (not found) list) ; (save-excursion ; (set-buffer (car list)) -; (if (and buffer-file-number -; (equal buffer-file-number number) +; (if (and buffer-file-name +; (equal buffer-file-number number) ; ;; Verify this buffer's file number ; ;; still belongs to its file. ; (file-exists-p buffer-file-name) @@ -823,13 +826,15 @@ The buffer is not selected, just returned to the caller. If NOWARN is non-nil warning messages about several potential problems will be suppressed." - (setq filename (abbreviate-file-name (expand-file-name filename))) + (setq filename + (abbreviate-file-name + (expand-file-name filename))) (if (file-directory-p filename) (if find-file-run-dired - (dired-noselect (if find-file-use-truenames + (dired-noselect (if find-file-use-truenames ; XEmacs (abbreviate-file-name (file-truename filename)) filename)) - (error "%s is a directory." filename)) + (error "%s is a directory" filename)) (let* ((buf (get-file-buffer filename)) ; (truename (abbreviate-file-name (file-truename filename))) ; (number (nthcdr 10 (file-attributes truename))) @@ -839,17 +844,16 @@ ; (other (and (not buf) (find-buffer-visiting filename))) (error nil)) -; ;; Let user know if there is a buffer with the same truename. -; (if (and (not buf) same-truename (not nowarn)) -; (message "%s and %s are the same file (%s)" -; filename (buffer-file-name same-truename) -; truename) -; (if (and (not buf) same-number (not nowarn)) -; (message "%s and %s are the same file" -; filename (buffer-file-name same-number)))) -; ;; Optionally also find that buffer. -; (if (or find-file-existing-other-name find-file-visit-truename) -; (setq buf (or same-truename same-number))) +; ;; Let user know if there is a buffer with the same truename. +; (if other +; (progn +; (or nowarn +; (string-equal filename (buffer-file-name other)) +; (message "%s and %s are the same file" +; filename (buffer-file-name other))) +; ;; Optionally also find that buffer. +; (if (or find-file-existing-other-name find-file-visit-truename) +; (setq buf other)))) (if (and buf (or find-file-compare-truenames find-file-use-truenames) @@ -901,13 +905,13 @@ (file-error ;; Unconditionally set error (setq error t))) - (condition-case e + (condition-case e ; XEmacs - pass error through (insert-file-contents filename t) (file-error ;; Run find-file-not-found-hooks until one returns non-nil. (or (run-hook-with-args-until-success 'find-file-not-found-hooks) ;; If they fail too, set error. - (setq error e))))) + (setq error e))))) ; XEmacs ;; Find the file's truename, and maybe use that as visited name. ;; automatically computed in XEmacs. ; (setq buffer-file-truename truename) @@ -941,13 +945,15 @@ (setq backup-inhibited t))) (if rawfile nil - (after-find-file error (not nowarn))))) + (after-find-file error (not nowarn)) + (setq buf (current-buffer))))) buf))) (defvar after-find-file-from-revert-buffer nil) (defun after-find-file (&optional error warn noauto - after-find-file-from-revert-buffer) + after-find-file-from-revert-buffer + nomodes) "Called after finding a file and by the default revert function. Sets buffer mode, parses local variables. Optional args ERROR, WARN, and NOAUTO: ERROR non-nil means there was an @@ -956,7 +962,10 @@ NOAUTO means don't mess with auto-save mode. Fourth arg AFTER-FIND-FILE-FROM-REVERT-BUFFER non-nil means this call was from `revert-buffer'. -Finishes by calling the functions in `find-file-hooks'." +Finishes by calling the functions in `find-file-hooks'. +Fifth arg NOMODES non-nil means don't alter the file's modes. +Finishes by calling the functions in `find-file-hooks' +unless NOMODES is non-nil." (setq buffer-read-only (not (file-writable-p buffer-file-name))) (if noninteractive nil @@ -985,6 +994,7 @@ ;; than when we save the buffer, because we want ;; autosaving to work. (setq buffer-read-only nil) + ;; XEmacs change (or (file-exists-p (file-name-directory buffer-file-name)) (if (yes-or-no-p (format @@ -1000,8 +1010,9 @@ (or not-serious (sit-for 1 t))))) (if (and auto-save-default (not noauto)) (auto-save-mode t))) - (normal-mode t) - (run-hooks 'find-file-hooks)) + (unless nomodes + (normal-mode t) + (run-hooks 'find-file-hooks))) (defun normal-mode (&optional find-file) "Choose the major mode for this buffer automatically. @@ -1015,6 +1026,7 @@ run `normal-mode' explicitly." (interactive) (or find-file (funcall (or default-major-mode 'fundamental-mode))) + ;; XEmacs change (and (condition-case err (progn (set-auto-mode) t) @@ -1031,6 +1043,7 @@ 'purecopy '(("\\.te?xt\\'" . text-mode) ("\\.[ch]\\'" . c-mode) + ("\\.tex\\'" . tex-mode) ("\\.ltx\\'" . latex-mode) ("\\.el\\'" . emacs-lisp-mode) ("\\.l\\(i?sp\\)?\\'" . lisp-mode) @@ -1055,6 +1068,10 @@ ("\\.mss\\'" . scribe-mode) ("\\.m\\([mes]\\|an\\)\\'" . nroff-mode) ("\\.icn\\'" . icon-mode) + ("\\.[ck]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode) + ("/\\.\\(bash_profile\\|z?login\\|bash_login\\|z?logout\\)\\'" . sh-mode) + ("/\\.\\(bash_logout\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode) + ("/\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode) ;;; The following should come after the ChangeLog pattern ;;; for the sake of ChangeLog.1, etc. ;;; and after the .scm.[0-9] pattern too. @@ -1074,6 +1091,7 @@ ;; Mailer puts message to be edited in ;; /tmp/Re.... or Message ("^/tmp/Re" . text-mode) + ("^/tmp/L[0-9]+TMP\\.html" . text-mode) ; Lynx mail mode ("/Message[0-9]*\\'" . text-mode) ("/drafts/[0-9]+\\'" . mh-letter-mode) ;; some news reader is reported to use this @@ -1104,15 +1122,15 @@ (defconst interpreter-mode-alist (mapcar 'purecopy - '(("^#!.*csh" . csh-mode) - ("^#!.*sh\\b" . ksh-mode) + '(("^#!.*[acjkwz]sh" . sh-mode) + ("^#!.*sh\\b" . sh-mode) ("^#!.*\\b\\(scope\\|wish\\|tcl\\|expect\\)" . tcl-mode) ("perl" . perl-mode) ("python" . python-mode) ("awk\\b" . awk-mode) ("rexx" . rexx-mode) ("scm" . scheme-mode) - ("^:" . ksh-mode) + ("^:" . sh-mode) )) "Alist mapping interpreter names to major modes. This alist is used to guess the major mode of a file based on the @@ -1140,6 +1158,7 @@ "" ; set by command-line "File name including directory of user's initialization file.") +;; XEmacs (This function is not synched with FSF) (defun set-auto-mode () "Select major mode appropriate for current buffer. This checks for a -*- mode tag in the buffer's text, @@ -1201,6 +1220,89 @@ (funcall mode)) )))))) +;; XEmacs: this function is not synched with FSF +(defun hack-local-variables-prop-line (&optional force) + ;; Set local variables specified in the -*- line. + ;; Returns t if mode was set. + (let ((result nil)) + (save-excursion + (goto-char (point-min)) + (skip-chars-forward " \t\n\r") + (let ((end (save-excursion + ;; If the file begins with "#!" + ;; (un*x exec interpreter magic), look + ;; for mode frobs in the first two + ;; lines. You cannot necessarily + ;; put them in the first line of + ;; such a file without screwing up + ;; the interpreter invocation. + (end-of-line (and (looking-at "^#!") 2)) + (point)))) + ;; Parse the -*- line into the `result' alist. + (cond ((not (search-forward "-*-" end t)) + ;; doesn't have one. + nil) + ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)") + ;; Antiquated form: "-*- ModeName -*-". + (setq result + (list (cons 'mode + (intern (buffer-substring + (match-beginning 1) + (match-end 1))))) + )) + (t + ;; Usual form: '-*-' [ <variable> ':' <value> ';' ]* '-*-' + ;; (last ";" is optional). + (save-excursion + (if (search-forward "-*-" end t) + (setq end (- (point) 3)) + (error "-*- not terminated before end of line"))) + (while (< (point) end) + (or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*") + (error "malformed -*- line")) + (goto-char (match-end 0)) + ;; There used to be a downcase here, + ;; but the manual didn't say so, + ;; and people want to set var names that aren't all lc. + (let ((key (intern (buffer-substring + (match-beginning 1) + (match-end 1)))) + (val (save-restriction + (narrow-to-region (point) end) + (read (current-buffer))))) + ;; Case sensitivity! Icepicks in my forehead! + (if (equal (downcase (symbol-name key)) "mode") + (setq key 'mode)) + (setq result (cons (cons key val) result)) + (skip-chars-forward " \t;"))) + (setq result (nreverse result)))))) + + (let ((set-any-p (or force (hack-local-variables-p t))) + (mode-p nil)) + (while result + (let ((key (car (car result))) + (val (cdr (car result)))) + (cond ((eq key 'mode) + (setq mode-p t) + (funcall (intern (concat (downcase (symbol-name val)) + "-mode")))) + (set-any-p + (hack-one-local-variable key val)) + (t + nil))) + (setq result (cdr result))) + mode-p))) + +(defvar hack-local-variables-hook nil + "Normal hook run after processing a file's local variables specs. +Major modes can use this to examine user-specified local variables +in order to initialize other data structure based on them. + +This hook runs even if there were no local variables or if their +evaluation was suppressed. See also `enable-local-variables' and +`enable-local-eval'.") + +;; XEmacs this function is not synched with FSF (defun hack-local-variables (&optional force) "Parse, and bind or evaluate as appropriate, any local variables for current buffer." @@ -1336,80 +1438,9 @@ (hack-one-local-variable var val)))))))) -(defun hack-local-variables-prop-line (&optional force) - ;; Set local variables specified in the -*- line. - ;; Returns t if mode was set. - (let ((result nil)) - (save-excursion - (goto-char (point-min)) - (skip-chars-forward " \t\n\r") - (let ((end (save-excursion - ;; If the file begins with "#!" - ;; (un*x exec interpreter magic), look - ;; for mode frobs in the first two - ;; lines. You cannot necessarily - ;; put them in the first line of - ;; such a file without screwing up - ;; the interpreter invocation. - (end-of-line (and (looking-at "^#!") 2)) - (point)))) - ;; Parse the -*- line into the `result' alist. - (cond ((not (search-forward "-*-" end t)) - ;; doesn't have one. - nil) - ((looking-at "[ \t]*\\([^ \t\n\r:;]+\\)\\([ \t]*-\\*-\\)") - ;; Antiquated form: "-*- ModeName -*-". - (setq result - (list (cons 'mode - (intern (buffer-substring - (match-beginning 1) - (match-end 1))))) - )) - (t - ;; Usual form: '-*-' [ <variable> ':' <value> ';' ]* '-*-' - ;; (last ";" is optional). - (save-excursion - (if (search-forward "-*-" end t) - (setq end (- (point) 3)) - (error "-*- not terminated before end of line"))) - (while (< (point) end) - (or (looking-at "[ \t]*\\([^ \t\n:]+\\)[ \t]*:[ \t]*") - (error "malformed -*- line")) - (goto-char (match-end 0)) - ;; There used to be a downcase here, - ;; but the manual didn't say so, - ;; and people want to set var names that aren't all lc. - (let ((key (intern (buffer-substring - (match-beginning 1) - (match-end 1)))) - (val (save-restriction - (narrow-to-region (point) end) - (read (current-buffer))))) - ;; Case sensitivity! Icepicks in my forehead! - (if (equal (downcase (symbol-name key)) "mode") - (setq key 'mode)) - (setq result (cons (cons key val) result)) - (skip-chars-forward " \t;"))) - (setq result (nreverse result)))))) - - (let ((set-any-p (or force (hack-local-variables-p t))) - (mode-p nil)) - (while result - (let ((key (car (car result))) - (val (cdr (car result)))) - (cond ((eq key 'mode) - (setq mode-p t) - (funcall (intern (concat (downcase (symbol-name val)) - "-mode")))) - (set-any-p - (hack-one-local-variable key val)) - (t - nil))) - (setq result (cdr result))) - mode-p))) (defconst ignored-local-variables - (list 'enable-local-eval) + '(enable-local-eval) "Variables to be ignored in a file's local variable spec.") ;; Get confirmation before setting these variables as locals in a file. @@ -1427,10 +1458,12 @@ (put 'load-path 'risky-local-variable t) (put 'exec-directory 'risky-local-variable t) (put 'process-environment 'risky-local-variable t) +(put 'dabbrev-case-fold-search 'risky-local-variable t) +(put 'dabbrev-case-replace 'risky-local-variable t) ;; Don't wait for outline.el to be loaded, for the sake of outline-minor-mode. (put 'outline-level 'risky-local-variable t) (put 'rmail-output-file-alist 'risky-local-variable t) - + ;; This one is safe because the user gets to check it before it is used. (put 'compile-command 'safe-local-variable t) @@ -1485,12 +1518,15 @@ (t (make-local-variable var) (set var val)))) -(defun set-visited-file-name (filename) +(defun set-visited-file-name (filename &optional no-query) "Change name of file visited in current buffer to FILENAME. The next time the buffer is saved it will go in the newly specified file. nil or empty string as argument means make buffer not be visiting any file. Remember to delete the initial contents of the minibuffer -if you wish to pass an empty string as the argument." +if you wish to pass an empty string as the argument. + +The optional second argument NO-QUERY, if non-nil, inhibits asking for +confirmation in the case where the file FILENAME already exists." (interactive "FSet visited file name: ") (if (buffer-base-buffer) (error "An indirect buffer cannot visit a file")) @@ -1504,8 +1540,15 @@ (progn (setq truename (file-truename filename)) ;; #### Do we need to check if truename is non-nil? + ;; XEmacs: FSF uses -visit- (if find-file-use-truenames (setq filename truename)))) +; (let ((buffer (and filename (find-buffer-visiting filename)))) +; (and buffer (not (eq buffer (current-buffer))) +; (not no-query) +; (not (y-or-n-p (message "A buffer is visiting %s; proceed? " +; filename))) +; (error "Aborted"))) (or (equal filename buffer-file-name) (progn (and filename (lock-buffer filename)) @@ -1523,6 +1566,7 @@ (setq buffer-backed-up nil) (clear-visited-file-modtime) (compute-buffer-file-truename) ; insert-file-contents does this too. +;; XEmacs deletion ; ;; Abbreviate the file names of the buffer. ; (if truename ; (progn @@ -1537,9 +1581,9 @@ ;; that visit things that are not local files as if they were files. ;; Changing to visit an ordinary local file instead should flush the hook. (kill-local-variable 'write-file-hooks) - (kill-local-variable 'after-save-hook) + (kill-local-variable 'after-save-hook) ; XEmacs (kill-local-variable 'local-write-file-hooks) - (kill-local-variable 'write-file-data-hooks) + (kill-local-variable 'write-file-data-hooks) ; XEmacs (kill-local-variable 'revert-buffer-function) (kill-local-variable 'backup-inhibited) ;; If buffer was read-only because of version control, @@ -1571,7 +1615,7 @@ (rename-file oauto buffer-auto-save-file-name t))) (if buffer-file-name (set-buffer-modified-p t)) - ;; #### ?? + ;; #### ?? (Not in FSF -sb) (run-hooks 'after-set-visited-file-name-hooks)) (defun write-file (filename &optional confirm) @@ -1580,8 +1624,10 @@ If the buffer is already visiting a file, you can specify a directory name as FILENAME, to write a file of the same old name in that directory. + If optional second arg CONFIRM is non-nil, -ask for confirmation for overwriting an existing file." +ask for confirmation for overwriting an existing file. +Interactively, confirmation is required unless you supply a prefix argument." ;; (interactive "FWrite file: ") (interactive (list (if buffer-file-name @@ -1592,6 +1638,7 @@ (buffer-local-variables))) nil nil (buffer-name))) t)) + ;; XEmacs (and (eq (current-buffer) mouse-grabbed-buffer) (error "Can't write minibuffer window")) (or (null filename) (string-equal filename "") @@ -1607,17 +1654,16 @@ (error "Canceled"))) (set-visited-file-name filename))) (set-buffer-modified-p t) - (setq buffer-read-only nil) + (setq buffer-read-only nil) ; XEmacs (save-buffer)) (defun backup-buffer () "Make a backup of the disk file visited by the current buffer, if appropriate. This is normally done before saving the buffer the first time. -If the value is non-nil, it is the result of `file-modes' on the original file; -this means that the caller, after saving the buffer, should change the modes -of the new file to agree with the old modes." - (if (and make-backup-files - (not backup-inhibited) +If the value is non-nil, it is the result of `file-modes' on the original +file; this means that the caller, after saving the buffer, should change +the modes of the new file to agree with the old modes." + (if (and make-backup-files (not backup-inhibited) (not buffer-backed-up) (file-exists-p buffer-file-name) (memq (aref (elt (file-attributes buffer-file-name) 8) 0) @@ -1669,8 +1715,11 @@ (setq setmodes (file-modes backupname))) (file-error ;; If trouble writing the backup, write it in ~. - (setq backupname (expand-file-name "~/%backup%~")) - (message "Cannot write backup file; backing up in ~/%%backup%%~") + (setq backupname (expand-file-name + (convert-standard-filename + "~/%backup%~"))) + (message "Cannot write backup file; backing up in %s" + (file-name-nondirectory backupname)) (sleep-for 1) (condition-case () (copy-file real-file-name backupname t t) @@ -1716,7 +1765,8 @@ (if keep-backup-version (length name) (or (string-match "\\.~[0-9.]+~\\'" name) - ;; XEmacs - VC uses extensions like ".~tagname~" or ".~1.1.5.2~" + ;; XEmacs - VC uses extensions like ".~tagname~" + ;; or ".~1.1.5.2~" (let ((pos (string-match "\\.~\\([^.~ \t]+\\|[0-9.]+\\)~\\'" name))) (and pos ;; #### - is this filesystem check too paranoid? @@ -1752,11 +1802,17 @@ (defun make-backup-file-name (file) "Create the non-numeric backup file name for FILE. This is a separate function so you can redefine it for customization." - (if (eq system-type 'ms-dos) + (if (and (eq system-type 'ms-dos) + (not (msdos-long-file-names))) (let ((fn (file-name-nondirectory file))) (concat (file-name-directory file) (if (string-match "\\([^.]*\\)\\(\\..*\\)?" fn) (substring fn 0 (match-end 1))) +; (or +; (and (string-match "\\`[^.]+\\'" fn) +; (concat (match-string 0 fn) ".~")) +; (and (string-match "\\`[^.]+\\.\\(..?\\)?" fn) +; (concat (match-string 0 fn) "~"))))) ".bak")) (concat file "~"))) @@ -1837,33 +1893,27 @@ (defun file-relative-name (filename &optional directory) "Convert FILENAME to be relative to DIRECTORY (default: default-directory)." (setq filename (expand-file-name filename) - directory (file-name-as-directory (if directory - (expand-file-name directory) - default-directory))) - (while directory - (let ((up (file-name-directory (directory-file-name directory)))) - (cond ((and (string= directory up) - (file-name-absolute-p directory)) - ;; "/" - (setq directory nil)) - ((string-match (concat "\\`" (regexp-quote directory)) - filename) - (setq filename (substring filename (match-end 0))) - (setq directory nil)) - (t - ;; go up one level - (setq directory up))))) - filename) + directory (file-name-as-directory (expand-file-name + (or directory default-directory)))) + (let ((ancestor "")) + (while (not (string-match (concat "^" (regexp-quote directory)) filename)) + (setq directory (file-name-directory (substring directory 0 -1)) + ancestor (concat "../" ancestor))) + (concat ancestor (substring filename (match-end 0))))) (defun save-buffer (&optional args) "Save current buffer in visited file if modified. Versions described below. By default, makes the previous version into a backup file if previously requested or if this is the first save. -With 1 or 3 \\[universal-argument]'s, marks this version +With 1 \\[universal-argument], marks this version to become a backup when the next save is done. -With 2 or 3 \\[universal-argument]'s, +With 2 \\[universal-argument]'s, unconditionally makes the previous version into a backup file. +With 3 \\[universal-argument]'s, marks this version + to become a backup when the next save is done, + and unconditionally makes the previous version into a backup file. + With argument of 0, never makes the previous version into a backup file. If a file's name is FOO, the names of its numbered backup versions are @@ -1885,8 +1935,7 @@ (make-backup-files (or (and make-backup-files (not (eq args 0))) (memq args '(16 64))))) (and modp (memq args '(16 64)) (setq buffer-backed-up nil)) - (if (and modp large) (message "Saving file %s..." - (buffer-file-name))) + (if (and modp large) (message "Saving file %s..." (buffer-file-name))) (basic-save-buffer) (and modp (memq args '(4 64)) (setq buffer-backed-up nil)))) @@ -1941,7 +1990,8 @@ (if (buffer-base-buffer) (set-buffer (buffer-base-buffer))) (if (buffer-modified-p) - (let ((recent-save (recent-auto-save-p))) + (let ((recent-save (recent-auto-save-p)) + setmodes tempsetmodes) ;; On VMS, rename file and buffer to get rid of version number. (if (and (eq system-type 'vax-vms) (not (string= buffer-file-name @@ -2027,7 +2077,7 @@ ;; but inhibited if one of write-file-hooks returns non-nil. ;; It returns a value to store in setmodes. (defun basic-save-buffer-1 () - (let (setmodes tempsetmodes) + (let (tempsetmodes setmodes) (if (not (file-writable-p buffer-file-name)) (let ((dir (file-name-directory buffer-file-name))) (if (not (file-directory-p dir)) @@ -2043,20 +2093,25 @@ "Attempt to save to a file which you aren't allowed to write")))))) (or buffer-backed-up (setq setmodes (backup-buffer))) - (let ((dir (file-name-directory buffer-file-name))) + (let ((dir (file-name-directory buffer-file-name))) (if (and file-precious-flag (file-writable-p dir)) ;; If file is precious, write temp name, then rename it. ;; This requires write access to the containing dir, ;; which is why we don't try it if we don't have that access. (let ((realname buffer-file-name) - tempname nogood i succeed + tempname temp nogood i succeed (old-modtime (visited-file-modtime))) (setq i 0) (setq nogood t) ;; Find the temporary name to write under. (while nogood - (setq tempname (format "%s#tmp#%d" dir i)) + (setq tempname (format + (if (and (eq system-type 'ms-dos) + (not (msdos-long-file-names))) + "%s#%d.tm#" ; MSDOS limits files to 8+3 + "%s#tmp#%d") + dir i)) (setq nogood (file-exists-p tempname)) (setq i (1+ i))) (unwind-protect @@ -2067,7 +2122,7 @@ (setq succeed t)) ;; If writing the temp file fails, ;; delete the temp file. - (or succeed + (or succeed (progn (delete-file tempname) (set-visited-file-modtime old-modtime)))) @@ -2086,6 +2141,7 @@ ;; Change the mode back, after writing. (setq setmodes (file-modes buffer-file-name)) (set-file-modes buffer-file-name 511))) + ;; XEmacs change to end of function (basic-write-file-data buffer-file-name buffer-file-truename))) (setq buffer-file-number (if buffer-file-name @@ -2129,6 +2185,7 @@ as well as about file buffers." (interactive "P") (save-window-excursion + ;; XEmacs - do not use queried flag (let ((files-done (map-y-or-n-p (function @@ -2239,13 +2296,16 @@ (file (file-name-nondirectory filename)) (dir (file-name-directory filename)) (comp (file-name-all-completions file dir)) - newest) + newest tem) (while comp - (setq file (concat dir (car comp)) + (setq tem (car comp) comp (cdr comp)) - (if (and (backup-file-name-p file) - (or (null newest) (file-newer-than-file-p file newest))) - (setq newest file))) + (cond ((and (backup-file-name-p tem) + (string= (file-name-sans-versions tem) file)) + (setq tem (concat dir tem)) + (if (or (null newest) + (file-newer-than-file-p tem newest)) + (setq newest tem))))) newest)) (defun rename-uniquely () @@ -2270,6 +2330,7 @@ (rename-buffer name) (redraw-modeline)))) +;; XEmacs (defun make-directory-path (path) "Create all the directories along path that don't exist yet." (interactive "Fdirectory path to create: ") @@ -2283,6 +2344,7 @@ Noninteractively, the second (optional) argument PARENTS says whether to create parent directories if they don't exist." + ;; XEmacs (interactive (list (let ((current-prefix-arg current-prefix-arg)) (read-directory-name "Create directory: ")) current-prefix-arg)) @@ -2326,7 +2388,7 @@ If `revert-buffer-function' is used to override the normal revert mechanism, this hook is not used.") -(defun revert-buffer (&optional ignore-auto noconfirm) +(defun revert-buffer (&optional ignore-auto noconfirm preserve-modes) "Replace the buffer text with the text of the visited file on disk. This undoes all changes since the file was visited or saved. With a prefix argument, offer to revert from latest auto-save file, if @@ -2356,7 +2418,7 @@ (funcall revert-buffer-function ignore-auto noconfirm) (let* ((opoint (point)) (auto-save-p (and (not ignore-auto) - (recent-auto-save-p) + (recent-auto-save-p) buffer-auto-save-file-name (file-readable-p buffer-auto-save-file-name) (y-or-n-p @@ -2381,6 +2443,7 @@ ;; Effectively copy the after-revert-hook status, ;; since after-find-file will clobber it. (let ((global-hook (default-value 'after-revert-hook)) + ;; XEmacs (local-hook-p (local-variable-p 'after-revert-hook (current-buffer))) (local-hook (and (local-variable-p 'after-revert-hook @@ -2407,7 +2470,7 @@ ;; have changed the truename. ;XEmacs: already done by insert-file-contents ;(compute-buffer-file-truename) - (after-find-file nil nil t t) + (after-find-file nil nil t t preserve-modes) ;; Run after-revert-hook as it was before we reverted. (setq-default revert-buffer-internal-hook global-hook) (if local-hook-p @@ -2425,7 +2488,7 @@ ;; Not just because users often use the default. (interactive "FRecover file: ") (setq file (expand-file-name file)) - (if (auto-save-file-name-p file) + (if (auto-save-file-name-p (file-name-nondirectory file)) (error "%s is an auto-save file" file)) (let ((file-name (let ((buffer-file-name file)) (make-auto-save-file-name)))) @@ -2455,7 +2518,8 @@ To choose one, move point to the proper line and then type C-c C-c. Then you'll be asked about a number of files to recover." (interactive) - (dired (concat auto-save-list-file-prefix "*")) + (let ((ls-lisp-support-shell-wildcards t)) + (dired (concat auto-save-list-file-prefix "*"))) (goto-char (point-min)) (or (looking-at "Move to the session you want to recover,") (let ((inhibit-read-only t)) @@ -2463,6 +2527,7 @@ "then type C-c C-c to select it.\n\n" "You can also delete some of these files;\n" "type d on a line to mark that file for deletion.\n\n"))) + ;; XEmacs (use-local-map (let ((map (make-sparse-keymap))) (set-keymap-parents map (list (current-local-map))) map)) @@ -2532,7 +2597,7 @@ (lambda (file) (condition-case nil (save-excursion (recover-file file)) - (error + (error "Failed to recover `%s'" file))) files '("file" "files" "recover")) @@ -2549,6 +2614,7 @@ (and (not (string-equal name "")) (/= (aref name 0) ? ) (yes-or-no-p + ;; XEmacs change (format (if (buffer-modified-p buffer) (gettext "Buffer %s HAS BEEN EDITED. Kill? ") @@ -2596,6 +2662,7 @@ (rename-file osave buffer-auto-save-file-name t)))) ;; see also ../packages/auto-save.el +;; XEmacs change (defun make-auto-save-file-name (&optional filename) "Return file name to use for auto-saves of current buffer. Does not consider `auto-save-visited-file-name' as that variable is checked @@ -2658,10 +2725,76 @@ (defun auto-save-file-name-p (filename) "Return non-nil if FILENAME can be yielded by `make-auto-save-file-name'. -FILENAME should lack slashes. -You can redefine this for customization." +FILENAME should lack slashes. You can redefine this for customization." (string-match "\\`#.*#\\'" filename)) +(defun wildcard-to-regexp (wildcard) + "Given a shell file name pattern WILDCARD, return an equivalent regexp. +The generated regexp will match a filename iff the filename +matches that wildcard according to shell rules. Only wildcards known +by `sh' are supported." + (let* ((i (string-match "[[.*+\\^$?]" wildcard)) + ;; Copy the initial run of non-special characters. + (result (substring wildcard 0 i)) + (len (length wildcard))) + ;; If no special characters, we're almost done. + (if i + (while (< i len) + (let ((ch (aref wildcard i)) + j) + (setq + result + (concat result + (cond + ((eq ch ?\[) ; [...] maps to regexp char class + (progn + (setq i (1+ i)) + (concat + (cond + ((eq (aref wildcard i) ?!) ; [!...] -> [^...] + (progn + (setq i (1+ i)) + (if (eq (aref wildcard i) ?\]) + (progn + (setq i (1+ i)) + "[^]") + "[^"))) + ((eq (aref wildcard i) ?^) + ;; Found "[^". Insert a `\0' character + ;; (which cannot happen in a filename) + ;; into the character class, so that `^' + ;; is not the first character after `[', + ;; and thus non-special in a regexp. + (progn + (setq i (1+ i)) + "[\000^")) + ((eq (aref wildcard i) ?\]) + ;; I don't think `]' can appear in a + ;; character class in a wildcard, but + ;; let's be general here. + (progn + (setq i (1+ i)) + "[]")) + (t "[")) + (prog1 ; copy everything upto next `]'. + (substring wildcard + i + (setq j (string-match + "]" wildcard i))) + (setq i (if j (1- j) (1- len))))))) + ((eq ch ?.) "\\.") + ((eq ch ?*) "[^\000]*") + ((eq ch ?+) "\\+") + ((eq ch ?^) "\\^") + ((eq ch ?$) "\\$") + ((eq ch ?\\) "\\\\") ; probably cannot happen... + ((eq ch ??) "[^\000]") + (t (char-to-string ch))))) + (setq i (1+ i))))) + ;; Shell wildcards should match the entire filename, + ;; not its part. Make the regexp say so. + (concat "\\`" result "\\'"))) + (defconst list-directory-brief-switches (if (eq system-type 'vax-vms) "" "-CF") "*Switches for list-directory to pass to `ls' for brief listing,") @@ -2694,7 +2827,10 @@ (terpri) (save-excursion (set-buffer "*Directory*") - (setq default-directory (file-name-directory dirname)) + (setq default-directory + (if (file-directory-p dirname) + (file-name-as-directory dirname) + (file-name-directory dirname))) (let ((wildcard (not (file-directory-p dirname)))) (insert-directory dirname switches wildcard (not wildcard))))))) @@ -2740,10 +2876,10 @@ (vms-read-directory file switches (current-buffer)) (if wildcard ;; Run ls in the directory of the file pattern we asked for. - (let ((default-directory - (if (file-name-absolute-p file) - (file-name-directory file) - (file-name-directory (expand-file-name file)))) + (let ((default-directory + (if (file-name-absolute-p file) + (file-name-directory file) + (file-name-directory (expand-file-name file)))) (pattern (file-name-nondirectory file)) (beg 0)) ;; Quote some characters that have special meanings in shells; @@ -2751,7 +2887,7 @@ ;; We also currently don't quote the quoting characters ;; in case people want to use them explicitly to quote ;; wildcard characters. - ;;#### Unix-specific + ;;#### Unix-specific (while (string-match "[ \t\n;<>&|()#$]" pattern beg) (setq pattern (concat (substring pattern 0 (match-beginning 0)) @@ -2782,7 +2918,7 @@ (setq list (cons (substring switches 0 (match-beginning 0)) list) switches (substring switches (match-end 0)))) - (setq list (cons switches list))))) + (setq list (nreverse (cons switches list)))))) (append list (list (if full-directory-p @@ -2824,6 +2960,7 @@ (run-hook-with-args-until-failure 'kill-emacs-query-functions) (kill-emacs))) +;; XEmacs (defun symlink-expand-file-name (filename) "If FILENAME is a symlink, return its non-symlink equivalent. Unlike `file-truename', this doesn't chase symlinks in directory @@ -2838,7 +2975,7 @@ (error "Apparently circular symlink path")))) - +;; Written in C in FSF (defun insert-file-contents (filename &optional visit beg end replace) "Insert contents of file FILENAME after point. Returns list of absolute file name and length of data inserted. @@ -2857,6 +2994,7 @@ and (2) it puts less data in the undo list." (insert-file-contents-internal filename visit beg end replace)) +;; Written in C in FSF (defun write-region (start end filename &optional append visit lockname) "Write current region into specified file. When called from a program, takes three arguments: @@ -2878,6 +3016,7 @@ (interactive "r\nFWrite region to file: ") (write-region-internal start end filename append visit lockname)) +;; Written in C in FSF (defun load (file &optional noerror nomessage nosuffix) "Execute a file of Lisp code named FILE. First try FILE with `.elc' appended, then try with `.el', @@ -2892,4 +3031,27 @@ Return t if file exists." (load-internal file noerror nomessage nosuffix)) +;(define-key ctl-x-map "\C-f" 'find-file) +;(define-key ctl-x-map "\C-q" 'toggle-read-only) +;(define-key ctl-x-map "\C-r" 'find-file-read-only) +;(define-key ctl-x-map "\C-v" 'find-alternate-file) +;(define-key ctl-x-map "\C-s" 'save-buffer) +;(define-key ctl-x-map "s" 'save-some-buffers) +;(define-key ctl-x-map "\C-w" 'write-file) +;(define-key ctl-x-map "i" 'insert-file) +;(define-key esc-map "~" 'not-modified) +;(define-key ctl-x-map "\C-d" 'list-directory) +;(define-key ctl-x-map "\C-c" 'save-buffers-kill-emacs) + +;(define-key ctl-x-4-map "f" 'find-file-other-window) +;(define-key ctl-x-4-map "r" 'find-file-read-only-other-window) +;(define-key ctl-x-4-map "\C-f" 'find-file-other-window) +;(define-key ctl-x-4-map "b" 'switch-to-buffer-other-window) +;(define-key ctl-x-4-map "\C-o" 'display-buffer) + +;(define-key ctl-x-5-map "b" 'switch-to-buffer-other-frame) +;(define-key ctl-x-5-map "f" 'find-file-other-frame) +;(define-key ctl-x-5-map "\C-f" 'find-file-other-frame) +;(define-key ctl-x-5-map "r" 'find-file-read-only-other-frame) + ;;; files.el ends here