aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndré Spiegel2003-04-23 12:49:25 +0000
committerAndré Spiegel2003-04-23 12:49:25 +0000
commitd3ed06c6d1ab6817c28a607d0c819086fdb6bd54 (patch)
tree607020fc8011d107e91365a604e143976062accf
parent15a45706450959fa14ea259c059414a19c9bafbc (diff)
downloademacs-d3ed06c6d1ab6817c28a607d0c819086fdb6bd54.tar.gz
emacs-d3ed06c6d1ab6817c28a607d0c819086fdb6bd54.zip
Patch by Wolfgang Scherer <Wolfgang.Scherer@gmx.de>
(vc-cvs-stay-local): Allow lists of host regexps. (vc-cvs-stay-local-p): Handle them. (vc-cvs-parse-root): New function, used by the above.
-rw-r--r--lisp/vc-cvs.el129
1 files changed, 110 insertions, 19 deletions
diff --git a/lisp/vc-cvs.el b/lisp/vc-cvs.el
index 4fcba6a07e1..ab69de81d77 100644
--- a/lisp/vc-cvs.el
+++ b/lisp/vc-cvs.el
@@ -5,7 +5,7 @@
5;; Author: FSF (see vc.el for full credits) 5;; Author: FSF (see vc.el for full credits)
6;; Maintainer: Andre Spiegel <spiegel@gnu.org> 6;; Maintainer: Andre Spiegel <spiegel@gnu.org>
7 7
8;; $Id: vc-cvs.el,v 1.53 2003/04/05 15:51:14 spiegel Exp $ 8;; $Id: vc-cvs.el,v 1.54 2003/04/19 22:40:18 monnier Exp $
9 9
10;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
11 11
@@ -81,15 +81,24 @@ This is only meaningful if you don't use the implicit checkout model
81 :version "21.1" 81 :version "21.1"
82 :group 'vc) 82 :group 'vc)
83 83
84(defcustom vc-cvs-stay-local t 84(defcustom vc-cvs-stay-local '(except "^\\(localhost\\)$")
85 "*Non-nil means use local operations when possible for remote repositories. 85 "*Non-nil means use local operations when possible for remote repositories.
86This avoids slow queries over the network and instead uses heuristics 86This avoids slow queries over the network and instead uses heuristics
87and past information to determine the current status of a file. 87and past information to determine the current status of a file.
88The value can also be a regular expression to match against the host name 88The value can also be a regular expression or list of regular
89of a repository; then VC only stays local for hosts that match it." 89expressions to match against the host name of a repository; then VC
90only stays local for hosts that match it.
91This is useful in a setup, where most CVS servers should be contacted
92directly, and only a few CVS servers cannot be reached easily.
93For the opposite scenario, when only a few CVS servers are to be
94queried directly, a list of regular expressions can be specified,
95whose first element is the symbol `except'."
90 :type '(choice (const :tag "Always stay local" t) 96 :type '(choice (const :tag "Always stay local" t)
91 (string :tag "Host regexp") 97 (const :tag "Don't stay local" nil)
92 (const :tag "Don't stay local" nil)) 98 (list :format "\nExamine hostname and %v" :tag "Examine hostname ..."
99 (set :format "%v" :inline t (const :format "%t" :tag "don't" except))
100 (regexp :format " stay local,\n%t: %v" :tag "if it matches")
101 (repeat :format "%v%i\n" :inline t (regexp :tag "or"))))
93 :version "21.1" 102 :version "21.1"
94 :group 'vc) 103 :group 'vc)
95 104
@@ -715,7 +724,8 @@ and that it passes `vc-cvs-global-switches' to it before FLAGS."
715 flags)))) 724 flags))))
716 725
717(defun vc-cvs-stay-local-p (file) 726(defun vc-cvs-stay-local-p (file)
718 "Return non-nil if VC should stay local when handling FILE." 727 "Return non-nil if VC should stay local when handling FILE.
728See `vc-cvs-stay-local'."
719 (if vc-cvs-stay-local 729 (if vc-cvs-stay-local
720 (let* ((dirname (if (file-directory-p file) 730 (let* ((dirname (if (file-directory-p file)
721 (directory-file-name file) 731 (directory-file-name file)
@@ -726,18 +736,99 @@ and that it passes `vc-cvs-global-switches' to it before FLAGS."
726 (vc-file-setprop 736 (vc-file-setprop
727 dirname 'vc-cvs-stay-local-p 737 dirname 'vc-cvs-stay-local-p
728 (when (file-readable-p rootname) 738 (when (file-readable-p rootname)
729 (with-temp-buffer 739 (with-temp-buffer
730 (vc-insert-file rootname) 740 (vc-insert-file rootname)
731 (goto-char (point-min)) 741 (goto-char (point-min))
732 (if (looking-at "\\([^:]*\\):") 742 (looking-at "\\([^\n]*\\)")
733 (if (not (stringp vc-cvs-stay-local)) 743 (let* ((cvs-root-members
734 'yes 744 (vc-cvs-parse-root (match-string 1)))
735 (let ((hostname (match-string 1))) 745 (hostname (nth 2 cvs-root-members)))
736 (if (string-match vc-cvs-stay-local hostname) 746 (if (not hostname)
737 'yes 747 'no
738 'no))) 748 (let ((stay-local t) rx)
739 'no)))))))) 749 (cond
740 (if (eq prop 'yes) t nil)))) 750 ;; vc-cvs-stay-local: rx
751 ((stringp vc-cvs-stay-local)
752 (setq rx vc-cvs-stay-local))
753 ;; vc-cvs-stay-local: '( [except] rx ... )
754 ((consp vc-cvs-stay-local)
755 (setq rx (mapconcat
756 (function
757 (lambda (elt)
758 elt))
759 (if (not (eq (car vc-cvs-stay-local)
760 'except))
761 vc-cvs-stay-local
762 (setq stay-local nil)
763 (cdr vc-cvs-stay-local))
764 "\\|"))))
765 (if (not rx)
766 'yes
767 (if (not (string-match rx hostname))
768 (setq stay-local (not stay-local)))
769 (if stay-local
770 'yes
771 'no))))))))))))
772 (if (eq prop 'yes) t nil))))
773
774(defun vc-cvs-parse-root ( root )
775 "Split CVS ROOT specification string into a list of fields.
776A CVS root specification of the form
777 [:METHOD:][[USER@]HOSTNAME:]/path/to/repository
778is converted to a normalized record with the following structure:
779 \(METHOD USER HOSTNAME CVS-ROOT).
780The default METHOD for a CVS root of the form
781 /path/to/repository
782is `local'.
783The default METHOD for a CVS root of the form
784 [USER@]HOSTNAME:/path/to/repository
785is `ext'.
786For an empty string, nil is returned (illegal CVS root)."
787 ;; Split CVS root into colon separated fields (0-4).
788 ;; The `x:' makes sure, that leading colons are not lost;
789 ;; `HOST:/PATH' is then different from `:METHOD:/PATH'.
790 (let* ((root-list (cdr (split-string (concat "x:" root) ":")))
791 (len (length root-list))
792 ;; All syntactic varieties will get a proper METHOD.
793 (root-list
794 (cond
795 ((= len 0)
796 ;; Invalid CVS root
797 nil)
798 ((= len 1)
799 ;; Simple PATH => method `local'
800 (cons "local"
801 (cons nil root-list)))
802 ((= len 2)
803 ;; [USER@]HOST:PATH => method `ext'
804 (and (not (equal (car root-list) ""))
805 (cons "ext" root-list)))
806 ((= len 3)
807 ;; :METHOD:PATH
808 (cons (cadr root-list)
809 (cons nil (cddr root-list))))
810 (t
811 ;; :METHOD:[USER@]HOST:PATH
812 (cdr root-list)))))
813 (if root-list
814 (let ((method (car root-list))
815 (uhost (or (cadr root-list) ""))
816 (root (nth 2 root-list))
817 user host)
818 ;; Split USER@HOST
819 (if (string-match "\\(.*\\)@\\(.*\\)" uhost)
820 (setq user (match-string 1 uhost)
821 host (match-string 2 uhost))
822 (setq host uhost))
823 ;; Remove empty HOST
824 (and (equal host "")
825 (setq host))
826 ;; Fix windows style CVS root `:local:C:\\project\\cvs\\some\\dir'
827 (and host
828 (equal method "local")
829 (setq root (concat host ":" root) host))
830 ;; Normalize CVS root record
831 (list method user host root)))))
741 832
742(defun vc-cvs-parse-status (&optional full) 833(defun vc-cvs-parse-status (&optional full)
743 "Parse output of \"cvs status\" command in the current buffer. 834 "Parse output of \"cvs status\" command in the current buffer.