From: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: stardiviner <numbchild@gmail.com>, Org mode <emacs-orgmode@gnu.org>
Subject: Re: [PATCH v2] Inline image display as part of a new org-link-preview system
Date: Sat, 31 Aug 2024 15:37:27 -0700 [thread overview]
Message-ID: <87h6b09v4o.fsf@gmail.com> (raw)
In-Reply-To: <87jzfwljkq.fsf@localhost>
[-- Attachment #1: Type: text/plain, Size: 3046 bytes --]
v2 of the patch is attached. I incorporated most of your suggested
changes including in the commit message, except for a couple that I talk
about below.
First, here's an updated description of the proposed API:
1. You can register a previewer with each type of Org link in the
following way:
(org-link-set-parameters "file" :preview #'org-link-preview-file)
(org-link-set-parameters "https" :preview #'my/org-link-preview-web)
2. This previewer is called by Org with three parameters: an overlay,
the link path being previewed and the link element:
(funcall #'org-link-preview-file ov path link)
- To preview the link, the previewer must update the overlay ov as
needed, for example by placing an image as its `display' property.
It should not modify the buffer contents.
- The previewer must return a non-nil value to indicate preview
success. If the preview fails, it should return nil.
That's it.
>> Q: I don't follow. Right now `org-link-preview-file' is the :preview
>> org-link-parameter of file links and attachments. Could you explain how
>> this indirection should work instead?
>
> What I meant is that org-attach will define a custom
> `org-attach-preview-file' function that will compute the filename, and
> then internally call `org-link-preview-file'. Then, attachment: link
> will have :preview set to `org-attach-preview-file'. This way, you will
> not need to require org-attach from ol and ol from org-attach
> simultaneously. (no cyclic dependencies, please)
Done.
> Then, the commit message is not accurate.
Fixed.
> I know that this is a copy-paste, but
> we may utilize 'org-image-overlay
> + `org-find-overlays' here.
I decided not to do this since the logic in
org-link-preview--remove-overlay is different: it checks for the
existence of overlays in the maintained list org-link-preview-overlays
instead of checking for overlays in the buffer.
> It implies that every :preview function _must_ put an image as 'display
> property. If it does not, we will run into errors. But should it?
Fixed.
> Also, when if preview is asynchronous, and we run this function when the
> image is not yet assigned to the overlay?
> In asynchronous previews, some overlays may be deleted already. We
> should be careful with this.
No changes here. When the async callback runs, the state of the buffer
can have changed. There's nothing Org can do about that. The callback
has access to the overlay, so it will have to use a construct like
(and (overlay-buffer ov) (add-preview-to link))
If the preview fails, there will be an undecorated overlay hanging
around, I'm not sure what to do about it. The async function can run
`(delete-overlay ov)', but that breaks the abstraction boundary we're
trying to create. (It will also have to remove the overlay from
`org-link-preview-overlays'.)
It can't run `org-link-preview-clear' on the link, since the link
element's bounds might be invalid. I'm assuming that the :begin and
:end property of the link are integers and not markers.
Karthik
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-org-link-Move-inline-image-display-to-org-link.patch --]
[-- Type: text/x-patch, Size: 45064 bytes --]
From d60d5bef78841d548cfbcdca3a461cb9c52e4314 Mon Sep 17 00:00:00 2001
From: Karthik Chikmagalur <karthikchikmagalur@gmail.com>
Date: Fri, 23 Aug 2024 15:46:53 -0700
Subject: [PATCH] org-link: Move inline image display to org-link
Make inline image previews a part of a more universal org-link
preview feature. Each link type can now be previewed differently
based on a new link parameter.
* lisp/ol.el (org-link-parameters, org-link-preview-overlays,
org-link-preview--get-overlays, org-link-preview--remove-overlay,
org-link-previeworg-link-preview-region, org-link-preview-clear,
org-link-preview-file): Add new commands `org-link-preview',
`org-link-preview-region' and `org-link-preview-clear' for
creating link previews for any kind of link. Add new org-link
parameter `:preview' for specifying how a link type should be
previewed. File links and attachments are previewed using inline
image previews as before.
* testing/lisp/test-org-fold.el: Use `org-link-preview'.
* lisp/org.el (org-toggle-inline-images,
org-toggle-inline-images-command, org-display-inline-images,
org--inline-image-overlays, org-inline-image-overlays,
org-redisplay-inline-images, org-image-align,
org-display-inline-remove-overlay, org-remove-inline-images):
Obsolete and move `org-toggle-inline-images',
`org-display-inline-images' and `org-redisplay-inline-images' to
org-compat. These are obsoleted by `org-link-preview' and
`org-link-preview-region'. Remove
`org-toggle-inline-images-command'. Move the other internal
functions to org-link.
* lisp/org-plot.el (org-plot/redisplay-img-in-buffer): Modify to
use `org-link-preview'.
* lisp/org-keys.el: Bind `C-c C-x C-v' to new command
`org-link-preview', which has the same prefix arg behaviors as
`org-latex-preview'. In addition to these, it supports numeric
prefix args 1 and 11 to preview links with descriptions at
point/region (with 1) and across the buffer (with 11).
* lisp/org-cycle.el (org-cycle-display-inline-images): Use
`org-link-preview'.
* lisp/org-compat.el (org-display-inline-remove-overlay,
org--inline-image-overlays, org-remove-inline-images,
org-inline-image-overlays, org-display-inline-images,
org-toggle-inline-images):
* lisp/org-attach.el: Add new `:preview' link parameter for links
of type "attachment".
---
lisp/ol.el | 280 ++++++++++++++++++++++++++++++++-
lisp/org-attach.el | 10 +-
lisp/org-compat.el | 189 +++++++++++++++++++++++
lisp/org-cycle.el | 10 +-
lisp/org-keys.el | 4 +-
lisp/org-plot.el | 2 +-
lisp/org.el | 283 +---------------------------------
testing/lisp/test-org-fold.el | 4 +-
8 files changed, 489 insertions(+), 293 deletions(-)
diff --git a/lisp/ol.el b/lisp/ol.el
index 52ea62d69..baed73daa 100644
--- a/lisp/ol.el
+++ b/lisp/ol.el
@@ -82,6 +82,13 @@ (declare-function org-src-source-buffer "org-src" ())
(declare-function org-src-source-type "org-src" ())
(declare-function org-time-stamp-format "org" (&optional long inactive))
(declare-function outline-next-heading "outline" ())
+(declare-function image-flush "image" (spec &optional frame))
+(declare-function org-entry-end-position "org" ())
+(declare-function org-element-contents-begin "org-element" (node))
+(declare-function org-attach-expand "org-attach" (file))
+(declare-function org-display-inline-image--width "org" (link))
+(declare-function org-image--align "org" (link))
+(declare-function org--create-inline-image "org" (file width))
\f
;;; Customization
@@ -171,6 +178,16 @@ (defcustom org-link-parameters nil
The default face is `org-link'.
+`:preview'
+
+ Function to run to generate an in-buffer preview for the link. It
+ must accept three arguments:
+ - an overlay placed from the start to the end of the link.
+ - the link path, as a string.
+ - the link element
+
+ This function must return a non-nil value to indicate success.
+
`:help-echo'
String or function used as a value for the `help-echo' text
@@ -649,6 +666,13 @@ (defvar org-link--insert-history nil
(defvar org-link--search-failed nil
"Non-nil when last link search failed.")
+(defvar-local org-link-preview-overlays nil)
+;; Preserve when switching modes or when restarting Org.
+;; If we clear the overlay list and later enable Or mode, the existing
+;; image overlays will never be cleared by `org-link-preview'
+;; and `org-link-preview-clear'.
+(put 'org-link-preview-overlays 'permanent-local t)
+
\f
;;; Internal Functions
@@ -881,6 +905,30 @@ (defun org-link--file-link-to-here ()
(setq desc search-desc))))
(cons link desc)))
+(defun org-link-preview--get-overlays (&optional beg end)
+ "Return link preview overlays between BEG and END."
+ (let* ((beg (or beg (point-min)))
+ (end (or end (point-max)))
+ (overlays (overlays-in beg end))
+ result)
+ (dolist (ov overlays result)
+ (when (memq ov org-link-preview-overlays)
+ (push ov result)))))
+
+(defun org-link-preview--remove-overlay (ov after _beg _end &optional _len)
+ "Remove link-preview overlay OV if a corresponding region is modified.
+
+AFTER is true when this function is called post-change."
+ (when (and ov after)
+ (setq org-link-preview-overlays (delete ov org-link-preview-overlays))
+ ;; Clear image from cache to avoid image not updating upon
+ ;; changing on disk. See Emacs bug#59902.
+ (when-let* (((overlay-get ov 'org-image-overlay))
+ (disp (overlay-get ov 'display))
+ ((imagep disp)))
+ (image-flush disp))
+ (delete-overlay ov)))
+
\f
;;; Public API
@@ -1573,6 +1621,194 @@ (defun org-link-add-angle-brackets (s)
(unless (equal (substring s -1) ">") (setq s (concat s ">")))
s)
+;;;###autoload
+(defun org-link-preview (&optional arg beg end)
+ "Toggle display of link previews in the buffer.
+
+When region BEG..END is active, preview links in the
+region.
+
+When point is at a link, display a preview for that link only.
+Otherwise, display previews for links in current entry.
+
+With numeric prefix ARG 1, preview links with description as
+well.
+
+With prefix ARG `\\[universal-argument]', clear link previews at
+point or in the current entry.
+
+With prefix ARG `\\[universal-argument] \\[universal-argument]',
+ display link previews in the accessible portion of the
+ buffer. With numeric prefix ARG 11, do the same, but include
+ links with descriptions.
+
+With prefix ARG `\\[universal-argument] \\[universal-argument] \\[universal-argument]',
+hide all link previews in the accessible portion of the buffer.
+
+This command is designed for interactive use. From Elisp, you can
+also use `org-link-preview-region'."
+ (interactive (cons current-prefix-arg
+ (when (use-region-p)
+ (list (region-beginning) (region-end)))))
+ (let* ((include-linked
+ (cond
+ ((member arg '(nil (4) (16)) ) nil)
+ ((member arg '(1 11)) 'include-linked)
+ (t 'include-linked)))
+ (interactive? (called-interactively-p 'any))
+ (toggle-previews
+ (lambda (&optional beg end scope remove)
+ (let* ((beg (or beg (point-min)))
+ (end (or end (point-max)))
+ (old (org-link-preview--get-overlays beg end))
+ (scope (or scope (format "%d:%d" beg end))))
+ (if remove
+ (progn
+ (org-link-preview-clear beg end)
+ (when interactive?
+ (message
+ "[%s] Inline link previews turned off (removed %d images)"
+ scope (length old))))
+ (org-link-preview-region include-linked t beg end)
+ (when interactive?
+ (let ((new (org-link-preview--get-overlays beg end)))
+ (message
+ (if new
+ (format "[%s] %d images displayed inline %s"
+ scope (length new)
+ (if include-linked "(including images with description)"
+ ""))
+ (format "[%s] No images to display inline" scope))))))))))
+ (cond
+ ;; Region selected :: display previews in region.
+ ((and beg end)
+ (funcall toggle-previews beg end "region"
+ (and (equal arg '(4)) 'remove)))
+ ;; C-u argument: clear image at point or in entry
+ ((equal arg '(4))
+ (if (get-char-property (point) 'org-image-overlay)
+ ;; clear link preview at point
+ (when-let ((context (org-element-context))
+ ((org-element-type-p context 'link)))
+ (funcall toggle-previews
+ (org-element-begin context)
+ (org-element-end context)
+ "preview at point" 'remove))
+ ;; Clear link previews in entry
+ (funcall toggle-previews
+ (if (org-before-first-heading-p) (point-min)
+ (save-excursion
+ (org-with-limited-levels (org-back-to-heading t) (point))))
+ (org-with-limited-levels (org-entry-end-position))
+ "current section" 'remove)))
+ ;; C-u C-u or C-11 argument :: display images in the whole buffer.
+ ((member arg '(11 (16))) (funcall toggle-previews nil nil "buffer"))
+ ;; C-u C-u C-u argument :: unconditionally hide images in the buffer.
+ ((equal arg '(64)) (funcall toggle-previews nil nil "buffer" 'remove))
+ ;; Argument nil or 1, no region selected :: display images in
+ ;; current section or image link at point.
+ ((and (member arg '(nil 1)) (null beg) (null end))
+ (let ((context (org-element-context)))
+ ;; toggle display of inline image link at point.
+ (if (org-element-type-p context 'link)
+ (let* ((ov (cdr-safe (get-char-property-and-overlay
+ (point) 'org-image-overlay)))
+ (remove? (and ov (memq ov org-link-preview-overlays)
+ 'remove)))
+ (funcall toggle-previews
+ (org-element-begin context)
+ (org-element-end context)
+ "image at point" remove?))
+ (let ((beg (if (org-before-first-heading-p) (point-min)
+ (save-excursion
+ (org-with-limited-levels (org-back-to-heading t) (point)))))
+ (end (org-with-limited-levels (org-entry-end-position))))
+ (funcall toggle-previews beg end "current section")))))
+ ;; Any other non-nil argument.
+ ((not (null arg)) (funcall toggle-previews beg end "region")))))
+
+(defun org-link-preview-region (&optional include-linked refresh beg end)
+ "Display link previews.
+
+A previewable link type is one that has a `:preview' link
+parameter, see `org-link-parameters'.
+
+By default, a file link or attachment is previewable if it
+follows either of these conventions:
+
+ 1. Its path is a file with an extension matching return value
+ from `image-file-name-regexp' and it has no contents.
+
+ 2. Its description consists in a single link of the previous
+ type. In this case, that link must be a well-formed plain
+ or angle link, i.e., it must have an explicit \"file\" or
+ \"attachment\" type.
+
+File links are equipped with the keymap `image-map'.
+
+When optional argument INCLUDE-LINKED is non-nil, links with a
+text description part will also be inlined. This can be nice for
+a quick look at those images, but it does not reflect what
+exported files will look like.
+
+When optional argument REFRESH is non-nil, refresh existing
+images between BEG and END. This will create new image displays
+only if necessary.
+
+BEG and END define the considered part. They default to the
+buffer boundaries with possible narrowing."
+ (interactive "P")
+ (when (display-graphic-p)
+ (when refresh (org-link-preview-clear beg end))
+ (when (fboundp 'clear-image-cache) (clear-image-cache)))
+ (org-with-point-at (or beg (point-min))
+ (let ((case-fold-search t))
+ (while (re-search-forward org-link-any-re end t)
+ (when-let* ((link (org-element-lineage
+ (save-match-data (org-element-context))
+ 'link t))
+ (linktype (org-element-property :type link))
+ (preview-func (org-link-get-parameter linktype :preview))
+ (path (and (or include-linked
+ (not (org-element-contents-begin link)))
+ (org-element-property :path link))))
+ ;; Create an overlay to hold the preview
+ (let ((ov (make-overlay
+ (org-element-begin link)
+ (progn
+ (goto-char
+ (org-element-end link))
+ (unless (eolp) (skip-chars-backward " \t"))
+ (point)))))
+ ;; TODO: Change this overlay property to `org-link-preview' everywhere.
+ (overlay-put ov 'org-image-overlay t)
+ (overlay-put ov 'modification-hooks
+ (list 'org-link-preview--remove-overlay))
+ ;; call preview function for link type
+ (if (funcall preview-func ov path link)
+ (when (overlay-buffer ov)
+ (push ov org-link-preview-overlays))
+ ;; Preview was unsuccessful, delete overlay
+ (delete-overlay ov))))))))
+
+(defun org-link-preview-clear (&optional beg end)
+ "Clear link previews in region BEG to END."
+ (interactive (and (use-region-p) (list (region-beginning) (region-end))))
+ (let* ((beg (or beg (point-min)))
+ (end (or end (point-max)))
+ (overlays (overlays-in beg end)))
+ (dolist (ov overlays)
+ (when (memq ov org-link-preview-overlays)
+ (when-let ((image (overlay-get ov 'display))
+ ((imagep image)))
+ (image-flush image))
+ (setq org-link-preview-overlays (delq ov org-link-preview-overlays))
+ (delete-overlay ov)))
+ ;; Clear removed overlays.
+ (dolist (ov org-link-preview-overlays)
+ (unless (overlay-buffer ov)
+ (setq org-link-preview-overlays (delq ov org-link-preview-overlays))))))
+
\f
;;; Built-in link types
@@ -1595,7 +1831,49 @@ (defun org-link--open-elisp (path _)
(org-link-set-parameters "elisp" :follow #'org-link--open-elisp)
;;;; "file" link type
-(org-link-set-parameters "file" :complete #'org-link-complete-file)
+(org-link-set-parameters "file"
+ :complete #'org-link-complete-file
+ :preview #'org-link-preview-file)
+
+(defun org-link-preview-file (ov path link)
+ "Display image file PATH in overlay OV for LINK.
+
+LINK is the Org element being previewed.
+
+Equip each image with the keymap `image-map'.
+
+This is intended to be used as the `:preview' link property of
+file links, see `org-link-parameters'."
+ (if (not (display-graphic-p))
+ (prog1 nil
+ (message "Your Emacs does not support displaying images!"))
+ (when-let* ((file-full (expand-file-name path))
+ (file (substitute-in-file-name file-full))
+ ((string-match-p (image-file-name-regexp) file))
+ ((file-exists-p file)))
+ (let* ((width (org-display-inline-image--width link))
+ (align (org-image--align link))
+ (image (org--create-inline-image file width)))
+ (when image ; Add image to overlay
+ ;; See bug#59902. We cannot rely
+ ;; on Emacs to update image if the file
+ ;; has changed.
+ (image-flush image)
+ (overlay-put ov 'display image)
+ (overlay-put ov 'face 'default)
+ (overlay-put ov 'org-image-overlay t)
+ (when (boundp 'image-map)
+ (overlay-put ov 'keymap image-map))
+ (when align
+ (overlay-put
+ ov 'before-string
+ (propertize
+ " " 'face 'default
+ 'display
+ (pcase align
+ ("center" `(space :align-to (- center (0.5 . ,image))))
+ ("right" `(space :align-to (- right ,image)))))))
+ t)))))
;;;; "help" link type
(defun org-link--open-help (path _)
diff --git a/lisp/org-attach.el b/lisp/org-attach.el
index 7a03d170e..4b0887fcd 100644
--- a/lisp/org-attach.el
+++ b/lisp/org-attach.el
@@ -797,9 +797,17 @@ (defun org-attach-follow (file arg)
See `org-open-file' for details about ARG."
(org-link-open-as-file (org-attach-expand file) arg))
+(defun org-attach-preview-file (ov path link)
+ "Preview attachment with PATH in overlay OV.
+
+LINK is the Org link element being previewed."
+ (org-link-preview-file
+ ov (org-attach-expand path) link))
+
(org-link-set-parameters "attachment"
:follow #'org-attach-follow
- :complete #'org-attach-complete-link)
+ :complete #'org-attach-complete-link
+ :preview #'org-attach-preview-file)
(defun org-attach-complete-link ()
"Advise the user with the available files in the attachment directory."
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index d843216f3..242b46a86 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -783,6 +783,195 @@ (defun org-add-link-type (type &optional follow export)
(make-obsolete 'org-add-link-type "use `org-link-set-parameters' instead." "9.0")
+(declare-function org-link-preview--remove-overlay "ol")
+(declare-function org-link-preview--get-overlays "ol")
+(declare-function org-link-preview-clear "ol")
+(declare-function org-link-preview--remove-overlay "ol")
+
+(define-obsolete-function-alias 'org-display-inline-remove-overlay
+ 'org-link-preview--remove-overlay "9.8")
+(define-obsolete-function-alias 'org--inline-image-overlays
+ 'org-link-preview--get-overlays "9.8")
+(define-obsolete-function-alias 'org-remove-inline-images
+ 'org-link-preview-clear "9.8")
+(define-obsolete-variable-alias 'org-inline-image-overlays
+ 'org-link-preview-overlays "9.8")
+(defvar org-link-preview-overlays)
+(defvar org-link-abbrev-alist-local)
+(defvar org-link-abbrev-alist)
+(defvar org-link-angle-re)
+(defvar org-link-plain-re)
+(declare-function org-attach-expand "org-attach")
+(declare-function org-display-inline-image--width "org")
+(declare-function org-image--align "org")
+(declare-function org--create-inline-image "org")
+
+(make-obsolete 'org-display-inline-images
+ 'org-link-preview-region "9.8")
+;; FIXME: Unused; obsoleted; to be removed
+(defun org-display-inline-images (&optional include-linked refresh beg end)
+ "Display inline images.
+
+An inline image is a link which follows either of these
+conventions:
+
+ 1. Its path is a file with an extension matching return value
+ from `image-file-name-regexp' and it has no contents.
+
+ 2. Its description consists in a single link of the previous
+ type. In this case, that link must be a well-formed plain
+ or angle link, i.e., it must have an explicit \"file\" or
+ \"attachment\" type.
+
+Equip each image with the key-map `image-map'.
+
+When optional argument INCLUDE-LINKED is non-nil, also links with
+a text description part will be inlined. This can be nice for
+a quick look at those images, but it does not reflect what
+exported files will look like.
+
+When optional argument REFRESH is non-nil, refresh existing
+images between BEG and END. This will create new image displays
+only if necessary.
+
+BEG and END define the considered part. They default to the
+buffer boundaries with possible narrowing."
+ (interactive "P")
+ (when (display-graphic-p)
+ (when refresh
+ (org-link-preview-clear beg end)
+ (when (fboundp 'clear-image-cache) (clear-image-cache)))
+ (let ((end (or end (point-max))))
+ (org-with-point-at (or beg (point-min))
+ (let* ((case-fold-search t)
+ (file-extension-re (image-file-name-regexp))
+ (link-abbrevs (mapcar #'car
+ (append org-link-abbrev-alist-local
+ org-link-abbrev-alist)))
+ ;; Check absolute, relative file names and explicit
+ ;; "file:" links. Also check link abbreviations since
+ ;; some might expand to "file" links.
+ (file-types-re
+ (format "\\[\\[\\(?:file%s:\\|attachment:\\|[./~]\\)\\|\\]\\[\\(<?\\(?:file\\|attachment\\):\\)"
+ (if (not link-abbrevs) ""
+ (concat "\\|" (regexp-opt link-abbrevs))))))
+ (while (re-search-forward file-types-re end t)
+ (let* ((link (org-element-lineage
+ (save-match-data (org-element-context))
+ 'link t))
+ (linktype (org-element-property :type link))
+ (inner-start (match-beginning 1))
+ (path
+ (cond
+ ;; No link at point; no inline image.
+ ((not link) nil)
+ ;; File link without a description. Also handle
+ ;; INCLUDE-LINKED here since it should have
+ ;; precedence over the next case. I.e., if link
+ ;; contains filenames in both the path and the
+ ;; description, prioritize the path only when
+ ;; INCLUDE-LINKED is non-nil.
+ ((or (not (org-element-contents-begin link))
+ include-linked)
+ (and (or (equal "file" linktype)
+ (equal "attachment" linktype))
+ (org-element-property :path link)))
+ ;; Link with a description. Check if description
+ ;; is a filename. Even if Org doesn't have syntax
+ ;; for those -- clickable image -- constructs, fake
+ ;; them, as in `org-export-insert-image-links'.
+ ((not inner-start) nil)
+ (t
+ (org-with-point-at inner-start
+ (and (looking-at
+ (if (char-equal ?< (char-after inner-start))
+ org-link-angle-re
+ org-link-plain-re))
+ ;; File name must fill the whole
+ ;; description.
+ (= (org-element-contents-end link)
+ (match-end 0))
+ (progn
+ (setq linktype (match-string 1))
+ (match-string 2))))))))
+ (when (and path (string-match-p file-extension-re path))
+ (let ((file (if (equal "attachment" linktype)
+ (progn
+ (require 'org-attach)
+ (ignore-errors (org-attach-expand path)))
+ (expand-file-name path))))
+ ;; Expand environment variables.
+ (when file (setq file (substitute-in-file-name file)))
+ (when (and file (file-exists-p file))
+ (let ((width (org-display-inline-image--width link))
+ (align (org-image--align link))
+ (old (get-char-property-and-overlay
+ (org-element-begin link)
+ 'org-image-overlay)))
+ (if (and (car-safe old) refresh)
+ (image-flush (overlay-get (cdr old) 'display))
+ (let ((image (org--create-inline-image file width)))
+ (when image
+ (let ((ov (make-overlay
+ (org-element-begin link)
+ (progn
+ (goto-char
+ (org-element-end link))
+ (unless (eolp) (skip-chars-backward " \t"))
+ (point)))))
+ ;; See bug#59902. We cannot rely
+ ;; on Emacs to update image if the file
+ ;; has changed.
+ (image-flush image)
+ (overlay-put ov 'display image)
+ (overlay-put ov 'face 'default)
+ (overlay-put ov 'org-image-overlay t)
+ (overlay-put
+ ov 'modification-hooks
+ (list 'org-link-preview--remove-overlay))
+ (when (boundp 'image-map)
+ (overlay-put ov 'keymap image-map))
+ (when align
+ (overlay-put
+ ov 'before-string
+ (propertize
+ " " 'face 'default
+ 'display
+ (pcase align
+ ("center" `(space :align-to (- center (0.5 . ,image))))
+ ("right" `(space :align-to (- right ,image)))))))
+ (push ov org-inline-image-overlays))))))))))))))))
+
+(make-obsolete 'org-toggle-inline-images
+ 'org-link-preview "9.8")
+;; FIXME: Unused; obsoleted; to be removed
+(defun org-toggle-inline-images (&optional include-linked beg end)
+ "Toggle the display of inline images.
+INCLUDE-LINKED is passed to `org-display-inline-images'."
+ (interactive "P")
+ (if (org-link-preview--get-overlays beg end)
+ (progn
+ (org-link-preview-clear beg end)
+ (when (called-interactively-p 'interactive)
+ (message "Inline image display turned off")))
+ (org-display-inline-images include-linked nil beg end)
+ (when (called-interactively-p 'interactive)
+ (let ((new (org-link-preview--get-overlays beg end)))
+ (message (if new
+ (format "%d images displayed inline"
+ (length new))
+ "No images to display inline"))))))
+
+(make-obsolete 'org-redisplay-inline-images
+ 'org-link-preview "9.8")
+;; FIXME: Unused; obsoleted; to be removed
+(defun org-redisplay-inline-images ()
+ "Assure display of inline images and refresh them."
+ (interactive)
+ (org-toggle-inline-images)
+ (unless org-link-preview-overlays
+ (org-toggle-inline-images)))
+
;;;; Functions unused in Org core.
(defun org-table-recognize-table.el ()
"If there is a table.el table nearby, recognize it and move into it."
diff --git a/lisp/org-cycle.el b/lisp/org-cycle.el
index 8a39bdb8c..1a1c916bd 100644
--- a/lisp/org-cycle.el
+++ b/lisp/org-cycle.el
@@ -40,14 +40,14 @@ (declare-function org-element-property "org-element-ast" (property node))
(declare-function org-element-post-affiliated "org-element" (node))
(declare-function org-element-lineage "org-element-ast" (datum &optional types with-self))
(declare-function org-element-at-point "org-element" (&optional pom cached-only))
-(declare-function org-display-inline-images "org" (&optional include-linked refresh beg end))
+(declare-function org-link-preview-region "ol" (&optional include-linked refresh beg end))
(declare-function org-get-tags "org" (&optional pos local fontify))
(declare-function org-subtree-end-visible-p "org" ())
(declare-function org-narrow-to-subtree "org" (&optional element))
(declare-function org-next-visible-heading "org" (arg))
(declare-function org-at-property-p "org" ())
(declare-function org-re-property "org" (property &optional literal allow-null value))
-(declare-function org-remove-inline-images "org" (&optional beg end))
+(declare-function org-link-preview-clear "ol" (&optional beg end))
(declare-function org-item-beginning-re "org" ())
(declare-function org-at-heading-p "org" (&optional invisible-not-ok))
(declare-function org-at-item-p "org" ())
@@ -817,19 +817,19 @@ (defun org-cycle-display-inline-images (state)
;; If has nested headlines, beg,end only from parent headline
;; to first child headline which reference to upper
;; let-binding `org-next-visible-heading'.
- (org-display-inline-images
+ (org-link-preview-region
nil nil
(point-min) (progn (org-next-visible-heading 1) (point)))))
('subtree
(org-with-wide-buffer
(org-narrow-to-subtree)
;; If has nested headlines, also inline display images under all sub-headlines.
- (org-display-inline-images nil nil (point-min) (point-max))))
+ (org-link-preview-region nil nil (point-min) (point-max))))
('folded
(org-with-wide-buffer
(org-narrow-to-subtree)
(if (numberp (point-max))
- (org-remove-inline-images (point-min) (point-max))
+ (org-link-preview-clear (point-min) (point-max))
(ignore)))))))
(provide 'org-cycle)
diff --git a/lisp/org-keys.el b/lisp/org-keys.el
index 1daedaae8..77cbe5c0f 100644
--- a/lisp/org-keys.el
+++ b/lisp/org-keys.el
@@ -218,7 +218,7 @@ (declare-function org-toggle-checkbox "org" (&optional toggle-presence))
(declare-function org-toggle-radio-button "org" (&optional arg))
(declare-function org-toggle-comment "org" ())
(declare-function org-toggle-fixed-width "org" ())
-(declare-function org-toggle-inline-images-command "org" (&optional arg beg end))
+(declare-function org-link-preview "ol" (&optional arg beg end))
(declare-function org-latex-preview "org" (&optional arg))
(declare-function org-toggle-narrow-to-subtree "org" ())
(declare-function org-toggle-ordered-property "org" ())
@@ -618,7 +618,7 @@ (org-defkey org-mode-map (kbd "C-c C-x C-d") #'org-clock-display)
(org-defkey org-mode-map (kbd "C-c C-x x") #'org-dynamic-block-insert-dblock)
(org-defkey org-mode-map (kbd "C-c C-x C-u") #'org-dblock-update)
(org-defkey org-mode-map (kbd "C-c C-x C-l") #'org-latex-preview)
-(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images-command)
+(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-link-preview)
(org-defkey org-mode-map (kbd "C-c C-x C-M-v") #'org-redisplay-inline-images)
(org-defkey org-mode-map (kbd "C-c C-x \\") #'org-toggle-pretty-entities)
(org-defkey org-mode-map (kbd "C-c C-x C-b") #'org-toggle-checkbox)
diff --git a/lisp/org-plot.el b/lisp/org-plot.el
index b045344f0..836cfaffc 100644
--- a/lisp/org-plot.el
+++ b/lisp/org-plot.el
@@ -633,7 +633,7 @@ (defun org-plot/gnuplot-script (table data-file num-cols params &optional prefac
(defun org-plot/redisplay-img-in-buffer (img-file)
"Find any overlays for IMG-FILE in the current Org buffer, and refresh them."
- (dolist (img-overlay org-inline-image-overlays)
+ (dolist (img-overlay org-link-preview-overlays)
(when (string= img-file (plist-get (cdr (overlay-get img-overlay 'display)) :file))
(when (and (file-exists-p img-file)
(fboundp 'image-flush))
diff --git a/lisp/org.el b/lisp/org.el
index d5c1dcb35..091a09344 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -5079,7 +5079,7 @@ (define-derived-mode org-mode outline-mode "Org"
;; modifications to make cache updates work reliably.
(org-unmodified
(when org-startup-with-beamer-mode (org-beamer-mode))
- (when org-startup-with-inline-images (org-display-inline-images))
+ (when org-startup-with-inline-images (org-link-preview '(16)))
(when org-startup-with-latex-preview (org-latex-preview '(16)))
(unless org-inhibit-startup-visibility-stuff (org-cycle-set-startup-visibility))
(when org-startup-truncated (setq truncate-lines t))
@@ -16651,126 +16651,6 @@ (defun org-normalize-color (value)
\f
;; Image display
-(defvar-local org-inline-image-overlays nil)
-;; Preserve when switching modes or when restarting Org.
-;; If we clear the overlay list and later enable Or mode, the existing
-;; image overlays will never be cleared by `org-toggle-inline-images'
-;; and `org-toggle-inline-images-command'.
-(put 'org-inline-image-overlays 'permanent-local t)
-
-(defun org--inline-image-overlays (&optional beg end)
- "Return image overlays between BEG and END."
- (let* ((beg (or beg (point-min)))
- (end (or end (point-max)))
- (overlays (overlays-in beg end))
- result)
- (dolist (ov overlays result)
- (when (memq ov org-inline-image-overlays)
- (push ov result)))))
-
-(defun org-toggle-inline-images-command (&optional arg beg end)
- "Toggle display of inline images without description at point.
-
-When point is at an image link, toggle displaying that image.
-Otherwise, toggle displaying images in current entry.
-
-When region BEG..END is active, toggle displaying images in the
-region.
-
-With numeric prefix ARG 1, display images with description as well.
-
-With prefix ARG `\\[universal-argument]', toggle displaying images in
-the accessible portion of the buffer. With numeric prefix ARG 11, do
-the same, but include images with description.
-
-With prefix ARG `\\[universal-argument] \\[universal-argument]', hide
-all the images in accessible portion of the buffer.
-
-This command is designed for interactive use. From Elisp, you can
-also use `org-toggle-inline-images'."
- (interactive (cons current-prefix-arg
- (when (use-region-p)
- (list (region-beginning) (region-end)))))
- (let* ((include-linked
- (cond
- ((member arg '(nil (4) (16)) ) nil)
- ((member arg '(1 11)) 'include-linked)
- (t 'include-linked)))
- (interactive? (called-interactively-p 'any))
- (toggle-images
- (lambda (&optional beg end scope force-remove)
- (let* ((beg (or beg (point-min)))
- (end (or end (point-max)))
- (old (org--inline-image-overlays beg end))
- (scope (or scope (format "%d:%d" beg end))))
- (if (or old force-remove)
- (progn
- (org-remove-inline-images beg end)
- (when interactive?
- (message
- "[%s] Inline image display turned off (removed %d images)"
- scope (length old))))
- (org-display-inline-images include-linked t beg end)
- (when interactive?
- (let ((new (org--inline-image-overlays beg end)))
- (message
- (if new
- (format "[%s] %d images displayed inline %s"
- scope (length new)
- (if include-linked "(including images with description)"
- ""))
- (format "[%s] No images to display inline" scope))))))))))
- (cond
- ((not (display-graphic-p))
- (message "Your Emacs does not support displaying images!"))
- ;; Region selected :: toggle images in region.
- ((and beg end) (funcall toggle-images beg end "region"))
- ;; C-u or C-11 argument :: toggle images in the whole buffer.
- ((member arg '(11 (4))) (funcall toggle-images nil nil "buffer"))
- ;; C-u C-u argument :: unconditionally hide images in the buffer.
- ((equal arg '(16)) (funcall toggle-images nil nil "buffer" 'remove))
- ;; Argument nil or 1, no region selected :: toggle (display or hide
- ;; dwim) images in current section or image link at point.
- ((and (member arg '(nil 1)) (null beg) (null end))
- (let ((context (org-element-context)))
- ;; toggle display of inline image link at point.
- (if (org-element-type-p context 'link)
- (funcall toggle-images
- (org-element-begin context)
- (org-element-end context)
- "image at point")
- (let ((beg (if (org-before-first-heading-p) (point-min)
- (save-excursion
- (org-with-limited-levels (org-back-to-heading t) (point)))))
- (end (org-with-limited-levels (org-entry-end-position))))
- (funcall toggle-images beg end "current section")))))
- ;; Any other non-nil argument.
- ((not (null arg)) (funcall toggle-images beg end "region")))))
-
-(defun org-toggle-inline-images (&optional include-linked beg end)
- "Toggle the display of inline images.
-INCLUDE-LINKED is passed to `org-display-inline-images'."
- (interactive "P")
- (if (org--inline-image-overlays beg end)
- (progn
- (org-remove-inline-images beg end)
- (when (called-interactively-p 'interactive)
- (message "Inline image display turned off")))
- (org-display-inline-images include-linked nil beg end)
- (when (called-interactively-p 'interactive)
- (let ((new (org--inline-image-overlays beg end)))
- (message (if new
- (format "%d images displayed inline"
- (length new))
- "No images to display inline"))))))
-
-(defun org-redisplay-inline-images ()
- "Assure display of inline images and refresh them."
- (interactive)
- (org-toggle-inline-images)
- (unless org-inline-image-overlays
- (org-toggle-inline-images)))
-
;; For without-x builds.
(declare-function image-flush "image" (spec &optional frame))
@@ -16793,7 +16673,7 @@ (defcustom org-display-remote-inline-images 'skip
:safe #'symbolp)
(defcustom org-image-align 'left
- "How to align images previewed using `org-display-inline-images'.
+ "How to align images previewed using `org-link-preview-region'.
Only stand-alone image links are affected by this setting. These
are links without surrounding text.
@@ -16850,139 +16730,6 @@ (defun org--create-inline-image (file width)
org-image-max-width)))
:scale 1))))
-(defun org-display-inline-images (&optional include-linked refresh beg end)
- "Display inline images.
-
-An inline image is a link which follows either of these
-conventions:
-
- 1. Its path is a file with an extension matching return value
- from `image-file-name-regexp' and it has no contents.
-
- 2. Its description consists in a single link of the previous
- type. In this case, that link must be a well-formed plain
- or angle link, i.e., it must have an explicit \"file\" or
- \"attachment\" type.
-
-Equip each image with the key-map `image-map'.
-
-When optional argument INCLUDE-LINKED is non-nil, also links with
-a text description part will be inlined. This can be nice for
-a quick look at those images, but it does not reflect what
-exported files will look like.
-
-When optional argument REFRESH is non-nil, refresh existing
-images between BEG and END. This will create new image displays
-only if necessary.
-
-BEG and END define the considered part. They default to the
-buffer boundaries with possible narrowing."
- (interactive "P")
- (when (display-graphic-p)
- (when refresh
- (org-remove-inline-images beg end)
- (when (fboundp 'clear-image-cache) (clear-image-cache)))
- (let ((end (or end (point-max))))
- (org-with-point-at (or beg (point-min))
- (let* ((case-fold-search t)
- (file-extension-re (image-file-name-regexp))
- (link-abbrevs (mapcar #'car
- (append org-link-abbrev-alist-local
- org-link-abbrev-alist)))
- ;; Check absolute, relative file names and explicit
- ;; "file:" links. Also check link abbreviations since
- ;; some might expand to "file" links.
- (file-types-re
- (format "\\[\\[\\(?:file%s:\\|attachment:\\|[./~]\\)\\|\\]\\[\\(<?\\(?:file\\|attachment\\):\\)"
- (if (not link-abbrevs) ""
- (concat "\\|" (regexp-opt link-abbrevs))))))
- (while (re-search-forward file-types-re end t)
- (let* ((link (org-element-lineage
- (save-match-data (org-element-context))
- 'link t))
- (linktype (org-element-property :type link))
- (inner-start (match-beginning 1))
- (path
- (cond
- ;; No link at point; no inline image.
- ((not link) nil)
- ;; File link without a description. Also handle
- ;; INCLUDE-LINKED here since it should have
- ;; precedence over the next case. I.e., if link
- ;; contains filenames in both the path and the
- ;; description, prioritize the path only when
- ;; INCLUDE-LINKED is non-nil.
- ((or (not (org-element-contents-begin link))
- include-linked)
- (and (or (equal "file" linktype)
- (equal "attachment" linktype))
- (org-element-property :path link)))
- ;; Link with a description. Check if description
- ;; is a filename. Even if Org doesn't have syntax
- ;; for those -- clickable image -- constructs, fake
- ;; them, as in `org-export-insert-image-links'.
- ((not inner-start) nil)
- (t
- (org-with-point-at inner-start
- (and (looking-at
- (if (char-equal ?< (char-after inner-start))
- org-link-angle-re
- org-link-plain-re))
- ;; File name must fill the whole
- ;; description.
- (= (org-element-contents-end link)
- (match-end 0))
- (progn
- (setq linktype (match-string 1))
- (match-string 2))))))))
- (when (and path (string-match-p file-extension-re path))
- (let ((file (if (equal "attachment" linktype)
- (progn
- (require 'org-attach)
- (ignore-errors (org-attach-expand path)))
- (expand-file-name path))))
- ;; Expand environment variables.
- (when file (setq file (substitute-in-file-name file)))
- (when (and file (file-exists-p file))
- (let ((width (org-display-inline-image--width link))
- (align (org-image--align link))
- (old (get-char-property-and-overlay
- (org-element-begin link)
- 'org-image-overlay)))
- (if (and (car-safe old) refresh)
- (image-flush (overlay-get (cdr old) 'display))
- (let ((image (org--create-inline-image file width)))
- (when image
- (let ((ov (make-overlay
- (org-element-begin link)
- (progn
- (goto-char
- (org-element-end link))
- (unless (eolp) (skip-chars-backward " \t"))
- (point)))))
- ;; See bug#59902. We cannot rely
- ;; on Emacs to update image if the file
- ;; has changed.
- (image-flush image)
- (overlay-put ov 'display image)
- (overlay-put ov 'face 'default)
- (overlay-put ov 'org-image-overlay t)
- (overlay-put
- ov 'modification-hooks
- (list 'org-display-inline-remove-overlay))
- (when (boundp 'image-map)
- (overlay-put ov 'keymap image-map))
- (when align
- (overlay-put
- ov 'before-string
- (propertize
- " " 'face 'default
- 'display
- (pcase align
- ("center" `(space :align-to (- center (0.5 . ,image))))
- ("right" `(space :align-to (- right ,image)))))))
- (push ov org-inline-image-overlays))))))))))))))))
-
(declare-function org-export-read-attribute "ox"
(attribute element &optional property))
(defvar visual-fill-column-width) ; Silence compiler warning
@@ -17135,32 +16882,6 @@ (defun org-image--align (link)
(when (memq org-image-align '(center right))
(symbol-name org-image-align))))))))
-
-(defun org-display-inline-remove-overlay (ov after _beg _end &optional _len)
- "Remove inline-display overlay if a corresponding region is modified."
- (when (and ov after)
- (setq org-inline-image-overlays (delete ov org-inline-image-overlays))
- ;; Clear image from cache to avoid image not updating upon
- ;; changing on disk. See Emacs bug#59902.
- (when (overlay-get ov 'org-image-overlay)
- (image-flush (overlay-get ov 'display)))
- (delete-overlay ov)))
-
-(defun org-remove-inline-images (&optional beg end)
- "Remove inline display of images."
- (interactive)
- (let* ((beg (or beg (point-min)))
- (end (or end (point-max)))
- (overlays (overlays-in beg end)))
- (dolist (ov overlays)
- (when (memq ov org-inline-image-overlays)
- (setq org-inline-image-overlays (delq ov org-inline-image-overlays))
- (delete-overlay ov)))
- ;; Clear removed overlays.
- (dolist (ov org-inline-image-overlays)
- (unless (overlay-buffer ov)
- (setq org-inline-image-overlays (delq ov org-inline-image-overlays))))))
-
(defvar org-self-insert-command-undo-counter 0)
(defvar org-speed-command nil)
diff --git a/testing/lisp/test-org-fold.el b/testing/lisp/test-org-fold.el
index f58642be6..809738f6c 100644
--- a/testing/lisp/test-org-fold.el
+++ b/testing/lisp/test-org-fold.el
@@ -716,14 +716,14 @@ (ert-deftest test-org-fold/org-fold-display-inline-images ()
(org-show-subtree)
(org-fold-subtree t)
(run-hook-with-args 'org-cycle-hook 'folded)
- (should-not org-inline-image-overlays)
+ (should-not org-link-preview-overlays)
(should-not
(cl-every
(lambda (ov) (overlay-get ov 'org-image-overlay))
(overlays-in (point-min) (point-max))))
(org-show-subtree)
(run-hook-with-args 'org-cycle-hook 'subtree)
- (should org-inline-image-overlays)
+ (should org-link-preview-overlays)
(should
(cl-every
(lambda (ov) (overlay-get ov 'org-image-overlay))
--
2.44.1
next prev parent reply other threads:[~2024-08-31 22:38 UTC|newest]
Thread overview: 75+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-05-15 3:28 [PATCH] add a function to only refresh inline images under current headline instead of global buffer Christopher M. Miles
2023-05-15 11:08 ` Ihor Radchenko
2023-05-15 13:01 ` Christopher M. Miles
2023-05-15 14:00 ` [PATCH v2] " Christopher M. Miles
2023-05-16 9:17 ` Ihor Radchenko
2023-05-16 12:18 ` Christopher M. Miles
2023-07-24 11:25 ` Ihor Radchenko
2023-08-01 4:40 ` [PATCH v3] " Christopher M. Miles
2023-08-01 8:04 ` Ihor Radchenko
2023-08-01 12:17 ` [PATCH v3.1] " Christopher M. Miles
2023-08-01 14:09 ` Ihor Radchenko
2023-08-01 15:22 ` Christopher M. Miles
2023-08-01 15:46 ` Christopher M. Miles
2023-08-02 16:08 ` Ihor Radchenko
2023-08-04 6:30 ` Christopher M. Miles
2023-08-02 7:26 ` Ihor Radchenko
2023-08-02 15:44 ` Christopher M. Miles
2023-08-04 8:20 ` Ihor Radchenko
2023-08-05 5:28 ` [PATCH v3.2] " Christopher M. Miles
2024-07-22 10:46 ` Ihor Radchenko
2024-08-01 22:58 ` [PATCH v4.0] " stardiviner
[not found] ` <66a8b73b.170a0220.383476.996e@mx.google.com>
2024-08-12 10:18 ` Ihor Radchenko
2024-08-14 2:04 ` stardiviner
2024-08-18 10:27 ` Ihor Radchenko
2024-08-20 2:02 ` Karthik Chikmagalur
2024-08-20 15:43 ` Karthik Chikmagalur
2024-08-20 18:19 ` Ihor Radchenko
2024-08-20 19:46 ` Karthik Chikmagalur
2024-08-22 13:19 ` Ihor Radchenko
2024-08-23 6:04 ` Karthik Chikmagalur
2024-08-23 23:36 ` [PATCH v1] Inline image display as part of a new org-link-preview system Karthik Chikmagalur
2024-08-24 1:00 ` Karthik Chikmagalur
2024-08-31 14:22 ` Ihor Radchenko
2024-08-31 16:41 ` Karthik Chikmagalur
2024-08-31 16:53 ` Ihor Radchenko
2024-08-31 22:37 ` Karthik Chikmagalur [this message]
2024-09-01 13:06 ` [PATCH v2] " Ihor Radchenko
2024-09-02 20:13 ` [PATCH v3] " Karthik Chikmagalur
2024-09-08 7:43 ` Ihor Radchenko
2024-09-09 3:21 ` Karthik Chikmagalur
2024-09-09 6:06 ` Ihor Radchenko
2024-09-09 6:30 ` Karthik Chikmagalur
2024-09-09 16:47 ` Ihor Radchenko
2024-09-09 19:14 ` Karthik Chikmagalur
2024-09-10 16:57 ` Ihor Radchenko
2024-09-10 19:53 ` Karthik Chikmagalur
2024-09-15 7:51 ` Ihor Radchenko
2024-09-09 21:45 ` Karthik Chikmagalur
2024-09-10 16:58 ` Ihor Radchenko
2024-09-10 17:38 ` Karthik Chikmagalur
2024-09-10 18:34 ` Ihor Radchenko
2024-09-10 19:43 ` Karthik Chikmagalur
2024-09-15 8:12 ` Ihor Radchenko
2024-09-15 20:50 ` Karthik Chikmagalur
2024-09-15 21:57 ` [PATCH v4] " Karthik Chikmagalur
2024-09-17 18:16 ` Ihor Radchenko
2024-09-18 1:44 ` [PATCH v5] " Karthik Chikmagalur
2024-09-21 10:11 ` Ihor Radchenko
2024-09-22 22:00 ` [PATCH v6] " Karthik Chikmagalur
2024-10-03 17:03 ` Ihor Radchenko
2024-10-08 0:07 ` [PATCH v7] " Karthik Chikmagalur
2024-10-10 17:15 ` Ihor Radchenko
2024-10-10 21:23 ` Karthik Chikmagalur
2024-10-12 8:15 ` Ihor Radchenko
2024-10-28 6:13 ` [PATCH v8] " Karthik Chikmagalur
2024-10-28 18:16 ` Ihor Radchenko
2024-10-28 21:53 ` [PATCH v9] " Karthik Chikmagalur
2024-10-29 18:46 ` Ihor Radchenko
2024-10-29 20:45 ` [PATCH v10] " Karthik Chikmagalur
2024-10-30 17:32 ` Ihor Radchenko
2024-10-30 19:50 ` Karthik Chikmagalur
2024-10-31 18:16 ` Ihor Radchenko
2024-08-18 10:34 ` [FR] Automatically display images in resutls of evaluation (was: [PATCH v4.0] Re: [PATCH] add a function to only refresh inline images under current headline instead of global buffer) Ihor Radchenko
[not found] ` <66c54dfc.a70a0220.3c823a.2899@mx.google.com>
2024-08-22 13:06 ` [FR] Automatically display images in resutls of evaluation Ihor Radchenko
[not found] ` <66c89411.170a0220.3255c1.0cd5@mx.google.com>
[not found] ` <87zfor7b04.fsf@localhost>
[not found] ` <CAL1eYuLOsaS43ahueN4uWiCn+Ykp=p_-t9dzAypKdy1en_53BQ@mail.gmail.com>
2024-09-15 13:33 ` [PATCH v3] " Ihor Radchenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.orgmode.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87h6b09v4o.fsf@gmail.com \
--to=karthikchikmagalur@gmail.com \
--cc=emacs-orgmode@gnu.org \
--cc=numbchild@gmail.com \
--cc=yantar92@posteo.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).