<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/assets/rss.xsl" type="text/xsl"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
>
<channel>
	<title>Sacha Chua - category - emacs</title>
	<atom:link href="https://sachachua.com/blog/category/emacs/feed/index.xml" rel="self" type="application/rss+xml" />
	<atom:link href="https://sachachua.com/blog/category/emacs" rel="alternate" type="text/html" />
	<link>https://sachachua.com/blog/category/emacs/feed/index.xml</link>
	<description>Emacs, sketches, and life</description>
	<lastBuildDate>Mon, 06 Apr 2026 14:36:57 GMT</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>11ty</generator>
  <item>
		<title>YE12: Categorizing Emacs News, epwgraph, languages</title>
		<link>https://sachachua.com/blog/2026/04/ye12-categorizing-emacs-news-epwgraph-languages/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Mon, 06 Apr 2026 14:36:57 GMT</pubDate>
    <category>emacs</category>
<category>stream</category>
<category>yay-emacs</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/04/ye12-categorizing-emacs-news-epwgraph-languages/</guid>
		<description><![CDATA[<p>
<video controls="1" src="https://archive.org/download/2026-04-06-ye-12-emacs-news-epwgraph-languages/2026-04-06-ye12-emacs-news-epwgraph-languages.mp4" type="video/mp4"></video>
</p>

<p>
<a href="https://archive.org/details/2026-04-06-ye-12-emacs-news-epwgraph-languages">View in the Internet Archive</a>, <a href="https://youtube.com/live/zMcyTAOG0i8">watch or comment on YouTube</a>, or <a href="mailto:sacha@sachachua.com">email me</a>.
</p>

<p>
Chapters:
</p>

<ul class="org-ul">
<li><span class="media-time" data-start="2481.000">00:41:21</span> epwgraph</li>
<li><span class="media-time" data-start="3296.000">00:54:56</span> learning languages</li>
</ul>

<p>
Thanks for your patience with the audio issues! At some point, I need to work out the contention between all the different processes that I want to be listening to the audio from my mic. =)
</p>

<p>
In this livestream, I categorize <a href="https://sachachua.com/blog/2026/04/2026-04-06-emacs-news/">Emacs News for 2026-04-06</a>, show <a href="https://github.com/sachac/epwgraph">epwgraph</a> for managing Pipewire connections from Emacs, and share some of my <a href="https://codeberg.org/sachac/learn-lang/">language learning workflows</a>.
</p>
<div><a href="https://sachachua.com/blog/2026/04/ye12-categorizing-emacs-news-epwgraph-languages/index.org">View Org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F04%2Fye12-categorizing-emacs-news-epwgraph-languages%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>2026-04-06 Emacs news</title>
		<link>https://sachachua.com/blog/2026/04/2026-04-06-emacs-news/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Mon, 06 Apr 2026 12:00:00 GMT</pubDate>
    <category>emacs</category>
<category>emacs-news</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/04/2026-04-06-emacs-news/</guid>
		<description><![CDATA[<p>
There's a lot of buzz around the remote code
execution thing that involves Git, but it seems to be
more of a Git issue than an Emacs one. <a href="https://github.com/califio/publications/blob/main/MADBugs/vim-vs-emacs-vs-claude/Emacs.md">This might
be a workaround</a> if you want, and in the meantime,
don't check out git repositories you don't trust.
There's no page for the <a href="https://www.emacswiki.org/emacs/Carnival">Emacs Carnival</a> for April
yet, but you can start thinking about the theme of
"newbies/starter kits" already, and I'm sure Cena
or someone will round things up afterwards. Enjoy!
</p>

<ul class="org-ul">
<li><a href="https://github.com/califio/publications/blob/main/MADBugs/vim-vs-emacs-vs-claude/Emacs.md">Workaround for the Git-related security issue that lots of people are talking about</a> (<a href="https://social.tchncs.de/@stackeffect/116327976371248454">@stackeffect@social.tchncs.de</a>)</li>
<li>Upcoming events (<a href="https://emacslife.com/calendar/emacs-calendar.ics">iCal file</a>, <a href="https://emacslife.com/calendar/">Org</a>):
<ul class="org-ul">
<li>Emacs.si (in person): Emacs.si meetup #4 2026 (v #živo) <a href="https://dogodki.kompot.si/events/c4ee8c26-c668-491e-91b3-b466578b83e2">https://dogodki.kompot.si/events/c4ee8c26-c668-491e-91b3-b466578b83e2</a> Mon Apr 6 1900 CET</li>
<li>Emacs Paris: S: Emacs workshop in Paris (online) <a href="https://emacs-doctor.com/">https://emacs-doctor.com/</a> Tue Apr 7 0830 America/Vancouver - 1030 America/Chicago - 1130 America/Toronto - 1530 Etc/GMT - 1730 Europe/Berlin - 2100 Asia/Kolkata - 2330 Asia/Singapore</li>
<li>OrgMeetup (virtual) <a href="https://orgmode.org/worg/orgmeetup.html">https://orgmode.org/worg/orgmeetup.html</a> Wed Apr 8 0900 America/Vancouver - 1100 America/Chicago - 1200 America/Toronto - 1600 Etc/GMT - 1800 Europe/Berlin - 2130 Asia/Kolkata &ndash; Thu Apr 9 0000 Asia/Singapore</li>
<li>Atelier Emacs Montpellier (in person) <a href="https://lebib.org/date/atelier-emacs">https://lebib.org/date/atelier-emacs</a> Fri Apr 10 1800 Europe/Paris</li>
<li>London Emacs (in person): Emacs London meetup <a href="https://www.meetup.com/london-emacs-hacking/events/313909207/">https://www.meetup.com/london-emacs-hacking/events/313909207/</a> Tue Apr 14 1800 Europe/London</li>
<li>Emacs Berlin: In-Person-Only Emacs-Berlin Stammtisch <a href="https://emacs-berlin.org/">https://emacs-berlin.org/</a> Tue Apr 14 1900 Europe/Berlin</li>
<li>M-x Research: TBA <a href="https://m-x-research.github.io/">https://m-x-research.github.io/</a> Wed Apr 15 0800 America/Vancouver - 1000 America/Chicago - 1100 America/Toronto - 1500 Etc/GMT - 1700 Europe/Berlin - 2030 Asia/Kolkata - 2300 Asia/Singapore</li>
<li><a href="https://protesilaos.com/codelog/2026-04-04-emacs-live-with-sacha-chua/">Protesilaos Stavrou: Emacs live stream with Sacha Chua on 2026-04-16 17:30 Europe/Athens</a></li>
</ul></li>
<li>Emacs configuration:
<ul class="org-ul">
<li><a href="http://yummymelon.com/devnull/announcing-anju.html">Announcing Anju</a> (<a href="https://www.reddit.com/r/emacs/comments/1s7un9y/announcing_anju/">Reddit</a>) - mouse interactions for modeline, context menu, and main menu</li>
<li><a href="https://emacsredux.com/blog/2026/04/04/repeat-mode/">Emacs Redux: Repeat Mode: Stop Repeating Yourself</a> (<a href="https://irreal.org/blog/?p=13722">Irreal</a>)</li>
<li><a href="https://github.com/shackra/backpack">backpack 0.4.0 - adds self-documenting inventory browser</a> (<a href="https://www.reddit.com/r/emacs/comments/1sab5si/backpack_emacs_version_040/">Reddit</a>)</li>
</ul></li>
<li>Emacs Lisp:
<ul class="org-ul">
<li><a href="https://almightylisp.com/">Almighty Lisp: Lisp &amp; Emacs Essentials - almightylisp.com</a> (<a href="https://news.ycombinator.com/item?id=47612277">HN</a>)</li>
<li><a href="https://blog.davep.org/2026/04/03/nukneval-el-v1-3.html">Dave Pearson: nukneval.el v1.3</a> unload and re-evaluate</li>
<li><a href="https://www.youtube.com/watch?v=FUAXrMbY9nE">Creating an Emacs Package from Concept to MELPA (Part 7)</a> (57:13)</li>
<li><a href="https://www.reddit.com/r/emacs/comments/1sduilc/how_to_run_a_function_when_my_buffer_selection/">How to run a function when my buffer selection changes?</a> - updated with window-state-change-hook</li>
<li><a href="https://www.youtube.com/watch?v=9CV5pTIM7Vk">Yay Emacs live: Reorganizing my Emacs configuration so that my defuns are tangled to separate files</a> (01:48:56)</li>
<li><a href="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/">Sacha Chua: YE11: Fix find-function for Emacs Lisp from org-babel or scratch</a> (<a href="https://www.youtube.com/watch?v=PKkV1Tbev_Y">YouTube</a>, 08:19)</li>
</ul></li>
<li>Appearance:
<ul class="org-ul">
<li><a href="https://codeberg.org/phmcc/outline-stars">New package: outline-stars.el</a> (<a href="https://www.reddit.com/r/emacs/comments/1sayd4i/new_package_outlinestarsel/">Reddit</a>)</li>
<li><a href="https://github.com/agzam/occult.el">occult.el - collapse buffer regions into single-line summaries</a> (<a href="https://www.reddit.com/r/emacs/comments/1s7xiti/tiny_package_may_come_handy/">Reddit</a>)</li>
<li><a href="https://www.reddit.com/r/emacs/comments/1s83i2i/make_the_left_margin_shine/">Make the left margin shine!</a></li>
<li><a href="https://github.com/Senka07/yotsuba-emacs-theme">Senka07/yotsuba-emacs-theme · GitHub</a> (<a href="https://www.reddit.com/r/emacs/comments/1s8joc7/i_made_a_theme_for_emacs_based_on_the_yotsuba/">Reddit</a>)</li>
</ul></li>
<li>Navigation:
<ul class="org-ul">
<li><a href="https://snac.lab8.cz/mattof/p/1775377168.159080">Tip about using other-window-prefix C-x 4 4</a></li>
<li><a href="https://fe.disroot.org/objects/c9be1ac9-8404-4114-8787-3cc4ba6957e6">Tip about using windmove</a></li>
</ul></li>
<li>Writing:
<ul class="org-ul">
<li><a href="https://curtismchale.ca/2026/03/31/check-spelling-in-emacs">Curtis McHale: Check Spelling in Emacs</a> (<a href="https://www.youtube.com/watch?v=LML6pnwLcKE">YouTube</a> 06:38)</li>
<li><a href="https://blog.davep.org/2026/04/05/blogmore-el-v3-1.html">Dave Pearson: blogmore.el v3.1</a></li>
</ul></li>
<li>Denote:
<ul class="org-ul">
<li><a href="https://protesilaos.com/codelog/2026-04-03-emacs-denote-sequence-new-alphanumeric-delimited-scheme/">Protesilaos Stavrou: Emacs: new sequence scheme for the ‘denote-sequence’ package</a></li>
</ul></li>
<li>Org Mode:
<ul class="org-ul">
<li><a href="https://www.youtube.com/watch?v=k2-9DS7jZyg">[EMACS LAB] #3: Introduction to Org Mode</a> (01:57:55)</li>
<li><a href="https://github.com/aravindps/org-gtd">aravindps/org-gtd: Things 3 style GTD for Emacs — org-mode agenda views, ⌘ keybindings, context tags. Works with Doom and vanilla Emacs. · GitHub</a> (<a href="https://www.reddit.com/r/emacs/comments/1s86q3t/nonemacs_person_accidentally_built_a_gtd_thing_in/">r/emacs</a>, <a href="https://www.reddit.com/r/orgmode/comments/1s8cuwd/work_blocked_gtd_apps_so_i_built_my_own_plaintext/">r/orgmode</a>)</li>
<li><a href="https://list.orgmode.org/orgmode/87pl4lul8r.fsf@localhost/">[BLOG] #27 bbb:OrgMeetup on Wed, February 11, 19:00 UTC+3 - Ihor Radchenko</a> (<a href="https://fosstodon.org/@yantar92/116320012163184817">@yantar92@fosstodon.org</a>) notes</li>
<li>Import, export, and integration:
<ul class="org-ul">
<li><a href="https://github.com/lopeztel/ox-dnd-html">lopeztel/ox-dnd-html: Emacs export org files to D&amp;D themed html · GitHub</a> (<a href="https://www.reddit.com/r/emacs/comments/1scdtlw/oxdndhtml/">Reddit</a>)</li>
<li><a href="https://chatziiola.github.io/posts/20251216_adding-org-protocol-support.html">Adding org-protocol support</a> (<a href="https://www.reddit.com/r/orgmode/comments/1s9g7xt/orgprotocol_capture_my_configuration/">Reddit</a>)</li>
<li><a href="https://sachachua.com/blog/2026/04/demo-extract-pdf-highlights-into-an-org-file-with-python/">Sacha Chua: Extract PDF highlights into an Org file with Python</a> (<a href="https://www.youtube.com/watch?v=OTnYV2IZL_U">YouTube</a> 04:27)</li>
<li><a href="https://jamesendreshowell.com/2026-04-04-my-first-advice-in-emacs-lisp.html">James Endres Howell: My first advice! (in Emacs Lisp)</a> - specifying HTML boilerplace for org-static-blog</li>
<li><a href="https://thibaut.dev/blog/org-publish-rss.html">RSS feeds for your org-mode website</a> (<a href="https://toot.io/@bgtdsword/116353992060134650">@bgtdsword@toot.io</a>)</li>
<li><a href="https://www.youtube.com/watch?v=oBkzkDutLCI">Org-mode - Various font sizes LaTeX</a> (04:14)</li>
</ul></li>
<li>Org development:
<ul class="org-ul">
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=62cad0194b2ac91b3de85caab33e40bef9eeb2a4">ol: Allow targets as search option in id: links</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=8c24e4bb5378e71141fdcc4278bc005ced00f126">org-babel: Fix and extend `org-babel-update-intermediate' variable</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=972d5c2ba44fe8afd6cdcdee8952d244a1d4078b">Query before attempting to overwrite existing attachment/DnD/yank file</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=f57de9dac30231e731a3622f0897d9a945762ae0">Merge branch 'bugfix'</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=c1b4247115c198761cd9dbb7703833bc4de6378b">etc/ORG-NEWS: Remove announcement about bugfix</a></li>
</ul></li>
</ul></li>
<li>Completion:
<ul class="org-ul">
<li><a href="https://emacsredux.com/blog/2026/04/04/read-extended-command-predicate/">Emacs Redux: Declutter M-x with read-extended-command-predicate</a></li>
<li><a href="https://github.com/gggion/let-completion.el">[RELEASE] let-completion v0.2.0: full overhaul of Elisp completion - 46 binding forms, function argument candidates, expandable registry, fully customizable two-column annotations</a> (<a href="https://www.reddit.com/r/emacs/comments/1s8pde5/release_letcompletion_v020_full_overhaul_of_elisp/">Reddit</a>)</li>
<li><a href="https://github.com/rougier/nano-vertico">rougier/nano-vertico: Emacs / nano + vertico · GitHub</a> (<a href="https://www.reddit.com/r/emacs/comments/1s9deym/nano_vertico_tui/">Reddit</a>)</li>
</ul></li>
<li>Coding:
<ul class="org-ul">
<li><a href="https://mwolson.org/blog/2026-04-02-eglot-python-preset-and-eglot-typescript-preset-now-on-melpa/">Mike Olson - eglot-python-preset and eglot-typescript-preset: Now on MELPA</a> (<a href="https://www.reddit.com/r/emacs/comments/1sb1f8b/multilsp_support_for_python_and_typescript_in/">Reddit</a>)</li>
<li><a href="https://www.reddit.com/r/emacs/comments/1sano0b/function_to_make_eglot_add_iwyu_headers_without/">Function to make eglot add IWYU headers without doing an autocomplete in the buffer</a></li>
<li><a href="https://blog.davep.org/2026/04/03/make-phony-el-v1-3.html">Dave Pearson: make-phony.el v1.3</a> for Makefiles</li>
<li><a href="https://github.com/Daskeladden/shipit">Daskeladden/shipit: Code review in Emacs · GitHub</a> (<a href="https://www.reddit.com/r/emacs/comments/1s8qmj2/shipit_code_review_without_leaving_emacs/">Reddit</a>)</li>
</ul></li>
<li>Shells:
<ul class="org-ul">
<li><a href="https://github.com/dakra/ghostel">Ghostel - terminal emulator powered by libghostty</a> (<a href="https://www.reddit.com/r/emacs/comments/1sc4n6k/ghostel_terminal_emulator_powered_by_libghostty/">Reddit</a>)</li>
</ul></li>
<li>Mail, news, and chat:
<ul class="org-ul">
<li><a href="https://thanosapollo.org/posts/emacs-jabber-revival/">Thanos Apollo: Bringing jabber.el Back From the Dead</a> (<a href="https://framapiaf.org/@debacle/116346678036311813">@debacle@framapiaf.org</a>)</li>
<li><a href="https://codeberg.org/martianh/mastodon.el">mastodon.el 2.0.14 - jump to quoting toot, bugfixes, annotations</a> (<a href="https://todon.nl/@mousebot/116323493425072693">@mousebot@todon.nl</a>)</li>
</ul></li>
<li>Multimedia:
<ul class="org-ul">
<li><a href="https://mathstodon.xyz/@tusharhero/116345234415202702">Using Android TTS in Emacs</a></li>
</ul></li>
<li>Fun:
<ul class="org-ul">
<li><a href="https://www.reddit.com/r/emacs/comments/1s8kox8/anybody_interested_in_writing_sdl_games_in_emacs/">Anybody interested in writing SDL games in Emacs Lisp?</a>
<ul class="org-ul">
<li><a href="https://www.reddit.com/r/emacs/comments/1sc2dfx/emacs_sdl_unblocking_the_unblockable/">Emacs + SDL: unblocking the unblockable</a> (<a href="https://lists.gnu.org/archive/html/emacs-devel/2026-04/msg00189.html">emacs-devel</a>)</li>
</ul></li>
<li><a href="https://blog.davep.org/2026/03/31/eg-el-v1-2.html">Dave Pearson: eg.el v1.2</a> Norton Guide?, <a href="https://blog.davep.org/2026/03/31/thinks-el-v1-13.html">thinks.el v1.13</a> thought bubbles, <a href="https://blog.davep.org/2026/04/01/binclock-el-v1-12.html">binclock.el v1.12</a> binary clock, <a href="https://blog.davep.org/2026/04/01/obfusurl-el-v2-2.html">obfusurl.el v2.2</a> obfuscating URLs</li>
</ul></li>
<li>AI:
<ul class="org-ul">
<li><a href="https://www.thetypicalset.com/blog/emacs-as-ceo-operating-system">I run my company from Emacs</a> (<a href="https://news.ycombinator.com/item?id=47626006">HN</a>)</li>
<li><a href="https://www.youtube.com/watch?v=SrRweChigB0">Crafting an AI-Driven Workflow System - System Crafters Live!</a> (01:52:03)</li>
<li><a href="https://www.youtube.com/watch?v=ePH3u7lmFWU">Will using Emacs give you an edge in the AI-era?</a> (45:08, <a href="https://www.reddit.com/r/emacs/comments/1s8atnd/will_using_emacs_give_you_an_edge_in_the_aiera_45/">Reddit</a>, <a href="https://www.reddit.com/r/emacs/comments/1s8m35w/will_using_emacs_give_you_an_edge_in_the_aiera/">Reddit</a>)</li>
<li><a href="https://noquiche.fyi/emacs-for-agents">The Agent-Native Editor Was Invented in 1976</a></li>
</ul></li>
<li>Community:
<ul class="org-ul">
<li><a href="https://www.youtube.com/watch?v=465GSalM6oI">Emacs ATX Meetup. April 2026. - YouTube</a> (2:04:58)</li>
<li><a href="https://sachachua.com/blog/2026/04/yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp/">Sacha Chua: #YayEmacs 10: Emacs coaching with Prot: Emacs workflows and streaming</a> (<a href="https://www.youtube.com/watch?v=kvBS8wz8ZRw">YouTube</a> 01:06:30)
<ul class="org-ul">
<li><a href="https://sachachua.com/blog/2026/03/thinking-about-coaching-goals-with-prot/">Sacha Chua: Thinking about Emacs coaching goals with Prot</a></li>
<li><a href="https://protesilaos.com/codelog/2026-03-31-emacs-coaching-with-sacha-chua/">Protesilaos Stavrou: Emacs coaching with Sacha Chua</a></li>
</ul></li>
<li><a href="https://sdf.org/~pkal/blog/emacs/mistakes.html">Emacs Carnival March 2026: Mistakes and Misconceptions</a>
<ul class="org-ul">
<li><a href="https://lio.novelli.si/en/blog/mistakes-and-misconceptions.html">The Comfort Trap</a> (<a href="https://toot.si/@len/116323162366294557">@len@toot.si</a>)</li>
<li><a href="https://christiantietze.de/posts/2026/03/emacs-mistakes-and-misconceptions-that-held-me-back-in-2018/">Christian Tietze: Emacs Mistakes and Misconceptions That Held Me Back in 2019</a></li>
<li><a href="https://einar.codeberg.page/emacs-mistakes-and-misconceptions.html">Einar Mostad: Emacs mistakes and misconceptions</a></li>
</ul></li>
<li><a href="https://www.youtube.com/watch?v=XlESi31czFA">Prot Asks: Hjalmar about Emacs for music, the joy of art, and Internet sociability</a> (02:04:24)</li>
<li><a href="https://xenodium.com/and-then-there-were-three">Alvaro Ramirez: …and then there were three (expect delays)</a> (<a href="https://irreal.org/blog/?p=13719">Irreal</a>)</li>
<li><a href="https://www.youtube.com/watch?v=sV7C6Ezl35A">A Cult AI Computer’s Boom and Bust - YouTube</a> (<a href="https://irreal.org/blog/?p=13707">Irreal</a>)</li>
</ul></li>
<li>Other:
<ul class="org-ul">
<li><a href="https://doc.emacsen.de/">Emacs Docs</a> (<a href="https://www.reddit.com/r/emacs/comments/1sbb72w/initiative_restyling_the_official_emacs_manuals/">Reddit</a>, <a href="https://mastodon.social/@maxxcan/116336010699503942">@maxxcan@mastodon.social</a>)</li>
<li><a href="https://thanosapollo.org/posts/gnosis-8-to-10/">Thanos Apollo: Gnosis 0.10: Import Anki, Merge Everything Into One</a></li>
<li><a href="https://www.youtube.com/watch?v=tj6iMpf18DU">doom emacs install on manjaro linux walkthrough on hyper-v vm</a> (17:29)</li>
</ul></li>
<li>Emacs development:
<ul class="org-ul">
<li><a href="https://lists.gnu.org/archive/html/emacs-devel/2026-03/msg01121.html">On keybindings and the slow erosion of help's utility</a> - long discussion</li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=d604445954d0c390e7c6c1280bf48b6858881bef">New option vc-dir-auto-hide-up-to-date</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=859e0622ae5e8303d288a345d9ef9181fa0aa6ae">* lisp/vc/diff-mode.el (diff-mode-read-only-map): Bind 'v'.</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=ae1ac739b799608cca0ec9f0e78f2b852078bd57">* etc/NEWS: Announce Org update.</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=0a62e6c304d880b9fcb91c9ce091200cd2436a52">; Fix documentation of last change</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=6a15c02a59d6caf171c7cb9b85f48ec845853445">Recursively check dependencies for package compatibility</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=52205e38d3ea670f2685e345591eac43d7a9b613">Inform macOS Accessibility Zoom of cursor position (bug#80624)</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=faf1932875754c446361106cd8035c85fcc598f3">New macro setopt-local and function set-local (bug#80709)</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=cda65ffa58e1280fabfdf3eb7340f429b2aedd4d">Add xref-edit-mode (bug#80616)</a></li>
</ul></li>
<li>New packages:
<ul class="org-ul">
<li><a target="_blank" href="https://melpa.org/#/compilation-history">compilation-history</a>: Track compilation history in SQLite (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/corg">corg</a>: Header completion for org-mode (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/evim">evim</a>: Evil Visual Multi - Multiple cursors for evil-mode (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/ghostel">ghostel</a>: Terminal emulator powered by libghostty (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/meshmonitor-chat">meshmonitor-chat</a>: Chat client for MeshMonitor (Meshtastic) (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/occult">occult</a>: Collapse and reveal buffer regions (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/org-dt">org-dt</a>: Dynamic templating loader (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/org-grimoire">org-grimoire</a>: Emacs-native static site generator (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/org-invox">org-invox</a>: Invoice management for contractors using Org mode (MELPA)</li>
</ul></li>
</ul>

<p>
Links from <a href="https://www.reddit.com/r/emacs">reddit.com/r/emacs</a>, <a href="https://www.reddit.com/r/orgmode">r/orgmode</a>, <a href="https://www.reddit.com/r/spacemacs">r/spacemacs</a>, <a href="https://mastodon.social/tags/emacs">Mastodon #emacs</a>, <a href="https://bsky.app/hashtag/emacs">Bluesky #emacs</a>, <a href="https://hn.algolia.com/?query=emacs&amp;sort=byDate&amp;prefix&amp;page=0&amp;dateRange=all&amp;type=story">Hacker News</a>, <a href="https://lobste.rs/search?q=emacs&amp;what=stories&amp;order=newest">lobste.rs</a>, <a href="https://programming.dev/c/emacs?dataType=Post&amp;page=1&amp;sort=New">programming.dev</a>, <a href="https://lemmy.world/c/emacs">lemmy.world</a>, <a href="https://lemmy.ml/c/emacs?dataType=Post&amp;page=1&amp;sort=New">lemmy.ml</a>, <a href="https://planet.emacslife.com">planet.emacslife.com</a>, <a href="https://www.youtube.com/playlist?list=PL4th0AZixyREOtvxDpdxC9oMuX7Ar7Sdt">YouTube</a>, <a href="http://git.savannah.gnu.org/cgit/emacs.git/log/etc/NEWS">the Emacs NEWS file</a>, <a href="https://emacslife.com/calendar/">Emacs Calendar</a>, and <a href="https://lists.gnu.org/archive/html/emacs-devel/2026-04">emacs-devel</a>. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at <a href="mailto:sacha@sachachua.com">sacha@sachachua.com</a>. Thank you!
</p>
<div><a href="https://sachachua.com/blog/2026/04/2026-04-06-emacs-news/index.org">View Org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F04%2F2026-04-06-emacs-news%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>YE11: Fix find-function for Emacs Lisp from org-babel or scratch</title>
		<link>https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Sun, 05 Apr 2026 21:03:48 GMT</pubDate>
    <category>org</category>
<category>emacs</category>
<category>elisp</category>
<category>stream</category>
<category>yay-emacs</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/</guid>
		<description><![CDATA[<p>
<video controls="1" src="https://archive.org/download/yay-emacs-11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/ye11-find-function.mp4" poster="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/2026-04-05-19-25-03.png" type="video/mp4"><track kind="subtitles" label="Captions" src="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/Yay%20Emacs%2011:%20Fix%20find-function%20for%20Emacs%20Lisp%20from%20org-babel%20or%20scratch.vtt" srclang="en" default=""><span>Video not supported. Thumbnail:<br><img src="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/2026-04-05-19-25-03.png" alt="Thumbnail"></span></video>
</p>

<p>
<a href="https://archive.org/details/yay-emacs-11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch">Watch on Internet Archive</a>, <a href="https://youtube.com/live/PKkV1Tbev_Y">watch/comment on YouTube</a>, <a href="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/Yay%20Emacs%2011:%20Fix%20find-function%20for%20Emacs%20Lisp%20from%20org-babel%20or%20scratch.vtt">download captions</a>, or <a href="mailto:sacha@sachachua.com">email me</a>
</p>


<p>
Where can you define an Emacs Lisp function so
that you can use <code>find-function</code> to jump to it
again later?
</p>

<ul class="org-ul">
<li><b>A: In an indirect buffer</b> from Org Mode source
block with your favorite eval function like
<code>eval-defun</code> <label class="hint"><input type="checkbox"> <span class="hint-desc">(hint)</span><span class="hint-text">nope</span></label>

<ul class="org-ul">
<li><p>
<code>C-c '</code> (<code>org-edit-special</code>) inside the block; execute the defun with <code>C-M-x</code> (<code>eval-defun</code>), <code>C-x C-e</code> (<code>eval-last-sexp</code>), or <code>eval-buffer</code>.
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>    (<span class="org-keyword">defun</span> <span class="org-function-name">my-test-1</span> () (message <span class="org-string">"Hello"</span>))
</code></pre>
</div>
</li>
</ul></li>

<li><p>
<b>B: In an Org Mode file</b> by executing the block
with C-c C-c <label class="hint"><input type="checkbox"> <span class="hint-desc">(hint)</span><span class="hint-text">nope</span></label>
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>  (<span class="org-keyword">defun</span> <span class="org-function-name">my-test-2</span> () (message <span class="org-string">"Hello"</span>))
</code></pre>
</div>
</li>

<li><p>
<b>C: In a .el file</b> <label class="hint"><input type="checkbox"> <span class="hint-desc">(hint)</span><span class="hint-text">yup</span></label>
</p>

<p>
<a href="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/test-search-function.el">file:///tmp/test-search-function.el</a> : execute the defun with <code>C-M-x</code> (<code>eval-defun</code>), <code>C-x C-e</code> (<code>eval-last-sexp</code>), or <code>eval-buffer</code>
</p></li>

<li><p>
<b>D: In a scratch buffer,</b> other temporary buffer,
or really any buffer thanks to eval-last-sexp
<label class="hint"><input type="checkbox"> <span class="hint-desc">(hint)</span><span class="hint-text">nope</span></label>
</p>

<p>
<code>(defun my-test-4 () (message "Hello"))</code>
</p></li>
</ul>

<p>
Only option C works - it's gotta be in an .el file for
<code>find-function</code> to find it. But I love jumping to
function definitions using <code>find-function</code> or
<code>lispy-goto-symbol</code> (which is bound to <code>M-.</code> if
you use <a target="_blank" href="https://melpa.org/#/lispy">lispy</a> and set up <code>lispy-mode</code>) so
that I can look at or change how something works.
It can be a little frustrating when I try to jump
to a definition and it says, "Don't know where
blahblahblah is defined." I just defined it five
minutes ago! It's there in one of my other
buffers, don't make me look for it myself.
Probably this will get fixed in Emacs core
someday, but no worries, we can work around it
today with a little bit of advice.
</p>

<p>
I did some digging around in the source code.
Turns out that <code>symbol-file</code> can't find the
function definition in the <code>load-history</code> variable
if you're not in a .el file, so
<code>find-function-search-for-symbol</code> gets called with
<code>nil</code> for the library, which causes the error.
(<a href="https://github.com/emacs-mirror/emacs/blob/master/lisp/subr.el">emacs:subr.el</a>)
</p>

<p>
I wrote some advice that searches in any open
<code>emacs-lisp-mode</code> buffers or in a list of other
files, like my Emacs configuration.
This is how I activate it:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">setq</span> sacha-elisp-find-function-search-extra <span class="org-highlight-quoted-quote">'</span>(<span class="org-string">"~/sync/emacs/Sacha.org"</span>))
(advice-add <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">find-function-search-for-symbol</span> <span class="org-builtin">:around</span> <span class="org-highlight-quoted-quote">#'</span><span class="org-highlight-quoted-symbol">sacha-elisp-find-function-search-for-symbol</span>)
</code></pre>
</div>


<p>
Now I should be able to jump to all those
functions wherever they're defined.
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(my-test-1)
(my-test-2)
(my-test-3)
(my-test-4)
</code></pre>
</div>


<p>
Note that by default, <code>M-.</code> in <code>emacs-lisp-mode</code> uses <code>xref-find-definitions</code>, which seems to really want files. I haven't figured out a good workaround for that yet, but <a target="_blank" href="https://melpa.org/#/lispy">lispy-mode</a> makes <code>M-.</code> work and gives me a bunch of other great shortcuts, so I'd recommend checking that out.
</p>

<p>
Here's the source code for the find function thing:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">defvar</span> <span class="org-variable-name">sacha-elisp-find-function-search-extra</span>
  nil
  <span class="org-doc">"List of filenames to search for functions."</span>)

<span class="org-comment-delimiter">;;;</span><span class="org-comment">###</span><span class="org-comment"><span class="org-warning">autoload</span></span>
(<span class="org-keyword">defun</span> <span class="org-function-name">sacha-elisp-find-function-search-for-symbol</span> (fn symbol type library <span class="org-type">&amp;rest</span> _)
  <span class="org-doc">"Find SYMBOL with TYPE in Emacs Lisp buffers or `</span><span class="org-doc"><span class="org-constant">sacha-find-function-search-extra</span></span><span class="org-doc">'.</span>
<span class="org-doc">Prioritize buffers that do not have associated files, such as Org Src</span>
<span class="org-doc">buffers or *scratch*. Note that the fallback search uses \"^([</span><span class="org-doc"><span class="org-negation-char">^</span></span><span class="org-doc"> )]+\" so that</span>
<span class="org-doc">it isn't confused by preceding forms.</span>

<span class="org-doc">If LIBRARY is specified, fall back to FN.</span>

<span class="org-doc">Activate this with:</span>

<span class="org-doc">(advice-add 'find-function-search-for-symbol</span>
<span class="org-doc"> :around #'sacha-org-babel-find-function-search-for-symbol-in-dotemacs)"</span>
  (<span class="org-keyword">if</span> (null library)
      <span class="org-comment-delimiter">;; </span><span class="org-comment">Could not find library; search my-dotemacs-file just in case</span>
      (<span class="org-keyword">progn</span>
        (<span class="org-keyword">while</span> (<span class="org-keyword">and</span> (symbolp symbol) (get symbol <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">definition-name</span>))
          (<span class="org-keyword">setq</span> symbol (get symbol <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">definition-name</span>)))
        (<span class="org-keyword">catch</span> <span class="org-highlight-quoted-quote">'</span><span class="org-constant">found</span>
          (mapc
           (<span class="org-keyword">lambda</span> (buffer-or-file)
             (<span class="org-keyword">with-current-buffer</span> (<span class="org-keyword">if</span> (bufferp buffer-or-file)
                                      buffer-or-file
                                    (find-file-noselect buffer-or-file))
               (<span class="org-keyword">let*</span> ((regexp-symbol
                       (<span class="org-keyword">or</span> (<span class="org-keyword">and</span> (symbolp symbol)
                                (alist-get type (get symbol <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">find-function-type-alist</span>)))
                           (alist-get type find-function-regexp-alist)))
                      (form-matcher-factory
                       (<span class="org-keyword">and</span> (functionp (cdr-safe regexp-symbol))
                            (cdr regexp-symbol)))
                      (regexp-symbol (<span class="org-keyword">if</span> form-matcher-factory
                                         (car regexp-symbol)
                                       regexp-symbol))

                      (case-fold-search)
                      (regexp (<span class="org-keyword">if</span> (functionp regexp-symbol) regexp-symbol
                                (format (symbol-value regexp-symbol)
                                        <span class="org-comment-delimiter">;; </span><span class="org-comment">Entry for ` (backquote) macro in loaddefs.el,</span>
                                        <span class="org-comment-delimiter">;; </span><span class="org-comment">(defalias (quote \`)..., has a \ but</span>
                                        <span class="org-comment-delimiter">;; </span><span class="org-comment">(symbol-name symbol) doesn't.  Add an</span>
                                        <span class="org-comment-delimiter">;; </span><span class="org-comment">optional \ to catch this.</span>
                                        (concat <span class="org-string">"\\\\?"</span>
                                                (regexp-quote (symbol-name symbol)))))))
                 (<span class="org-keyword">save-restriction</span>
                   (widen)
                   (<span class="org-keyword">with-syntax-table</span> emacs-lisp-mode-syntax-table
                     (goto-char (point-min))
                     (<span class="org-keyword">if</span> (<span class="org-keyword">if</span> (functionp regexp)
                             (funcall regexp symbol)
                           (<span class="org-keyword">or</span> (re-search-forward regexp nil t)
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">`</span><span class="org-comment"><span class="org-constant">regexp</span></span><span class="org-comment">' matches definitions using known forms like</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">`</span><span class="org-comment"><span class="org-constant">defun</span></span><span class="org-comment">', or `</span><span class="org-comment"><span class="org-constant">defvar</span></span><span class="org-comment">'.  But some functions/variables</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">are defined using special macros (or functions), so</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">if `</span><span class="org-comment"><span class="org-constant">regexp</span></span><span class="org-comment">' can't find the definition, we look for</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">something of the form "(SOMETHING &lt;symbol&gt; ...)".</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">This fails to distinguish function definitions from</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">variable declarations (or even uses thereof), but is</span>
                               <span class="org-comment-delimiter">;; </span><span class="org-comment">a good pragmatic fallback.</span>
                               (re-search-forward
                                (concat <span class="org-string">"^([</span><span class="org-string"><span class="org-negation-char">^</span></span><span class="org-string"> )]+"</span> find-function-space-re <span class="org-string">"['(]?"</span>
                                        (regexp-quote (symbol-name symbol))
                                        <span class="org-string">"\\_&gt;"</span>)
                                nil t)))
                         (<span class="org-keyword">progn</span>
                           (beginning-of-line)
                           (<span class="org-keyword">throw</span> <span class="org-highlight-quoted-quote">'</span><span class="org-constant">found</span>
                                   (cons (current-buffer) (point))))
                       (<span class="org-keyword">when-let*</span> ((find-expanded
                                    (<span class="org-keyword">when</span> (trusted-content-p)
                                      (find-function&#45;&#45;search-by-expanding-macros
                                       (current-buffer) symbol type
                                       form-matcher-factory))))
                         (<span class="org-keyword">throw</span> <span class="org-highlight-quoted-quote">'</span><span class="org-constant">found</span>
                                 (cons (current-buffer)
                                       find-expanded)))))))))
           (delq nil
                 (append
                  (sort
                   (match-buffers <span class="org-highlight-quoted-quote">'</span>(derived-mode . emacs-lisp-mode))
                   <span class="org-builtin">:key</span> (<span class="org-keyword">lambda</span> (o) (<span class="org-keyword">or</span> (buffer-file-name o) <span class="org-string">""</span>)))
                  sacha-elisp-find-function-search-extra)))))
    (funcall fn symbol type library)))
</code></pre>
</div>


<p>
I even figured out how to <span title="(ignore (ert &quot;sacha-elisp&#45;&#45;find-function-search-for-symbol&#45;&#45;.*&quot;))">write tests for it</span>:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">ert-deftest</span> <span class="org-function-name">sacha-elisp&#45;&#45;find-function-search-for-symbol&#45;&#45;in-buffer</span> ()
  (<span class="org-keyword">let</span> ((sym (make-temp-name <span class="org-string">"&#45;&#45;test-fn"</span>))
        buffer)
    (<span class="org-keyword">unwind-protect</span>
        (<span class="org-keyword">with-temp-buffer</span>
          (emacs-lisp-mode)
          (insert (format <span class="org-string">";; Comment\n(defun %s () (message \"Hello\"))"</span> sym))
          (eval-last-sexp nil)
          (<span class="org-keyword">setq</span> buffer (current-buffer))
          (<span class="org-keyword">with-temp-buffer</span>
            (<span class="org-keyword">let</span> ((pos (sacha-elisp-find-function-search-for-symbol nil (intern sym) nil nil)))
              (<span class="org-keyword">should</span> (equal (car pos) buffer))
              (<span class="org-keyword">should</span> (equal (cdr pos) 12)))))
      (fmakunbound (intern sym)))))

(<span class="org-keyword">ert-deftest</span> <span class="org-function-name">sacha-elisp&#45;&#45;find-function-search-for-symbol&#45;&#45;in-file</span> ()
  (<span class="org-keyword">let*</span> ((sym (make-temp-name <span class="org-string">"&#45;&#45;test-fn"</span>))
         (temp-file (make-temp-file
                     <span class="org-string">"test-"</span> nil <span class="org-string">".org"</span>
                     (format
                      <span class="org-string">"#+begin_src emacs-lisp\n;; Comment\n(defun %s () (message \"Hello\"))\n#+end_src"</span>
                      sym)))
         (sacha-elisp-find-function-search-extra (list temp-file))
         buffer)
    (<span class="org-keyword">unwind-protect</span>
        (<span class="org-keyword">with-temp-buffer</span>
          (<span class="org-keyword">let</span> ((pos (sacha-elisp-find-function-search-for-symbol nil (intern sym) nil nil)))
            (<span class="org-keyword">should</span> (equal (buffer-file-name (car pos)) temp-file))
            (<span class="org-keyword">should</span> (equal (cdr pos) 35))))
      (delete-file temp-file))))
</code></pre>
</div>


<div class="note">This is part of my <a href="https://sachachua.com/dotemacs#org-mode-org-babel-fix-find-function-when-i-ve-evaluated-something-from-org-babel">Emacs configuration.</a></div><div><a href="https://sachachua.com/blog/2026/04/ye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch/index.org">View Org source for this post</a></div>
<p>You can <a href="https://social.sachachua.com/@sacha/statuses/01KNFTFSC3D0K7XH1JW1XTF6QG" target="_blank" rel="noopener noreferrer">comment on Mastodon</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F04%2Fye11-fix-find-function-for-emacs-lisp-from-org-babel-or-scratch%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>#YayEmacs 10: Emacs coaching with Prot: Emacs workflows and streaming</title>
		<link>https://sachachua.com/blog/2026/04/yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Sat, 04 Apr 2026 02:23:03 GMT</pubDate>
    <category>emacs</category>
<category>yay-emacs</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/04/yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp/</guid>
		<description><![CDATA[<p>
I realized that one of the <a href="https://sachachua.com/blog/2026/03/emacs-carnival-march-2026-mistakes-and-learning-to-reach-out/">mistakes</a> I often make with Emacs is not asking other people for help, so I experimented with a coaching session with Prot. With his permission, here's a recording of our conversation.
</p>

<video controls="1" preload="none" src="https://archive.org/download/2026-04-02-sacha-prot-emacs-workflows-and-streaming/2026-04-02-sacha-prot-emacs-workflows-and-streaming.mp4" type="video/mp4"><track kind="subtitles" label="Captions" src="https://sachachua.com/blog/2026/04/yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp/2026-04-02-sacha-prot-emacs-workflows-and-streaming.vtt" srclang="en" default=""><a href="https://archive.org/download/2026-04-02-sacha-prot-emacs-workflows-and-streaming/2026-04-02-sacha-prot-emacs-workflows-and-streaming.mp4">Download the video</a></video>

<p>
View in the <a href="https://archive.org/details/2026-04-02-sacha-prot-emacs-workflows-and-streaming">Internet Archive</a>, <a href="https://youtu.be/kvBS8wz8ZRw">watch/comment on YouTube</a>, <a href="https://sachachua.com/blog/2026/04/yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp/2026-04-02-sacha-prot-emacs-workflows-and-streaming.vtt">download the captions</a>, or <a href="mailto:sacha@sachachua.com">e-mail me your thoughts</a>.
</p>

<div class="sticky-toc" id="org37e77c6">
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="https://sachachua.com/blog/feed/index.xml#orgaa513ed">Resources</a></li>
<li><a href="https://sachachua.com/blog/feed/index.xml#org0dc74a0">Chapters</a></li>
<li><a href="https://sachachua.com/blog/feed/index.xml#projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-rough-notes-to-clean-up-over-the-next-little-while">Rough notes to clean up over the next little while</a></li>
<li><a href="https://sachachua.com/blog/feed/index.xml#projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-transcript">Transcript</a></li>
<li><a href="https://sachachua.com/blog/feed/index.xml#projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-ideas-for-next-steps">Ideas for next steps</a></li>
</ul>
</div>

</div>
<div id="outline-container-orgaa513ed" class="outline-3">
<h3 id="orgaa513ed">Resources</h3>
<div class="outline-text-3" id="text-orgaa513ed">
<ul class="org-ul">
<li><a href="https://protesilaos.com/codelog/2026-03-31-emacs-coaching-with-sacha-chua/">Emacs coaching with Sacha Chua | Protesilaos Stavrou</a></li>
<li><a href="https://sachachua.com/blog/2026/03/thinking-about-coaching-goals-with-prot/">Thinking about Emacs coaching goals with Prot</a></li>
<li><a href="https://sachachua.com/dotemacs">My Emacs configuration</a></li>
<li><a href="https://protesilaos.com/emacs/dotemacs">Prot's Emacs configuration</a></li>
<li><a href="https://youtube.com/live/djE_pVlgDHg?feature=share">The livestream we've penciled in for April 16</a> - come join us!</li>
</ul>
</div>
</div>
<div id="outline-container-org0dc74a0" class="outline-3">
<h3 id="org0dc74a0">Chapters</h3>
<div class="outline-text-3" id="text-org0dc74a0">
<ul class="org-ul">
<li><span class="media-time" data-start="0.000">00:00</span> Intro</li>
<li><span class="media-time" data-start="50.000">00:50</span> Organizing my config into multiple modules and org-babel-post-tangle-hook</li>
<li><span class="media-time" data-start="285.000">04:45</span> Changing namespace, renaming functions</li>
<li><span class="media-time" data-start="431.000">07:11</span> Defining aliases for old functions</li>
<li><span class="media-time" data-start="510.000">08:30</span> Improving my streaming setup</li>
<li><span class="media-time" data-start="729.000">12:09</span> Keeping things from accidentally airing</li>
<li><span class="media-time" data-start="890.000">14:50</span> Livestreaming and recording</li>
<li><span class="media-time" data-start="909.000">15:09</span> Keeping track of interesting moments</li>
<li><span class="media-time" data-start="1099.000">18:19</span> Editing</li>
<li><span class="media-time" data-start="1226.000">20:26</span> Writing</li>
<li><span class="media-time" data-start="1354.000">22:34</span> Packaging</li>
<li><span class="media-time" data-start="1540.000">25:40</span> Responding to email</li>
<li><span class="media-time" data-start="1761.000">29:21</span> Development workflow</li>
<li><span class="media-time" data-start="1799.000">29:59</span> Testing</li>
<li><span class="media-time" data-start="2026.000">33:46</span> Learning and reminders</li>
<li><span class="media-time" data-start="2131.000">35:31</span> Encapsulating workflows into functions</li>
<li><span class="media-time" data-start="2225.000">37:05</span> Popping up notes</li>
<li><span class="media-time" data-start="2301.000">38:21</span> Rediscovering things in my config</li>
<li><span class="media-time" data-start="2431.000">40:31</span> Catching up on Emacs developments</li>
<li><span class="media-time" data-start="2489.000">41:29</span> diffs</li>
<li><span class="media-time" data-start="2588.000">43:08</span> Thinking about the community</li>
<li><span class="media-time" data-start="2640.000">44:00</span> org-link-preview</li>
<li><span class="media-time" data-start="2731.000">45:31</span> Prioritizing things to work on</li>
<li><span class="media-time" data-start="2799.000">46:39</span> Modelines</li>
<li><span class="media-time" data-start="2930.000">48:50</span> Themes would be nice to have per-frame</li>
<li><span class="media-time" data-start="2967.000">49:27</span> Livestreaming conversations with Prot</li>
<li><span class="media-time" data-start="3011.000">50:11</span> Getting together</li>
<li><span class="media-time" data-start="3284.000">54:44</span> Namespaces</li>
<li><span class="media-time" data-start="3346.000">55:46</span> Verbose function names</li>
<li><span class="media-time" data-start="3405.000">56:45</span> Naming conventions for ERT tests</li>
<li><span class="media-time" data-start="3434.000">57:14</span> shorthands</li>
<li><span class="media-time" data-start="3507.000">58:27</span> Bisecting config in multiple files</li>
<li><span class="media-time" data-start="3526.000">58:46</span> "I don't write bugs."</li>
</ul>
</div>
</div>
<div id="outline-container-projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-rough-notes-to-clean-up-over-the-next-little-while" class="outline-3">
<h3 id="projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-rough-notes-to-clean-up-over-the-next-little-while">Rough notes to clean up over the next little while</h3>
<div class="outline-text-3" id="text-projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-rough-notes-to-clean-up-over-the-next-little-while">
<ul class="org-ul">
<li>Meta: learning things
<ul class="org-ul">
<li>Don't try to remember too many things</li>
<li>Build a command that does those for you</li>
<li>Ex: preparing for videos, prot-streaming-mode
<ul class="org-ul">
<li>line numbers</li>
<li>disable spacious padding</li>
</ul></li>
<li>long names: more chances to match it</li>
<li>new frame and then making it disappear: org-capture, timer; I can use that for notes</li>
<li>Tip: prefix keys are also helpful; for example, replace C-z, no one needs to suspend Emacs anyway
<code>defvar-keymap</code> <code>:prefix</code> defines how it should be called as a command, which is good for handling updates to keymaps as well</li>
</ul></li>
<li>Emacs Lisp development workflow
<ul class="org-ul">
<li>diff-buffer-with-file buffer-file-name - diff current buffer</li>
<li>Renaming a symbol
<ul class="org-ul">
<li>single file
<ul class="org-ul">
<li><a target="_blank" href="https://elpa.gnu.org/packages/substitute.html">substitute</a>
<ul class="org-ul">
<li>also noting function aliases, obsolete</li>
</ul></li>
</ul></li>
<li>multiple files?
-wgrep
<ul class="org-ul">
<li>keyboard macros from dired and substitute</li>
</ul></li>
</ul></li>
<li>Bisecting config in modules?
<ul class="org-ul">
<li>"I don't write bugs&hellip; Of course I'm kidding."</li>
<li>Ah, I can probably use bug-hunter with a setup file</li>
</ul></li>
<li>Testing
<ul class="org-ul">
<li>I think I just need to get the hang of:
<ul class="org-ul">
<li>ERT, modus-themes-test&ndash;modus-themes-load-theme</li>
<li>nameless -&gt; shorthands</li>
<li>Tip: Docstring as a declaration of intent; the docstring is the source of truth, not the code. If you write more than the minimum, then you are helping future you.</li>
<li>setting things up at the beginning (Makefiles, continuously running batch mode tests, etc.)</li>
<li>navigating to where I want to write the tests</li>
<li>mocking functions</li>
</ul></li>
</ul></li>
</ul></li>
<li>Making more of my config reusable
<ul class="org-ul">
<li>"I implement the package that I want."</li>
</ul></li>
<li>Workflows for writing, making videos, livestreaming
<ul class="org-ul">
<li>wide monitor is awesome</li>
<li>different font configuration with <a target="_blank" href="https://elpa.gnu.org/packages/fontaine.html">fontaine</a></li>
<li>private stuff:
<ul class="org-ul">
<li>private vertico</li>
<li>turning off preview for consult</li>
<li>keeping files organized</li>
</ul></li>
<li>marking chapters and highlights: using his memory for this</li>
<li>just capture a timestamp and possibly a note</li>
<li>could also just do the offsets manually by saving the time</li>
<li>display line numbers to help people orient themselves and so they can mention it in the chat</li>
<li>writing: splitting it into modules helps</li>
<li>Ooh, idea, theme for streaming</li>
</ul></li>
<li>Other stuff I forgot to mention
<ul class="org-ul">
<li>TODO: link preview - update my code for svgs</li>
<li>Emacs modeline? Smaller lighters, buffer name, view narrowed, read-only, keyboard macro;
<ul class="org-ul">
<li>streaming, microphone</li>
</ul></li>
</ul></li>
</ul>
</div>
</div>
<div id="outline-container-projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-transcript" class="outline-3">
<h3 id="projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-transcript">Transcript</h3>
<div class="outline-text-3" id="text-projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-transcript">
<details class="code-details" style="padding: 1em;
                 border-radius: 15px;
                 font-size: 0.9em;
                 box-shadow: 0.05em 0.1em 5px 0.01em  #00000057;">
                  <summary><strong>Transcript</strong></summary>
<ul class="org-ul">
<li><p>
<span class="audio-time" data-start="1.720" data-stop="56.839">0:01</span>: <b>Intro</b>:
Sacha: Fantastic, this is great, I finally get to talk to you. I
appreciate that you blogged so quickly about some of the
things that I mentioned, and we can certainly dive right
into that, or you have a lot more experience with how these
conversations go, so I can let you take the lead.
</p>

<p>
Prot: Since you put in the effort to write, we already have a
very good structure. The idea is, let's have your screen, so
you can share your screen with Jitsi.
</p>

<p>
Sacha: Yeah. I will share my screen.
</p>

<p>
Prot: And we can go right into it. Let's see. So if you hover over&hellip;
Okay, yeah, you have it.
</p>

<p>
Sacha: yeah oh you know if if at some point I should be really like fancy&hellip; Future session, we should get crdt working because that's fun.
</p>

<p>
Prot: Ah, yes. Oh, that would be nice. Yes.
</p>

<p>
Sacha: Yeah, that would be nice. All right.
</p></li>

<li><p>
<span class="audio-time" data-start="50.455" data-stop="285.228">0:50</span>: <b>Organizing my config into multiple modules and org-babel-post-tangle-hook</b>:
Sacha: So I've been making good progress in splitting up my config into
multiple modules. I just have to iron out a couple of things
like do I actually have to load the autoloads from the user
list directory or does it automatically take care of that?
Because sometimes it doesn't seem like it's doing the
thing. Anyway. It's making good progress. And in fact, I
came across something that I'm not sure you know about yet,
or maybe you know about it and you decided not to do it. I found
out that, so, okay, so here's the context. You know, when you
do your literate config, you have your modules and they're
actually just one big file, like one big source block with a
commentary and everything in it. Yeah, yeah. So I found out
that you can use a hook if you want to, to add stuff to the
tangled files afterwards. So the way I set it up with my
config is I still want all the different functions
scattered all over the place because I'm not yet as
organized as you in terms of the modules. So the
org-babel-post-tangle-hook here, post. Yeah, yeah, yeah, post
</p>

<p>
Prot: So what did you do with that? Let's see.
</p>

<p>
Sacha: and boilerplate&hellip; has that boilerplate here we go so what
it's what this does is when it tangles it it then goes back
into the file and it inserts all that extra text and the
footer into the tangled files so I still have my links to
</p>

<p>
Prot: Nice.
</p>

<p>
Sacha: the different source files where it comes from. So this is
the section where it comes from but I also have all the extra
lovely commentary and stuff so I'm like&hellip;
</p>

<p>
Prot: Ah, that's smart. That's good. That's good. Yes.
</p>

<p>
Sacha: That way, you don't have to keep repeating things. Although I
guess if you really wanted to repeat things you could you
could theoretically have the license just as a no web
reference and then have it go in there automatically.
anyway so I thought that was really cool so I'm making
progress on the things that I had mentioned in the in the blog
post about organizing my config into multiple modules
and other yeah&hellip;
</p>

<p>
Prot: And how far are you in that project? How far are you?
</p>

<p>
Sacha: Let me see. I can look at the sacha.el here and I can do an occur on the files that have the lines that have the
defun. I only have 482 defuns to get rid of. This is
already a lot less than what I started with because like you,
I have a very large&hellip; Almost 40,000 lines in this sacha.org.
</p>

<p>
Prot: Yeah, yeah, that's massive. Yeah.
</p>

<p>
Sacha: It's fun and it's interesting. It is a little reassuring to
know that people still rely on your published modules
instead of actually, like, do people take your config? I
know you've got stuff in the config that makes it possible
for people to just load it and add their customizations on
top, but do you hear from a lot of people who do that?
</p>

<p>
Prot: From a few of them, yes. And this is why I actually created
those customizations. But I must say, I have been trying to
</p>

<p>
Sacha: Yeah, yeah.
</p>

<p>
Prot: make it more difficult for them. So I used to have a use
package, but now I disabled it on purpose and I have my own
macros, so that somebody doesn't just copy-paste. And I
don't do this to be mean, but I do it because this way somebody
will have to think about, like, okay, what is this?
What am I doing here?
</p>

<p>
Sacha: yeah I figure making making them still do that okay what am I
doing here while still being able to automatically load all
the function definitions will probably get them over that
you know like make it a little bit easier for them so at least
that way like right now it is difficult to copy things from my
config like like you're so like okay maybe this is a feature
but you know, maybe changing it will be nice.
</p></li>

<li><p>
<span class="audio-time" data-start="285.229" data-stop="430.519">4:45</span>: <b>Changing namespace, renaming functions</b>:
Sacha: The other big thing that I need to do with my config is
I'm thinking about shifting everything to the sacha- namespace
instead of the my- namespace, which is going to be a lot of
renaming, which is actually, it was actually the question
that I had about renaming things, not necessarily coming up
with clever names that have good acronyms like you do. And I
love that the humor that you have in there, but like, like
just mechanically, are we talking wgrep is like, is there a
more modern, emacs 31 way to rename things? Am I just using
erefactor or like replace-regexp? What do you do when you need
to rename a symbol in possibly multiple files?
</p>

<p>
Prot: If it's in multiple files, I do the grep approach. So it's not
that sophisticated, but it works. Because the thing
with the multiple files is, and it goes also to what you were
telling me in that article, is first you organize, and then
you refactor. It's that idea. The multiple files will not
have a lot of extraneous information. You will not be
matching, at least in theory, you will not be matching too
many false positives.
</p>

<p>
Sacha: Yeah, and if you're doing a single file,
</p>

<p>
Prot: So you won't have to sort it.
</p>

<p>
Sacha: what do you like to do?
</p>

<p>
Prot: I have a package called substitute.
One of the ways I do it is just
substitute the symbol at point. But of course, this is just a
minor convenience. You can do that with a query-replace.
I'm not saying that you really need the package. But the idea is
that you do it and you know that it works. Like, for me&hellip;
I know that it works in the file.
So for me, that's very reliable.
But the other thing I should mention is
keyboard macros from dired combined with substitute.
So you start from a dired buffer, and you go file by file.
That's the general idea. And in each file, you will perform,
for example, a search to the symbol. Once you are on the symbol,
you do the substitute-replace command, and then you move to
the next file. So that is the workflow. And I do that a lot, for
example, with my themes, because they have a lot of
repetitive code, like each theme.
</p></li>

<li><p>
<span class="audio-time" data-start="431.457" data-stop="510.949">7:11</span>: <b>Defining aliases for old functions</b>:
Sacha: Okay, the other thing that I was thinking of as a
workflow improvement here, because I'm sure that I'm going
to keep calling them by their old names, especially
interactively, like have a lot of commands that go off the
meta x, my do this and this and this is I might also need to
think about adding a function alias automatically. And one
way I was thinking of doing that was just, you know,
iterating over our array and bulk defining aliases so that
all the sacha- stuff is now named my- stuff but I was wondering
if that was a or actually also manually inserting the like
well not of course manually but but creating forms for like
defining the aliases somewhere but I was wondering if
this was something that you already did as part of your
workflow like do you when you rename things okay
</p>

<p>
Prot: No, I haven't. When I rename things for my packages, I do use
aliases. But for my own code, if I rename it, basically, it's
</p>

<p>
Sacha: yeah yeah
</p>

<p>
Prot: just the latest name. So I don't try to keep aliases around.
Because I eventually use a similar name,
it won't be very different.
</p>

<p>
Sacha: huh all right yeah yeah I mean like it's it's there you
</p>

<p>
Prot: But what you said about the obarray makes perfect sense.
</p>

<p>
Sacha: might as well do do it automatically right okay all right
that's me oh okay okay I can
</p></li>

<li><p>
<span class="audio-time" data-start="510.950" data-stop="729.648">8:30</span>: <b>Improving my streaming setup</b>:
Sacha: I can do my jitsi thing so I can see
everyone and the screen at the same time the screen is very
small okay so so that's I do have a dual monitor setup, which
</p>

<p>
Prot: Yeah, you need that dual monitor setup,
</p>

<p>
Sacha: is why I was like, OK, maybe I can start looking at your
B-frame things. And in fact, in the minutes before I called,
I figured out how to use MasterChat CLI to get the YouTube
live chat into a command line program, which means that it
can be run from call-process or make-process or other such
wonderful things. So now it's an Emacs buffer. And then I was
thinking, okay, maybe I'll make a pause frame or like a
B-framed like dedicated frame for it so that I can have the
chat of a live stream displayed within Emacs because you
know, it's Emacs. We should do that. Yeah, yeah, yeah.
</p>

<p>
Prot: Nice. Yes, of course.
And you can have it in a side window dedicated buffer.
</p>

<p>
Sacha: Although I might actually have to write my own like Node.js
program so that I can also send text from it, from Emacs.
I think the masterchat CLI, it only displays, but
the library that it uses, if you pass it your browser
cookie, you can use it to send messages back to chat as well.
The reason I had liked Twitch before was because
Twitch had some kind of IRC type thing that you could connect
to. And then that meant, of course, that you can use ERC from
within Emacs in order to send stuff to it. Anyway, live
streaming and chatting, I've also been getting into that
lately. And I was going to pick your brain about this whole
like workflow for making videos or live streaming them. And
more importantly, going back afterwards and
remembering to post them or edit it, in case you forgot
something or whatever. So if you happen to have any tips
or the things that you like about your setup, I would love to
hear about that.
</p>

<p>
Prot: Though in my case, the setup is really simple,
and I admit that I could improve it.
But it's really simple right now,
where I have a wide monitor.
So it's one display, I don't have two,
but it's like 2500 pixels instead of 920.
So I have a little sidebar on the side,
and there on the sidebar I put OBS, for example,
and I put everything I need there on the sidebar.
And then I have enough space to have
whatever it is I am displaying
and maybe another widget on the side.
So that is in terms of the physical layout
of the monitor here.
And then in terms of the Emacs side,
I don't have a lot going on.
I have one package to load the different font configuration.
So when I do streaming or videos,
I will load basically the presentation setup.
</p>

<p>
Sacha: It is a spontaneous.
</p>

<p>
Prot: That's Fontaine, exactly.
But again, it's not a matter of the package.
You could have a function that just changes the
default phase, the height attribute.
</p>

<p>
Sacha: I have this monitor and then laptop,
so this is my workaround for not having
enough space in this desk for a super wide monitor.
My husband has a super wide monitor which I like to borrow
during EmacsConf.
Hello child who is wonderful and likes to
make cameos during my EmacsConf. Okay, I'm going to hug you.
</p>

<p>
Prot: Hello!
</p>

<p>
Sacha: Yes. So okay, so live streaming and then you just basically
hop on the stream and talk about stuff.
</p></li>

<li><p>
<span class="audio-time" data-start="729.649" data-stop="890.389">12:09</span>: <b>Keeping things from accidentally airing</b>:
Sacha: I know you've mentioned things like just starting Emacs with your
Scratch buffer, but yeah, how about the interesting
workflows for not accidentally spilling secret stuff
online?
</p>

<p>
Prot: Part of that is&hellip;
so I use Vertico normally for my completions.
I have some configurations for private Vertico,
where by default, it doesn't display
what Vertico normally displays.
It's just a blank minibuffer,
the way it is with the default Emacs minibuffer UI, right?
But what happens is as soon as you do TAB
or as soon as you move up and down,
then it displays Vertico.
So that, that is one way for me to make sure
that I'm not showing anything I didn't want to show.
The other thing is when I do videos,
I don't use consult actually, even though I like it,
because of the preview functionality.
I don't want to be switching between files
and then consult shows us something which is private.
Right. So. So the private VertiCo, it's a small extension
that I have with a few functions for Vertico.
</p>

<p>
Sacha: I've been thinking about modifying the console preview
states so that I can elide more, I can skip over things that
might be private. And things like, I already have a filter
function for marginalia so that it doesn't show me the
values of variables that might be private. But yeah, just
turning off all these things makes it a little bit easier to
say, okay, I'm just going to jump on the live stream and do
this thing.
Some of the other fun stuff that I've been doing along the
</p>

<p>
Prot: So there is that. And for private, of course, the other thing
with privacy is that you want to have a generally good sense
of where you put your files. So for example, in my pictures
folder, I know that I don't have anything private there. But
there are some sub folders which are like personal. So I know
not to go there.
So it might happen, I need to show a picture,
okay, I just go to the pictures folder, and I show it,
no problem.
</p>

<p>
Sacha: lines of keeping things organized is if I have a stream tag on
a task, I know that's safe to show on screen.
And then I modified my Org jump stuff.
There's a hook that you can use to
narrow things to just that subtree.
So at least I can jump to it
and not have to worry about
the rest of the context in my inbox.
Trying to slowly slowly get the hang of this
</p></li>

<li><p>
<span class="audio-time" data-start="890.390" data-stop="909.531">14:50</span>: <b>Livestreaming and recording</b>:
Sacha: Okay. So it's live stream. Do you like to
live stream and record at the same time locally
or just live stream and then go into
the YouTube thing afterwards to download?
</p>

<p>
Prot: I just do the latter.
</p>

<p>
Sacha: It takes a little bit of a while,
</p>

<p>
Prot: I just download it from Youtube afterwards
</p>

<p>
Sacha: so I'm like&hellip; I could get started on the transcription.
</p></li>

<li><p>
<span class="audio-time" data-start="909.532" data-stop="1099.399">15:09</span>: <b>Keeping track of interesting moments</b>:
Sacha: Do you have anything to keep track of interesting moments
that you want to revisit, or do you just, I don't know, skip
around in the video, look at the transcript, whatever?
</p>

<p>
Prot: I remember, I know this sounds bad, but I remember.
</p>

<p>
Sacha: People with good memories, boo!
</p>

<p>
Prot: And generally I try to also sharpen my memory.
So whenever I can practice something, I will do it like that.
But otherwise, if you really need to take a note of something,
you can always have a small function
that just records the timestamp.
Like, what is the current time? And then you know
when you started, so you will know where you are in the video.
Like, it would be a very simple function that simply prints
the current time, you know, format-time-string,
</p>

<p>
Sacha: Yeah. I just have to write something that gets the time
</p>

<p>
Prot: in a buffer at the bottom of a buffer.
And that buffer is like your interesting moments kind of thing.
And if you really want, you can make that prompt you
for some text, like here is the timestamp
and here is like, you know Prot said a joke
or whatever, you know, like&hellip;
</p>

<p>
Sacha: started from YouTube
and then calculates the offset automatically,
so that I can say okay, here are my chapters roughly.
</p>

<p>
Prot: Yeah, that's even more fancy.
Or you could do the other thing, which is all local,
which is the moment the stream starts,
you hit this command, like you invoke it,
so it resets the time
and then it performs the calculation locally.
So you can do calculations with time in Emacs.
So you can perform that as well.
</p>

<p>
Sacha: Yeah, that's really straightforward.
Okay, so that's definitely something that I'm going to want
to think about, because video is great for enthusiasm
and showing cool stuff that you might otherwise
forget to mention, but it's just so slow to review afterwards.
</p>

<p>
Prot: Yeah, of course, of course, of course.
Just to say another thing with video,
what I have found that is really helpful is
to display line numbers.
</p>

<p>
Sacha: Oh yeah? Huh.
</p>

<p>
Prot: Me personally, I don't use line numbers,
but I have found that when I am displaying
something that others need to follow,
line numbers help them. Because for example,
earlier you were jumping around trying to find that hook, you were&hellip;
</p>

<p>
Sacha: Oh yeah, yeah, yeah. Okay. Display now.
</p>

<p>
Prot: And of course, me, I have experience,
so I kind of know what you are doing,
but somebody who is not really into it will be like,
what is happening?
Why are things moving up and down so quickly, right?
</p>

<p>
Sacha: Okay. And they can mention it, too, in the comments,
</p>

<p>
Prot: And they cannot track where you are.
</p>

<p>
Sacha: which is nice.
</p>

<p>
Prot: Yes, yes, of course. And also, when you are displaying
something, you can say, look, on line 100,
what I am doing, for example.
</p>

<p>
Sacha: I have to steal your config for the highlight line
</p>

<p>
Prot: And it's easy for everybody. Yeah.
</p>

<p>
Sacha: priority because I've been using the highlight line for
that. But sometimes it overwrites things. I'm like, OK.
Today it is well-behaved, so I'm glad for that.
</p></li>

<li><p>
<span class="audio-time" data-start="1099.400" data-stop="1226.578">18:19</span>: <b>Editing</b>:
Sacha: Making videos, all right. Just go ahead and make the videos,
you just do it pretty straight, you don't do a lot of editing
afterwards, I'm hearing,
following the same kind of philosophy
that you use for your blog posts?
</p>

<p>
Prot: That's the idea.
</p>

<p>
Sacha: All right, I should just go do things and not worry about
whether the live stream demo that I just made
of how I can highlight the PDF of your literate config
and extract the stuff into whatever has a bug in it.
And I'm like, oh, I just demonstrated that.
It's okay, I can update it in the show notes.
Oh, that's true, especially since
</p>

<p>
Prot: Or even better, you do a second video
afterwards, a follow up.
</p>

<p>
Sacha: now I figured out that you can use org-pdfview view
to link to pages in the PDF.
So now my index.org has the highlights from your config,
and it takes me back to the page that it was on.
Very very cool stuff.
</p>

<p>
Prot: That's nice.
</p>

<p>
Sacha: Okay, so I just gotta do it.
</p>

<p>
Prot: I think Org-noter also is another package
you could use for that.
</p>

<p>
Sacha: Yeah, probably. and then I just need to get&hellip;
I think I've got PDF tools or PDF view set up.
And then reader of course looks very interesting also.
So I've got to tweak my config a little bit more
to get it running because it has an
external dependency.
Anyway, so just got to do the live streaming.
I was delighted. People have actually been
dropping by and commenting or chatting during the live
streams, which is great because I get to remember,
oh yeah, I should explain that part, taking it for granted.
</p>

<p>
Prot: The thing with a live stream,
</p>

<p>
Sacha: So all of that is good stuff.
</p>

<p>
Prot: because it's something you also wrote,
like getting used to talking to yourself, right?
So, of course, that takes some practice,
but I think, yeah, you have the hang of it already.
</p>

<p>
Sacha: Something is ringing. Hang on, sorry.
I forgot. That was just my reminder that the kiddo is back to
school. Virtual school is fine.
Anyways, OK, so so just got to do it.
</p></li>

<li><p>
<span class="audio-time" data-start="1226.579" data-stop="1354.451">20:26</span>: <b>Writing</b>:
Sacha: Thank you for the tips. This is very helpful for
</p>

<p>
Prot: You're welcome.
</p>

<p>
Sacha: writing. I'm getting better at actually remembering to
include more bits and pieces from my config, and I'm sure
that now that I have them in different files, it'll be easier
for me to then write the post that links to, oh yeah, here's
the five other functions you need in order to make this
little snippet work. But do you happen to, knowing the kinds
of stuff that we like to write about, do you have any other
tips from your workflow?
</p>

<p>
Prot: When it comes to sharing code like that, I already noticed
while you were moving around that you have many things like
my-consult, my-org, etc.
What helps there is to just make those
their own module right away. And from there, you know
that, okay, this is either self-contained or it has an
explicit require, so I can already know where I need to
search for dependencies.
So it's really that. It's because, for example, if you take
just a my-consult function, right, of course, you know by the
name that it depends on consult, but you don't know if it
depends on my- common functions, for example. Right.
Whereas if you have it in its own file,
there will be a require at the top.
So, you know, OK, require my-common-functions.
And that way you can tell, okay, there is a dependency here.
So then when you are to share this function, you can search
for, okay, my-common-functions, is it mentioned here?
Yes or no. And then you know what the dependency is.
</p>

<p>
Sacha: And I think this process of moving things into those
separate files will make it easier for then, for people to
say, okay, yes, I do want to try that thing. Let me check out
the repository required, just load-file that
particular file and then be off to the races.
So we'll see how it works.
I don't know if people actually&hellip;
Sometimes people mention borrowing stuff from my blog.
So maybe people are actually reading
the non-Emacs News posts. We'll get to see that.
</p></li>

<li><p>
<span class="audio-time" data-start="1354.452" data-stop="1540.575">22:34</span>: <b>Packaging</b>:
Sacha: Sometimes I feel like a lot of my tweaks
are very idiosyncratic, right?
</p>

<p>
Prot: Yes, what I found that has helped me is I implement the
</p>

<p>
Sacha: They're very suited to the particular need that I have.
And then it's difficult to say,
OK, if I were going to generalize this for other people, what
kind of defcustoms will I need? What kind of options?
And there's always that trade-off between, yeah, but I just
want to implement the next little thing that I want to make
for myself versus, well, if I put in the
polishing effort, then possibly other people could use it,
and learn from it, and then contribute their own ideas,
and then everything gets better without me having to do the work
myself. So it's a bit of a balance.
</p>

<p>
Prot: package that I want. So for example with denote, but this
applies to everything, denote version 0.1 is the package
that I wanted. So basically, it works for me. Ever since, I
have been adding other things that people want, which are,
of course, good things to have. They improve the package,
but I have already been using the package that I want since
the beginning. So ever since, it's just adding stuff and
learning about how people use it and refining the code,
which everybody benefits from. So whenever you have an idea
that you are like, okay, this may be too idiosyncratic,
don't worry about it. Make it into a package, and then what
other people need will become apparent, and then over time
it will change, but the core package is still what you want.
</p>

<p>
Sacha: Although it is interesting to see, for example, with the
university calendar, institution-calendar thing, it's
like, okay, you can get it to work for a small number of
institutions, ELPA wants&hellip; they want it to work for
everyone, everywhere, all the time.
Okay, that might be too general.
You might need to actually have lots of other people
saying what they need in order to make that
happen in the first place, right?
</p>

<p>
Prot: Which at that point, of course, what you want
is to write the documentation. So for example, with the
institution calendar, I wrote a couple of examples. Okay,
how do you extend this? And yeah, I think that helps. But then
of course, you cannot cover every use case like people have
to also make contributions if they really care about.
</p>

<p>
Sacha: Yeah, so I think at the moment,
I've been writing for n equals one,
the audience is really just me.
And occasionally I hear from people who are like,
oh, that's an interesting idea, let me adapt it.
Sometimes if I'm really lucky,
they will go and write their own package
on top of the stuff that I shared,
which is the ideal situation,
because then I can just like, oh, yeah,
I'm going to borrow that and use it.
It'll have more features
and they're in charge of dealing with that.
But I suppose at some point it behooves me to practice.
OK, I'm just going to write it as a package,
pretending that this is something,
as you said, this is something that I want to be able to
install and use myself. Then if other people find it
useful, it's a lot easier for them to experiment with and
then add on to.
</p></li>

<li><p>
<span class="audio-time" data-start="1540.576" data-stop="1761.852">25:40</span>: <b>Responding to email</b>:
Sacha: Which goes to my second thing. Doing this and
making things open to other people probably means being
more responsive to email. And this is, for me, this is a bit of
a challenge. I'm starting to feel less time-starved,
which is good. I'm starting to actually be able to schedule
things.
One of these days, we should probably see if
we can schedule a Prot Asks thing.
I don't know if I can do two hours,
but maybe I can do one hour or whatever.
Anyway, the rest of it involves actually doing
</p>

<p>
Prot: For sure.
</p>

<p>
Sacha: the responsible thing and responding to issues
and emails and whatever.
It's always a bit of a trade-off, like, oh, do I implement
this other crazy idea I have, or do I answer my email?
</p>

<p>
Prot: For that, of course, it's a challenge. I must say that a lot of
the maintenance work I do is via email. Or email or Signal or
Telegram. People will ask me, hey, Prat, what is this? And
many of the issues are not with my package. I had an issue
earlier with the modus themes, no, the ef-themes, and
eventually it was something to do with the user's
configuration of some function of center tabs. But I had to
go into it and check. So, of course, there will be that. But I
must say, it's not too bad. It's not a big issue. You can
always have in your email, like, hey, please don't use this
for issues. And it's not a replacement for that.
Just use the issue tracker.
</p>

<p>
Sacha: I know I just have to&hellip;
I think I just have to like reframe my perspective.
This is a gift. Other people are taking their
time and effort to do this.
It's wonderful that they're trying things out
and putting their&hellip;
actually doing things themselves
and then reaching out in case&hellip;
'cause it would be nice to get things working on more
people's computers. I think that the stuff that I've
been building around learning languages and doing voice
input into Emacs probably&hellip;
There are a lot of these things already,
but they tend to also be very individual workflows
and individual setups.
So it'll be interesting to get to the point
where we can start to even have a conversation with shared code.
</p>

<p>
Prot: About the individual workflow, again, it's not a
problem because what is individual now will eventually
become kind of a standard workflow. Think about org, the
beginning of org. You have Carsten Dominik, who is like, you
know what, this outline mode isn't enough. I need more stuff
on top. And eventually we have Org. In the beginning, I
imagine org was basically Carsten's org, and it became this uh
this package that everybody can use however they feel like.
</p>

<p>
Sacha: I used to maintain Planner Mode before Org Mode got super popular
and I remember feeling very embarrassed when someone very,
very kindly said "I appreciate the work that
you do; incidentally, the latest update kind of
deleted a lot of my notes." So this is like,
when you make something that other people use,
sometimes your mistakes will affect more people
than just you. But I'm hoping now that
now that the disks are in the spaces of terabytes
instead of whatever, people are just backing up everything
and version controlling everything
and everything will be fine.
</p>

<p>
Prot: Yeah, of course, of course.
Writing packages, of course, is a responsibility. The
upside, though, is that because you know that it is a
responsibility, you try to write cleaner code at the outset.
Whereas if it's just for your own configuration,
you're like, okay, this will work and I will fix it later.
</p></li>

<li><span class="audio-time" data-start="1761.646" data-stop="1799.534">29:21</span>: <b>Development workflow</b>:
Sacha: Yeah, and that actually brings me back to this Emacs Lisp
development workflow thing. So I think one of the things
that I just need to do is I just need to set up the Makefiles and
the snippets and the shortcuts to say that if I'm
starting a new proto-package, the thing to run the tests
is there, and whatever it is that maybe even continuously
runs the test when I make a change, and lets me mock up
functions so that I can test some of the things that might be
more interactive or might require deleting files or
whatever. It's just changing my buffer configuration and
whatever.</li>

<li><p>
<span class="audio-time" data-start="1799.535" data-stop="2026.503">29:59</span>: <b>Testing</b>:
Sacha: So I occasionally write ERT tests when I feel diligent.
Sometimes I'm starting to write the test first
and then write the code that makes a thing,
but if you happen to have any parts of your workflow
that you particularly like
when it comes to testing things,
I would love to hear about them
because I haven't gotten to
that part of your config yet
</p>

<p>
Prot: Yeah, so I don't have a lot going on for that. So it's simply
ERT. But what I do with the tests is really basic. So ERT,
M-x ert, and then I pick the test that I want. And I must say that
when it comes to tests, I can be better myself. So there are
some packages I write where they have good tests, but there
are others that have zero tests. So I want to reach a point
where everything has tests, but it takes a lot of work.
</p>

<p>
Sacha: Yeah. I mean, like every so often
I feel like very, very diligent
and I'm like, okay, let's do code coverage.
So I can see things with undercover.
Let's write a function and make sure there's a test
associated with it. And let's write a keyboard shortcut that
lets me jump from the thing to the test
that's associated with it or to run it.
And in fact, I still need to
get embark to do all these things for me so I can
be looking at a function and say
just rerun the test for this, please.
</p>

<p>
Prot: Just to say one low-tech feature that has helped me a lot,
low-tech, Is i use the docstring as a declaration of intent.
So in the docstring, I say what is the function or the variable
meant to do, like what is it meant to provide. And then if I look
at the code and I'm like, ah, this doesn't work, I know that
the doc string is what I wanted. It's never the code. So there
is this idea that the code is a source of truth. For me, it's
the opposite. It's like the doc. It's the specification.
And then the code is&hellip; I was wrong. I was sloppy. I
wasn't paying attention. I missed something or whatever.
And the reason for that is the following. It's because with
the code, you may have used the symbol wrongly, or you may be
calling something that you don't mean to call, or there is
another function. Or, for example, you use mapc instead of
mapcar, so you don't get the return value you expect, that
sort of thing. So something, basically you don't deal with
sloppy problems. So you don't have confusion there. You
know that, okay, the source of truth is the docstring.
This is my intention.
</p>

<p>
Sacha: I should do that more often. Now that I've changed my
yasnippet for inserting functions to automatically have the
docstring, I feel a little guiltier when I delete the
docstring, so I am compelled to instead fill it out. But if I
specify it in more detail, as you do with it becoming the
statement of intent, then I can be like, OK, let's try that.
It's a good practice.
And then I can write the test.
</p>

<p>
Prot: And the thing with docstrings is that, of course, you are
</p>

<p>
Sacha: Yeah? This is me.
</p>

<p>
Prot: motivated to just write the minimum necessary so that you
don't get the warnings, right, from checkdoc.
But if you write more, then you are rewarded yourself.
It's something that helps you, future you,
and of course other users, because you always have to
consider yourself as basically a user.
I don't remember why I wrote this six months ago,
so of course having the docstring there,
actually spell it out, helps me.
</p></li>

<li><p>
<span class="audio-time" data-start="2026.504" data-stop="2130.784">33:46</span>: <b>Learning and reminders</b>:
Sacha: I definitely have problems with working memory
and long-term attention. Which actually touches on this
other thing that I mentioned in my post, which is, in your
experience coaching other people and also in your personal
practice, what are you finding as good ways to keep
reminding yourself, okay, these are the keyboard
shortcuts I want to internalize, or this is the the workflow
tweak that I wanted to try naturally. I was
thinking, maybe I make an Org file or maybe I make a
quick help thing or whatever. But it's always interesting
to hear about other people's workflows.
</p>

<p>
Prot: What I find most useful is to not try to memorize too many
things, but whenever you are in the flow of, oh, this is a
process that I want to be doing, to actually implement it as a
command or whatever, as a package or whatever, like
basically don't try to memorize the steps and of course the
key bindings.
Try to build a function that does those for you.
A command basically that does those for you.
So for example, to be concrete,
I mentioned earlier that for video purposes,
I will enable line numbers.
And I will also enable the line highlight.
And I have another thing where I disable spacious padding.
So the package I have. And all this, of course,
I know the key binding. So it's F7 and F8 and F6 or
whatever, right? But I'm like, I cannot remember all that.
I will just write a function, and it will be
prot-streaming-mode. And I enable prot-streaming-mode, and
it does what I want it to do, and then I disable
prot-streaming-mode, and I'm back to where I need to be.
</p></li>

<li><p>
<span class="audio-time" data-start="2131.732" data-stop="2225.120">35:31</span>: <b>Encapsulating workflows into functions</b>:
Sacha: Yeah, I have a prepare-for-screencast that does
something similar, changes font size, etc, etc.
Tt's so wonderful that in Emacs, you can
</p>

<p>
Prot: Exactly.
</p>

<p>
Sacha: just keep collapsing things into functions that do the
thing that you wanted,
and it has access to pretty much everything.
I just need to remember to actually call the
thing and remember what the thing was actually called.
Aliases are very helpful, so it's orderless, but it's like&hellip;
</p>

<p>
Prot: Another thing that might help is long names. Because with long
names, you have more chances to match it. For example, in
this case, it could be called prot-streaming-mode, but you
could also call it prot-streaming-and-video-demonstrations-mode.
And of course it sounds ridiculous,
but if you think about it, I might search for,
I do M-x and I search stream. I find it. I search video.
I find it, right. I search demo. I find it.
So, if you care about something, you can name it that way,
and then you find it more easily. Or, of course, with
aliases, you do the same, right? prot-streaming-mode,
alias, prot-video-mode, alias, you know how it is. But, yeah,
either of those would work. Basically, benefit from the
fact that you have completion, and I imagine you also have
orderless.
</p>

<p>
Sacha: So definitely that. And then
</p>

<p>
Prot: So, yeah.
</p>

<p>
Sacha: for the free form notes thing, it just occurred to me.
</p></li>

<li><p>
<span class="audio-time" data-start="2225.121" data-stop="2301.616">37:05</span>: <b>Popping up notes</b>:
Sacha: So in addition to your posframe stuff in your config for
quickly popping up an Emacs posframe for some
commands, like, do you have some things?
I suppose I could just use that directly for my notes
and for the chat. Do you have any other of those "quickly pop up
something so that you can do something with it and then make
it disappear?"
</p>

<p>
Prot: No, I haven't built a lot on that. So I have some functions I do
</p>

<p>
Sacha: That's your main thing.
</p>

<p>
Prot: with that. Specifically, I have it for the timers. For me,
that's very useful. And for org-capture, but I haven't
elaborated on it. Of course, I could do that more. Another
that I&hellip; By the way, it's not a poframe.
Technically, what I have is just a new frame.
But the idea is the same, right?
It pops up and it disappears.
And I can share the code for that.
It's in the prot-window package, actually.
</p>

<p>
Sacha: I have it highlighted here in my&hellip;
</p>

<p>
Prot: So it's a small macro there.
</p>

<p>
Sacha: So this is the thing that I was telling you about earlier
where it just extracts all the things that I've
highlighted. It's very, very cool.
It's in one of these, I'll grab it eventually.
Which is good because I have to go over
my config at some point.
</p></li>

<li><p>
<span class="audio-time" data-start="2301.617" data-stop="2431.131">38:21</span>: <b>Rediscovering things in my config</b>:
Sacha: There's so much in there that
I've completely forgotten writing about.
And so I'm like
reading this now as I'm splitting it into different modules
and saying, oh yeah, I automated that.
I'm doing it manually again.
</p>

<p>
Prot: The other thing that might help is a prefix key.
So I have done that with C-z. So it's a prefix key,
and then either with which-key or with Embark,
you know, the Embark&hellip; When Embark replaces C-h.
I forget how it's called now.
You can always see, OK, what do I have? Like, what are the groups?
And then you can cluster things there. And it's very easy.
Ever since defvar-keymap, ever since that became a thing,
it's very easy to write prefix keymaps, because it has a
keyword called prefix, and then with that prefix you define
how the keymap should be called as a command.
</p>

<p>
Sacha: That's interesting. I should definitely look into that.
Finds how it should be called. That's a command.
So you can just add it to other key maps as needed.
That sounds cool.
</p>

<p>
Prot: So consider this difference, like right now, you can take a
defvar, which is a keymap, right? And you can bind it to a key,
the keymap itself, without the quote,
you can bind it to a key. So you will do define key
in the global map, like whatever you want, and then bind it.
What happens though with that
is that you're binding the value of the keymap to the key,
which means if you make changes to the keymap,
your key doesn't know about them.
</p>

<p>
Sacha: I've been running into that. I get annoyed and I have to keep
re-evaluating my definitions.
So yeah, okay, that's what I do.
</p>

<p>
Prot: Whereas if you have the prefix, which is now a command, you
have created an indirection. So now you define key to the
symbol that you have specified.
And that, of course, is that indirection,
which now gets the up-to-date value of the keymap.
</p></li>

<li><p>
<span class="audio-time" data-start="2431.853" data-stop="2489.639">40:31</span>: <b>Catching up on Emacs developments</b>:
Sacha: So this is Emacs stuff that I have been missing out on,
because for the past 10 years
I've just been squeezing things
into whatever moments I can have
before somebody comes and says hello
and says mom mom mom mom,
and now that I have a little bit more focus time,
I'm looking forward to finding out about all the cool stuff
that has gone into Emacs and that I'm not currently taking
advantage of.
So things like, for example, I only scratch the
surface of using Lispy, and I want to do other things as
expressions because it's all magical. And if you have
similar, like, oh yeah, this is a new thing in Emacs 30 or 31
that is super helpful and not everyone knows about it, I'd
love to know about it. I mean, I know it's on Emacs News,
but sometimes I'm like, whoosh, it goes past my radar
and I don't have the time to dig in.
</p>

<p>
Prot: Yeah, right now I cannot think of something.
But yeah, I will.
</p></li>

<li><p>
<span class="audio-time" data-start="2489.640" data-stop="2590.465">41:29</span>: <b>diffs</b>:
Prot: Oh, a very small thing that helps me a lot when I make any
kind of edit. You know, there is this function diff buffer
with file. So that's good. For me, what I always want is
</p>

<p>
Sacha: that sounds like a little tweak
</p>

<p>
Prot: diff-buffer with a current file.
I don't want to diff a buffer
with some random file. So what I have is a very small
extension, a very small function,
which is diff-buffer-buffer-file-name.
So buffer-file-name is the variable for the
current buffer's file. And then I do the buffer file name.
And for me, that's very useful. Whenever I make an edit or I'm
not sure what happened, I do that and I already see the diff. I
use that a lot.
</p>

<p>
Sacha: that I would love to to pick up as well.
There's all sorts of interesting workflow things
that I am looking forward to discovering
as I figure out the better way to watch videos
and then also make videos,
because one of the things I find
is whenever you demonstrate something, sometimes,
if you're really lucky, someone will say,
oh yeah do you know about this thing
that does the whole thing,
which is great.
One of my favorite reasons for sharing things
is learning from other people.
All right.
You write this really long blog
</p>

<p>
Prot: Same. Like you put it out there and somebody will be like,
hey, you could do it this way instead.
</p>

<p>
Sacha: post about this clever thing that you just figured out and
then five minutes later, oh yeah,
that's been built into Org since, you know, version 9.7.
</p>

<p>
Prot: Exactly, exactly.
</p></li>

<li><p>
<span class="audio-time" data-start="2588.000" data-stop="2639.759">43:08</span>: <b>Thinking about the community</b>:
Sacha: Which actually leads me to: what can we do?
We've got about 20, 15 minutes left in this hour.
Taking advantage of your very large context window for all things
Emacs community, you know, those kinds of stuff that we are
interested in, what are some of the things that we could do to
make things even better? This is a very open question, of
course, but yeah.
</p>

<p>
Prot: Even better, you mean Emacs in general or Org in particular?
Because Org got a very nice feature lately, Org 9.8, which is
the ability to preview images for any link type.
So that's very useful.
Before it was like the file type. Now it's any
link type. And of course, if you ever want to do something
with a custom link type, there you have it.
</p></li>

<li><p>
<span class="audio-time" data-start="2640.640" data-stop="2731.744">44:00</span>: <b>org-link-preview</b>:
Sacha: Which is good because I, in fact, have an override for a
custom link type where I had done it before. So I just
basically copied and pasted the image preview link so that I
could have my SVGs either included in it as a whole or just
preview.
Anyway, so yes, I'm going to switch over to the new one.
Link preview, update my code for SVGs.
</p>

<p>
Prot: Yeah, for example, now imagine this. Imagine you have a
custom link type, which is called image or something, and
you just give the image a name, nothing else. And
internally, this link type knows to go in a specific
directory and get the image from there, maybe even have
copies of the image, so it can give you a copy that matches
some parameter or whatever, like some user option maybe.
You could have fancy things like this. I have been thinking
about it, but I haven't written anything yet.
</p>

<p>
Sacha: I would probably like&hellip; Things like my audio waveforms could
go in there very easily and things like that.
I'm very curious about this idea of mixing more things into other
places in Emacs. And one of the things that I've been meaning
to dig into is how LECDraw does SVG interaction, because it
uses mouse events to be able to drag things around and
whatever. Because I think if we can get richer
interactivity and more graphical elements, that could be
really fun.
</p></li>

<li><p>
<span class="audio-time" data-start="2731.745" data-stop="2812.599">45:31</span>: <b>Prioritizing things to work on</b>:
Sacha: Anyway, but yes, so I've got basically three
months of focus time before the kid goes on summer vacation
and wants my attention at probably the majority of the day
at an irregular interval. So it'll be a lot harder for me to
schedule things then. I can set aside maybe 10
hours a week to work on Emacs-y things, including possibly
working on infrastructure for the upcoming EmacsConf,
or tweaking Emacs News or hosting meetups or whatever.
Taking advantage of you as an external perspective,
are there things that would be a good idea for
me to particularly focus on? Things that you've been
wishing you could say, Sacha, hey,
just do this thing and it'll be awesome.
</p>

<p>
Prot: I think you already have a very good setup, actually.
So I don't think there is much to be done
in terms of adding things.
Maybe the work here is to be removing things, and
that's the more difficult part.
</p>

<p>
Sacha: No!
Delegating things. Passing things to other people, maybe.
Making it possible for other people to help.
</p></li>

<li><span class="audio-time" data-start="2799.931" data-stop="2813.679">46:39</span>: <b>Modelines</b>:
Prot: There is a very small thing which maybe is useful,
maybe it isn't. I don't know how much you use the mode line,
how much you rely on that, but the newer version of Emacs makes it
possible to shrink the lighters for the minor modes.</li>

<li><p>
<span class="audio-time" data-start="2812.600" data-stop="2944.755">46:52</span>: <b>Modelines</b>:
Sacha: Yeah, I don't use the mode-line as much.
I ended up moving keycast to the header line
because it's a little bit more visible in videos.
Sometimes when closed captioning is on, it obscures the mode line.
So I don't tend to look at the mode line for much,
and I'm wondering what I'm missing out on.
And I'll probably also want to add: am I streaming?
</p>

<p>
Prot: Yeah, not much. Not much is the answer, but maybe you could
declutter it in that regard so that then it is useful. For me,
where it really is useful is to know some things such as, of
course, what is the buffer name? Is the view narrowed?
That's, for me, really important.
Maybe is it a read-only file?
And am I running a keyboard macro?
</p>

<p>
Sacha: Is my microphone on?
</p>

<p>
Prot: Yes. Good, good.
You see, there are all sorts of good ideas.
And you can think of those as just one character, right?
And you can have that one character with a face, which has,
for example, a background. So is my microphone on?
That's a green background. Am I streaming?
That's a red background or whatever.
And you just see the colors there and you know
everything is all right.
</p>

<p>
Sacha: Although, actually, now that we're talking about it,
I'm thinking maybe I should just revive websockets.
So I made an obs-websocket.el thing before, and someone has&hellip;
The benefits of making a package:
someone has actually updated it
to work with the new WebSocket protocols.
I just have to get the whole thing set up again
so I can communicate with OBS.
I can use a different theme, most likely
another Modus theme, when I'm streaming,
so that it's a little bit more in my face:
okay I'm looking at the correct colors, I am public.
</p>

<p>
Prot: That's the other thing. Yeah, that's good. That's good.
</p></li>

<li><p>
<span class="audio-time" data-start="2930.136" data-stop="2967.263">48:50</span>: <b>Themes would be nice to have per-frame</b>:
Prot: With themes, unfortunately, that's
actually something I would like to have. We cannot have them
per frame, which is strange because if you do
set-face-attribute, you can specify a frame argument.
But if you do something like custom-set-faces, you cannot.
</p>

<p>
Sacha: I'm sure that once you start messing around with Emacs
internals, you might be able to figure out the way to do that.
</p>

<p>
Prot: Yeah, now that I say it, it shouldn't be too difficult. Yeah.
Famous last words.
</p>

<p>
Sacha: Yeah, yeah, yeah. That's really fun.
Okay, so that gives me stuff to work on.
</p></li>

<li><span class="audio-time" data-start="2967.264" data-stop="3011.719">49:27</span>: <b>Livestreaming conversations with Prot</b>:
Sacha: I brought up briefly the idea of possibly
setting up some kind of streaming things because I think,
for example, this conversation that we have&hellip;
I have so far managed to not share anything
that is too private, except for, of course,
the time when the kid is like, hello, mom,
I need your attention and I want to be on stream.
She likes to make cameos.
So we could share this,
and we could potentially think about
having these kinds of conversations
as something that other people could join in on,
because it causes more questions,
it's more interesting, and it also gets stuff out there
without me having to type the lessons learned.
So is that maybe something we can consider doing,
I don't know, once a month for the next three months?</li>

<li><p>
<span class="audio-time" data-start="3011.965" data-stop="3284.242">50:11</span>: <b>Getting together</b>:
Prot: For me, yes. Even more frequently than once a month.
Whatever works for you. For me, it works. That's the point.
And also not in the context of coaching or whatever, but
generally as a collaboration, I'm totally okay with that.
Basically, more events for the community. I'm all for it.
</p>

<p>
Sacha: Yeah, because it is different.
I very much had missed doing Emacs chats,
and I'm so delighted that you've got Prot Asks.
I'm looking forward to watching
the one that you just released,
because it's a community event, right?
You get to know about interesting things about people.
And there are a lot of things
that come up through conversations
that don't come up when you're just
writing by yourself.
</p>

<p>
Prot: Yes, yes, yes. It's really that. It's really that. And for
me, it's also another thing, which is it's more inviting.
Like, it's like you are telling people, hey, show up like you
can participate. Actually, we are friendly. Like, here we
are. You see us.
I think that kind of encouragement helps.
</p>

<p>
Sacha: So if you want to do, like, Emacs office hours
on a regular basis,
either something that you schedule in yours&hellip;
Is it a YouTube thing where we can both schedule a live
and then both have it, or not?
I think they've got a collab thing now. I don't know.
</p>

<p>
Prot: I haven't explored it. So on the technical side, I really
don't know. But in terms of intention, I'm all for it. So we
can of course figure out the technicality.
</p>

<p>
Sacha: You have the bigger channel.
</p>

<p>
Prot: But I really don't know.
We can do it twice a month, or even if you want, if you are really
</p>

<p>
Sacha: If you want to set it up, then Thursdays are probably good.
Or if you want me to set it up, then I can do that.
And then we can figure out the platform details
and the non-YouTube way for people to join&hellip;
probably IRC. We've got all this lovely
infrastructure for EmacsConf,
which I dust off every month for meetups.
So that's certainly something
we can slide right in there too.
Okay, so if we do it once a month,
that just gives me three sessions of practice,
but if we do it like twice a month or more,
I am also okay with that.
I think we can squeeze that in and make that happen.
</p>

<p>
Prot: into it, once a week, a live stream once a week. And yeah,
people can join, and we can always have a topic and talk about
it and take it from there. We could also do it.
Now, I don't know whatever makes more sense,
but we could do it on my channel. And then, of course,
with a prominent link to your channel,
or we can do it one on your channel,
one on my channel or always on your channel.
Me, I don't mind at all. Like me,
I'm in for the fun.
</p>

<p>
Sacha: We'll figure out the technical details
and whatever off-stream.
It could be interesting because then
that gives people a friendly place to drop by and chat.
And also because I know you're there and I'm there,
it gets away from the talking to myself.
When it's just me talking
and then it's just like chat is silent,
it just feels like I have this unfairly privileged position.
So yeah, that's definitely something
we're going to look into.
We can structure that as one of these coaching thingies
if I'm looking for excuses to use
the Google Open Source Peer Bonus.
I still haven't really made a justifiably good plan for it.
So yes. Okay.
Oh, this has been very helpful.
I've got like all these tips.
If you're okay with it, I am totally fine with posting
this recording online.
If you want, you can also post it.
I think there's some kind of collab thing.
</p>

<p>
Prot: Me, I don't have a recording. So you can do whatever you want.
So it's really up to you. Me, I don't mind. The reason I don't
have recordings of my meetings is because I really have this
policy of, you know, it's private. Your name is never known.
Nobody has seen this. That's the idea. Of course, in your
case, you're making it public. So, of course, that's fine.
</p>

<p>
Sacha: Yeah, my stance is always, well,
I'm going to learn stuff, but A, I'm very forgetful,
so I need to be able to search it and find it again.
And B, other people can pick up stuff too.
I might as well expand the learning
and do the learning out loud.
So all that is good.
And then for next time,
which will probably be in two weeks,
or maybe earlier if I manage to get my act together,
</p></li>

<li><p>
<span class="audio-time" data-start="3284.243" data-stop="3346.639">54:44</span>: <b>Namespaces</b>:
Sacha: I'd like to see if I can get my stuff
properly split up into different modules
that have the different namespace.
I really think I'm going to end up shifting to
the sacha- namespace instead of all the my- stuff.
I used to use the my- namespace prefix
so that people could copy and paste things
more easily into their code.
But now I'm like, well, if I put it in sacha-,
then I'm not polluting their namespace
if they're loading the whole library.
</p>

<p>
Prot: Yes, yes, exactly. Exactly, exactly. That's a good thing.
</p>

<p>
Sacha: So that's on my to-do list.
</p>

<p>
Prot: And with naming things, of course, I also hinted that in the
article I wrote in response to your blog post. It really
helps to think about the names. Also, with what we said
earlier about finding things like so don't try to be too
terse, too economical with the names like make the most of it.
</p>

<p>
Sacha: I'm using nameless anyway to hide the prefixes.
Got to get the hang of using the keyboard shortcuts
to insert things.
</p></li>

<li><p>
<span class="audio-time" data-start="3346.640" data-stop="3403.240">55:46</span>: <b>Verbose function names</b>:
Sacha: Yeah, so I do like having very verbose function names
and just practically full sentences in the thing.
All that is very good. So that's my main thing.
Aand then of course, getting into more ERT&hellip;
I have this function that now that lets me try to
jump to the test or the file that's related to this thing.
So we'll see how it goes,
especially as I move things into these different functions.
</p>

<p>
Prot: Okay, okay I'm not sure how you are doing that, but if I were to
implement something like that myself, what I do with the ERT
tests, it's always the prefix of the ERT file and then the
name of the original function, double dash and then the name
of the original function. So, for example, let's say,
modus-themes-tests, right? So then it's
modus-themes-tests&ndash;modus-themes-load-theme, for example.
</p></li>

<li><p>
<span class="audio-time" data-start="3405.526" data-stop="3434.839">56:45</span>: <b>Naming conventions for ERT tests</b>:
Sacha: Okay, so that's your naming convention.
</p>

<p>
Prot: That's a convention. That's a convention, yes.
</p>

<p>
Sacha: I should try that.
I've just been basically naming things as function-name.
And then I was,  like, maybe I should be calling them
function-name-test.
Or in this case, you know, package.
</p>

<p>
Prot: Just to add something to this, because you also named this,
so the nameless user. So there is built into Emacs this thing
called shorthands.
</p></li>

<li><p>
<span class="audio-time" data-start="3434.650" data-stop="3507.720">57:14</span>: <b>shorthands</b>:
Sacha: Yeah, I read about that, but you did mention that some people
have been going back and forth about whether it's worth
using it or whether it confuses things more.
I think just leaving the names as is
and then just displaying it differently
seems to be like an in-between step.
</p>

<p>
Prot: So that's what shorthand does. The name is, for example,
modus-themes-test. And shorthand, effectively, is a buffer
local variable which takes the small prefix and maps it to
the larger prefix. So modus-themes-test can be mtt, for example.
</p>

<p>
Sacha: Okay. All right.
So basically it's a more powerful nameless,
more configurable, and it's built in.
So I should check that out also.
</p>

<p>
Prot: Yeah, you can check it. It's not configurable, like it
doesn't give you too many options. But the point is that for
this simple case, at least for the tests, I find it useful
because I don't want to have like a railroad of a function
name, right? So I just want to be looking at something that I
can understand. And basically, the prefix of the test is
just there for it to have a prefix. And then I know what the
function I am testing is.
</p></li>

<li><span class="audio-time" data-start="3507.786" data-stop="3525.222">58:27</span>: <b>Bisecting config in multiple files</b>:
Sacha: I had a quick question about the config. So you
have, in addition to your modules, you also have&hellip;
Your Emacs's configuration is also split up
into multiple files.
How do you bisect these things when you're tracking down the bug?</li>

<li><p>
<span class="audio-time" data-start="3526.908" data-stop="3989.520">58:46</span>: <b>"I don't write bugs."</b>:
Prot: I don't write bugs. No, no, no, of course, I'm kidding.
</p>

<p>
Sacha: That's going to go in the quotes.
Okay, I don't write bugs.
I write a lot of bugs.
That's going to go to the blog post.
It's going to be very large.
So you never have to use bug-hunter because you just
don't write bugs in the first place. Bravo. Good for you.
</p>

<p>
Prot: Why didn't people think about that?
Now, of course, I'm kidding.
So the way it works is that they are actually
standalone packages. So there is a distinction, actually,
in my configuration. So there are the modules, which is the
configuration blocks, what would be done with. And then
there are the libraries, which are actually packages, like
I could just publish them right now. For example, for the
mode line, there is prot-mode-line. That could be a package
tomorrow, no problem. So if there is a bug there, I will go and
deal with it the way I would deal with any package, like
edebug, toggle-debug-on-error, whatever it is that I am
doing. So there never is a scenario where the code is in all
sorts of places, scattered across the file, and then, of
course, it's very difficult to track it.
</p>

<p>
Sacha: But for your config, if it's in multiple files
and you need to bisect it&hellip; Bisecting can get you to
this load-file over here, this require over here
is where things break down, but then you have to&hellip;
okay, I want to load everything above that point and then
bisect into the thing, which is slightly more annoying.
</p>

<p>
Prot: In practice, it's not difficult, because the way I
</p>

<p>
Sacha: I don't know. How does that work?
</p>

<p>
Prot: load my packages, so in the modules themselves. So I have
this macro, which has a condition case in it. Of course,
usePackage has the same, but with usePackage, you have to
have everything as a package, whereas what I have here is
even if it's not a package. So condition case, and basically
if there is an error, it tells me where the error is, and then I
can find it very easily. I have never had a scenario (of course I was joking,
but actually I'm serious)&hellip; I've never had a scenario where
I was confused as to what was happening. It was always very
easy to find the error. If it's a bug&hellip; Yeah.
</p>

<p>
Sacha: Errors are fairly straightforward
because it complains about it,
but when it runs but it just produces
the wrong behavior eventually,
then that's the annoying part
that I've been using bug hunter for.
</p>

<p>
Prot: The only scenario I think now that I had an
issue like that was with the mode line, actually. Because
with the mode line, if you give it like a wrong face or
something, I don't remember, it will print like several
messages for everything that changes on the mode line. So
you will get like, well, invalid face, and there will be
like, in square brackets, 100 times of this message. So
That's the sort of thing that indeed is more tricky, but that
was not because of my code. It was because of one small tweak
that affects the mode line, and then it was about figuring
out what the error is there, what's the bug there. But if you
have the configuration split up in ways that are logical or
thematic, if you want, whatever bug is always in one spot. It
won't cut between files. So for example i have a module
which is theme in the wider set but the theme also includes
fonts. because fonts are, in Emacs terms, part of faces,
themes deal with faces, that sort of thing. So whenever it's
something related to appearance, I know that it's in the
theme. It cannot be somewhere else because of how I have
written it. Of course, depending on how you split things up,
you will end up in a scenario where you have bugs that go
across files. For example, a common one is where people will
have, for example, evil mode, right? And then they will load
everything, and then they will have a separate
configuration module, which is for key bindings. And
basically, that's a disaster, because whenever there is
some problem, you don't know which key binding relates to
which package, and you are always in a state that it's hard to
predict.
And basically, you have to do every key binding with eval
after load, this package, this key binding kind of thing.
</p>

<p>
Sacha: Oh, that's going to be fun.
I do have a bunch of key bindings in my file,
so I'll just have to see how that all gets organized.
</p>

<p>
Prot: If you have them, organize them by package. Define them
close to the context. Okay.
</p>

<p>
Sacha: That's actually mostly what I've been doing,
mostly because I think of it,
I think of the key binding
when I'm adding the package to my config,
so it's right there.
I just realized I could probably just copy
the top of my config file with requires or whatever
to a setup file,
which bug-hunter can then load. So I can still probably use
</p>

<p>
Prot: Okay, good.
</p>

<p>
Sacha: bug-hunter with that. Anyway, thank you so much.
</p>

<p>
Prot: Yeah, sure. I just wanted to ask the last thing.
What is the kind of bug that you have encountered?
What kind of bugs are we talking about here?
</p>

<p>
Sacha: Recently, in my shifting of everything to the new system,
I also happened to realize that I had updated my Emacs
and then stuff wasn't highlighting in the mini buffer.
I eventually found out that it was because I needed
to upgrade certain packages.
But in the meantime, I was like, what do you mean?
Okay, emacs -Q, sometimes it's working,
sometimes it's not working.
Okay, let's start narrowing it down.
And that was fun.
The other thing that I recently had to bisect was:
I was exporting my really large config
after having split things up into different modules.
One of the lines was causing it to go into like a
debugging thing, but it would not tell me what
it actually debugged. You know, the backtrace would just
not happen. So then I actually had to narrow to region
and then export the specific sections of my file until I
narrowed it down to, okay, my defvar custom link needs
fixing. So I do this kind of bisection a lot.
Ideally, whenever I can, I like to be able to
just write an assertion
so that Emacs can do the work of narrowing down
when this happens but sometimes it's just,
you know, you gotta pick your range
and then execute the thing and see what happens.
So I'm always looking for tools
because I write a lot of bugs.
I'm sure by the time I see you again,
it may be either next week or next next week,
I will have more bugs to share
and more things to learn from.
But this is very helpful
and I am looking forward to updating you
once I get all of the stuff checked off my to-do list.
</p>

<p>
Prot: Very good. Let me know how it goes.
</p>

<p>
Sacha: Yeah, yeah, awesome. Thank you so much.
</p>

<p>
Prot: And for the live streams, we see how it goes. Yeah.
You will tell me. Yeah.
</p>

<p>
Sacha: And it's okay to post this recording if you want to?
</p>

<p>
Prot: Whatever you want. Whatever you want.
</p>

<p>
Sacha: Awesome, all right, see you around.
</p>

<p>
Prot: Take care, Sacha. Bye bye.
</p></li>
</ul>


</details>
</div>
</div>
<div id="outline-container-projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-ideas-for-next-steps" class="outline-3">
<h3 id="projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-ideas-for-next-steps">Ideas for next steps</h3>
<div class="outline-text-3" id="text-projects-experiment-with-learning-from-prot-yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp-ideas-for-next-steps">
<p>
Oh, do I ever have a lot of ideas to follow up on. =) But I'm making myself get used to writing them down so that I can post these notes instead of trying to squeeze in just one more tweak&hellip; Anyway, plenty to explore!
</p>

<ul class="org-ul">
<li class="on"><span class="task-done">&#x2611;</span> Add chapters to video</li>
<li class="on"><span class="task-done">&#x2611;</span> Edit transcript - rough</li>
<li class="on"><span class="task-done">&#x2611;</span> combine multiple captions</li>
<li class="on"><span class="task-done">&#x2611;</span> Post the video</li>
<li class="on"><span class="task-done">&#x2611;</span> Post notes (this one!)</li>
<li class="on"><span class="task-done">&#x2611;</span> Schedule next session and open it up</li>
<li class="on"><span class="task-done">&#x2611;</span> Try Internet Archive</li>
<li class="on"><span class="task-done">&#x2611;</span> Combine transcripts and use speaker tags; style the output</li>
<li class="trans"><span class="task-in-progress">[-]</span> Redact part of the video
<ul class="org-ul">
<li class="off"><span class="task-todo">&#x2610;</span> Write about compile-media updates</li>
<li class="on"><span class="task-done">&#x2611;</span> Get my GPU working for ffmpeg</li>
<li class="off"><span class="task-todo">&#x2610;</span> Get my GPU working for whisperx</li>
<li class="off"><span class="task-todo">&#x2610;</span> Select the coordinates from Emacs</li>
</ul></li>

<li>Streaming and video
<ul class="org-ul">
<li class="off"><span class="task-todo">&#x2610;</span> Write about two-speaker workflow</li>
<li class="off"><span class="task-todo">&#x2610;</span> Make sure vtime link type works with this player</li>
<li class="off"><span class="task-todo">&#x2610;</span> Figure out a workflow for adding intros or wrap-ups</li>
<li class="off"><span class="task-todo">&#x2610;</span> Display YouTube chat in Emacs</li>
<li class="off"><span class="task-todo">&#x2610;</span> Find a command-line way to send text to the YouTube chat</li>
<li class="off"><span class="task-todo">&#x2610;</span> Extract part of a video as a clip</li>
<li class="trans"><span class="task-in-progress">[-]</span> Make a global minor mode for doing things publicly (<a href="https://sachachua.com/dotemacs#streaming-mode-for-streaming">Mode for streaming</a>)
<ul class="org-ul">
<li class="on"><span class="task-done">&#x2611;</span> Change theme</li>
<li class="on"><span class="task-done">&#x2611;</span> Turn on line numbers</li>
<li class="on"><span class="task-done">&#x2611;</span> Turn on keycast</li>
<li class="on"><span class="task-done">&#x2611;</span> Change agenda files and inbox</li>
<li class="off"><span class="task-todo">&#x2610;</span> Save narration</li>
<li class="off"><span class="task-todo">&#x2610;</span> Consider consult previews, marginalia</li>
</ul></li>
<li class="off"><span class="task-todo">&#x2610;</span> Make a todo link type that creates the TODO item and publishes a link to it when finished</li>
<li class="on"><span class="task-done">&#x2611;</span> Make public-ish Org files</li>
<li class="off"><span class="task-todo">&#x2610;</span> Send a URL to the stream as QR and text chat</li>
<li class="on"><span class="task-done">&#x2611;</span> Send text to the stream</li>
<li class="off"><span class="task-todo">&#x2610;</span> Calculate timestamp offsets into a recording</li>
<li class="off"><span class="task-todo">&#x2610;</span> Quickly log times and notes to current task and stream log</li>
<li class="off"><span class="task-todo">&#x2610;</span> Make a nicer combined transcript PDF for review</li>
</ul></li>
<li class="off"><span class="task-todo">&#x2610;</span> Reorganize my configuration
<ul class="org-ul">
<li class="off"><span class="task-todo">&#x2610;</span> Finish extracting the rest of my functions</li>
<li class="off"><span class="task-todo">&#x2610;</span> Rename my- to sacha-</li>
<li class="off"><span class="task-todo">&#x2610;</span> Write about my org-babel-post-tangle-hook</li>
<li class="off"><span class="task-todo">&#x2610;</span> Try out substitute, especially with the replace-regexp-as-diff idea</li>
<li class="off"><span class="task-todo">&#x2610;</span> Define function aliases</li>
<li class="off"><span class="task-todo">&#x2610;</span> Try shorthands</li>
<li class="off"><span class="task-todo">&#x2610;</span> Try defvar-keymap :prefix</li>
<li class="off"><span class="task-todo">&#x2610;</span> Practise using docstrings to declare intent</li>
<li class="off"><span class="task-todo">&#x2610;</span> Convert my custom link preview code</li>
<li class="off"><span class="task-todo">&#x2610;</span> Replace C-z</li>
</ul></li>
<li class="off"><span class="task-todo">&#x2610;</span> Testing
<ul class="org-ul">
<li class="off"><span class="task-todo">&#x2610;</span> Set up a Makefile snippet for tests</li>
<li class="off"><span class="task-todo">&#x2610;</span> Settle into a naming convention for tests</li>
<li class="off"><span class="task-todo">&#x2610;</span> Practise mocking up functions in order to test things that are more interactive</li>
<li class="off"><span class="task-todo">&#x2610;</span> Make code coverage more habitual</li>
</ul></li>
<li class="off"><span class="task-todo">&#x2610;</span> Finish reading Prot's config and process my notes</li>
<li class="off"><span class="task-todo">&#x2610;</span> Set up crdt just in case</li>
<li class="off"><span class="task-todo">&#x2610;</span> Play with the idea of XP (experience points) as a reward for postponing a task and then picking it up again</li>
<li class="off"><span class="task-todo">&#x2610;</span> Write about deleting windows vertically; consider beframe and shortcuts to arrange frames</li>
<li class="off"><span class="task-todo">&#x2610;</span> Pop up and dismiss my notes
<ul class="org-ul">
<li class="off"><span class="task-todo">&#x2610;</span> Make my notes contextual</li>
</ul></li>
</ul>


<p>
Want to join us on Thu April 16 10:30 AM America/Toronto, 5:30 PM Europe/Athens? Check out <a href="https://youtube.com/live/djE_pVlgDHg?feature=share">the livestream we've penciled in for April 16</a> - come join us!
</p>
</div>
</div>
<div><a href="https://sachachua.com/blog/2026/04/yayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp/index.org">View Org source for this post</a></div>
<p>You can <a href="https://social.sachachua.com/@sacha/statuses/01KNBEKNBFP9NNX9MSPCFFZ05Z" target="_blank" rel="noopener noreferrer">comment on Mastodon</a> or <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F04%2Fyayemacs-10-emacs-coaching-with-prot-packaging-emacs-lisp%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Extract PDF highlights into an Org file with Python</title>
		<link>https://sachachua.com/blog/2026/04/demo-extract-pdf-highlights-into-an-org-file-with-python/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Thu, 02 Apr 2026 12:05:16 GMT</pubDate>
    <category>org</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/04/demo-extract-pdf-highlights-into-an-org-file-with-python/</guid>
		<description><![CDATA[<div class="update" id="orge9cc480">
<p>
<span class="timestamp-wrapper"><time class="timestamp" datetime="2026-04-06">[2026-04-06 Mon]</time></span>: Updated screenshot. I finished
reading all the pages and ended up with 202
highlights, so I'm going to have fun updating my
config with those notes!
</p>

</div>

<p>
I've been trying to find a good workflow for highlighting interesting parts of PDFs, and then getting that into my notes as images and text in Emacs. I think I've finally figured out something that works well for me that feels natural (marking things.
</p>

<p>
I wanted to read through <a href="https://protesilaos.com/emacs/dotemacs">Prot's Emacs configuration</a> while the kiddo played with her friends at the playground. I saved the web page as a PDF and exported it to <a href="http://getnoteful.com/">Noteful</a>. The PDF has 481 pages. Lots to explore! It was a bit chilly, so I had my gloves on. I used a capacitative stylus in my left hand to scroll the document and an Apple Pencil in my right hand to highlight the parts I wanted to add to my config or explore further.
</p>

<p>
Back at my computer, I used <code>pip install pymupdf</code> to install the <a href="https://github.com/pymupdf/PyMuPDF">PyMuPDF</a> library. I poked around the PDF in the Python shell to see what it had, and I noticed that the highlights were drawings with fill 0.5. So I wrote this Python script to extract the images and text near that rectangle:
</p>


<div class="org-src-container">
<pre class="src src-python"><code><span class="org-keyword">import</span> fitz
<span class="org-keyword">import</span> pathlib
<span class="org-keyword">import</span> sys
<span class="org-keyword">import</span> os

<span class="org-variable-name">BUFFER</span> <span class="org-operator">=</span> 5

<span class="org-keyword">def</span> <span class="org-function-name">extract_highlights</span>(filename, output_dir):
    <span class="org-variable-name">doc</span> <span class="org-operator">=</span> fitz.<span class="org-builtin">open</span>(filename)
    <span class="org-variable-name">s</span> <span class="org-operator">=</span> <span class="org-string">"* Excerpts</span><span class="org-constant">\n</span><span class="org-string">"</span>
    <span class="org-keyword">for</span> page_num, page <span class="org-keyword">in</span> <span class="org-builtin">enumerate</span>(doc):
        <span class="org-variable-name">page_width</span> <span class="org-operator">=</span> page.rect.width
        <span class="org-variable-name">page_text</span> <span class="org-operator">=</span> <span class="org-string">""</span>
        <span class="org-keyword">for</span> draw_num, d <span class="org-keyword">in</span> <span class="org-builtin">enumerate</span>(page.get_drawings()):
            <span class="org-keyword">if</span> d[<span class="org-string">'fill_opacity'</span>] <span class="org-operator">==</span> 0.5:
               <span class="org-variable-name">rect</span> <span class="org-operator">=</span> d[<span class="org-string">'rect'</span>]
               <span class="org-variable-name">clip_rect</span> <span class="org-operator">=</span> fitz.Rect(0, rect.y0 <span class="org-operator">-</span> BUFFER, page_width, rect.y1 <span class="org-operator">+</span> BUFFER)
               <span class="org-variable-name">img</span> <span class="org-operator">=</span> page.get_pixmap(clip<span class="org-operator">=</span>clip_rect)
               <span class="org-variable-name">img_filename</span> <span class="org-operator">=</span> <span class="org-string">"page-%03d-%d.png"</span> <span class="org-operator">%</span> (page_num <span class="org-operator">+</span> 1, draw_num <span class="org-operator">+</span> 1)
               img.save(os.path.join(output_dir, img_filename))
               <span class="org-variable-name">text</span> <span class="org-operator">=</span> page.get_text(clip<span class="org-operator">=</span>clip_rect)
               <span class="org-variable-name">page_text</span> <span class="org-operator">=</span> (page_text
                            <span class="org-operator">+</span> <span class="org-string">"[[file:%s]]</span><span class="org-constant">\n</span><span class="org-string">#+begin_quote</span><span class="org-constant">\n</span><span class="org-string">[[pdf:%s::%d][p%d]]: %s</span><span class="org-constant">\n</span><span class="org-string">#+end_quote</span><span class="org-constant">\n\n</span><span class="org-string">"</span>
                            <span class="org-operator">%</span> (img_filename,
                               os.path.join(<span class="org-string">".."</span>, filename),
                               page_num <span class="org-operator">+</span> 1,
                               page_num <span class="org-operator">+</span> 1, text))
        <span class="org-keyword">if</span> page_text <span class="org-operator">!=</span> <span class="org-string">""</span>:
            <span class="org-variable-name">s</span> <span class="org-operator">+=</span> <span class="org-string">"** Page %d</span><span class="org-constant">\n</span><span class="org-string">%s"</span> <span class="org-operator">%</span> (page_num <span class="org-operator">+</span> 1, page_text)
    pathlib.Path(os.path.join(output_dir, <span class="org-string">"index.org"</span>)).write_bytes(s.encode())

<span class="org-keyword">if</span> <span class="org-builtin">__name__</span> <span class="org-operator">==</span> <span class="org-string">'__main__'</span>:
    <span class="org-keyword">if</span> <span class="org-builtin">len</span>(sys.argv) <span class="org-operator">&lt;</span> 3:
        <span class="org-builtin">print</span>(<span class="org-string">"Usage: list-highlights.py pdf-filename output-dir"</span>)
    <span class="org-keyword">else</span>:
        extract_highlights(sys.argv[1], sys.argv[2])
</code></pre>
</div>


<p>
After I opened the resulting <code>index.org</code> file, I used <code>C-u C-u</code> <code>C-c C-x C-v</code> (<code>org-link-preview</code>) to make the images appear inline throughout the whole buffer. There's a little extra text from the PDF extraction, but it's a great starting point for cleaning up or copying. The org-pdftools package lets me link to specific pages in PDFs, neat!
</p>


<figure id="orgef7258d">
<a href="https://sachachua.com/blog/2026/04/demo-extract-pdf-highlights-into-an-org-file-with-python/2026-04-06-22-55-35.png"><img src="https://sachachua.com/blog/2026/04/demo-extract-pdf-highlights-into-an-org-file-with-python/2026-04-06-22-55-35.png" alt="2026-04-06-22-55-35.png"></a>

<figcaption><span class="figure-number">Figure 1: </span>Screenshot of Org Mode file with link previews</figcaption>
</figure>

<p>
To set up <code>org-pdftools</code>, I used:
</p>


<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">use-package</span> org-pdftools
  <span class="org-builtin">:hook</span> (org-mode . org-pdftools-setup-link))
</code></pre>
</div>


<p>
Here's my quick livestream about the script with a slightly older version that had an off-by-one bug in the page numbers and didn't have the fancy PDF links. =)
</p>

<p>
</p><div class="yt-video"><iframe width="456" height="315" title="YouTube video player" src="https://www.youtube-nocookie.com/embed/OTnYV2IZL_U?enablejsapi=1" frameborder="0" allowfullscreen="">nil</iframe><a href="https://youtube.com/live/OTnYV2IZL_U">Watch on YouTube</a></div>
<p></p>
<div><a href="https://sachachua.com/blog/2026/04/demo-extract-pdf-highlights-into-an-org-file-with-python/index.org">View Org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F04%2Fdemo-extract-pdf-highlights-into-an-org-file-with-python%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>Thinking about Emacs coaching goals with Prot</title>
		<link>https://sachachua.com/blog/2026/03/thinking-about-coaching-goals-with-prot/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Tue, 31 Mar 2026 18:37:44 GMT</pubDate>
    <category>emacs</category>
<category>community</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/03/thinking-about-coaching-goals-with-prot/</guid>
		<description><![CDATA[<div class="update" id="orgec330df">
<p>
<span class="timestamp-wrapper"><time class="timestamp" datetime="2026-03-31">[2026-03-31 Tue]</time></span>: Hooray for learning out loud! <a href="https://protesilaos.com/codelog/2026-03-31-emacs-coaching-with-sacha-chua/">Prot has already posted his responses</a>.
</p>

</div>

<p>
Following up on <a href="https://sachachua.com/blog/2026/03/emacs-carnival-march-2026-mistakes-and-learning-to-reach-out/">Emacs Carnival March 2026: Mistakes and learning to reach out</a>: I want to get better at learning with other people's help, so I'm going to experiment with engaging <a href="https://protesilaos.com/coach/">Prot as an Emacs coach</a>. Our first session is this week. Time to lay the groundwork!
</p>

<p>
If I meet with Prot twice a month for three months, that's a budget of €60 (~CAD 100), which is a reasonable size for an experiment especially since I still have the budget set aside from the <a href="https://sachachua.com/blog/2023/12/google-open-source-peer-bonus/">Google Open Source Peer Bonus</a> and lovely folks already donated to <a href="https://my.fsf.org/civicrm/contribute/transact?reset=1&amp;id=70">cover the costs for EmacsConf</a>. When I schedule something with someone, the accountability makes it easier to get stuff done and out the door. For this, a real person is much better than AI because:
</p>
<ul class="org-ul">
<li>I get to take advantage of Prot's very large context window, and he knows stuff about the Emacs, the community, and me that I might not remember to mention</li>
<li>He can ask real questions and prod at things that are unclear or contradictory, unlike the confirmation bias of LLMs</li>
<li>He might point out things that wouldn't occur to me to ask about</li>
<li>It triggers my "I promised someone I'd do this" thing</li>
<li>I get to support an individual worth supporting rather than contributing to the concentration of wealth and information in for-profit entities</li>
</ul>

<p>
My motivations:
</p>

<ul class="org-ul">
<li><p>
<b>I want to make better use of my focused time</b> during the rest of the schoolyear. For the next three months, my schedule will be fairly predictable and I'll have regular chunks of focused time. Over the past two months, I've averaged around 10 hours of Emacs-related stuff per week (including 1.5 hours or so for Emacs News). I'm currently thinking about language learning and speech input. EmacsConf is on the horizon and will probably ramp up after September, but I can also think ahead of workflow improvements or ways to collaborate with other people. I might put together an Emacs News Highlights presentation. Also, I'm always looking out for ways to build the community.
</p>

<p>
Summer break during July and August will shake things up again, but I might be able to find some focused time early morning or evening. I'd like to be in a good position to make the most of those time fragments.
</p></li>

<li><b>I want to improve my Emacs Lisp development workflow</b> and learn more about libraries and techniques that might be useful. I'm beginning to have more time to sharpen the saw and I'm curious about all the cool stuff that I missed or skimmed over the past ten years. What are some useful setups for completion, debugging, navigation, etc.?
<ul class="org-ul">
<li>Current: I sporadically use the extra awesomeness in seq, pcase, <a target="_blank" href="https://melpa.org/#/lispy">lispy</a>, <a target="_blank" href="https://melpa.org/#/erefactor">erefactor</a>, ert, <a target="_blank" href="https://melpa.org/#/buttercup">buttercup</a>, and <a target="_blank" href="https://melpa.org/#/undercover">undercover</a>, but not consistently. I'd like to reduce the friction and make these habitual.</li>
<li>Areas of friction / improvement:
<ul class="org-ul">
<li>writing tests, especially for things that are more interactive</li>
<li>navigating code that might be scattered in literate config files or in Emacs Lisp files</li>
<li>forgetting to restart or to make sure all code is saved; running tests via Emacs batch mode will help, as will <code>package-isolate</code> and <code>restart-emacs</code></li>
</ul></li>
</ul></li>

<li><b>I want to improve my workflows for writing, making videos, and streaming.</b> If I get better at sharing what I'm working on, I might be able to connect with more people and bounce ideas around.  Also, accountability might help me nudge this over the threshold. I probably still need to work in stops and starts, so I want to reduce the friction. I'm curious about other people's workflows for sharing. I like joining meetups, but I tend to share stuff only if no one else has anything planned, because I have my blog and my YouTube channel in case I want to share anything with a wider group of people. I just have to actually post things.
<ul class="org-ul">
<li><p>
Current: ~1.5 <a href="https://sachachua.com/blog/category/emacs">Emacs</a> posts a week aside from Emacs News, attending meetups, sporadically adding short video demos to posts
</p>
<details><summary>Average number of Emacs-related posts that aren't Emacs News</summary>
<div class="org-src-container">
<pre class="src src-emacs-lisp"><code>(<span class="org-keyword">let*</span> ((start <span class="org-string">"2026-02-01"</span>)
       (end <span class="org-string">"2026-03-31"</span>)
       (posts (my-blog-posts
               start end
               (<span class="org-keyword">lambda</span> (o)
                 (<span class="org-keyword">and</span> (member <span class="org-string">"emacs"</span> (alist-get <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">categories</span> o))
                      (not (member <span class="org-string">"emacs-news"</span> (alist-get <span class="org-highlight-quoted-quote">'</span><span class="org-highlight-quoted-symbol">categories</span> o)))))))
       (count (length posts)))
  (my-weekly-average count start end))
</code></pre>
</div>

</details></li>
<li>Goal: 2-3 non-News posts a week, one video a month, one stream or meetup a month; maybe also beyond looking at the numbers, it might be interesting to build more momentum around a topic, set up trails/navigation, cultivate more of a digital garden</li>
<li>Areas of friction / improvement:
<ul class="org-ul">
<li>Resisting "one more tweak"</li>
<li>Streaming: Still need to get the hang of talking to myself or having half-conversations with chat: can be worked around by scheduling a session with Prot and opening it to the public</li>
<li>Hiding private information or setting up a separate Emacs for demonstration</li>
<li>Harvesting videos/clips/notes afterwards</li>
</ul></li>
</ul></li>

<li><b>I want to move more of my configuration into files and libraries</b> that other people can reuse, like <a href="https://codeberg.org/sachac/learn-lang/">sachac/learn-lang</a> and <a href="https://codeberg.org/sachac/speech-input">sachac/speech-input</a>. I can also separate the function definitions from the configuration in my code so that people can reuse the functions if they want.
<ul class="org-ul">
<li>Areas of friction / improvement
<ul class="org-ul">
<li>renaming things when I want to move them to a library</li>
<li>duplicating small functions (ex: simplify string)</li>
<li>figuring out how to make it possible for someone else to start using my stuff</li>
</ul></li>
</ul></li>
</ul>

<p>
Starting questions for Prot:
</p>

<ul class="org-ul">
<li>Meta: what are people finding useful for coaching and behaviour change, like learning new keyboard shortcuts or workflows?</li>
<li>Your literate config exports to individual .el files. I could probably do something similar to separate my functions from my personal config in order to make it easier for people to reuse parts of my config. Is it worth doing so? Do people tell you that they use those private Emacs Lisp files by loading them, or do they mostly rely on your published packages?</li>
<li>Does the division into multiple .el files work fine if you need to bisect your configuration?</li>
<li>Do you have some tweaks to make it easier to jump to function definitions considering a literate configuration?</li>
<li>What's your general process for migrating things from your config to a repository or package?</li>
</ul>

<p>
Could be fun. Let's experiment!</p>
<div><a href="https://sachachua.com/blog/2026/03/thinking-about-coaching-goals-with-prot/index.org">View Org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F03%2Fthinking-about-coaching-goals-with-prot%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item><item>
		<title>2026-03-30 Emacs news</title>
		<link>https://sachachua.com/blog/2026/03/2026-03-30-emacs-news/</link>
		<dc:creator><![CDATA[Sacha Chua]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 13:57:50 GMT</pubDate>
    <category>emacs</category>
<category>emacs-news</category>
		<guid isPermaLink="false">https://sachachua.com/blog/2026/03/2026-03-30-emacs-news/</guid>
		<description><![CDATA[<p>
It's not too late to write about <a href="https://sdf.org/~pkal/blog/emacs/mistakes.html">mistakes and misconceptions</a> as part of the Emacs Carnival for March and not too early to think about the theme of "Newbies/Starter Kits" which Cena will be hosting for April. Who knows, maybe those ideas can become part of the <a href="https://github.com/emacs-mirror/emacs/blob/db412283d6b4fb8ea9d48629add952bf8fe2f423/etc/themes/newcomers-presets-theme.el">newcomers presets</a>.
It could be fun to explore something like <a href="https://org-roam.nshephard.dev/#754f25a5-3429-4504-8a17-4efea1568eba">notes for Emacs beginners</a> and see where you end up.
</p>

<p>
Also, I'm looking forward to seeing if these tips for <a href="https://emacsredux.com/blog/2026/03/25/reloading-emacs-lisp-code/">reloading Emacs Lisp code</a> can help me avoid little bugs from leftover code.
</p>

<p>
Enjoy!
</p>

<ul class="org-ul">
<li>Upcoming events (<a href="https://emacslife.com/calendar/emacs-calendar.ics">iCal file</a>, <a href="https://emacslife.com/calendar/">Org</a>):
<ul class="org-ul">
<li>EmacsATX: Emacs Social <a href="https://www.meetup.com/emacsatx/events/313720093/">https://www.meetup.com/emacsatx/events/313720093/</a> Thu Apr 2 1600 America/Vancouver - 1800 America/Chicago - 1900 America/Toronto - 2300 Etc/GMT &ndash; Fri Apr 3 0100 Europe/Berlin - 0430 Asia/Kolkata - 0700 Asia/Singapore</li>
<li>M-x Research: TBA <a href="https://m-x-research.github.io/">https://m-x-research.github.io/</a> Fri Apr 3 0800 America/Vancouver - 1000 America/Chicago - 1100 America/Toronto - 1500 Etc/GMT - 1700 Europe/Berlin - 2030 Asia/Kolkata - 2300 Asia/Singapore</li>
<li>Emacs.si (in person): Emacs.si meetup #4 2026 (v #živo) <a href="https://dogodki.kompot.si/events/c4ee8c26-c668-491e-91b3-b466578b83e2">https://dogodki.kompot.si/events/c4ee8c26-c668-491e-91b3-b466578b83e2</a> Mon Apr 6 1900 CET</li>
<li>OrgMeetup (virtual) <a href="https://orgmode.org/worg/orgmeetup.html">https://orgmode.org/worg/orgmeetup.html</a> Wed Apr 8 0900 America/Vancouver - 1100 America/Chicago - 1200 America/Toronto - 1600 Etc/GMT - 1800 Europe/Berlin - 2130 Asia/Kolkata &ndash; Thu Apr 9 0000 Asia/Singapore</li>
<li>Atelier Emacs Montpellier (in person) <a href="https://lebib.org/date/atelier-emacs">https://lebib.org/date/atelier-emacs</a> Fri Apr 10 1800 Europe/Paris</li>
</ul></li>
<li>Beginner:
<ul class="org-ul">
<li><a href="https://org-roam.nshephard.dev/#754f25a5-3429-4504-8a17-4efea1568eba">Emacs Getting Started - notes in org-roam</a></li>
<li><a href="https://www.youtube.com/watch?v=uNR18ylj9rg">Emacs Describes Almost Everything Within It 2026 03 30 03:29:50</a> (10:02)</li>
</ul></li>
<li>Emacs configuration:
<ul class="org-ul">
<li><a href="https://bicycleforyourmind.com/generaldotel-to-conquer-emacs-keybindings">general.el to Conquer Emacs Keybindings - Bicycle For Your Mind</a></li>
<li><a href="https://github.com/jamescherti/compile-angel.el/">compile-angel.el - Ensure that all Emacs Lisp files are always byte-compiled and native-compiled [Release 1.2.0]​</a></li>
<li><a href="https://emacsredux.com/blog/2026/03/26/emacs-prelude-redux/">Emacs Redux: Emacs Prelude: Redux</a></li>
</ul></li>
<li>Emacs Lisp:
<ul class="org-ul">
<li><a href="https://emacsredux.com/blog/2026/03/25/reloading-emacs-lisp-code/">Emacs Redux: Reloading Emacs Lisp Code</a> (<a href="https://irreal.org/blog/?p=13703">Irreal</a>)</li>
<li><a href="https://codeberg.org/rossabaker/better-calculate-lisp-indent.el">rossabaker/better-calculate-lisp-indent.el: Improves indentation of quoted and backquoted lists in Emacs lisp - Codeberg.org</a> (<a href="https://social.rossabaker.com/@ross/116309247188891323">@ross@social.rossabaker.com</a>)</li>
</ul></li>
<li>Appearance:
<ul class="org-ul">
<li><a href="https://emacsredux.com/blog/2026/03/29/automatic-light-dark-theme-switching/">Emacs Redux: Automatic Light/Dark Theme Switching</a></li>
<li><a href="https://emacsredux.com/blog/2026/03/30/creating-emacs-color-themes/">Emacs Redux: Creating Emacs Color Themes, Revisited</a></li>
<li><a href="https://www.reddit.com/gallery/1s2zmzt">A small victory: Emacs core modification in C to set line-height less than the default</a></li>
<li><a href="https://batsov.com/articles/2026/03/29/batppuccin-my-take-on-catppuccin-for-emacs/">Bozhidar Batsov: Batppuccin: My Take on Catppuccin for Emacs</a></li>
</ul></li>
<li>Navigation:
<ul class="org-ul">
<li><a href="https://vmst.io/@t0yv0/116315552245920931">treesitedit-mark-sexp is useful</a></li>
</ul></li>
<li>TRAMP:
<ul class="org-ul">
<li><a href="https://www.reddit.com/r/emacs/comments/1s6t15d/the_new_tramp_alternatives_are_probably_not_worth/">The new TRAMP alternatives are probably not worth it</a></li>
</ul></li>
<li>Writing:
<ul class="org-ul">
<li><a href="https://chrismaiorana.com/git-commits-tell-the-story/">Chris Maiorana: Let the commits tell the story</a> (<a href="https://irreal.org/blog/?p=13713">Irreal</a>)</li>
<li><a href="https://www.youtube.com/watch?v=016N8DNGm7I">my minimalist emacs setup for writing</a> (21:43)</li>
<li><a href="https://blog.davep.org/2026/03/29/blogmore-el-v2-0.html">blogmore.el v2.0 - davep - setting up multiple blogs</a> (<a href="https://fosstodon.org/@davep/116314226800303433">@davep@fosstodon.org</a>) <a href="https://blog.davep.org/2026/03/30/blogmore-el-v2-1.html">and 2.1</a></li>
</ul></li>
<li>Denote:
<ul class="org-ul">
<li><a href="https://protesilaos.com/codelog/2026-03-24-emacs-another-spontaneous-live-stream/">Protesilaos Stavrou: Emacs: another spontaneous live stream for denote-sequence</a> (<a href="https://www.youtube.com/watch?v=rDJbPCjZiOI">YouTube</a>)</li>
<li><a href="https://www.youtube.com/watch?v=4RxFImWhNrI">Emacs: spontaneous live stream to implement a denote-sequence feature</a> (02:13:01)</li>
</ul></li>
<li>Org Mode:
<ul class="org-ul">
<li><a href="https://sachachua.com/blog/2026/03/categorizing-emacs-news-items-by-voice-in-org-mode/">Sacha Chua: Categorizing Emacs News items by voice in Org Mode</a></li>
<li><a href="https://curtismchale.ca/2026/03/24/goodbye-longform-hello-emacs">Curtis McHale: Goodbye Longform Hello Emacs</a> (<a href="https://www.youtube.com/watch?v=d5fRFF6Q5aU">YouTube</a> 16:59, <a href="https://irreal.org/blog/?p=13696">Irreal</a>)</li>
<li><a href="https://chrismaiorana.com/introduction-orgfolio/">Chris Maiorana: OrgFolio | Turn your scattered interests into cultivated obsessions</a> (<a href="https://irreal.org/blog/?p=13694">Irreal</a>)</li>
<li><a href="https://github.com/aleksozolins/org-taube">aleksozolins/org-taube: Email-first capture pipeline for Org mode · GitHub</a> (<a href="https://www.reddit.com/r/orgmode/comments/1s61k4j/orgtaube_emailfirst_capture_pipeline_for_org_mode/">Reddit</a>)</li>
<li>Org development:
<ul class="org-ul">
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=bf0df4898adf48cf55ab03453c93c27e6ee0a9f4">Fixed org-babel-execute:awk to work on remote machines</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/etc/ORG-NEWS?id=d26b3b7db3ec61c92d77877fb25d8f1ef70ccc21">ox-latex: Make brackets around LATEX_CLASS_OPTIONS optional</a></li>
</ul></li>
</ul></li>
<li>Coding:
<ul class="org-ul">
<li><a href="https://github.com/iquiw/emacstreak">iquiw/emacstreak: GitHub streak stats on Emacs · GitHub</a> (<a href="https://mstdn.jp/@iquiw/116284618043833112">@iquiw@mstdn.jp</a>)</li>
<li><a href="https://masutaka.net/en/2026-03-29-1/">Migrating from asdf and direnv to mise | Masutaka's ChangeLog Memo</a> (<a href="https://mstdn.love/@masutaka/116311842345792856">@masutaka@mstdn.love</a>) - fixing ruby-lsp not working in Emacs</li>
<li><a href="https://github.com/bbatsov/neocaml/releases/tag/v0.6.0">neocaml 0.6: dune major/minor mode, flymake backend</a> (<a href="https://hachyderm.io/@bbatsov/116289235912157177">@bbatsov@hachyderm.io</a>)</li>
<li><a href="https://emacsredux.com/blog/2026/03/27/paredit-keybinding-conflicts/">Emacs Redux: Paredit’s Keybinding Conflicts</a> (<a href="https://irreal.org/blog/?p=13705">Irreal</a>)</li>
<li><a href="https://mbork.pl/2026-03-23_Disabling_Eslint_in_one_line_with_Tide">Marcin Borkowski: Disabling Eslint in one line with Tide</a></li>
<li><a href="https://www.emacs.dyerdwelling.family/emacs/20260329084330-emacs&#45;&#45;simply-annotate-0.9/">James Dyer: Simply Annotate 0.9.8: Threaded Conversations on Your Code</a> (<a href="https://github.com/captainflasmr/simply-annotate">Github</a>, <a href="https://www.reddit.com/r/emacs/comments/1s6qnxk/simply_annotate_098_threaded_conversations_on/">Reddit</a>)</li>
<li><a href="https://github.com/torusJKL/flymake-janet">flymake-janet: A Flymake backend for the Janet language [v0.2.0]​</a></li>
<li><a href="https://batsov.com/articles/2026/03/25/neocaml-0-6-opam-dune-and-more/">Bozhidar Batsov: Neocaml 0.6: Opam, Dune, and More</a></li>
<li><a href="https://einar.codeberg.page/use-python-shell-from-virtual-environment-if-there-is-one-in-Emacs.html">Einar Mostad: Use python shell from virtual environment if there is one in Emacs</a></li>
<li><a href="https://batsov.com/articles/2026/03/27/fsharp-ts-mode-a-modern-emacs-mode-for-fsharp/">Bozhidar Batsov: fsharp-ts-mode: A Modern Emacs Mode for F#</a></li>
<li><a href="https://www.youtube.com/watch?v=4rqzQwYG_Co">Monday Live Coding with Emacs. 3/23/2026 #coding #livecoding #emacs #learnc</a> (01:20:11)</li>
</ul></li>
<li>Shells:
<ul class="org-ul">
<li><a href="https://www.youtube.com/watch?v=rGfV8ivDn_0">Edit Shell Commands in Emacs with CTRL-X CTRL-E</a> (15:43)</li>
</ul></li>
<li>Web:
<ul class="org-ul">
<li><a href="https://www.youtube.com/watch?v=vu2AoMmjSAo">Emacs Webpaste Is A Tool To Use Online Pastebin Services 2026_03_25_03:57:04</a> (18:01)</li>
</ul></li>
<li>Mail, news, and chat:
<ul class="org-ul">
<li><a href="https://todon.nl/@janneke/116318089281171468">Code for reminding you about forgotten attachments</a></li>
<li><a href="https://git.andros.dev/andros/meshmonitor-chat.el">andros/meshmonitor-chat.el - chat client for Meshtastic mesh networks</a> (<a href="https://activity.andros.dev/@andros/statuses/01KMG6VG1Y4ZQ40YGR2HHC5HN6">@andros@activity.andros.dev</a>)</li>
</ul></li>
<li>Fun:
<ul class="org-ul">
<li><a href="https://www.travellerrpg.com/threads/random-character-generator.44664/">Random Character Generator | Citizens of the Imperium</a> (<a href="https://tabletop.social/@kensanata/116305994604769025">@kensanata@tabletop.social</a>)</li>
</ul></li>
<li>Community:
<ul class="org-ul">
<li><a href="https://www.reddit.com/r/emacs/comments/1s229ve/fortnightly_tips_tricks_and_questions_20260324/">Fortnightly Tips, Tricks, and Questions — 2026-03-24 / week 12</a></li>
<li><a href="https://www.birkey.co/2026-03-28-emacs-as-a-programmable-workbench.html">Emacs as a programmable workbench</a> (<a href="https://www.reddit.com/r/emacs/comments/1s6j2ac/emacs_as_a_programmable_workbench/">Reddit</a>)</li>
<li><a href="https://sdf.org/~pkal/blog/emacs/mistakes.html">Emacs Carnival March 2026: Mistakes and Misconceptions</a>
<ul class="org-ul">
<li><a href="https://www.acdw.net/eww-fragments.html">EWW fragments: fixing my own mistakes | acdw.net</a></li>
<li><a href="https://sachachua.com/blog/2026/03/emacs-carnival-march-2026-mistakes-and-learning-to-reach-out/">Sacha Chua: Emacs Carnival March 2026: Mistakes and learning to reach out</a></li>
<li><a href="https://box.matto.nl/my-emacs-misconceptions.html">My Emacs misconceptions - box.matto.nl</a></li>
</ul></li>
<li><a href="https://emacsredux.com/blog/2026/03/26/happy-13th-birthday-emacs-redux/">Emacs Redux: Happy 13th Birthday, Emacs Redux!</a></li>
<li><a href="https://protesilaos.com/prot-asks/2026-03-25-arkadiusz-blindness-emacspeak-hyperbole-chinese-slavic-culture/">Prot Asks: Arkadiusz about blindness, Emacspeak, Hyperbole, Chinese and Slavic culture | Protesilaos Stavrou</a> (<a href="https://www.youtube.com/watch?v=oH5GKEgEGV0">YouTube</a> 01:57:23)</li>
<li><a href="https://www.reddit.com/r/emacs/comments/1s6x9gk/google_sheets_anyone/">xenodium wants to know if people want to sponsor Org Mode + Google Sheets sync</a> (<a href="https://indieweb.social/@xenodium/116313054843219060">@xenodium@indieweb.social</a>)</li>
</ul></li>
<li>Other:
<ul class="org-ul">
<li><a href="https://github.com/Malabarba/aggressive-indent-mode/pull/165">Fix idle timer leak when saving buffers by kommen · Pull Request #165 · Malabarba/aggressive-indent-mode · GitHub</a> (<a href="https://hachyderm.io/@kommen/116314449174368819">@kommen@hachyderm.io</a>)</li>
<li><a href="https://www.reddit.com/r/emacs/comments/1s5gnfa/emacs_on_the_go_on_a_zinwa_q25_on_android/">Emacs on the go on a Zinwa Q25 on Android</a></li>
</ul></li>
<li>Emacs development:
<ul class="org-ul">
<li>emacs-devel:
<ul class="org-ul">
<li><a href="https://yhetil.org/emacs-devel/AMBP194MB2691225C32CCDCEB595ED3248455A@AMBP194MB2691.EURP194.PROD.OUTLOOK.COM/">new branch scratch/ert-play-keys lets ERT interactively play keystrokes during tests</a></li>
<li><a href="https://yhetil.org/emacs-devel/87y0jbk80r.fsf@recursewithless.net/">How can we improve shorthands? - Richard Lawrence</a></li>
<li><a href="https://yhetil.org/emacs-devel/jwvfr5kqdcn.fsf-monnier+emacs@gnu.org/">monitoring GC</a></li>
<li><a href="https://debbugs.gnu.org/cgi/bugreport.cgi?bug=80602">"GNU ELPA packages with NonGNU ELPA dependencies" (a very long thread) that people who maintain packages in GNU ELPA might want to know about</a> (<a href="https://www.reddit.com/r/emacs/comments/1s4ty7u/gnu_elpa_packages_with_nongnu_elpa_dependencies_a/">Reddit</a>)</li>
</ul></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=3b7d9e37ce0c27d942ee583526bd5c96cbdd6f1e">Implement new Dired handling of errors from 'ls'</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=d78000728351986b0083013728dc3ef366112c0b">Add predicate for initial_terminal</a></li>
<li><a href="https://git.savannah.gnu.org/cgit/emacs.git/commit/etc/NEWS?id=a4d99971d8e835fddf5a604d8da1d74c5eb3c858">New user option 'whitespace-global-mode-buffers'</a></li>
</ul></li>
<li>New packages:
<ul class="org-ul">
<li><a target="_blank" href="https://melpa.org/#/ancient-theme">ancient-theme</a>: A theme about ruins (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/anju">anju</a>: Mouse UX Customizations (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/clj-doc-browse">clj-doc-browse</a>: Browse Clojure library docs from classpath JARs (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/eglot-typescript-preset">eglot-typescript-preset</a>: Eglot preset for TypeScript (MELPA)</li>
<li><a target="_blank" href="https://elpa.nongnu.org/nongnu/eldoc-mouse-nov.html">eldoc-mouse-nov</a>: Preview epub link for mouse hover (NonGNU ELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/flywrite">flywrite</a>: Inline writing suggestions via LLM (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/fsharp-ts-mode">fsharp-ts-mode</a>: Major mode for F# code (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/llm-test">llm-test</a>: LLM-driven testing for packages (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/ros-face">ros-face</a>: Syntax highlighting for ROS files (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/tetris-60">tetris-60</a>: Retro ASCII Tetris (MELPA)</li>
<li><a target="_blank" href="https://melpa.org/#/vterm-editor">vterm-editor</a>: Edit text in a buffer and send it to vterm (MELPA)</li>
</ul></li>
</ul>

<p>
Links from <a href="https://www.reddit.com/r/emacs">reddit.com/r/emacs</a>, <a href="https://www.reddit.com/r/orgmode">r/orgmode</a>, <a href="https://www.reddit.com/r/spacemacs">r/spacemacs</a>, <a href="https://mastodon.social/tags/emacs">Mastodon #emacs</a>, <a href="https://bsky.app/hashtag/emacs">Bluesky #emacs</a>, <a href="https://hn.algolia.com/?query=emacs&amp;sort=byDate&amp;prefix&amp;page=0&amp;dateRange=all&amp;type=story">Hacker News</a>, <a href="https://lobste.rs/search?q=emacs&amp;what=stories&amp;order=newest">lobste.rs</a>, <a href="https://programming.dev/c/emacs?dataType=Post&amp;page=1&amp;sort=New">programming.dev</a>, <a href="https://lemmy.world/c/emacs">lemmy.world</a>, <a href="https://lemmy.ml/c/emacs?dataType=Post&amp;page=1&amp;sort=New">lemmy.ml</a>, <a href="https://planet.emacslife.com">planet.emacslife.com</a>, <a href="https://www.youtube.com/playlist?list=PL4th0AZixyREOtvxDpdxC9oMuX7Ar7Sdt">YouTube</a>, <a href="http://git.savannah.gnu.org/cgit/emacs.git/log/etc/NEWS">the Emacs NEWS file</a>, <a href="https://emacslife.com/calendar/">Emacs Calendar</a>, and <a href="https://lists.gnu.org/archive/html/emacs-devel/2026-03">emacs-devel</a>. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at <a href="mailto:sacha@sachachua.com">sacha@sachachua.com</a>. Thank you!
</p>
<div><a href="https://sachachua.com/blog/2026/03/2026-03-30-emacs-news/index.org">View Org source for this post</a></div>
<p>You can <a href="mailto:sacha@sachachua.com?subject=Comment%20on%20https%3A%2F%2Fsachachua.com%2Fblog%2F2026%2F03%2F2026-03-30-emacs-news%2F&body=Name%20you%20want%20to%20be%20credited%20by%20(if%20any)%3A%20%0AMessage%3A%20%0ACan%20I%20share%20your%20comment%20so%20other%20people%20can%20learn%20from%20it%3F%20Yes%2FNo%0A">e-mail me at sacha@sachachua.com</a>.</p>]]></description>
		</item>
	</channel>
</rss>