Hello Paul,
On 22/12/2025, Paul D. Nelson wrote:
> The motivation for that behavior (preview-leave-open-previews-visible)
> was to eliminate flickering with automatic and/or live previewing
> enabled. Seeing as most users of automatic previewing will probably
> take visibility-style to be either 'always or 'at-point, there's perhaps
> less benefit in the 'off-point case under discussion, so if you feel
> strongly and/or if it would complicate the implementation, then I'm
> happy to leave it as is until someone else complains. So maybe all
> that's left on this point is to sync the docs with the behavior.
My 'off-point special treatment does not simplify the implementation,
but I simply don't know what's the best thing to do (given that we
agreed to keep the previews open when the source is modified).
For reference and your testing, I attach a patch which removes the
off-point special treatment (in `preview-disable`). I am happy to leave
it like this and document that `'off-point` works best with
`preview-keep-stale-images` being nil as I do in this patch in
`preview-visibility-style`.
However, you will see that the behaviour with
`preview-keep-stale-images` being non-nil is highly non-intuitive:
- Editing the source replaces the icon with a stale image (when using
'always, the stale image is simply kept).
- Moving away from source does not collapse the preview (as we discussed
since the preview does not match the source).
I don't see a good way to design this, which is why I was suggesting
ignoring when `preview-keep-stale-images` is non-nil. As you mentioned,
this might be an unnecessary discussion since this combination of
settings is likely to be rare and we can leave it as is until someone
complains with a better suggestion.
> Do you mean keeping the old image visible (no flicker), or keeping TeX
> source visible? For my workflow ('always with automatic previewing),
> keeping the TeX source visible during regeneration would feel jarring.
> The contract is that the TeX code is visible only while I'm editing it.
> Otherwise, I just see previews everywhere, which update as soon as they
> can (a fraction of a second).
[cont]
>
> I might be misremembering on this point -- I tried testing just now,
> and it wasn't so jarring with the TeX source visible. Moreover, it
> seems like the TeX source stays visible during the brief regeneration
> even after loading an earlier preview.el.
OK, I am not sure anymore. I believe the old and current versions close
the preview (hide the source) while it's being generated. My idea of the
"contract" is that the preview should only replace the source when it is
an accurate reflection of it, and when the user is not editing the
source. That is why I was suggesting keeping the preview open while
generating. However, I tested this and it is indeed quite jarring, so I
suggest we leave it as it as.
> I'm on macOS. You can probably see my detailed specs in the debug
> attachments from a couple messages ago.
>
> Here are the stats for the main, secondary and tertiary monitors in my
> current setup.
OK, this will require a bit more investigation on my part. It certainly
is a "bug" in buframe, not in the preview code, and I think I know the
reason for it but I need to check.
BTW, I restored `preview-inactive-string` and `preview-disabled-string`
and marked them obsolete. I also tried adding a value setter for
`preview-leave-open-previews-visible` as you suggested, however I ran
into an issue where setting the value of `preview-keep-stale-images` and
`preview-visibility-style` before loading preview, then loading preview
results in resetting those variables (because
'preview-leave-open-previews-visible' is set to nil when defined), so I
don't think it's a good solution. I am open to suggestions.
Best regards,
-- Al
>From 4c9b4d5fae73a64d61306aa9380441fecddca742 Mon Sep 17 00:00:00 2001
From: Al Haji-Ali <[email protected]>
Date: Wed, 26 Nov 2025 12:26:40 +0100
Subject: [PATCH] New feature: preview at point
* doc/preview-latex.texi: Add docs for new customizations.
* preview.el: (preview-visibility-style, preview-keep-stale-images,
preview-at-point-placement): New customizations.
(preview--update-buframe, preview-overlay-updated): New functions.
(preview-leave-open-previews-visible, preview-protect-point): Mark as
obsolete.
(preview--string): New macro.
(preview-replace-active-icon): Call preview-overlay-updated.
(preview-place-preview): Clear-out before toggling.
(preview-mark-point, preview--open-for-replace): Add condition on
`preview-visibility-style`.
(preview-toggle): Update to handle values of preview-visibility-style
and preview-at-point-placement call preview-overlay-updated. Handle ARG
being equal to `maybe-open'.
(preview-move-point): Handle `preview-visibility-style` and call
`preview--update-buframe`.
(preview-active-string, preview-disabled-string): Refactor into a
generic preview--string and mark as obsolete.
(preview-disable): Always call preview-toggle and condition deleting
files on `preview-leave-open-previews-visible`.
(preview-parse-messages): Restore point before placing preview.
(preview-region): Update documentation to return started process.
(preview-dvi*-command): Fix case in docstring.
(preview-gs-flag-error): Fix spacing, fix bug and conditionally open
previews.
(preview-gs-place): Use `preview-keep-stale-images` instead of
`preview-leave-open-previews-visible`.
(preview-check-changes): Use `preview-visibility-style` instead of
`preview-leave-open-previews-visible`.
(preview-temporary-opened): Change location of defining to avoid
compilation errors. Developed in collaboration with Paul
D. Nelson (ultrono (at) gmail).
---
doc/preview-latex.texi | 41 ++++
preview.el | 493 ++++++++++++++++++++++++++++-------------
2 files changed, 386 insertions(+), 148 deletions(-)
diff --git a/doc/preview-latex.texi b/doc/preview-latex.texi
index 19210a3506..9daab4eeb3 100644
--- a/doc/preview-latex.texi
+++ b/doc/preview-latex.texi
@@ -480,6 +480,47 @@ math (@code{$@dots{}$}), or if your usage of @code{$} conflicts with
@previewlatex{}'s, you can turn off inline math previews. In the
@samp{Preview Latex} group, remove @code{textmath} from
@code{preview-default-option-list} by customizing this variable.
+
+@item Customize where previews are shown
+
+Set @code{preview-visibility-style} to control when previews appear:
+
+@table @code
+
+@item off-point
+Default. Previews replace the source when point is elsewhere. When a
+preview is opened to show the source, the preview is replaced by an icon.
+
+@item at-point
+Previews never obscure the source. When the cursor enters the source, the
+preview, if there is one, appears alongside it.
+
+@item always
+Previews are always visible when available. Away from point they replace
+the source; when opened they remain displayed alongside the source.
+
+@end table
+
+The placement of previews when shown with their source is controlled with
+@code{preview-at-point-placement}, which can take these values:
+
+@table @code
+
+@item before-string
+Show the preview before the source (default).
+
+@item after-string
+Show the preview after the source.
+
+@item buframe
+Show the preview in a side frame adjacent to point. Requires the
+@code{buframe} package (available on ELPA). Only one frame is used,
+showing the preview whose source is at point. If
+@code{preview-visibility-style} is set to @code{off-point} or
+@code{always}, a preview opened away from point is shown only when point
+is on its source.
+
+@end table
@end itemize
@node Known problems, For advanced users, Simple customization, top
diff --git a/preview.el b/preview.el
index 9481288675..2433ad2e5c 100644
--- a/preview.el
+++ b/preview.el
@@ -453,9 +453,80 @@ show as response of Ghostscript."
"Set this for single-file PostScript conversion.
This will have no effect when `preview-image-type' is
set to `postscript'."
- :group 'preview-latex
+ :group 'preview-appearance
:type 'boolean)
+(defcustom preview-visibility-style 'off-point
+ "When and where previews are displayed relative to their source.
+
+Possible values:
+
+ \\='always Show previews both at point (alongside the source) and
+ away from point (replacing the source).
+
+ \\='at-point Show previews only when point is on their source; never hide
+ the source.
+
+ \\='off-point Show previews only away from point, replacing the source;
+ at point, show a small icon instead (alongside the
+ source). Regenerated previews appear immediately,
+ hiding the source.
+
+The source is always shown while it is being edited or when it is out of
+sync with the preview. For consistent behaviour with \\='off-point, set
+`preview-keep-stale-images' to nil."
+ :group 'preview-appearance
+ :type '(choice
+ (const :tag "Only at point with source" at-point)
+ (const :tag "Only away from point, hiding source" off-point)
+ (const :tag "Both" always)))
+
+(define-obsolete-variable-alias
+ 'preview-leave-open-previews-visible
+ 'preview-keep-stale-images
+ "14.2.0"
+ "Use `preview-keep-stale-images' \
+ and `preview-visibility-style' instead.")
+
+(defcustom preview-keep-stale-images nil
+ "Keep the last preview image visible even when the source changes.
+If non-nil, a preview that was just edited retains its previous image
+while it sits in the disabled state instead of showing the construction
+icon. When nil, the icon appears until the refreshed image arrives."
+ :group 'preview-appearance
+ :type 'boolean)
+
+(defcustom preview-at-point-placement 'before-string
+ "Placement of the at-point preview or icon relative to its source.
+
+Values:
+
+ \\='before-string Show the preview before the TeX source (default).
+ \\='after-string Show the preview after the TeX source.
+ \\='buframe Show the preview in a separate frame (requires
+ the `buframe' package).
+
+You may also use:
+ (buframe FN-POS FRAME-PARAMETERS BUF-PARAMETERS)
+
+where:
+ FN-POS Position function (default:
+ `buframe-position-right-of-overlay').
+ FRAME-PARAMETERS Alist of extra frame parameters.
+ BUF-PARAMETERS Alist of buffer-local variables and values."
+ :group 'preview-appearance
+ :type '(choice
+ (const :tag "Before source (default)" before-string)
+ (const :tag "After source" after-string)
+ (const :tag "On frame" buframe)
+ (list :tag "On frame with explicit parameters"
+ (const buframe)
+ (choice
+ (const :tag "Default" nil)
+ (function :tag "Position function"))
+ (alist :tag "Frame parameters")
+ (alist :tag "Buffer parameters"))))
+
(defun preview-string-expand (arg &optional separator)
"Expand ARG as a string.
It can already be a string. Or it can be a list, then it is
@@ -567,7 +638,7 @@ CMD can be used to override the command line which is used as a basis.
You may set the variable `preview-dvi*-command' to
`preview-dvisvgm-command' and set `preview-dvi*-image-type' to
-`svg' to produce svg images instead of png ones."
+\\='svg to produce SVG images instead of PNG ones."
(let* ((scale (* (/ (preview-hook-enquiry preview-scale)
(preview-get-magnification))
(with-current-buffer TeX-command-buffer
@@ -1271,28 +1342,15 @@ is located."
(cons 'image (cdr icon)))
-(defcustom preview-leave-open-previews-visible nil
- "Whether to leave previews visible when they are opened.
-If nil, then the TeX preview icon is used when the preview is opened.
-If non-nil, then the preview image remains visible. In either case, the
-TeX code appears either below or to the right of the displayed graphic.
-
-If you enable this option, the preview image doesn't turn into
-construction sign temporarily when you edit the underlying LaTeX code
-and regenerate the preview; it is just replaced by updated image when
-ready. This behavior suppresses flicker in the appearance."
- :group 'preview-appearance
- :type 'boolean)
-
(defsubst preview-replace-active-icon (ov replacement)
"Replace the active Icon in OV by REPLACEMENT, another icon."
(let ((img (overlay-get ov 'preview-image)))
(setcdr (car img) (cdar replacement))
(setcdr img (cdr replacement))
- (when (and preview-leave-open-previews-visible
- (consp img))
+ (when (and preview-keep-stale-images (consp img))
;; No "TeX icon" has been shown, so we flush manually.
- (image-flush (car img) t))))
+ (image-flush (car img) t))
+ (preview-overlay-updated ov)))
(defun preview-gs-place (ov snippet box run-buffer tempdir ps-file _imagetype)
"Generate an image placeholder rendered over by Ghostscript.
@@ -1318,7 +1376,7 @@ for the file extension."
(vector box nil snippet))
(if-let* ((old-ov
- (and preview-leave-open-previews-visible
+ (and preview-keep-stale-images
(car
(delq
nil
@@ -1417,6 +1475,8 @@ Place point at POSITION, else beginning of file."
Try \\[ps-run-start] \\[ps-run-buffer] and \
\\<ps-run-mode-map>\\[ps-run-mouse-goto-error] on error offset.")))))
+(defvar preview-temporary-opened nil)
+
(defun preview-gs-flag-error (ov err)
"Make an eps error flag in overlay OV for ERR string."
(let* ((filenames (overlay-get ov 'filenames))
@@ -1463,7 +1523,10 @@ Try \\[ps-run-start] \\[ps-run-buffer] and \
(apply #'preview-mouse-open-eps
args))])))))))
(overlay-put ov 'strings (cons str str))
- (preview-toggle ov)))
+ (preview-toggle ov (and (eq preview-visibility-style 'at-point)
+ 'maybe-open))
+ (setq preview-temporary-opened
+ (cl-delete ov preview-temporary-opened))))
(defun preview-gs-transact (process answer)
"Work off Ghostscript transaction.
@@ -2033,7 +2096,7 @@ Disable it if that is the case. Ignores text properties."
text (overlay-get ov 'preview-prechange)))
(overlay-put ov 'insert-in-front-hooks nil)
(overlay-put ov 'insert-behind-hooks nil)
- (when (and preview-leave-open-previews-visible
+ (when (and (eq preview-visibility-style 'off-point)
(eq (overlay-get ov 'preview-state) 'active))
;; This is so that remote commands, such as `undo',
;; open active previews before disabling them.
@@ -2074,42 +2137,114 @@ definition of OV, AFTER-CHANGE, BEG, END and LENGTH."
(unless after-change
(preview-register-change ov)))
+(defmacro preview--string (ov use-icon helpstring &optional click1)
+ "Generate a string for preview overlay OV.
+If USE-ICON is non-nil, then use it instead of the `preview-image' of
+OV. Pass HELPSTRING and CLICK1 to `preview-make-clickable'."
+ ;; Add new lines at beginning or end of string to separate the string
+ ;; only for when the overlay starts or ends on its own line.
+ `(concat
+ (or (when (eq preview-at-point-placement 'after-string)
+ (with-current-buffer (overlay-buffer ,ov)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (overlay-end ,ov))
+ (when (eolp) "\n")))))
+ "")
+ (preview-make-clickable
+ (overlay-get ,ov 'preview-map)
+ (or ,use-icon (overlay-get ,ov 'preview-image))
+ ,helpstring
+ ,click1)
+ (or (when (eq preview-at-point-placement 'before-string)
+ (with-current-buffer (overlay-buffer ,ov)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (overlay-start ,ov))
+ (when (bolp) "\n")))))
+ "")))
+
+(defun preview-disabled-strings (ov)
+ "Generate a before-string for disabled preview overlay OV."
+ (declare (obsolete 'preview--string "14.2.0"))
+ (preview--string
+ ov
+ (and (not preview-keep-stale-images) preview-icon)
+ "%s regenerates preview\n%s more options"
+ (lambda () (interactive) (preview-regenerate ov))))
+
+(defun preview-inactive-string (ov)
+ "Generate before-string for an inactive preview overlay OV.
+This is for overlays where the source text has been clicked
+visible. For efficiency reasons it is expected that the buffer
+is already selected and unnarrowed."
+ (declare (obsolete 'preview--string "14.2.0"))
+ (preview--string
+ ov
+ (and (eq preview-visibility-style 'off-point)
+ preview-icon)
+ "%s redisplays preview\n%s more options"))
+
(defun preview-toggle (ov &optional arg event)
"Toggle visibility of preview overlay OV.
-ARG can be one of the following: t displays the overlay,
-nil displays the underlying text, and `toggle' toggles.
-If EVENT is given, it indicates the window where the event
-occured, either by being a mouse event or by directly being
-the window in question. This may be used for cursor restoration
+ARG can be one of the following: t displays the overlay, nil displays
+the underlying text, and `toggle' toggles. ARG can also be `maybe-open'
+to display the underlying text only when the cursor the overlay's buffer
+is on the overlay (in this case OV is added to
+`preview-temporary-opened'). If EVENT is given, it indicates the window
+where the event occured, either by being a mouse event or by directly
+being the window in question. This may be used for cursor restoration
purposes."
- (let ((old-urgent (preview-remove-urgentization ov))
- (preview-state
- (if (if (eq arg 'toggle)
- (null (eq (overlay-get ov 'preview-state) 'active))
- arg)
- 'active
- 'inactive))
- (strings (overlay-get ov 'strings)))
- (unless (eq (overlay-get ov 'preview-state) 'disabled)
- (overlay-put ov 'preview-state preview-state)
- (if (eq preview-state 'active)
- (progn
+ (let ((old-urgent (preview-remove-urgentization ov)))
+ (unwind-protect
+ (let ((preview-state
+ (if (cond
+ ((eq arg 'toggle)
+ (null (eq (overlay-get ov 'preview-state) 'active)))
+ ((eq arg 'maybe-open)
+ (with-current-buffer (overlay-buffer ov)
+ ;; if (point) is on the overlay
+ (or (not (memq ov (overlays-at (point))))
+ (progn (push ov preview-temporary-opened)
+ nil))))
+ (t arg))
+ 'active
+ 'inactive))
+ (prop (if (consp preview-at-point-placement)
+ (car preview-at-point-placement)
+ preview-at-point-placement))
+ (strings (overlay-get ov 'strings)))
+ (unless (eq (overlay-get ov 'preview-state) 'disabled)
+ (overlay-put ov 'preview-state preview-state)
(overlay-put ov 'category 'preview-overlay)
- (if (eq (overlay-start ov) (overlay-end ov))
- (overlay-put ov 'before-string (car strings))
+ (if (eq preview-state 'active)
+ (progn
+ (if (eq (overlay-start ov) (overlay-end ov))
+ (overlay-put ov prop (car strings))
+ (unless (eq preview-visibility-style 'at-point)
+ (dolist (prop '(display keymap mouse-face help-echo))
+ (overlay-put ov prop
+ (get-text-property 0 prop
+ (car strings)))))
+ (overlay-put ov prop nil))
+ (overlay-put ov 'face nil))
(dolist (prop '(display keymap mouse-face help-echo))
- (overlay-put ov prop
- (get-text-property 0 prop (car strings))))
- (overlay-put ov 'before-string nil))
- (overlay-put ov 'face nil))
- (dolist (prop '(display keymap mouse-face help-echo))
- (overlay-put ov prop nil))
- (overlay-put ov 'face 'preview-face)
- (unless (cdr strings)
- (setcdr strings (preview-inactive-string ov)))
- (overlay-put ov 'before-string (cdr strings)))
- (if old-urgent
- (apply #'preview-add-urgentization old-urgent))))
+ (overlay-put ov prop nil))
+ (unless (eq preview-visibility-style 'at-point)
+ (overlay-put ov 'face 'preview-face))
+ (unless (cdr strings)
+ (setcdr strings
+ (preview--string
+ ov
+ (and (eq preview-visibility-style 'off-point)
+ preview-icon)
+ "%s redisplays preview\n%s more options")))
+ (overlay-put ov prop (cdr strings)))
+ (preview-overlay-updated ov)))
+ (when old-urgent
+ (apply #'preview-add-urgentization old-urgent))))
(if event
(preview-restore-position
ov
@@ -2117,23 +2252,28 @@ purposes."
event
(posn-window (event-start event))))))
+(defun preview-overlay-updated (ov)
+ "Mark preview OV as updated."
+ (with-current-buffer (window-buffer)
+ ;; Only force an update if the cursor is at point
+ (preview--update-buframe (memq ov (overlays-at (point))))))
+
(defvar preview-marker (make-marker)
"Marker for fake intangibility.")
-(defvar preview-temporary-opened nil)
-
(defvar-local preview-last-location nil
"Restored cursor position marker for reopened previews.")
(defun preview-mark-point ()
"Mark position for fake intangibility."
- (when (eq (get-char-property (point) 'preview-state) 'active)
- (unless preview-last-location
- (setq preview-last-location (make-marker)))
- (set-marker preview-last-location (point))
- (set-marker preview-marker (point))
- (preview-move-point))
- (set-marker preview-marker (point)))
+ (unless (eq preview-visibility-style 'at-point)
+ (when (eq (get-char-property (point) 'preview-state) 'active)
+ (unless preview-last-location
+ (setq preview-last-location (make-marker)))
+ (set-marker preview-last-location (point))
+ (set-marker preview-marker (point))
+ (preview-move-point))
+ (set-marker preview-marker (point))))
(defun preview-restore-position (ov window)
"Tweak position after opening/closing preview.
@@ -2177,17 +2317,19 @@ overlays not in the active window."
(current-buffer))
(- pt (marker-position preview-marker))))))
(preview-open-overlays lst)
- (while lst
- (setq lst
- (if (and
- (eq (overlay-get (car lst) 'preview-state) 'active)
- (> pt (overlay-start (car lst))))
- (overlays-at
- (setq pt (if (and distance (< distance 0))
- (overlay-start (car lst))
- (overlay-end (car lst)))))
- (cdr lst))))
- (goto-char pt)))))
+ (unless (eq preview-visibility-style 'at-point)
+ (while lst
+ (setq lst
+ (if (and
+ (eq (overlay-get (car lst) 'preview-state) 'active)
+ (> pt (overlay-start (car lst))))
+ (overlays-at
+ (setq pt (if (and distance (< distance 0))
+ (overlay-start (car lst))
+ (overlay-end (car lst)))))
+ (cdr lst))))
+ (goto-char pt)))))
+ (preview--update-buframe))
(defun preview-open-overlays (list &optional pos)
"Open all previews in LIST, optionally restricted to enclosing POS."
@@ -2202,7 +2344,8 @@ overlays not in the active window."
(defun preview--open-for-replace (beg end &rest _)
"Make `query-replace' open preview text about to be replaced."
- (preview-open-overlays (overlays-in beg end)))
+ (unless (eq preview-visibility-style 'at-point)
+ (preview-open-overlays (overlays-in beg end))))
(defcustom preview-query-replace-reveal t
"Make `query-replace' autoreveal previews."
@@ -2312,39 +2455,27 @@ active (`transient-mark-mode'), it is run through `preview-region'."
(preview-region (preview-next-border t)
(preview-next-border nil)))))
-(defun preview-disabled-string (ov)
- "Generate a before-string for disabled preview overlay OV."
- (concat (preview-make-clickable
- (overlay-get ov 'preview-map)
- preview-icon
- "\
-%s regenerates preview
-%s more options"
- (lambda () (interactive) (preview-regenerate ov)))
-;; icon on separate line only for stuff starting on its own line
- (with-current-buffer (overlay-buffer ov)
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (overlay-start ov))
- (if (bolp) "\n" ""))))))
-
(defun preview-disable (ovr)
"Change overlay behaviour of OVR after source edits."
- ;; Do not reset queued, a disabled image will be shown anyways.
- ;; More importantly, resetting queued will orphan files if a conversion
- ;; process is underway.
- ;;(overlay-put ovr 'queued nil)
-
- (preview-remove-urgentization ovr)
- (unless preview-leave-open-previews-visible
- (overlay-put ovr 'preview-image nil))
- (overlay-put ovr 'timestamp nil)
- (setcdr (overlay-get ovr 'strings) (preview-disabled-string ovr))
- (unless preview-leave-open-previews-visible
- (preview-toggle ovr))
- (overlay-put ovr 'preview-state 'disabled)
- (preview--delete-overlay-files ovr))
+ (let ((remove-image (not preview-keep-stale-images)))
+ ;; Do not reset queued, a disabled image will be shown anyways.
+ ;; More importantly, resetting queued will orphan files if a conversion
+ ;; process is underway.
+ ;;(overlay-put ovr 'queued nil)
+ (preview-remove-urgentization ovr)
+ (when remove-image
+ (overlay-put ovr 'preview-image nil))
+ (overlay-put ovr 'timestamp nil)
+ (setcdr (overlay-get ovr 'strings)
+ (preview--string
+ ovr
+ (and remove-image preview-icon)
+ "%s regenerates preview\n%s more options"
+ (lambda () (interactive) (preview-regenerate ovr))))
+ (preview-toggle ovr)
+ (when remove-image
+ (preview--delete-overlay-files ovr))
+ (overlay-put ovr 'preview-state 'disabled)))
(defun preview--delete-overlay-files (ovr)
"Delete files owned by OVR."
@@ -2573,27 +2704,6 @@ This is called as a hook when exiting Emacs."
(mapc #'preview-kill-buffer-cleanup (buffer-list))
(mapc #'preview-format-kill preview-dumped-alist))
-(defun preview-inactive-string (ov)
- "Generate before-string for an inactive preview overlay OV.
-This is for overlays where the source text has been clicked
-visible. For efficiency reasons it is expected that the buffer
-is already selected and unnarrowed."
- (concat
- (preview-make-clickable (overlay-get ov 'preview-map)
- (if preview-leave-open-previews-visible
- (overlay-get ov 'preview-image)
- preview-icon)
- "\
-%s redisplays preview
-%s more options")
-;; icon on separate line only for stuff starting on its own line
- (with-current-buffer (overlay-buffer ov)
- (save-excursion
- (save-restriction
- (widen)
- (goto-char (overlay-start ov))
- (if (bolp) "\n" ""))))))
-
(defun preview-dvi*-place-all ()
"Place all images that the dvi convertion process has created, if any.
Deletes the dvi file when finished."
@@ -2666,7 +2776,7 @@ Deletes the dvi file when finished."
'preview-dvipng-place-all #'preview-dvi*-place-all "14.2.0")
(defun preview-active-string (ov)
- "Generate before-string for active image overlay OV."
+ "Generate string for active image overlay OV."
(preview-make-clickable
(overlay-get ov 'preview-map)
(car (overlay-get ov 'preview-image))
@@ -2758,8 +2868,9 @@ to the close hook."
place-opts)
(overlay-put ov 'strings
(list (preview-active-string ov)))
- (preview-toggle ov t)
- (preview-clearout start end tempdir ov))))
+ (preview-clearout start end tempdir ov)
+ (preview-toggle ov (or (not (eq preview-visibility-style 'at-point))
+ 'maybe-open)))))
(defun preview-counter-find (begin)
"Fetch the next preceding or next preview-counters property.
@@ -3455,12 +3566,19 @@ with `preview-preprocess-function' when the latter introduces
significant modifications.")
(defcustom preview-protect-point nil
- "Temporarily open new previews that would obscure point.
-If non-nil, then any new preview whose bounds contain point is
-temporarily opened, as if the user had entered it via movement commands."
+ "Obsolete variable.
+
+Use `preview-visibility-style' instead to control how previews are
+displayed."
:group 'preview-appearance
:type 'boolean)
+(make-obsolete-variable
+ 'preview-protect-point
+ "Use `preview-visibility-style' instead to control how previews are
+displayed."
+ "14.2.0")
+
(defvar preview-locating-previews-message "locating previews...")
(defun preview-parse-messages (open-closure)
@@ -3803,22 +3921,28 @@ name(\\([^)]+\\))\\)\\|\
(funcall preview-find-end-function
region-beg)
(point)))
- (ovl (preview-place-preview
- snippet
- region-beg
- region-end
- (preview-TeX-bb box)
- (cons lcounters counters)
- tempdir
- (cdr open-data))))
- (setq close-data (nconc ovl close-data))
- (when (and preview-protect-point
- (<= region-beg point-current)
- (< point-current region-end))
- ;; Temporarily open the preview if it
- ;; would bump the point.
- (preview-toggle (car ovl))
- (push (car ovl) preview-temporary-opened)))
+ ovl)
+ (save-excursion
+ ;; Restore point to current one before
+ ;; placing preview
+ (goto-char point-current)
+ (setq ovl (preview-place-preview
+ snippet
+ region-beg
+ region-end
+ (preview-TeX-bb box)
+ (cons lcounters counters)
+ tempdir
+ (cdr open-data)))
+ (setq close-data (nconc ovl close-data))
+ (when (and
+ (eq preview-visibility-style 'always)
+ (<= region-beg point-current)
+ (< point-current region-end))
+ ;; Temporarily open the preview if it
+ ;; would bump the point.
+ (preview-toggle (car ovl))
+ (push (car ovl) preview-temporary-opened))))
(with-current-buffer run-buffer
(preview-log-error
(list 'error
@@ -4211,7 +4335,9 @@ The functions in this variable will each be called inside
`preview-region' with one argument which is a string.")
(defun preview-region (begin end)
- "Run preview on region between BEGIN and END."
+ "Run preview on region between BEGIN and END.
+
+It returns the started process."
(interactive "r")
(let ((TeX-region-extra
;; Write out counter information to region.
@@ -4426,6 +4552,77 @@ If not a regular release, the date of the last change.")
(insert "\n")))
(error nil)))
+;;; buframe specific
+
+;; Buframe functions, it will be assumed that buframe is installed so
+;; that it can be required.
+(declare-function buframe-position-right-of-overlay "ext:buframe"
+ (frame ov &optional location))
+(declare-function buframe-make-buffer "ext:buframe" (name &optional locals))
+(declare-function buframe-make "ext:buframe"
+ (frame-or-name fn-pos buffer &optional
+ parent-buffer parent-frame parameters))
+(declare-function buframe-disable "ext:buframe" (frame-or-name
+ &optional enable))
+(declare-function buframe--find "ext:buframe"
+ (&optional frame-or-name buffer parent noerror))
+
+(defun preview--update-buframe (&optional force)
+ "Show or hide a buframe popup depending on overlays at point.
+
+The frame is not updated if the `buframe' property has not changed,
+unless FORCE is non-nil."
+ (when (featurep 'buframe)
+ (let* ((frame-name "auctex-preview")
+ (buf-name " *auctex-preview-buffer*")
+ (old-frame (buframe--find frame-name nil nil t)))
+ (if-let* ((ov (cl-find-if
+ (lambda (ov) (when (overlay-get ov 'buframe) ov))
+ (overlays-at (point))))
+ (str (overlay-get ov 'buframe)))
+ (unless (and (not force)
+ old-frame
+ (pcase (frame-parameter old-frame 'auctex-preview)
+ (`(,o . ,s) (and (eq o ov) (eq s str)))))
+ (let* ((buf (buframe-make-buffer buf-name
+ (car-safe
+ (cddr (cdr-safe
+ preview-at-point-placement)))))
+ (max-image-size
+ (if (integerp max-image-size)
+ max-image-size
+ ;; Set the size max-image-size using the current frame
+ ;; since the popup frame will be small to begin with
+ (* max-image-size (frame-width)))))
+ (with-current-buffer buf
+ (let (buffer-read-only)
+ (with-silent-modifications
+ (erase-buffer)
+ (insert (propertize str
+ ;; Remove unnecessary properties
+ 'help-echo nil
+ 'keymap nil
+ 'mouse-face nil))
+ (goto-char (point-min)))))
+ (setq old-frame
+ (buframe-make
+ frame-name
+ (lambda (frame)
+ (funcall
+ (or (car-safe (cdr-safe preview-at-point-placement))
+ #'buframe-position-right-of-overlay)
+ frame
+ ov))
+ buf
+ (overlay-buffer ov)
+ (window-frame)
+ (car-safe (cdr (cdr-safe preview-at-point-placement)))))
+ (set-frame-parameter old-frame 'auctex-preview
+ (cons ov str))))
+ (when old-frame
+ (set-frame-parameter old-frame 'auctex-preview nil)
+ (buframe-disable old-frame))))))
+
;;;###autoload
(defun preview-report-bug () "Report a bug in the preview-latex package."
(interactive)
--
2.39.5 (Apple Git-154)
_______________________________________________
bug-auctex mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/bug-auctex