aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1998-04-04 05:22:37 +0000
committerRichard M. Stallman1998-04-04 05:22:37 +0000
commit3d30b8bc56cfe56c36f4e813c1396e04fc6f88a4 (patch)
treeb313207df41d0058acd0400a273796dce9ea804c
parent8aa81ea8c418df3f6f57f57aa5fe8c45399394c6 (diff)
downloademacs-3d30b8bc56cfe56c36f4e813c1396e04fc6f88a4.tar.gz
emacs-3d30b8bc56cfe56c36f4e813c1396e04fc6f88a4.zip
(vc-next-action-dired): Use dired-do-redisplay. Handle
window configuration correctly. (vc-next-action): Save window configuration for vc-next-action-dired. (vc-finish-logentry): Only kill log buffer if it does exist. (vc-dired-mode): Rewritten so that it works entirely through dired-after-readin-hook. Subdirectories are handled just as in ordinary dired. (vc-dired-hook): New function. (vc-state-info, vc-dired-reformat-line): Adapted. (vc-dired-update, vc-dired-update-line): Removed. (vc-directory): Rewritten. (vc-directory-18): Removed. (vc-dired-mark-locked): New function, bound to "*l" in vc-dired-mode. (vc-do-command): Only compute vc-name if it is really needed. (vc-fetch-cvs-status): New function. (vc-dired-hook): Use it.
-rw-r--r--lisp/vc.el287
1 files changed, 124 insertions, 163 deletions
diff --git a/lisp/vc.el b/lisp/vc.el
index 2257363ae5a..b14791931a2 100644
--- a/lisp/vc.el
+++ b/lisp/vc.el
@@ -1,11 +1,11 @@
1;;; vc.el --- drive a version-control system from within Emacs 1;;; vc.el --- drive a version-control system from within Emacs
2 2
3;; Copyright (C) 1992, 93, 94, 95, 96, 97 Free Software Foundation, Inc. 3;; Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 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: Andre Spiegel <spiegel@inf.fu-berlin.de> 6;; Maintainer: Andre Spiegel <spiegel@inf.fu-berlin.de>
7 7
8;; $Id: vc.el,v 1.214 1998/03/31 18:08:36 spiegel Exp spiegel $ 8;; $Id: vc.el,v 1.215 1998/04/01 12:26:43 spiegel Exp rms $
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11 11
@@ -32,7 +32,7 @@
32;; Paul Eggert <eggert@twinsun.com>, Sebastian Kremer <sk@thp.uni-koeln.de>, 32;; Paul Eggert <eggert@twinsun.com>, Sebastian Kremer <sk@thp.uni-koeln.de>,
33;; and Richard Stallman contributed valuable criticism, support, and testing. 33;; and Richard Stallman contributed valuable criticism, support, and testing.
34;; CVS support was added by Per Cederqvist <ceder@lysator.liu.se> 34;; CVS support was added by Per Cederqvist <ceder@lysator.liu.se>
35;; in Jan-Feb 1994. Further enhancements came from ttn.netcom.com and 35;; in Jan-Feb 1994. Further enhancements came from ttn@netcom.com and
36;; Andre Spiegel <spiegel@inf.fu-berlin.de>. 36;; Andre Spiegel <spiegel@inf.fu-berlin.de>.
37;; 37;;
38;; Supported version-control systems presently include SCCS, RCS, and CVS. 38;; Supported version-control systems presently include SCCS, RCS, and CVS.
@@ -540,9 +540,8 @@ before the filename."
540 (message "Running %s on %s..." command file)) 540 (message "Running %s on %s..." command file))
541 (let ((obuf (current-buffer)) (camefrom (current-buffer)) 541 (let ((obuf (current-buffer)) (camefrom (current-buffer))
542 (squeezed nil) 542 (squeezed nil)
543 (vc-file (and file (vc-name file)))
544 (olddir default-directory) 543 (olddir default-directory)
545 status) 544 vc-file status)
546 (set-buffer (get-buffer-create buffer)) 545 (set-buffer (get-buffer-create buffer))
547 (set (make-local-variable 'vc-parent-buffer) camefrom) 546 (set (make-local-variable 'vc-parent-buffer) camefrom)
548 (set (make-local-variable 'vc-parent-buffer-name) 547 (set (make-local-variable 'vc-parent-buffer-name)
@@ -554,7 +553,7 @@ before the filename."
554 (mapcar 553 (mapcar
555 (function (lambda (s) (and s (setq squeezed (append squeezed (list s)))))) 554 (function (lambda (s) (and s (setq squeezed (append squeezed (list s))))))
556 flags) 555 flags)
557 (if (and vc-file (eq last 'MASTER)) 556 (if (and (eq last 'MASTER) file (setq vc-file (vc-name file)))
558 (setq squeezed (append squeezed (list vc-file)))) 557 (setq squeezed (append squeezed (list vc-file))))
559 (if (and file (eq last 'WORKFILE)) 558 (if (and file (eq last 'WORKFILE))
560 (progn 559 (progn
@@ -893,8 +892,7 @@ before the filename."
893(defun vc-next-action-dired (file rev comment) 892(defun vc-next-action-dired (file rev comment)
894 ;; Do a vc-next-action-on-file on all the marked files, possibly 893 ;; Do a vc-next-action-on-file on all the marked files, possibly
895 ;; passing on the log comment we've just entered. 894 ;; passing on the log comment we've just entered.
896 (let ((configuration (current-window-configuration)) 895 (let ((dired-buffer (current-buffer))
897 (dired-buffer (current-buffer))
898 (dired-dir default-directory)) 896 (dired-dir default-directory))
899 (dired-map-over-marks 897 (dired-map-over-marks
900 (let ((file (dired-get-filename)) p 898 (let ((file (dired-get-filename)) p
@@ -906,10 +904,11 @@ before the filename."
906 (vc-next-action-on-file file nil comment) 904 (vc-next-action-on-file file nil comment)
907 (set-buffer dired-buffer) 905 (set-buffer dired-buffer)
908 (setq default-directory dired-dir) 906 (setq default-directory dired-dir)
909 (vc-dired-update-line file) 907 (dired-do-redisplay file)
910 (set-window-configuration configuration) 908 (set-window-configuration vc-dired-window-configuration)
911 (message "Processing %s...done" file)) 909 (message "Processing %s...done" file))
912 nil t))) 910 nil t))
911 (dired-move-to-filename))
913 912
914;; Here's the major entry point. 913;; Here's the major entry point.
915 914
@@ -956,6 +955,8 @@ merge in the changes into your working copy."
956 (catch 'nogo 955 (catch 'nogo
957 (if vc-dired-mode 956 (if vc-dired-mode
958 (let ((files (dired-get-marked-files))) 957 (let ((files (dired-get-marked-files)))
958 (set (make-local-variable 'vc-dired-window-configuration)
959 (current-window-configuration))
959 (if (string= "" 960 (if (string= ""
960 (mapconcat 961 (mapconcat
961 (function (lambda (f) 962 (function (lambda (f)
@@ -1231,11 +1232,14 @@ May be useful as a `vc-checkin-hook' to update change logs automatically."
1231 ;; Remove checkin window (after the checkin so that if that fails 1232 ;; Remove checkin window (after the checkin so that if that fails
1232 ;; we don't zap the *VC-log* buffer and the typing therein). 1233 ;; we don't zap the *VC-log* buffer and the typing therein).
1233 (let ((logbuf (get-buffer "*VC-log*"))) 1234 (let ((logbuf (get-buffer "*VC-log*")))
1234 (delete-windows-on logbuf) 1235 (cond (logbuf
1235 (kill-buffer logbuf)) 1236 (delete-windows-on logbuf)
1237 (kill-buffer logbuf))))
1236 ;; Now make sure we see the expanded headers 1238 ;; Now make sure we see the expanded headers
1237 (if buffer-file-name 1239 (if buffer-file-name
1238 (vc-resynch-window buffer-file-name vc-keep-workfiles t)) 1240 (vc-resynch-window buffer-file-name vc-keep-workfiles t))
1241 (if vc-dired-mode
1242 (dired-move-to-filename))
1239 (run-hooks after-hook 'vc-finish-logentry-hook))) 1243 (run-hooks after-hook 'vc-finish-logentry-hook)))
1240 1244
1241;; Code for access to the comment ring 1245;; Code for access to the comment ring
@@ -1568,42 +1572,69 @@ The conflicts must be marked with rcsmerge conflict markers."
1568;; All VC commands get mapped into logical equivalents. 1572;; All VC commands get mapped into logical equivalents.
1569 1573
1570(define-derived-mode vc-dired-mode dired-mode "Dired under VC" 1574(define-derived-mode vc-dired-mode dired-mode "Dired under VC"
1571 "The major mode used in VC directory buffers. It is derived from Dired. 1575 "The major mode used in VC directory buffers. It works like Dired,
1572All Dired commands operate normally. Users currently locking listed files 1576but lists only files under version control, with the current VC state of
1573are listed in place of the file's owner and group. 1577each file being indicated in the place of the file's link count, owner,
1574Keystrokes bound to VC commands will execute as though they had been called 1578group and size. Subdirectories are also listed, and you may insert them
1575on a buffer attached to the file named in the current Dired buffer line." 1579into the buffer as desired, like in Dired.
1580 All Dired commands operate normally, with the exception of `v', which
1581is redefined as the version control prefix, so that you can type
1582`vl', `v=' etc. to invoke `vc-print-log', `vc-diff', and the like on
1583the file named in the current Dired buffer line. `vv' invokes
1584`vc-next-action' on this file, or on all files currently marked.
1585There is a special command, `*l', to mark all files currently locked."
1586 (make-local-variable 'dired-after-readin-hook)
1587 (add-hook 'dired-after-readin-hook 'vc-dired-hook)
1576 (setq vc-dired-mode t)) 1588 (setq vc-dired-mode t))
1577 1589
1578(define-key vc-dired-mode-map "\C-xv" vc-prefix-map) 1590(define-key vc-dired-mode-map "\C-xv" vc-prefix-map)
1579(define-key vc-dired-mode-map "g" 'vc-dired-update) 1591(define-key vc-dired-mode-map "v" vc-prefix-map)
1580(define-key vc-dired-mode-map "=" 'vc-diff) 1592(define-key vc-dired-mode-map "=" 'vc-diff)
1581 1593
1594(defun vc-dired-mark-locked ()
1595 "Mark all files currently locked."
1596 (interactive)
1597 (dired-mark-if (let ((f (dired-get-filename nil t)))
1598 (and f
1599 (not (file-directory-p f))
1600 (vc-locking-user f)))
1601 "locked file"))
1602
1603(define-key vc-dired-mode-map "*l" 'vc-dired-mark-locked)
1604
1605(defun vc-fetch-cvs-status (dir)
1606 (let ((default-directory dir))
1607 (vc-do-command "*vc-info*" 0 "cvs" nil nil "status" dir)
1608 (save-excursion
1609 (set-buffer (get-buffer "*vc-info*"))
1610 (goto-char (point-min))
1611 (while (re-search-forward "^=+\n\\([^=\n].*\n\\|\n\\)+" nil t)
1612 (narrow-to-region (match-beginning 0) (match-end 0))
1613 (vc-parse-cvs-status)
1614 (goto-char (point-max))
1615 (widen)))))
1616
1582(defun vc-dired-state-info (file) 1617(defun vc-dired-state-info (file)
1583 ;; Return the string that indicates the version control status 1618 ;; Return the string that indicates the version control status
1584 ;; on a VC dired line. 1619 ;; on a VC dired line.
1585 (let ((cvs-state (and (eq (vc-backend file) 'CVS) 1620 (let* ((cvs-state (and (eq (vc-backend file) 'CVS)
1586 (vc-cvs-status file)))) 1621 (vc-cvs-status file)))
1587 (if cvs-state 1622 (state
1588 (cond ((eq cvs-state 'up-to-date) nil) 1623 (if cvs-state
1589 ((eq cvs-state 'needs-checkout) "patch") 1624 (cond ((eq cvs-state 'up-to-date) nil)
1590 ((eq cvs-state 'locally-modified) "modified") 1625 ((eq cvs-state 'needs-checkout) "patch")
1591 ((eq cvs-state 'needs-merge) "merge") 1626 ((eq cvs-state 'locally-modified) "modified")
1592 ((eq cvs-state 'unresolved-conflict) "conflict") 1627 ((eq cvs-state 'needs-merge) "merge")
1593 ((eq cvs-state 'locally-added) "added")) 1628 ((eq cvs-state 'unresolved-conflict) "conflict")
1594 (vc-locking-user file)))) 1629 ((eq cvs-state 'locally-added) "added"))
1630 (vc-locking-user file))))
1631 (if state (concat "(" state ")"))))
1595 1632
1596(defun vc-dired-reformat-line (x) 1633(defun vc-dired-reformat-line (x)
1597 ;; Hack a directory-listing line, plugging in locking-user info in 1634 ;; Reformat a directory-listing line, plugging in version control info in
1598 ;; place of the user and group info. Should have the beneficial 1635 ;; place of the user and group info.
1599 ;; side-effect of shortening the listing line. Each call starts with
1600 ;; point immediately following the dired mark area on the line to be
1601 ;; hacked.
1602 ;;
1603 ;; Simplest possible one:
1604 ;; (insert (concat x "\t")))
1605 ;;
1606 ;; This code, like dired, assumes UNIX -l format. 1636 ;; This code, like dired, assumes UNIX -l format.
1637 (beginning-of-line)
1607 (let ((pos (point)) limit perm owner date-and-file) 1638 (let ((pos (point)) limit perm owner date-and-file)
1608 (end-of-line) 1639 (end-of-line)
1609 (setq limit (point)) 1640 (setq limit (point))
@@ -1611,144 +1642,74 @@ on a buffer attached to the file named in the current Dired buffer line."
1611 (cond 1642 (cond
1612 ((or 1643 ((or
1613 (re-search-forward ;; owner and group 1644 (re-search-forward ;; owner and group
1614"\\([drwxlts-]+ \\) *[0-9]+ \\([^ ]+\\) +[^ ]+ +[0-9]+\\( [^ 0-9]+ [0-9 ][0-9] .*\\)" 1645"^\\(..[drwxlts-]+ \\) *[0-9]+ \\([^ ]+\\) +[^ ]+ +[0-9]+\\( [^ 0-9]+ [0-9 ][0-9] .*\\)"
1615 limit t) 1646 limit t)
1616 (re-search-forward ;; only owner displayed 1647 (re-search-forward ;; only owner displayed
1617"\\([drwxlts-]+ \\) *[0-9]+ \\([^ ]+\\) +[0-9]+\\( [^ 0-9]+ [0-9 ][0-9] .*\\)" 1648"^\\(..[drwxlts-]+ \\) *[0-9]+ \\([^ ]+\\) +[0-9]+\\( [^ 0-9]+ [0-9 ][0-9] .*\\)"
1618 limit t)) 1649 limit t))
1619 (setq perm (match-string 1) 1650 (setq perm (match-string 1)
1620 owner (match-string 2) 1651 owner (match-string 2)
1621 date-and-file (match-string 3))) 1652 date-and-file (match-string 3)))
1622 ((re-search-forward ;; OS/2 -l format, no links, owner, group 1653 ((re-search-forward ;; OS/2 -l format, no links, owner, group
1623"\\([drwxlts-]+ \\) *[0-9]+\\( [^ 0-9]+ [0-9 ][0-9] .*\\)" 1654"^\\(..[drwxlts-]+ \\) *[0-9]+\\( [^ 0-9]+ [0-9 ][0-9] .*\\)"
1624 limit t) 1655 limit t)
1625 (setq perm (match-string 1) 1656 (setq perm (match-string 1)
1626 date-and-file (match-string 2)))) 1657 date-and-file (match-string 2))))
1627 (if x (setq x (concat "(" x ")"))) 1658 (setq x (substring (concat x " ") 0 10))
1628 (let ((rep (substring (concat x " ") 0 10))) 1659 (replace-match (concat perm x date-and-file))))
1629 (replace-match (concat perm rep date-and-file))))) 1660
1630 1661(defun vc-dired-hook ()
1631(defun vc-dired-update-line (file) 1662 ;; Called by dired after any portion of a vc-dired buffer has been read in.
1632 ;; Update the vc-dired listing line of file -- it is assumed 1663 ;; Reformat the listing according to version control.
1633 ;; that point is already on this line. Don't use dired-do-redisplay 1664 (message "Getting version information... ")
1634 ;; for this, because it cannot handle the way vc-dired deals with 1665 (let (subdir filename (buffer-read-only nil))
1635 ;; subdirectories. 1666 (goto-char (point-min))
1636 (beginning-of-line) 1667 (while (not (eq (point) (point-max)))
1637 (forward-char 2) 1668 (cond
1638 (let ((start (point))) 1669 ;; subdir header line
1639 (forward-line 1) 1670 ((setq subdir (dired-get-subdir))
1640 (beginning-of-line) 1671 (if (file-directory-p (concat subdir "/CVS"))
1641 (delete-region start (point)) 1672 (vc-fetch-cvs-status (file-name-as-directory subdir)))
1642 (insert-directory file dired-listing-switches) 1673 (forward-line 1)
1643 (forward-line -1) 1674 ;; erase (but don't remove) the "total" line
1644 (end-of-line) 1675 (let ((start (point)))
1645 (delete-char (- (length file))) 1676 (end-of-line)
1646 (insert (substring file (length (expand-file-name default-directory)))) 1677 (delete-region start (point))
1647 (goto-char start)) 1678 (beginning-of-line)
1648 (vc-dired-reformat-line (vc-dired-state-info file))) 1679 (forward-line 1)))
1649 1680 ;; an ordinary file line
1650(defun vc-dired-update (verbose) 1681 ((setq filename (dired-get-filename nil t))
1651 (interactive "P") 1682 (cond
1652 (vc-directory default-directory verbose)) 1683 ((file-directory-p filename)
1684 (if (member (file-name-nondirectory filename)
1685 vc-directory-exclusion-list)
1686 (dired-kill-line)
1687 (vc-dired-reformat-line nil)
1688 (forward-line 1)))
1689 ((vc-backend filename)
1690 (vc-dired-reformat-line (vc-dired-state-info filename))
1691 (forward-line 1))
1692 (t
1693 (dired-kill-line))))
1694 ;; any other line
1695 (t (forward-line 1)))))
1696 (message "Getting version information... done"))
1653 1697
1654;;; Note in Emacs 18 the following defun gets overridden
1655;;; with the symbol 'vc-directory-18. See below.
1656;;;###autoload 1698;;;###autoload
1657(defun vc-directory (dirname verbose) 1699(defun vc-directory (dirname read-switches)
1658 "Show version-control status of the current directory and subdirectories.
1659Normally it creates a Dired buffer that lists only the locked files
1660in all these directories. With a prefix argument, it lists all files."
1661 (interactive "DDired under VC (directory): \nP") 1700 (interactive "DDired under VC (directory): \nP")
1662 (require 'dired) 1701 (let ((switches
1663 (setq dirname (expand-file-name dirname)) 1702 (if read-switches (read-string "Dired listing switches: "
1664 ;; force a trailing slash 1703 dired-listing-switches))))
1665 (if (not (eq (elt dirname (1- (length dirname))) ?/)) 1704 (require 'dired)
1666 (setq dirname (concat dirname "/"))) 1705 (require 'dired-aux)
1667 (let (nonempty 1706 ;; force a trailing slash
1668 (dl (length dirname)) 1707 (if (not (eq (elt dirname (1- (length dirname))) ?/))
1669 (filelist nil) (statelist nil) 1708 (setq dirname (concat dirname "/")))
1670 (old-dir default-directory) 1709 (switch-to-buffer
1671 dired-buf 1710 (dired-internal-noselect (expand-file-name dirname)
1672 dired-buf-mod-count) 1711 (or switches dired-listing-switches)
1673 (vc-file-tree-walk 1712 'vc-dired-mode))))
1674 dirname
1675 (function
1676 (lambda (f)
1677 (if (vc-registered f)
1678 (let ((state (vc-dired-state-info f)))
1679 (and (or verbose state)
1680 (setq filelist (cons (substring f dl) filelist))
1681 (setq statelist (cons state statelist))))))))
1682 (save-window-excursion
1683 (save-excursion
1684 ;; This uses a semi-documented feature of dired; giving a switch
1685 ;; argument forces the buffer to refresh each time.
1686 (setq dired-buf
1687 (dired-internal-noselect
1688 (cons dirname (nreverse filelist))
1689 dired-listing-switches 'vc-dired-mode))
1690 (setq nonempty (not (eq 0 (length filelist))))))
1691 (switch-to-buffer dired-buf)
1692 ;; Make a few modifications to the header
1693 (setq buffer-read-only nil)
1694 (goto-char (point-min))
1695 (forward-line 1) ;; Skip header line
1696 (let ((start (point))) ;; Erase (but don't remove) the
1697 (end-of-line) ;; "wildcard" line.
1698 (delete-region start (point)))
1699 (beginning-of-line)
1700 (if nonempty
1701 (progn
1702 ;; Plug the version information into the individual lines
1703 (mapcar
1704 (function
1705 (lambda (x)
1706 (forward-char 2) ;; skip dired's mark area
1707 (vc-dired-reformat-line x)
1708 (forward-line 1))) ;; go to next line
1709 (nreverse statelist))
1710 (setq buffer-read-only t)
1711 (goto-char (point-min))
1712 (dired-next-line 2)
1713 )
1714 (dired-next-line 1)
1715 (insert " ")
1716 (setq buffer-read-only t)
1717 (message "No files are currently %s under %s"
1718 (if verbose "registered" "locked") dirname))
1719 ))
1720
1721;; Emacs 18 version
1722(defun vc-directory-18 (verbose)
1723 "Show version-control status of all files under the current directory."
1724 (interactive "P")
1725 (let (nonempty (dir default-directory))
1726 (save-excursion
1727 (set-buffer (get-buffer-create "*vc-status*"))
1728 (erase-buffer)
1729 (cd dir)
1730 (vc-file-tree-walk
1731 default-directory
1732 (function (lambda (f)
1733 (if (vc-registered f)
1734 (let ((user (vc-locking-user f)))
1735 (if (or user verbose)
1736 (insert (format
1737 "%s %s\n"
1738 (concat user) f))))))))
1739 (setq nonempty (not (zerop (buffer-size)))))
1740
1741 (if nonempty
1742 (progn
1743 (pop-to-buffer "*vc-status*" t)
1744 (goto-char (point-min))
1745 (shrink-window-if-larger-than-buffer)))
1746 (message "No files are currently %s under %s"
1747 (if verbose "registered" "locked") default-directory))
1748 )
1749
1750(or (boundp 'minor-mode-map-alist)
1751 (fset 'vc-directory 'vc-directory-18))
1752 1713
1753;; Named-configuration support for SCCS 1714;; Named-configuration support for SCCS
1754 1715