diff lisp/diff-mode.el @ 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 9355f9b7bbff
children a3a4480349cb
line wrap: on
line diff
--- 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"))