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.
I don't particularly mind either way, in fact what I was doing did not
particularly simplify the implementations. In the attached patch I
removed the special consideration for 'off-point so that 'off-point and
'always behave "similarly" away from point. If you test 'off-point with
preview-keep-stale-images=t, you will see the issues that I highlighted
in a normal operation with this straightforward implementation. I am
happy to leave it as is, or make any changes you suggest as long as the
preview remains open when modified which as I argued is a fundamental
feature.
The issues of 'off-point' can be avoided by setting
`preview-keep-stale-images` to nil. I added this in the documentation of
`preview-visibility-style` and we can have a value-setting function to
do this automatically.
> 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).
I think there is a broader discussion on what is the best behaviour for
the few seconds while the preview is being generated and an icon or an
old preview is being shown: to hide or show the source?
The "contract", as I see it, is that the preview should only replace the
source when it is a reflection of it (and unless the user wants to
modify the source).
With the being said, leaving the preview open during generation is a
much bigger departure from the current and old implementation, so I
suggest we leave it as is for now.
> Here are the stats for the main, secondary and tertiary monitors in my
> current setup.
> [...]
> Hope that helps!
This is gonna require more time on my part as I don't see an issue with
the output.
> 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.
I am not sure of this anymore. I think the old preview.el would close
the preview (hide the source) while generating it when
preview-leave-open-previews-visible is nil or t.
BTW, I've tried adding the custom setting code for
preview-leave-open-previews-visible, but I ran into an issue if I set
the custom variables `preview-keep-stale-images` and
`preview-visibility-style` before loading preview then their value is
overwritten once preview is loaded and
preview-leave-open-previews-visible is defined. So I don't think this is
a good option.
Best regards,
-- Al
>From e9d4ef65826ad164091d0a8efccdbac0f896e485 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