changeset 53918:3619e67b00f4

Don't use compile any more, use diff-mode instead. (diff-regexp-alist, diff-old-file, diff-new-file) (diff-parse-differences, diff-process-setup): Remove. (diff-sentinel): New fun. (diff): Use it. Run the process ourselves. Use diff-mode for the rest of the processing.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Wed, 11 Feb 2004 06:06:24 +0000
parents 04ab10f25d5c
children 095e499a14ad
files lisp/diff.el
diffstat 1 files changed, 49 insertions(+), 170 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/diff.el	Wed Feb 11 06:01:50 2004 +0000
+++ b/lisp/diff.el	Wed Feb 11 06:06:24 2004 +0000
@@ -30,8 +30,6 @@
 
 ;;; Code:
 
-(require 'compile)
-
 (defgroup diff nil
   "Comparing files with `diff'."
   :group 'tools)
@@ -48,143 +46,11 @@
   :type 'string
   :group 'diff)
 
-(defvar diff-regexp-alist
-  '(
-    ;; -u format: @@ -OLDSTART,OLDEND +NEWSTART,NEWEND @@
-    ("^@@ -\\([0-9]+\\),[0-9]+ \\+\\([0-9]+\\),[0-9]+ @@$" 1 2)
-
-    ;; -c format: *** OLDSTART,OLDEND ****
-    ("^\\*\\*\\* \\([0-9]+\\),[0-9]+ \\*\\*\\*\\*$" 1 nil)
-    ;;            --- NEWSTART,NEWEND ----
-    ("^--- \\([0-9]+\\),[0-9]+ ----$" nil 1)
-
-    ;; plain diff format: OLDSTART[,OLDEND]{a,d,c}NEWSTART[,NEWEND]
-    ("^\\([0-9]+\\)\\(,[0-9]+\\)?[adc]\\([0-9]+\\)\\(,[0-9]+\\)?$" 1 3)
-
-    ;; -e (ed) format: OLDSTART[,OLDEND]{a,d,c}
-    ("^\\([0-9]+\\)\\(,[0-9]+\\)?[adc]$" 1)
-
-    ;; -f format: {a,d,c}OLDSTART[ OLDEND]
-    ;; -n format: {a,d,c}OLDSTART LINES-CHANGED
-    ("^[adc]\\([0-9]+\\)\\( [0-9]+\\)?$" 1)
-    )
-  "Alist of regular expressions to match difference sections in \\[diff] output.
-Each element has the form (REGEXP OLD-IDX NEW-IDX).
-Any text that REGEXP matches identifies one difference hunk
-or the header of a hunk.
-
-The OLD-IDX'th subexpression of REGEXP gives the line number
-in the old file, and NEW-IDX'th subexpression gives the line number
-in the new file.  If OLD-IDX or NEW-IDX
-is nil, REGEXP matches only half a hunk.")
-
-(defvar diff-old-file nil
-  "This is the old file name in the comparison in this buffer.")
-(defvar diff-new-file nil
-  "This is the new file name in the comparison in this buffer.")
 (defvar diff-old-temp-file nil
   "This is the name of a temp file to be deleted after diff finishes.")
 (defvar diff-new-temp-file nil
   "This is the name of a temp file to be deleted after diff finishes.")
 
-;; See compilation-parse-errors-function (compile.el).
-(defun diff-parse-differences (limit-search find-at-least)
-  (setq compilation-error-list nil)
-  (message "Parsing differences...")
-
-  ;; Don't reparse diffs already seen at last parse.
-  (if compilation-parsing-end (goto-char compilation-parsing-end))
-
-  ;; Construct in REGEXP a regexp composed of all those in dired-regexp-alist.
-  (let ((regexp (mapconcat (lambda (elt)
-			     (concat "\\(" (car elt) "\\)"))
-			   diff-regexp-alist
-			   "\\|"))
-	;; (GROUP-IDX OLD-IDX NEW-IDX)
-	(groups (let ((subexpr 1))
-		  (mapcar (lambda (elt)
-			    (prog1
-				(cons subexpr
-				      (mapcar (lambda (n)
-						(and n
-						     (+ subexpr n)))
-					      (cdr elt)))
-			      (setq subexpr (+ subexpr 1
-					       (count-regexp-groupings
-						(car elt))))))
-			  diff-regexp-alist)))
-
-	(new-error
-	 (function (lambda (file subexpr)
-		     (setq compilation-error-list
-			   (cons
-			    (list (save-excursion
-				    ;; Report location of message
-				    ;; at beginning of line.
-				    (goto-char
-				     (match-beginning subexpr))
-				    (beginning-of-line)
-				    (point-marker))
-				  ;; Report location of corresponding text.
-				  (list file nil)
-				  (string-to-int
-				   (buffer-substring
-				    (match-beginning subexpr)
-				    (match-end subexpr)))
-				  nil)
-			    compilation-error-list)))))
-
-	(found-desired nil)
-	(num-loci-found 0)
-	g)
-
-    (while (and (not found-desired)
-		;; We don't just pass LIMIT-SEARCH to re-search-forward
-		;; because we want to find matches containing LIMIT-SEARCH
-		;; but which extend past it.
-		(re-search-forward regexp nil t))
-
-      ;; Find which individual regexp matched.
-      (setq g groups)
-      (while (and g (null (match-beginning (car (car g)))))
-	(setq g (cdr g)))
-      (setq g (car g))
-
-      (if (nth 1 g)			;OLD-IDX
-	  (funcall new-error diff-old-file (nth 1 g)))
-      (if (nth 2 g)			;NEW-IDX
-	  (funcall new-error diff-new-file (nth 2 g)))
-
-      (setq num-loci-found (1+ num-loci-found))
-      (if (or (and find-at-least
-		   (>= num-loci-found find-at-least))
-	      (and limit-search (>= (point) limit-search)))
-	      ;; We have found as many new loci as the user wants,
-	      ;; or the user wanted a specific diff, and we're past it.
-	  (setq found-desired t)))
-    (set-marker compilation-parsing-end
-		(if found-desired (point)
-		  ;; Set to point-max, not point, so we don't perpetually
-		  ;; parse the last bit of text when it isn't a diff header.
-		  (point-max)))
-    (message "Parsing differences...done"))
-  (setq compilation-error-list (nreverse compilation-error-list)))
-
-(defun diff-process-setup ()
-  "Set up \`compilation-exit-message-function' for \`diff'."
-  ;; Avoid frightening people with "abnormally terminated"
-  ;; if diff finds differences.
-  (set (make-local-variable 'compilation-exit-message-function)
-       (lambda (status code msg)
-	 (cond ((not (eq status 'exit))
-		(cons msg code))
-	       ((zerop code)
-		'("finished (no differences)\n" . "no differences"))
-	       ((= code 1)
-		'("finished\n" . "differences found"))
-	       (t
-		(cons msg code))))))
-
 ;; prompt if prefix arg present
 (defun diff-switches ()
   (if current-prefix-arg
@@ -193,6 +59,17 @@
 		       diff-switches
 		     (mapconcat 'identity diff-switches " ")))))
 
+(defun diff-sentinel (code)
+  "Code run when the diff process exits.
+CODE is the exit code of the process.  It should be 0 iff no diffs were found."
+  (if diff-old-temp-file (delete-file diff-old-temp-file))
+  (if diff-new-temp-file (delete-file diff-new-temp-file))
+  (save-excursion
+    (goto-char (point-max))
+    (insert (format "\nDiff finished%s.  %s\n"
+		    (if (equal 0 code) " (no differences)" "")
+		    (current-time-string)))))
+
 ;;;###autoload
 (defun diff (old new &optional switches no-async)
   "Find and display the differences between OLD and NEW files.
@@ -223,43 +100,45 @@
   (or switches (setq switches diff-switches)) ; If not specified, use default.
   (let* ((old-alt (file-local-copy old))
 	(new-alt (file-local-copy new))
-	buf)
+	 (command
+	  (mapconcat 'identity
+		     `(,diff-command
+		       ;; Use explicitly specified switches
+		       ,@(if (listp switches) switches (list switches))
+		       ,@(if (or old-alt new-alt)
+			     (list "-L" old "-L" new))
+		       ,(shell-quote-argument (or old-alt old))
+		       ,(shell-quote-argument (or new-alt new)))
+		     " "))
+	 (buf (get-buffer-create "*Diff*"))
+	 proc)
     (save-excursion
-	(let ((compilation-process-setup-function 'diff-process-setup)
-	      (command
-	       (mapconcat 'identity
-			  `(,diff-command
-			    ;; Use explicitly specified switches
-			    ,@(if (listp switches) switches (list switches))
-			    ,@(if (or old-alt new-alt)
-				  (list "-L" old "-L" new))
-			    ,(shell-quote-argument (or old-alt old))
-			    ,(shell-quote-argument (or new-alt new)))
-			  " ")))
-	  (setq buf
-		(compile-internal command
-				  "No more differences" "Diff"
-				  'diff-parse-differences
-				  nil nil nil nil nil nil no-async))
-	  (set-buffer buf)
-	  (set (make-local-variable 'revert-buffer-function)
-	       `(lambda (ignore-auto noconfirm)
-		  (diff ',old ',new ',switches ',no-async)))
-	  (set (make-local-variable 'diff-old-file) old)
-	  (set (make-local-variable 'diff-new-file) new)
-	  (set (make-local-variable 'diff-old-temp-file) old-alt)
-	  (set (make-local-variable 'diff-new-temp-file) new-alt)
-	  (set (make-local-variable 'compilation-finish-function)
-	       (function (lambda (buff msg)
-			   (if diff-old-temp-file
-			       (delete-file diff-old-temp-file))
-			   (if diff-new-temp-file
-			       (delete-file diff-new-temp-file)))))
-	  ;; When async processes aren't available, the compilation finish
-	  ;; function doesn't get chance to run.  Invoke it by hand.
-	  (or (fboundp 'start-process)
-	      (funcall compilation-finish-function nil nil))
-	  buf))))
+      (display-buffer buf)
+      (set-buffer buf)
+      (setq buffer-read-only nil)
+      (buffer-disable-undo (current-buffer))
+      (erase-buffer)
+      (buffer-enable-undo (current-buffer))
+      (diff-mode)
+      (set (make-local-variable 'revert-buffer-function)
+	   `(lambda (ignore-auto noconfirm)
+	      (diff ',old ',new ',switches ',no-async)))
+      (set (make-local-variable 'diff-old-temp-file) old-alt)
+      (set (make-local-variable 'diff-new-temp-file) new-alt)
+      (insert command "\n")
+      (if (and (not no-async) (fboundp 'start-process))
+	  (progn
+	    (setq proc (start-process "Diff" buf shell-file-name
+				      shell-command-switch command))
+	    (set-process-sentinel
+	     proc (lambda (proc msg)
+		    (with-current-buffer (process-buffer proc)
+		      (diff-sentinel (process-exit-status proc))))))
+	;; Async processes aren't available.
+	(diff-sentinel
+	 (call-process shell-file-name nil buf nil
+		       shell-command-switch command))))
+    buf))
 
 ;;;###autoload
 (defun diff-backup (file &optional switches)