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