<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>notes from /dev/null - emacs</title><link href="http://yummymelon.com/devnull/" rel="alternate"/><link href="http://yummymelon.com/devnull/feeds/tags/emacs.atom.xml" rel="self"/><id>http://yummymelon.com/devnull/</id><updated>2026-03-03T13:10:00-08:00</updated><entry><title>Casual now available on NonGNU ELPA</title><link href="http://yummymelon.com/devnull/casual-now-available-on-nongnu-elpa.html" rel="alternate"/><published>2026-03-03T13:10:00-08:00</published><updated>2026-03-03T13:10:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-03-03:/devnull/casual-now-available-on-nongnu-elpa.html</id><summary type="html">&lt;p&gt;Casual is now available on NonGNU ELPA.&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you are an Emacs user who only uses 3rd party packages from ELPA or NonGNU ELPA, I’m happy to announce that &lt;a href="https://elpa.nongnu.org/nongnu/casual.html"&gt;Casual is now available on NonGNU ELPA&lt;/a&gt;. 🎉&lt;/p&gt;
&lt;p&gt;If this is the first time you’ve heard of Casual, it is a project to re-imagine the primary user interface for Emacs using keyboard-driven menus. Casual’s design intent is to make the vast feature set of Emacs easier to discover and use in &lt;em&gt;casual&lt;/em&gt; fashion. It does so by providing bespoke hand-crafted menus for different modes provided by Emacs. These menus are opinionated in that the design of what goes into those menus are editorially determined by yours truly. To understand more about what Casual has to offer, &lt;a href="https://kickingvegas.github.io/casual/"&gt;please peruse its User Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In terms of implementation, Casual is built using the &lt;a href="https://docs.magit.vc/transient/"&gt;Transient library&lt;/a&gt; made by Jonas Bernoulli. This is the same library that powers the UI for &lt;a href="https://magit.vc/"&gt;Magit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Development of Casual has been on-going for nearly &lt;em&gt;two years&lt;/em&gt; now. Interested readers can read about Casual’s progress over that time &lt;a href="http://yummymelon.com/devnull/tag/casual.html"&gt;from my blog posts here&lt;/a&gt;. Throughout it all I’ve learned a lot about Emacs, its ecosystem of modes, and the powerful features they bring. It has only reinforced my conviction that Casual makes these powerful features more &lt;em&gt;usable&lt;/em&gt; beyond what is offered by default in Emacs.&lt;/p&gt;
&lt;p&gt;To clarify, if you still get Casual from &lt;a href="https://melpa.org/#/casual"&gt;MELPA&lt;/a&gt; (or MELPA Stable), &lt;em&gt;you do not have to change anything&lt;/em&gt;. The only difference is that users can now choose to install Casual from either MELPA or NonGNU ELPA. Updates to Casual will be distributed on both equally.&lt;/p&gt;
&lt;p&gt;My thanks goes out to the NonGNU ELPA reviewers who have provided guidance in helping get Casual on there. Additional thanks goes out to all the Casual users whose input and support have kept me going at this since 2024.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry><entry><title>Announcing Casual Org</title><link href="http://yummymelon.com/devnull/announcing-casual-org.html" rel="alternate"/><published>2026-02-19T15:00:00-08:00</published><updated>2026-02-19T15:00:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-02-19:/devnull/announcing-casual-org.html</id><summary type="html">&lt;p&gt;At long last, announcing Casual support for Org Mode.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Most Emacs Org users would concur that &lt;strong&gt;Org mode&lt;/strong&gt; is a magnificent tool for capturing and communicating thought. That said, Org mode’s &lt;a href="https://orgmode.org/features.html"&gt;vast set of features&lt;/a&gt; can be daunting to master. A common guidance for new users is to take it slow: incrementally learn a subset of Org’s features as you need them.&lt;/p&gt;
&lt;p&gt;A big reason for Org mode’s steep learning curve is that it adopts Emacs’ unfortunate culture of compelling users to memorize keybindings. Learning a distinct keybinding for each Org command (remember I said &lt;em&gt;vast&lt;/em&gt; feature set?) is onerous, so a different tack is made: reuse the same keybinding but have it possess different behavior based on context. This context is usually tied to the type of structure the point (aka cursor) is in. For example, if the point is in a source block, the binding &lt;code&gt;C-c C-c&lt;/code&gt; would execute it, but if the point is on a checkbox item, then &lt;code&gt;C-c C-c&lt;/code&gt; would toggle its checked state. Taking this approach lowers the effort to recall a keybinding at the cost of recalling what its contextual behavior would be. In practice, using such overloaded keybindings is…okay. But I’d argue that we could have a more usable interface, leading to the point of this post:&lt;/p&gt;
&lt;p&gt;Announcing support for &lt;a href="https://kickingvegas.github.io/casual/Org.html"&gt;Org mode&lt;/a&gt; in the &lt;a href="https://github.com/kickingvegas/casual/discussions/397"&gt;v2.14.0 update for Casual&lt;/a&gt;, now available on &lt;a href="https://melpa.org/#/casual"&gt;MELPA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Readers of this blog will know that &lt;a href="https://kickingvegas.github.io/casual/"&gt;Casual&lt;/a&gt; is my project to re-imagine the primary user interface for Emacs using keyboard-driven menus. If this is new to you, I highly recommend reading this &lt;a href="https://github.com/kickingvegas/casual"&gt;introduction&lt;/a&gt; to it.&lt;/p&gt;
&lt;p&gt;Primary to the design of the Casual Org menus is to be context-sensitive, only showing a subset of Org mode commands that are relevant. This set of context-sensitive commands is opinionated, but seeks to provide utility to users both new and experienced with Org.&lt;/p&gt;
&lt;p&gt;Shown below is a demo of Casual Org at work:&lt;/p&gt;
&lt;video controls  muted=true poster="http://yummymelon.com/devnull/images/announcing-casual-org/casual-org-demo-poster.png" width="75%"&gt;
&lt;source src="http://yummymelon.com/images/videos/casual-org-demo.mp4" type="video/mp4" /&gt;
&lt;p&gt;
Your browser does not support HTML video. &lt;a href="http://yummymelon.com/images/videos/casual-org-demo.mp4" download="http://yummymelon.com/images/videos/casual-org-demo.mp4"&gt;Link to video&lt;/a&gt;.
&lt;/p&gt;
&lt;/video&gt;
&lt;p&gt;&lt;br/&gt;&lt;/p&gt;
&lt;p&gt;While the design of this UI has been months in the making, there is nothing like real-world use and feedback. &lt;a href="https://github.com/kickingvegas/casual/discussions/397"&gt;Constructive input is appreciated&lt;/a&gt;, especially if you are relatively new to using Org.&lt;/p&gt;
&lt;p&gt;A great deal of thanks goes out to the maintainers of and contributors to Org mode and to the community that uses it. If you are able, &lt;a href="https://liberapay.com/org-mode"&gt;please support it&lt;/a&gt;. Also, if you find Casual useful, I’d &lt;a href="https://buymeacoffee.com/kickingvegas"&gt;appreciate a coffee&lt;/a&gt; as well.&lt;/p&gt;
&lt;p&gt;&amp;#x2014;&lt;/p&gt;
&lt;p&gt;Video music: &lt;a href="https://jonreyes.bandcamp.com/track/burna-boy-last-last-jon-reyes-findaway-blend"&gt;Burna Boy - Last Last (JON REYES FINDAWAY BLEND) | Jon Reyes&lt;/a&gt;&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="org mode"/><category term="casual"/></entry><entry><title>Deburring Emacs Imenu GUI Configuration</title><link href="http://yummymelon.com/devnull/deburring-emacs-imenu-gui-configuration.html" rel="alternate"/><published>2026-02-10T09:20:00-08:00</published><updated>2026-02-10T09:20:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-02-10:/devnull/deburring-emacs-imenu-gui-configuration.html</id><summary type="html">&lt;p&gt;A bit of tuning to get Imenu GUI configuration working with any derived mode from &lt;code&gt;prog-mode&lt;/code&gt;.&lt;/p&gt;</summary><content type="html">&lt;p&gt;A while back, I made a &lt;a href="http://yummymelon.com/devnull/til-imenu.html"&gt;post on Emacs Imenu configuration&lt;/a&gt; that made an unsafe assumption that any mode derived from &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Basic-Major-Modes.html#index-prog_002dmode"&gt;prog-mode&lt;/a&gt; would support Imenu. Turns out, that’s not always true (for example, looking at you &lt;code&gt;gnuplot-mode&lt;/code&gt;). This post shows how to deal with this using an error handler.&lt;/p&gt;
&lt;p&gt;One such implementation of an error handler is the lambda expression shown below using &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Handling-Errors.html"&gt;condition-case&lt;/a&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;/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;prog-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="no"&gt;nil&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;condition-case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;imenu-add-menubar-index&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;imenu-unavailable&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;inhibit-message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&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;message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Warning: %s&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;error-message-string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;err&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;A couple of observations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The error handler is opportunistic in applying &lt;code&gt;imenu-add-menubar-index&lt;/code&gt; to a mode derived from &lt;code&gt;prog-mode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the error &lt;code&gt;imenu-unavailable&lt;/code&gt; is caught, then a warning message is logged but not messaged to the mini-buffer.&lt;ul&gt;
&lt;li&gt;The variable &lt;code&gt;inhibit-message&lt;/code&gt; is used to avoid sending a warning message to the minibuffer (it will still be logged in &lt;strong&gt;&lt;em&gt;*Messages&lt;/em&gt;&lt;/strong&gt;*) to avoid noise from modes that do not support Imenu. (Thanks to bpalmer for this guidance.)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you use Emacs and this is the first time you’ve heard of &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Imenu.html"&gt;Imenu&lt;/a&gt;, I highly recommend that you learn what it has to offer.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/></entry><entry><title>Using Casual to work with Emacs Registers, Rectangles, and Windows</title><link href="http://yummymelon.com/devnull/using-casual-to-work-with-emacs-registers-rectangles-and-windows.html" rel="alternate"/><published>2026-02-07T10:00:00-08:00</published><updated>2026-02-07T10:00:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-02-07:/devnull/using-casual-to-work-with-emacs-registers-rectangles-and-windows.html</id><summary type="html">&lt;p&gt;Use Casual to effectively use Emacs registers, rectangles, and windows on the regular.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The features of &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Registers.html"&gt;registers&lt;/a&gt;, &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Rectangles.html"&gt;rectangles&lt;/a&gt;, and &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Windows.html"&gt;window management&lt;/a&gt; in Emacs are quite powerful yet prior to building &lt;a href="https://kickingvegas.github.io/casual/"&gt;Casual&lt;/a&gt;, I rarely used them because of the cognitive load of remembering each feature’s command sets, much less their bindings. Using keyboard-driven menus tailored for these three features changed that. Now I only have to recall &lt;em&gt;three&lt;/em&gt; key bindings to get easy access to registers, rectangles, and window management. This post demonstrates how you can as well.&lt;/p&gt;
&lt;p&gt;Provided you have &lt;a href="https://melpa.org/#/casual"&gt;Casual installed from MELPA&lt;/a&gt;, consider making the following global key bindings to your Emacs setup:&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;/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;keymap-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-c r&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;casual-editkit-rectangle-tmenu&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-c g&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;casual-editkit-registers-tmenu&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-c w&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;casual-editkit-windows-tmenu&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;As always, you can adjust these bindings to your preference.&lt;/p&gt;
&lt;p&gt;Each of these menus are detailed further below.&lt;/p&gt;
&lt;h1&gt;Rectangle Menu (&lt;a href="https://kickingvegas.github.io/casual/Edit-commands.html#Rectangle_203a-_0028casual_002deditkit_002drectangle_002dtmenu_0029"&gt;casual-editkit-rectangle-tmenu&lt;/a&gt;)&lt;/h1&gt;
&lt;p&gt;The rectangle feature gives you the ability to mark (select) an arbitrary rectangle region in an Emacs buffer. There are many times where if the text is shaped like a rectangle, making transformations on them is exceptionally convenient. This menu provides you this.&lt;/p&gt;
&lt;p align='left'&gt;
&lt;img src='http://yummymelon.com/devnull/images/casual-registers-rectangles-windows/casual-editkit-rectangle-screenshot.png' alt='Screenshot of Casual rectangle menu' /&gt;
&lt;/p&gt;

&lt;h1&gt;Registers Menu (&lt;a href="https://kickingvegas.github.io/casual/Register-commands.html"&gt;casual-editkit-registers-tmenu&lt;/a&gt;)&lt;/h1&gt;
&lt;p&gt;Registers provide users a way to temporarily keep track of Emacs run-time state like text clippings, cursor (point) positions, macros, and arrangement of windows.&lt;/p&gt;
&lt;p align='left'&gt;
&lt;img src='http://yummymelon.com/devnull/images/casual-registers-rectangles-windows/casual-editkit-registers-screenshot.png' alt='Screenshot of Casual registers menu' /&gt;
&lt;/p&gt;

&lt;p&gt;Registers are a distinguishing feature of Emacs from other applications that support writing. It’s definitely a feature I miss when working outside of Emacs.&lt;/p&gt;
&lt;h1&gt;Windows Menu (&lt;a href="https://kickingvegas.github.io/casual/Window-management.html"&gt;casual-editkit-windows-tmenu&lt;/a&gt;)&lt;/h1&gt;
&lt;p&gt;In Emacs vernacular, a &lt;em&gt;window&lt;/em&gt; is a visual organization of how a buffer is displayed. Emacs windows are &lt;em&gt;not&lt;/em&gt; the same as what conventional GUIs (e.g. Wayland/X11, Apple macOS, Microsoft Windows) refer to as windows. In Emacs, GUI windows are referred to as &lt;em&gt;frames&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Emacs provides a number of commands to manage windows throughout their entire life-cycle which Casual organizes into the menu shown below:&lt;/p&gt;
&lt;p align='left'&gt;
&lt;img src='http://yummymelon.com/devnull/images/casual-registers-rectangles-windows/casual-editkit-window-screenshot.png' alt='Screenshot of Casual window management menu' /&gt;
&lt;/p&gt;

&lt;p&gt;In practice, I’ve found this menu to be most useful when using a compact/laptop-style keyboard or accessing Emacs via TTY. But if you are using GUI Emacs with a keyboard that has a number-pad, consider making the following number-pad bindings, particularly for selecting focus and swapping windows.&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;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&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="c1"&gt;;; Number pad bindings for window management.&lt;/span&gt;
&lt;span class="c1"&gt;;; Requires GUI Emacs.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keymap-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-add&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;enlarge-window&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-subtract&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;shrink-window&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-add&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;enlarge-window-horizontally&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-subtract&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;shrink-window-horizontally&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-enter&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;other-window&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-enter&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;switch-to-buffer&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;return&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;other-window&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-8&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;windmove-up&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-5&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;windmove-down&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-2&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;windmove-down&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-4&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;windmove-left&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-6&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;windmove-right&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-8&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;windmove-swap-states-up&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-5&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;windmove-swap-states-down&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-2&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;windmove-swap-states-down&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-4&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;windmove-swap-states-left&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;M-&amp;lt;kp-6&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;windmove-swap-states-right&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; These require the `ace-window&amp;#39; and `transpose-frame&amp;#39; packages.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;keymap-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-0&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;ace-select-window&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-global-set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;C-&amp;lt;kp-divide&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;transpose-frame&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;Note that the bindings for &lt;code&gt;ace-select-window&lt;/code&gt; and &lt;code&gt;transpose-frame&lt;/code&gt; require that you have the &lt;a href="https://melpa.org/#/ace-window"&gt;ace-window&lt;/a&gt; and &lt;a href="https://melpa.org/#/transpose-frame"&gt;transpose-frame&lt;/a&gt; packages installed.&lt;/p&gt;
&lt;h1&gt;Closing Thoughts&lt;/h1&gt;
&lt;p&gt;Registers, rectangles, and managing windows in Emacs are powerful features that are made easier to use with Casual. If you haven’t explored them, consider trying them out. I think you’ll be pleasantly surprised by what they offer and over time will consider them essential to your Emacs experience.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry><entry><title>Getting Eshell nth History to Work</title><link href="http://yummymelon.com/devnull/getting-eshell-nth-history-to-work.html" rel="alternate"/><published>2026-01-26T22:15:00-08:00</published><updated>2026-01-26T22:15:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-01-26:/devnull/getting-eshell-nth-history-to-work.html</id><summary type="html">&lt;p&gt;Out of the box, Eshell n&lt;sup&gt;th&lt;/sup&gt; history recall is disabled. Here’s how to turn it on.&lt;/p&gt;</summary><content type="html">&lt;p&gt;As much as I &lt;a href="http://yummymelon.com/devnull/take-two-eshell.html"&gt;enjoy using Eshell&lt;/a&gt;, it is not without its annoyances. In this case, I’m writing about the common shell convention of using &lt;code&gt;!n&lt;/code&gt; to recall a previously entered command.&lt;/p&gt;
&lt;p&gt;In Eshell, entering the &lt;code&gt;history&lt;/code&gt; command will show you all of your previously entered commands alongside a number &lt;code&gt;n&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The problem is in attempting to use &lt;code&gt;!n&lt;/code&gt; to recall a specific command in Eshell as one would do in &lt;code&gt;bash&lt;/code&gt; or &lt;code&gt;zsh&lt;/code&gt;. By default it will not work as described in &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eshell/History.html"&gt;Info (eshell) History&lt;/a&gt; without configuring &lt;code&gt;eshell-expand-input-functions&lt;/code&gt; first. (My current configuration is GNU Emacs 30.2.)&lt;/p&gt;
&lt;p&gt;To get &lt;code&gt;!n&lt;/code&gt; to work requires adding the function &lt;code&gt;eshell-expand-history-references&lt;/code&gt; to the customizable variable &lt;code&gt;eshell-expand-input-functions&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following configuration Elisp will achieve this.&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;/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-to-list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;eshell-expand-input-functions&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;eshell-expand-history-references&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;A nice feature of &lt;code&gt;eshell-expand-history-references&lt;/code&gt; is that it will expand using the content of an actual command instead of a number reference. So &lt;code&gt;!foo&lt;/code&gt; will invoke the last command that you entered the string “foo” in.&lt;/p&gt;
&lt;p&gt;It’s not clear to me whether coupling n&lt;sup&gt;th&lt;/sup&gt; history support to &lt;code&gt;eshell-expand-history-references&lt;/code&gt; is intentional or a bug. If the former, then I’d consider this yet another example of staying “on brand” with Emacs’ tendency to &lt;a href="http://yummymelon.com/devnull/surprise-and-emacs-defaults.html"&gt;ship with questionable defaults&lt;/a&gt;. That shade aside, Eshell is still an amazing package that I could not imagine using Emacs without.&lt;/p&gt;
&lt;h1&gt;Links&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/eshell/History.html"&gt;History (Eshell: The Emacs Shell)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="emacs"/></entry><entry><title>Announcing Casual EWW</title><link href="http://yummymelon.com/devnull/announcing-casual-eww.html" rel="alternate"/><published>2026-01-22T14:20:00-08:00</published><updated>2026-01-22T14:20:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-01-22:/devnull/announcing-casual-eww.html</id><summary type="html">&lt;p&gt;Announcing Casual support for EWW, a web browser within Emacs.&lt;/p&gt;</summary><content type="html">&lt;p&gt;I confess to taking a perverse delight in browsing the web from within Emacs. The &lt;a href="https://www.gnu.org/software/emacs/manual/html_mono/eww.html"&gt;EWW&lt;/a&gt; package that comes with the standard distribution of Emacs makes this possible. On paper, Emacs really has no business trying to support web browsing with its laughably threadbare support for layout and typography, much less its lack of support for multi-threaded operation. In practice though, I’ve found browsing the web from Emacs to be surprisingly useful. To enhance my usage of EWW, I wanted easy discovery of its features via Transient menus. With that motivation, I set out to build &lt;a href="https://kickingvegas.github.io/casual/EWW.html"&gt;Casual EWW&lt;/a&gt;, now available on &lt;a href="https://melpa.org/#/casual"&gt;MELPA&lt;/a&gt; in the &lt;a href="https://github.com/kickingvegas/casual/releases/tag/2.13.0"&gt;Casual v2.13.0 update&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;EWW is a minimal browser in that no CSS nor JavaScript is supported. As such, EWW is best suited for websites that treat HTML as a document specification and not as a sub-system to a web application.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/announcing-casual-eww/casual-eww-screenshot.png' alt='' /&gt;
&lt;/p&gt;

&lt;p&gt;Features of Casual EWW include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Support for in-page paragraph and link navigation.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Key bindings that match Safari and Chrome on macOS.&lt;/p&gt;
&lt;p&gt;In particular &lt;code&gt;M-[&lt;/code&gt; and &lt;code&gt;M-]&lt;/code&gt; for historical navigation and &lt;code&gt;M-l&lt;/code&gt; for entering a URL to open are supported.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Menus for toggling and configuring the display of a web page (font, colors, images).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Support for document navigation.&lt;/p&gt;
&lt;p&gt;This feature distinguishes EWW from other conventional web browsers for navigating websites that support the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel"&gt;rel&lt;/a&gt; attribute. For example, Texinfo uses the &lt;code&gt;rel&lt;/code&gt; attribute in generating HTML output.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Observations and Closing Thoughts&lt;/h1&gt;
&lt;p&gt;Some observations in using EWW:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The implementation of bookmarks in EWW is… underwhelming.&lt;/p&gt;
&lt;p&gt;Note that EWW bookmarks are a different implementation from a regular &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Bookmarks.html"&gt;Emacs bookmark&lt;/a&gt;. The EWW bookmark list does not provide a means for ordering a bookmark, much less for sorting and editing them.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;eww-readable&lt;/code&gt; command (bound to &lt;code&gt;R&lt;/code&gt;) is your friend (when it works).&lt;/p&gt;
&lt;p&gt;EWW provides a “reader” mode via the command &lt;code&gt;eww-readable&lt;/code&gt; which attempts to display only the main content of a web page. If successful, I’ve found it to vastly improve EWW’s utility.&lt;/p&gt;
&lt;p&gt;Setting the variable &lt;code&gt;eww-readable-urls&lt;/code&gt; to include documentation from &lt;a href="https://developer.mozilla.org"&gt;https://developer.mozilla.org&lt;/a&gt; will break the command &lt;code&gt;css-lookup-symbol&lt;/code&gt; (accessible via &lt;a href="https://kickingvegas.github.io/casual/CSS-Usage.html"&gt;Casual CSS&lt;/a&gt;) as that command expects the web page to &lt;em&gt;not&lt;/em&gt; be in reader mode.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For Emacs users, the utility of EWW is very much a YMMV thing as it can overlap the features of other packages like the Info reader and Elfeed. Regardless of what is preferred, it is assuring to know that web browsing (however limited) is supported within Emacs.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://kickingvegas.github.io/casual/EWW.html"&gt;Casual EWW&lt;/a&gt; is now available on &lt;a href="https://melpa.org/#/casual"&gt;MELPA&lt;/a&gt; in the &lt;a href="https://github.com/kickingvegas/casual/releases/tag/2.13.0"&gt;Casual v2.13.0 update&lt;/a&gt;.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry><entry><title>Announcing Casual HTML &amp; CSS</title><link href="http://yummymelon.com/devnull/announcing-casual-html-css.html" rel="alternate"/><published>2026-01-06T17:40:00-08:00</published><updated>2026-01-06T17:40:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2026-01-06:/devnull/announcing-casual-html-css.html</id><summary type="html">&lt;p&gt;Announcing Casual support for the HTML and CSS editing modes in Emacs.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Although I rarely code up HTML and CSS these days, knowing their basics have brought me compounding rewards time and time again. If you use Emacs, you’re in luck as it provides built-in editing modes for both. These modes can make short work of sculpting your web pages to be presentable to the world at large.&lt;/p&gt;
&lt;p&gt;Improving the discoverability of the features in these modes is what the latest &lt;a href="https://github.com/kickingvegas/casual/releases/tag/2.12.0"&gt;v2.12.0 update&lt;/a&gt; of Casual is all about. Announcing Casual menus for &lt;a href="https://kickingvegas.github.io/casual/HTML.html"&gt;HTML&lt;/a&gt; and &lt;a href="https://kickingvegas.github.io/casual/CSS.html"&gt;CSS&lt;/a&gt;, new for 2026, now available on &lt;a href="https://melpa.org/#/casual"&gt;MELPA&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Casual HTML&lt;/h1&gt;
&lt;p&gt;The main menu for HTML mode is shown below. Tag (&amp;lt;/&amp;gt;) operations for inserting, adding an attribute, closing, and deleting are supported.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/announcing-casual-html-css/casual-html-screenshot.png' alt='' /&gt;
&lt;/p&gt;

&lt;p&gt;HTML-specific tags are given their own menu.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/announcing-casual-html-css/casual-html-tags-screenshot.png' alt='' /&gt;
&lt;/p&gt;

&lt;h1&gt;Casual CSS&lt;/h1&gt;
&lt;p&gt;The main menu for CSS mode is shown below. A notable feature is the ability to lookup a CSS symbol from the Mozilla Developer Network (MDN) website using the built-in Emacs browser &lt;a href="https://www.gnu.org/software/emacs/manual/html_mono/eww.html"&gt;EWW&lt;/a&gt;.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/announcing-casual-html-css/casual-css-screenshot.png' alt='' /&gt;
&lt;/p&gt;

&lt;h1&gt;Closing Thoughts&lt;/h1&gt;
&lt;p&gt;Both HTML and CSS modes support Tree-sitter which offers nice structural navigation features. Although at the time of this writing (Emacs 30.2), using &lt;code&gt;html-ts-mode&lt;/code&gt; will break tag deletion (&lt;code&gt;sgml-tag-delete&lt;/code&gt;). On the other hand, I use &lt;code&gt;css-ts-mode&lt;/code&gt; without issue.&lt;/p&gt;
&lt;p&gt;If you haven't used either HTML or CSS modes yet, definitely give them a try using my Casual menus. I think you'll find them to be quite usable.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry><entry><title>Export Org to Markdown with the Clipboard</title><link href="http://yummymelon.com/devnull/export-org-to-markdown-with-the-clipboard.html" rel="alternate"/><published>2025-12-17T11:30:00-08:00</published><updated>2025-12-17T11:30:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-12-17:/devnull/export-org-to-markdown-with-the-clipboard.html</id><summary type="html">&lt;p&gt;A companion post to my last one on importing Markdown to Org, but the other way around.&lt;/p&gt;</summary><content type="html">&lt;p&gt;In symmetry with my post, &lt;a href="http://yummymelon.com/devnull/import-markdown-to-org-with-the-clipboard-in-emacs.html"&gt;Import Markdown to Org with the Clipboard in Emacs&lt;/a&gt;, exporting Org to Markdown via the system clipboard might be desired instead. Turns out, Marcin Borkowski has already done this as detailed in his post &lt;a href="https://mbork.pl/2021-05-02_Org-mode_to_Markdown_via_the_clipboard"&gt;Org-mode to Markdown via the clipboard&lt;/a&gt; with the function &lt;code&gt;org-copy-region-as-markdown&lt;/code&gt;. In my Emacs initialization, I’ve taken the liberty of prefixing that function name with &lt;code&gt;mb/&lt;/code&gt; to disambiguate it with actual functions from Org.&lt;/p&gt;
&lt;p&gt;If you prefer to write in Org but need to post in Markdown, definitely give Borkowski’s post a look.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="org mode"/><category term="markdown"/></entry><entry><title>Import Markdown to Org with the Clipboard in Emacs</title><link href="http://yummymelon.com/devnull/import-markdown-to-org-with-the-clipboard-in-emacs.html" rel="alternate"/><published>2025-12-04T13:30:00-08:00</published><updated>2025-12-04T13:30:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-12-04:/devnull/import-markdown-to-org-with-the-clipboard-in-emacs.html</id><summary type="html">&lt;p&gt;Import Markdown from other apps into your Org files easy.&lt;/p&gt;</summary><content type="html">&lt;p&gt;The preponderance of Markdown formatted text in both websites and apps is a blessing and a point of friction for Org users. The content is there, but if you’re an Org user, you really prefer the text to be formatted for Org. If you have &lt;a href="https://pandoc.org/index.html"&gt;Pandoc&lt;/a&gt; installed, converting from Markdown to Org is trivial but laborious as it involves making the right command invocation with temporary files.&lt;/p&gt;
&lt;p&gt;Thankfully, Emacs can automate this conversion as described in the workflow below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;From the source app or website, copy the Markdown into the system clipboard. This step pushes this text into the Emacs &lt;code&gt;kill-ring&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In Emacs, invoke a command which converts the above Markdown text into Org, then pastes (yanks) converted text into a desired Org file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that this workflow presumes that the Emacs &lt;code&gt;kill-ring&lt;/code&gt; is integrated with the system clipboard and that &lt;code&gt;pandoc&lt;/code&gt; is installed.&lt;/p&gt;
&lt;p&gt;The following Elisp command &lt;code&gt;cc/yank-markdown-as-org&lt;/code&gt; implements the above workflow:&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;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&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/yank-markdown-as-org&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;Yank Markdown text as Org.&lt;/span&gt;

&lt;span class="s"&gt;This command will convert Markdown text in the top of the &lt;/span&gt;&lt;span class="ss"&gt;`kill-ring&amp;#39;&lt;/span&gt;
&lt;span class="s"&gt;and convert it to Org using the pandoc utility.&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="k"&gt;save-excursion&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;with-temp-buffer&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;yank&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;shell-command-on-region&lt;/span&gt;
&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;point-min&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;point-max&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;pandoc -f markdown -t org --wrap=preserve&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&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;kill-region&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;point-min&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;point-max&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;yank&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;This command can be invoked in numerous ways including by key binding, context menu, Transient menu, and directly via &lt;code&gt;M-x&lt;/code&gt;. My preference is using the context menu as illustrated in the screenshot below to optimize for mouse copy/paste interactions between different apps.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/import-markdown-to-org/paste-markdown-as-org.png' alt='' /&gt;
&lt;/p&gt;

&lt;p&gt;Users interested in seeing how I’ve configured my context menu can &lt;a href="https://github.com/kickingvegas/cclisp/blob/98aad8329bc5788448fc9dde23b6e56bd4a3014c/cc-context-menu.el#L104"&gt;read the source here&lt;/a&gt;. Users unfamiliar with Emacs context menus can learn more about it in my post &lt;a href="http://yummymelon.com/devnull/customizing-the-emacs-context-menu.html"&gt;Customizing the Emacs Context Menu&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Closing Thoughts&lt;/h1&gt;
&lt;p&gt;Implementing &lt;code&gt;cc/yank-markdown-as-org&lt;/code&gt; turned out to be a lot more simpler than expected, as the command &lt;code&gt;shell-command-on-region&lt;/code&gt; does the heavy lifting in abstracting away the &lt;code&gt;pandoc&lt;/code&gt; command invocation and its handling of temporary files. This implementation can serve as a example for other conversions using the &lt;code&gt;kill-ring&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A word of thanks to mekeor on IRC for reminding me that &lt;code&gt;(point-min)&lt;/code&gt; and &lt;code&gt;(point-max)&lt;/code&gt; exist.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="org mode"/><category term="markdown"/></entry><entry><title>Announcing Casual CSV</title><link href="http://yummymelon.com/devnull/announcing-casual-csv.html" rel="alternate"/><published>2025-11-24T09:00:00-08:00</published><updated>2025-11-24T09:00:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-11-24:/devnull/announcing-casual-csv.html</id><summary type="html">&lt;p&gt;If you need to work with CSV files in Emacs, Casual with &lt;code&gt;csv-mode&lt;/code&gt; can help. Announcing Casual CSV, now available in the Casual v2.11.1 update.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Like &lt;a href="http://yummymelon.com/devnull/announcing-casual-make.html"&gt;Make&lt;/a&gt;, the CSV file format will outlive us all. That said, editing a CSV file is a precarious task, as it can be easy to violate its separator and escape rules. Thankfully, the Emacs ecosystem has got you covered, with the 3rd party ELPA package &lt;a href="https://elpa.gnu.org/packages/csv-mode.html"&gt;csv-mode&lt;/a&gt;. This mode provides all kinds of conveniences including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;spreadsheet-like visualizing and editing of fields (field alignment)&lt;/li&gt;
&lt;li&gt;separator auto-detection (comma, tab, space, etc.)&lt;/li&gt;
&lt;li&gt;support for quoted fields&lt;/li&gt;
&lt;li&gt;sorting by fields&lt;/li&gt;
&lt;li&gt;killing and yanking fields&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To aid in the discovery and usage of these features, I’m happy to announce &lt;a href="https://kickingvegas.github.io/casual/CSV.html"&gt;Casual CSV&lt;/a&gt;, a Transient menu for &lt;code&gt;csv-mode&lt;/code&gt;, now available in the &lt;a href="https://github.com/kickingvegas/casual/releases/tag/2.11.0"&gt;Casual v2.11.1 update&lt;/a&gt; on MELPA.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/announcing-casual-csv/casual-csv-edit-screenshot.png' alt='Screenshot of Casual CSV' /&gt;
&lt;/p&gt;

&lt;p&gt;One notable feature Casual CSV adds is the ability to select a region of rows to copy to the &lt;code&gt;kill-ring&lt;/code&gt; as an Org table. This is also usable in Markdown flavors that support tables.&lt;/p&gt;
&lt;h1&gt;Closing Thoughts and Caveats&lt;/h1&gt;
&lt;p&gt;YMMV on how well &lt;code&gt;csv-mode&lt;/code&gt; works for you as its performance is tied to the size of CSV file you are working with. If you are trying to edit a CSV file that is hundreds of megabytes in size or greater, you might want to think twice before doing this in Emacs with &lt;code&gt;csv-mode&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As a general rule, I try to avoid editing CSV files in the first place, as I prefer to think of them as files for data exchange. My ideal use-case for &lt;code&gt;csv-mode&lt;/code&gt; is really for viewing. That said, if you really need to edit a CSV file, it is best to copy it first. Casual CSV reflects this sensibility by offering a command to duplicate a file.&lt;/p&gt;
&lt;p&gt;To get the best results out of &lt;code&gt;csv-mode&lt;/code&gt;, I highly recommend turning on field alignment and separator auto-detection. In addition, turning off line-wrapping will aid in both visualization and navigation. The following Elisp configuration shows how to do this.&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="c1"&gt;;; disable line wrap&lt;/span&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;csv-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="nv"&gt;visual-line-mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;-1&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;toggle-truncate-lines&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;;; auto detect separator&lt;/span&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;csv-mode-hook&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;csv-guess-set-separator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;;; turn on field alignment&lt;/span&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;csv-mode-hook&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;csv-align-mode&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;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry><entry><title>Thoughts on Funding Free Software Development</title><link href="http://yummymelon.com/devnull/thoughts-on-funding-free-software-development.html" rel="alternate"/><published>2025-11-13T17:20:00-08:00</published><updated>2025-11-13T17:20:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-11-13:/devnull/thoughts-on-funding-free-software-development.html</id><summary type="html">&lt;p&gt;“I don’t like to dream about getting paid.”&lt;/p&gt;</summary><content type="html">&lt;p&gt;“I have always depended on the kindness of strangers.” — Blanche Dubois from “A Streetcar Named Desire”, Tennessee Williams.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;DISCLAIMER: None of this post should be considered as financial or career advice of any kind. All views and opinions expressed here belong solely to Charles Y. Choi.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Not getting paid for making free software has long been recognized as a conundrum in the early 21st century, where much of its  discourse is trenchantly summarized by the xkcd drawing “Dependency” &lt;a href="#citeproc_bib_item_1"&gt;[1]&lt;/a&gt; shown below.&lt;/p&gt;
&lt;p align='center'&gt;
&lt;img src='http://yummymelon.com/devnull/images/funding-free-software/dependency.png' alt='' /&gt;
&lt;/p&gt;

&lt;p&gt;For some time I’ve been gathering my thoughts on this matter, with stances that I’ll share in this post today.&lt;/p&gt;
&lt;h1&gt;Fundamentals on Bringing a Product to Market&lt;/h1&gt;
&lt;p&gt;Before talking about software, let’s review the basic steps needed to bring a physical product to market.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Design &amp;amp; Development&lt;/p&gt;
&lt;p&gt;In this step, the intellectual construction of the product is defined.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Manufacture&lt;/p&gt;
&lt;p&gt;In this step the product is mass produced. This step must occur after step 1.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Distribution&lt;/p&gt;
&lt;p&gt;In this step the manufactured product is delivered. This step must occur after step 2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Marketing&lt;/p&gt;
&lt;p&gt;In this step, awareness of the product to its target market is raised to induce demand for it. Ideally this step is taken when there is high confidence in delivering the product to the market.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Support&lt;/p&gt;
&lt;p&gt;In this step, the producers provide support for the product after it has shipped. This step must occur after step 3.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For a physical product, each step has a monetary cost associated with it. If the producer wishes to make a profit by selling the product, the price of the product must be greater than the cost to produce it. This leads to the incentive to manufacture and distribute as many copies as possible to maximize profit. At scale, the dominant costs are manufacturing and distribution for a physical product.&lt;/p&gt;
&lt;h1&gt;Software is Different&lt;/h1&gt;
&lt;p&gt;If the product is software using internet distribution, then its costs for manufacture and distribution become effectively zero. For a software provider, the dominant costs to bring a product to market are design &amp;amp; development, marketing, and support. Such costs are largely fixed with respect to demand. Since software has no intrinsic manufacturing nor distribution cost, for-profit software must resort to creating artificial scarcity to justify (and protect) profit that scales with meeting demand. Tactics to create scarcity include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Constraining code to be closed-source.&lt;/li&gt;
&lt;li&gt;Distributing only executables, typically code-signed to a model of computer.&lt;/li&gt;
&lt;li&gt;Compilation-enforced licensing, typically tied to a subscription model.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;What about Free Software?&lt;/h1&gt;
&lt;p&gt;With that background in place, let’s talk about &lt;em&gt;free&lt;/em&gt; (both in speech and beer) software. In this post, I make no distinction between free (libre) and open source licensed software &lt;a href="#citeproc_bib_item_2"&gt;[2]&lt;/a&gt; as their differences fixate on the user’s ability to modify and redistribute received software. In contrast, this post views &lt;em&gt;free&lt;/em&gt; software through the lens of the costs required to deliver said software to the market as described above.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Free software requires that its distribution be zero-cost to users&lt;/strong&gt;. In contrast with for-profit software, free software evades the creation of artificial scarcity. In light of this, what options are available for developers who want to get paid for making free software? Here are three:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ask users to voluntarily give money after the software has been produced.&lt;/li&gt;
&lt;li&gt;Attach the developed software to a service or hardware-based business model.&lt;/li&gt;
&lt;li&gt;Get money upfront from users (or organizations) who have an interest in realizing some specific software, &lt;em&gt;before&lt;/em&gt; its design and development are completed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The first option offers providers no financial incentive to make free software, nor offers a reliable path to cover the cost to make it.&lt;/p&gt;
&lt;p&gt;The second option relies on indirect compensation where the service or hardware revenue is expected to cover the cost of software development. Scarcity is imposed by restricting access to the service or hardware based on payment. This option is often taken by startups funded with venture capital.&lt;/p&gt;
&lt;p&gt;The third option offers direct financial incentive for the developer to create free software, as money is taken by the developer with the expectation that said software is delivered at a future date. With this option, the design &amp;amp; development step is what is considered scarce. Upfront funding can come in a variety of forms, but largely fall into the following patterns:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Institutional funding, where an organization puts up the funding.&lt;/li&gt;
&lt;li&gt;Angel funding, where a small group (&amp;lt; 5) of people contribute the funding.&lt;/li&gt;
&lt;li&gt;Crowdfunding, where a pool of small contributions from individuals (&amp;gt; 1,000) is gathered, typically with a target funding goal.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Which approach is taken can vary widely depending on the functionality of the software and the relationship (or lack thereof) between the developer and their benefactors. Note that getting money upfront to develop software &lt;em&gt;precludes gaining profit from it based on demand after it is made&lt;/em&gt;, as free software insists its distribution be zero-cost to users. The only avenue for developer profit in this case is to demand funding that exceeds the baseline cost of producing the software.&lt;/p&gt;
&lt;p&gt;Getting money upfront implies negotiation, which gives the developer agency to choose whether to commit to building the desired software. It also significantly raises risk to all involved parties if the software fails to be built.&lt;/p&gt;
&lt;p&gt;Upfront funding aligns the incentives for producers and consumers of software by having agreement on a future deliverable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consumers pay to get the future software deliverable.&lt;/li&gt;
&lt;li&gt;Producers work to build the future software deliverable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;While the exact number is unknown, I think a safe presumption is that single developers have built the vast majority of free software packages as evidenced by the Linux, Emacs, Python, and Node ecosystems. Most all of them resort to appeals to user gratuity, which is not enough to actually cover the market cost of designing &amp;amp; developing that software.&lt;/p&gt;
&lt;p&gt;Given the above options for upfront funding, I’ll further make the assumption that most single developers do not have access to institutional nor angel funding. So, let's talk about crowdfunding.&lt;/p&gt;
&lt;h1&gt;Crowdfunding&lt;/h1&gt;
&lt;p&gt;The dominant cost to producing software is labor. A common project scope is a three month schedule with a single developer. Estimating a market rate salary of $10K/month, this results in a budget of $30K to deliver software at cost.&lt;/p&gt;
&lt;p&gt;Crowdfunding has proven to be successful in raising that level of funding, by mitigating risk to all participants by defining a funding goal. Typically a funding goal is set within a window of time. If the goal is not met, then patrons who already put money down will have their money returned and the producer is not committed to work on the software. With high demand, the goal can be met with potentially low financial risk to an individual patron. For example, if 30,000 people gave $1, the above budget could be met.&lt;/p&gt;
&lt;p&gt;Reaching those 30,000 people is another thing altogether, as crowdfunding is an exercise in &lt;em&gt;marketing&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;To have a successful crowdfunding campaign, the producer must deliver a message about a future software product that is compelling enough to create demand for it. Common tasks undertaken to make a crowdfunding campaign include producing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A video describing the envisioned product.&lt;/li&gt;
&lt;li&gt;Marketing copy for said envisioned product published on web, possibly print.&lt;/li&gt;
&lt;li&gt;Brand merchandise for patrons.&lt;ul&gt;
&lt;li&gt;Order taking&lt;/li&gt;
&lt;li&gt;Fulfillment&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Press campaign.&lt;/li&gt;
&lt;li&gt;Social media campaign.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that the success of the crowdfunding campaign will depend on how effective its message is to the target audience. Each audience is bespoke, meaning that not all things successful for one crowdfunding campaign can be applied to another. Invariably, the software producer must know their audience.&lt;/p&gt;
&lt;p&gt;Single developers producing free software might look at the above and say “nope.” Most certainly it is a lot of work, much of which is perhaps outside the comfort level of persons whose focus has only been on coding. It is also not a common practice to use crowdfunding to support free (libre) or open source development. Regardless, if a developer wishes to be paid to work on free software, they will need to get comfortable with pitching their work beforehand to get the funding to do it. Wider-scale use of crowdfunding could bring better agency to the developer and enable the development of larger scope free software projects that would be untenable with volunteer time.&lt;/p&gt;
&lt;h1&gt;Observations and Closing Thoughts&lt;/h1&gt;
&lt;p&gt;This post has been a distillation of my thinking about free software and how it can be sustainably funded. From this exercise are some of my personal observations:&lt;/p&gt;
&lt;p&gt;If you have a software idea that you want to distribute for free, determine as soon as possible if you want to get paid to make it.&lt;/p&gt;
&lt;p&gt;If you don’t care about getting paid, ever, for that work, then GO MAKE IT! Be thankful for whatever gratuity you get from it.&lt;/p&gt;
&lt;p&gt;If you do care about getting paid to make the idea, then explore what funding model fits best for the idea. At this point, DO NOT MAKE THE IDEA AND PUBLISH IT.&lt;/p&gt;
&lt;p&gt;If you get funding, GO MAKE THE THING. MAKE PEOPLE HAPPY.&lt;/p&gt;
&lt;p&gt;If you don’t get funding, let it rest. Move on to the next idea.&lt;/p&gt;
&lt;p&gt;If you already produced free software that was built without funding, accept that you will never recover your development cost.&lt;/p&gt;
&lt;p&gt;To reiterate, free software requires that its distribution be zero-cost to users. This is excellent for user freedom but comes at the expense of agency for developers: Users can not be compelled to pay developers for their already published work. Developers can however make new features and fixes contingent on funding. I think this position is fair and defensible for the obvious reason that software developers must pay for the costs of living in a material world.&lt;/p&gt;
&lt;p&gt;If you’ve made to here, thanks for reading! Feel free to share your thoughts about this post on &lt;a href="https://sfba.social/@kickingvegas/115545442516504660"&gt;Mastodon&lt;/a&gt; or &lt;a href="https://www.reddit.com/r/emacs/comments/1owj8zo/thoughts_on_funding_free_software_development/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button"&gt;Reddit&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;style&gt;.csl-left-margin{float: left; padding-right: 0em;}
 .csl-right-inline{margin: 0 0 0 1em;}&lt;/style&gt;
&lt;div class="csl-bib-body"&gt;
  &lt;div class="csl-entry"&gt;&lt;a id="citeproc_bib_item_1"&gt;&lt;/a&gt;
    &lt;div class="csl-left-margin"&gt;[1]&lt;/div&gt;&lt;div class="csl-right-inline"&gt;R. Munroe, “Dependency,” Aug. 17, 2020. Available: &lt;a href="https://xkcd.com/2347/"&gt;https://xkcd.com/2347/&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="csl-entry"&gt;&lt;a id="citeproc_bib_item_2"&gt;&lt;/a&gt;
    &lt;div class="csl-left-margin"&gt;[2]&lt;/div&gt;&lt;div class="csl-right-inline"&gt;R. Stallman, “Why open source misses the point of free software - gnu project - free software foundation,” 2024. Available: &lt;a href="https://www.gnu.org/philosophy/open-source-misses-the-point.en.html"&gt;https://www.gnu.org/philosophy/open-source-misses-the-point.en.html&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</content><category term="misc"/><category term="emacs"/><category term="software"/><category term="musings"/></entry><entry><title>Prototyping a Toolbar UI for Edebug</title><link href="http://yummymelon.com/devnull/prototyping-a-toolbar-ui-for-edebug.html" rel="alternate"/><published>2025-11-03T13:55:00-08:00</published><updated>2025-11-03T13:55:00-08:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-11-03:/devnull/prototyping-a-toolbar-ui-for-edebug.html</id><summary type="html">&lt;p&gt;Where a prototype toolbar UI for Edebug is made available for public scrutiny.&lt;/p&gt;</summary><content type="html">&lt;p&gt;About a year and a half ago I delved into understanding Edebug (&lt;a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Edebug.html"&gt;(elisp) Edebug&lt;/a&gt;), the built-in debugger for Emacs Lisp (Elisp), as I was to give a &lt;a href="http://yummymelon.com/presentations/demystifying-edebug/demystifying-edebug.html"&gt;presentation on it&lt;/a&gt; at the &lt;a href="https://www.meetup.com/emacs-sf/"&gt;Emacs SF meetup&lt;/a&gt;. For new users, Edebug can be bewildering as it forces them to know beforehand its many commands and respective keybindings to make good use of it. Because of this complexity, many users writing Elisp often favor simple print-style debugging to avoid ever dealing with Edebug.&lt;/p&gt;
&lt;p&gt;My dive into Edebug however left me with the impression that it was more a “kit of parts” in need of a good UI. So I set about to build an Edebug UI with Transient menus. The result of that effort was decidedly mixed. More often than not, window/frame management by Edebug would conflict with Transient. I shelved it.&lt;/p&gt;
&lt;p&gt;Working on the toolbar icons for &lt;a href="https://github.com/kickingvegas/calle24"&gt;Calle 24&lt;/a&gt;, the thought occurred: what about a toolbar for Edebug? The results I think are much more successful, with a number of caveats that I’ll get to later. As far as successes, here’s what I think this toolbar brings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Similarity to conventional IDE debuggers.&lt;/li&gt;
&lt;li&gt;Avoidance of Edebug window/frame management.&lt;/li&gt;
&lt;li&gt;Improved discovery of Edebug features.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The screenshot below shows this toolbar in action:&lt;/p&gt;
&lt;p align="center"&gt;
&lt;img src="http://yummymelon.com/devnull/images/edebug-ui/calle24-edebug.png" /&gt;
&lt;/p&gt;

&lt;p&gt;Motivated readers are invited to try this toolbar out using the instructions described in &lt;a href="https://github.com/kickingvegas/calle24?tab=readme-ov-file#edebug-support"&gt;Calle 24 Edebug Support&lt;/a&gt;. If you have a prior installation of Calle 24 installed, you should update and re-run the command &lt;code&gt;calle24-install&lt;/code&gt; to synchronize with the latest icon set in the v1.1.1 update on &lt;a href="https://melpa.org/#/calle24"&gt;MELPA&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;Edebug differences from other IDE debuggers&lt;/h1&gt;
&lt;p&gt;Users new to Edebug but familiar with debuggers for ALGOL-like languages (C, Java, Python, Swift, etc.) should understand that stepping through Elisp code is &lt;em&gt;sexp&lt;/em&gt;-based. This distinction is significant when considering stepping into and out of an sexp, which is not the same as a function in ALGOL-like languages. Also, breakpoints can only be set during an Edebug session. If the Edebug-instrumented function is re-evaluated using &lt;code&gt;eval-defun&lt;/code&gt;, all prior breakpoints defined for it are &lt;em&gt;lost&lt;/em&gt;.&lt;/p&gt;
&lt;h1&gt;Caveats&lt;/h1&gt;
&lt;p&gt;Despite my enthusiasm for this toolbar, this should be considered prototype code for the following reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There is an existing bug in the NS variant of GNU Emacs 30.1 where repeated rapid pressing of a toolbar button can force Emacs into a state where it is not responsive to GUI input. Bug reports can be found at &lt;a href="https://debbugs.gnu.org/cgi/bugreport.cgi?bug=76749"&gt;#76749&lt;/a&gt;, &lt;a href="https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72496"&gt;#72496&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Both NS and GTK variants can only show toolbar icons in a single row.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;window-tool-bar-mode&lt;/code&gt; does not support appearance changes (dark, light mode).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The licensing of SF Symbols icons precludes their distribution using a GPLv3 license.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Closing Thoughts&lt;/h1&gt;
&lt;p&gt;In many ways, building this toolbar has been a “proof of concept” for me in answering the question: can Edebug have a better UI? I think the answer is a resounding yes, so much so that I’ve decided to put it out in public for others to scrutinize. By no means do I consider this “finished product” given the caveats described above. That said, for those folks who decide to give it a try I’d be interested to know &lt;a href="https://github.com/kickingvegas/calle24/discussions/60"&gt;your thoughts&lt;/a&gt;.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/></entry><entry><title>Announcing Casual Ediff</title><link href="http://yummymelon.com/devnull/announcing-casual-ediff.html" rel="alternate"/><published>2025-10-30T07:00:00-07:00</published><updated>2025-10-30T07:00:00-07:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-10-30:/devnull/announcing-casual-ediff.html</id><summary type="html">&lt;p&gt;Where an earnest attempt is made to improve the usability of Ediff for sensibilities in 2025.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Truth be told, I find default Ediff to be weird and intimidating compared to other tools that do the same thing, which is to find differences between two files. Like other modes, Ediff is reliant on the user knowing beforehand its commands and respective keybindings, which means it has a steep learning curve. Many of these commands are context specific. While Ediff tries to be helpful by displaying a cheat sheet, I find this feature to be so information dense and context-free (in a bad way) that it usually results in upping my anxiety. I mean, look at this table!&lt;/p&gt;
&lt;p align="center"&gt;
&lt;img src="http://yummymelon.com/devnull/images/announcing-casual-ediff/ediff-interface.png" / &gt;
&lt;/p&gt;

&lt;p&gt;That said, I’m not here to bury Ediff, but to praise it. Ediff is embarrassingly rich in functionality and time-tested. It just needs a better UI, which brings us to today’s post topic: Announcing Casual support for Ediff.&lt;/p&gt;
&lt;p&gt;The approach Casual takes is to provide a Transient menu for the Ediff control panel, which is configured to be in the same frame as the windows holding the compared files. This menu organizes relevant commands in sections that map to the files being compared and does its best to be context-sensitive (e.g. determine if the buffer is writable or read-only, know if its a file comparision or a merge, etc.).&lt;/p&gt;
&lt;p&gt;The result is an interface that is calmer to my eyes, as shown below.&lt;/p&gt;
&lt;p align="center"&gt;
&lt;img src="http://yummymelon.com/devnull/images/announcing-casual-ediff/casual-ediff-basic-screenshot.png" /&gt;
&lt;/p&gt;

&lt;p&gt;Casual Ediff builds on the work described in my earlier blog post &lt;a href="http://yummymelon.com/devnull/using-ediff-in-2023.html"&gt;Using Ediff in 2023&lt;/a&gt;, in providing a streamlined way to diff a modified version-controlled file. This way, if you already have the file loaded in a window, you can call &lt;code&gt;casual-ediff-revision&lt;/code&gt; to immediately see what changes you’ve made to it and to selectively be able to revert each change.&lt;/p&gt;
&lt;p align="center"&gt;
&lt;img src="http://yummymelon.com/devnull/images/announcing-casual-ediff/casual-ediff-screenshot.png" /&gt;
&lt;/p&gt;

&lt;p&gt;Casual Ediff also lets you resolve merge conflicts (typically from Magit). Added to Ediff is the ability to merge &lt;em&gt;both&lt;/em&gt; conflicting differences in the order of choice by the user (the menu items “Merge A,B to C”, “Merge B,A to C”).&lt;/p&gt;
&lt;p align="center"&gt;
&lt;img src="http://yummymelon.com/devnull/images/announcing-casual-ediff/casual-ediff-merge-conflict.png" /&gt;
&lt;/p&gt;

&lt;p&gt;Read more about Casual Ediff at &lt;a href="https://kickingvegas.github.io/casual/Ediff.html"&gt;Ediff (Casual User Guide)&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Casual Ediff is now available on MELPA as part of the &lt;a href="https://github.com/kickingvegas/casual/releases/tag/2.10.0"&gt;v2.10.0 update for Casual&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It costs money to make, enhance, and maintain Casual as ideologically free software. If you enjoy using Casual, please consider a &lt;a href="https://buymeacoffee.com/kickingvegas"&gt;financial contribution&lt;/a&gt; to help support its development and maintenance. Thanks!&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry><entry><title>Storing a Link from your Web Browser to BibTeX using Org protocol</title><link href="http://yummymelon.com/devnull/storing-a-link-from-your-web-browser-to-bibtex-using-org-protocol.html" rel="alternate"/><published>2025-09-25T16:15:00-07:00</published><updated>2025-09-25T16:15:00-07:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-09-25:/devnull/storing-a-link-from-your-web-browser-to-bibtex-using-org-protocol.html</id><summary type="html">&lt;p&gt;Automate writing a BibTeX Online entry to Emacs from your web browser using Org protocol.&lt;/p&gt;</summary><content type="html">&lt;p&gt;If you’re familiar with this blog, you’ll know that I’m a fan of &lt;a href="https://orgmode.org/worg/org-contrib/org-protocol.html"&gt;Org protocol&lt;/a&gt;, a means of sending data such as web links and content to an Org file from outside of Emacs. Following up on my last &lt;a href="http://yummymelon.com/devnull/announcing-casual-bibtex.html"&gt;post on Casual BibTeX&lt;/a&gt;, this post will show how to re-purpose Org protocol to send a link from your preferred web browser to a BibTeX file.&lt;/p&gt;
&lt;p&gt;This is achieved by adding the following template (named “bib”) to the variable &lt;code&gt;org-capture-templates&lt;/code&gt; as shown below:&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;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&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-to-list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;org-capture-templates&lt;/span&gt;
&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;bib&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;BibTex Online Entry&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="nv"&gt;plain&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;file&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;~/org/bib/references.bib&amp;quot;&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;function&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="nv"&gt;string-join&lt;/span&gt;
&lt;span class="w"&gt;                            &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;@Online {,&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;author = {%^{Author(s)}},&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;organization = {%^{Organization}},&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;title = {%:description},&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;url = {%:link},&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date = {%&amp;lt;%Y-%m-%d&amp;gt;%?},&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;notes = {&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;%i&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;}&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;                                  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;}&amp;quot;&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;\n&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="nb"&gt;:prepend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;t&lt;/span&gt;
&lt;span class="w"&gt;               &lt;/span&gt;&lt;span class="nb"&gt;:empty-lines-after&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&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;The web link is treated as an BibTeX &lt;code&gt;Online&lt;/code&gt; entry type whose fields are populated as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;url&lt;/code&gt; field holds the web page link.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title&lt;/code&gt; field holds the web page title.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;date&lt;/code&gt; is populated with the current day (this should be edited to the actual date).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;notes&lt;/code&gt; is populated with the body value according to the &lt;a href="https://orgmode.org/manual/The-capture-protocol.html"&gt;capture protocol&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;author&lt;/code&gt; is populated with the value entered via mini-buffer prompt.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;organization&lt;/code&gt; is populated with the value entered via mini-buffer prompt, typically the name of the website.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The template is configured to prepend (via the &lt;code&gt;:prepend&lt;/code&gt; property) the captured &lt;code&gt;Online&lt;/code&gt; entry to the file “~/org/bib/references.bib”. These values can be adjusted to taste.&lt;/p&gt;
&lt;p&gt;When invoking this template via Org protocol, a temporary capture window holding the populated template is created. This entry will not have a citation key, so it is recommended to run &lt;code&gt;M-x&lt;/code&gt; &lt;code&gt;bibtex-clean-entry&lt;/code&gt; to generate it before committing the capture via &lt;code&gt;C-c C-c&lt;/code&gt;. If you have &lt;a href="https://kickingvegas.github.io/casual/BibTeX.html"&gt;Casual BibTeX&lt;/a&gt; installed, you can invoke the Transient menu &lt;code&gt;casual-bibtex-tmenu&lt;/code&gt; with the binding &lt;code&gt;M-m&lt;/code&gt; and invoke the clean command from there.&lt;/p&gt;
&lt;h1&gt;Closing Thoughts&lt;/h1&gt;
&lt;p&gt;Arguably, Org protocol was not designed to support files other than those using Org markup, so the above practice skirts its design intent by sending the capture to a BibTeX file. But as of Emacs 30.2 and Org 9.7.34, this works fine, so YOLO. Users intent on customizing the above “bib” template should be advised that many &lt;a href="https://orgmode.org/manual/Template-elements.html"&gt;template properties&lt;/a&gt; are not supported, so be advised.&lt;/p&gt;
&lt;p&gt;That all said, it’s a nice win to automate the task of writing a BibTeX &lt;code&gt;Online&lt;/code&gt; entry.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="org mode"/></entry><entry><title>Announcing Casual BibTeX</title><link href="http://yummymelon.com/devnull/announcing-casual-bibtex.html" rel="alternate"/><published>2025-09-24T16:00:00-07:00</published><updated>2025-09-24T16:00:00-07:00</updated><author><name>Charles Choi</name></author><id>tag:yummymelon.com,2025-09-24:/devnull/announcing-casual-bibtex.html</id><summary type="html">&lt;p&gt;Announcing Casual support for BibTeX, a bibilography database.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Given current events, the importance of having a shared and testable truth is arguably the only thing that matters these days. A time-honored practice to reaching such truth is to write and distribute documentation with good references.&lt;/p&gt;
&lt;p&gt;Emacs has long had support for BibTeX, &lt;a href="https://www2.eecs.berkeley.edu/Pubs/TechRpts/1987/6006.html#:~:text=http://www2.eecs.berkeley,and%20a%20draft%20making%20facility."&gt;going as far back as 1987&lt;/a&gt;. &lt;a href="https://bibtex.eu"&gt;BibTeX&lt;/a&gt; is both a bibliography processor for &lt;a href="https://www.latex-project.org"&gt;LaTeX&lt;/a&gt; documents and more importantly, a database schema for bibliographic data. The significance of the latter allows for using a BibTeX database for contexts outside of LaTeX.&lt;/p&gt;
&lt;p&gt;BibTeX organizes bibliographic data into a collection of records (or entries) that are stored in a plain-text file (multiple files are also supported). This plain-text file is identified using a “.bib” suffix and is treated as a database. Any plain-text editor can edit a BibTeX file. This can be seen, especially with 2025 eyes, as a virtue or an anathema. Because the BibTeX database is just a plain-text file, schema enforcement ultimately rests upon the user editing the file.&lt;/p&gt;
&lt;p&gt;The Emacs built-in package &lt;code&gt;bibtex&lt;/code&gt; tries to help shoulder this schema enforcement by providing commands for both navigating and editing BibTeX data structures (entries and the fields within an entry). In this way, &lt;code&gt;bibtex&lt;/code&gt; tries to provide the user a quasi-“form-based” interface to editing a BibTeX file.&lt;/p&gt;
&lt;p&gt;Like many other Emacs modes, I find the commands for &lt;code&gt;bibtex-mode&lt;/code&gt; to be difficult to both discover and recall. I also find &lt;code&gt;bibtex-mode&lt;/code&gt; to not be opinionated enough in trying to provide a form-based experience.&lt;/p&gt;
&lt;p&gt;To address this, I’m happy to announce the latest &lt;a href="https://melpa.org/#/casual"&gt;Casual&lt;/a&gt; addition: support for &lt;a href="https://kickingvegas.github.io/casual/BibTeX.html"&gt;BibTeX&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="http://yummymelon.com/devnull/images/announcing-casual-bibtex/casual-bibtex-screenshot.png" /&gt;&lt;/p&gt;
&lt;p&gt;Casual BibTeX organizes &lt;code&gt;bibtex&lt;/code&gt; commands into a Transient menu. The bindings remap conventional Emacs navigation bindings for field or entry navigation. Casual BibTeX holds the strong opinion that creation, update, or deletion of either an entry or a field should be done via commands dedicated for those respective operations. Using manual editing of the BibTeX file to achieve the same end is discouraged.&lt;/p&gt;
&lt;p&gt;If you are invested in Org, knowing how to work with BibTeX has great benefit as Org has &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/org/Citation-handling.html#Citation-handling"&gt;extensive citation support&lt;/a&gt; for it.&lt;/p&gt;
&lt;p&gt;Casual BibTeX is now available in the &lt;a href="https://github.com/kickingvegas/casual/releases/tag/2.9.0"&gt;v2.9.0 update of Casual&lt;/a&gt; on &lt;a href="https://melpa.org/#/casual"&gt;MELPA&lt;/a&gt;. Learn more about Casual BibTeX in its &lt;a href="https://kickingvegas.github.io/casual/BibTeX.html"&gt;documentation&lt;/a&gt;.&lt;/p&gt;</content><category term="misc"/><category term="emacs"/><category term="casual"/></entry></feed>