aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1995-04-26 10:15:03 +0000
committerRichard M. Stallman1995-04-26 10:15:03 +0000
commitf2ee419195f831face5b6ac90860b6ac03c85ecd (patch)
treed59b9ed1d76010c97e937ab9eea08eb18637a42a
parentc6d4f6288af8068b414c2e54371f0d69b55aeeac (diff)
downloademacs-f2ee419195f831face5b6ac90860b6ac03c85ecd.tar.gz
emacs-f2ee419195f831face5b6ac90860b6ac03c85ecd.zip
(vc-buffer-backend): New function.
Also new variable, local in all buffers. (vc-kill-buffer-hook): Kill local vc-buffer-backend. (vc-kill-buffer-hook): Don't put it on kill-buffer-hook. (vc-file-clearprops): Function moved here. (vc-workfile-version): Function moved here. (vc-mode-line): Don't call vc-locking-user. Add branch support for RCS; treat CVS more like RCS and SCCS. (vc-occurences, vc-trunk-p, vc-branch-p, vc-minor-revision) (vc-branch-part): new functions that operate on RCS revision numbers. (vc-status): Use the new property vc-workfile-version and vc-locking-user (see vc.el). Display "locking state" for CVS. (vc-find-cvs-master): Search for file name case-sensitively, store version number into the new property vc-workfile-version. (vc-find-file-hook): kill any remaining properties. Like this, when re-finding a file (for example because it has changed on disk), the version control state gets re-computed. (vc-mode-line): CVS case: make the buffer read-only if the file is unmodified. (vc-kill-buffer-hook): Clear file's vc props when buffer is killed.
-rw-r--r--lisp/vc-hooks.el155
1 files changed, 111 insertions, 44 deletions
diff --git a/lisp/vc-hooks.el b/lisp/vc-hooks.el
index 6780f3ad703..c3ca8c57c8b 100644
--- a/lisp/vc-hooks.el
+++ b/lisp/vc-hooks.el
@@ -3,8 +3,9 @@
3;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
4 4
5;; Author: Eric S. Raymond <esr@snark.thyrsus.com> 5;; Author: Eric S. Raymond <esr@snark.thyrsus.com>
6;; Maintainer: ttn@netcom.com 6;; Modified by:
7;; Version: 5.3 + CVS hacks by ceder@lysator.liu.se made in Jan-Feb 1994. 7;; Per Cederqvist <ceder@lysator.liu.se>
8;; Andre Spiegel <spiegel@berlin.informatik.uni-stuttgart.de>
8 9
9;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
10 11
@@ -24,6 +25,9 @@
24 25
25;;; Commentary: 26;;; Commentary:
26 27
28;; This is the always-loaded portion of VC.
29;; It takes care VC-related activities that are done when you visit a file,
30;; so that vc.el itself is loaded only when you use a VC command.
27;; See the commentary of vc.el. 31;; See the commentary of vc.el.
28 32
29;;; Code: 33;;; Code:
@@ -53,8 +57,10 @@ Otherwise, not displayed.")
53(put 'vc-mode 'permanent-local t) 57(put 'vc-mode 'permanent-local t)
54 58
55;; We need a notion of per-file properties because the version 59;; We need a notion of per-file properties because the version
56;; control state of a file is expensive to derive --- we don't 60;; control state of a file is expensive to derive --- we compute
57;; want to recompute it even on every find. 61;; them when the file is initially found, keep them up to date
62;; during any subsequent VC operations, and forget them when
63;; the buffer is killed.
58 64
59(defmacro vc-error-occurred (&rest body) 65(defmacro vc-error-occurred (&rest body)
60 (list 'condition-case nil (cons 'progn (append body '(nil))) '(error t))) 66 (list 'condition-case nil (cons 'progn (append body '(nil))) '(error t)))
@@ -62,6 +68,9 @@ Otherwise, not displayed.")
62(defvar vc-file-prop-obarray [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 68(defvar vc-file-prop-obarray [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
63 "Obarray for per-file properties.") 69 "Obarray for per-file properties.")
64 70
71(defvar vc-buffer-backend t)
72(make-variable-buffer-local 'vc-buffer-backend)
73
65(defun vc-file-setprop (file property value) 74(defun vc-file-setprop (file property value)
66 ;; set per-file property 75 ;; set per-file property
67 (put (intern file vc-file-prop-obarray) property value)) 76 (put (intern file vc-file-prop-obarray) property value))
@@ -70,6 +79,36 @@ Otherwise, not displayed.")
70 ;; get per-file property 79 ;; get per-file property
71 (get (intern file vc-file-prop-obarray) property)) 80 (get (intern file vc-file-prop-obarray) property))
72 81
82;;; functions that operate on RCS revision numbers
83
84(defun vc-occurrences (object sequence)
85 ;; return the number of occurences of OBJECT in SEQUENCE
86 ;; (is it really true that Emacs Lisp doesn't provide such a function?)
87 (let ((len (length sequence)) (index 0) (occ 0))
88 (while (< index len)
89 (if (eq object (elt sequence index))
90 (setq occ (1+ occ)))
91 (setq index (1+ index)))
92 occ))
93
94(defun vc-trunk-p (rev)
95 ;; return t if REV is a revision on the trunk
96 (not (eq nil (string-match "\\`[0-9]+\\.[0-9]+\\'" rev))))
97
98(defun vc-branch-p (rev)
99 ;; return t if REV is the branch part of a revision,
100 ;; i.e. a revision without a minor number
101 (eq 0 (% (vc-occurrences ?. rev) 2)))
102
103(defun vc-minor-revision (rev)
104 ;; return the minor revision number of REV,
105 ;; i.e. the number after the last dot.
106 (substring rev (1+ (string-match "\\.[0-9]+\\'" rev))))
107
108(defun vc-branch-part (rev)
109 ;; return the branch part of a revision number REV
110 (substring rev 0 (string-match "\\.[0-9]+\\'" rev)))
111
73;;; actual version-control code starts here 112;;; actual version-control code starts here
74 113
75(defun vc-registered (file) 114(defun vc-registered (file)
@@ -108,25 +147,29 @@ Otherwise, not displayed.")
108 ;; If it is, do a (throw 'found (cons MASTER 'CVS)). 147 ;; If it is, do a (throw 'found (cons MASTER 'CVS)).
109 ;; Note: If the file is ``cvs add''ed but not yet ``cvs commit''ed 148 ;; Note: If the file is ``cvs add''ed but not yet ``cvs commit''ed
110 ;; the MASTER will not actually exist yet. The other parts of VC 149 ;; the MASTER will not actually exist yet. The other parts of VC
111 ;; checks for this condition. This function returns something random if 150 ;; checks for this condition. This function returns nil if
112 ;; DIRNAME/BASENAME is not handled by CVS. 151 ;; DIRNAME/BASENAME is not handled by CVS.
113 (if (and (file-directory-p (concat dirname "CVS/")) 152 (if (and (file-directory-p (concat dirname "CVS/"))
114 (file-readable-p (concat dirname "CVS/Entries"))) 153 (file-readable-p (concat dirname "CVS/Entries")))
115 (let ((bufs nil)) 154 (let ((bufs nil) (fold case-fold-search))
116 (unwind-protect 155 (unwind-protect
117 (save-excursion 156 (save-excursion
118 (setq bufs (list 157 (setq bufs (list
119 (find-file-noselect (concat dirname "CVS/Entries")))) 158 (find-file-noselect (concat dirname "CVS/Entries"))))
120 (set-buffer (car bufs)) 159 (set-buffer (car bufs))
121 (goto-char (point-min)) 160 (goto-char (point-min))
161 ;; make sure the file name is searched
162 ;; case-sensitively
163 (setq case-fold-search nil)
122 (cond 164 (cond
123 ((re-search-forward 165 ((re-search-forward
124 (concat "^/" (regexp-quote basename) "/\\([^/]*\\)/") 166 (concat "^/" (regexp-quote basename) "/\\([^/]*\\)/")
125 nil t) 167 nil t)
168 (setq case-fold-search fold) ;; restore the old value
126 ;; We found it. Store away version number, now 169 ;; We found it. Store away version number, now
127 ;; that we are anyhow so close to finding it. 170 ;; that we are anyhow so close to finding it.
128 (vc-file-setprop (concat dirname basename) 171 (vc-file-setprop (concat dirname basename)
129 'vc-your-latest-version 172 'vc-workfile-version
130 (buffer-substring (match-beginning 1) 173 (buffer-substring (match-beginning 1)
131 (match-end 1))) 174 (match-end 1)))
132 (setq bufs (cons (find-file-noselect 175 (setq bufs (cons (find-file-noselect
@@ -139,7 +182,9 @@ Otherwise, not displayed.")
139 (1- (point-max)))) 182 (1- (point-max))))
140 basename 183 basename
141 ",v"))) 184 ",v")))
142 (throw 'found (cons master 'CVS)))))) 185 (throw 'found (cons master 'CVS))))
186 (t (setq case-fold-search fold) ;; restore the old value
187 nil)))
143 (mapcar (function kill-buffer) bufs))))) 188 (mapcar (function kill-buffer) bufs)))))
144 189
145(defun vc-name (file) 190(defun vc-name (file)
@@ -161,12 +206,17 @@ Otherwise, not displayed.")
161 (vc-file-setprop file 'vc-name (car name-and-type)) 206 (vc-file-setprop file 'vc-name (car name-and-type))
162 (vc-file-setprop file 'vc-backend (cdr name-and-type)))))))) 207 (vc-file-setprop file 'vc-backend (cdr name-and-type))))))))
163 208
209(defun vc-buffer-backend ()
210 "Return the version-control type of the visited file, or nil if none."
211 (if (eq vc-buffer-backend t)
212 (setq vc-buffer-backend (vc-backend-deduce (buffer-file-name)))
213 vc-buffer-backend))
214
164(defun vc-toggle-read-only (&optional verbose) 215(defun vc-toggle-read-only (&optional verbose)
165 "Change read-only status of current buffer, perhaps via version control. 216 "Change read-only status of current buffer, perhaps via version control.
166If the buffer is visiting a file registered with version control, 217If the buffer is visiting a file registered with version control,
167then check the file in or out. Otherwise, just change the read-only flag 218then check the file in or out. Otherwise, just change the read-only flag
168of the buffer. 219of the buffer. With prefix argument, ask for version number."
169If you provide a prefix argument, we pass it on to `vc-next-action'."
170 (interactive "P") 220 (interactive "P")
171 (if (vc-backend-deduce (buffer-file-name)) 221 (if (vc-backend-deduce (buffer-file-name))
172 (vc-next-action verbose) 222 (vc-next-action verbose)
@@ -179,31 +229,32 @@ The value is set in the current buffer, which should be the buffer
179visiting FILE. Second optional arg LABEL is put in place of version 229visiting FILE. Second optional arg LABEL is put in place of version
180control system name." 230control system name."
181 (interactive (list buffer-file-name nil)) 231 (interactive (list buffer-file-name nil))
182 (if file 232 (let ((vc-type (vc-backend-deduce file)))
183 (let ((vc-type (vc-backend-deduce file))) 233 (setq vc-mode
184 (setq vc-mode 234 (concat " " (or label (symbol-name vc-type))
185 (if vc-type 235 (if vc-display-status (vc-status file vc-type))))
186 (concat " " (or label (symbol-name vc-type)) 236;;; ;; Make the buffer read-only if the file is not locked
187 (if vc-display-status 237;;; ;; (or unchanged, in the CVS case).
188 (vc-status file vc-type))))) 238;;; (if (not (vc-locking-user file))
189 ;; Even root shouldn't modify a registered file without 239;;; (setq buffer-read-only t))
190 ;; locking it first. 240 ;; Even root shouldn't modify a registered file without
191 (and vc-type 241 ;; locking it first.
192 (not buffer-read-only) 242 (and vc-type
193 (zerop (user-uid)) 243 (not buffer-read-only)
194 (require 'vc) 244 (zerop (user-uid))
195 (not (equal (user-login-name) (vc-locking-user file))) 245 (require 'vc)
196 (setq buffer-read-only t)) 246 (not (equal (user-login-name) (vc-locking-user file)))
197 (and (null vc-type) 247 (setq buffer-read-only t))
198 (file-symlink-p file) 248 (and (null vc-type)
199 (let ((link-type (vc-backend-deduce (file-symlink-p file)))) 249 (file-symlink-p file)
200 (if link-type 250 (let ((link-type (vc-backend-deduce (file-symlink-p file))))
201 (message 251 (if link-type
202 "Warning: symbolic link to %s-controlled source file" 252 (message
203 link-type)))) 253 "Warning: symbolic link to %s-controlled source file"
204 (force-mode-line-update) 254 link-type))))
205 ;;(set-buffer-modified-p (buffer-modified-p)) ;;use this if Emacs 18 255 (force-mode-line-update)
206 vc-type))) 256 ;;(set-buffer-modified-p (buffer-modified-p)) ;;use this if Emacs 18
257 vc-type))
207 258
208(defun vc-status (file vc-type) 259(defun vc-status (file vc-type)
209 ;; Return string for placement in modeline by `vc-mode-line'. 260 ;; Return string for placement in modeline by `vc-mode-line'.
@@ -326,18 +377,25 @@ control system name."
326 (set-buffer-modified-p nil) 377 (set-buffer-modified-p nil)
327 status)))) 378 status))))
328 379
380(defun vc-file-clearprops (file)
381 ;; clear all properties of a given file
382 (setplist (intern file vc-file-prop-obarray) nil))
383
329;;; install a call to the above as a find-file hook 384;;; install a call to the above as a find-file hook
330(defun vc-find-file-hook () 385(defun vc-find-file-hook ()
331 ;; Recompute whether file is version controlled, 386 ;; Recompute whether file is version controlled,
332 ;; if user has killed the buffer and revisited. 387 ;; if user has killed the buffer and revisited.
333 (if buffer-file-name 388 (cond
334 (vc-file-setprop buffer-file-name 'vc-backend nil)) 389 (buffer-file-name
335 (if (and (vc-mode-line buffer-file-name) (not vc-make-backup-files)) 390 (vc-file-clearprops buffer-file-name)
336 (progn 391 (cond
337 ;; Use this variable, not make-backup-files, 392 ((vc-backend-deduce buffer-file-name)
338 ;; because this is for things that depend on the file name. 393 (vc-mode-line buffer-file-name)
339 (make-local-variable 'backup-inhibited) 394 (cond ((not vc-make-backup-files)
340 (setq backup-inhibited t)))) 395 ;; Use this variable, not make-backup-files,
396 ;; because this is for things that depend on the file name.
397 (make-local-variable 'backup-inhibited)
398 (setq backup-inhibited t))))))))
341 399
342(add-hook 'find-file-hooks 'vc-find-file-hook) 400(add-hook 'find-file-hooks 'vc-find-file-hook)
343 401
@@ -352,6 +410,15 @@ Returns t if checkout was successful, nil otherwise."
352 410
353(add-hook 'find-file-not-found-hooks 'vc-file-not-found-hook) 411(add-hook 'find-file-not-found-hooks 'vc-file-not-found-hook)
354 412
413;; Discard info about a file when we kill its buffer.
414(defun vc-kill-buffer-hook ()
415 (if (stringp (buffer-file-name))
416 (progn
417 (vc-file-clearprops (buffer-file-name))
418 (kill-local-variable 'vc-buffer-backend))))
419
420;;;(add-hook 'kill-buffer-hook 'vc-kill-buffer-hook)
421
355;;; Now arrange for bindings and autoloading of the main package. 422;;; Now arrange for bindings and autoloading of the main package.
356;;; Bindings for this have to go in the global map, as we'll often 423;;; Bindings for this have to go in the global map, as we'll often
357;;; want to call them from random buffers. 424;;; want to call them from random buffers.
@@ -402,7 +469,7 @@ Returns t if checkout was successful, nil otherwise."
402 (put 'vc-version-other-window 'menu-enable 'vc-mode) 469 (put 'vc-version-other-window 'menu-enable 'vc-mode)
403 (put 'vc-diff 'menu-enable 'vc-mode) 470 (put 'vc-diff 'menu-enable 'vc-mode)
404 (put 'vc-update-change-log 'menu-enable 471 (put 'vc-update-change-log 'menu-enable
405 '(eq (vc-backend-deduce (buffer-file-name)) 'RCS)) 472 '(eq (vc-buffer-backend) 'RCS))
406 (put 'vc-print-log 'menu-enable 'vc-mode) 473 (put 'vc-print-log 'menu-enable 'vc-mode)
407 (put 'vc-cancel-version 'menu-enable 'vc-mode) 474 (put 'vc-cancel-version 'menu-enable 'vc-mode)
408 (put 'vc-revert-buffer 'menu-enable 'vc-mode) 475 (put 'vc-revert-buffer 'menu-enable 'vc-mode)