Ben said he'd be happy just to have revision numbers in his modeline.
This is enough to do that, with ':' for locally modified files vs.
'-' for unmodified files, but not much else. :)
If anyone is interested, maybe this could find a place in the
Subversion tree!
;;;; vc-svn.el --- a VC backend for Subversion
;;;; Jim Blandy <jimb@red-bean.com> --- July 2002
;;; To do:
;;; Provide more of the optional VC backend functions:
;;; - vc-svn-dir-state
;;;
;;; Some are unnecessary; for example,
;;; `vc-BACKEND-workfile-unchanged-p' defaults to calling the full
;;; `vc-BACKEND-diff' function, which is actually fine for Subversion,
;;; since it has a copy of the base revision cached locally.
;;;
;;; VC passes the vc-svn-register function a COMMENT argument, which
;;; is like the file description in CVS and RCS. Could we store the
;;; COMMENT as a Subversion property? Would that show up in fancy DAV
;;; web folder displays, or would it just languish in obscurity, the
;;; way CVS and RCS descriptions do?
(add-value 'vc-handled-backends 'SVN)
(defvar vc-svn-program-name "svn"
"*Name of Subversion client program, for use by Emacs's VC package.")
(defun vc-svn-registered (file)
"Return true if FILE is registered under Subversion."
;; First, a quick false positive test: is there a `.svn/entries' file?
(and (file-exists-p (expand-file-name ".svn/entries"
(file-name-directory file)))
(not (null (vc-svn-run-status file)))))
(put 'vc-svn-with-output-buffer 'lisp-indent-function 0)
(defmacro vc-svn-with-output-buffer (&rest body)
"Save excursion, switch to buffer ` *Subversion Output*', and erase it."
`(save-excursion
;; Let's not delete this buffer when we're done --- leave
;; it around for debugging.
(set-buffer (get-buffer-create " *Subversion Output*"))
(erase-buffer)
,@body))
(defun vc-svn-run-status (file &optional update)
"Run `svn status -v' on FILE, and return the result.
If optional arg UPDATE is true, pass the `-u' flag to check against
the repository, across the network.
See `vc-svn-parse-status' for a description of the result."
(vc-svn-with-output-buffer
(let ((status (apply 'call-process vc-svn-program-name nil t nil
(append '("status" "-v")
(if update '("-u") '())
(list file)))))
(goto-char (point-min))
(if (not (zerop status))
;; If you ask for the status of a file that isn't even in a
;; Subversion-controlled directory, then Subversion exits with
;; this error.
(if (or (looking-at "\\(.*\n\\)*.*is not a working copy directory")
(looking-at "\\(.*\n\\)*.*is not a versioned resource"))
nil
;; Other errors we should actually report to the user.
(display-buffer (current-buffer))
(error "Error running Subversion to check status of `%s'"
(file-name-nondirectory file)))
;; Otherwise, we've got valid status output in the buffer, so
;; just parse that.
(vc-svn-parse-status)))))
(defun vc-svn-parse-status ()
"Parse the output from `svn status -v' at point.
We return nil for a file not under Subversion's control,
or (STATE LOCAL CHANGED) for files that are, where:
STATE is the file's VC state (see the documentation for `vc-state'),
LOCAL is the base revision in the working copy, and
CHANGED is the last revision in which it was changed. If we passed
`svn status' the `-u' flag, then CHANGED might be greater than LOCAL."
(let ((state (vc-svn-parse-state-only)))
(and state
(if (looking-at
"\\S-+\\s-+\\(\\*\\s-+\\)?\\([0-9]+\\)\\s-+\\([0-9]+\\)")
(list state
(string-to-number (match-string 2))
(string-to-number (match-string 3)))
(error "Couldn't parse output from `svn status -v'")))))
(defun vc-svn-parse-state-only ()
"Parse the output from `svn status -v' at point, and return a state.
The documentation for the function `vc-state' describes the possible values."
(cond
;; Be careful --- some of the later clauses here could yield false
;; positives, if the clauses preceding them didn't screen those
;; out. Making a pattern more selective could break something.
;; nil The given file is not under version control.
((looking-at "\\?") nil)
;; 'needs-patch The file has not been edited by the
;; user, but there is a more recent version
;; on the current branch stored in the
;; master file.
((looking-at "_[_ ]..\\s-+\\*") 'needs-patch)
;; 'up-to-date The working file is unmodified with
;; respect to the latest version on the
;; current branch, and not locked.
((looking-at "_[_ ]") 'up-to-date)
;; 'needs-merge The file has been edited by the user,
;; and there is also a more recent version
;; on the current branch stored in the
;; master file. This state can only occur
;; if locking is not used for the file.
((looking-at "\\S-+\\s-+\\*") 'needs-merge)
;; 'edited The working file has been edited by the
;; user. If locking is used for the file,
;; this state means that the current
;; version is locked by the calling user.
(t 'edited)))
(defun vc-svn-state (file)
"Return the current version control state of FILE.
For a list of possible return values, see `vc-state'.
This function should do a full and reliable state computation; it is
usually called immediately after `C-x v v'. `vc-svn-state-heuristic'
provides a faster heuristic when visiting a file."
(car (vc-svn-run-status file 'update)))
(defun vc-svn-state-heuristic (file)
"Estimate the version control state of FILE at visiting time.
For a list of possible values, see the doc string of `vc-state'.
This is supposed to be considerably faster than `vc-svn-state'. It
just runs `svn status -v', without the `-u' flag, so it's a strictly
local operation."
(car (vc-svn-run-status file)))
(defun vc-svn-workfile-version (file)
"Return the current workfile version of FILE."
(number-to-string (cadr (vc-svn-run-status file))))
(defun vc-svn-checkout-model (file)
'implicit)
(provide 'vc-svn)
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Fri Jul 12 03:00:35 2002