diff lisp/diff-mode.el @ 82255:eea3be43d1de

(diff-font-lock-keywords): Fix up false positives. (diff-beginning-of-file): Adjust to the fact that diff-file-header-re may match up to 4 lines. (diff-beginning-of-file-and-junk): Rewrite.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Fri, 03 Aug 2007 22:06:36 +0000
parents b98604865ea0
children e5a68f18fcb9
line wrap: on
line diff
--- a/lisp/diff-mode.el	Fri Aug 03 17:09:01 2007 +0000
+++ b/lisp/diff-mode.el	Fri Aug 03 22:06:36 2007 +0000
@@ -349,8 +349,11 @@
     ("^--- .+ ----$"             . diff-hunk-header-face) ;context
     ("^[0-9,]+[acd][0-9,]+$"     . diff-hunk-header-face) ;normal
     ("^---$"                     . diff-hunk-header-face) ;normal
-    ("^\\(---\\|\\+\\+\\+\\|\\*\\*\\*\\) \\([^\t\n]+\\)\\(.*[^*-]\\)?\n"
-     (0 diff-header-face) (2 diff-file-header-face prepend))
+    ;; For file headers, accept files with spaces, but be careful to rule
+    ;; out false-positives when matching hunk headers.
+    ("^\\(---\\|\\+\\+\\+\\|\\*\\*\\*\\) \\([^\t\n]+?\\)\\(?:\t.*\\| \\(\\*\\*\\*\\*\\|----\\)\\)?\n"
+     (0 diff-header-face)
+     (2 (if (not (match-end 3)) diff-file-header-face) prepend))
     ("^\\([-<]\\)\\(.*\n\\)"
      (1 diff-indicator-removed-face) (2 diff-removed-face))
     ("^\\([+>]\\)\\(.*\n\\)"
@@ -425,10 +428,20 @@
 (defun diff-beginning-of-file ()
   (beginning-of-line)
   (unless (looking-at diff-file-header-re)
-    (forward-line 2)
-    (condition-case ()
-	(re-search-backward diff-file-header-re)
-      (error (error "Can't find the beginning of the file")))))
+    (let ((start (point))
+          res)
+      ;; diff-file-header-re may need to match up to 4 lines, so in case
+      ;; we're inside the header, we need to move up to 3 lines forward.
+      (forward-line 3)
+      (if (and (setq res (re-search-backward diff-file-header-re nil t))
+               ;; Maybe the 3 lines forward were too much and we matched
+               ;; a file header after our starting point :-(
+               (or (<= (point) start)
+                   (setq res (re-search-backward diff-file-header-re nil t))))
+          res
+        (goto-char start)
+        (error "Can't find the beginning of the file")))))
+        
 
 (defun diff-end-of-file ()
   (re-search-forward "^[-+#!<>0-9@* \\]" nil t)
@@ -481,26 +494,34 @@
   "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))))))
+  (let* ((start (point))
+         (prevfile (condition-case err
+                       (save-excursion (diff-beginning-of-file) (point))
+                     (error err)))
+         (err (if (consp prevfile) prevfile))
+         (nextfile (ignore-errors
+                     (save-excursion
+                       (goto-char start) (diff-file-next) (point))))
+         ;; prevhunk is one of the limits.
+         (prevhunk (save-excursion
+                     (ignore-errors
+                       (if (numberp prevfile) (goto-char prevfile))
+                       (diff-hunk-prev) (point))))
+         (previndex (save-excursion
+                      (re-search-backward "^Index: " prevhunk t))))
+    ;; If we're in the junk, we should use nextfile instead of prevfile.
+    (if (and (numberp nextfile)
+             (or (not (numberp prevfile))
+                 (and previndex (> previndex prevfile))))
+        (setq prevfile nextfile))
+    (if (and previndex (numberp prevfile) (< previndex prevfile))
+        (setq prevfile previndex))
+    (if (and (numberp prevfile) (<= prevfile start))
+        (goto-char prevfile)
+      ;; 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."