Subject: 13.1.10; bug in preview-region applied to repeated math environments
From: Paul Nelson <[email-masked]>
To: [email-masked]
Date: Sat, 25 Mar 2023 17:14:48 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Emacs  : GNU Emacs 29.0.50 (build 3, x86_64-apple-darwin21.6.0, NS
appkit-2113.60 Version 12.6 (Build 21G115))
 of 2022-11-06
Package: 13.1.10

Take the following document:

#+begin_src latex
\documentclass{amsart}
\begin{document}
 $x$ $x$
\end{document}
#+end_src

Run ~preview-region~ on the region consisting of the first $x$.  This works
as expected.

Next, run ~preview-region~ on the region consisting of just the second
$x$.  This does not preview the second $x$.  Instead, it refreshes the
overlay on the first $x$.

The relevant output:

#+begin_quote
./_region_.tex:5: Preview: Snippet 1 started.
<-><->

l.5 $
     x$
Preview: Tightpage -32891 -32891 32891 32891
./_region_.tex:5: Preview: Snippet 1 ended.(282168+0x374556).
<-><->

l.5 $x$

#+end_quote

The issue here is that there's not enough context for
~preview-parse-messages~ to determine which $x$ to overlay.

One workaround would be to apply ~preview-region~ to a region containing
both $x$'s (or to use ~preview-buffer~, etc).  This workaround wasn't ideal
for my use-case (see parenthetical comment at the bottom).

I think a fix would be to store the beginning of the region being previewed
in a buffer-local variable and, if needed, bump the point when searching
for where to place the overlay.  Details:

- Add the following line somewhere in preview.el:
  #+begin_src elisp
  (defvar-local preview-region--begin nil "Start of region being
processed.")
  #+end_src

- Add the following line to ~preview-region~, just before the invocation of
~preview-generate-preview~:
  #+begin_src elisp
  (setq-local preview-region--begin begin)
  #+end_src

- Add this to ~preview-parse-messages~, just before the second ~cond~ block:
  #+begin_src elisp
  (when (< (point) preview-region--begin)
    (goto-char preview-region--begin))
  #+end_src

I've made these changes in my local version and they have worked for me.

(This bug was an issue for me because I had set up a timer that searches
the visible portion of a TeX buffer for unrendered math environments and
runs ~preview-region~ on contiguous unpreviewed blocks.  This led to many
situations where  ~preview-region~ was called on math regions, such as the
second $x$ in the above example, that had already been previewed in the
current line.  My original workaround was to enlarge the region sent to
~preview-region~ to contain any repeated math regions that appear earlier
in a given line.  This worked, but often resulted in many fragments getting
unnecessarily refreshed.)