home *** CD-ROM | disk | FTP | other *** search
- ;;; compare-w.el --- compare text between windows for Emacs.
-
- ;; Copyright (C) 1986, 1989, 1993 Free Software Foundation, Inc.
-
- ;; Maintainer: FSF
-
- ;; This file is part of XEmacs.
-
- ;; XEmacs is free software; you can redistribute it and/or modify it
- ;; under the terms of the GNU General Public License as published by
- ;; the Free Software Foundation; either version 2, or (at your option)
- ;; any later version.
-
- ;; XEmacs is distributed in the hope that it will be useful, but
- ;; WITHOUT ANY WARRANTY; without even the implied warranty of
- ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- ;; General Public License for more details.
-
- ;; You should have received a copy of the GNU General Public License
- ;; along with XEmacs; see the file COPYING. If not, write to the Free
- ;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-
- ;;; Synched up with: FSF 19.28.
- ;;; This file has been somewhat rewritten in XEmacs. It's not clear
- ;;; whether the changes between 19.22 and 19.28 can replace some of
- ;;; the rewriting.
-
- ;;; Commentary:
-
- ;; This package provides one entry point, compare-windows. It compares
- ;; text starting from point in two adjacent windows, advancing point
- ;; until it finds a difference. Option variables permit you to ignore
- ;; whitespace differences, or case differences, or both.
-
- ;;; Code:
-
- (provide 'compare-w)
-
- (defvar compare-windows-whitespace "[ \t\n]+"
- "*Regexp that defines whitespace sequences for \\[compare-windows].
- Changes in whitespace are optionally ignored.
-
- The value of `compare-windows-whitespace' may instead be a function; this
- function is called in each buffer, with point at the current scanning point.
- The function's job is to categorize any whitespace around (including before)
- point; it should also advance past any whitespace.
-
- The function is passed one argument, the point where compare-windows
- was originally called; it should not consider any text before that point.
- If the function returns the same value for both buffers, then the
- whitespace is considered to match, and is skipped.")
-
- (defvar compare-ignore-case nil
- "*If the value of this variable evaluates to non-nil, \\[compare-windows]
- ignores case differences. Some useful settings: nil, t or 'case-fold-search,
- meaning to track the value of the `case-fold-search' variable.")
-
- ;;;###autoload
- (defun compare-windows (&optional ignore-whitespace)
- "Compare text in current window with text in next window.
- Compares the text starting at point in each window,
- moving over text in each one as far as they match.
-
- A prefix arg means ignore changes in whitespace.
- The variable `compare-windows-whitespace' controls how whitespace is skipped.
-
- If `compare-ignore-case' is non-nil, changes in case are also ignored."
- (interactive "P")
- (let* ((p1 (point))
- (opoint1 p1)
- (b1 (current-buffer))
- (w2 (let* ((w (selected-window))
- (n (next-window w)))
- (if (eq n w)
- (error "No other window")
- n)))
- (p2 (window-point w2))
- (b2 (window-buffer w2))
- (opoint2 p2)
- (success t)
- (compare-ignore-case
- ;;#### ARGGGH
- (eval compare-ignore-case))
- (skip-whitespace (cond ((not ignore-whitespace)
- nil)
- ((stringp compare-windows-whitespace)
- (function (lambda (start)
- (let ((p (point))
- (found nil))
- (while (and (looking-at
- compare-windows-whitespace)
- ;; whitespace still covers p
- (<= p (match-end 0))
- (progn (setq p (match-end 0)
- found t)
- (> (point) start)))
- ;; keep going back until whitespace
- ;; doesn't extend to or past p
- (backward-char 1))
- (if found (goto-char p))
- found))))
- (t
- compare-windows-whitespace))))
- (while success
- (setq success nil)
- ;; if interrupted, show how far we've gotten
- (goto-char p1)
- (set-window-point w2 p2)
-
- ;; If both buffers have whitespace next to point,
- ;; optionally skip over it.
-
- (if skip-whitespace
- (save-excursion
- (let* ((result1 (cond ((funcall skip-whitespace opoint1))
- ((= p1 opoint1) nil)
- (t
- (goto-char (1- p1))
- (funcall skip-whitespace opoint1))))
- (p1a (point))
- (result2 (cond ((progn (set-buffer b2)
- (goto-char p2)
- (funcall skip-whitespace opoint2)))
- ((= p2 opoint2) nil)
- (t
- (goto-char (1- p2))
- (funcall skip-whitespace opoint2))))
- (p2a (point)))
- (if (and (eq result1 result2) result1)
- (setq p1 p1a
- p2 p2a)))))
-
- (let ((case-fold-search compare-ignore-case))
- (setq success (compare-buffer-substrings b1 p1 nil
- b2 p2 nil))
- (if (< success 0) (setq success (- success)))
- (cond ((= success 0)
- ;; whole buffer matched
- (set-buffer b1)
- (setq p1 (point-max)
- p2 (save-excursion
- (set-buffer b2)
- (point-max))
- ;; Can't be any more successful
- success nil))
- ((= success 1)
- ;; nothing matched
- (setq success nil))
- (t
- (setq p1 (+ p1 success -1))
- (setq p2 (+ p2 success -1))))))
-
- (goto-char p1)
- (set-window-point w2 p2)
- ;; Beep if nothing matched
- (if (= (point) opoint1)
- (beep))))
-
- ;;; compare-w.el ends here
-