aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Love2000-04-09 17:18:48 +0000
committerDave Love2000-04-09 17:18:48 +0000
commit86724078eac458d89e6b1acb98fda23d9c0ef40a (patch)
treeaa3a854fc955099450fb47bbf390842e85e98e79
parentbe0dbdab007cf09a2cac30c89ad4d530b08abeae (diff)
downloademacs-86724078eac458d89e6b1acb98fda23d9c0ef40a.tar.gz
emacs-86724078eac458d89e6b1acb98fda23d9c0ef40a.zip
(backup-enable-predicate): Use temporary-file-directory,
small-temporary-file-directory. (make-backup-file-name-function, backup-directory-alist): New variables. (make-backup-file-name-1): New function. (make-backup-file-name): Use it. (find-backup-file-name): Likewise. Use format for clarity, not concat. (file-newest-backup): Use make-backup-file-name.
-rw-r--r--lisp/files.el177
1 files changed, 133 insertions, 44 deletions
diff --git a/lisp/files.el b/lisp/files.el
index 9de7c0ba8ea..f3af7b9e511 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -135,10 +135,20 @@ This variable is relevant only if `backup-by-copying' and
135 135
136(defvar backup-enable-predicate 136(defvar backup-enable-predicate
137 '(lambda (name) 137 '(lambda (name)
138 (or (< (length name) 5) 138 (and (let ((comp (compare-strings temporary-file-directory 0 nil
139 (not (string-equal "/tmp/" (substring name 0 5))))) 139 name 0 nil)))
140 (and (not (eq comp t))
141 (< comp -1)))
142 (if small-temporary-file-directory
143 (let ((comp (compare-strings small-temporary-file-directory 0 nil
144 name 0 nil)))
145 (and (not (eq comp t))
146 (< comp -1)))
147 t)))
140 "Predicate that looks at a file name and decides whether to make backups. 148 "Predicate that looks at a file name and decides whether to make backups.
141Called with an absolute file name as argument, it returns t to enable backup.") 149Called with an absolute file name as argument, it returns t to enable backup.
150The default version checks for files in `temporary-file-directory' or
151`small-temporary-file-directory'.")
142 152
143(defcustom buffer-offer-save nil 153(defcustom buffer-offer-save nil
144 "*Non-nil in a buffer means always offer to save buffer on exit. 154 "*Non-nil in a buffer means always offer to save buffer on exit.
@@ -724,7 +734,7 @@ expand wildcards (if any) and visit multiple files."
724 734
725(defun find-file-read-only (filename &optional wildcards) 735(defun find-file-read-only (filename &optional wildcards)
726 "Edit file FILENAME but don't allow changes. 736 "Edit file FILENAME but don't allow changes.
727Like \\[find-file] but marks buffer as read-only. 737Like `find-file' but marks buffer as read-only.
728Use \\[toggle-read-only] to permit editing." 738Use \\[toggle-read-only] to permit editing."
729 (interactive "fFind file read-only: \np") 739 (interactive "fFind file read-only: \np")
730 (find-file filename wildcards) 740 (find-file filename wildcards)
@@ -1571,10 +1581,9 @@ and we don't even do that unless it would come from the file name."
1571 (if (string-match (car (car alist)) name) 1581 (if (string-match (car (car alist)) name)
1572 (if (and (consp (cdr (car alist))) 1582 (if (and (consp (cdr (car alist)))
1573 (nth 2 (car alist))) 1583 (nth 2 (car alist)))
1574 (progn 1584 (setq mode (car (cdr (car alist)))
1575 (setq mode (car (cdr (car alist))) 1585 name (substring name 0 (match-beginning 0))
1576 name (substring name 0 (match-beginning 0)) 1586 keep-going t)
1577 keep-going t))
1578 (setq mode (cdr (car alist)) 1587 (setq mode (cdr (car alist))
1579 keep-going nil))) 1588 keep-going nil)))
1580 (setq alist (cdr alist)))) 1589 (setq alist (cdr alist))))
@@ -1593,9 +1602,9 @@ and we don't even do that unless it would come from the file name."
1593 (let ((interpreter 1602 (let ((interpreter
1594 (save-excursion 1603 (save-excursion
1595 (goto-char (point-min)) 1604 (goto-char (point-min))
1596 (if (looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)") 1605 (if (looking-at "#![ \t]?\\([^ \t\n]*\
1597 (buffer-substring (match-beginning 2) 1606/bin/env[ \t]\\)?\\([^ \t\n]+\\)")
1598 (match-end 2)) 1607 (match-string 2)
1599 ""))) 1608 "")))
1600 elt) 1609 elt)
1601 ;; Map interpreter name to a mode. 1610 ;; Map interpreter name to a mode.
@@ -2173,19 +2182,94 @@ the value is \"\"."
2173 (if period 2182 (if period
2174 ""))))) 2183 "")))))
2175 2184
2185(defcustom make-backup-file-name-function nil
2186 "A function to use instead of the default `make-backup-file-name'.
2187A value of nil gives the default `make-backup-file-name' behaviour.
2188
2189This could be buffer-local to do something special for for specific
2190files. If you define it, you may need to change `backup-file-name-p'
2191and `file-name-sans-versions' too.
2192
2193See also `backup-directory-alist'."
2194 :group 'backup
2195 :type '(choice (const :tag "Default" nil)
2196 (function :tag "Your function")))
2197
2198(defcustom backup-directory-alist nil
2199 "Alist of filename patterns and backup directory names.
2200Each element looks like (REGEXP . DIRECTORY). Backups of files with
2201names matching REGEXP will be made in DIRECTORY. DIRECTORY may be
2202relative or absolute. If it is absolute, so that all matching files
2203are backed up into the same directory, the file names in this
2204directory will be the full name of the file backed up with all
2205directory separators changed to `|' to prevent clashes. This will not
2206work correctly if your filesystem truncates the resulting name.
2207
2208For the common case of all backups going into one directory, the alist
2209should contain a single element pairing \".\" with the appropriate
2210directory name.
2211
2212If this variable is nil, or it fails to match a filename, the backup
2213is made in the original file's directory.
2214
2215On MS-DOS filesystems without long names this variable is always
2216ignored."
2217 :group 'backup
2218 :type '(repeat (cons (regexp :tag "Regexp macthing filename")
2219 (directory :tag "Backup directory name"))))
2220
2176(defun make-backup-file-name (file) 2221(defun make-backup-file-name (file)
2177 "Create the non-numeric backup file name for FILE. 2222 "Create the non-numeric backup file name for FILE.
2178This is a separate function so you can redefine it for customization." 2223Normally this will just be the file's name with `~' appended.
2179 (if (and (eq system-type 'ms-dos) 2224Customization hooks are provided as follows.
2180 (not (msdos-long-file-names))) 2225
2181 (let ((fn (file-name-nondirectory file))) 2226If the variable `make-backup-file-name-function' is non-nil, its value
2182 (concat (file-name-directory file) 2227should be a function which will be called with FILE as its argument;
2183 (or 2228the resulting name is used.
2184 (and (string-match "\\`[^.]+\\'" fn) 2229
2185 (concat (match-string 0 fn) ".~")) 2230Otherwise a match for FILE is sought in `backup-directory-alist'; see
2186 (and (string-match "\\`[^.]+\\.\\(..?\\)?" fn) 2231the documentation of that variable. If the directory for the backup
2187 (concat (match-string 0 fn) "~"))))) 2232doesn't exist, it is created."
2188 (concat file "~"))) 2233 (if make-backup-file-name-function
2234 (funcall make-backup-file-name-function file)
2235 (if (and (eq system-type 'ms-dos)
2236 (not (msdos-long-file-names)))
2237 (let ((fn (file-name-nondirectory file)))
2238 (concat (file-name-directory file)
2239 (or (and (string-match "\\`[^.]+\\'" fn)
2240 (concat (match-string 0 fn) ".~"))
2241 (and (string-match "\\`[^.]+\\.\\(..?\\)?" fn)
2242 (concat (match-string 0 fn) "~")))))
2243 (concat (make-backup-file-name-1 file) "~"))))
2244
2245(defun make-backup-file-name-1 (file)
2246 "Subroutine of `make-backup-file-name' and `find-backup-file-name'."
2247 (let ((alist backup-directory-alist)
2248 elt backup-directory)
2249 (while alist
2250 (setq elt (pop alist))
2251 (if (string-match (car elt) file)
2252 (setq backup-directory (cdr elt)
2253 alist nil)))
2254 (if (null backup-directory)
2255 file
2256 (unless (file-exists-p backup-directory)
2257 (condition-case nil
2258 (make-directory backup-directory 'parents)
2259 (file-error file)))
2260 (if (file-name-absolute-p backup-directory)
2261 ;; Make the name unique by substituting directory
2262 ;; separators. It may not really be worth bothering about
2263 ;; doubling `|'s in the original name...
2264 (expand-file-name
2265 (subst-char-in-string
2266 directory-sep-char ?|
2267 (replace-regexp-in-string "|" "||" file))
2268 backup-directory)
2269 (expand-file-name (file-name-nondirectory file)
2270 (file-name-as-directory
2271 (expand-file-name backup-directory
2272 (file-name-directory file))))))))
2189 2273
2190(defun backup-file-name-p (file) 2274(defun backup-file-name-p (file)
2191 "Return non-nil if FILE is a backup file name (numeric or not). 2275 "Return non-nil if FILE is a backup file name (numeric or not).
@@ -2212,45 +2296,47 @@ the index in the name where the version number begins."
2212(defun find-backup-file-name (fn) 2296(defun find-backup-file-name (fn)
2213 "Find a file name for a backup file FN, and suggestions for deletions. 2297 "Find a file name for a backup file FN, and suggestions for deletions.
2214Value is a list whose car is the name for the backup file 2298Value is a list whose car is the name for the backup file
2215 and whose cdr is a list of old versions to consider deleting now. 2299and whose cdr is a list of old versions to consider deleting now.
2216If the value is nil, don't make a backup." 2300If the value is nil, don't make a backup.
2301Uses `backup-directory-alist' in the same way as does
2302`make-backup-file-name'."
2217 (let ((handler (find-file-name-handler fn 'find-backup-file-name))) 2303 (let ((handler (find-file-name-handler fn 'find-backup-file-name)))
2218 ;; Run a handler for this function so that ange-ftp can refuse to do it. 2304 ;; Run a handler for this function so that ange-ftp can refuse to do it.
2219 (if handler 2305 (if handler
2220 (funcall handler 'find-backup-file-name fn) 2306 (funcall handler 'find-backup-file-name fn)
2221 (if (eq version-control 'never) 2307 (if (eq version-control 'never)
2222 (list (make-backup-file-name fn)) 2308 (list (make-backup-file-name fn))
2223 (let* ((base-versions (concat (file-name-nondirectory fn) ".~")) 2309 (let* ((basic-name (make-backup-file-name-1 fn))
2310 (base-versions (concat (file-name-nondirectory basic-name)
2311 ".~"))
2224 (backup-extract-version-start (length base-versions)) 2312 (backup-extract-version-start (length base-versions))
2225 possibilities
2226 (versions nil)
2227 (high-water-mark 0) 2313 (high-water-mark 0)
2228 (deserve-versions-p nil) 2314 (number-to-delete 0)
2229 (number-to-delete 0)) 2315 possibilities deserve-versions-p versions)
2230 (condition-case () 2316 (condition-case ()
2231 (setq possibilities (file-name-all-completions 2317 (setq possibilities (file-name-all-completions
2232 base-versions 2318 base-versions
2233 (file-name-directory fn)) 2319 (file-name-directory basic-name))
2234 versions (sort (mapcar 2320 versions (sort (mapcar #'backup-extract-version
2235 (function backup-extract-version) 2321 possibilities)
2236 possibilities) 2322 #'<)
2237 '<)
2238 high-water-mark (apply 'max 0 versions) 2323 high-water-mark (apply 'max 0 versions)
2239 deserve-versions-p (or version-control 2324 deserve-versions-p (or version-control
2240 (> high-water-mark 0)) 2325 (> high-water-mark 0))
2241 number-to-delete (- (length versions) 2326 number-to-delete (- (length versions)
2242 kept-old-versions kept-new-versions -1)) 2327 kept-old-versions
2243 (file-error 2328 kept-new-versions
2244 (setq possibilities nil))) 2329 -1))
2330 (file-error (setq possibilities nil)))
2245 (if (not deserve-versions-p) 2331 (if (not deserve-versions-p)
2246 (list (make-backup-file-name fn)) 2332 (list (concat basic-name "~"))
2247 (cons (concat fn ".~" (int-to-string (1+ high-water-mark)) "~") 2333 (cons (format "%s.~%d~" basic-name (1+ high-water-mark))
2248 (if (and (> number-to-delete 0) 2334 (if (and (> number-to-delete 0)
2249 ;; Delete nothing if there is overflow 2335 ;; Delete nothing if there is overflow
2250 ;; in the number of versions to keep. 2336 ;; in the number of versions to keep.
2251 (>= (+ kept-new-versions kept-old-versions -1) 0)) 2337 (>= (+ kept-new-versions kept-old-versions -1) 0))
2252 (mapcar (function (lambda (n) 2338 (mapcar (lambda (n)
2253 (concat fn ".~" (int-to-string n) "~"))) 2339 (format "%s.~%d~" basic-name n))
2254 (let ((v (nthcdr kept-old-versions versions))) 2340 (let ((v (nthcdr kept-old-versions versions)))
2255 (rplacd (nthcdr (1- number-to-delete) v) ()) 2341 (rplacd (nthcdr (1- number-to-delete) v) ())
2256 v)))))))))) 2342 v))))))))))
@@ -2651,15 +2737,18 @@ saying what text to write."
2651 2737
2652(defun file-newest-backup (filename) 2738(defun file-newest-backup (filename)
2653 "Return most recent backup file for FILENAME or nil if no backups exist." 2739 "Return most recent backup file for FILENAME or nil if no backups exist."
2654 (let* ((filename (expand-file-name filename)) 2740 ;; `make-backup-file-name' will get us the right directory for
2741 ;; ordinary or numeric backups. It might create a directory for
2742 ;; backups as a side-effect, according to `backup-directory-alist'.
2743 (let* ((filename (file-name-sans-versions
2744 (make-backup-file-name filename)))
2655 (file (file-name-nondirectory filename)) 2745 (file (file-name-nondirectory filename))
2656 (dir (file-name-directory filename)) 2746 (dir (file-name-directory filename))
2657 (comp (file-name-all-completions file dir)) 2747 (comp (file-name-all-completions file dir))
2658 (newest nil) 2748 (newest nil)
2659 tem) 2749 tem)
2660 (while comp 2750 (while comp
2661 (setq tem (car comp) 2751 (setq tem (pop comp))
2662 comp (cdr comp))
2663 (cond ((and (backup-file-name-p tem) 2752 (cond ((and (backup-file-name-p tem)
2664 (string= (file-name-sans-versions tem) file)) 2753 (string= (file-name-sans-versions tem) file))
2665 (setq tem (concat dir tem)) 2754 (setq tem (concat dir tem))