mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-23 07:19:15 +00:00
*** empty log message ***
This commit is contained in:
parent
c958d90f6d
commit
646bd33103
357
lisp/diff.el
357
lisp/diff.el
@ -1,10 +1,7 @@
|
||||
;;; diff.el --- "DIFF" mode for handling output from unix diff utility.
|
||||
;;; diff.el --- Run `diff' in compilation-mode.
|
||||
|
||||
;; Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
;; Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
;; Author: Frank P. Bresz <fpb@ittc.wec.com>
|
||||
;; Maintainer: FSF
|
||||
;; Created: 27 Jan 1989
|
||||
;; Keyword: unix, tools
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
@ -23,84 +20,180 @@
|
||||
;; along with GNU Emacs; see the file COPYING. If not, write to
|
||||
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;; todo: diff-switches flexibility:
|
||||
;; (defconst diff-switches-function
|
||||
;; '(lambda (file)
|
||||
;; (if (string-match "\\.el$" file)
|
||||
;; "-c -F\"^(\""
|
||||
;; "-p"))
|
||||
;; "Function to return switches to pass to the `diff' utility, in \\[diff].
|
||||
;; This function is called with one arg, a file name, and returns a string
|
||||
;; containing 0 or more arguments which are passed on to `diff'.
|
||||
;; NOTE: This is not an ordinary hook; it may not be a list of functions.")
|
||||
|
||||
;; - fpb@ittc.wec.com - Sep 25, 1990
|
||||
;; Added code to support sccs diffing.
|
||||
;; also fixed one minor glitch in the
|
||||
;; search for the pattern. If you only 1 addition you won't find the end
|
||||
;; of the pattern (minor)
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'compile)
|
||||
|
||||
(defvar diff-switches nil
|
||||
"*A list of switches to pass to the diff program.")
|
||||
"*A string or list of strings specifying switches to be be passed to diff.")
|
||||
|
||||
(defvar diff-search-pattern "^\\([0-9]\\|\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\)"
|
||||
"Regular expression that delineates difference regions in diffs.")
|
||||
(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)
|
||||
|
||||
(defvar diff-rcs-extension ",v"
|
||||
"*Extension to find RCS file, some systems do not use ,v")
|
||||
;; plain diff format: OLDSTART[,OLDEND]{a,d,c}NEWSTART[,NEWEND]
|
||||
("^\\([0-9]+\\)\\(,[0-9]+\\)?[adc]\\([0-9]+\\)\\(,[0-9]+\\)?$" 1 3)
|
||||
|
||||
;; Initialize the keymap if it isn't already
|
||||
(if (boundp 'diff-mode-map)
|
||||
nil
|
||||
(setq diff-mode-map (make-keymap))
|
||||
(suppress-keymap diff-mode-map)
|
||||
(define-key diff-mode-map "?" 'describe-mode)
|
||||
(define-key diff-mode-map "." 'diff-beginning-of-diff)
|
||||
(define-key diff-mode-map " " 'scroll-up)
|
||||
(define-key diff-mode-map "\177" 'scroll-down)
|
||||
(define-key diff-mode-map "n" 'diff-next-difference)
|
||||
(define-key diff-mode-map "p" 'diff-previous-difference)
|
||||
(define-key diff-mode-map "j" 'diff-show-difference))
|
||||
;; -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 (REGEXP OLD-IDX NEW-IDX) of regular expressions to match difference
|
||||
sections in \\[diff] output. If REGEXP matches, the OLD-IDX'th
|
||||
subexpression 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 section.")
|
||||
|
||||
;; See compilation-parse-errors-function (compile.el).
|
||||
(defun diff-parse-differences (limit-search)
|
||||
(setq compilation-error-list nil)
|
||||
(message "Parsing differences...")
|
||||
|
||||
;; Don't reparse diffs already seen at last parse.
|
||||
(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
|
||||
(cons (set-marker (make-marker)
|
||||
(match-beginning subexpr)
|
||||
(current-buffer))
|
||||
(let ((line (string-to-int
|
||||
(buffer-substring
|
||||
(match-beginning subexpr)
|
||||
(match-end subexpr)))))
|
||||
(save-excursion
|
||||
(set-buffer (find-file-noselect file))
|
||||
(save-excursion
|
||||
(goto-line line)
|
||||
(point-marker)))))
|
||||
compilation-error-list)))))
|
||||
|
||||
(found-desired nil)
|
||||
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)))
|
||||
|
||||
(and limit-search (>= (point) limit-search)
|
||||
;; The user wanted a specific diff, and we're past it.
|
||||
(setq found-desired t)))
|
||||
(if found-desired
|
||||
(setq compilation-parsing-end (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.
|
||||
(setq compilation-parsing-end (point-max))
|
||||
(message "Parsing differences...done")))
|
||||
(setq compilation-error-list (nreverse compilation-error-list)))
|
||||
|
||||
;;;###autoload
|
||||
(defun diff (old new)
|
||||
(defun diff (old new &optional switches)
|
||||
"Find and display the differences between OLD and NEW files.
|
||||
Interactively the current buffer's file name is the default for for NEW
|
||||
and a backup file for NEW is the default for OLD."
|
||||
and a backup file for NEW is the default for OLD.
|
||||
With prefix arg, prompt for diff switches."
|
||||
(interactive
|
||||
(let (oldf newf)
|
||||
(reverse
|
||||
(list
|
||||
(setq newf (buffer-file-name)
|
||||
newf (if (and newf (file-exists-p newf))
|
||||
(read-file-name
|
||||
(concat "Diff new file: ("
|
||||
(file-name-nondirectory newf) ") ")
|
||||
nil newf t)
|
||||
(read-file-name "Diff new file: " nil nil t)))
|
||||
(setq oldf (file-newest-backup newf)
|
||||
oldf (if (and oldf (file-exists-p oldf))
|
||||
(read-file-name
|
||||
(concat "Diff original file: ("
|
||||
(file-name-nondirectory oldf) ") ")
|
||||
(file-name-directory oldf) oldf t)
|
||||
(read-file-name "Diff original file: "
|
||||
(file-name-directory newf) nil t)))))))
|
||||
(nconc
|
||||
(let (oldf newf)
|
||||
(nreverse
|
||||
(list
|
||||
(setq newf (buffer-file-name)
|
||||
newf (if (and newf (file-exists-p newf))
|
||||
(read-file-name
|
||||
(concat "Diff new file: ("
|
||||
(file-name-nondirectory newf) ") ")
|
||||
nil newf t)
|
||||
(read-file-name "Diff new file: " nil nil t)))
|
||||
(setq oldf (file-newest-backup newf)
|
||||
oldf (if (and oldf (file-exists-p oldf))
|
||||
(read-file-name
|
||||
(concat "Diff original file: ("
|
||||
(file-name-nondirectory oldf) ") ")
|
||||
(file-name-directory oldf) oldf t)
|
||||
(read-file-name "Diff original file: "
|
||||
(file-name-directory newf) nil t))))))
|
||||
(if current-prefix-arg
|
||||
(list (read-string "Diff switches: "
|
||||
(if (stringp diff-switches)
|
||||
diff-switches
|
||||
(mapconcat 'identity diff-switches " "))))
|
||||
nil)))
|
||||
(message "Comparing files %s %s..." new old)
|
||||
(setq new (expand-file-name new)
|
||||
old (expand-file-name old))
|
||||
(diff-internal-diff "diff" (append diff-switches (list new old)) nil))
|
||||
(let ((buf (compile-internal (mapconcat 'identity
|
||||
(append '("diff")
|
||||
(if (consp diff-switches)
|
||||
diff-switches
|
||||
(list diff-switches))
|
||||
(list old)
|
||||
(list new))
|
||||
" ")
|
||||
"No more differences" "Diff"
|
||||
'diff-parse-differences)))
|
||||
(save-excursion
|
||||
(set-buffer buf)
|
||||
(set (make-local-variable 'diff-old-file) old)
|
||||
(set (make-local-variable 'diff-new-file) new))
|
||||
buf))
|
||||
|
||||
(defun diff-backup (file)
|
||||
;;;###autoload
|
||||
(defun diff-backup (file &optional switches)
|
||||
"Diff this file with its backup file or vice versa.
|
||||
Uses the latest backup, if there are several numerical backups.
|
||||
If this file is a backup, diff it with its original.
|
||||
The backup file is the first file given to `diff'."
|
||||
(interactive "fDiff (file with backup): ")
|
||||
(interactive (list (read-file-name "Diff (file with backup): ")
|
||||
(if current-prefix-arg
|
||||
(read-string "Diff switches: "
|
||||
(if (stringp diff-switches)
|
||||
diff-switches
|
||||
(mapconcat 'identity
|
||||
diff-switches " ")))
|
||||
nil)))
|
||||
(let (bak ori)
|
||||
(if (backup-file-name-p file)
|
||||
(setq bak file
|
||||
@ -108,7 +201,7 @@ The backup file is the first file given to `diff'."
|
||||
(setq bak (or (diff-latest-backup-file file)
|
||||
(error "No backup found for %s" file))
|
||||
ori file))
|
||||
(diff bak ori)))
|
||||
(diff bak ori switches)))
|
||||
|
||||
(defun diff-latest-backup-file (fn) ; actually belongs into files.el
|
||||
"Return the latest existing backup of FILE, or nil."
|
||||
@ -133,138 +226,4 @@ The backup file is the first file given to `diff'."
|
||||
(> (backup-extract-version fn1)
|
||||
(backup-extract-version fn2))))))))))
|
||||
|
||||
(defun diff-internal-diff (diff-command sw strip)
|
||||
(let ((buffer-read-only nil))
|
||||
(with-output-to-temp-buffer "*Diff Output*"
|
||||
(buffer-disable-undo standard-output)
|
||||
(save-excursion
|
||||
(set-buffer standard-output)
|
||||
(erase-buffer)
|
||||
(apply 'call-process diff-command nil t nil sw)))
|
||||
(set-buffer "*Diff Output*")
|
||||
(goto-char (point-min))
|
||||
(while sw
|
||||
(if (string= (car sw) "-c")
|
||||
;; strip leading filenames from context diffs
|
||||
(progn (forward-line 2) (delete-region (point-min) (point))))
|
||||
(if (and (string= (car sw) "-C") (string= "sccs" diff-command))
|
||||
;; strip stuff from SCCS context diffs
|
||||
(progn (forward-line 2) (delete-region (point-min) (point))))
|
||||
(setq sw (cdr sw)))
|
||||
(if strip
|
||||
;; strip stuff from SCCS context diffs
|
||||
(progn (forward-line strip) (delete-region (point-min) (point)))))
|
||||
(diff-mode)
|
||||
(if (string= "0" diff-total-differences)
|
||||
(let ((buffer-read-only nil))
|
||||
(insert (message "There are no differences.")))
|
||||
(narrow-to-region (point) (progn
|
||||
(forward-line 1)
|
||||
(if (re-search-forward diff-search-pattern
|
||||
nil t)
|
||||
(goto-char (match-beginning 0))
|
||||
(goto-char (point-max)))))
|
||||
(setq diff-current-difference "1")))
|
||||
|
||||
;; Take a buffer full of Unix diff output and go into a mode to easily
|
||||
;; see the next and previous difference
|
||||
(defun diff-mode ()
|
||||
"Diff Mode is used by \\[diff] for perusing the output from the diff program.
|
||||
All normal editing commands are turned off. Instead, these are available:
|
||||
\\<diff-mode-map>
|
||||
\\[diff-beginning-of-diff] Move point to start of this difference.
|
||||
\\[scroll-up] Scroll to next screen of this difference.
|
||||
\\[scroll-down] Scroll to previous screen of this difference.
|
||||
\\[diff-next-difference] Move to Next Difference.
|
||||
\\[diff-previous-difference] Move to Previous Difference.
|
||||
\\[diff-show-difference] Jump to difference specified by numeric position.
|
||||
"
|
||||
(interactive)
|
||||
(use-local-map diff-mode-map)
|
||||
(setq buffer-read-only t
|
||||
major-mode 'diff-mode
|
||||
mode-name "Diff"
|
||||
mode-line-modified "--- "
|
||||
mode-line-process
|
||||
'(" " diff-current-difference "/" diff-total-differences))
|
||||
(make-local-variable 'diff-current-difference)
|
||||
(set (make-local-variable 'diff-total-differences)
|
||||
(int-to-string (diff-count-differences))))
|
||||
|
||||
(defun diff-next-difference (n)
|
||||
"Go to the beginning of the next difference.
|
||||
Differences are delimited by `diff-search-pattern'."
|
||||
(interactive "p")
|
||||
(if (< n 0) (diff-previous-difference (- n))
|
||||
(if (zerop n) ()
|
||||
(goto-char (point-min))
|
||||
(forward-line 1) ; to get past the match for the start of this diff
|
||||
(widen)
|
||||
(if (re-search-forward diff-search-pattern nil 'move n)
|
||||
(let ((start (goto-char (match-beginning 0))))
|
||||
(forward-line 1)
|
||||
(if (re-search-forward diff-search-pattern nil 'move)
|
||||
(goto-char (match-beginning 0)))
|
||||
(narrow-to-region start (point))
|
||||
(setq diff-current-difference
|
||||
(int-to-string (+ n (string-to-int
|
||||
diff-current-difference)))))
|
||||
(re-search-backward diff-search-pattern nil)
|
||||
(narrow-to-region (point) (point-max))
|
||||
(message "No following differences.")
|
||||
(setq diff-current-difference diff-total-differences))
|
||||
(goto-char (point-min)))))
|
||||
|
||||
(defun diff-previous-difference (n)
|
||||
"Go the the beginning of the previous difference.
|
||||
Differences are delimited by `diff-search-pattern'."
|
||||
(interactive "p")
|
||||
(if (< n 0) (diff-next-difference (- n))
|
||||
(if (zerop n) ()
|
||||
(goto-char (point-min))
|
||||
(widen)
|
||||
(if (re-search-backward diff-search-pattern nil 'move n)
|
||||
(setq diff-current-difference
|
||||
(int-to-string (- (string-to-int diff-current-difference) n)))
|
||||
(message "No previous differences.")
|
||||
(setq diff-current-difference "1"))
|
||||
(narrow-to-region (point) (progn
|
||||
(forward-line 1)
|
||||
(re-search-forward diff-search-pattern nil)
|
||||
(goto-char (match-beginning 0))))
|
||||
(goto-char (point-min)))))
|
||||
|
||||
(defun diff-show-difference (n)
|
||||
"Show difference number N (prefix argument)."
|
||||
(interactive "p")
|
||||
(let ((cur (string-to-int diff-current-difference)))
|
||||
(cond ((or (= n cur)
|
||||
(zerop n)
|
||||
(not (natnump n))) ; should signal an error perhaps.
|
||||
;; just redisplay.
|
||||
(goto-char (point-min)))
|
||||
((< n cur)
|
||||
(diff-previous-difference (- cur n)))
|
||||
((> n cur)
|
||||
(diff-next-difference (- n cur))))))
|
||||
|
||||
(defun diff-beginning-of-diff ()
|
||||
"Go to beginning of current difference."
|
||||
(interactive)
|
||||
(goto-char (point-min)))
|
||||
|
||||
;; This function counts up the number of differences in the buffer.
|
||||
(defun diff-count-differences ()
|
||||
"Count number of differences in the current buffer."
|
||||
(message "Counting differences...")
|
||||
(save-excursion
|
||||
(save-restriction
|
||||
(widen)
|
||||
(goto-char (point-min))
|
||||
(let ((cnt 0))
|
||||
(while (re-search-forward diff-search-pattern nil t)
|
||||
(setq cnt (1+ cnt)))
|
||||
(message "Counting differences...done (%d)" cnt)
|
||||
cnt))))
|
||||
|
||||
;;; diff.el ends here
|
||||
|
@ -6,8 +6,6 @@
|
||||
;; Maintainer: FSF
|
||||
;; Keyword: tools, processes
|
||||
|
||||
;;;!!! dup removal is broken.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software; you can redistribute it and/or modify
|
||||
@ -36,12 +34,12 @@
|
||||
|
||||
(defvar compilation-error-list nil
|
||||
"List of error message descriptors for visiting erring functions.
|
||||
Each error descriptor is a cons (or nil).
|
||||
Its car is a marker pointing to an error message.
|
||||
If its cdr is a marker, it points to the text of the line the message is about.
|
||||
If its cdr is a cons, that cons's car is a cons (DIRECTORY . FILE), specifying
|
||||
file the message is about, and its cdr is the number of the line the message
|
||||
is about. Or its cdr may be nil if that error is not interesting.
|
||||
Each error descriptor is a cons (or nil). Its car is a marker pointing to
|
||||
an error message. If its cdr is a marker, it points to the text of the
|
||||
line the message is about. If its cdr is a cons, that cons's car is a cons
|
||||
\(DIRECTORY . FILE\), specifying the file the message is about, and its cdr
|
||||
is the number of the line the message is about. Or its cdr may be nil if
|
||||
that error is not interesting.
|
||||
|
||||
The value may be t instead of a list; this means that the buffer of
|
||||
error messages should be reparsed the next time the list of errors is wanted.")
|
||||
@ -219,7 +217,9 @@ arg REGEXP-ALIST is the error message regexp alist to use (nil means the
|
||||
default). Sixth arg NAME-FUNCTION is a function called to name the buffer (nil
|
||||
means the default). The defaults for these variables are the global values of
|
||||
\`compilation-parse-errors-function', `compilation-error-regexp-alist', and
|
||||
\`compilation-buffer-name-function', respectively."
|
||||
\`compilation-buffer-name-function', respectively.
|
||||
|
||||
Returns the compilation buffer created."
|
||||
(let (outbuf)
|
||||
(save-excursion
|
||||
(or name-of-mode
|
||||
@ -303,6 +303,10 @@ means the default). The defaults for these variables are the global values of
|
||||
(let ((map (make-sparse-keymap)))
|
||||
(define-key map "\C-c\C-c" 'compile-goto-error)
|
||||
(define-key map "\C-c\C-k" 'kill-compilation)
|
||||
(define-key map " " 'scroll-up)
|
||||
(define-key map "\^?" 'scroll-down)
|
||||
(define-key map "\M-n" 'compilation-next-error)
|
||||
(define-key map "\M-p" 'compilation-previous-error)
|
||||
map)
|
||||
"Keymap for compilation log buffers.")
|
||||
|
||||
@ -374,6 +378,67 @@ Runs `compilation-mode-hook' with `run-hooks' (which see)."
|
||||
(setq compilation-in-progress (delq proc compilation-in-progress))
|
||||
))))
|
||||
|
||||
|
||||
(defun compilation-next-error (n)
|
||||
"Move point to the next error in the compilation buffer.
|
||||
Does NOT find the source line like \\[next-error]."
|
||||
(interactive "p")
|
||||
(or (compilation-buffer-p (current-buffer))
|
||||
(error "Not in a compilation buffer."))
|
||||
(setq compilation-last-buffer (current-buffer))
|
||||
(let ((p (point))
|
||||
(errors nil)
|
||||
(first t))
|
||||
|
||||
(save-excursion ;save point in case of later error
|
||||
(while (and (if (< n 0)
|
||||
(null errors)
|
||||
(< (length errors) n))
|
||||
(or first (< compilation-parsing-end (point-max))))
|
||||
(setq first nil)
|
||||
|
||||
(if (< compilation-parsing-end (point-max))
|
||||
(progn
|
||||
;; Move forward a bit and parse.
|
||||
;; Hopefully we will parse enough to find the one we want.
|
||||
(forward-line n)
|
||||
(compile-reinitialize-errors nil (point))))
|
||||
(setq errors compilation-old-error-list)
|
||||
|
||||
;; Look for the error containing P (the original point).
|
||||
(if (< n 0)
|
||||
(while (and errors
|
||||
(> p (car (car errors))))
|
||||
(setq errors (cdr errors)))
|
||||
(while (and errors
|
||||
(>= p (car (car errors))))
|
||||
(setq errors (cdr errors))))
|
||||
(ignore))
|
||||
|
||||
;; Move to the error after the one containing point.
|
||||
(setq p (car (if (< n 0)
|
||||
(let ((i 0)
|
||||
(e compilation-old-error-list))
|
||||
;; See how many cdrs away ERRORS is from the start.
|
||||
(while (not (eq e errors))
|
||||
(setq i (1+ i)
|
||||
e (cdr e)))
|
||||
(if (> (- n) i)
|
||||
(error "Moved back past first error")
|
||||
(nth (+ i n) compilation-old-error-list)))
|
||||
(if errors
|
||||
(nth (1- n) errors)
|
||||
(error "Moved past last error"))))))
|
||||
|
||||
(goto-char p)))
|
||||
|
||||
(defun compilation-previous-error (n)
|
||||
"Move point to the previous error in the compilation buffer.
|
||||
Does NOT find the source line like \\[next-error]."
|
||||
(interactive "p")
|
||||
(compilation-next-error (- n)))
|
||||
|
||||
|
||||
(defun kill-compilation ()
|
||||
"Kill the process made by the \\[compile] command."
|
||||
(interactive)
|
||||
@ -394,7 +459,7 @@ Runs `compilation-mode-hook' with `run-hooks' (which see)."
|
||||
(consp argp))
|
||||
(progn (compilation-forget-errors)
|
||||
(setq compilation-parsing-end 1)))
|
||||
(if compilation-error-list
|
||||
(if (and compilation-error-list (not limit-search))
|
||||
;; Since compilation-error-list is non-nil, it points to a specific
|
||||
;; error the user wanted. So don't move it around.
|
||||
nil
|
||||
@ -419,24 +484,23 @@ other kinds of prefix arguments are ignored."
|
||||
(error "Not in a compilation buffer."))
|
||||
(setq compilation-last-buffer (current-buffer))
|
||||
(compile-reinitialize-errors argp (point))
|
||||
(save-excursion
|
||||
(beginning-of-line)
|
||||
;; Move compilation-error-list to the elt of
|
||||
;; compilation-old-error-list whose car is the error we want.
|
||||
(setq compilation-error-list
|
||||
(memq (let (elt)
|
||||
(while (not (or (setq elt (assoc (point-marker)
|
||||
compilation-old-error-list))
|
||||
(eobp)))
|
||||
;; This line doesn't contain an error.
|
||||
;; Move forward a line and look again.
|
||||
(forward-line 1))
|
||||
elt)
|
||||
compilation-old-error-list)))
|
||||
|
||||
;; Move compilation-error-list to the elt of compilation-old-error-list
|
||||
;; whose cadr is the error we want.
|
||||
(setq compilation-error-list compilation-old-error-list)
|
||||
(while (and (cdr compilation-error-list)
|
||||
(> (point) (car (car (cdr compilation-error-list)))))
|
||||
(setq compilation-error-list (cdr compilation-error-list)))
|
||||
|
||||
;; Move to another window, so that next-error's window changes
|
||||
;; result in the desired setup.
|
||||
(or (one-window-p)
|
||||
(other-window -1))
|
||||
(progn
|
||||
(other-window -1)
|
||||
;; other-window changed the selected buffer,
|
||||
;; but we didn't want to do that.
|
||||
(set-buffer compilation-last-buffer)))
|
||||
|
||||
(next-error 1))
|
||||
|
||||
(defun compilation-buffer-p (buffer)
|
||||
@ -505,11 +569,10 @@ See variables `compilation-parse-errors-function' and
|
||||
(let (next-errors next-error)
|
||||
(save-excursion
|
||||
(set-buffer compilation-last-buffer)
|
||||
(setq next-errors (nthcdr (+ (- (length compilation-old-error-list)
|
||||
(length compilation-error-list)
|
||||
1)
|
||||
(prefix-numeric-value argp))
|
||||
compilation-old-error-list)
|
||||
;; This code used to do something bizarre and incomprehensible.
|
||||
;; Was there a reason I wrote it like that? --roland
|
||||
(setq next-errors (nthcdr (prefix-numeric-value argp)
|
||||
compilation-error-list)
|
||||
next-error (car next-errors))
|
||||
(while
|
||||
(progn
|
||||
@ -650,7 +713,7 @@ See variables `compilation-parse-errors-function' and
|
||||
;; Set compilation-error-list to nil, and unchain the markers that point to the
|
||||
;; error messages and their text, so that they no longer slow down gap motion.
|
||||
;; This would happen anyway at the next garbage collection, but it is better to
|
||||
;; do it the right away.
|
||||
;; do it right away.
|
||||
(defun compilation-forget-errors ()
|
||||
(while compilation-old-error-list
|
||||
(let ((next-error (car compilation-old-error-list)))
|
||||
@ -741,11 +804,11 @@ See variable `compilation-parse-errors-function' for the interface it uses."
|
||||
(setq subexpr (+ subexpr 1 (count-regexp-groupings (car (car alist)))))
|
||||
(setq alist (cdr alist)))
|
||||
|
||||
(while (and (re-search-forward regexp nil t)
|
||||
(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.
|
||||
(not found-desired))
|
||||
(re-search-forward regexp nil t))
|
||||
;; Figure out which constituent regexp matched.
|
||||
(cond ((match-beginning enter-group)
|
||||
;; The match was the enter-directory regexp.
|
||||
@ -813,16 +876,13 @@ See variable `compilation-parse-errors-function' for the interface it uses."
|
||||
(cons filename linenum))
|
||||
compilation-error-list)))))
|
||||
(t
|
||||
(error "Impossible regexp match!")))
|
||||
(error "compilation-parse-errors: impossible regexp match!")))
|
||||
(and limit-search (>= (point) limit-search)
|
||||
;; The user wanted a specific error, and we're past it.
|
||||
(setq found-desired t)))
|
||||
(if desired-found
|
||||
(progn
|
||||
(setq compilation-parsing-end (point))
|
||||
(message "Desired error message found."))
|
||||
;; Set to point-max, not point, so we don't perpetually
|
||||
;; parse the last bit of text when it isn't an error message.
|
||||
(if found-desired
|
||||
(setq compilation-parsing-end (point))
|
||||
;; We have searched the whole buffer.
|
||||
(setq compilation-parsing-end (point-max))
|
||||
(message "Parsing error messages...done")))
|
||||
(setq compilation-error-list (nreverse compilation-error-list)))
|
||||
|
Loading…
Reference in New Issue
Block a user