Latest iteration of patch attached. >>>> +BEG and END define the considered part. They default to the >>>> +buffer boundaries with possible narrowing." >>>> + (interactive "P") >>>> + (when (display-graphic-p) >>> >>> Do we need it here? You check graphics both here and later in the >>> preview function. We may probably drop the check herein. >> >> I moved the `refresh' clause out of the display-graphic-p check, but I >> think it's needed. Otherwise this line will run once per previewed >> image instead of once per call to `org-link-preview': >> >> (when (fboundp 'clear-image-cache) (clear-image-cache)) >> >> clearing newly placed previews (within the same run) from the cache. > > Sorry, I was not clear. I only referred to `display-graphic-p' check. I > did not mean `clear-image-cache'. Removed the display-graphic-p check. >> That said, I have a question about `clear-image-cache' here. Why does [...] >> LaTeX previews. Images in unrelated buffers/major-modes are also >> affected. > > Here is the original code: > > (when refresh > (org-remove-inline-images beg end) > (when (fboundp 'clear-image-cache) (clear-image-cache))) > > Image cache is cleared _only_ with REFRESH argument. > I think that makes sense, right? Yes. But `org-link-preview-region' is always called with the REFRESH argument set to `t' though. >>> I am wondering why you left these functions in org.el. Why not moving >>> them here? >> >> They seemed out of place in ol.el, so my plan was the following: >> 1. This patch: Implement org-link-preview. >> 2. Another patch: Move image creation/manipulation/geometry functions >> from org into an org-image (or org-image-utils) library. Require it in >> ol. >> >> However, I can move them wherever you want, let me know. > > I'd rather see them moved. > You can later send another patch moving them into the new utils library, > if you want. Okay, I moved them to ol.el. They seem out of place here, but I can send another patch after merging this one to create org-image.el. >> I don't know how create-image can fail. Suppose a .jpg file exists but >> is corrupted or does not have image/jpeg data. Then create-image >> returns nil, as does `org--create-inline-image'. This check guards >> against trying to preview an "image" that's nil. > > Let me elaborate. > > In `org-link-preview-region', you set org-image-overlay property: > > + (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) > > Then, you do it yet again in `org-link-preview-file', when the property > is already there - this part is redundant. Fixed. >>>> + (when (boundp 'image-map) >>> >>> What if not bound? Why not simply (require 'image)? >> >> Just unmodified old code. I've require'd image in ol now, let me know >> if I should do it differently. > > Let's not require it on top level. Maybe better do it within the preview > function. Moved (require 'image) to inside the `org-link-preview-file'. I know it doesn't affect performance in any reasonable way, but I'm usually hesitant to do this in functions that run inside loops. > I mostly meant calling preview-func asynchronously, while idle, spaced > out, spending not longer than a fraction of second to call several > preview-funcs. > Spacing might then be controlled by the users. > > We might go further, and let the preview functions return a > process. Then, we may explicitly control running sentinels just for that > process via `accept-process-output'. But I am not sure if we need to go > that far. Following our other discussion in this thread, I've now implemented batched previews via idle-timers, controlled by `org-link-preview-delay' and `org-link-preview-batch-size'. The default values of these parameters needs to be tuned. I tested a few combinations but couldn't perceive a difference in lag or in the profiler. The only unhandled case is when an asynchronous preview (in the sense that preview-func is itself asynchronous) fails. It is then the responsibility of preview-func's callback to clean up the overlay. This can be done by calling org-link-preview-clear on the bounds of the link. I think this is sufficient for now.