<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
	<title>Sacha Chua - category - link</title>
	<atom:link href="https://sachachua.com/blog/category/link/feed/index.xml" rel="self" type="application/rss+xml" />
	<atom:link href="https://sachachua.com/blog/category/link" rel="alternate" type="text/html" />
	<link>https://sachachua.com/blog/category/link/feed/index.xml</link>
	<description>Emacs, sketches, and life</description>
	<lastBuildDate>Sat, 11 Apr 2026 14:13:19 GMT</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>11ty</generator>
  <item>
		<title>Using image-dired to browse the latest screenshots from multiple directories</title>
		<link>https://sachachua.com/blog/2025/01/using-image-dired-to-browse-the-latest-screenshots-from-multiple-directories/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Thu, 02 Jan 2025 13:24:06 GMT</pubDate>
    <category>emacs</category>
<category>image</category>
<category>org</category>
<category>link</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2025/01/using-image-dired-to-browse-the-latest-screenshots-from-multiple-directories/</guid>
		<description><![CDATA[<div class="update" id="org32cd72b">
<p>
<span class="timestamp-wrapper"><span class="timestamp">[2025-01-06 Mon]</span></span>: <a href="https://lists.gnu.org/archive/html/emacs-devel/2025-01/msg00064.html">Patch in progress</a>, Stefan Kangas is looking into it.
</p>

</div>

<p>
Since A+ and I play lots of Minecraft together, I
figured it's a good opportunity to slowly get her
into the idea of documenting learning. Besides, I
can always practise it myself. Screenshots are
handy for that. In Minecraft Java, <code>F1</code> hides the
usual heads-up display, and <code>F2</code> takes the
screenshot. Usually, when I start taking
screenshots. A+ starts taking screenshots too. I
want to build on her enthusiasm by including her
screenshots in notes. To make it easy to
incorporate her pictures into our notes, I've
shared her <a href="https://gdlauncher.com/">GDLauncher</a> folder and her Videos folder
with my computer using <a href="https://docs.syncthing.net/">Syncthing</a> so that I can
grab any screenshots or videos that she's taken.
</p>

<p>
In Emacs, <a href="http://www.gnu.org/s/emacs/manual/html_node/emacs/Image_002dDired.html">image-dired</a> makes it easy to see
thumbnails. The neat thing is that it doesn't just
work with a single directory. Just like Dired, you
can give it a cons cell with a directory in the
first part and a list of files in the second part
as the first argument to the function, and it will
display those files. This means I can use
<code>directory-files-recursively</code> to make a list of
files, sort it to show most recent screenshots
first, limit it to the most recent items, and then
display a buffer with thumbnails.
<code>image-dired-show-all-from-dir</code> reports a small
error when you do this (I need to send a patch
<a href="https://lists.gnu.org/archive/html/emacs-devel/2025-01/msg00064.html">upstream</a>), so we hush it with <code>condition-case</code> in
<code>my-show-combined-screenshots</code>.
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp" id="org4a04d44">(<span class="org-keyword">defvar</span> <span class="org-variable-name">my-screenshot-dirs</span>
  <span class="org-highlight-quoted-quote">'</span>(<span class="org-string">"~/recordings"</span>
    <span class="org-string">"~/.var/app/org.prismlauncher.PrismLauncher/data/PrismLauncher/instances/"</span>
    <span class="org-string">"~/sync/gdlauncher-instances/"</span>))
(<span class="org-keyword">defvar</span> <span class="org-variable-name">my-recent-screenshot-limit</span> 50)

(<span class="org-keyword">defun</span> <span class="org-function-name">my-combined-screenshots</span> (<span class="org-type">&amp;optional</span> limit)
  (seq-take
   (sort
    (seq-mapcat (<span class="org-keyword">lambda</span> (dir)
                  (directory-files-recursively dir <span class="org-string">"^[0-9][0-9][0-9][0-9]-.*\\.</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">(</span></span><span class="org-string">png</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">|</span></span><span class="org-string">webm</span><span class="org-string"><span class="org-regexp-grouping-backslash">\\</span></span><span class="org-string"><span class="org-regexp-grouping-construct">)</span></span><span class="org-string">"</span>))
                my-screenshot-dirs)
    <span class="org-builtin">:key</span> <span class="org-highlight-quoted-quote">#'</span><span class="org-highlight-quoted-symbol">file-name-base</span>
    <span class="org-builtin">:lessp</span> <span class="org-highlight-quoted-quote">#'</span><span class="org-highlight-quoted-symbol">string&lt;</span>
    <span class="org-builtin">:reverse</span> t)
   (<span class="org-keyword">or</span> limit my-recent-screenshot-limit)))

(<span class="org-keyword">defun</span> <span class="org-function-name">my-latest-screenshot</span> ()
  (car (my-combined-screenshots)))

(<span class="org-keyword">defun</span> <span class="org-function-name">my-show-combined-screenshots</span> (<span class="org-type">&amp;optional</span> limit)
  <span class="org-doc">"Show thumbnails for combined screenshots."</span>
  (<span class="org-keyword">interactive</span> (list (<span class="org-keyword">when</span> current-prefix-arg (read-number <span class="org-string">"Limit: "</span>))))
  (<span class="org-keyword">condition-case</span> nil
      <span class="org-comment-delimiter">;; </span><span class="org-comment">ignore errors from image-dired trying to set default-directory</span>
      (image-dired-show-all-from-dir
       (cons (car my-screenshot-dirs) (my-combined-screenshots limit)))
    (<span class="org-warning">error</span> nil)))
</pre>
</div>



<figure id="org623c723">
<img src="https://sachachua.com/blog/2025/01/using-image-dired-to-browse-the-latest-screenshots-from-multiple-directories/2025-01-02_08-19-32.png" alt="2025-01-02_08-19-32.png">

<figcaption><span class="figure-number">Figure 1: </span>The result of <code>my-show-combined-screenshots</code></figcaption>
</figure>

<p>
In the <code>*image-dired*</code> buffer created by
<code>my-show-combined-screenshots</code>, I can use <code>m</code>
(<code>image-dired-mark-thumb-original-file</code>) to mark
images and <code>C-u w</code>
(<code>image-dired-copy-filename-as-kill</code>) to copy
their absolute paths.
</p>

<p>
To make it easier to create links to a file by
using <code>org-store-link</code> (which I've bound to <code>C-c
l</code>) and <code>org-insert-link</code> (<code>C-c C-l</code> in an Org
buffer), I can define a link-storing function that
takes the original filename:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp" id="org58f886a">(<span class="org-keyword">defun</span> <span class="org-function-name">my-org-image-dired-store-link</span> ()
  (<span class="org-keyword">when</span> (<span class="org-keyword">and</span> (derived-mode-p <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">image-dired-thumbnail-mode</span>)
             (get-text-property (point) <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">original-file-name</span>))
    (org-link-store-props
     <span class="org-builtin">:link</span> (concat <span class="org-string">"file:"</span> (get-text-property (point) <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">original-file-name</span>)))))

(<span class="org-keyword">with-eval-after-load</span> <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">org</span>
  (org-link-set-parameters
   <span class="org-string">"image-dired"</span>
   <span class="org-builtin">:store</span> <span class="org-highlight-quoted-quote">#'</span><span class="org-highlight-quoted-symbol">my-org-image-dired-store-link</span>))
</pre>
</div>


<p>
To make it easier to insert the marked links that
have been copied as absolute paths:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp">(<span class="org-keyword">defun</span> <span class="org-function-name">my-org-yank-file-links-from-kill-ring</span> ()
  (<span class="org-keyword">interactive</span>)
  (<span class="org-keyword">dolist</span> (file (read (concat <span class="org-string">"("</span> (current-kill 0) <span class="org-string">")"</span>)))
      (insert (org-link-make-string (concat <span class="org-string">"file:"</span> file)) <span class="org-string">"\n"</span>)))
</pre>
</div>


<p>
I usually want to copy those files to another
directory anyway. I have a
<code>my-org-copy-linked-files</code> function in <a href="https://sachachua.com/dotemacs#copy-linked-file-and-change-link">Copy linked
file and change link</a> that copies the files and
rewrites the Org links. This means that I can copy
my notes to an index.org in a directory I share
with A+, save the images to an <code>images</code>
subdirectory, and export the index.html so that
she can read the notes any time she likes.
</p>

<div class="note">This is part of my <a href="https://sachachua.com/dotemacs#image-dired-screenshots">Emacs configuration.</a></div><div><a href="https://sachachua.com/blog/2025/01/using-image-dired-to-browse-the-latest-screenshots-from-multiple-directories/index.org">View org source for this post</a></div>
<p>You can <a href="https://sachachua.com/blog/2025/01/using-image-dired-to-browse-the-latest-screenshots-from-multiple-directories/#comment">view 2 comments</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2025%2F01%2Fusing-image-dired-to-browse-the-latest-screenshots-from-multiple-directories%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item>
	</channel>
</rss>