changeset 78359:2dd5d799a16d

* vc-git.el: (vc-directory-exclusion-list, vc-handled-backends): Remove. (vc-git-revision-completion-table): Enable. * vc-hooks.el (vc-handled-backends): Add GIT and HG. * vc.el (vc-directory-exclusion-list): Add .git and .hg. * vc-hg.el (vc-hg-revision-completion-table): Re-enable. * diff-mode.el (diff-mode-menu): New entries. * diff-mode.el (diff-beginning-of-file-and-junk): New function. (diff-file-kill): Use it. (diff-beginning-of-hunk): Add arg `try-harder' using it. (diff-restrict-view, diff-find-source-location, diff-refine-hunk): Use it so they find the hunk even when we're in the file header. * vc.el: Add new VC operation `revision-completion-table'. (vc-default-revision-completion-table): New function. (vc-version-diff, vc-version-other-window): Use it to provide completion of revision names if the backend provides it. * vc-arch.el (vc-arch--version-completion-table) (vc-arch-revision-completion-table): New functions to provide completion of revision names. * vc-cvs.el: Require CL. (vc-cvs-revision-table, vc-cvs-revision-completion-table): New functions to provide completion of revision names. * eval.c (init_eval_once): Bump max_lisp_eval_depth to 400. * vc2-xtra.texi (Customizing VC): Add GIT and HG.
author Dan Nicolaescu <dann@ics.uci.edu>
date Mon, 30 Jul 2007 00:19:06 +0000
parents 9b7f2e8baaeb
children 2454989fea3a
files etc/NEWS lisp/ChangeLog lisp/diff-mode.el lisp/vc-arch.el lisp/vc-cvs.el lisp/vc-git.el lisp/vc-hg.el lisp/vc-hooks.el lisp/vc.el man/ChangeLog man/vc2-xtra.texi src/ChangeLog src/eval.c
diffstat 13 files changed, 211 insertions(+), 62 deletions(-) [+]
line wrap: on
line diff
--- a/etc/NEWS	Sun Jul 29 20:11:25 2007 +0000
+++ b/etc/NEWS	Mon Jul 30 00:19:06 2007 +0000
@@ -63,6 +63,8 @@
 
 ** VC
 
+*** VC backends can provide completion of revision names.
+
 *** VC has some support for Mercurial (hg).
 
 *** VC has some support for Git.
--- a/lisp/ChangeLog	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/ChangeLog	Mon Jul 30 00:19:06 2007 +0000
@@ -1,3 +1,38 @@
+2007-07-30  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc-git.el: (vc-directory-exclusion-list, vc-handled-backends):
+	Remove.
+	(vc-git-revision-completion-table): Enable.
+	
+	* vc-hooks.el (vc-handled-backends): Add GIT and HG.
+
+	* vc.el (vc-directory-exclusion-list): Add .git and .hg.
+
+	* vc-hg.el (vc-hg-revision-completion-table): Re-enable.
+
+	* diff-mode.el (diff-mode-menu): New entries.
+
+2007-06-30  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* diff-mode.el (diff-beginning-of-file-and-junk): New function.
+	(diff-file-kill): Use it.
+	(diff-beginning-of-hunk): Add arg `try-harder' using it.
+	(diff-restrict-view, diff-find-source-location, diff-refine-hunk):
+	Use it so they find the hunk even when we're in the file header.
+
+	* vc.el: Add new VC operation `revision-completion-table'.
+	(vc-default-revision-completion-table): New function.
+	(vc-version-diff, vc-version-other-window): Use it to provide
+	completion of revision names if the backend provides it.
+
+	* vc-arch.el (vc-arch--version-completion-table)
+	(vc-arch-revision-completion-table): New functions to provide
+	completion of revision names.
+
+	* vc-cvs.el: Require CL.
+	(vc-cvs-revision-table, vc-cvs-revision-completion-table):
+	New functions to provide completion of revision names.
+
 2007-07-29  Kimit Yada  <kimitto@gmail.com>  (tiny change)
 
 	* emacs-lisp/copyright.el (copyright-update-year, copyright-update)
--- a/lisp/diff-mode.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/diff-mode.el	Mon Jul 30 00:19:06 2007 +0000
@@ -164,12 +164,23 @@
   '("Diff"
     ["Jump to Source"		diff-goto-source	t]
     ["Apply hunk"		diff-apply-hunk		t]
+    ["Test applying hunk"	diff-test-hunk		t]
     ["Apply diff with Ediff"	diff-ediff-patch	t]
-    ["-----" nil nil]
+    "-----"
     ["Reverse direction"	diff-reverse-direction	t]
     ["Context -> Unified"	diff-context->unified	t]
     ["Unified -> Context"	diff-unified->context	t]
     ;;["Fixup Headers"		diff-fixup-modifs	(not buffer-read-only)]
+    "-----"
+    ["Split hunk"		diff-split-hunk		t]
+    ["Refine hunk"	        diff-refine-hunk	t]
+    ["Kill current hunk"	diff-hunk-kill   	t]
+    ["Kill current file's hunks" diff-file-kill   	t]
+    "-----"
+    ["Previous Hunk"		diff-hunk-prev  	t]
+    ["Next Hunk"		diff-hunk-next  	t]
+    ["Previous File"		diff-file-prev  	t]
+    ["Next File"		diff-file-next  	t]
     ))
 
 (defcustom diff-minor-mode-prefix "\C-c="
@@ -390,13 +401,20 @@
     ;; The return value is used by easy-mmode-define-navigation.
     (goto-char (or end (point-max)))))
 
-(defun diff-beginning-of-hunk ()
+(defun diff-beginning-of-hunk (&optional try-harder)
+  "Move back to beginning of hunk.
+If TRY-HARDER is non-nil, try to cater to the case where we're not in a hunk
+but in the file header instead, in which case move forward to the first hunk."
   (beginning-of-line)
   (unless (looking-at diff-hunk-header-re)
     (forward-line 1)
     (condition-case ()
 	(re-search-backward diff-hunk-header-re)
-      (error (error "Can't find the beginning of the hunk")))))
+      (error
+       (if (not try-harder)
+           (error "Can't find the beginning of the hunk")
+         (diff-beginning-of-file-and-junk)
+         (diff-hunk-next))))))
 
 (defun diff-beginning-of-file ()
   (beginning-of-line)
@@ -425,7 +443,7 @@
 If the prefix ARG is given, restrict the view to the current file instead."
   (interactive "P")
   (save-excursion
-    (if arg (diff-beginning-of-file) (diff-beginning-of-hunk))
+    (if arg (diff-beginning-of-file) (diff-beginning-of-hunk 'try-harder))
     (narrow-to-region (point)
 		      (progn (if arg (diff-end-of-file) (diff-end-of-hunk))
 			     (point)))
@@ -453,18 +471,37 @@
       (diff-end-of-hunk)
       (kill-region start (point)))))
 
+(defun diff-beginning-of-file-and-junk ()
+  "Go to the beginning of file-related diff-info.
+This is like `diff-beginning-of-file' except it tries to skip back over leading
+data such as \"Index: ...\" and such."
+  (let ((start (point))
+        (file (condition-case err (progn (diff-beginning-of-file) (point))
+                (error err)))
+        ;; prevhunk is one of the limits.
+        (prevhunk (save-excursion (ignore-errors (diff-hunk-prev) (point))))
+        err)
+    (when (consp file)
+      ;; Presumably, we started before the file header, in the leading junk.
+      (setq err file)
+      (diff-file-next)
+      (setq file (point)))
+    (let ((index (save-excursion
+                   (re-search-backward "^Index: " prevhunk t))))
+      (when index (setq file index))
+      (if (<= file start)
+          (goto-char file)
+        ;; File starts *after* the starting point: we really weren't in
+        ;; a file diff but elsewhere.
+        (goto-char start)
+        (signal (car err) (cdr err))))))
+          
 (defun diff-file-kill ()
   "Kill current file's hunks."
   (interactive)
-  (diff-beginning-of-file)
+  (diff-beginning-of-file-and-junk)
   (let* ((start (point))
-	 (prevhunk (save-excursion
-		     (ignore-errors
-		       (diff-hunk-prev) (point))))
-	 (index (save-excursion
-		  (re-search-backward "^Index: " prevhunk t)))
 	 (inhibit-read-only t))
-    (when index (setq start index))
     (diff-end-of-file)
     (if (looking-at "^\n") (forward-char 1)) ;`tla' generates such diffs.
     (kill-region start (point))))
@@ -1289,7 +1326,8 @@
 SWITCHED is non-nil if the patch is already applied."
   (save-excursion
     (let* ((other (diff-xor other-file diff-jump-to-old-file))
-	   (char-offset (- (point) (progn (diff-beginning-of-hunk) (point))))
+	   (char-offset (- (point) (progn (diff-beginning-of-hunk 'try-harder)
+                                          (point))))
            ;; Check that the hunk is well-formed.  Otherwise diff-mode and
            ;; the user may disagree on what constitutes the hunk
            ;; (e.g. because an empty line truncates the hunk mid-course),
@@ -1458,7 +1496,8 @@
 (defun diff-refine-hunk ()
   "Refine the current hunk by ignoring space differences."
   (interactive)
-  (let* ((char-offset (- (point) (progn (diff-beginning-of-hunk) (point))))
+  (let* ((char-offset (- (point) (progn (diff-beginning-of-hunk 'try-harder)
+                                        (point))))
 	 (opts (case (char-after) (?@ "-bu") (?* "-bc") (t "-b")))
 	 (line-nb (and (or (looking-at "[^0-9]+\\([0-9]+\\)")
 			   (error "Can't find line number"))
--- a/lisp/vc-arch.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/vc-arch.el	Mon Jul 30 00:19:06 2007 +0000
@@ -419,6 +419,31 @@
 
 (defun vc-arch-init-version () nil)
 
+;;; Completion of versions and revisions.
+
+(defun vc-arch--version-completion-table (root string)
+  (delq nil
+	(mapcar
+	 (lambda (d)
+	   (when (string-match "/\\([^/]+\\)/\\([^/]+\\)\\'" d)
+	     (concat (match-string 2 d) "/" (match-string 1 d))))
+	 (let ((default-directory root))
+	   (file-expand-wildcards
+	    (concat "*/*/"
+		    (if (string-match "/" string)
+			(concat (substring string (match-end 0))
+				"*/" (substring string 0 (match-beginning 0)))
+		      (concat "*/" string))
+		    "*"))))))
+
+(defun vc-arch-revision-completion-table (file)
+  (lexical-let ((file file))
+    (lambda (string pred action)
+      ;; FIXME: complete revision patches as well.
+      (let* ((root (expand-file-name "{arch}" (vc-arch-root file)))
+             (table (vc-arch--version-completion-table root string)))
+	(complete-with-action action table string pred)))))
+
 ;;; Less obvious implementations.
 
 (defun vc-arch-find-version (file rev buffer)
--- a/lisp/vc-cvs.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/vc-cvs.el	Mon Jul 30 00:19:06 2007 +0000
@@ -29,8 +29,7 @@
 
 ;;; Code:
 
-(eval-when-compile
-  (require 'vc))
+(eval-when-compile (require 'cl) (require 'vc))
 
 ;;;
 ;;; Customization options
@@ -960,6 +959,33 @@
 	       (vc-file-setprop file 'vc-checkout-time 0)
 	       (if set-state (vc-file-setprop file 'vc-state 'edited)))))))))
 
+;; Completion of revision names.
+;; Just so I don't feel like I'm duplicating code from pcl-cvs, I'll use
+;; `cvs log' so I can list all the revision numbers rather than only
+;; tag names.
+
+(defun vc-cvs-revision-table (file)
+  (let ((default-directory (file-name-directory file))
+        (res nil))
+    (with-temp-buffer
+      (vc-cvs-command t nil file "log")
+      (goto-char (point-min))
+      (when (re-search-forward "^symbolic names:\n" nil t)
+        (while (looking-at "^	\\(.*\\): \\(.*\\)")
+          (push (cons (match-string 1) (match-string 2)) res)
+          (forward-line 1)))
+      (while (re-search-forward "^revision \\([0-9.]+\\)" nil t)
+        (push (match-string 1) res))
+      res)))
+
+(defun vc-cvs-revision-completion-table (file)
+  (lexical-let ((file file)
+                table)
+    (setq table (lazy-completion-table
+                 table (lambda () (vc-cvs-revision-table file))))
+    table))
+                                           
+
 (provide 'vc-cvs)
 
 ;;; arch-tag: 60e1402a-aa53-4607-927a-cf74f144b432
--- a/lisp/vc-git.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/vc-git.el	Mon Jul 30 00:19:06 2007 +0000
@@ -111,13 +111,6 @@
 
 (eval-when-compile (require 'cl) (require 'vc))
 
-;; XXX when this backend is considered sufficiently reliable this
-;; should be moved to vc-hooks.el
-(add-to-list 'vc-handled-backends 'GIT)
-(eval-after-load "vc"
-  '(add-to-list 'vc-directory-exclusion-list ".git" t))
-
-
 (defvar git-commits-coding-system 'utf-8
   "Default coding system for git commits.")
 
@@ -331,14 +324,12 @@
         (push (match-string 2) table)))
     table))
 
-;; Commented out on the 22.x branch, VC here does not support it yet
-;; and when bytecompiling it max-specpdl-size is exceeded.
-;; (defun vc-git-revision-completion-table (file)
-;;   (lexical-let ((file file)
-;;                 table)
-;;     (setq table (lazy-completion-table
-;;                  table (lambda () (vc-git-revision-table file))))
-;;     table))
+(defun vc-git-revision-completion-table (file)
+  (lexical-let ((file file)
+                table)
+    (setq table (lazy-completion-table
+                 table (lambda () (vc-git-revision-table file))))
+    table))
 
 (defun vc-git-diff-tree (dir &optional rev1 rev2)
   (vc-git-diff dir rev1 rev2))
--- a/lisp/vc-hg.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/vc-hg.el	Mon Jul 30 00:19:06 2007 +0000
@@ -292,12 +292,12 @@
        (buffer-substring-no-properties (point-min) (point-max))))))
 
 ;; Modelled after the similar function in vc-cvs.el
-;; (defun vc-hg-revision-completion-table (file)
-;;   (lexical-let ((file file)
-;;                 table)
-;;     (setq table (lazy-completion-table
-;;                  table (lambda () (vc-hg-revision-table file))))
-;;     table))
+(defun vc-hg-revision-completion-table (file)
+  (lexical-let ((file file)
+                table)
+    (setq table (lazy-completion-table
+                 table (lambda () (vc-hg-revision-table file))))
+    table))
 
 (defalias 'vc-hg-diff-tree 'vc-hg-diff)
 
--- a/lisp/vc-hooks.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/vc-hooks.el	Mon Jul 30 00:19:06 2007 +0000
@@ -62,8 +62,9 @@
   :type 'regexp
   :group 'vc)
 
-(defcustom vc-handled-backends '(RCS CVS SVN SCCS Arch MCVS)
-  ;; Arch and MCVS come last because they are per-tree rather than per-dir.
+(defcustom vc-handled-backends '(RCS CVS SVN SCCS GIT HG Arch MCVS)
+  ;; GIT, HG, Arch and MCVS come last because they are per-tree rather
+  ;; than per-dir.
   "*List of version control backends for which VC will be used.
 Entries in this list will be tried in order to determine whether a
 file is under that sort of version control.
@@ -71,7 +72,7 @@
 when visiting a file managed by that backend.
 An empty list disables VC altogether."
   :type '(repeat symbol)
-  :version "21.1"
+  :version "22.2"
   :group 'vc)
 
 (defcustom vc-path
--- a/lisp/vc.el	Sun Jul 29 20:11:25 2007 +0000
+++ b/lisp/vc.el	Mon Jul 30 00:19:06 2007 +0000
@@ -327,6 +327,11 @@
 ;;   of either 0 (no differences found), or 1 (either non-empty diff
 ;;   or the diff is run asynchronously).
 ;;
+;; - revision-completion-table (file)
+;;
+;;   Return a completion table for existing revisions of FILE.
+;;   The default is to not use any completion table.
+;;
 ;; - diff-tree (dir &optional rev1 rev2)
 ;;
 ;;   Insert the diff for all files at and below DIR into the *vc-diff*
@@ -559,7 +564,8 @@
   :group 'vc
   :version "20.3")
 
-(defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS" "MCVS" ".svn" "{arch}")
+(defcustom vc-directory-exclusion-list '("SCCS" "RCS" "CVS" "MCVS" ".svn" 
+					 ".git" ".hg" "{arch}")
   "List of directory names to be ignored when walking directory trees."
   :type '(repeat string)
   :group 'vc)
@@ -1752,6 +1758,8 @@
 	  (message "No changes to %s since latest version" file)
 	(vc-version-diff file nil nil)))))
 
+(defun vc-default-revision-completion-table (backend file) nil)
+
 (defun vc-version-diff (file rev1 rev2)
   "List the differences between FILE's versions REV1 and REV2.
 If REV1 is empty or nil it means to use the current workfile version;
@@ -1759,12 +1767,13 @@
 a directory, in that case, generate diffs between the correponding
 versions of all registered files in or below it."
   (interactive
-   (let ((file (expand-file-name
-                (read-file-name (if buffer-file-name
-                                    "File or dir to diff (default visited file): "
-                                  "File or dir to diff: ")
-                                default-directory buffer-file-name t)))
-         (rev1-default nil) (rev2-default nil))
+   (let* ((file (expand-file-name
+                 (read-file-name (if buffer-file-name
+                                     "File or dir to diff (default visited file): "
+                                   "File or dir to diff: ")
+                                 default-directory buffer-file-name t)))
+          (rev1-default nil) (rev2-default nil)
+          (completion-table (vc-call revision-completion-table file)))
      ;; compute default versions based on the file state
      (cond
       ;; if it's a directory, don't supply any version default
@@ -1780,17 +1789,21 @@
        (if (string= rev1-default "") (setq rev1-default nil))
        (setq rev2-default (vc-workfile-version file))))
      ;; construct argument list
-     (list file
-           (read-string (if rev1-default
-			    (concat "Older version (default "
-				    rev1-default "): ")
-			  "Older version: ")
-			nil nil rev1-default)
-           (read-string (if rev2-default
-			    (concat "Newer version (default "
-				    rev2-default "): ")
-			  "Newer version (default current source): ")
-			nil nil rev2-default))))
+     (let* ((rev1-prompt (if rev1-default
+			     (concat "Older version (default "
+				     rev1-default "): ")
+			   "Older version: "))
+	    (rev2-prompt (concat "Newer version (default "
+				 (or rev2-default "current source") "): "))
+	    (rev1 (if completion-table
+		      (completing-read rev1-prompt completion-table
+                                       nil nil nil nil rev1-default)
+		    (read-string rev1-prompt nil nil rev1-default)))
+	    (rev2 (if completion-table
+		      (completing-read rev2-prompt completion-table
+                                       nil nil nil nil rev2-default)
+		    (read-string rev2-prompt nil nil rev2-default))))
+       (list file rev1 rev2))))
   (if (file-directory-p file)
       ;; recursive directory diff
       (progn
@@ -1945,7 +1958,16 @@
   "Visit version REV of the current file in another window.
 If the current file is named `F', the version is named `F.~REV~'.
 If `F.~REV~' already exists, use it instead of checking it out again."
-  (interactive "sVersion to visit (default is workfile version): ")
+  (interactive
+   (save-current-buffer
+     (vc-ensure-vc-buffer)
+     (let ((completion-table
+            (vc-call revision-completion-table buffer-file-name))
+           (prompt "Version to visit (default is workfile version): "))
+       (list
+        (if completion-table
+            (completing-read prompt completion-table)
+          (read-string prompt))))))
   (vc-ensure-vc-buffer)
   (let* ((file buffer-file-name)
 	 (version (if (string-equal rev "")
--- a/man/ChangeLog	Sun Jul 29 20:11:25 2007 +0000
+++ b/man/ChangeLog	Mon Jul 30 00:19:06 2007 +0000
@@ -1,3 +1,7 @@
+2007-07-30  Dan Nicolaescu  <dann@ics.uci.edu>
+
+	* vc2-xtra.texi (Customizing VC): Add GIT and HG.
+
 2007-07-28  Nick Roberts  <nickrob@snap.net.nz>
 
 	* building.texi (GDB Graphical Interface): Qualify use of "M-x gdba".
--- a/man/vc2-xtra.texi	Sun Jul 29 20:11:25 2007 +0000
+++ b/man/vc2-xtra.texi	Mon Jul 30 00:19:06 2007 +0000
@@ -588,9 +588,9 @@
 @subsection Customizing VC
 
 @vindex vc-handled-backends
-The variable @code{vc-handled-backends} determines which version
-control systems VC should handle.  The default value is @code{(RCS CVS
-SVN SCCS Arch MCVS)}, so it contains all six version systems that are
+The variable @code{vc-handled-backends} determines which version control
+systems VC should handle.  The default value is @code{(RCS CVS SVN SCCS
+GIT HG Arch MCVS)}, so it contains all six version systems that are
 currently supported.  If you want VC to ignore one or more of these
 systems, exclude its name from the list.  To disable VC entirely, set
 this variable to @code{nil}.
--- a/src/ChangeLog	Sun Jul 29 20:11:25 2007 +0000
+++ b/src/ChangeLog	Mon Jul 30 00:19:06 2007 +0000
@@ -1,3 +1,7 @@
+2007-07-30  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* eval.c (init_eval_once): Bump max_lisp_eval_depth to 400.
+
 2007-07-25  Glenn Morris  <rgm@gnu.org>
 
 	* Relicense all FSF files to GPLv3 or later.
--- a/src/eval.c	Sun Jul 29 20:11:25 2007 +0000
+++ b/src/eval.c	Mon Jul 30 00:19:06 2007 +0000
@@ -221,7 +221,7 @@
   specpdl_ptr = specpdl;
   /* Don't forget to update docs (lispref node "Local Variables").  */
   max_specpdl_size = 1000;
-  max_lisp_eval_depth = 300;
+  max_lisp_eval_depth = 400;
 
   Vrun_hooks = Qnil;
 }