bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Compare-windows bug


From: Whitfield Diffie
Subject: Compare-windows bug
Date: Sat, 29 Jul 2006 17:52:11 -0700

                                Saturday  29 July 2006  at 17:47

    When compare-windows is called with an argument (ignore whitespace)
in a text window and the other window is a TeX window, the following
error results:

 Debugger entered--Lisp error:
         (wrong-type-argument stringp tex-categorize-whitespace)
   looking-at(tex-categorize-whitespace)
   (and (looking-at compare-windows-whitespace) ...
                        ...
   compare-windows-skip-whitespace(1)
   funcall(compare-windows-skip-whitespace 1)
                        ...
   compare-windows((4))*
 * call-interactively(compare-windows)
   execute-extended-command((4))
 * call-interactively(execute-extended-command)


    This occurs because only one compare-widows-skip-whitespace function is
created and two distinct ones are needed, one for each window.

    I have rewritten the code as follows:


(defun compare-windows (ignore-whitespace)

  "   Compare-windows compares the text in current window with text in next
   window, starting at point in each window and moving over text in each
   one as far as they match.

   This command pushes the mark in each window at the prior location of
   point in that window.  If both windows display the same buffer, the mark
   is pushed twice in that buffer: first in the other window, then in the
   selected window.

   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* ((progress 1)
         (p1 (point)) 
         (b1 (current-buffer))
         (w1 (selected-window))
         (w2 (if (not (equal w1 (next-window w1))) (next-window w1)
               (next-window (selected-window) nil 'visible)))
         (p2 (window-point w2))
         (b2 (window-buffer w2))
         (opoint1 (point))
         (opoint2 p2)
         (maxp1 (point-max))
         (maxp2 (save-excursion (set-buffer b2)
                  (push-mark p2 t)
                  (point-max)))
         (skip-func1 (if ignore-whitespace
                        (if (stringp compare-windows-whitespace)
                            'compare-windows-skip-whitespace
                          compare-windows-whitespace)))
         (skip-func2 (save-excursion (set-buffer b2)
                       (if ignore-whitespace
                           (if (stringp compare-windows-whitespace)
                               'compare-windows-skip-whitespace
                             compare-windows-whitespace)))))
    (if (eq w2 (selected-window)) (error "No other window"))
    (push-mark p2 t)
    (push-mark)

    (while (> progress 0)
      ;; If both buffers have whitespace next to point,
      ;; optionally skip over it.

      (and skip-func1 skip-func2
           (save-excursion
             (let (p1a p2a w1 w2 result1 result2)
               (setq result1 (funcall skip-func1 opoint1))
               (setq p1a (point))
               (set-buffer b2)
               (goto-char p2)
               (setq result2 (funcall skip-func2 opoint2))
               (setq p2a (point))
               (if (or (stringp compare-windows-whitespace)
                       (and result1 result2 (eq result1 result2)))
                   (setq p1 p1a
                         p2 p2a)))))

      (let ((size (min (- maxp1 p1) (- maxp2 p2)))
            (case-fold-search compare-ignore-case))
        (setq progress (compare-buffer-substrings b2 p2 (+ size p2)
                                                  b1 p1 (+ size p1)))
        (setq progress (if (zerop progress) size (1- (abs progress))))
        (setq p1 (+ p1 progress) p2 (+ p2 progress)))
      ;; Advance point now rather than later, in case we're interrupted.
      (goto-char p1)
      (set-window-point w2 p2))

    (if (= (point) opoint1) (ding t))))


    In the rewriting I have taken the liberty of moving the variable
assignments into the let* statement and diminishing the number of setqs.
I have also added a t to the ding command to facilitate doing the
comparison with a keyboard macro.

Additional Points

    The reason for wanting to compare windows of different types is that
I frequently get comments in email on TeX manuscripts.  These are often
in mixed syntax and I want to compare what is in the mail with what I
had without creating an additional file, switching to TeX mode in the
mail reader, etc.

    At present, TeX may be the ony mode with distinctive skip-whitespace
characteristics --- consecutive carriage returns terminate a paragraph
--- but it is easy to imagine someone wanting to create other modes with
their own special skip-whitespace functions.

    The comparison strategy in the TeX case is a bit inflexible.  TeX's
syntax results from statements assigning characters to classes and there
are perfectly reasonable TeX styles with different conventions. Alas,
fixing this would seem to require making the TeX interpreter available
to the emacs.

                                        Whit


* Why does <ctrl-U><command><ctrl-M> pass a (4) to the command?
Seems like an odd default.






reply via email to

[Prev in Thread] Current Thread [Next in Thread]