<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>notes from /dev/null - anju</title><link href="http://yummymelon.com/devnull/" rel="alternate"/><link href="http://yummymelon.com/devnull/feeds/tags/anju.atom.xml" rel="self"/><id>http://yummymelon.com/devnull/</id><updated>2026-04-07T13:25:00-07:00</updated><entry><title>Calming Mouse Interaction in Dired</title><link href="http://yummymelon.com/devnull/calming-mouse-interaction-in-dired.html" rel="alternate"/><published>2026-04-07T13:25:00-07:00</published><updated>2026-04-07T13:25:00-07:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-04-07:/devnull/calming-mouse-interaction-in-dired.html</id><summary type="html">&lt;p&gt;Single click to open a file in Dired is too twitchy. This post shows how to change it.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Conventional file managers have conditioned me to expect that a single left-button mouse click (&lt;code&gt;&amp;lt;mouse-1&amp;gt;&lt;/code&gt;) will select a file (or directory) and double-click will open it. This is not the default behavior of Dired, where a single click is an open action. I find this far too twitchy for my taste.&lt;/p&gt;
&lt;p&gt;This post shows how to make Dired mouse interaction align with a conventional file manager where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Single-click on a file or directory will move the point to it, making it the implicit target for any subsequent Dired command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Left double-click on file or directory will open it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Selecting multiple files is emulated using Dired marking, in this case using the binding &lt;code&gt;M-&amp;lt;mouse-1&amp;gt;&lt;/code&gt; to toggle marking a file.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first two points above can be addressed with the global variable &lt;code&gt;mouse-1-click-follows-link&lt;/code&gt;. Dired uses this variable to control its mouse behavior, but we don’t want to change it everywhere, just for Dired buffers. This can be implemented by setting &lt;code&gt;mouse-1-click-follows-link&lt;/code&gt; locally as a hook to &lt;code&gt;dired-mode-hook&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt;1&lt;/span&gt;
&lt;span class="normal"&gt;2&lt;/span&gt;
&lt;span class="normal"&gt;3&lt;/span&gt;
&lt;span class="normal"&gt;4&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;dired-mode-hook&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;setq-local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;mouse-1-click-follows-link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;double&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To address multiple file selection, we can define a function &lt;code&gt;cc/dired-mouse-toggle-mark&lt;/code&gt; and bind it to &lt;code&gt;M-&amp;lt;mouse-1&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;cc/dired-mouse-toggle-mark&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Toggle mark of a Dired item via mouse.&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;unless&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;use-region-p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;mouse-set-point&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;last-input-event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;char-equal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;char-after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;line-beginning-position&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dired-marker-char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;call-interactively&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;dired-unmark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;call-interactively&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;dired-mark&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keymap-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;dired-mode-map&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;mouse-1&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;#&amp;#39;&lt;/span&gt;&lt;span class="nv"&gt;cc/dired-mouse-toggle-mark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Coupled with &lt;a href="https://melpa.org/#/anju"&gt;Anju&lt;/a&gt; support for a &lt;a href="https://kickingvegas.github.io/anju/Dired-Mode-Context-Menu.html"&gt;Dired specific context menu&lt;/a&gt; and many basic file manager operations can be done in Dired via mouse with minimal fuss.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="anju"/></entry><entry><title>Announcing Anju</title><link href="http://yummymelon.com/devnull/announcing-anju.html" rel="alternate"/><published>2026-03-30T08:45:00-07:00</published><updated>2026-03-30T08:45:00-07:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-03-30:/devnull/announcing-anju.html</id><summary type="html">&lt;p&gt;Announcing Anju, a project to align mouse interactions in Emacs with contemporary (circa 2026) expectations. Now available on MELPA.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The recent post “&lt;a href="https://meanwhiling.com/you-dont-not-need-the-mouse.html"&gt;You don’t not need the mouse&lt;/a&gt;” by noa ks speaks to a sentiment that I’ve had for some time. Using the mouse in Emacs can be a good, daresay &lt;em&gt;delightful&lt;/em&gt;, experience. Unfortunately though, Emacs has antiquated default settings that presume we’re all still using a &lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Sun_optical_mouse.jpg/960px-Sun_optical_mouse.jpg"&gt;90’s style 3-button workstation mouse&lt;/a&gt;. In addition, the overreliance on reusing menu keymaps for both the main &lt;em&gt;and&lt;/em&gt; context menus results in poor user experience. I feel strongly that context menus populated this way feel more like an inventory than a thoughtful selection of commands relevant to &lt;em&gt;context&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Thankfully, Emacs offers the mechanisms to sculpt mouse interactions to contemporary (circa 2026) expectations. Over the past three years, I’ve taken advantage of them to implement the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Mode Line&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Right mouse click on blank space to pop-up a window management menu&lt;/li&gt;
&lt;li&gt;Left mouse click on buffer name to pop-up a customizable list of buffers&lt;/li&gt;
&lt;li&gt;Double click on blank space to toggle current window to maximize or return to prior window configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context Menu&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Context-aware commands for selected text (&lt;code&gt;use-region-p&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Context-aware commands for Org and Dired mode&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Main Menu&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add Bookmarks menu&lt;/li&gt;
&lt;li&gt;Reorganize Help menu&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Several months ago, I decided these mouse interaction changes should be generalized into a package that others could use. So began the &lt;em&gt;Anju&lt;/em&gt; project.&lt;/p&gt;
&lt;p&gt;Today I’m happy to announce that &lt;a href="https://github.com/kickingvegas/anju"&gt;Anju v1.0&lt;/a&gt; is now available on &lt;a href="https://melpa.org/#/anju"&gt;MELPA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Learn more details about Anju in its &lt;a href="https://kickingvegas.github.io/anju/"&gt;User Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As Anju is new, I’m always open to constructive feedback on it. Let me know &lt;a href="https://github.com/kickingvegas/anju/discussions/33"&gt;what you think&lt;/a&gt;. Work on Anju is ongoing with the plan to keep adding improvements to it over time, in particular with supporting more context menus for different modes.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="anju"/></entry></feed>