Irreal: đŸ„© Red Meat Friday: The Perils Of Rewriting

The Emacs Cat, of whom I’ve written many times, has a post on a broken change in Ubuntu that affected Emacs. The TL;DR is that the Cat upgraded to Ubuntu 26.4 but when he tried to use Emacs he discovered a problem with Dired. At first he thought the problem was with Emacs 30.2, which is the default Emacs with that version of Ubuntu. But the actual problem turned out to be with Ubuntu’s implementation of ls. The Cat solved his problem by using the “old” version of ls from GNU coreutils. Ubuntu had decided that it was a good idea to rewrite the core Unix utilities—such as ls​—in Rust.

Maybe I’m just old and grumpy but this seems to me to be a terrible idea. Utilities like ls have been around and working more or less flawlessly for close to 50 years. What, really, was the reasoning behind the decision to rewrite ls? Twenty six years ago, Joe Spolsky answered that question and explained why the rewriting is almost always a bad idea.

It may have been written a quarter of century ago but Spolsky’s explanation remains true. There really is no reason—other than fashion—to rewrite core utilities that have been working perfectly well for longer than many of us have been alive. When you do, you can expect exactly the sort of problem that the Cat stumbled on.

The problem with the new ls was very specific involving an obscure parameter but it reached out to disable a major Emacs functionality and probably affected other applications as well. The annoying thing is that there really wasn’t any reason for this to happen: just someone who decided it would be a good idea to rewrite an application that was working fine.

-1:-- đŸ„© Red Meat Friday: The Perils Of Rewriting (Post Irreal)--L0--C0--2026-08-14T15:32:50.000Z

Chris Maiorana: The Emacs pastoral tradition

You’ve probably noticed, Emacs users tend to be a different breed than other computer users. While you can be reasonably sure that anyone who uses vim or VSCode is probably a developer, or someone who works in software engineering, devops, or systems administration, Emacs users can be from virtually anywhere else on the map.

While conventional software has the basics—like users, functions, documentation, and best practices—Emacs has a tradition.

In this article, we’ll look at:

Table of Contents

Let’s get nutty.

The Emacs pastoral tradition

Emacs users may come from career backgrounds or intellectual disciplines that have almost nothing to do with software or computers in general, but they have simply found their way into the “cult” of Emacs from pursuits like:

  • Academics
  • Writing and literature
  • Civics
  • Philosophy
  • Law
  • Medicine
  • Music

(And more, I’m sure.)

I’ll use myself as an example. In my technical writing career I was searching for a more optimized text editor. I started learning vim, but switched to Emacs because, as it turns out, I wasn’t looking for a text editor so much as an “operating system” for writing.

Emacs could be more than a text editor. It could be an organizer, a scratchpad, a dictionary, a canvas, a database, a calendar, an email client, and much more. What should have been work started to feel like fun.

This is what I’ve started calling the Emacs pastoral tradition.

Pastoral themes in literature evoke images of shepherds ostensibly tending to a flock, but really engaging in more leisurely pursuits like writing poetry and music. The point being that it’s the leisurely pursuits that uplift the soul and are thus more important than mere toil, even if toil is useful and productive.

Emacs is a kind of playground where we can bring our unique ideas and favorite hobbyhorses and have fun building systems around them.

The pastoral also applies to the church: the pastor as the shepherd, and the ones being sermonized to as the flock. Emacs is already jokingly referred to as a cult, so I need not belabor this point.

Doing “useless” work can be useful

What we do in Emacs can look a lot like work, and sometimes it is, but often it’s leisure disguised as work.

This might include:

  • Writing a blog post in Org Mode (as I’m doing now).
  • Tweaking your init.el file to approach that ever-illusive perfect configuration.
  • Auditioning new packages out of curiosity.
  • Trying to play Doom or surf the web in Emacs.

I’d go so far as to say that there are some entire projects out there, such as EXWM, that can be described as leisure.

Does anyone really need an Emacs window manager? No, but that’s the point. It’s an aesthetic choice rather than a purely rational one. An Emacs window manager is no more useful than any other.

I’ll paraphrase Roger Scruton in saying:

There’s nothing quite as useful as the truly useless.

But even useless pursuits can be useful, even if the only useful aspect is the fun of leisurely non-productivity.

The tool doesn’t always matter

Emacs pursuits can be productive endeavors, but they need not be in order to justify our time.

There are lots of productivity tools out there that are probably better than Org Mode. Or, at the very least, an intelligent critic could make an impassioned case for why Org Mode is lame, with multiple bullet points and peer-reviewed references; but it would not be persuasive at all to a sufficiently dedicated Org user.

For Emacs users, the user-friendliness or usefulness of the tool is the not the key point. The promise of endless tinkering is more tantalizing than a tool that simply works all the time. That’s why we’re always tweaking but never really landing on a static configuration. Emacs itself is a running Lisp image you can manipulate on the fly. At this level of interaction, the margins between work, experimentation, and play become invisible, or at least quite porous.

Some people believe we may on the cusp on a new era of non-production. You know as well as I do that there’s more hype than substance around AI at the moment. However, in the brave new world, there’s a non-zero chance that the machines will take over all the toil and leave us free to indulge in a new age of pastoral leisure. Sitting under shady trees and composing romantic sonnets in iambic pentameter sounds pretty good to me.

For people who derive value and validation from productivity, this is a threat. But for Emacs users it might be what we’ve always wanted.


If you enjoyed this ramble, here are some next steps for your consideration:

Thanks for reading. See you next time!

The post The Emacs pastoral tradition appeared first on Chris Maiorana.

-1:-- The Emacs pastoral tradition (Post Chris Maiorana)--L0--C0--2026-08-14T04:00:24.000Z

Sacha Chua: Emacs Chat 28: Fabrice Niessen (en français)

Nous avons parlé en direct avec Fabrice Niessen (Formation Emacs Boost) d'Emacs, de ses flux de travail, de sa configuration, et d'autres sujets en français.

J'ai essayé de corriger la transcription, mais je crois qu'il y a encore beaucoup d'erreurs, donc n'hésitez pas à m'envoyer un message.

  • 0:00 Introduction
  • 1:46 Le parcours
  • 4:15 Emacs sur Windows : Cygwin et WSL
  • 8:26 Les automatisations
  • 12:15 Emacs Boost
  • 21:15 Emacsclient
  • 28:49 org-html-themes
  • 35:02 Review
  • 37:25 PDF
  • 40:03 Key-chord
  • 45:41 Copier sans sĂ©lectionner
  • 48:29 fill-paragraph
  • 50:02 Les macros
  • 51:02 Volatile highlight
  • 52:47 Les tableaux Org
  • 55:43 Les formations et les cours particuliers

La transcription un peu corrigée

Details

0:00 Introduction

Sacha: Ça marche!

Prot: Maintenant, nous sommes en direct.

Sacha: SuccĂšs! Bonjour Ă  toutes et Ă  tous et bienvenue dans le deuxiĂšme Ă©pisode d'Emacs Chat en français. C'est le 28e Ă©pisode de la sĂ©rie. J'espĂšre que j'ai lancĂ© la diffusion correctement cette fois. Aujourd'hui, notre invitĂ© est Fabrice Niessen, un consultant informatique qui habite en Belgique et qui a beaucoup de dĂ©pĂŽts dĂ©diĂ©s Ă  Emacs et Ă  Org Mode, tels que le kit de configuration Leuven et le thĂšme de publication d'Org Mode org-html-themes. Il propose aussi des formations Ă  Emacs en prĂ©sentiel Ă  Paris, Ă  Rotterdam et dans d'autres villes. Merci d'ĂȘtre lĂ , Fabrice.

Fabrice: Merci pour l'invitation. C'est trĂšs sympa de votre part.

Sacha: Merci aussi Ă  Prot de m'aider pour la conversation. En fait, je pense que mon niveau de français est un peu trop faible pour ce genre de conversation, mĂȘme avec le sous-titrage automatique de mon navigateur. Donc, je vais Ă©tudier le sous-titre aprĂšs la conversation pour mieux en tirer parti. Nous faisons de notre mieux ensemble.

Prot: Merci. Je t'en prie, je t'en prie. Non, de fait, trĂšs bien, trĂšs bien.

Sacha: C'est parti. Fabrice, tu utilises Emacs depuis trĂšs longtemps. 1999, c'est plus logique en Belgique.

Fabrice: Absolument. La Suisse est encore mieux avec le 8 ans.

Sacha: Oui.

1:46 Le parcours

Sacha: Comment t'as-tu découvert Emacs?

Fabrice: En fait, j'ai dĂ©couvert Emacs en 95, lors de mon stage de fin d'Ă©tudes. J'ai Ă©tĂ© dans une entreprise pendant six mois et lĂ , ils utilisaient Linux. Enfin, Unix plutĂŽt, un serveur Unix. Et donc, j'ai dĂ» apprendre Ă  dĂ©velopper sous Emacs. Alors, j'ai appris les keybindings, j'avais la refcard imprimĂ©e avec un stabilo pour souligner tous les trucs que j'apprenais au fur et Ă  mesure. Ça m'a beaucoup aidĂ© d'ailleurs, d'en apprendre comme ça, C-x C-s, et puis tous les suivants. Et aprĂšs les six mois, c'Ă©tait donc en 95, c'est l'Ă©poque de la sortie de Windows 3.11, je pense. J'avais un ordinateur avec Windows 3.11. AprĂšs, j'ai repris les habitudes point and click, donc des interfaces graphiques. Jusqu'en 99, Ă  peu prĂšs 99, oĂč un de mes collĂšgues, Dominique, utilise Emacs. Et en fait, Ă  l'Ă©poque, on avait dĂ©jĂ  du versionning au boulot et c'Ă©tait PCL CVS, c'Ă©tait CVS le versionneur, donc un ancĂȘtre de Subversion et un ancĂȘtre de Git. Et il y avait un mode PCL CVS d'utiliser dans Emacs. Et quand j'ai vu ça une fois, c'est en fait un peu ça qui m'a fait sauter le pas de me dire il faut que je retourne parce que retourne regarder Emacs. Parce que c'Ă©tait beaucoup plus simple pour lui, il avait modifiĂ© ses fichiers dans Emacs, il avait son petit truc oĂč il sĂ©lectionnait les quelques fichiers qu'il voulait committer, il les sĂ©lectionnait, il faisait je ne sais plus quel key binding, et puis il mettait son message de commit, C-c C-c, et voilĂ , c'Ă©tait fait. Et donc quand j'ai vu ça, alors que moi, il fallait que je passe dans le shell, il fallait que je fasse sans doute des CVS add ou des choses comme ça, des quelques fichiers, c'Ă©tait beaucoup plus long. Beaucoup plus compliquĂ©. Donc, j'ai recommencĂ© Ă  me rĂ©intĂ©resser Ă  Emacs. J'ai utilisĂ© son .emacs et puis j'ai retirĂ© un petit peu de trucs et j'en ai rajoutĂ© Ă©normĂ©ment. Et c'est comme ça que ça a commencĂ©. Et voilĂ , c'est fantastique. Évidemment, une fois qu'on rentre dans Emacs, c’est-Ă -dire le C-s, rien que ça, la puissance du C-s, l’incrĂ©mental search, c’est dingue. Donc, c'est comme ça que j'ai commencĂ© et puis je n'ai pas pu m'arrĂȘter.

4:15 Emacs sur Windows : Cygwin et WSL

Sacha: Tu utilises Emacs sur Windows.

Fabrice: Exactement. Donc, effectivement, Ă  l'Ă©poque, j'ai fait plusieurs tentatives. J'ai utilisĂ© Cygwin, donc j'ai utilisĂ© Emacs ou Cygwin. Je vais aussi utiliser le Emacs natif. Ce qui Ă©tait compliquĂ©, parce que j'Ă©crivais quand mĂȘme aussi beaucoup de shell scripts, etc. Donc lĂ , c'Ă©tait dans mon Cygwin. Avec les Emacs natifs, il y avait les montages, le /mnt, etc. Donc c'Ă©tait surtout le Emacs Cygwin que j'utilisais. Et depuis maintenant 3-4 ans, 4-5 ans, Windows a eu la gĂ©niale idĂ©e de mettre le WSL, donc Windows Subsystem Linux, et donc dans mon Windows, j'ai un vrai Linux, encore mieux, qui est plus puissant que Cygwin encore. Et tout est prĂ©vu, tout est interconnectĂ©. Donc je peux passer, je peux ĂȘtre dans le monde Linux et voir mes fichiers qui sont sur le c: et vice versa, ce qui Ă©tait plus compliquĂ© avant. Donc voilĂ , c'est fantastique et donc j'utilise maintenant WSL. Je n'ai plus que ça et ça marche extrĂȘmement bien. Et c'est mon environnement de travail.

Prot: A-t-il des difficultés d'utiliser Emacs sur Cygwin ? Ou c'est comme WSL ?

Fabrice: C'Ă©tait un Ă©mulateur. Il y avait Ă  peu prĂšs tout ce que je voulais quand mĂȘme. Mais il n'y avait pas tous les outils. Peut-ĂȘtre des outils style... Non, et encore, je dirais des bĂȘtises. Top, je pensais Ă  top, etc. Mais je pense que non, ça, c'Ă©tait aussi implĂ©mentĂ©. Mais bon, il y avait un certain souci. Il y avait un certain nombre de commandes implĂ©mentĂ©es. Ici, c'est un vrai Linux. Et alors avec sudo apt install, tandis que sous Cygwin, il fallait installer des packages sĂ©parĂ©ment. Donc on a une petite interface, on sĂ©lectionne les packages. Ici, je recopie ce que je peux trouver sur le web. Si je veux installer R, j'utilise le langage R, sudo apt install R et des choses comme ça. Donc c'est beaucoup plus facile. C'est vraiment typiquement tout ce que les gens font qui n'ont que Linux. C'est exactement les mĂȘmes commandes. Je trouve ça beaucoup mieux, c'est beaucoup plus intĂ©grĂ©.

Sacha: Je pense que c'est aussi plus vite qu'utiliser Emacs sur Windows directement parce que Magit, par exemple, Magit est trop lent, je pense, si tu utilises Magit sur Windows directement.

Fabrice: Ça c'est un truc, c'Ă©tait dĂ©jĂ  pareil avant avec Cygwin aussi. Au dĂ©but, j'avais installĂ© mon WSL Linux, donc il est montĂ©, et j'avais mis Emacs, je pense... Attends, comment ça allait ? Non, je mettais mes repos Ă  l'extĂ©rieur, dans le C:. Et en fait, lĂ , il y a quand mĂȘme un passage entre les deux mondes qui est extrĂȘmement lent. Rien que pour lancer Emacs, mon Emacs se lance en une Ă  deux secondes. LĂ , dans ce cas-lĂ , ça se lançait en une ou deux minutes. Donc, il y a une diffĂ©rence Ă©norme. Donc, en fait, il faut vraiment tout mettre, vivre uniquement dans le monde WSL, dans le monde Linux. Donc, mes repos sont dans Linux. Mon Emacs, il est dans mon Linux. Mais en fait, les fenĂȘtres sont partagĂ©es. C'est ça aussi qui est bien. Je peux avoir une fenĂȘtre, ma fenĂȘtre Emacs, elle est Ă  cĂŽtĂ© d'une fenĂȘtre Outlook, par exemple. Et les presse-papiers, etc. sont complĂštement interconnectĂ©s aussi. Donc, c'est vraiment comme si c'Ă©tait une application Windows. Sauf que rĂ©ellement, elle est dans le sous-systĂšme Linux. Mais il faut vraiment mettre tout dans le sous-systĂšme Linux pour que les performances soient potables. Sinon, il y a quand mĂȘme des lenteurs pour les fichiers qui sont lus d'un domaine Ă  l'autre, d'un espace Ă  l'autre. Les shared files, quoi. Tout ce qui passe par le point de montage est quand mĂȘme beaucoup plus long.

8:26 Les automatisations

Sacha: Maintenant, tu as un environnement plus pratique pour tes automatisations. Parle-moi de tes automatisations préférées pour les tùches répétitives.

Fabrice: Volontiers. En fait, j'ai préparé un fichier Org, évidemment, pour préparer cet entretien. Et donc, vous voyez mon écran ou je dois partager ? Oui, vous le voyez, c'est ça ? Toujours ?

Prot: Oui, oui, oui, oui, je peux voir ton écran.

Fabrice: Donc, voilĂ . VoilĂ , ici, j'ai mon Emacs en grand. Et vous voyez dans le titre ici ? Le titre, je le... Oui, toutes les 20 secondes, il y a un petit truc comme ça. Toutes les 20 minutes, il faut poser les yeux pendant 20 secondes. Toutes les 20 minutes, j'ai un programme qui m'interrompt pendant 20 secondes. Ça va encore arriver deux fois tout Ă  l'heure. Et donc ici, dans le titre, vous voyez GNU Linux Emacs. Donc, on voit vraiment que c'est l'Emacs du GNU Linux. Et avec ici, j'ai la date dans laquelle il avait Ă©tĂ© compilĂ©. Et puis j'ai le PID aussi. Parfois, dans le temps, j'avais plusieurs Emacs, donc j'ai le PID qui est aussi indiquĂ©. Comme ça, quand je devais faire un kill, ça arrivait parfois de devoir faire des kills, je savais au moins lequel il fallait que je kill, parce que j'avais l'information directement dans le titre. Donc ici, j'ai une petite prĂ©sentation Org. Avec un agenda. On a parlĂ© de mon parcours, de comment j'ai fait la connaissance d'Emacs. Tu posais des questions sur diffĂ©rents repositories que j'ai rendus publics sur YouTube. Il y a le fameux thĂšme de couleur Leuven. Leuven, pour information, c'est la ville oĂč j'habite.

Prot: Une belle ville.

Fabrice: TrĂšs belle ville, absolument. Et voilĂ , j'ai un peu copiĂ© Thiel tantĂŽt, je pense, le crĂ©ateur de Beamer, qui avait donnĂ© des noms pour ses thĂšmes, Madrid, etc., Hanover, lĂ  oĂč il Ă©tait passĂ© faire des sĂ©minaires. Donc c'est comme ça que j'ai pris le vƓu au dĂ©but. D'ailleurs, ici, vous voyez ce thĂšme Leuven Team qui est appliquĂ© avec des titres plus gros pour les sections de premier niveau et puis des couleurs un peu diffĂ©rentes pour les to-do keywords, pour les titres, pour les sections, pour les tags, etc. Il y a des morceaux qui sont dans Leuven theme, il y a des morceaux qui sont dans ma configuration Emacs. Le team de couleurs s'appelle Leuven theme et la configuration Emacs. Pour l'instant, le repository sur GitHub s'appelle Emacs Leuven. J'ai mis ici un lien. D'ailleurs, pour information, cette note que je partage, c'est aussi sur GitHub. Vous pouvez trĂšs bien la chercher sur https://github.com. Et alors ici, donc, Emacs Chat Sacha Chua. Donc, vous pourrez le trouver lĂ . Donc ici, il n'y a qu'un fichier, il y a juste l'heure et demie.

Prot: Oui, bonne idée de...

12:15 Emacs Boost

Prot: Et c'est quoi Emacs Boost ?

Fabrice: Donc en fait Emacs Boost, je fais des formations Ă  Emacs depuis 2024 et j'ai appelĂ© ça Emacs Boost, l'idĂ©e Ă©tant de booster l'utilisation d'Emacs, d'ĂȘtre plus efficace, d'ĂȘtre plus rapide, d'avoir des automatisations qui soient incluses dedans. Mon projet s'appelle Emacs Leuven depuis longtemps, mais pour ĂȘtre cohĂ©rent entre la formation que j'ai appelĂ©e Emacs Boost et mes configurations qui s'appellent pour l'instant Emacs Leuven, je suis en train de renommer tout doucement des fonctions, des variables, etc. vers Emacs Boost. L'idĂ©e, ce sera que tout mon fichier de configuration, que je peux vous montrer, Emacs Leuven, Je fais du literate programming. Donc ça c'est mon fichier de configuration d'Emacs. C'est le fichier Ă  partir duquel est anglĂ© ma configuration Emacs. Donc ici si je vais montrer de l'autre cĂŽtĂ© le fichier liste. Donc, ça, c'est mon fichier de configuration avec toutes mes configs Ă  moi. Il fait, je pense, 7500 lignes. Je pensais qu'on Ă©tait Ă  10 000 dĂ©jĂ . C'est un petit peu de nettoyage. Bon, alors Ă©videmment, c'est facile parce que j'ai quasiment toujours, devant cette queue, j'ai toujours un commentaire. Donc, si on regarde ici, si je remonte un petit peu, voilĂ , tous mes sets de pubs. Je vais agrandir un peu. J'ai systĂ©matiquement une ligne de commentaire au-dessus. VoilĂ , define. Donc, j'ai une ligne blanche, une ligne de commentaire et puis une ligne de commande. Donc, en fait, si on retirait tous les blancs ou tous les commentaires, je serais Ă  2500 lignes. C'est dĂ©jĂ  pas mal. VoilĂ , mais donc ça, c'est le fichier que j'ai commencĂ© en 99. Et donc qui est aussi public avec toutes les configurations que j'ai et tous les packages que j'utilise. J'utilise un certain nombre de packages. Donc si je regarde, par exemple, un dont je vais vous parler tout Ă  l'heure, je vais retourner au dĂ©but du fichier. Je vais retomber sur ma liste, voilĂ . Donc ça c'est les packages que je charge ou en tout cas que je customise. Donc voilĂ , ça c'est toute la liste. Je crois qu'il y en a Ă  peu prĂšs 70. Oui, un petit peu moins peut-ĂȘtre. Deux packages que j'utilise. Alors certains, je les ai commentĂ©s parce que je n'utilise plus tellement. Et sinon, ça c'est les packages que j'utilise couramment et pour lesquels il y a des configurations. Et donc d'ailleurs, le but d'Emacs Leven, c'Ă©tait de dire c'est un fichier de configuration qui est pour moi, il y a mes configurations, la façon dont je veux travailler, mes automatisations, mes settings par dĂ©faut, ou des fonctions supplĂ©mentaires, des commandes supplĂ©mentaires. Mais l'idĂ©e, c'est que n'importe qui pourrait faire require Emacs Leven, donc Ă©videmment cloner le repo, faire require de ce fichier-lĂ , et ça ne devrait pas perturber son systĂšme. Ça devrait rajouter toutes les configs que j'ai faites, mais sans perturber, sans imposer, par exemple, je ne sais pas, fancy narrow. Donc, en fait, au dĂ©marrage, ça regarde, est-ce que ça va demander, ça va regarder les packages qui sont installĂ©s dans, si je prends l'exemple de Sacha, si Sacha faisait ça, ça regarderait les packages qu'elle a installĂ©s, qui sont appelables, qui sont loadables, qu'elle a installĂ©s dans son systĂšme. Et ça dirait, tiens, voilĂ , il manque tel et tel package, voulez-vous les installer ? Donc, ça va proposer d'installer tous ces packages-lĂ . Mais on peut dire non. Et dans tous les cas, toutes mes configurations, je vĂ©rifie chaque fois si je modifie web-mode. Par exemple, je vĂ©rifie, est-ce que web-mode est installĂ© ? Si oui, alors voilĂ  les configs. S'il n'est pas installĂ©, il n'y a aucune config qui se passe. Donc, j'ai toujours un... Si je vais regarder web-mode, par exemple, pour cet exemple-ci. with-eval-after-load, voilĂ . Donc ici j'ai toujours with-eval-after-load de web-mode. Et donc ma configuration de web-mode ne sera active que si web-mode a Ă©tĂ© trouvĂ© et est utilisĂ©. Donc je ne vais pas, en thĂ©orie, je ne vais pas rajouter des raccourcis clavier, etc. pour des modes que vous n'auriez pas. Et en thĂ©orie, le fichier, il n'y a pas de truc qui soit vraiment privĂ©. Donc il n'y a pas mon nom, mon prĂ©nom, mon username, par exemple, il n'est pas dans ce fichier lĂ . Mon adresse email n'est pas dans ce fichier-lĂ . Donc j'ai un petit fichier init-local.el qui est vraiment spĂ©cifique Ă  moi. Tout ce qui est lĂ , en thĂ©orie, c'est relativement gĂ©nĂ©rique et universel. TrĂšs bien. Donc maintenant, si je repasse sur la... C'est ce que je considĂšre ĂȘtre les meilleurs packages, ceux que j'ai testĂ©s. J'ai lu des centaines, si pas des milliers, sur une vingtaine d'annĂ©es, si pas des milliers de fichiers de config. J'ai vu beaucoup de choses chez plein de gens et c'est comme ça que j'ai trouvĂ© beaucoup de packages au fur et Ă  mesure. Et quand c'Ă©tait des choses qui me plaisaient, j'ai rajoutĂ© des configurations de ces packages. C'est pour ça que c'est aussi gros, mais ça fait beaucoup de choses. Et malgrĂ© tout, ça se charge quasiment instantanĂ©ment. Donc aussi, les packages un peu plus longs, je fais des idle require. Donc j'attends qu'il y ait 5 secondes d'inactivitĂ© dans la session Emacs pour aller charger certains packages. Mon adresse email n'est pas dans ce fichier-lĂ . Donc j'ai un petit fichier init local.el qui est vraiment spĂ©cifique Ă  moi. Tout ce qui est lĂ , en thĂ©orie, c'est relativement gĂ©nĂ©rique et universel.

Prot: TrĂšs bien.

Fabrice: Donc maintenant, si je repasse sur...

Sacha: MĂȘme si ta configuration inclut beaucoup de package, parce que tu dĂ©lais le dĂ©marrage du package, c'est vite, c'est rapide.

Fabrice: Exactement. Je dis que c'est une Ă  deux secondes maximum. Et en fait, l'idĂ©e, et on va en parler encore tout Ă  l'heure, on verra, j'ai beaucoup de choses que j'aimerais bien dire, on va voir le temps qu'on a. Mais l'idĂ©e, c'est qu'en plus, une fois qu'il est dĂ©marrĂ©, il passe en mode serveur. Et donc, je peux lancer, ouvrir un fichier directement dans Emacs sans lancer une nouvelle instance d'Emacs. Donc je n'ai qu'une seule instance d'Emacs et c'est celle-lĂ  qui est utilisĂ©e tout le temps. Donc aprĂšs, chaque fois que j'appelle Emacs pour Ă©crire un message de commit ou des choses comme ça, c'est instantanĂ©. Il n'y a vraiment mĂȘme plus de temps d'attente du tout. Il n'y a mĂȘme pas les une Ă  deux secondes de dĂ©marrage. Et par exemple, un petit truc que je voulais montrer Ă©ventuellement, deux petites automatisations que je trouve extrĂȘmement utiles, qui font le pont. En fait, j'ai trois applications que j'utilise tout le temps chez Emacs. J'ai le Shell, ici, le terminal. Donc j'utilise pas, j'ai pas l'habitude, et ça c'est plutĂŽt d'ailleurs Ă  cause, entre guillemets, Ă  cause de l'Ă©poque Cygwin, oĂč le shell dans Cygwin, un shell dans Cygwin, dans l'Emacs Cygwin, ça marchait pas bien, il y avait des problĂšmes de C-m qui apparaissaient, etc. Donc j'ai pas pris l'habitude d'utiliser le shell dans Emacs. Donc j'ai toujours, voilĂ , mon petit shell sur le cĂŽtĂ©, j'ai Emacs et j'ai le browser. En gros c'est mes trois, et puis alors... Pour le boulot, Ă©videmment, Outlook. Mais sinon, c'est les trois applications que j'utilise vraiment le plus. C'est Emacs, le Shell et le Browser. Et j'ai envie d'avoir des ponts entre ces deux mondes. Donc ici, mon Shell, mon terminal et Emacs. Du style, je veux donc voir si je vais ouvrir un fichier.

21:15 Emacsclient

Fabrice: Par exemple, je vais ouvrir le fichier Emacs... Leuven, tout doux. Donc ici, j’ai un petit alias e qui en fait va faire emacsclient. Quand je fais ça, si tout se passe bien, voilĂ . Donc ici, il m'a ouvert ce fichier tout doux dans Emacs. Donc ça, c'est pour ouvrir un fichier. Je peux aussi ouvrir Le rĂ©pertoire dans lequel je suis, ça ouvre le rĂ©pertoire et je passe en direct. Par exemple, si j'Ă©tais dans ce repository Emacs Leuven, imaginons que je veux faire un guide status. J'ai aussi des alias Ă©videmment pour... Si je veux faire un Git status, je vois qu'il y a ces fichiers-lĂ . Je pourrais Ă©ventuellement vouloir garder les modifications. Je vais les faire avec Emacs. Je pourrais faire simplement up point pour me retrouver directement ici, dans le bon rĂ©pertoire. Et comme ça, lĂ , je vais faire, chez moi, je vais faire C-<f9>, qui va me lancer vc-dir sans me poser la question de savoir oĂč je veux lancer vc-dir. Donc, mon C-<f9> ne prompte pas, il lance vc-dir sur le rĂ©pertoire ou le fichier dans lequel je suis. Et donc, c'est avec ça que je commencerai. Ici, je regarderai les diffĂ©rences avec un Ă©gal. Je vais voir si c'est bon ou pas, puis je vais committer. Donc ça, c'est pour passer du shell vers Emacs. J’ai le petit e. Beaucoup de gens connaissent emacsclient, donc ce n'est pas trĂšs nouveau. J'ai juste abrĂ©viĂ© en e. Deux choses qui sont plus marrantes ou plus utiles. Il y en a une qui est marrante et une qui est utile. Celle qui est marrante, c'est cate, qui est une petite fonction dans le terminal, un petit shell script, et qui fait un cate.

Sacha: Cat plus Emacs.

Fabrice: cat de ce qu'il y a dans Emacs. Donc, si je fais cate, il va en fait m'afficher le contenu du buffer working-dir. C'est gĂ©nial. Si j'ai ce todo-lĂ , par exemple, je peux faire ici si je fais cate, ou si j'en avais plusieurs, on peut imaginer que j'ai plusieurs fenĂȘtres. Donc, si je vais ici, voilĂ . Pour l'instant, la fenĂȘtre active, c'est celle-lĂ . Donc, si je fais Cat, Cat, Ça va me remontrer ça. Si je mets mon curseur lĂ  et que je refais cate, ça va m'afficher l'autre fichier. Alors ça c'est plus... Et alors c'est emacsclient aussi. Alors ça c'est plus marrant, entre guillemets, parce que ça n'a pas beaucoup d'intĂ©rĂȘt, sauf Ă©ventuellement, parfois. Imaginons que je ne sache pas faire un grep. Il y a des opĂ©rations que je connaĂźtrais mieux dans le terminal. Par exemple, compter le nombre de lignes. J'ai un petit... Je suis sous et j’ai un global w qui va me faire le compte. Donc ici, je vais savoir directement, voilĂ , j'ai 1397 lignes dans ce fichier-lĂ . Ce qui revient Ă  faire, juste pour expliquer, ça revient Ă  faire pipe wc -l. Donc voilĂ , je pourrais faire ici aussi un grep, Ă©ventuellement, grep, je ne sais pas, test, je ne sais pas si j'ai... VoilĂ . Donc il y a toutes les lignes qui sont dans ce buffer lĂ  avec le mot test. Donc ça c'est plus marrant entre guillemets, c'est pas tout le temps utile. Par contre un qui est extrĂȘmement utile, c'est imaginons que je sois, je vais ici me redĂ©placer dans mon route, dans mon home directory. Je suis dans le home directory et en fait ici dans Emacs, j'ai ouvert ce fichier lĂ . Et j'aimerais bien faire le status, par exemple, le guide status, dans ce repo-lĂ . Mais donc, il faut que j'aille dans le repo. Donc ici, si je fais C-x C-k, avec direct plus, je sais passer Ă  la vue directe et je vois que le chemin d'accĂšs, donc le chemin, c'est ~/.dotfiles/emacs-leuven. Donc, je pourrais faire ici cd slash... En fait, ça, ce qui est juste au-dessus. Mais si je veux l'automatiser, en fait, je peux faire cde. Donc cde, comme cate, c’était cat de ce qu’il y a dans Emacs, cde, c’est cd de ce qu’il y a dans Emacs. Donc cde va me conduire lĂ  oĂč je suis dans Emacs. Donc dans le mĂȘme rĂ©pertoire, voilĂ .

Sacha: Je vais voler toutes les idées.

Fabrice: C'est le but, parce que j'ai trouvĂ© quelque part cette idĂ©e, et je l'ai peut-ĂȘtre un peu modifiĂ©e, mais c'est gĂ©nial. Donc ici, maintenant, si je vais sur n'importe quel fichier, je ne sais pas si je prends de nouveau notre exemple ici, Readme. Est-ce que vous voyez assez grand ? Est-ce que je peux augmenter la taille aussi ? De la fonte. Donc ici, je suis dans le fichier que j'ai prĂ©parĂ© pour cette prĂ©sentation. C'est un autre repository. Imaginons que dans mon shell, je veuille retourner dans ce repository, cde. Et je suis dans le repository Emacs, Sacha Chua. Je peux faire mon guide status. Je suis directement bien placĂ©. Je n'ai pas besoin de devoir taper des chemins d'accĂšs.

Sacha: Tu as aussi un script pour récupérer ou retrouver le nombre de fichiers qui est courant en Emacs dans la command line?

Fabrice: Je ne l'ai pas, mais ce serait facile Ă  faire puisqu'en fait, il y a ici ce que je... Imaginons que je veuille le faire. Je vais prendre quelques touches en plus. Je vais faire C-x C-j. Et puis... Je ne sais pas si vous savez, w, le petit w, ça me copie. Donc, le contrĂŽler, il me place dans direct sur le fichier en question. Et w, dans le presse-papier, le nom du fichier. Je pourrais faire cat. C'est facile d'implementer. Ce serait facile, parce qu'ici, je l'ai rĂ©cupĂ©rĂ©. cat, ceci. Donc j'ai directement le fichier comme ça. Donc ce serait extrĂȘmement facile. Plus dur, ce sera de lui trouver un nom. À cette commande.

Sacha: Génial, génial.

28:49 org-html-themes

Fabrice: Non, vas-y, j'allais éventuellement, maintenant on était dans, j'allais éventuellement parler d'export HTML, etc.

Sacha: Oui, oui, oui.

Fabrice: Donc vous voyez ici, on est dans le buffer Emacs, alors c'est dĂ©jĂ  agrĂ©able Ă  lire parce qu'il y a un certain nombre de couleurs, etc. J'aimerais bien d'ailleurs ici que les notes soient colorisĂ©es avec une certaine couleur, mais bon, ce sera pour une prochaine fois. Mais il y a Ă©videmment un moyen de lire qui est quand mĂȘme beaucoup plus agrĂ©able, c'est de lire ce mĂȘme document. qui est assez long, ce serait de le lire en HTML ou en PDF. Et donc, en rajoutant un setup file, donc ici simplement une ligne comme ça. Donc, il faut avoir clonĂ© le repository Ă  Org-html-themes. Et alors, aprĂšs, il faut taper le chemin d'accĂšs vers le HTML theme readtheorg.setup. readtheorg est un des deux thĂšmes HTML que j'ai Ă©crit. Et donc, simplement en mettant une ligne comme ça, quand on va faire C-c C-e h h, ça va gĂ©nĂ©rer. VoilĂ , c'est dĂ©jĂ  fait. On voit ici dans l'Ă©cho area, ça va gĂ©nĂ©rer la version HTML. Et donc, oui, pour aller l'ouvrir, il y aurait moyen d'aller encore plus vite, etc. Ce que je fais encore toujours pour l'instant, je fais C-x C-j, je passe dans Dired. Et dans Dired, j'ai un petit raccourci qui est extrĂȘmement pratique, que j'ai nommĂ© pour l’instant o pour Open. Et en fait, ça ouvre le fichier sur lequel je suis en utilisant l'application standard Windows. Donc, c'est ça aussi l'intĂ©rĂȘt ici. Donc, ça montre bien qu'avec WSL, je suis intĂ©grĂ© avec mon Windows. Donc, en faisant O sur ce fichier-lĂ , Ça va m'ouvrir Edge. Si je fais O sur le fichier PDF, ça va m'ouvrir sous Matra PDF. Parce que j'ai configurĂ© dans Windows que mon lecteur, c'est sous Sumatra PDF. Et donc ici, je vais faire O. Et ça doit m'ouvrir ici. Alors voilĂ , ça m'ouvre un fichier. Vous voyez ? Et donc ça m'ouvre le fichier avec... Le fichier Org, mais avec une prĂ©sentation beaucoup plus sympathique, beaucoup plus jolie, beaucoup plus agrĂ©able Ă  lire.

Sacha: Je l'adore.

Fabrice: Elle est gĂ©niale, elle est magnifique. Et en fait, il y en a une deuxiĂšme, et je vais vous montrer des petits trucs de la deuxiĂšme, parce que je n'ai pas encore tout mis dans celle-ci. J'aurais bien portĂ© des choses que j'avais créées dans l'autre, mais que je n'ai pas encore portĂ©es, donc j'aurais bien les partager dans tous les thĂšmes. Si je retourne ici dans mon fichier Org et que je mets Big Blow Ă  la place, c'est le nom de l'autre thĂšme. Je vais refaire un export. Cette fois-ci, je n'ai plus qu'Ă  faire F5 ici pour faire un refresh. On a une autre vue oĂč lĂ , chaque section devient un tab. On a tous des tabs. Donc ça peut ĂȘtre aussi intĂ©ressant en fonction de la taille du fichier. Ça peut ĂȘtre aussi intĂ©ressant de voir une vue plus monolithique oĂč on a tout en une seule page ou une vue avec des tables ici oĂč on voit section par section ou chapitre par chapitre. Mais alors cette vue-ci, elle a des trucs un peu spĂ©ciaux. Donc j'ai notamment la possibilitĂ© de faire un collapse. On va aller Ă  un endroit oĂč j'ai ici... Quelques astuces, voilĂ . Donc j'ai collapse all ou extend all. Donc je peux collapser toutes mes sections. En fait, j'ai voulu faire comme dans Org. Et j'ai mes petites flĂšches ici. Donc je peux, en cliquant sur n'importe quel item, je peux l'expander ou le collapser. Donc si j'expand ou je collapse.

Sacha: Pardon, je vais apporter des tissus Ă  ma fille.

Prot: C'est effectif comme ça, oui. Et tu as d'autres thÚmes aussi ?

Fabrice: Non, pas encore publics. J'en ai en deux, mais ils ne sont pas encore publics. Et donc voilĂ , ça peut ĂȘtre intĂ©ressant quand on a beaucoup de tĂąches, etc., pour pouvoir de nouveau, un peu comme dans le fichier Org, de collapser tout sauf un certain truc. Et alors, j'avais mis exprĂšs ici, donc lĂ  j'ai deux tĂąches, j'ai fait deux tĂąches, en todo et en startit, avec des petites tags. Et en fait, j'ai mĂȘme... Ici, un petit dashboard sur le cĂŽtĂ©. Il y a un petit truc dashboard qui s'est mis quand on l'ouvre. On voit le nombre de tĂąches en todo, le nombre de tĂąches en started. Donc, dynamiquement, ça va questionner, ça va afficher tous les statuts qui existent. Si j'en ai que deux dans tout mon fichier, c'Ă©tait pour un petit exemple. LĂ , pareil, j'ai tous les tags et on peut mĂȘme highlighter carrĂ©ment tous les trucs qui sont en todo. C'est des flags, en fait. On peut les highlighter. Je peux highlighter et ça prend la couleur du todo. Comme ça, si je veux scanner tous les trucs qui seraient en todo, je peux les mettre en todo et je peux scanner, quand j'ai un long fichier, je peux scanner tout ce qu'il y a dedans. Et ça marche aussi, si je me souviens bien, avec les petits tags. Je peux highlighter toutes les tĂąches qui ont le tag personnel ou toutes les tĂąches qui ont le tag work d'un coup. Ça me permet de scanner, de regarder ce qui est important. C'est un peu un fonctionnement Ă  la Org, mais dans le browser.

35:02 Review

Prot: Qu’est-ce que ça veut dire r ? r, or click here to review. Exactement.

Fabrice: C'est ce que je voulais te montrer. J'ai un petit truc en plus pour faire un vrai review. Si je clique sur r, ça va faire comme un narrowing. Tout le reste de l'Ă©cran va devenir foncer. Sauf la tĂąche, une tĂąche Ă  la fois. Et donc ça va aller chaque fois sur la next tĂąche. Donc ici, quand je vais cliquer sur R, il va passer Ă  la tĂąche suivante, qui est active, c'est-Ă -dire ici la tĂąche qui sera en start-it. Et donc ça collapse tout le reste. Et si je refais un r, ici c’est bloquĂ©, donc je peux faire q pour quitter. Donc r, il va Ă  la premiĂšre tĂąche, et donc je vois cette premiĂšre tĂąche ouverte, et puis il va Ă  la deuxiĂšme. Donc on pourrait passer, scanner une par une toutes les tĂąches. Et ça va chaque fois mettre en Ă©vidence uniquement cette tĂąche-lĂ . Et donc, je peux faire grand R, donc c’est pour faire le reverse, donc aller en arriĂšre. Donc r, ça va vers le suivant, la tĂąche suivante. Si j'en ai que deux, on pourrait imaginer que j'en ai 100 dans un fichier. Et donc, je peux faire mon review comme ça et relire le truc et puis Ă©ventuellement changer. Ce qui serait gĂ©nial, c'est de pouvoir changer le statut ici, etc. aussi. Et que ce soit rĂ©percutĂ© vers le fichier Org, mais ce n'est pas le cas. C'est un petit ensemble de Org ici. J'ai aussi lĂ  un petit mini-talk, comme la mini-talk dans les chapitres LaTeX. Et donc vous voyez que simplement en mettant une ligne ici, BigBlow ou ReadTheDocs, On a accĂšs Ă  l'une ou l'autre. Je gĂ©nĂšre l'autre version. F5, voilĂ . Ici, il y a un petit truc de recherche en plus que je n'ai pas dans l'autre. J'ai des petites diffĂ©rences dans les deux thĂšmes. Et donc, ça, c'est l'export vers HTML. L'idĂ©e, c'est d'avoir... J'ai mis une rĂ©fĂ©rence ici, vers le repo. Et l'idĂ©e, c'est d'avoir 0 CSS Ă  Ă©crire. Une navigation confortable, une lisibilitĂ© plus grande, un rendu professionnel.

37:25 PDF

Fabrice: On peut carrĂ©ment imprimer ça. VoilĂ , une personnalisation qui est assez simple. J'ai fait aussi un petit repository pour l'export vers la tech. Donc ici, si j'exporte, je l'ai dĂ©jĂ  fait, mais je peux directement l'ouvrir. Oh, donc je vais faire de nouveau... Oh, et ça va ouvrir l'application dans Windows qui est liĂ©e pour les PDF. Chez moi, c'est sous Sumatra PDF. VoilĂ . Et donc, ça m'ouvre ici mon fichier. Cette fois-ci, comme un PDF, avec une table des contenus, une table des matiĂšres. Et voilĂ , j'ai essayĂ© de nouveau de faire les notes, les types, etc. Donc, de les faire un rendu qui soit assez joli. Tout Ă  l'heure, on Ă©tait ici dans Emacs Leuven Boost. Et donc ça, c'est aussi public. C'est une classe qui s'appelle mcreport. Je l'ai appelĂ© mcreport pour l'instant. Donc, il faut juste charger la premiĂšre fois. Il faut charger, donc la premiĂšre fois que je lance Emacs, je devrais le faire automatiquement, mais pour l'instant je ne l'ai pas encore fait. Je dois le faire une fois Ă  chaque session. Je vais Ă©valuer ce buffer-ci dans lequel j'ai les dĂ©finitions de mes diffĂ©rents... de mcarticles, de mcreports, de mcbooks, etc. Donc je dois juste Ă©valuer une fois C'est un package. C'est des accords sur une guitare oĂč on peut gratter plusieurs cordes sur une guitare. Ici, l'idĂ©e, c'est qu'on peut appeler une commande avec deux touches simultanĂ©es. Donc, par exemple, eval-buffer. Donc ici, quand je dois Ă©valuer ceci, je ferais, si je faisais comme avant, je ferais M-x, eval-buffer, Enter.

40:03 Key-chord

Fabrice: Mais en fait, avec key-chord, je peux simplement faire vb en mĂȘme temps. Donc, si je fais vb, il y a genre 100 ou 200 millisecondes. Donc ça doit ĂȘtre fait quasiment simultanĂ©ment. Et le b peut ĂȘtre avant le v ou le v avant le b. Et donc quand je fais les deux en mĂȘme temps, vb, ça fait eval-buffer. Si vous voulez, alors ici on voit rien, c'est pas trĂšs visuel. Si vous voulez voir un truc, hh par exemple, quand je tape hh rapidement, ça fait la sĂ©lection d'abord du mot. Si je retape rapidement, ça grandit chaque fois la rĂ©gion. Donc ça fait un expand region. Et grand H, ça fait l’inverse, je retourne vers du plus petit au plus petit. xk par exemple, si je tape xk, ça va faire kill-buffer. Donc c'est chaque fois juste, si vous voulez voir dans ma configuration, oĂč ça se trouve, Emacs Levenel, XK par exemple, voilĂ . Donc c’est lĂ  que j’ai mis other window, ww, xj, ça fait le C-x C-k, donc le direct jump. Et le eval-buffer dont j’ai parlĂ©, oĂč est-ce qu'il est ? On va mettre un peu
 Donc eval-buffer, voilĂ , vb, ça fait eval-buffer. Donc pratique ça pour Ă©crire en français. Quand j'Ă©cris plus petit, plus petit, deux fois rapidement, donc il faut que ce soit chaque fois rapidement, ça va faire un insert de caractĂšres guillemets français. Donc ici, je vais faire si je le fais lentement, il ne se passe rien. Si je le fais vite, il insĂšre les guillemets. D'accord. Tant que j'y suis, vous avez vu aussi, si je fais plus petit, plus petit ici, et puis je fais un save, vous voyez que j'ai Ă  ce moment-lĂ  ici une ligne bleue dans le gutter, dans le fringe. Donc j'utilise git-gutter, si je me souviens bien, de Dmitry, j'ai oubliĂ© son nom de famille. C'est diff-hl, de Dmitry Gutov.

Sacha: Moi aussi.

Fabrice: Ouais, ça doit ĂȘtre ça. Et donc ça me met en fonction, si j'efface ici des lignes, ça va mettre du rouge. Et si je fais une insertion, et si je fais des insertions, ça va mettre du vert. Donc je vois directement dans mon buffer, systĂ©matiquement, oĂč est-ce que j'ai des choses qui ne sont pas encore commitĂ©es. Et alors pour, ça c'est la premiĂšre customisation que j'ai indiquĂ©e, si je retourne dans mon... Je peux en mĂȘme temps parler de F5 et F6. J'ai quelques trucs assez sympathiques. F5, ça va me faire... Si j'ai un seul window, quand je fais F5, ça me crĂ©e un deuxiĂšme window. Ça fait l’équivalent de C-x 2 ou de C-x 3. En fonction de la place que j'ai. Donc si j'ai assez de place pour avoir 80 caractĂšres prĂ©sentĂ©s, il va passer Ă  un mode vertical, cĂŽte Ă  cĂŽte. Sinon, si j'ai moins d'espace, il va passer sur un mode dessus-dessous. Et si je suis Ă  l'inverse, dans une situation avec plusieurs buffers, avec plusieurs windows, donc ici j'en avais encore une troisiĂšme, quand je fais F5, en fait, c'est l'Ă©quivalent de faire C-x 1, donc ça va faire Ça va garder uniquement la fenĂȘtre qui Ă©tait active. Et donc souvent, quand je dois passer d'un buffer Ă  l'autre, quand je veux ouvrir autre chose, je vais faire F5, ça me crĂ©e un deuxiĂšme buffer. Et puis je vais mettre le contenu ici d'autres choses. Je vais retourner sur ma prĂ©sentation. Et je voulais parler, par exemple, du C-w et du M-w sans sĂ©lectionner de rĂ©gion. Ça, pour moi, c'est un des trucs les plus... Les plus importants, que j'utilise tout le temps, tout le temps, tout le temps. Donc, imaginons que je veuille... Si je veux copier cette rĂ©gion-lĂ , je dois commencer Ă  sĂ©lectionner une rĂ©gion, et puis je vais pouvoir faire un copie. Si je veux, en fait, si je me rends compte... Imaginons que je veuille faire une ligne qui ressemble Ă  celle-lĂ , celle-ci, avec le kk. Imaginons que je veuille aussi faire qq, que qq ait la mĂȘme... Appel la mĂȘme commande. Donc je pourrais dupliquer la ligne. J'ai aussi une petite commande pour dupliquer les lignes. Et sinon, en fait, il faut que je copie cette ligne-lĂ . Dans un Emacs standard, pour copier la ligne, je dois aller au dĂ©but de la ligne, faire la sĂ©lection, aller Ă  la fin de la ligne et puis faire M-w. Et Ă  ce moment-lĂ , je peux la copier. En fait, c'est trop long pour moi. Donc j'Ă©tais lĂ  au milieu et donc je veux copier la ligne. Simplement, je vais prendre un autre exemple, je vais prendre celle-lĂ . Je fais M-w. Et M-w, donc j’ai un advice au-dessus de M-w. M-w, s’il n’y a pas de rĂ©gion, il considĂšre que la rĂ©gion, c'est la ligne courante. Donc ici, si j’insĂšre, je fais C-y, voilĂ . J'ai la ligne que j'avais mise dans le presse-papier.

45:41 Copier sans sélectionner

Fabrice: Et ça, ça sauve en temps fou de pouvoir... C'est quand je veux copier une ligne ou Ă  l'inverse couper une ligne parfois. C'est le mĂȘme principe. Donc le C-w, donc le cut, si on parle en Windows. Donc si je veux faire un cut de cette ligne-lĂ , de nouveau, si je n'ai pas cette customisation-lĂ , je vais devoir, au dĂ©but de la ligne, sĂ©lectionner la rĂ©gion et puis je peux faire C-w. Mais avec la petite customisation, avec l'advice que j'ai, sur n'importe quelle ligne, je suis au milieu, C-w, ça fait le cut. Et donc ça m'arrive trĂšs souvent, si je veux supprimer, par exemple, ces trois lignes-lĂ , alors je pourrais me remettre au dĂ©but, puis sĂ©lectionner ma rĂ©gion, faire C-w. Ça ne me dĂ©range pas que ça aille dans le presse-papier. Ou encore plus rapidement, je suis lĂ -dessus et ces trois lignes qui ne m'intĂ©ressent plus, je fais C-w C-w C-w. Et les trois lignes ont disparu. C'est plus facile. C'est beaucoup plus rapide, c'est beaucoup plus facile. Le fait de pouvoir faire un copier ou un couper sans sĂ©lection. De nouveau, je reviens ici, je fais un M-w, et puis je vais lĂ , C-y. Heureusement que j'ai Git, parce que lĂ , je suis en train de casser mon fichier. Ce n'est pas grave parce que je vais faire un revert aprĂšs. Mais bon, voilĂ , ça, c'est un truc extrĂȘmement utile pour moi, ce C-w, M-w. Donc, j’ai mis un lien. Ceux qui veulent aller chercher les notes de cette prĂ©sentation, j'ai mis un lien directement vers L'endroit, ça se trouve dans mon fichier de config Emacs qui est sur GitHub. Ça va ouvrir directement la section deletion and killing. Vous pourrez avoir le code. Ici, voilĂ  le code qu'il faut copier si vous le voulez. Ça, c'est pour le cut. C'est un slick cut, ce que ça s'appelle. Et puis ici, pareil pour le copier. Donc le M-w, il faut copier ça. Et donc ça regarde, en fait, est-ce qu'il y a une rĂ©gion ou pas. Et s'il n'y a pas de rĂ©gion active, ça sĂ©lectionne la ligne courante.

Sacha: J'adore ce genre de fonction, do what I mean.

Fabrice: Oui, j'en ai plusieurs autres, mais exactement.

48:29 fill-paragraph

Fabrice: Par exemple, un autre do what I mean, je l'ai pour le M-q. Imaginons ici que je vais rajouter... Tiens, j'ai des trucs dans le presse-papiers, je peux les mettre lĂ . J'avais upcase, la region. Donc maintenant, si je veux remettre en forme le paragraphe, je vais faire metacue. Et en fait, imaginons par exemple que je veuille... En fait, ça, c'Ă©tait un paragraphe qui pourrait ĂȘtre beaucoup plus long. Je vais faire loremipsum. J'ai un yasnippet qui va me faire un message un peu plus long. Et imaginons que je veuille remettre ça en une seule ligne, parce que je dois copier ça, par exemple, dans Outlook. Et dans Outlook, ce sera moche si j'ai des retours dans la ligne physique Ă  chaque fois. Ou si je veux le copier dans WhatsApp, un message. Donc, ce que je vais faire, en fait, je vais faire M-q. Il va faire l'inverse, il va toggler. Donc, mon M-q Ă  moi, il tog
 Donc, la premiĂšre fois, il fait un M-q normal et la deuxiĂšme fois, il passe Ă  la version sur une seule ligne. Quand je refais M-q, je repasse en version multiligne. Une seule ligne, plusieurs lignes, une seule ligne, plusieurs lignes.

Sacha: Donc, ça fait un toggle.

Fabrice: Donc, ça regarde la derniĂšre commande. Si la derniĂšre commande est dĂ©jĂ  le M-q, alors je refais le M-q, mais dans l’autre sens.

50:02 Les macros

Fabrice: J'ai la mĂȘme chose pour les macros. Maintenant, il y a F3 et F4 qui, depuis une dizaine d'annĂ©es, ont Ă©tĂ© bindĂ©s pour les macros. J’utilisais Shift F8 pour dĂ©finir une macro et F8 pour l'exĂ©cuter. Donc Shift F8. Imaginons que je veuille supprimer les deux premiers caractĂšres de la ligne. Ça n'a aucun sens, mais c'est pour l'exemple. Je vais faire Shift F8. VoilĂ . Non, je me suis trompĂ©. Shift F8. Et donc on voit Define Keyboard Macro. Je vais supprimer les deux premiers caractĂšres. Je passe Ă  une suivante. Et je refais Shift F8. Et parce que j'Ă©tais en mode dĂ©finition de macro, il sait qu'il doit arrĂȘter la macro. Et puis pour l'exĂ©cution, ce sera juste F8 tout seul.

51:02 Volatile highlight

Fabrice: Un truc aussi extrĂȘmement utile, je trouve, visuellement, c'est si je vais faire un undo, maintenant, les deux premiĂšres lignes de chaque phrase vont se remettre, de chaque ligne vont se remettre. Mais en fait, j'utilise Volatile Highlight qui va me montrer ce qui vient de changer. Quand je ne fais pas de mouvement dans le buffer, je vois qu'il vient de rajouter gr. Et si je refais undo, undo, undo, undo. Je vois chaque fois la modification qu'il a faite dans le buffer. Donc quand on fait des yanks, des copies, etc., des insertions ou des replays, on va voir, volatile-highlight va montrer juste comment j'ai dĂ©placĂ© mon caractĂšre. Et ça, c'est trĂšs utile pour voir un peu visuellement qu'est-ce qui s'est passĂ©. C'Ă©tait la mĂȘme chose avec mon metacue. Si je fais un undo, si je refais le metacue ici et que je fais un undo, voilĂ . On voit les insertions d'un retour en ligne Ă  chaque fin de ligne. Il ne reste que quelques minutes. Je n'aurais pas le temps de montrer tout ce que j'ai imaginĂ©. Je ne sais pas si vous avez des questions. Sinon, j'ai encore un truc que je voudrais montrer qui est assez utile. Et puis le reste vous pourrez lire.

Prot: Oui, je crois que c'est OK. Pardon ? Oui, je crois que c'est OK pour toi de démontrer. Parce que si on a des questions, on peut voir le Elisp que tu as écrit.

Fabrice: Tout Ă  fait.

Prot: Tout est public.

52:47 Les tableaux Org

Fabrice: Un truc qui m'intĂ©resse dans les fichiers Org, j'utilise beaucoup les tableaux. Par exemple, mes factures que je fais chaque mois. Je l'ai fait avec Org. J'ai un fichier qui ressemble Ă  ça. Ici, j'ai mis dans le fichier de note de cette prĂ©sentation, j'ai mis un petit exemple avec des personnes, des prix. Ici, on a un total de 2250 euros. Et ça, c'est un prix hors TVA. Ici, j'ai une autre table qui va appliquer la TVA. Elle reprend. Ici, j'ai un remote. Donc je vais chercher dans la carte participant, je vais chercher ce montant lĂ . Et donc il vient se copier lĂ  tout seul. Et sur ce montant lĂ , j'applique une TVA Ă  21%. Donc j'ai le montant, toutes charges comprises, donc avec la TVA. Et donc le truc que je trouve embĂȘtant, par dĂ©faut, enfin qui m'embĂȘte moi, c'est que potentiellement, je vais dire en fait non, et si c'Ă©tait pas 500, c'Ă©tait 1500. Et je vais sauver mon buffer. Et en fait, c'est totalement incohĂ©rent maintenant, puisque la somme n'est plus correcte. Et en plus, un tableau qui se trouve ici juste derriĂšre, mais qui pourrait se trouver totalement ailleurs dans le document, n'est plus du tout Ă  jour non plus. Et si je fais un export, je vais publier un document qui sera totalement avec des fautes, en fait. Et donc, j'ai surchargĂ© le Save Buffer dans le mode Org. Et dans le mode Org, quand ça fait Save Buffer, ça fait aussi le recalcul de toutes les tables dynamiques, le recalcul de tous les blocs dynamiques, pardon, le recalcul de toutes les tables et aussi le rĂ©alignement des tags. Par exemple, ici, je vais mettre un tag. Tout ça, vous verrez en mĂȘme temps. Mon tag. Les tags, par dĂ©faut, sont alignĂ©s Ă  80 caractĂšres. À la fin, ici, il y a une petite ligne grise. Je ne sais pas si vous la voyez bien. Elle est assez fine. Maintenant, quand je vais faire simplement save, chez moi, c'est F2, ça va calculer les montants. On va voir que ce montant-lĂ  va ĂȘtre changĂ©, ce montant-lĂ , celui-lĂ  et celui-lĂ . Je vais faire save ici. Et mon tag a Ă©tĂ© rĂ©alignĂ© aussi. 80 caractĂšres, sauf qu'ici j'ai une prĂ©sentation avec les deux chiffres, c'est pour ça qu'il y a un petit dĂ©calage. Donc de nouveau, si je mets 11500, C-x C-s, je suis sĂ»r que mon document est correct. Je n'ai pas d'information incorrecte de table avec des erreurs, simplement parce que j'aurais oubliĂ©. Vous m'entendez encore ?

Prot: Sacha, je ne peux pas t'écouter.

Sacha: Je suis muette.

55:43 Les formations et les cours particuliers

Sacha: Ma fille s'est réveillée, donc je veux consacrer du temps pour la publicité de ta formation avant qu'elle devenue grincheuse. Si c'est acceptable, dites-nous sur les formations en présentiel.

Fabrice: Je fais effectivement des formations sur Emacs parce que je suis tellement passionnĂ© par cet outil et que je le trouve magnifique, je le trouve extrĂȘmement puissant. que j'ai envie d'aider des gens Ă  pouvoir s'en servir de la mĂȘme maniĂšre que moi. Donc l'idĂ©e, c'est de montrer tout ce que j'utilise, un peu comme je le fais maintenant, mais ici, c'est avec quelques petits Ă©lĂ©ments Ă  gauche, Ă  droite. Et donc, j'aimerais bien en faire tout le temps, mais bon, j'ai fait pour l'instant dĂ©jĂ  trois formations, deux Ă  Paris, une Ă  Rotterdam, et je compte en refaire une soit en Q4 d'RGSI, J'avais quelques notes, voilĂ . Soit en Q4 2026 ou alors probablement plutĂŽt le Q1 2027, en refaire une autre Ă  Paris, oĂč l'idĂ©e, c'est en fait d'apprendre aux gens Ă  utiliser Emacs et de montrer, comme je le fais un petit peu ici, montrer les packages que j'utilise et qu'est-ce qu'ils apportent, donc qu'est-ce qu'ils font de plus, qu'est-ce qu'ils permettent d'apporter plus, comme donc le keychords, le volatile-highlight. Les petites fonctions que j'ai Ă©crites sur le recalcul des tables, par exemple sur Org, le M-w, C-w qui sĂ©lectionne la ligne d’office s'il n'y a pas de rĂ©gion, tout ça en fait, le but c'est de le montrer, de l'expliquer et que les gens puissent ou bien utiliser mon Emacs Leven tel quel et puis connaĂźtre tout ce qu'il y a dedans ou bien aller piquer des choses intĂ©ressantes qui sont dans ce fichier-lĂ .

Sacha: Est-ce que tu es aussi disponible pour les cours particuliers comme le coaching de Prot ? Tu offres aussi les cours particuliers ?

Fabrice: Absolument, absolument. Je suis passionnĂ© par Emacs et donc effectivement, des cours particuliers, je suis aussi tout Ă  fait disponible Ă  le faire. C'est le mĂȘme enthousiasme pour... En français et en anglais. En français, en anglais, en irlandais et en espagnol.

Sacha: C'est trĂšs cool. Tu as un autre rendez-vous. J'ai un fil. Merci beaucoup Ă  Fabrice et Ă  Prot.

Prot: Merci, merci Sacha et Fabrice.

Fabrice: Merci à vous. Merci beaucoup pour cette invitation. J'espÚre que ça donnera quelques idées. Je suis disponible pour... Pour toute question supplémentaire ou pour toute info supplémentaire, voilà, un grand plaisir.

Sacha: À la prochaine, je pense que nous devons à une autre conversation.

Fabrice: Avec grand plaisir. À la prochaine. Merci beaucoup.

Prot: Au revoir, au revoir, Ă  bientĂŽt.

Fabrice: Merci, au revoir.

View Org source for this post

You can e-mail me at sacha@sachachua.com.

-1:-- Emacs Chat 28: Fabrice Niessen (en français) (Post Sacha Chua)--L0--C0--2026-08-14T00:13:37.000Z

Magnus: Emacs salmagundi, 2026-08-13

Here's a few minor tweaks I've made to my Emacs setup recently.

Limiting enabled tree-sitter modes

After reading Rahul's post Emacs 31 Is Around the Corner: The Changes I'm Already Daily Driving I simplified my setup and turned on all the tree-sitter modes

(treesit-enabled-modes t)

I regretted that as soon as I opened a YAML file though. It turns out the yaml-ts-mode is rather unusable.1 I switched back to yaml-mode and adjusted the value of treesit-enabled-modes to include what I have use for (the change):

(treesit-enabled-modes '(bash-ts-mode
                         c++-ts-mode
                         c-or-c++-ts-mode
                         c-ts-mode
                         dockerfile-ts-mode
                         go-mod-ts-mode
                         go-ts-mode
                         go-work-ts-mode
                         json-ts-mode
                         python-ts-mode
                         rust-ts-mode
                         typescript-ts-mode))

The customization of treesit-enabled-modes contains a list of all the supported modes.

I hope someone will take pity on yaml-ts-mode and make it usable soon.

Tree-sitter grammar for Cabal files

When I began tinkering with my own treesitter-based mode for Haskell I failed to find a tree-sitter grammar for Cabal files so I wrote a rather rough one myself. My hope was that it could serve as a base, or motivation, for someone else to write a proper one. It took more than 2 years, but now it's finally happened!

I've switched my mode to use Curtis's grammar and I'll be archiving mine. (The change.)

Hello editable xref, good bye wgrep

Rahul's post also mentions that editable xref buffers. I had the same itch to have editable xref buffers, and I'd added a function to turn them into grep buffers to be able to edit them. I've now switched to using the built-in support, and removed the function.

At the same time I also decided to remove wgrep and instead use the builtin function for editing grep buffers.

Footnotes:

1

A mode for an indentation-sensitive language really ought to at least handle indentation!

-1:-- Emacs salmagundi, 2026-08-13 (Post Magnus)--L0--C0--2026-08-13T19:44:00.000Z

Sacha Chua: 27 août: Emacs Chat: Fabrice Niessen (en français, partie 2)

Nous allons à nouveau parler en direct avec Fabrice Niessen d'Emacs, de ses flux de travail, de sa configuration et d'autres sujets en français. Voici ses notes.

dans le fuseau horaire America/Toronto, soit 0730H EDT / 0630H CDT / 0530H MDT / 0430H PDT / 1130H UTC / 1330H CEST / 1430H EEST / 1700H IST / 1930H +08 / 2030H JST.

Voici notre conversation prĂ©cĂ©dente :

View Org source for this post

You can e-mail me at sacha@sachachua.com.

-1:-- 27 août: Emacs Chat: Fabrice Niessen (en français, partie 2) (Post Sacha Chua)--L0--C0--2026-08-13T15:58:31.000Z

Raymond Zeitler: One Hundred Times the Highest Priority

Please note that org‑get‑cust‑priority has been updated. The code that was published on 2026-07-10 causes org‑tags‑list to crash.

In the previous post,1 I was disappointed to learn that valid priority characters are limited to 0–9 and A–Z. I thought it would be neat if the exclamation mark ("!") could represent the ultimate priority, a sort of "drop everything and do this immediately" kind of priority.

It turns out that you can use "!" for this purpose, regardless of which priority characters you've configured. The trick is to write a function and assign it to org-priority-get-priority-function.

The function (which I named org-get-cust-priority) simply looks for "!" in the priority cookie and returns one hundred times the value that would be returned by the highest valid priority. If it doesn't find "!" it simply calls a modified version of the usual org-get-property function,2 which I named org-get-std-priority. The two functions are shown below.3

(defun org-get-cust-priority (s)
  "Return 100 times the highest priority when S contains
a priority cookie with `!'.  Otherwise call the usual
`org-get-property' function. Intended to be the function
`org-priority-get-priority-function' is set to."
  (interactive)
  (if (not (functionp org-priority-get-priority-function))
      (org-get-std-priority s)
    (string-match ".*?\\(\\[#\\(!\\)\\] ?\\)" s)
    (if (and (string-match ".*?\\(\\[#\\(!\\)\\] ?\\)" s) (string-equal (match-string 2 s) "!"))
        (* 100000 (abs (- org-priority-lowest org-priority-highest)))
      (org-get-std-priority s))))

(defun org-get-std-priority (s)
  "Find priority cookie and return priority.
S is a string against which you can match `org-priority-regexp'.
Same function as `org-get-priority' sans test for a custom
function in `org-priority-get-priority-function'."
  (save-match-data
    (if (not (string-match org-priority-regexp s))
        (* 1000 (- org-priority-lowest org-priority-default))
      (* 1000 (- org-priority-lowest
                 (org-priority-to-value (match-string 2 s)))))))

The number that Org uses to sort on priority depends on the values of org-priority-lowest and org-priority-highest,4 which are "C" and "A" by default. In the default configuration, the highest priority has a numeric value of 2000, while the lowest has a value of 0. If the highest and lowest priority characters are 1 and 9, respectively, the highest priority has a value of 8000.

You know you need this if you have about a dozen items on your agenda and half of them are prioritized A.


2026-08-13 Update org-get-cust-priority. Previous version breaks org-tags-list.

1 https://ray-on-emacs.blogspot.com/2026/07/numeric-priorities-in-org-mode.html
2 Modified just to prevent recursion.
3 I know this code isn't particuarly elegant. I could have made custom variables for "!" and the priority multiplier, for example. I'd like to use it for a while before deciding whether it's worth investing any more effort. I do welcome suggestions on how to improve.
4 Or rather, the difference between the highest and lowest priorities.

-1:-- One Hundred Times the Highest Priority (Post Raymond Zeitler)--L0--C0--2026-08-13T15:34:56.336Z

Irreal: Some Thursday Humor

I don’t see anything in my feed worth writing about so I offer this bit of humor to help you get through the day. If you’ve ever wondered why an S-expressions is called an sexp, here’s your answer.

Like all humor, there’s a bit of truth here. Not the part about sexp, of course, but the notion that many of us come to Emacs for some particular feature, venture too close to the init.el event horizon, and never escape.

-1:-- Some Thursday Humor (Post Irreal)--L0--C0--2026-08-13T15:05:22.000Z

The Emacs Cat: Emacs, Dired, and Ubuntu 26.04

Just recently I upgraded one of my Dell laptops to the latest Ubuntu 26.04 LTS with a clean install. The installation process was smooth and enjoyable.

Ubuntu 26.04 ships with Emacs 30.2, which made me happy, so I installed it immediately—more precisely, the emacs-pgtk Wayland-optimized package, since Wayland is the default windowing system on Ubuntu 26.04.

The Problem

I started Emacs and, after a short time, ran into a problem: Dired (C-x d) did not work properly. It displayed a strange mess of unsorted, chaotic entries, as shown below. It was a big surprise.

Click or tap to view the full-size picture.

I’ve been using the same .emacs multi-platform config file for Linux, macOS, and Windows for years and have never had any problems with Dired on different platforms, let alone across versions of the same OS.

My Dired configuration is quite simple:

;;; `DIRED'
(require 'dired)

;; Dired options for Windows and non-Windows (Linux, macOS) systems.
;; http://oremacs.com/2015/01/13/dired-options/
(if (string-equal system-type "windows-nt")
    (setq dired-listing-switches "/A:H /O:NG")
  (setq dired-listing-switches "-laGgh1v --group-directories-first --time-style=long-iso"))

;; `dired-subtree' (since 2022-10-18)
;; https://xenodium.com/drill-down-emacs-dired-with-dired-subtree/
(use-package dired-subtree
  :ensure t
  :after dired
  :config
  (bind-key "<tab>" #'dired-subtree-toggle dired-mode-map)
  (bind-key "<backtab>" #'dired-subtree-cycle dired-mode-map))

;; By default, Dired buffers will not update themselves
;; unless you explicitly tell them to.
(setq dired-auto-revert-buffer t)

The dired-listing-switches variable defines the switches passed to dir or ls for Dired on Windows and Linux/macOS systems, respectively. I’ve been using this configuration for years.

On Ubuntu 24.04 everything looks fine. So, what’s wrong with Emacs 30.2?

I decided to test the ls switches in the console. Oops—the same result as in Dired under Emacs 30.2!

Click or tap to view the full-size picture.

This means the problem is not with the new version of Emacs. After a short search, the answer was found.

The Bug in Ubuntu 26.04

It turns out the bug in Ubuntu 26.04 is real, documented, and already tracked in Ubuntu’s Rust-based coreutils for Ubuntu 26.04. The issue specifically affects ls when using --group-directories-first and is tied to missing locale collation support in the Rust rewrite.

Launchpad Bug 2154042 — Incorrect alphabetical sorting with --group-directories-first

This is the main bug report affecting Ubuntu 26.04 users after the Rust coreutils transition. It explicitly states that:

  1. ls from the Rust-based coreutils does not sort alphabetically when using --group-directories-first.
  2. The bug appears both when LC_ALL is set and when it is unset.
  3. GNU ls (gnuls) sorts correctly; Rust ls does not.

Conclusion

Since Dired—and possibly other Emacs packages—uses ls to list directories and files, Dired will not work properly on Ubuntu 26.04 regardless of the Emacs version.

Solution

Luckily, the Ubuntu team has kept the old version of coreutils (GNU coreutils), written in good old C. The GNU version of ls is gnuls and is installed by default on Ubuntu 26.04. This means we can use gnuls—which works properly—for Dired instead of ls when running Ubuntu 26.04.

To do this, we will use the insert-directory-program variable, which holds the absolute or relative name of the ls-like program. This variable is used by insert-directory and dired-insert-directory (and therefore by Dired). Its default value on Linux and macOS is ls.

First we need to determine the name and version of the OS. The custom ubuntu-version function helps with that:

(defun ubuntu-version ()
  "Return (MAJOR MINOR) as integers if running on Ubuntu, else nil."
  (when (and (eq system-type 'gnu/linux)
             (file-readable-p "/etc/os-release"))
    (with-temp-buffer
      (insert-file-contents "/etc/os-release")
      (let* ((os-release (buffer-string))
             (is-ubuntu (string-match-p "^ID=ubuntu" os-release))
             (version-id (and is-ubuntu
                              (when (string-match "VERSION_ID=\"\\([0-9]+\\)\\.\\([0-9]+\\)\"" os-release)
                                (list (string-to-number (match-string 1 os-release))
                                      (string-to-number (match-string 2 os-release)))))))
        version-id))))

On my machine ubuntu-version returns (26 4).

Now we can replace ls with gnuls if we are on Ubuntu 26.x:

(when (eq (car (ubuntu-version)) 26)
  (setq insert-directory-program "gnuls")
  (message "`ls' is replaced with `gnuls' on Ubuntu 26.x."))

After that, Dired works as before.

Click or tap to view the full-size picture.

Happy Emacsing on Ubuntu 26.04!

– The Emacs Cat.

-1:-- Emacs, Dired, and Ubuntu 26.04 (Post The Emacs Cat)--L0--C0--2026-08-13T09:55:47.000Z

Meta Redux: Projectile 3.4

Projectile 3.4 is out! After the four releases that preceded it this summer, this one is polish rather than ambition.

Most of it came out of an annoyance I’d been living with for years without ever quite naming it: a lot of what I work on isn’t one directory. CIDER is really CIDER plus cider-nrepl plus orchard plus clj-refactor plus a handful of others. RuboCop is RuboCop plus rubocop-ast plus rubocop-rails and the other extension gems plus the style guide. I’ve been maintaining families of repositories for the better part of a decade.

Lately I’ve also been reaching for git worktrees far more than I used to, so the same repository is now checked out two or three times on my disk at any given moment.

Projectile saw all of that as a pile of unrelated projects, which is exactly what it looks like from the outside.

Somewhere else in the same project

projectile-switch-worktree (s-p W) offers the other checkouts of the repository you’re in, each labelled with whatever tells it apart - the branch for git, the workspace name for Jujutsu:

Switch to worktree:
~/src/myapp-main/     (main)
~/src/myapp-hotfix/   (hotfix/crash-on-open)

Git worktrees are the obvious case. Projectile asks git about those, so a worktree you’ve never opened in Emacs shows up anyway. Jujutsu workspaces work the same way.

The case I care about more is the one without any plumbing: a second git clone of the same upstream. Same workflow, done by hand. I looked at my own ~/projects while writing this and found four separate clones of CIDER sitting in it. Nothing records those anywhere, so Projectile can’t ask git to list them - it matches them among your known projects by their remote instead.

Somewhere else in the same effort

The other half is projectile-switch-sibling-project (s-p n), which offers the projects related to the one you’re in rather than every project on the machine.

The interesting question was what “related” should mean. My first instinct was to compare directory names and look for a shared prefix. Before writing anything I tried the candidates out on my actual project directory, all ninety-odd repositories of it.

Comparing names does find rubocop, rubocop-ast and rubocop-rails. But grouping by the owner of the upstream remote finds this:

The sibling project prompt in CIDER, listing sixteen related projects including orchard, haystack, port and sayid

Half of those names have nothing in common with cider, and no amount of staring at directory names would ever have related them. haystack parses stack traces, port is a printer registry, sayid is a tracing debugger. Nothing in those names says “CIDER”.

What they do have in common is an org: they all live under clojure-emacs on GitHub. That’s not incidental, it’s how the project is actually organised - the org is the boundary of the effort, and the individual repositories are just where the pieces ended up when they got big enough to split out. Same story for the rubocop org, and for nrepl. Once I saw that, keying on the owner of the remote was obviously right, because it’s the same fact GitHub is already recording for me.

It needs a bound, though, and the same experiment showed why: about 40% of my checkouts are under my own GitHub account, and “we’re both under bbatsov” doesn’t relate anything. So an inferred group covering more than a quarter of your known projects gets dropped and the next signal takes over.1 If you’d rather just say what belongs together, projectile-project-groups is there and is never second-guessed.

Switching is only the obvious thing to do with this. Now that Projectile can tell which projects belong together, the same grouping could back a find-file or a search across the whole family - one prompt that reaches every repository in the org rather than just the one you happen to be sitting in. I go looking for “which of these fifteen repos defines this var” often enough that I suspect it’s the more useful half. Nothing built yet, but that’s where I expect this to go.

The commands come with you

Once Projectile knows two directories are the same repository, the command history can follow you between them.

Press M-p at the compile or test prompt in a worktree you made this morning and you get the commands the project is actually built with, instead of an empty history. That’s an issue from 2022 that a stale bot had helpfully closed for me at some point.

What doesn’t follow you is anything that runs without asking - what a prompt is pre-filled with, and what projectile-repeat-last-command replays. I had those shared too in the first draft, and then watched a repeat in one worktree rebuild the tree next door. A remembered command can carry absolute paths back to where it was typed.

More languages, fewer surprises

projectile-run-test-at-point (s-p c .) arrived in 3.1 knowing Python, Go and JS/TS. It now also knows Ruby (both RSpec and Minitest), Rust, Elixir, Java, Erlang and F#.

Ruby is written the same way whichever framework you use, so there the project type picks the runner rather than the syntax; Java’s picks between Maven and Gradle. Elixir tests get addressed as FILE:LINE, because ExUnit can’t select a test by name from the command line. OCaml deliberately gets nothing - its tests are ordinary values you register with Alcotest or OUnit, so there’s no syntax to recognize.

projectile-find-file-of-kind (s-p j) and projectile-toggle-related-file (s-p J) learned Phoenix, Laravel and Next.js. Rails and Django had been the only frameworks with file-kinds tables out of the box, which felt like a strange place to have stopped.

The reports answer back

The dashboard and the doctor from 3.3 both got a pass. They’re no longer plain text - section headers, field labels and findings are faced by meaning, with findings colored by severity and sorted so anything wanting your attention comes first. The faces only inherit from standard ones, so your theme styles them without knowing Projectile exists.

The doctor’s findings now come with a button that acts on them:

The doctor's findings section, with a warning about projectile-mode carrying an enable button, above four ok findings

[enable] for a projectile-mode you forgot to turn on, [enable caching] on a big uncached project, [open dirconfig], [edit .dir-locals.el]. Pressing one regenerates the report. Findings Projectile can’t act on stay plain advice.

And since a doctor report usually ends up pasted into an issue, w copies the buffer as plain text, without the faces and buttons.

Odds and ends

  • projectile-find-changed-file (s-p C) completes over what git reports as staged, unstaged or untracked - or, with a prefix argument, everything that differs from a revision you pick.
  • projectile-run-task discovers rake tasks now, read out of your Rakefile and .rake files rather than by running rake -T, which would load the whole application.
  • projectile-ignored-project-patterns is the regexp-matching sibling of projectile-ignored-projects, so keeping a whole area of your machine out of the known projects no longer needs a lambda.
  • Messages Projectile emits on its own initiative are prefixed with [Projectile] now, and the ones answering a command you just invoked aren’t. There were five different conventions in there before, which I’d somehow never noticed.
  • The known projects file, the frecency store and the session directory are resolved with locate-user-emacs-file, so they land in the right place if your configuration lives in ~/.config/emacs. Nothing moves if it doesn’t.
  • Elixir’s implementation/test toggle offers foo_test.exs rather than foo_test.ex, a script ExUnit will actually run. Project types can declare their test file extension now.

Upgrade notes

Nothing here should break a working setup, but two things are worth knowing.

A batch of options were renamed or folded together. The six projectile-<cmd>-use-comint-mode options became one projectile-use-comint-mode; projectile-per-project-compilation-buffer and projectile-per-command-compilation-buffer became projectile-compilation-buffer-scope; and a handful of options that had broken their own naming schemes were renamed to match their siblings.2 Every one of them is still honored under its old name, so your config keeps working - you’ll just see an obsolescence notice.

Two options are gone: projectile-tags-file-name and projectile-go-project-test-function were only ever read as Projectile loaded, which means setting them from your init file afterwards did precisely nothing.

And the command history is now the repository’s rather than the directory’s. Set projectile-command-history-scope to project if you’d rather have it per directory. Histories you already have are adopted, not dropped.

The full changelog is here, and the manual is at docs.projectile.mx. The cross-repository features have a page of their own, limitations included.

Five releases in six weeks is not a pace I intend to keep up, and this is the natural place for the burst to land. The big pieces from 3.0 through 3.3 have had their corners sanded down, and what’s left on my list is smaller and less interesting to write about. Which is roughly where a fifteen-year-old package ought to be.

That’s all I have for you today. Keep hacking!

  1. Which is why projectile itself comes back with no siblings on my machine. The cap is working; the answer is a configured group. â†©

  2. projectile-global-ignore-file-patterns, projectile-cmd-hist-ignoredups, projectile-related-files-fn-function, projectile-auto-discover, and the three reviewable-search options that were named after replace. â†©

-1:-- Projectile 3.4 (Post Meta Redux)--L0--C0--2026-08-13T07:30:00.000Z

Protesilaos: About Emacs themes, Solarized, and wallpapers

JTR from the blog The Art Of Not Asking Why sent me a few questions regarding Emacs themes, my opinion on the Solarized colour scheme, and even my choice of wallpaper.

JTR asks about Solarized because I consider Ethan Schoonover’s Solarized an excellent project, given what Ethan was trying to achieve. I asked JTR if I could publish my thoughts and they agreed. JTR has also written the article Back to Solarized.

Note that throughout this article I am only commenting on Ethan Schoonover’s Solarized (the original Solarized). There are many Solarized-like themes out there with lots of additions on top, including higher colour contrast, which are separate themes as far as I am concerned.

I should also point out something I always mention: themes are a personal choice and there are many factors that go into what a person wants. Keep in mind that readability is also a matter of font size, ambient light, and the screen brightness you are using.

To give a simple example, modus-operandi in a very dark room with maximum screen brightness at a fairly large font size will most probably harm you and is thus a terrible choice. But the same setup on a sunny Cyprus day in my well-light house is how you can read the screen without distractions.

Generally though, people forget to adjust their screen brightness, so always do that and rely on environmental light to not tire out your eyes.

Be mindful of the context

Have your thoughts changed about Solarized since the creation of Modus themes? Later, did they change after you created the ef-themes?

In short, no as the technological realities for my case and for the original Solarized remain the same. Ethan Schoonover wanted to have a colour scheme that would work reasonably well with terminal emulators and, by extension, Vim. Most terminal emulators let you define 16 colour values. Then applications running inside the terminal can map those to the objects they display.

Applications running inside the terminal cannot change the 16 colour values of the terminal. This means that Ethan’s Vim configuration necessarily had to have a light and a dark theme that worked with the same 16 colours. Ethan could have developed two distinct colour schemes for the terminal, which would then underpin two separate Vim themes, but I understand how this is a more complex arrangement.

My older Tempus themes project, from my pre-Emacs days, is for terminals, Vim, and friends. Same idea for its predecessor, Prot16.

I think both of those older projects are fundamentally flawed because the technological constraints they are designed to work in result in all sorts of little compromises. To give an example that many Linux users may have noticed: if you use a light theme in a terminal and do apt update && apt upgrade you will get the progress bar with a green background and a black foreground. Colour schemes cannot change that combination, so they make that text virtually unreadable (in a terminal, colour combinations should always be ACCENT + BACKGROUND, not ACCENT + BLACK/WHITE, as the accents are always designed to be visible against the background).

There cannot be one Solarized

Even though the original Solarized was designed to be a single theme, in practice it is not and cannot become as much. There is Solarized Light and Solarized Dark, sharing those same 16 colours. Solarized light has a background that is closer to yellow, while its dark counterpart’s background is closer to blue. This means that accent values which are picked to work with both eventually do not work equally well as they do not evoke the same feeling.

Without even considering the specific values of the Solarized palette, a combination of blue/cyan, magenta, and purple as foreground colours will be on the opposite side of the spectrum to the yellow background and on the same side as the blue background. This means that if we pick blue/cyan, magenta, and purple as our main colours we have a light theme (yellow) with a completely different feel than the dark theme (blue) even though they are supposed to be the “same Solarized”.

Let me outline this for you:

Foreground colours Solarized Light background Solarized Dark background
green, yellow, red/orange Same side Other side
blue/cyan, magenta, purple Other side Same side

So if we force the same mapping of foreground colours, then we have two themes with contrasting harmonies and necessarily distinct characters. In this context we begin to appreciate the importance of judgement: sometimes you achieve likeness through difference. For the table above, inter-theme likeness exists on the diagonals, so either have both themes with “same side” combinations or both themes with “other side” combinations.

This concerns the predominant colours. A theme that uses all accents in equal proportion will look very busy and thus run into other problems.

The designer can, of course, pick a colour that does not follow the overall pattern to produce an emphasis of some sort. Though they cannot start with emphasis as their baseline.

One set of values leads to compromises

Because Solarized Light and Solarized Dark are designed to share the same palette, individual values are picked as a matter of compromise, even though they are “equally good” on paper in terms of distance as measured by various luminance metrics. The blue used for the light theme, for example, must also be good enough with the dark theme. But “good enough” for both may not be optimal for either.

Concretely, the Solarized blue stands out more in the light version than in the dark version (because of the complementarity between yellow and blue). If the light effect is supposed to evoke sunlight on a surface, and if that is the reason green and yellow are desaturated, then the blue should not be as saturated for the light theme. It would have to be a considerably more washed out colour. Though the blue has to be fairly saturated to be readable on the Solarized Dark background and still look like a blue, hence the compromise.

Same idea for the green and yellow colours which are consistent with the light background but would require tweaks to be harmonious with the dark background.

The magenta does not fit any background: it stands out as an exaggeration. To be consistent with the light background, it has to be less saturated. To fit the dark background, it needs to have greater contribution from the blue channel of light (i.e. move closer to purple) or become more pink. But moving in either direction compromises the opposite theme


There is no “bright green” (terminal colour 10), “bright yellow” (terminal colour 11), “bright blue” (terminal colour 12), and “bright cyan” (terminal colour 14). I believe this is because they would not fit both Solarized Light and Solarized Dark.

My themes are designed for Emacs

As noted, Ethan’s Solarized was developed with a specific technology in mind. The same is true for my case: I develop all my themes to work with Emacs. This typically means that I can rely on more than 16 colours and each theme can have its own colour values.

For example, if I choose to apply a green background colour to the “current match” in a search, its value is not the same green I would use for, say, a “DONE” keyword in Org. Whereas in a terminal with 16 colours what you normally do is invert background and foreground colour combinations, which results in things standing out more than they need to (and becomes overwhelming when you want to use many such elements).

Each of my themes relies on its own palette. If I tweak one theme’s colour values, I am only affecting that one theme. Because each theme is its own design, I can make things similar by making them different. For example, modus-operandi-tinted is a “yellow-red theme” (simplifying greatly now) but its counterpart modus-vivendi-tinted is a “blue-purple” theme. On paper, this description alone makes them very different. But in terms of character, they both communicate a similar feel, owning to considerations that follow from what I mentioned above.

Additionally, each theme has its own colour mappings. This means that I do not have to make every theme use, for example, blue for links. In Emacs, I have greater control over what each “application” does, by configuring the relevant faces. There still are constraints, as I cannot for example decide which faces are applied to what portion of text, but this is generally not a problem.

Differences between my theme projects

What’s the difference between prot16 and your ef-themes? They seem to cover similar ideas, but it doesn’t look like prot16 has been updated.

My older projects are for terminal emulators. It is why they were inspired by Solarized. Terminals only have colour schemes though, not themes. The designer cannot control how colours are mapped to objects, so they have no means of enforcing thematic consistency.

A colour scheme sets the 16 values, but otherwise has no mappings for things such as “here is an error message” or “this is a progress bar and things are going well”, or even to specify “I only want green and blue here, but never magenta”.

If a colour-coded message gets a style, it will typically be hardcoded to red, green, or yellow. And if the colour scheme wants to support users with blue-yellow colour deficiency, for example, it will have to add a yellow value where the nominal red is (terminal colour 1 and terminal colour 9). But doing so leads to weird issues because, fundamentally, we are conflating colour names with colour mappings (there may be an application that wants to use yellow text on a red background, but now that actually becomes yellow on yellow, so you get the idea).

In Emacs, a theme designer has more control. They can specify colour values and write exactly how they are used by the relevant faces. For example, we do not only define “blue” but also say “I want keywords in programming modes to be blue”.

The constraint in Emacs is which faces do packages define and how exactly they apply them to elements of the display. A theme cannot, for instance, dictate how many separate faces a programming mode will add to its text. Furthermore, a theme cannot govern how generic faces, like font-lock-variable-use-face are set by modes to do things they are not supposed to do (for example, a mode specifies that face because they like its green colour in the one theme the author is using, but the thing being styled is not a variable and that specific face does not produce an optimal result in its context).

Additionally, themes cannot determine the surrounding text. For example, the Org export dispatcher has keys wrapped in square brackets (and I sent a patch that was merged a long time ago to have decent colours there by default when no theme is used). The bracketing is something the theme cannot change, so it has to do strange things to produce readable text because in an [i] indicator it is hard to discern the i due to how the square brackets limit the perceived boundaries—and you need to apply a highlight so that the user knows which exporter they are picking. An [ i ] is somewhat easier in this regard and a variation of it without the square brackets is even more flexible as then the theme can apply all the colour and typography attributes it needs.

Another constraint with Emacs is that we do not have real padding and margins, the way those are understood in CSS. I think this is fine for the majority of cases, but can be a problem sometimes such as when we need to use a coloured background that spans a small portion of text (e.g. with the Org dispatcher or with the style of rendered keys like <home>).

The gist is that Emacs gives the theme designer more control and in a more integrated way than a terminal+TUIs arrangement. This results in a coherent experience. Terminal-centric environments cannot have that to the same level because of disparate applications trying to form one computing environment, each doing its own thing in the process. I tried inter-application consistency in the terminal, discovered its limitations, and is the single most important reason why I switched to Emacs.

Contrast and readability

My understanding is that the contrast for Solarized wasn’t good enough for you. I don’t know if you have my issue specifically (https://taonaw.com/2023/07/05/halatoion-and-accessiblity.html), but I’m curious: don’t you get halation as well? Doesn’t it bother you, especially if you switch from a dark theme to something lighter? (For example, you read something with a dark background and light text, then switch to a page that has a light background and dark text)?

We measure contrast between colours to have an imperfect approximation of what might work in the average scenario. Though readability is influenced by many more factors beyond the applicable colours. Consider the environmental light and the brightness of the monitor. In addition, check the font size and even the font family you are using. Many font families can produce a halo effect at different sizes, regardless of colour combinations.

Have an extra source of light beside the monitor’s. If you do not, the eye focuses on one spot, which is more tiresome. And always adjust the screen brightness to not be too bright or too dim relative to the environment.

As for fonts, you may benefit from a design that has more open shapes. The exact size is also a factor.

For example, I have a font called Aporetic that is derived from Iosevka. What motivated me to do my own thing is the original monospaced m of Iosevka (maybe it is changed now), which blurred into a box at small point sizes and was thus not nice to read.

The Hack font I used to use (and which I had also modified), had similar issues. The Ubuntu Mono font that Ubuntu and derivative Linux distributions rely on, can have a g with a very short descender at certain point sizes, as well as a dotted zero where the dot is off centre.

I can go on to great details but you get the idea: you have to check all the variables and find what works for you. I am confident in stating that this is never a theme-specific issue.

As for switching between applications, these days most desktop environments have a concept of a light/dark preference, which many websites also follow. For example, GNOME has a menu from where you can toggle the “Dark Style” on/off.

The specific problem you will encounter with Solarized is that practically no other application or website uses it or similar colours. So either you will have to set Solarized everywhere you can, or you will be switching from the yellowish/blueish background to white/black, with whatever context-switching friction that may have.

Thoughts on wallpapers

This is an extra one I’m curious about: what are your thoughts about wallpapers? I noticed, the few times I worked with you and on video, that usually you have a natural scene. Have you ever switched to something else (like a drawing, perhaps an artwork, or maybe even a technical scheme)?

I have used wallpapers of all sorts and find that pictures I take of landscapes or flowers are the best for me. The reason is that they avoid exaggerations. Many pictures that are used for wallpapers are designed to show something in a more pronounced way and are thus calling for your attention. That is fine when the object of attention is the art piece. But when I am doing work on the computer, I do not want other elements to be competing for attention with whatever it is I am working on.

“Avoiding exaggerations” is a principle that informs my lifestyle. It also is why I prefer to live in the mountains and to spend plenty of time outdoors. The mountains do not have the intense stimuli a city has. In a city there are bright lights everywhere, a faster pace to motions, and sharper noises all around. Whereas the mountains are subtle, even though they are full of life.

People who go on a retreat say “I went to this holy place and found peace”, when in reality what likely happened is that they reduced their exposure to exaggerated stimuli and were thus able to lower their baseline intensity for a little while.

Because we are also conditioned by our habits, we do not realise just how much we have gotten used to things in our milieu, even when those are not benign to us.

People want magical solutions when the basics will suffice. We are heavily influenced by our environment and the elements we are exposed to. A stressful place will increase our stress levels. A harmonious place will make us more harmonious. Inconsiderate food choices will disturb us long-term, a poor work-life balance will harm us, and so on.

People think they can brute force their way into calmness or focus by means of “truly believing” in their project. This is a fool’s errand. Changing the scenery and relevant lifestyle will be far more effective than whatever willpower one thinks they can muster on demand.

-1:-- About Emacs themes, Solarized, and wallpapers (Post Protesilaos)--L0--C0--2026-08-13T00:00:00.000Z

Raymond Zeitler: Emacs Numbered Backup Strategy

Emacs produces a backup of each file by default. It does this by appending a tilde to the file's name. For example, Myfile.txt is backed up to Myfile.txt~. It's a reasonable strategy, assuming that a Version Control system is in place.

But in the absence of version control, you're limited to restoring just the previous version; older versions need to be restored from backup.

I use git for coding projects that I share to the public. But I didn't create a repository for my home directory. So when C-c a m TAG1 generated an error instead of a list of TAGged items, I hoped fervently that the latest init file change was to blame.

After finding and fixing the problem quickly, (and realizing I was lucky this time), I resolved to be more diligent about disaster recovery. I looked into what backup schemes Emacs already provides.

Emacs can create unique backups for a file rather than overwriting the previous backup. When Emacs sees a numbered backup for a given file, it will make a new, sequentially-named file for each backup of that file, while continuing to use the "append tilde" method for other files.

Once I renamed (or copied) .emacs~ to .emacs.~1~, Emacs created backups named .emacs.~2~, .emacs.~3~ (and so on). I didn't even need to change a variable -- when Emacs detected .emacs.~1~, it knew that backups of .emacs needed to be numeric, so it acted accordingly. Emacs continues to use bills.org~ as the backup for bills.org. Until I tell it otherwise.

A list of file names in light grey text on a blue background: .emacs; .emacs~1~; .emacs~2~; .emacs~3~;

Read the Emacs Manual to learn more about numbered backups.


1 C-c a m invokes org-tags-view

The default values for the pertinent backup variables are:

  • make-backup-files is t
  • backup-by-copying is nil
  • version-control is nil

-1:-- Emacs Numbered Backup Strategy (Post Raymond Zeitler)--L0--C0--2026-08-12T23:01:35.675Z

Irreal: Emacs Development: Ongoing And Good

One of the things that we Emacers hear with tiring frequency is that Emacs is moribund, old technology loved only by graybeards stuck in the last century. In fact, as actual users know, Emacs is undergoing constant development and is often the first to offer new features that the other editors copy. The most salient examples are Org mode and Magit but there are plenty of more recent examples.

But don’t take my word for it. Over at the Emacs subreddit, gonstrider has a short post relating his experience with all of this. He’s been using an unnamed editor—you’ll have no problem figuring out which one—that keeps having weekly updates that seem to make things worse each time. So he jumped in the deep end and downloaded and built Master (Emacs 32) fully expecting to find lots of broken things.

It didn’t turn out that way. He was, in fact, surprised to discover that almost everything worked well. The only problem he had was evil on Windows and he solved that by simply upgrading evil. As for the rest, he found that Emacs was super-responsive and all the functionality that seemed laggy in that other editor was snappy in Emacs.

There are two lessons here. The first is that Emacs, far from being moribund, is undergoing continuing development and introducing new features. The second point is that Emacs is, unlike some of its competitors, continuing to produce upgrades that simply work and don’t make their users crazy.

Very shortly, we should see the release of Emacs 31 but work on Emacs 32 is already ongoing and amazingly stable for what is, after all, alpha software. The next time someone tells you that Emacs is old and moribund, refer them to gonstrider’s post.

-1:-- Emacs Development: Ongoing And Good (Post Irreal)--L0--C0--2026-08-12T14:38:54.000Z

TAONAW - Emacs and Org Mode: Back to Solarized

Years ago, when I started the old blog1, I discovered Solarized.

I liked it. The colors were beautiful and worked for me, but eventually I switched to the Gotham theme in Emacs, which, if you take a look, is not much different — just a bit darker. I stayed with this theme for a long time, tweaking it a bit after a trip to New Mexico.

When I received my Mac and started working on it at home, I enjoyed its automatic switching between dark and light themes. At the same time, Prot started coming out with more of his excellent Ef Themes, and I adopted ef-reverie for my light theme and ef-night for my dark one (once again, if you look at the images, you’d see they’re not far off from Solarized, especially my choice of a light theme).

This has been the state of affairs until the beginning of this week, when I “found” Solarized again. I discovered Prot himself was heavily influenced by Solarized, and he discussed it several times on his blog. Here’s part of his background story for his project Prot16:

My starting point for developing a colour scheme was Ethan Schoonover’s Solarized. A true masterpiece. I thus settled on a method of using a 16-colour palette that consists of 8 base values and 8 accents. As with Solarized, the themes would have to be able to transition from ’light’ to ‘dark’ environments with minor alteration to the mapping of colours (though not the values themselves).

Prot’s quest is an interesting one. Like me, he enjoyed Solarized, but eventually decided the colors were not contrasting enough for his taste. His reaction was to create his well-known Modus themes, which, along with his Ef-themes and Prot16, set new theming standards for Emacs.

Meanwhile, I have had the other issue since childhood:

I’ve never liked harsh contrast for this reason. As a matter of fact, a more “gentle” contrasting theme is one of the reasons I like working in Emacs. My website and my wiki are a result of these preferences. The black text on the beige background is comfortable on my eyes. Enough contrast to read, but not enough to burn text into my vision, as many dark modes out there do.

While Prot’s ef-themes offer softer contrast (I didn’t check, but it does seem so visually) which I find excellent, I decided to try out bbatsov’s Solarized for Emacs, which I didn’t know about in the past when I first picked up this theme for Emacs — the official Emacs port is not as good in my opinion.

I’ve learned a couple of things I wasn’t aware of. For starters, you can have many variations of this theme, even though the main 16 colors are still preserved. It makes sense when you think about it: one person can choose Solarized’s red (#dc322f in hex) as an emphasis, while another can select its yellow (#b58900) or orange (#cb4b16), for example. Webpages and Emacs take it a step further, as certain texts can be bold or italicized, with solid underlines or dashed ones, etc. All of those changes take place without touching the colors themselves.

Solarized also helps me with a certain itch I’ve had for a couple of months: a dark theme for my blog. I know most of you read my posts in your RSS reader, hopefully with a theme you enjoy, so this won’t matter much. For me, how my site looks and is styled is important, and getting there is fun.

A minimalist (solarized) skyline of a city with a prominent tall building, set against a dark background with waves in the foreground and a red moon in the sky.

  1. This post is here, on the new blog, because I migrated it from the old. The date on it is accurate however, and it’s the first post I have saved in my old archive. The same is true about the New Mexico post. â†©ïžŽ

-1:-- Back to Solarized (Post TAONAW - Emacs and Org Mode)--L0--C0--2026-08-12T14:09:15.000Z

Ashish Panigrahi: Reviewing finished tasks from last week in org-agenda and emacs

Being a PhD student within a research group entails some structure to tracking your progress as you proceed with research. Within the current team that I'm in, we have weekly group meetings where each member presents the tasks that they've completed during the previous week and discusses any issues they might've faced (if any), to our supervisor.

Usually before the meeting, I jot down things that I've finished with pen and paper. But since I'm in the spirit of integrating my workflow with emacs and orgmode, I thought why don't I try implementing this part of my routine also into orgmode.

Enter org-agenda

All my todo items are tracked with org-agenda where I capture every task I need to finish with org-capture1.

I have a custom org-agenda view just for viewing my daily and weekly TODO items, events/meetings scheduled at a certain time and tasks that have a deadline associated with them. Suffice to say, this workflow has replaced all my needs for having a calendar over the cloud, be it Google, Outlook, what have you2. The only downside that I haven't figured out (yet) is to incorporate calendar invites that I receive via email, into my org-agenda automatically instead of manually capturing an event into the agenda view.

With this custom agenda view, as I finish tasks and mark them DONE, they disappear from the current view. This is by design. I figured I could just review my completed tasks by visiting the relevant files (tasks.org, meetings.org, etc. in my case). But who wants to sift through all the completed tasks and filter them manually to only note down the tasks completed during the previous week? Why not automate this with the power of emacs?

Elisp snippet that implements this weekly review

The idea is fairly simple. I'd like to look at the tasks that I've completed since the last group meeting. This assumes I review these tasks on the day of the group meeting (which I do currently3).

We simply then instruct orgmode to filter out the DONE items from the last 7 days. The org-agenda-custom-commands variable is what we'll use to define this custom org-agenda view.

(setq org-agenda-custom-commands
      '(("w" "Finished tasks from last week" tags "CLOSED>=\"<-7d>\""
         ((org-agenda-overriding-header "Finished tasks from last week")
         (org-agenda-archives-mode t)
         (org-agenda-tag-filter-preset '("-emacs" "-personal" "-email"))
         (org-agenda-prefix-format '((tags . " ")))
         (org-agenda-remove-tags nil)))))

Let's go over the various config options one by one:

  • The first line defines the keybinding in the primary org-agenda dashboard and the associated title for the keybinding.
  • tags "CLOSED>=\"<-7d>\"" is pretty self-explanatory. We filter for items that were completed in the last 7 days.
  • org-agenda-overriding-header: Simply defines the title of the agenda view.
  • org-agenda-archives-mode: This is set to t (True) meaning to also look at the archived entries from last week. I typically archive my entries frequently so this is helpful.
  • org-agenda-tag-filter-preset: I don't want personal tasks appearing in this view, so I remove any items that have the relevant tags.
  • org-agenda-prefix-format: By default, the agenda view contains information about which file the entries belong to (in my case, it's tasks.org). This appears as tasks: per entry in the agenda which unnecessarily clutters the view.
  • org-agenda-remove-tags: I don't want to remove the tags of the various entries (they are useful to me) that appear in the right margin. Hence this variable is set to nil (False).

To invoke the view, we can simply run M-x org-agenda and hit w to get into the view. My org-agenda dashboard looks like this:

My org-agenda dashboard

All the above keys are present in the default view, except my custom views (depicted by j and w keys).

Invoking custom org-agenda views (slightly) faster

For my workflow, I mostly deal with just the two org-agenda views (represented by j and w). It's a good idea to have a global keybinding to quickly invoke these views. Let's define the function and keybinding for it.

(defun pani/done-items-prev-week-org-agenda ()
  "Custom function to immediately jump to my custom org-agenda view."
  (interactive)
  (org-agenda nil "w"))

To invoke the function, we define the keybinding like via a use-package macro:

(use-package org-agenda
  :ensure nil
  ;; Don't need to go through org-agenda template for custom agenda
  :bind (:map global-map
	      ("C-c w" . pani/done-items-prev-week-org-agenda)))

I can then just hit CTRL c w to bring up this new agenda view.

That's it! This should make things easier for me during our group's weekly meetings.

Special thanks to Marci and my sister, Alaka Panigrahi for pointing out grammatical errors and typos.
  1. More on this in a future blog-post. ↩

  2. This is fully offline. Between my personal laptop and office PC, I simply use syncthing to sync all my orgmode files via peer-to-peer. ↩

  3. This is perhaps not the best approach but is a good enough starting point for me. ↩

-1:-- Reviewing finished tasks from last week in org-agenda and emacs (Post Ashish Panigrahi)--L0--C0--2026-08-12T00:00:00.000Z

Irreal: Markup Editing In Org Mode

Marcin Borkowski (mbork) does a lot of writing and, of course, uses Org mode for most of it. The hard part, he says, is not the writing but the editing. In particular, he’s talking about the emphasis markup. If he wants to write a word or region in bold, that’s easy. He merely starts and end it text with a star. Making a word or region bold after the fact—in the editing phase—is more difficult. You have to locate the beginning of the text, add a star, move to the end of the text, and add another star.

Mbork, of course, soon discovered the solution: org-emphjasize. All you need to do is highlight the text and specify the markup character. The problem is that the binding for org-emphasize, Ctrl+c Ctrl+x Ctrl+f, is difficult to type. Mbork solved that writing a function to call org-emphasize with an argument * to cover his most common use. But then he bound it to Ctrl+c Ctrl+x Ctrl+8, which strikes me as just as bad, although you don’t have to specify the *.

My solution for this is to use surround.el that I wrote about here and Bozhidar Batsov wrote about here. I have it bound to Hyper+’ so it’s easy to call. I suppose you could even do as mbork did and write a specialized function for a heavily applied use case.

One thing for sure, mbork is right about markup being harder to deal with when editing.

-1:-- Markup Editing In Org Mode (Post Irreal)--L0--C0--2026-08-11T14:43:02.000Z

Raymond Zeitler: How Much Management Does Knowledge Need?

The topic of this month's Emacs Carnival interests me, even though I "dump ... notes into a directory and simply grep for information ...."0 Org does not work the way my brain works,1 or rather, my brain doesn't work the way Org works.

I do use Org. At first I created a few Org files (work.org and home.org, and maybe todo.org) thinking I could rigidly dedicate all my topics to them.

Over time I had about dozen files, one for nearly every major facet of my life until I gave up. Why? Because it really doesn't matter where I put Org TODOs and their notes. When I need to locate something, Org provides a way to search entries for a regular expression, which is what grep does, sans all that Unixy CLI stuff.

So faced with the task of paying one of my wife's medical bills, I could agonize over whether to put the task into wife.org or bills.org or medical.org.2 Or I could just:

  • establish the task somewhere,
  • act on it
  • link to a receipt
  • mark it done3

I created a special template for org-capture, which places these one-off tasks into todo.org. And it clocks into the task, too.

A topic with even greater complexity is "education." I'm a lifelong learner; my edu.org file has (only) 29 headings, all of which have at least a few subheadings. If I learn about an Emacs feature, I might want to write about it, so I'll put a task into blog.org that links to it.

Occasionally a post will span multiple topics in edu.org, topics such as Emacs, Vivaldi, LibreOffice, HTML or LaTeX. In a year from now, which file should I look for it in? The keystroke C-c a s comes to the rescue.4 I might search for "Sacha" because all I remember is that I discovered an Emacs feature on Sacha's website.5 Incidentally, I get 13 hits when I search for "Sacha," one of which was the one I had in mind.

The question I think all Emacs users face is, "At what point does tweaking Emacs (and self-quantifying tools in general) tip the scales from aiding our progress to impeding it?" I dread going down a Knowledge Management rabbit hole,6 but I'm sure I'll enjoy the leap.

0 Charlie Holland's Search for Knowledge

1 A tree works like your brain.

2 Don't even get me started on insurance.

3 All of this occurs while clocked in to the task.

4 In this case, C-c a is bound to org-agenda.

5 Sacha Chua's blog

6 Can one gain knowledge of Knowledge Management Systems without having a Knowledge Management System in which to record that knowledge? That may be a Zen koan for someone.

-1:-- How Much Management Does Knowledge Need? (Post Raymond Zeitler)--L0--C0--2026-08-10T22:19:40.478Z

Marcin Borkowski: Emphasizing a region in Org mode

One of the most basic features of Org mode is its markup. It is basically the Markdown of the Emacs world (although some people, like Karl Voit, claim that it’s superior to Markdown), and it lets do basic things like italic, bold or verbatim very easily – at least if you’re writing text. I, on the other hand, happen to edit text pretty often. This is very different from writing. When I write, typing a slash before and after something I want to emphasize is easy. When I edit and just want to make some text bold, putting stars around it is much less convenient.
-1:-- Emphasizing a region in Org mode (Post Marcin Borkowski)--L0--C0--2026-08-10T20:35:30.000Z

Irreal: Conditional Abbrevs

Protesilaos Stavrou (Prot) has another nice video on something that I was vaguely aware of but had never used: conditional abbreviations. As most Emacers know, you can define abbreviations that will expand into another, usually longer or more complicated, string. It can save a lot of time and you can set them to fire automatically or when Tab is pressed right after the abbreviation.

What’s less well known is that these abbreviations can have properties and one of those properties is to specify a function that will tell Emacs whether or not it should expand the abbreviation. Prot gives a few examples of this. In one example, he wants “Welcome” to expand to a French greeting but only if he is using one of the French input methods. Another example expands an abbreviation only if he’s in a certain directory or one of its subdirectories. A third example expands an abbreviation only if a certain minor mode is active.

Those examples might seem like they’d be complicated but they are, in fact, simple, almost trivial. In the call to define-abbrev, you simply give the name of the deciding function in the :enable-function clause. Check out Prot’s video for the details.

I use several abbreviation systems—including abbrev—but this capability in abbrev is especially nice. It’s easy to use and you can make the firing condition as simple or complex as you need it to be.

Prot’s video is 14 minutes, 33 seconds so it should be easy to find time for it. As with all of Prot’s videos, it’s worth the time.

-1:-- Conditional Abbrevs (Post Irreal)--L0--C0--2026-08-10T14:45:51.000Z

Sacha Chua: 2026-08-10 Emacs news

The Navigation category has a couple of interesting window configuration tips this week in case you prefer to work with just one window or have multiple windows with some of them dedicated to specific buffers.

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View Org source for this post

You can e-mail me at sacha@sachachua.com.

-1:-- 2026-08-10 Emacs news (Post Sacha Chua)--L0--C0--2026-08-10T13:49:50.000Z

Andros Fenollosa: Web Design for Terminal Browsers

This is a purely-for-fun exercise: a guide to web design for terminal browsers. Starting from the text browsers people actually use, I am going to pull out a set of rules in case you ever decide to build a site meant to read and look its best in a terminal. It is not an alternative to Gemini, Gopher or a smallweb attempt, but a set of best practices so your site reads well in a terminal browser, and even so you can build Web Apps for the terminal.

Five engines, one test

The first step is to install the five text engines people actually use and feed them the same test pages, isolating one feature at a time.

  • w3m (0.5.6): the most capable with tables, and it even draws images in terminals that allow it.
  • lynx (2.9.3): the patriarch, the lowest common denominator since 1992.
  • links (2.30): fast, with a little bit of CSS.
  • elinks (0.20.0): the cousin with bigger ambitions, it even has an optional CSS engine.
  • EWW: the Emacs one.

Now we look for the compatibility crossovers. You test HTML and CSS features and see how each engine interprets them.

The results:

Feature EWW w3m lynx links elinks
JavaScript No No No No No
<style> / <link> sheets No No No No Partial
display:none inline Hides Shows Shows Hides Shows
display:none by class Shows Shows Shows Shows Shows
inline color Yes (with contrast) Depends on the terminal Depends on the terminal Depends on the terminal Depends on the terminal
text-align No No No No Yes
Data tables Yes Yes Yes (no borders) Yes Yes
colspan / rowspan Yes Yes Flattens Yes Yes
Graphical images Yes In the terminal No No No
alt of a broken image Yes Yes Yes Yes Yes
srcset Yes (picks resolution) alt/src alt/src alt/src alt/src
data: URI in an image Yes alt alt alt alt
GET/POST forms Yes Yes Yes Yes Yes
Collapsible <details> No No No No No
Spacing of <article>, <section>... No No No No No
<base href> Yes Yes Yes Yes Yes
<title>, <pre>, <hr>, lists Yes Yes Yes Yes Yes

From this we draw some general conclusions:

  • JavaScript does not exist. In any of them. It is not slow or partial. There simply is no interpreter.
  • CSS is almost a mirage. Stylesheets, whether <style> or <link>, are ignored in all of them except elinks, which applies a few things like text-align. Four out of five engines do not read your CSS. Design as if it were not there.
  • display:none is a trap. If you hide something with a class (class="hidden" and .hidden{display:none} in your sheet), all five engines show it. Every one. Because they do not read the sheet: do not hide anything important with CSS. If it should not be seen, do not put it in the HTML.
  • Images are text. Only EWW (and w3m in some terminals) actually draws the image. In the rest, the image is its alt attribute. All five fall back to alt when the image is broken, and an image with no alt leaves you a [hero] with the file name, or nothing at all. alt is not accessibility for others, it is your content.
  • <details> does not fold. None of the five make it interactive. The summary and the body always show, one after the other.
  • HTML5 semantic tags are invisible. article, section, nav, header, footer, main, aside: they are transparent containers. They do not add a single line break. Their value is semantic, not visual.

With that, we can lay down a few design lines and best practices.

8 rules for publishing to the terminal

1. DOM order rules

There is no float, no flex, no grid, no order. Whatever you put first in the HTML comes first on screen. So place the content right after opening the <body> and send the long navigation and the footer to the end. A reader who opens your article does not want to tab through thirty menu links before reaching the first sentence.

2. Mark structure with tags, not styles

Real headings <h1>..<h6> for the hierarchy, never a <div class="big-title">. Lists with <ul>/<ol>, definitions with <dl>. Quotes with <blockquote>, which all of them indent. Code with <pre> and <code>. Each engine gives them its own treatment: use them for what they mean.

3. Your page must read with CSS turned off

This is the touchstone. If you disable CSS and your page becomes unreadable, it is not the terminal browser's problem, it is your HTML's problem. Spacing (margin, padding, line-height) does not exist: the separation comes from paragraphs. Structure with real <p>, not with loose <br>.

4. Do not convey information with color alone

A "required field in red" or a "green = correct" evaporate. Inline color is the most fragile thing in the table: it depends on the terminal and its configuration, and in many cases it does not even show. Always pair color with text or a symbol. An "Error:" in front, an asterisk, anything.

5. Tables for data only, never for layout

EWW and w3m draw a surprisingly good ASCII grid, colspan and rowspan included. But a layout table produces an absurd, unreadable grid. Watch the width: if the columns add up to more than the terminal's, the experience degrades. Fewer columns and short cells win.

6. Images with a descriptive alt and srcset

alt is what you see in four out of five engines. Make it a sentence, not an image1.png. And if the image is pure decoration, give it an explicit alt="": that way the reader ignores it instead of reading you the file name. A missing alt and an empty one are not the same thing. Offer srcset with several resolutions, and the engine that can show images will pick the right one. And do not rely on an image to communicate anything critical, because in most engines they do not load at all.

7. Real forms

No JavaScript submissions. A <form> with its action and its method (GET or POST), and an <input type="submit"> or a <button>. Put a name on every field: the engines collect by name, and a field without one is lost. Associate a <label> with each one.

8. Headers that do count

<title> always, descriptive: lynx and links center it at the top, and all of them use it to identify the page. <meta charset> in UTF-8 as an encoding fallback. <base> if you use relative links, which all of them respect. And serve over HTTPS, since several engines flag the certificate status.

TerminalSpeed Insights

A guide you cannot run is a list of good intentions. So I wrote a prototype. It is a Python script that reads an HTML file, or a URL, and gives you back a readability score with the specific warnings. The number is a heuristic, not a science. I hand out the points by eye, an error weighs more than a warning and that is that. What really matters is the list of warnings, not the scoreboard.

You can download it from its repository, TerminalSpeed Insights, and run it against any page:

python3 terminalspeed.py https://your-site.dev/

Running it over a few popular sites, the ones leaning more on content than design, I get some numbers:

Site Score
andros.dev (this blog) 100
text.npr.org (NPR's text-only version) 100
motherfuckingwebsite.com 100
emacswiki.org 94
suckless.org 94
gnu.org 88
man pages on man7.org 88
Wikipedia (an article) 46
Hacker News 55

At the top are the wikis, the docs, the text sites and the ones that fly the minimalism flag. At the bottom, curiously, two of the sites most loved by people who read in the terminal. It is no coincidence: the ones that score high serve the content first and lean on the tags, not on CSS. EmacsWiki, for instance, is almost plain HTML, and that is why it reads on anything that can show text.

Still, these are numbers not every browser shares. Open Hacker News in w3m and you will see the front page perfectly readable, with its numbered list of headlines, despite that 55. w3m draws tables so well that it survives. The validator is not wrong to penalize it, it flags real friction, but friction is not always a death sentence. Take the score as a guide, not a verdict: a 100 almost guarantees it reads well, a low number tells you where to look.

Not just documents: a Terminal Web App

So far I have talked about documents: articles, cards, docs pages. We still have to squeeze the forms: GET and POST work in all five engines. And a form that works is, no more and no less, an application.

Let me show you with a coffee shop:

<form action="/order" method="post">
  <p><label>Your name <input type="text" name="name"></label></p>
  <p><label>Quantity <input type="number" name="qty" value="1"></label></p>
  <p><label><input type="checkbox" name="no_milk" value="yes"> No milk</label></p>
  <p><button type="submit">Order coffee</button></p>
</form>

And this is how it looks in EWW, the Emacs browser. The fields are edited with the keyboard; here I have already filled in the name, the quantity and checked "No milk":

Coffee order form in EWW, the Emacs browser, with the name "Bob", a quantity of 2 and the "No milk" checkbox ticked, and an "Order coffee" button

You hit submit and the <form> does a POST. The server responds with a redirect (the good old Post/Redirect/Get pattern) and the browser paints the confirmation, all without leaving the keyboard or touching the mouse:

Order confirmation in EWW, the Emacs browser: "Order confirmed. Coming right up: 2 coffees without milk for Bob. Total: 2.40 EUR" with a link to place another order

Look at the detail: heading in bold, the link colored, the quantity and the no-milk option collected correctly. It is a stateful app, interactive, with no JavaScript and without a single kilobyte of framework. And yes, it scores 100 with the validator.

It is a real application: it lives in the text browser, but it looks just as good in Chrome or Firefox, because underneath there is only HTML. You get a terminal interface without touching ncurses or any TUI library. Your toolkit is HTML, your renderer is the browser and your logic lives on the server. The same app, a language you already know, and it works everywhere.

Conclusion

It has been a fun investigation. Almost nobody designs their sites for the terminal, it is a minority and, even so, it is an audience that exists. And there is no shortage of reasons: these are visitors who want accessibility or speed, who are on low resolutions or who work with pipes. More than once I have found myself doing quick searches in EWW, or reading an article there for the visual comfort.

You can take it as a curious article or as another approach to web design. I, at least, will start looking at my pages with different eyes.

I hope you enjoyed this other point of view on web design.


Help me keep writing Every coffee gives me a push toward the next article. Sure, it's on me!

Send an email to comment+article-70d817e8@andros.dev to leave a comment. The subject will be ignored.

-1:-- Web Design for Terminal Browsers (Post Andros Fenollosa)--L0--C0--2026-08-10T13:47:15.000Z

James Cherti: single-window.el – Always Open Emacs Buffers in the Current Active Window

Build Status License

The single-window package forces Emacs to open buffers in the current active window.

It keeps your carefully arranged layouts intact, reduces visual clutter, and provides a much more predictable workflow. It handles edge cases by configuring modes like org-mode (src blocks and agenda) to respect the current window.

If this project helps your workflow, please consider supporting it by ⭐ starring single-window on GitHub and sharing it on your website, blog, Mastodon, Reddit, X, LinkedIn, or other social media platforms so other Emacs users can discover its benefits.

Installation and Usage

Emacs: use-package and straight (Emacs version < 30)

To install single-window with straight.el:

  1. It if hasn’t already been done, add the straight.el bootstrap code to your init file.
  2. Add the following code to the Emacs init file:
(use-package single-window
  :straight (single-window
             :type git
             :host github
             :repo "jamescherti/single-window.el")
  :config
  (single-window-mode 1))

Alternative installation: use-package and :vc (Built-in feature in Emacs version >= 30)

To install single-window with use-package and :vc (Emacs >= 30):

(use-package single-window
  :vc (:url "https://github.com/jamescherti/single-window.el"
       :rev :newest)
  :config
  (single-window-mode 1))

Alternative installation: Doom Emacs

Here is how to install single-window on Doom Emacs:

  1. Add to the ~/.doom.d/packages.el file:
(package! single-window
  :recipe
  (:host github :repo "jamescherti/single-window.el"))
  1. Add to ~/.doom.d/config.el:
(after! single-window
  (single-window-mode 1))
  1. Run the doom sync command:
doom sync

Author and License

The single-window Emacs package has been written by James Cherti and is distributed under terms of the GNU General Public License version 3, or, at your choice, any later version.

Copyright (C) 2026 James Cherti

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program.

See also

Links

Other Emacs packages by the same author:

  • compile-angel.el: Speed up Emacs! This package guarantees that all .el files are both byte-compiled and native-compiled, which significantly speeds up Emacs.
  • outline-indent.el: An Emacs package that provides a minor mode that enables code folding and outlining based on indentation levels for various indentation-based text files, such as YAML, Python, and other indented text files.
  • easysession.el: Easysession is lightweight Emacs session manager that can persist and restore file editing buffers, indirect buffers/clones, Dired buffers, the tab-bar, and the Emacs frames (with or without the Emacs frames size, width, and height).
  • vim-tab-bar.el: Make the Emacs tab-bar Look Like Vim’s Tab Bar.
  • elispcomp: A command line tool that allows compiling Elisp code directly from the terminal or from a shell script. It facilitates the generation of optimized .elc (byte-compiled) and .eln (native-compiled) files.
  • tomorrow-night-deepblue-theme.el: The Tomorrow Night Deepblue Emacs theme is a beautiful deep blue variant of the Tomorrow Night theme, which is renowned for its elegant color palette that is pleasing to the eyes. It features a deep blue background color that creates a calming atmosphere. The theme is also a great choice for those who miss the blue themes that were trendy a few years ago.
  • Ultyas: A command-line tool designed to simplify the process of converting code snippets from UltiSnips to YASnippet format.
  • dir-config.el: Automatically find and evaluate .dir-config.el Elisp files to configure directory-specific settings.
  • flymake-bashate.el: A package that provides a Flymake backend for the bashate Bash script style checker.
  • flymake-ansible-lint.el: An Emacs package that offers a Flymake backend for ansible-lint.
  • inhibit-mouse.el: A package that disables mouse input in Emacs, offering a simpler and faster alternative to the disable-mouse package.
  • quick-sdcv.el: This package enables Emacs to function as an offline dictionary by using the sdcv command-line tool directly within Emacs.
  • enhanced-evil-paredit.el: An Emacs package that prevents parenthesis imbalance when using evil-mode with paredit. It intercepts evil-mode commands such as delete, change, and paste, blocking their execution if they would break the parenthetical structure.
  • stripspace.el: Ensure Emacs Automatically removes trailing whitespace before saving a buffer, with an option to preserve the cursor column.
  • persist-text-scale.el: Ensure that all adjustments made with text-scale-increase and text-scale-decrease are persisted and restored across sessions.
  • pathaction.el: Execute the pathaction command-line tool from Emacs. The pathaction command-line tool enables the execution of specific commands on targeted files or directories. Its key advantage lies in its flexibility, allowing users to handle various types of files simply by passing the file or directory as an argument to the pathaction tool. The tool uses a .pathaction.yaml rule-set file to determine which command to execute. Additionally, Jinja2 templating can be employed in the rule-set file to further customize the commands.
  • kirigami.el: The kirigami Emacs package offers a unified interface for opening and closing folds across a diverse set of major and minor modes in Emacs, including outline-mode, outline-minor-mode, outline-indent-minor-mode, org-mode, markdown-mode, vdiff-mode, vdiff-3way-mode, hs-minor-mode, hide-ifdef-mode, origami-mode, yafolding-mode, folding-mode, and treesit-fold-mode. With Kirigami, folding key bindings only need to be configured once. After that, the same keys work consistently across all supported major and minor modes, providing a unified and predictable folding experience.
  • buffer-guardian.el: Automatically saves Emacs buffers without requiring manual intervention. By default, it triggers a save when the user switches to another buffer, switches to another window or frame, Emacs loses focus, or the minibuffer is opened. Beyond standard file buffers, buffer-guardian also manages specialized editing buffers such as org-src and edit-indirect. Additional features, disabled by default, include periodic or idle-time saving of all buffers, automatic exclusion of remote, nonexistent, or large files, and support for custom exclusion rules via regular expressions or predicate functions.
-1:-- single-window.el – Always Open Emacs Buffers in the Current Active Window (Post James Cherti)--L0--C0--2026-08-10T12:17:11.000Z

TAONAW - Emacs and Org Mode: Emacs Config Gems - Part 4

Part four of Emacs Config Gems is about basic file operations and save functions. I realized as I was working on this that I have the frame configuration here, which is the wrong place for it. I will change it after posting. Alright, here we go.


When deleting a file in Emacs, we should use the system’s trash (or recycle bin) instead of deleting the file permanently, giving us a chance to restore the file in case we’ve made a mistake.

In addition, since we have this turned on, we can also tell Emacs to always delete non-empty directories (because they’ll go to the trash) instead of prompting. It’s just faster.

(setq delete-by-moving-to-trash t)
(setq dired-recursive-deletes 'always)

Let’s set the frame Emacs starts with to be a bit bigger. In Emacs, these measurements are in lines and columns (character width), so we’re basically saying: “make the default frame 100 characters wide and 55 lines high.”1

(setq default-frame-alist
   '((width . 100)
     (height . 55))
    )

We might want to move Emacs’ backup files and temp files (those are the ones with ~ and #)2 to a different dedicated folder (emacs-bks) instead of the main Emacs folder. Since Emacs won’t just create the directory for us, let’s ask it to do so3. It won’t throw an error if we already have it.

(make-directory "~/emacs-bks" t)
(setq backup-directory-alist
      `((".*" . "~/emacs-bks")))
(setq auto-save-file-name-transforms
      `((".*" "~/emacs-bks" t)))

Now, let’s turn on the option to automatically save files we are working on inside Emacs, and set how long Emacs needs to be idle before auto-save kicks in. In my case, 300 seconds (= 5 minutes) is good enough for idle time. Importantly, I want to emphasize again, idle time. It will not auto-save the file as long as you type, so if you type non-stop for an hour and suddenly lose power, this will not save you, since Emacs didn’t get the chance to be idle for 5 minutes (or even 30 seconds, which is the default). For this, we have auto-save-interval, which auto-saves every 300 characters (globally in Emacs) by default. In my case, I’m lowering it here to 100, since I write plenty of quick notes (using org-add-note, C-c C-z), and it’s common for me to keep using Emacs between those without hitting the 300 mark. Both of those are described in the manual under auto-saving.

(auto-save-visited-mode t)
(setq auto-save-visited-interval 300)
(setq auto-save-interval 100)

Auto-revert checks the buffer we’re visiting against the saved file itself. If the buffer has no changes, but the saved file does have changes, it loads those changes into the buffer silently. However, if the buffer has changes (meaning, we’re writing something into the file and we haven’t saved yet), it won’t do a thing and won’t say anything. Since my particular setup means that all of my org files are inside a folder synced by Syncthing, this is ideal: if I save changes to a file on my Mac, when I switch to my Linux desktop I’ll have the file and the buffer visiting it refreshed and ready to go, provided of course that Syncthing is working and the sync is complete4.

(global-auto-revert-mode t)

Activate recentf mode, so Emacs has a list of the recent files we worked on last time, up to 30 by my config. 10 is too little; 50 starts to feel more like “everything I opened this month,” which defeats the purpose. Useful when we don’t want to navigate to the same file each time, and we don’t want to have a bookmark. Note: since I’m using consult, recent files are integrated and show under the file header in the consult minibuffer, and can be quickly viewed with f while visiting the consult minibuffer.

(recentf-mode t)
(setq recentf-max-saved-items 30)

  1. There are a couple of more interesting parameters (options) to choose from. For example, alpha is a thing, if you like your windows to be translucent (and you can set it so that the frame in focus has a different degree of alpha than those out of focus). I played with it a bit, but eventually found it to be too distracting. â†©ïžŽ

  2. But what are those anyway, and why do we need them? Let’s talk about auto-save first. It’s been there since the beginning. In the early 80s (and even before), when the idea of computers always being on and connected to some virtual cloud was science fiction, people lost their data quite often, either by hardware failure, power failures, and/or user errors, like hanging up the phone in the middle of a data transfer (these were the days of dial-up modems). Auto-saving a file was a feature that was a solution to a very common problem, and we can see it in computer magazines from the era (you can see those in the internet archive, look at page 70 in this magazine for example). As for backups, it’s a similar idea, but the purpose is slightly different. Think of backup literally means “back up.” The idea here is to restore the file from before you saved, backing up (as in going back) to what it was before you touched it. This idea is more closely associated with file-versioning, which Emacs also has, but that’s a slightly different story and it’s turned off by default. To differentiate the auto-save from backup files: In Emacs, auto-saved files are the ones marked with hashtags and the backup files are the ones with a trailing tilde: #autosave-file# and last-save-file~ â†©ïžŽ

  3. There are a bunch of these helpful OS-file level functions available to us from inside Emacs. They are scattered in the Lisp manual in the file section, depending what you’re looking for. If you want a quick cheat-sheet of sorts with examples, Xah Lee has something a bit old, but still relevant↩

  4. There are other functions around revert, particularly auto-revert-avoid-polling, which is off by default. it’s a bit confusing: auto-revert-avoid-polling means, avoid automatically polling for reverting. By default, this is nil (false) which means polling is on: Emacs does its own polling to check if a file was changed every 5 seconds by default (this is determined by auto-revert-interval). If this is flipped to true, Emacs does not check the file, and instead relies on the OS file notification system (inotify in Linux, FSEvents on macOS). This is good if we want to save battery and CPU cycles: our system checks if files were changed all the time, so Emacs just relies on that. In my case, with Syncthing, this is a bad idea because the OS may or may not catch changes done by Syncthing. My Desktop is always connected to power and my Mac is usually docked so leaving it as default makes sense. Check out the manual for auto-saving↩

-1:-- Emacs Config Gems - Part 4 (Post TAONAW - Emacs and Org Mode)--L0--C0--2026-08-10T00:01:32.000Z

Raymond Zeitler: Vakana -- Sneak a Peek

I installed Donovan Ratefison's brand-new Vakana app1 on my Android device this morning. After following the tutorial, I exported the thread as an Org-mode-compatible package in a ZIP and emailed it to myself in order to transfer it to my desktop.

After opening the Org file that Vakana generated, I exported the entire buffer to HTML. The result is shown below. The only change I wanted to make was to scale the bead of each heading 25%.2

It's fortuitous that Donovan Ratefison released Vakana in a month whose Emacs Carnival theme is "The Search for Knowledge," because Vakana provides a unique way to manage one's knowledge. I'll need to become proficient in it before adding it to my workflow. So my eventual Emacs Carnival submission will be more pedestrian.


1 Learn about Vakana here or download here.

2 The images used for beads are SVG files. However this blogging platform does not support that file type, so I converted them to GIF for this post. This should explain why they don't look awesome.

Your first thread

Your first thread
A 90-second tour. Walk it bead by bead, then make it yours — delete it, or reload it anytime from Settings → Pro Tips.

1. The thread

2. Start here · a 90-second tour

[2026-08-09 Sun]

First Bead, Marked 0
Welcome — and if this is all new, that’s perfectly fine. We’ll go gently.

Vakana is the Malagasy word for beads — there’s no other word for them in the language, and it’s where this app takes its name. The idea is old and simple: you turn a moment into a small bead — a little coloured token — and beads you keep together form a thread you can walk back along, like beads on a string. (These six notes are already a thread — “Your first thread.”)

That’s the whole shape of it. What a bead means is always yours — the app never decides that for you.

This is a short, hands-on tour: five steps, each one a thing you try yourself.

Next → 1/5 · Tap the bead.

3. 1/5 · Tap the bead

[2026-08-08 Sat]

Second Bead, Marked 1
,*Tap the bead* at the top of this note — the composer opens. That’s where you pick a bead’s shape, pattern, mood-colour and a tiny glyph (this one’s is the number 1ïžâƒŁ).

Eight shapes, eight patterns, eight moods — small enough to learn, wide enough for anything. There’s no legend: a circle isn’t “an encounter” unless you decide it is.

How does the user navigate the beads? Now I see "< Prev" and "Next >" so it's obvious.

Next → 2/5 · Open the thread.

4. 2/5 · Open the thread

[2026-08-07 Fri]

Third Bead, Marked 2
You’re on a thread right now — a chain of beads strung together on purpose. Open “Your first thread” (tap its chip here, or find it in the Threads view) and you’ll see all six beads in a row you can walk, bead by bead.

The app also keeps a quiet thread for every day you write, under Days in the Threads view — built for you, no effort.

Next → 3/5 · Comment.

5. 3/5 · Comment — swipe me right

[2026-08-06 Thu]

Some thoughts arrive after the moment. Instead of rewriting a note, leave a comment in its margin.

Try it: tap the 💬 at the top of this note — or, back in your list, swipe this row to the right. Either opens the margin, where you can jot a thought or even set it to remind you later.

(The next bead, 4ïžâƒŁ, already has a comment — spot the 💬 on its row.)

Next → 4/5 · Long-press the bead.

5.1. Comments

5.1.1. Comment — [2026-08-09 Sun 18:50]

The tutorial shows an icon for comment as a white-filled rectangular balloon with three dots. However the actual icon is a balloon that's an empty circle

6. 4/5 · Long-press a bead in the list

[2026-08-05 Wed]

Fifth Bead, Marked 4
Beads repeat, and you’ll want to find a bead’s kin. This is a thing you do from your list, not from inside a note — so head back to the list first.

There, press and hold any bead: the list instantly filters to every bead like it. (Long-press is the move most people miss.)

Want finer control? Tap the funnel at the top of the list to filter by shape, mood, pattern or glyph, then gather the results into a brand-new thread.

Next → 5/5 · Make it yours.

6.1. Comments

6.1.1. Comment — [2026-08-09 Sun 18:22]

I keep coming back to this one — long-pressing a bead is the move most people miss.

6.1.2. Comment — [2026-08-09 Sun 19:14]

The alarm clock icon next to the note field is for a reminder, not a timestamp. It puts it on the next business day at 9:00 a.m., perhaps. I pressed it at 3:00 p.m. on Sunday August 9th, and then entered the reminder for the next day at 9:00 a.m..

7. 5/5 · Close it, then make it yours

[2026-08-04 Tue]

Sixth Bead, Marked 5
This thread is closed — notice the clasp. Closing marks a loop that finished; you can reopen it anytime.

A finished thread can leave the app: open it and Export to turn it into a web page or a slide deck.

That’s the whole grammar — bead, thread, comment, close, export. Now make it yours:

‱ Delete this tour — swipe any note left, or remove it in one tap from Settings → Pro Tips → Interactive tutorial. ‱ Want it back later? Reload from the same place.

Now write your first real moment, and bead it however you like.

Created: 2026-08-09 Sun 16:42

Validate

-1:-- Vakana -- Sneak a Peek (Post Raymond Zeitler)--L0--C0--2026-08-09T23:56:55.107Z

Chris Maiorana: Using ffap to jump to file includes in Emacs

Lord knows I have trouble finding files sometimes. Over the years I’ve tried lots of schemes in Org Mode and elsewhere for the sole purpose of keeping track of stray items. Using includes in Org Mode has been helpful, but I didn’t have a way of jumping to those included files for quick access. Until now! Read on.

In this article, we’ll look at:

Table of Contents

Let’s get into it.

FFAP – Find file at point

For a refresher on Org includes for those who don’t know, I’d advise clicking on that link above or watching my recent video on this topic. Basically, includes let you include file contents from elsewhere in your system into a working document.

This can be useful for gathering individual files, like sections of a book, into a master document, or including bits of code from live files as examples.

Using ffap to jump to files

However, you may have noticed, these include lines don’t resolve as hyperlinks. So you cannot simply click an included file and jump to it.

This is where you can make use of the ffap (find file at point) command. It’s an interactive function that does exactly what it says: finds the file at your point.

Emascs ffap demo
The ~ffap~ command will present your file to you if the path resolves cleanly.

If the filepath under your point resolves cleanly to a file, absolutely or relatively, you will have the option to open that file presented to you in the minibuffer.

File paths passing and failing

Here’s a rundown of how you can write out your “include” statements in various filepath styles and get the result you want. This example assumes your working directory has an Org master file, and a relative subdirectory or “chapters”. The last instance fails because there would be no such subdirectory at the root level.

Path Result
title_page.org PASS
~/Desktop/ffap-demo/chapters/chapter1.org PASS
chapters/chapter1.org PASS
/chapters/chapter1.org FAIL

If you enjoyed this little article, you may want to check out the following.

As always, thanks for reading, see you next time.

The post Using ffap to jump to file includes in Emacs appeared first on Chris Maiorana.

-1:-- Using ffap to jump to file includes in Emacs (Post Chris Maiorana)--L0--C0--2026-08-09T19:05:34.000Z

Irreal: Deskstop Save Without The Restore

Srijan Choudhary likes desktop-save-mode but he wants a slightly different behavior. He likes having his session configuration saved but he usually doesn’t want it restored. He wants to restore it only when he closed it by mistake or forget do something in the last session. Then, he wants to restore it by hand.

He could, of course, do this by disabling desktop-save-mode and calling the save and restore functions manually. The problem with that solution is that like most of us Choudhary would forget to do the save.

But this is Emacs so Choudhary was able to roll his own solution. That solution does the automatic save, as usual, but the restore function is disabled at system startup. Instead, the last save is added to a list of the last 5 saves. When he wants to restore a session, he’s presented with the list and can choose the save that he wants.

This is another great example of how Emacs lets you have it your way. His code is a little complex but there are a lot of desktop save peculiarities to account for. If you’re like me, you probably aren’t interested in this capability but that’s the point: even if you’re the only one who wants some functionality, Emacs will let you have it. This capability is something no developer is likely to anticipate so it provides another example of the superiority of Emacs’ method over the typical extension system provided by other editors.

Update [2026-08-10 Mon 10:52]: Added link to Choudhary’s post.

-1:-- Deskstop Save Without The Restore (Post Irreal)--L0--C0--2026-08-09T15:13:09.000Z

Lars Ingebrigtsen: Prehistoric Blogging Evidence

I’ve been cleaning out the loft, and I found this in a box. What kind of exciting pictures could lurk within!

Heh heh.

Right
 during the 90s, while doing Gnus development, I sold a whole bunch of merchandise. These must be the mugs for Pterodactyl Gnus?

Man, so many shots, and almost all of them out of focus. I’m a master photographer, me.

Hey, that one’s in focus
 kinda impressive height, eh?

Right, I didn’t “blog” about this until 2001, and by that time I’d bought a digital camera.

And I’ve still got a couple of mugs, almost three decades later. Quality!

The first batch had non-metallic non-dishwasher-safe printing (it turned out), so those degraded fast, but the second batch, with silver inks, is still going strong.

(Here’s a link to the other Gnus stuff I did back then
 The 90s were fun.)

-1:-- Prehistoric Blogging Evidence (Post Lars Ingebrigtsen)--L0--C0--2026-08-09T14:42:25.000Z

Sacha Chua: Replace YouTube captions from Emacs Lisp

I want to be able to easily update YouTube captions from my VTT files. Adding a comment like this:

NOTE
#+YOUTUBE_URL: https://youtu.be/sxqsIgXYkVw
#+LANGUAGE: en

to the first subtitle in my VTT file lets me programmatically replace the captions for the specified language without needing to click through the YouTube interface, saving me at least 9 clicks, a slight delay, and the selection of the file. Now I can just bind it to C-c C-c when I'm working on correcting or translating captions.

;;;###autoload
(defun sacha-youtube-replace-captions (url language vtt-file)
  "Replace captions for URL in LANGUAGE with VTT-FILE."
  (interactive
   (let ((params (and (derived-mode-p 'subed-vtt-mode)
                      (sacha-subed-record-youtube-params))))
     (list
      (or (plist-get params :url)
          (read-string "YouTube URL: "))
      (or (plist-get params :language)
          (read-string "Language (ex: fr): "))
      (if (derived-mode-p 'subed-vtt-mode)
          (buffer-file-name)
        (read-file-name "VTT file: ")))))
  (let* ((video-id (sacha-org-yt-id url))
         (existing-captions (sacha-youtube-get-captions video-id))
         (boundary "---------------------------sacha_yt_caption_boundary"))
    (dolist (item existing-captions)
      (let ((snippet (alist-get 'snippet item)))
        (when (string= (alist-get 'language snippet) language)
          (sacha-youtube-delete-caption (alist-get 'id item)))))
    (let* ((metadata (json-encode `((snippet . ((videoId . ,video-id)
                                                (language . ,language)
                                                (name . ,language))))))
           (text (with-temp-buffer
                   (insert-file-contents vtt-file)
                   (buffer-string)))
           (body (concat "--" boundary "\r\n"
                         "Content-Type: application/json; charset=UTF-8\r\n\r\n"
                         metadata "\r\n"
                         "--" boundary "\r\n"
                         "Content-Type: text/vtt\r\n\r\n"
                         (encode-coding-string text 'utf-8) "\r\n"
                         "--" boundary "--\r\n"))
           (response (request-response-data
                      (request "https://www.googleapis.com/upload/youtube/v3/captions?uploadType=multipart&part=snippet"
                        :type "POST"
                        :headers `(("Authorization" . ,(format "Bearer %s" (sacha-google-access-token)))
                                   ("Content-Type" . ,(format "multipart/related; boundary=%s" boundary))
                                   ("Accept" . "application/json"))
                        :data body
                        :sync t
                        :parser #'json-read))))
      (message "Uploaded.")
      response)))

(defun sacha-youtube-get-captions (video-id)
  "Return the list of existing caption tracks for VIDEO-ID."
  (let ((response (request-response-data
                   (request (format "https://www.googleapis.com/youtube/v3/captions?part=snippet&videoId=%s" video-id)
                            :headers `(("Authorization" . ,(format "Bearer %s" (sacha-google-access-token))))
                            :sync t
                            :parser #'json-read))))
    (alist-get 'items response)))

(defun sacha-youtube-delete-caption (caption-id)
  "Delete the caption track identified by CAPTION-ID."
  (request (format "https://www.googleapis.com/youtube/v3/captions?id=%s" caption-id)
           :type "DELETE"
           :headers `(("Authorization" . ,(format "Bearer %s" (sacha-google-access-token))))
           :sync t))

(defun sacha-subed-record-youtube-params ()
  "Return directives related to YouTube."
  (save-excursion
    (goto-char (point-min))
    (unless (subed-subtitle-msecs-start) (subed-forward-subtitle-start-pos))
    (list
     :url (subed-record-get-directive "#+YOUTUBE_URL")
     :language (or (subed-record-get-directive "#+LANGUAGE")
                   (progn (goto-char (point-min))
                          (when (re-search-forward "^Language: \\(.+\\)\n" (or (save-excursion (re-search-forward "\n\n" nil t))
                                                                               (point-max)))
                            (match-string 1)))))))

The code uses some functions defined elsewhere in my configuration:

This is part of my Emacs configuration.
View Org source for this post

You can e-mail me at sacha@sachachua.com.

-1:-- Replace YouTube captions from Emacs Lisp (Post Sacha Chua)--L0--C0--2026-08-09T14:11:30.000Z

Donovan R.: 🚀 Vakana.mg mobile app is now available

The Vakana.mg wordmark

After months of cooking, I am happy to announce that the mobile app is now
available for download at https://vakana.mg.

Some highlights

  1. Fully offline. No ads, no data held hostage. Your data, your rules.
  2. Flexible exports: Export your threads and beads to HTML (from
    templates), Markdown format (e.g., Obsidian), or rich Org files for Emacs
    users.
  3. Built-in inspiration: Includes a list of use cases and possibilities.
    Find one that fits you.

Feel free to explore and share with friends.

The Vakana.mg app lock screen with the mala logo Your beads of life, laid out as a journal timeline The calendar view, a book of days Threads of life, grouped into collections A thread rendered as a looping bead chain Export a thread to Org, Markdown, HTML, PDF, or Slides
-1:-- 🚀 Vakana.mg mobile app is now available (Post Donovan R.)--L0--C0--2026-08-09T12:37:59.000Z

Protesilaos: Emacs: conditionally expand abbrev-mode definitions

Raw link: https://www.youtube.com/watch?v=QzhU6fklc4o

In this ~15-minute video I show how to add conditions to abbrev-mode abbreviations that you define. The idea is to have those abbrevs expand only in certain cases. I use three examples, which I think cover the common needs.

Code samples

(defun my-french-p ()
  "Return non-nil if `current-input-method' is French."
  (and current-input-method
       (string-match-p "french" current-input-method)))

(define-abbrev global-abbrev-table "welcome" "je t'en prie" nil :enable-function #'my-french-p)


(defvar my-notes-directory (expand-file-name "~/.emacs.d/abbrev-test/")
  "Directory where my notes are.")

(defun my-notes-directory-p ()
  "Return non-nil if we are in `my-notes-directory' or its subdirectories."
  (let ((current-directory (expand-file-name default-directory)))
    (string-prefix-p my-notes-directory current-directory)))

(define-abbrev global-abbrev-table "prot" "p’rǒt" nil :enable-function #'my-notes-directory-p)


(defun my-notes-keycast-mode-p ()
  "Return non-nil if `keycast-mode-line-mode' is enabled."
  (bound-and-true-p keycast-mode-line-mode))

(define-abbrev global-abbrev-table "prot" "Protesilaos, also known as Prot" nil :enable-function #'my-notes-keycast-mode-p)
-1:-- Emacs: conditionally expand abbrev-mode definitions (Post Protesilaos)--L0--C0--2026-08-09T00:00:00.000Z

Irreal: A Customized Agenda View

Ashish Panigrahi has an interesting post on customizing his agenda view. He’s a graduate student, apparently in the sciences, and has to keep track of his tasks and their statuses. The natural solution for us Emacsers is to use Org mode and the agenda view to track these things.

There’s nothing exciting about that, of course, but what makes his post interesting is that he shows how to create a custom agenda view. It’s easy to make a custom view and I have a lot of them but they’re pretty simple. Panigrahi views are more complex and he demonstrates how to specify more intricate criteria for the view.

For his main view, he wants to show tasks that he’s completed since his last group meeting. That means he wants to filter for tasks completed in the last 7 days that aren’t personal items. He also wants to keep tags, so he makes sure they aren’t removed.

Finally, since he often consults this view, he has a function that calls it with a simple Ctrl+c w rather than having to go through the agenda dispatch menu.

As I said, you probably won’t care about his particular view but it’s instructive to see how he defined it as a jumping off place for your own views.

-1:-- A Customized Agenda View (Post Irreal)--L0--C0--2026-08-08T14:46:47.000Z

Irreal: Emacs 31 And The Speedbar

Protesilaos Stavrou (Prot) has another excellent video. This time it’s on it’s on the Emacs speedbar and its Emacs 31 upgrade. The TL;DR is that as of Emacs 31, you can configure the speedbar to be displayed in a separate window instead of a separate frame. The video is 15 minutes, 39 seconds so it should be easy to find time for it.

The placement of the speedbar matters a lot to Prot. He found the speedbar to be unusable when it was displayed in a separate frame because it was difficult to deal with the two related frames. It’s absolutely impossible for me to deal with because I run Emacs as a full screen app so the speedbar is in another workspace and I have to switch to that workspace to see it.

Now that the speedbar can be displayed in the same frame, Prot finds that it can be useful when dealing with large projects with many files. His video is mostly concerned with showing how the speedbar works and what you can do with it.

Lots of people love speedbar-like applications and swear by them. I, however, have never been able to warm up to them. These days, I don’t work with large projects and perhaps I’d feel differently if I did but mostly they just seem like noise to me. Even Prot says he doesn’t use speedbar for his smaller personal projects but that it can be useful for larger, multi-file projects.

My recommendation is that if you don’t already strong opinions on the matter, give the speedbar a try when Emacs 31 comes out and see if it works for you. There are plenty of informed opinions on both sides of the issue so there’s no right answer, just what works for you. As always, Emacs will let you have it your way.

-1:-- Emacs 31 And The Speedbar (Post Irreal)--L0--C0--2026-08-07T14:27:46.000Z

Dave's blog: Run the file in Emacs’ dired

I started going through the The Rust Programming Language to learn rust. I’m using the rustic package to edit files, run cargo, etc.

Having run cargo build in the sample hello_cargo project, I wanted to run the executable file from within Dired. I realized there’s no obvious way to do this in Dired or Dired-X, and that’s probably a good thing. If it was easy I can imagine all sorts of havoc with people accidentally, or intentionally, runnning files out of Dired. Too easy.

But it occurred to me that bash has command to run the next word in the command line as a command. I tried ! command in Dired, but since the directory isn’t in the path, it told me

/bin/bash: line 1: hello_cargo: command not found

Okay, update PATH before running command: ! PATH=.:$PATH command. This actually works, but decades of training give me a queasy feeling about adding . to PATH. How about $PWD instead? ! PATH=$PWD:$PATH command. Yep, that works too.

But of course, with rustic, I can use C-c C-p r to run cargo run to run the command. But trying to run the file on the line in Dired was an interesting diversion!

-1:-- Run the file in Emacs’ dired (Post Dave's blog)--L0--C0--2026-08-07T00:00:00.000Z

Sacha Chua: Emacs Chat avec Richard Bonichon en français

Prot et moi avons parlé en direct avec Richard Bonichon (emacs.d, GitHub) d'Emacs, d'OCaml, de ses flux de travail, de sa configuration et d'autres sujets en français.

J'ai ratĂ© le dĂ©but de la diffusion en direct. Je suis vraiment dĂ©solĂ©e ! Heureusement, j'ai enregistrĂ© toute la conversation localement. Voici la vidĂ©o complĂšte :

J'ai essayé de corriger la transcription (voici le fichier VTT), mais je crois qu'il y a encore beaucoup d'erreurs, donc n'hésitez pas à m'envoyer un message.

Merci beaucoup Ă  Richard, Ă  Prot, et Ă  tous les auditeurs ! À la semaine prochaine pour le 13 aoĂ»t : Emacs Chat avec Fabrice Niessen !

Si vous voulez parler d'Emacs avec Prot et moi en français, n'hésitez pas à me contacter!

La transcription un peu corrigée

Details

Prot: Comment on dit « chat » en français ? Parce que je n'ai pas chat.

Richard: Non, on dit chat.

Prot: Ah, on dit chat. D'accord. C'est facile.

Sacha: Bonjour à tous et à toutes et bienvenue dans ce tout premier épisode d'Emacs Chat en français. J'ai hùte de converser avec notre invité, Richard Bonichon, pour parler d'Emacs, d'Org Mode et d'autres sujets. Comme dans l'épisode d'Emacs Chat en anglais, j'espÚre que nous pourrons explorer les choses qui ne sont pas évidentes, rien que sa configuration ou son code, comment utiliser et combiner les fonctions dans vos flux de travail les raccourcis clavier le plus utiles, les astuces. J'espÚre aussi que nous pourrons tous rencontre les personnes passionnées qui font vivre la communauté Emacs. Bonjour Richard, merci beaucoup d'avoir accepté mon invitation.

Richard: Le plaisir, c'est pour moi, en fait, de vous rencontrer tous les deux, en réalité. J'avoue que j'ai accepté en me disant, en voyant tes efforts, Sacha, pour écrire en français et apprendre le français. Et si je pouvais t'aider un tout petit peu avec tout ce que tu donnes à la communauté Emacs, et donc à moi, en t'aidant en français, alors c'est un plaisir de le faire.

Sacha: Et merci aussi à Prot de nous rejoindre pour m'aider à garder une conversation fluide et m'épauler si jamais je me retrouve bloquée par la barriÚre de la langue. Je vais vous présenter mes excuses d'avance. Je ne suis qu'une débutante en français qui a envie de vidéos intermédiaires sur Emacs, que je puisse écouter mille et une fois. Donc voilà mon plan diabolique. En français, salut Prot!

Prot: Salut Sacha, salut Richard. Allons-y, on va parler.

Sacha: Vous ĂȘtes prĂȘts ? Oui. C'est parti. Tout d'abord, Richard, peut-ĂȘtre vous prĂ©senter ?

Richard: Oui, alors moi, je suis Richard Bonichon, donc je suis français et je suis un utilisateur d'Emacs depuis bien longtemps. Je peux raconter un peu l'histoire, comment ça est arrivĂ©. Ça a commencĂ© en Ă©cole d'ingĂ©nieur. Donc en France, les Ă©tudes... Pas souvent en dehors de l'universitĂ©, donc par des Ă©coles dĂ©diĂ©es, des Ă©coles d'ingĂ©nieurs. Et lĂ , on devait choisir. Et Ă  l'Ă©poque, on nous avait encouragĂ© Ă  choisir entre Vi et Emacs sous Solaris. Et plus exactement, c'Ă©tait l'Ă©poque, il fallait prendre X et Emacs. Fin des annĂ©es 90, dĂ©but des annĂ©es 2000, il y avait encore ces deux choix. Moi, j'ai fait des Ă©tudes d'informatique. Aujourd'hui, je suis ingĂ©nieur, programmeur, ingĂ©nieur logiciel aprĂšs avoir Ă©tĂ© chercheur pendant trĂšs longtemps dans le domaine des mĂ©thodes formelles, des langages de programmation. Et mon langage de programmation prĂ©fĂ©rĂ©, c'est OCaml. Et dans la communautĂ© OCaml, l'Ă©diteur, jusqu'Ă  maintenant ça change un peu, l'Ă©diteur de prĂ©dilection pendant trĂšs longtemps, c'Ă©tait Emacs. Parce que c'est lui qui avait le meilleur support pour le langage Ă  travers le mode Tuareg et le mode Caml. Et donc, quand j'apprenais au niveau acadĂ©mique dans mon domaine, tous mes encadrants utilisaient Emacs pour coder en Caml. C'est lĂ  que le choix dĂ©finitif s'est fait et ça n'a fait que s'empirer entre guillemets. AprĂšs, j'ai commencĂ© Ă  creuser moi-mĂȘme et en particulier... GrĂące Ă  toi, Sacha, grĂące Ă  la newsletter hebdomadaire que tu fournis, parce que ça permet de perdre un temps fou dans tout ce que font les gens sur Emacs et d'aller voir comment ça se fait, ce qu'il y a de nouveau, essayer un nouveau mode ou un nouveau environnement tout le temps. Et j'ai aussi passĂ© le virus aprĂšs Ă  mes Ă©tudiants, donc les encourager Ă  utiliser Emacs et tout ce qu'il y avait dans Emacs, en particulier Org Mode et Magit, qui sont deux points d'entrĂ©e super importants et incroyables en termes de qualitĂ© pour utiliser Emacs. Et donc, il y en a d'autres qui l'utilisent. Mais je suis un maximaliste, moi, plutĂŽt. On pourra en reparler.

Sacha: Tu utilises Emacs pour ton travail, ton enseignement à l'université avec tes étudiants.

Richard: Oui, quand j'enseignais, j'ai montrĂ© tout le temps Emacs. Quand je montrais du code, c'Ă©tait dans Emacs. Quand je composais mes slides, ma prĂ©sentation, c'Ă©tait avec Emacs, avec Beamer et LaTeX. Et puis Org Mode, via LaTeX et Beamer. En fait, je l'utilise. J'ai trois fenĂȘtres en gĂ©nĂ©ral dans mon OS. J'ai Emacs, un navigateur. Et peut-ĂȘtre un terminal, mais les terminaux maintenant passent essentiellement dans Emacs Ă  travers les diffĂ©rents modes qu'on a, enfin les diffĂ©rentes capacitĂ©s, que ce soit Eat, Vterm ou Eshell.

Sacha: En lisant ta configuration, j'ai noté que tu as beaucoup de fonctions personnalisées pour Eshell. Donc, tu as bien utilisé ?

Richard: Oui, alors je les ai, comme une bonne partie de ma configuration, je les ai un peu volés des gens. Et notamment, je pense que pour Eshell, ça vient de deux personnes en particulier. Howard Abrams, qui à un moment avait une série de posts incroyables sur l'utilisation d'Org pour documenter et réexécuter tout ce qu'il faisait en DevOps, et notamment parler d'Eshell. Et probablement de John Wiegley, si je ne me trompe pas. Donc, j'ai récupéré des aliases qu'ils avaient et en fait, j'ai toujours cette envie de l'utiliser et à chaque fois, je retombe sur un autre. Mais il est toujours là dans un coin et il est assez personnalisé mais son usage est minimal, j'avoue.

Sacha: Mais tu as une vie de commande trĂšs complexe.

Richard: Oui, mais ça c'est pareil. C'est comme beaucoup de trucs, tu sais. C'est l'avantage des communautĂ©s ouvertes, c'est qu'on prend quelque chose et puis on le modifie et ça devient le nĂŽtre. Et c'est ça qui est super, en fait, dans Emacs en particulier, mais dans les communautĂ©s ouvertes et open source en gĂ©nĂ©ral, c'est d'avoir accĂšs Ă  toutes ces ressources et souvent d'avoir des gens qui les partagent gratuitement. C'est incroyable quand mĂȘme ça.

Prot: Et c'est l'esprit d'Emacs comme ça, de prendre quelque chose et de modifier pour faire ce que tu veux.

Richard: Exactement. Ah bah oui, ça c'est clairement... Mais ça, ça me parle beaucoup en plus en tant que programmeur. C'est vraiment adaptĂ© Ă ... Alors j'ai essayĂ© d'autres IDE de programmation dans les environnements de dĂ©veloppement. Le seul qui trouve un peu grĂące Ă  mes yeux, c'est le concurrent principal d'Emacs, dans ma tĂȘte en tout cas, c'est la famille Vim, parce que je comprends aussi, mais je me sens Ă  chaque fois extrĂȘmement gĂȘnĂ©, restreint et contraint dans un idĂ©al, mĂȘme dans Visual Code ou ce genre de choses, je me sens... Mal Ă  l'aise. Comment dire ? Je ne sais pas. Il y a trop de choses et on me contraint trop Ă  faire les choses de la maniĂšre dont on les a pensĂ©es et pas autrement. Et je ne comprends pas comment les adapter en plus. Je sais comment adapter les choses. Ce sont que des fonctions. Donc ça, ça me parle en tant que programmeur fonctionnel. Emacs Lisp, c'est trĂšs proche de ma maniĂšre de penser. J'ai une formation aussi de mathĂ©maticien, bien sĂ»r. Ça me parle trĂšs fort. C'est un langage qui est trĂšs, trĂšs proche dans beaucoup d'aspects de OCaml. Il est Ă  la fois fonctionnel, mais impur. On peut faire beaucoup d'effets, de bords, comme on dit, de changement de structure de donnĂ©es. Et il n'y a pas le typage. Mais c'est autre chose, un autre dĂ©bat.

Prot: Et tu préfÚres les modÚles OCaml comme ça ou les modÚles d'Emacs?

Richard: Alors, sincĂšrement, le langage oĂč je me sens le mieux quand je programme, oĂč je me sens bien, c'est OCaml. Clairement, ça fait 20 ans, plus de 20 ans que j'utilise et ça me fait plaisir. Je pense que vous connaissez ça tous les deux, mais il y a des moments oĂč on a du plaisir Ă  ĂȘtre dans un outil ou dans un monde qu'on connait. Et OCaml, je connais sur le bout des doigts quoi je connais par cƓur. Je prĂšfĂšre, j'aime moi le typage. Moi, je suis un programmeur qui assume qu'il va faire des erreurs. Le type m'aide en enlever une partie Ă  rĂ©flĂ©chir et Ă  structurer ma pensĂ©e. C'est un avis comme un autre, mais pour un Ă©diteur, par contre, le modĂšle d'Emacs Lisp a quand mĂȘme des avantages. Je ne sais pas comment ça s'est passĂ©, mais il se trouve que c'est quand mĂȘme bien, les deux se complĂštent bien. Le langage dans un Ă©diteur, ce langage-lĂ  dans un Ă©diteur, la famille Lisp, c'est pas mal.

Sacha: En lisant ta configuration, j'ai aussi noté que tu affiches les informations du mode line dans le header line. Est-ce que c'est plus pratique pour toi?

Richard: Oui, en fait, j'ai tendance à regarder en haut, dans mon buffer. Et j'avais vu, je pense que j'ai pris ce truc-là d'un autre francophone. Donc j'ai oublié le prénom, c'est Rougier. Et c'est de là que j'ai volé cette idée. Je suis un grand voleur, vous savez.

Sacha: Tout le monde.

Richard: Oui, on rĂ©cupĂšre les idĂ©es. Et c'est restĂ©. VoilĂ , c'est quelque chose que j'ai mis en place et c'est restĂ©. Ça me plaĂźt bien.

Prot: Voler à volonté.

Richard: Ouais, ouais. Et en fait, c'est bien que vous m'ayez un peu forcé à mettre ma config pour ce qu'elle a d'intéressant en public. Comme ça, les autres vont pouvoir voler s'ils veulent. C'est trÚs bien comme ça.

Sacha: Je vois que tu as tant de bibliothÚques. Il y en a une qui prépare un rapport sur tes journées de travail. Il y a une autre qui extrait des offres d'emploi sur une page. Un troisiÚme analyse les données Garmin en utilisant l'IA pour générer un rapport au format Org Mode. Tu peux nous en dire plus ? Quelle est ta fonctionnalité préférée ?

Richard: Ah, de celle-lĂ  ? Alors, c'est le mode Garmin. C'est le dernier que j'ai mis en place. Donc, moi, je fais pas mal de courses Ă  pied. J'aime bien ça. Et puis, ça me permet de... Moi, c'est lĂ  oĂč je fais de la mĂ©ditation, la course Ă  pied. Je vais courir et puis je pense... Vous savez, quand on est sous la douche ou quelque chose comme ça, on a des idĂ©es qui arrivent, la course Ă  pied, c'est Ă  se faire la mĂȘme chose et puis ça maintient en forme. C'est pas plus mal de prendre un peu soin de sa santĂ© quand on peut. Donc j'ai beaucoup de donnĂ©es Garmin et ça commençait Ă  m'embĂȘter de devoir aller sur le site de Garmin et puis pas adapter Ă  ce que je veux faire. Encore une fois, c'est toujours la mĂȘme idĂ©e et que mes donnĂ©es ne soient que lĂ  parce que c'est mes donnĂ©es. Le premier rĂ©flexe pour moi, c'est comment je peux les visualiser d'une maniĂšre cool sous Emacs. Pour moi, Org Mode, forcĂ©ment, il faut un truc textuel, donc sous Emacs et Org Mode, parce que pour moi, c'est liĂ©. Et oui, j'ai fait ça Ă  l'aide avec Claude, Ă©videmment, comme beaucoup de gens Ă  l'heure actuelle. Et c'est ça aussi qui est cool dans Emacs, c'est qu'on a pu analyser toute la base de code d'Elisp. Il sait faire ça raisonnablement bien. Oui, il y a plusieurs petits outils. Il y a un bout de code Rust pour extraire en mode JSON les donnĂ©es du format fit de Garmin parce qu'il y a une bonne bibliothĂšque en Rust tout simplement. Puis je fais du Rust en ce moment, donc voilĂ . C'est pratique. C'est un langage que j'aime bien. Donc ça, ça fait du JSON. Et aprĂšs, une fois qu'on a du JSON, on est bien dans Emacs. On n'a plus besoin... J'ai dĂ©cidĂ© de ne pas tout faire en Elisp. La fonction d'extraction du feed ne paraissait pas... J'ai essayĂ© de demander beaucoup plus de codes que nĂ©cessaire pour mon usage. AprĂšs, j'ai mis en place une pagination. Je savais que je voulais utiliser le mode tabulated pour les mettre en format colonne. Dans le passĂ©, j'avais dĂ©jĂ  utilisĂ© le docker mode. pour gĂ©rer plusieurs dockers. Et j'ai trouvĂ© ça gĂ©nial d'ĂȘtre dans Emacs et de gĂ©rer ces dockers, avoir une interface assez simple et d'avoir des raccourcis pour les lancer, les arrĂȘter. Et je me dis, mais c'est ça qu'il me faut. Moi, par moi, une page, je peux lancer l'analyse, parce que j'utilise aussi Claude pour essayer d'analyser mes entraĂźnements, etc. Et les analyser en Org Mode et les avoir, en fait, et avoir le journal de course Ă  pied. Automatiquement gĂ©nĂ©rĂ©, l'app en Elisp. Je pense que ça, je l'utilise tous les jours maintenant. Enfin, tous les jours, je vais courir en tout cas. Et les autres, c'est sympa aussi. Alors, les rapports, c'est parce qu'Ă  une Ă©poque, on demandait encore hebdomadaire sur mon activitĂ©.

Sacha: J'ai oublié de presser le bouton go live.

Prot: Ah non !

Sacha: Je dois présenter toutes mes excuses... J'ai totalement oublié le bouton...

Prot: Pas grave, pas de souci, pas de problĂšme.

Sacha: On recommence. Comment en français on dit que la premiÚre edition, c'est pour essuyer les plùtres. Quand on refait un mur, il faut que nettoye. [??]

Prot: Ouais, ouais, trĂšs bien.

Richard: On pourra recommencer.

Sacha: Donc, je ne répÚte pas mon introduction. Tu racontes une histoire fascinante de ses données de Garmin et...

Richard: Je peux recommencer, on recommence. Pas de souci, je peux raconter. On peut commencer directement lĂ -dessus. J'y vais ? La derniĂšre chose pour laquelle j'ai choisi Emacs et que j'aime bien, c'est pour crĂ©er un mode pour extraire, pour gĂ©rer les donnĂ©es de ma montre Garmin. J'ai un cĂŽtĂ© maximaliste, donc j'envisage Emacs comme l'endroit oĂč je vais gĂ©rer mes donnĂ©es et je vais les visualiser et qui va orchestrer. C'est vraiment mon OS en rĂ©alitĂ©. Quand nos copains qui sont plutĂŽt adeptes de Vim parlent d'Emacs comme un super OS, j'utilise vraiment comme ça. En fait, c'est l'orchestrateur et c'est lĂ  que je vois mes donnĂ©es. Et pour Garmin, j'ai pensĂ© immĂ©diatement Ă  Emacs et derriĂšre Ă  Org Mode pour les voir en textuel. C'est un orchestrateur entre un petit programme Rust qui fait le traitement de la donnĂ©e brute en format fit de Garmin, qu'il extrait en JSON, et c'est ça qui est aprĂšs analysĂ© en Emacs. Retravailler pour avoir une visualisation Org Mode avec un tableau kilomĂštre par kilomĂštre, les allures, la frĂ©quence cardiaque, etc. MĂȘme un petit... Je crois qu'il y a un petit bout qui est censĂ© faire des graphes aussi. Je ne l'utilise pas trop avec Gnuplot. Je ne sais pas si j'ai bien demandĂ©, si ça marche. Je n'ai pas trop testĂ©. Mais l'idĂ©e, c'est vraiment d'avoir tout ce que je trouve intĂ©ressant de chez Garmin dans un fichier Org Mode. Donc avec la capacitĂ© de le voir localement. Via Emacs. Quand je raconte ce genre de choses Ă  mes Ă©tudiants ou mes amis, ils me disent toujours, je ne suis pas trop Ă©tonnĂ© de tes choix. Quand on me connaĂźt, que je fasse des choses et que ça passe par Org Mode, les gens commencent Ă  ne plus ĂȘtre trop Ă©tonnĂ©s. J'adore cette idĂ©e-lĂ . En fait, c'est tellement... Chouette. J'aime bien l'idĂ©e que tout soit en texte, qu'on ait tout autour une gamme d'outils, que ce soit pour faire comme Prot avec Denote ou ce genre de choses. On a des outils autour qui permettent d'utiliser ce format qui a dĂ©jĂ  Ă©tĂ© super bien pensĂ© et qui avait dĂ©jĂ  beaucoup de capacitĂ©s, l'agenda, etc. Moi, j'y pense toujours. Je l'utilise aussi, l'agenda. Je diverge un peu. DĂ©solĂ©, je reviens au mode Garmin. Donc, j'ai une page par mois avec toutes mes sorties, savoir si elles ont Ă©tĂ© analysĂ©es. Je peux lancer l'analyse par IA aussi de ma progression ou de ma rĂ©gression. Ça arrive aussi. De ce que je devrais faire, de ce qu'ils pensent que je devrais faire. Alors, petit secret, j'arrive quand mĂȘme assez systĂ©matiquement Ă  convaincre l'IA que c'est bien ce que je fais et qu'elle a tort. Elle arrive toujours Ă  se faire convaincre que ça a du sens ce que je fais. Donc l'orchestrateur, une page par mois dans le mode tabulated pour avoir des petites visualisations aussi, ça a Ă©tĂ© analysĂ©. Je peux marquer, j'ai rajoutĂ©, je ne sais pas si je l'ai poussĂ©, j'ai rajoutĂ© des marqueurs. Ça, c'est une sĂ©ance de rĂ©fĂ©rence. Si, par exemple, il y avait un test ou une allure particuliĂšre qui est importante dans l'entraĂźnement, je peux marquer cette chose-lĂ . Donc, il y a une petite base de donnĂ©es. Il y a des mĂ©tadatas en format .el, je crois, essentiellement une S-expression, pour rajouter des donnĂ©es perso au-dessus des donnĂ©es extraites de Garmin en plus. Donc qui est lu par Emacs puisque les donnĂ©es sont dans un rĂ©pertoire et il y a ces donnĂ©es lĂ  aussi. Une mini base de donnĂ©es qui est juste en fait une... Pas une, c'est juste une donnĂ©e Lisp, quoi. Ça, c'est un exemple. Des trucs qui sont super chouettes en Lisp, c'est qu'on prend un fichier, on a juste la S-expression, il n'y a pas de diffĂ©rence, les donnĂ©es, le programme. Ça, c'est un truc pratique pour travailler sur les donnĂ©es ou les choses.

Sacha: C'est le pouvoir de Lisp.

Richard: Exactement, mais c'est pour ça que je dis que je pense que c'est un cas d'usage oĂč Lisp est particuliĂšrement bien adaptĂ©. Je vois les langages de programmation comme ayant tous des capacitĂ©s quand mĂȘme plus ou moins particuliĂšres. Je n'utiliserais pas, par exemple, mĂȘme si on a discutĂ© oĂč OCaml Ă©tait mon langage prĂ©fĂ©rĂ©, je ne l'utiliserais pas pour un Pour un tas de choses. Il y a des langages qui sont plus adaptĂ©s. MĂȘme si je veux faire des scripts, par exemple, un peu Ă  jeter, j'aurais quand mĂȘme tendance Ă  faire du Python, personnellement, malgrĂ© tout. MĂȘme si c'est possible, il n'y a pas tout le reste. Il manque des choses.

Sacha: Et parce que tu utilises Emacs pour créer une interface personnalisée avec le Tabulated et d'autres modules, tu peux créer ton interface dans tout ton flux de travail et tu peux aussi annoter tes données avec Org Mode.

Richard: Exactement. Et je peux les rechercher aprÚs avec les tags, comme ça se fait, ou avec les outils standards, Unix, Grep, RG, ce que vous préférez. Tout ça, c'est trÚs bien intégré dans Emacs, donc il n'y a pas besoin de sortir de son monde.

Prot: Est-ce que tu utilises l'agenda aussi pour chercher ces données ?

Richard: Ah, pour chercher ces donnĂ©es ? Non. L'agenda, je suis tombĂ©, j'ai beaucoup limitĂ© son usage. J'ai restreint sur quelques fichiers simplement. Peut-ĂȘtre Ă  tort, mais justement, je suis prĂȘt Ă  changer s'il y a des usages que je n'utilise pas trop. Ça fait partie des fichiers exclus parce que je commence Ă  avoir beaucoup de fichiers de notes diverses et variĂ©es sur des sujets. Et les sĂ©ries d'entraĂźnement, elles sont classĂ©es dans un sous-rĂ©pertoire de ces notes. qui sont pour l'instant indexĂ©s avec org-roam, mais j'utilise de plus en plus RG pour chercher dedans parce que des fois je cherche du contenu, pas les tags ou le titre. De toute façon, ce n'est pas indexĂ© dans la base SQLite de org-roam.

Prot: D'accord.

Sacha: Tu utilises Org Super Agenda. Oui. En disant ta configuration d'Org Mode, je suis trĂšs curieuse parce que tu as une vue d'agenda qui a 27 sections. Oui. Vraiment, ton Super Zaen View.

Richard: C'est peut-ĂȘtre une forme de paresse, mais j'aime bien avoir toute l'information en une fois et donc j'ai pas mal de filtres sur... Est-ce que ça s'agit d'une entreprise ? Est-ce que c'est pour l'entreprise ? Est-ce que c'est pour la maison ? Est-ce que c'est pour le travail mais pas pour l'entreprise ? Donc, Ă  la fin, on arrive avec beaucoup de catĂ©gories. Et vous savez, c'est des choses qui ne font que s'accumuler. Donc, c'est une fonction monotone croissante. J'en ajoute, mais j'en enlĂšve jamais. Ça manque de garbage collection. Il faudrait peut-ĂȘtre que je fasse une passe. Pour enlever des choses, il y a effectivement des choses sur dans combien de jours qui filtrent sur la deadline, le schedule. Il y a des choses qui filtrent sur la prioritĂ©. Il y a des choses qui filtrent sur le tag. LĂ , ça me convient Ă  peu prĂšs. Du coup, je n'ai pas trop rĂ©flĂ©chi Ă  faire mieux, mais c'est possible que ce soit un peu trop fort.

Sacha: Je pense que tu aimes distinguer les donnĂ©es par couleur. Tu as configurĂ© Dired, Elfeed, les prioritĂ©s d'Org Mode pour colorier les entrĂ©es selon le format ou par les Ă©tiquettes. Qu'est-ce que ça donne? Peux-tu nous montrer peut-ĂȘtre sur Elfeed?

Richard: Oui. Attends, je vais... Et puis c'est lĂ  que ça va ĂȘtre intĂ©ressant parce que j'utilise Wayland. Alors c'est toujours le suspense sur le partage d'Ă©cran.

Sacha: Pas de souci.

Richard: Mais pas de souci. J'ai pas de souci Ă  partager mon Ă©cran. On va voir. User operating system settings. Ok. Il va partager l'Ă©cran. Je vais essayer de nous mettre sur un autre. On va se mettre lĂ . VoilĂ  le flux. En fait, les couleurs, elles sont assez... C'est faiblement visible lĂ , comme c'est trĂšs grand. Donc c'est surtout des soulignĂ©s que j'utilise, des petites couleurs. Je ne suis pas sĂ»r d'y prĂȘter tant attention que ça. Au final. Mais oui, c'est restĂ©. C'est assez pareil. C'est pris du crĂ©ateur d'Elfeed. J'avais pris de lĂ . Je trouve que c'est ça. Moi, j'aime bien ce que ça donne en termes visuels. Je ne vais pas le changer. Donc lĂ  j'utilise un des modes fait par Prot justement. Un des modes de couleurs. Merci. Je suis tombĂ©. Celui-lĂ  il me plaĂźt parce qu'il est hyper lisible. Vous voyez moi je suis fond blanc. Je suis dans l'Ă©quipe fond blanc.

Prot: Oui, comme moi.

Richard: Ça ne me pose pas de problĂšme. J'ai l'Ă©cran, la luminositĂ© diminue un peu avec la fin de journĂ©e, ça suffit. Ça suffit pour moi, mais ça dĂ©pend des gens. Donc voilĂ , ça donne ça. Il n'y a pas... Donc tu es lĂ , tu vois, Sacha.

Sacha: Mon journal !

Prot: Et il y a les OCaml News aussi.

Richard: Oui, il y a l'OCaml News.

Prot: Sacha Chua de la communauté OCaml.

Richard: Exactement. En fait, j'ai trois weekly. Il y a trois trucs que je lis systĂ©matiquement. Sacha Weekly, Sacha Emacs News, This Week in Rust, et le Weekly News OCaml. Je trouve ces trois blogs oĂč le ratio signal-bruit, comme on dit, est trĂšs trĂšs Ă©levĂ©. J'en retire beaucoup de choses intĂ©ressantes, de curiositĂ©s, de choses Ă  aller voir. Et ça, moi, ça m'enthousiasme Ă  chaque fois que j'ai des choses Ă  aller voir. Ah, il y a encore un truc que je ne connais pas. Alors c'est un peu angoissant, on est toujours derriĂšre, on a toujours des choses Ă  faire. Mais c'est quand mĂȘme plus sympa de voir ce que les gens ont trouvĂ© de nouveau. Que ce soit dans un langage de programmation ou dans Emacs. C'est les trois newsletters que j'aime bien lire. Je sais que ça sera facile, c'est-Ă -dire que je ne vais pas devoir me concentrer des heures. Par exemple, il y en a oĂč c'est des maths, il faut pouvoir se poser pour lire. Pour lire le post, il faut rĂ©flĂ©chir. Et sur les newsletters weekly dont j'ai parlĂ©, c'est hebdomadaire, on dit en français, pas weekly. C'est des choses que je lis avec plaisir.

Sacha: En lisant aussi ta configuration, j'ai noté que tu as des fonctions qui répliquent la fonctionnalité d'org-capture, comme quand tu crées une note sur le rendez-vous ou tu saisis une tùche. Quelle différence... Je consulte mes notes. Pourquoi tu utilises ta propre fonction pour faire ça ?

Richard: C'est une excellente question et je ne suis mĂȘme pas sĂ»r de quoi tu parles, alors je vais aller voir.

Sacha: Par exemple, tu as une fonction qui te demande sur une tùche et aprÚs ça, tu le remplace dans un titre dans ta boßte de réception. Je pense... J'oublie.

Richard: On va aller voir. Dis-moi le nom si tu as la note. Dis-moi... Dis-moi...

Sacha: Je cherche pendant que vous conversez.

Prot: D'accord. Peut-ĂȘtre que c'est plus facile d'avoir une fonction personnalisĂ©e.

Richard: Je ne sais pas de quoi exactement on parle.

Prot: Moi aussi, je n'en suis pas sûr.

Richard: Et c'est possible, Sacha, je t'avoue, c'est possible que ce soit quelque chose que je n'utilise plus. C'est possible. Dans ma configuration Emacs, C'est un peu le mĂȘme problĂšme que le nombre de mes sections dans Super Agenda. Il y a des choses qui arrivent et il y a rarement des choses qui partent. Ça s'ajoute, ça s'ajoute et il manque la personne qui va faire le nettoyage. Je ne sais pas oĂč elle est cette personne.

Sacha: Je l'ai trouvé. Je l'ai trouvé. La fonction rb/org-add-task.

Richard: Ah, bah, j'utilise rb/org. Est-ce qu'elle est cette fonction ?

Sacha: org-add-task.

Richard: Ivy?

Sacha: rb/org-add-task. Pour ajouter une tĂąche avec un lien...

Richard: Ah oui, c'est... Oui. Je crois que je ne sais pas faire avec Capture. En fait, je pense que je n'ai pas rĂ©flĂ©chi Ă  faire avec Capture. Simplement, c'est quand je suis en train de faire quelque chose dans un autre buffer, ça me permet d'avoir un raccourci. Que je ne saurais peut-ĂȘtre pas faire avec Capture, je t'avoue. Oui, tu peux. Rajouter une tĂąche, mais peut-ĂȘtre qu'il me manque juste la curiositĂ© ou le bon raccourci dans Capture pour faire ça. Je n'ai pas trop rĂ©flĂ©chi et on va voir. Oui ? Non ? C'est bien. Bon, je t'avoue, il n'y a pas de raison fondamentale.

Sacha: Je suis seulement curieuse. Tes bibliothÚques contiennent un mélange amusant de fonctions qui portent un docstring qui ne sont que « docstrings » entre guillemets, et d'autres fonctions qui ont des docstrings plus longues, plus détaillées. Je pense que tu utilises l'IA pour écrire ça.

Richard: Alors, il y a deux, oui. DerniĂšrement, c'est l'IA qui fait mes docstrings. Ça, c'est vrai. Dans le passĂ©, ça existait dĂ©jĂ , cependant. Il y avait des fonctions que j'Ă©crivais en me disant que je vais la documenter correctement. Et d'autres, oĂč j'appliquais le fameux paradigme du programmeur, je la documenterais plus tard. Et plus tard, ce n'est pas encore aujourd'hui, visiblement. Ça, vous l'avez jamais. Oui, c'est ça.

Sacha: Moi aussi, je réponds toujours à mes documentations. Prot est bien documenté.

Prot: Non, non, moi je le documente, oui.

Richard: Mais parce que je pense que l'avantage de Prot, je pense qu'il a bien... C'est que lui, il fait vraiment des choses pour ĂȘtre publiĂ©es et pour ĂȘtre utilisĂ©es. Donc ça donne quand mĂȘme un coup de pouce Ă  produire de la documentation. Alors que moi, c'est vrai que mon optique, c'est souvent produire des choses pour moi-mĂȘme, pas trop les... Donc, c'est un peu... On a tous rencontrĂ© des ingĂ©nieurs ou des programmateurs, la documentation, mais c'est le code. Elle est lĂ , la documentation, c'est le code.

Sacha: Si je n'écris pas [ma] documentation, j'ai totalement oublié la fonction. AprÚs ça, je ne comprends pas.

Richard: Sacha, je suis d'accord avec toi. Mais de lĂ  Ă  ce que ça produise une action rĂ©elle, c'est lĂ  oĂč le problĂšme philosophique arrive. C'est qu'il faut arriver Ă  produire l'action derriĂšre. Mais c'est vrai, on oublie. D'ailleurs, il y a des fonctions dont tu me parles que j'ai oubliĂ©es. Celles-lĂ  dĂ©jĂ , je les ai quasiment oubliĂ©es, celles dont tu viens de me parler. Alors que c'est bien. C'est essentiellement quand je regarde du code pour me mettre une note en disant lĂ  il faut que je change quelque chose. Et ça va dans la to-do list. Et ça a un lien vers le code source et le contexte. Et si c'est possible de faire dans capture, je vais regarder. Je vais demander Ă ... Ouais, je vais demander Ă  l'IA, je pense. J'allais dire, soit je vais prendre le temps de le faire, moi, parce que c'est sympa aussi, c'est un peu de l'artisanat. Mais c'est vrai que ça va vite avec l'IA.

Sacha: J'aimerais que tout a beaucoup de priorités.

Richard: Oui, oui. Trop. Trop. Moi-mĂȘme, je ne suis pas sĂ»r de leur sĂ©mantique. Oui, c'est ça. Je crois que j'utilise essentiellement ABC. Ça, je comprends. On parlait des diffĂ©rentes sections. Les autres, oui. C'est essentiellement... En fait, ça va... Ceux qui sont plus tard, essentiellement un jour ça va devenir Someday. Et aprĂšs ça va faire Cancelled, je pense. Soyons rĂ©alistes.

Sacha: Moi aussi, mes fichiers Org Mode sont remplis de tùches annulées.

Richard: Par exemple, je vois ici la YubiKey GPG Stuff. Ça, je sais dĂ©jĂ  que ça n'arrivera jamais puisque je commence Ă  passer Ă  Age. Donc, ça ne va pas arriver. Ça n'arrivera jamais. Et ça, je n'ai plus la machine. Par exemple, on peut l'enlever. C'est bien, on va faire ça en direct.

Prot: VoilĂ  la progression.

Sacha: Oui, progress. Tu as une fonction pour suivre ton plan d'études?

Richard: Ah oui, ça c'est pareil. J'avais créé, alors je ne sais mĂȘme plus, mais c'est vrai, j'ai un rĂ©pertoire. Alors, parce que comme tout le monde, des fois je cherche, soit je suis curieux de quelque chose. Et donc j'ai utilisĂ© l'IA pour faire ça, pour me gĂ©nĂ©rer, c'est assez fort pour faire ça, gĂ©nĂ©rer des plans d'Ă©tudes, des sections, et on peut travailler avec elle aussi pour faire des interrogations. C'est pas mal. Et donc, ouais, c'est Study Plan, Study Next Plan. Oui, j'ai plusieurs. Plusieurs plans pour diffĂ©rents domaines de l'informatique.

Sacha: C'est trĂšs petit. Pouvez-vous?

Richard: On peut se tutoyer, comme on dit en français. Il y a des trucs en méthode formelle que je n'ai pas accompagné, comme l'arrivée de Lean4. J'aimerais bien prendre un peu de temps pour jouer avec. Il y a deux ou trois fonctions qui permettent de marquer, de passer à l'étape d'aprÚs avec Org Mode et un peu de glue autour pour voir quel fichier est en todo. On arrive à faire des étapes. Et c'est bien que tu me le rappelles parce que j'ai du retard là-dessus. Je ne suis pas en avance sur mon study plan, sur mon plan d'étude.

Sacha: C'est un bon plan. Tu utilises l'IA pour générer des plans. Tu as une fonction qui avance à la prochaine étape.

Richard: C'est ça. Donc il y a un format quand mĂȘme. Le format n'est pas trĂšs compliquĂ©. Week, l'index et puis des sujets qui sont marquĂ©s. Donc l'index permet de savoir ce qu'il y a Ă  faire et d'avoir une vue d'ensemble des sujets. Donc si je travaille avec l'IA, je lui demande quand mĂȘme d'aller suivre certaines choses. Par expĂ©rience, je sais que c'est un sujet sur lequel on peut passer toute une vie. On dĂ©limite quand mĂȘme. J'ai utilisĂ© l'IA aussi pour faire des interviews croisĂ©es sur des sujets. Vous savez les interviews techniques en informatique sont particuliĂšrement pĂ©nibles. Donc pour faire une simulation d'interview technique. Avec l'IA qui fait une impersonnation de quelqu'un qui serait un expert en mĂ©thode formelle et qui travaillerait sur tel sujet et qui vous pose des questions. Comme si c'Ă©tait une interview pour ĂȘtre... Pour ĂȘtre embauchĂ© pour travailler dans une entreprise.

Sacha: Tu le fais dans un fichier Org Mode ?

Richard: Je garde la trace dans un fichier Org Mode. Je garde la trace d'exĂ©cution dans un fichier Org Mode pour pouvoir repasser dessus et réétudier. C'est un peu des techniques de mĂ©morisation classiques. C'est-Ă -dire, on fait une premiĂšre stimulation, puis on revient un peu aprĂšs pour rafraĂźchir des choses qu'on a travaillĂ©es. La premiĂšre stimulation, c'est aussi, oups, ça, je ne connais pas du tout, je vais devoir aller chercher. Ce qu'on fait dans ce cadre-lĂ , parce qu'en fait, je ne le connais pas. Je ne sais pas. J'ai une idĂ©e, peut-ĂȘtre. Ou peut-ĂȘtre mon idĂ©e est fausse, d'ailleurs. Il faut la corriger. Donc ça, c'est la premiĂšre stimulation. C'est face Ă  la question, se mettre face Ă  son ignorance. ConfrontĂ© Ă  son ignorance. On peut soit demander Ă  l'IA de nous aider un peu, soit d'aller chercher soi-mĂȘme selon le temps qu'on a et selon ce qu'on juge le plus efficace. Mais aprĂšs, il faut repasser dessus, sinon on oublie. C'est juste une bonne sensation. Mais aprĂšs, ça ne sert pas Ă  grand-chose en termes d'apprentissage.

Sacha: Il y a une question associée au chat sur la gestion des idées. « Ma question est la suivante. Je pense que c'est une rabbit hole au lieu de se focaliser sur les choses les plus importantes, au lieu de créer des projets et se concentrer sur les dot files, etc. » Je pense que tout le monde a du mal avec la gestion d'attention.

Richard: Oui, alors... En fait, un des problĂšmes, c'est tes notes hebdomadaires, Sacha.

Sacha: Pour moi aussi !

Richard: Elle donne tellement d'ouverture. C'est super ce que fait personne. Je vais faire pareil. C'est intĂ©ressant. Et on se retrouve deux heures plus tard. On a juste avancĂ© sa configuration Emacs. Mais ce n'est pas grave. J'ai pris mon parti. Ça fait partie des activitĂ©s que je fais dans la semaine. Ça fait partie des choses. Je pense, en rĂ©alitĂ©, je crois que nos emplois du temps sont moins pleins que ce qu'on croit qu'ils sont. Et moi, j'admis que Emacs, ça faisait partie des outils que j'aimais utiliser et comme tous les outils qu'on aime utiliser, il faut les entretenir. Donc, passer un peu de temps sur l'entretien et regarder des choses parce que c'est agrĂ©able. VoilĂ , donc j'ai admis qu'il y aurait du temps passĂ© sur la configuration, et c'est pas grave parce que c'est un outil, il y a plein de gens, Emacs c'est un outil pour une vie, pour moi. Donc si on passe une heure par semaine, c'est pas grave, dans 20 ans, si on est encore lĂ , ça sera quelque chose qui va ĂȘtre, qui aura un bĂ©nĂ©fice si ce n'est juste pour la connaissance, juste pour le plaisir. C'est pas grave. Moi, c'est un truc que j'aime bien. On perd du temps entre guillemets, mais c'est pas vrai. Quand on fait des choses qu'on aime bien, on perd pas du temps, je pense.

Prot: Oui, oui, oui.

Sacha: Bien évidemment, tu utilises Emacs pendant plus de 20 ans.

Richard: Voilà, donc du coup, à force, ce n'est pas grave. Il y a des choses qui sont là depuis 20 ans. J'ai pris du temps pour les configurer, mais la configuration n'a pratiquement pas changé ou elle a évolué un petit peu. Donc, ce n'est pas grave. J'ai perdu une heure il y a 20 ans. Ce n'est pas grave. Ce n'est pas beaucoup de temps dans une vie.

Prot: Et tu as gagné les automatismes que tu préfÚres.

Richard: Ben oui, et ça je m'en rends compte quand je passe sur d'autres outils surtout. Que ça marche pas, C-x, CTRL F, ça marche pas, CTRL H, F, ça marche pas. Les raccourcis sont pas corrects. Je rigole bien sĂ»r, mais c'est un peu ça. J'ai tellement d'habitude que c'est une forme d'obstruction au changement. On est d'accord, force d'avoir. Mais bon... Quand je regarde avec un pas de cĂŽtĂ©, il y a trĂšs peu d'outils qui ont la pĂ©rennitĂ© d'Emacs ou de Vim d'ailleurs. Donc c'est des rĂ©flexes qui valent le coup d'apprendre que ce soit pour l'un ou pour l'autre. Ce sont des choses qui seront probablement encore lĂ  oĂč il y aura des hĂ©ritiers trĂšs similaires dans 15 ans, 20 ans. Moi je parie qu'il y aura toujours un Emacs ou une forme d'Emacs et il y aura toujours un hĂ©ritier de Vim quel qu'il soit dans 20 ans et c'est bien possible que Visual Code ait Ă©tĂ© remplacĂ© par un autre Ă©diteur plus Ă  la mode. J'en ai dĂ©jĂ  vu passer quelques-uns qui Ă©taient trĂšs Ă  la mode Ă  un moment ou Ă  un autre. Emacs a l'avantage d'ĂȘtre jamais Ă  la mode. Donc, en fait, si on admet que ce n'est pas grave de ne pas ĂȘtre Ă  la mode, on a un outil qui sera prĂ©sent aussi parce qu'il y a... GrĂące au travail de plein de gens et aux heures de travail de plein de gens dans la communautĂ©, parce que ce n'est pas magique, donc voilĂ ... On aura un outil qui va rester et qui sera toujours... De toute façon, on aura toujours une fonctionnalitĂ© ou une autre qu'on pourra continuer Ă  utiliser. MĂȘme si on utilise Emacs juste pour avoir une interface Git qui soit super chouette, Ça reste assez chouette, ça suffit. Ou juste pour Org Mode, ça suffit aussi. Effectivement, je suis maximaliste, j'essaie de l'utiliser pour presque tout. Mais je pense que ça convient Ă  plein d'usages.

Sacha: Tes étudiants supportent l'utilisation d'Emacs ? Ils continuent ?

Richard: Pardon?

Sacha: Tes étudiants. s'est passé à...

Richarde: Mon Ă©tudiant? Ah, mon Ă©tudiant, non, il continue avec Emacs, bien sĂ»r. Les Ă©tudiants que j'ai eus, ils ont tous utilisĂ© Emacs et il y en a plusieurs qui ont adhĂ©rĂ©, qui ont beaucoup aimĂ© Org Mode en particulier parce que souvent, je leur propose ça. Notamment dans les travails de master ou de thĂšse, il y a quand mĂȘme beaucoup de lecture. Le rĂŽle de l'encadrant, c'est de faire des recommandations. Vous savez comment est la vie, que ce soit en tant que parent ou en tant qu'encadrant, on fait des recommandations et les enfants ou les Ă©tudiants ne les suivent pas. Ils font leur propre expĂ©rience et aprĂšs, ils s'aperçoivent qu'il y avait quand mĂȘme des bonnes idĂ©es. C'est Ă  peu prĂšs ça le mĂ©canisme, comment ça fonctionne. Mais ils essayent. Et puis moi, je peux en parler pendant des heures et puis je suis enthousiaste sur ces outils-lĂ  parce que c'est pĂ©renne, parce que c'est ouvert, parce que c'est facile de donner le format et on peut le transformer facilement grĂące Ă  tous les outils qui existent dans le monde open source. Donc, on part d'Emacs et d'un format textuel. Pour moi, vraiment Org Mode, c'est le plus adaptĂ© quand on est dans Emacs. Parce que le mode est phĂ©nomĂ©nal, mĂȘme par rapport au support Markdown qu'on a, et par ses capacitĂ©s qui sont supĂ©rieures. Mais aprĂšs, on peut communiquer avec les gens facilement, produire Ă  un PDF de ses notes Org Mode pour communiquer avec quelqu'un qui n'utiliserait pas Emacs, mĂȘme pas en tant que visualiseur PDF. Donc, c'est facile. C'est trĂšs mallĂ©able. En fait, c'est vraiment lĂ  qu'on en revient. C'est trĂšs mallĂ©able comme outil. C'est fait pour ĂȘtre retransformĂ©, pris en main. En fait, ça convient bien aux gens qui ont cette philosophie, en particulier les programmeurs. Beaucoup de programmeurs, ça leur parle. Mais pas que. Prot, Ă  la base, il n'est pas programmeur, par exemple.

Prot: Oui, oui, c'est vrai.

Richard: Bon, et maintenant il l'est, mais de facto. Mais bon, voilĂ . Il continue, oui, ça continue. Mais mĂȘme des gens, en fait, beaucoup de gens l'utilisaient dans mon entourage juste pour Ă©crire les articles. En fait, c'est pour ça, initialement, en tant qu'Ă©tudiant, c'est pour ça que j'avais utilisĂ© Emacs plutĂŽt que Vim, c'Ă©tait que c'Ă©tait plus naturel de taper dans Emacs. C'est-Ă -dire, quand on tape une lettre, on obtient la lettre. Il n'y a pas de contrainte Ă  passer dans un mode ou un autre. La notion de modal dans Emacs est un peu diffĂ©rente, un peu sous-jacente, mais elle existe. Donc, c'est un peu pour ça que j'Ă©tais parti sur Emacs Ă  la base. Le choix, on conviendra que cette raison n'est pas extraordinaire. C'est une raison de facilitĂ© initiale. Et puis, du coup, je suis toujours dedans. Comme quoi.

Sacha: Mais les raccourcis clavier !

Prot: DÚs que c'est la facilité avec Emacs.

Richard: Non, mais c'est vrai qu'il y a toujours cette difficultĂ© de comprendre le mode. J'Ă©tais vraiment dans le Vi, donc il fallait vraiment taper sur Escape pour pouvoir taper une lettre, et puis pour bouger, aprĂšs il fallait retaper sur Escape, etc. Bon, j'ai un peu absorbĂ© ce genre de choses maintenant, puisqu'on a quand mĂȘme des interfaces, enfin l'interface de Magit en particulier, c'est plein d'autres. MĂȘme les miennes, elles sont un peu modales. On arrive dans un buffer, on a des raccourcis clavier dĂ©diĂ©s sur une lettre ou une autre. Bon, c'est clairement la mĂȘme logique. Ça a du bon. C'est vrai qu'il y a des gens qui argumentent du fait que Emacs est modal carrĂ©ment. Je n'irai peut-ĂȘtre pas jusque lĂ , mais la diffĂ©rence n'est pas si grande que ça. Il y a une diffĂ©rence fondamentale d'esprit et de contraintes, mais ça c'est comme dans le design de quoi que ce soit. Il y a une vision initiale, puis aprĂšs on s'aperçoit qu'en pratique, les diffĂ©rences sont beaucoup plus fines.

Prot: Et pour toi, comment on dit que le texte est malléable, c'est la malléabilité d'Emacs qui est l'essence de ces différences ?

Richard: Pour moi, oui. Le choix initial qui est de se dire je vais avoir un interprĂ©teur d'un langage. Et en fait, Emacs pour moi, je le vois vraiment comme on a essentiellement un langage interprĂ©tĂ©. Ça me parle beaucoup. Et au-dessus, il se trouve qu'on a rajoutĂ© toute une bibliothĂšque super chouette de fonctions pour afficher du texte. Il y a une bibliothĂšque en plus. C'est comme si on prenait un langage de programmation standard et qu'on avait prĂ©vu dĂ©jĂ  son utilisation au sein d'un Ă©diteur de texte. Donc on a toujours la capacitĂ© inhĂ©rente au langage de programmation et en particulier, dans le cas du Lisp, la mallĂ©abilitĂ©. et l'expressivitĂ©. En plus, on a toute la bibliothĂšque et lĂ  on a tous les modes en plus, donc ça c'est encore d'autres choses, mais je le vois vraiment comme ça. Ça vient d'un langage de programmation, donc d'un monde que je connais. Programmation fonctionnelle dit quasiment un interprĂ©teur pour pouvoir jouer avec le langage. Et au-dessus de ça, on a pensĂ© l'affichage et la fonction d'Ă©diteur, mais au-dessus de ce langage de programmation. Moi, j'aime bien ce cĂŽtĂ© langage de programmation qui est dans Emacs, qui est dans la nature d'Emacs.

Sacha: J'adore combiner les fonctions des bibliothÚques différentes pour faire une interface personnalisée.

Richard: Oui, c'est ça, c'est ça. Et puis on continue en fait. Et c'est vraiment l'esprit, enfin pour moi c'est vraiment l'esprit open source, mais mĂȘme la programmation fonctionnelle. On prend, on fait des, on a des briques de base et on les assemble. On fait des briques un peu plus abstraites et puis on... Et dans Emacs, force est constante. Moi, je trouve que les briques de base sont pas mal pensĂ©es. Est-ce que c'est vraiment... Je pense que c'est un peu organique. Un choix d'une essence initiale qui a tout bien dĂ©cidĂ© du dĂ©but. Mais on se trouve qu'on arrive Ă  un Ă©quilibre qui, moi, me satisfait. Et je ne cherche pas Ă  convaincre le reste du monde qu'ils ont tort. Moi, ça me va qu'Emacs ne soit pas l'Ă©diteur Ă  la mode, comme j'ai dit tout Ă  l'heure. Je ne cherche pas Ă  convaincre le reste du monde que c'est ça qu'il faut faire. J'incite fortement mes Ă©tudiants quand j'en ai Ă  l'utiliser. Mais sinon, ce n'est pas grave. Ça reste un outil et c'est pareil, les outils, il faut les adapter. L'open source permet ça et je pense que c'est aussi un message important.

Sacha: As-tu des astuces moins connues sur l'utilisation d'Emacs ?

Richard: Moins connues ? Je ne sais pas. Comme je vous ai dit, j'emprunte beaucoup de choses dans ce que je vois. La derniĂšre chose que j'ai commencĂ© Ă  utiliser et que j'aime bien, c'est Embark. Mais je pense que c'est suffisamment connu. Pour ne pas dire que c'est une astuce inconnue que je commence Ă  utiliser. Parce qu'effectivement, on a ce problĂšme de se rappeler de ce qui existe, ce qu'on a dĂ©jĂ  fait. Et je trouve que Embark m'aide un peu Ă  ça. On a un raccourci de base dans un contexte. Et on va afficher les choses qui existent dans ce contexte qui pourraient ĂȘtre intĂ©ressantes Ă  utiliser, qu'on a oubliĂ© parce que nos fichiers de configuration sont trop longs ou il y a plein de modes ou des choses comme ça. Et ça m'aide dans ça, ou pour rajouter facilement des fonctionnalitĂ©s dans des modes qui ne sont pas les miens. LĂ , dans Magit, par exemple, au-dessus de Forge, j'ai associĂ© dans Embark la possibilitĂ© d'ouvrir via peer review. La pull request qui Ă©tait ouverte et pouvoir faire la revue de code dans Emacs, Ă©videmment. Aussi. En se passant de GitHub.

Sacha: Ma fille ne s'est pas encore rĂ©veillĂ©e. Donc si vous ĂȘtes disponible, nous pouvons continuer. Si vous avez d'autres obligations, pas de souci. On continue?

Prot: Moi, je peux continuer.

Richard: Moi aussi. En plus, on a un quart d'heure à rattraper au moins. À cause de notre erreur initiale assumant collectivement.

Sacha: Oui, non, non, non. J'ai enregistré toutes les sessions, donc je peux publier l'enregistrement.

Richard: D'accord. TrĂšs bien. Non, pas de souci, avec plaisir. Moi, j'aime bien. Moi, juste d'ĂȘtre lĂ  avec vous deux, ça me va, et de parler d'Emacs. Comme je vous ai dit, je peux en parler pendant des heures. Je pense que certains de mes Ă©tudiants en avaient peut-ĂȘtre marre, mais osaient pas me le dire. Mais oui, on peut continuer.

Sacha: Je n'ose pas toujours aller aux réunions virtuelles d'Emacs Paris. Comment ça va? Il y a beaucoup de présentations en français ?

Richard: Alors moi, je n'y suis jamais allĂ©. En plus, tu m'as parlĂ© de virtuel, donc ça n'a pas d'impact, mais je n'habite pas Ă  Paris. Mais effectivement, c'est une bonne remarque. Peut-ĂȘtre que je devrais le faire. Il faut voir les horaires parce que je suis un peu comme toi. J'ai des contraintes familiales. J'ai aussi une fille. Donc, il y a des horaires qui sont impossibles Ă  l'heure actuelle. Et c'est bien, en fait. C'est comme ça. C'est la vie.

Sacha: C'est la vie.

Richard: Non, mais c'est bien. En fait, c'est bien. C'est bien. MalgrĂ© ma passion d'Emacs, on peut faire un petit pas de cĂŽtĂ©, avoir un enfant, moi, ça m'a amenĂ© Ă  reconsidĂ©rer beaucoup de choses. C'est normal, oui. Et d'ailleurs, juste en passant, moi, ça m'intĂ©resse ce que tu racontes sur la parentalitĂ©, Sacha, dans tes billets de blog. C'est un truc que je suis. Ça n'a rien Ă  voir avec Emacs, mais un peu, parce qu'Ă  travers toi, c'est un des sujets que j'aime bien suivre et qui m'interpelle depuis qu'il y a un enfant, essentiellement. C'est comme ça qu'on s'y intĂ©resse, je crois.

Sacha: Ma fille a 10 ans, donc je me sens toujours une débutante avec tous les sujets de parentalité... c'est difficile.

Richard: Mais je pense que c'est la mĂȘme attitude face Ă  Emacs. Il faut avoir... On est des dĂ©butants, on continue Ă  apprendre. C'est un environnement oĂč il y a tellement de choses Ă  apprendre. On continue. Ce qui est bien, c'est que ça peut satisfaire les gens qui sont curieux et qui sont quand mĂȘme aussi Ă  l'aise avec le fait qu'ils ne connaĂźtront jamais tout. Ce n'est pas grave. Moi, ça me nourrit comme ça. La parentalitĂ©, c'est un peu la mĂȘme chose. On ne connaĂźtra jamais tout. Sauf que ce qu'on fait a quand mĂȘme plus d'impact que dans Emacs. On est d'accord. C'est quand mĂȘme un peu diffĂ©rent.

Sacha: Quelles sont tes prochaines étapes sur ton bricolage d'Emacs ?

Richard: Alors probablement, visiblement, ce qu'on a discutĂ© lĂ , je suis conscient qu'il y a un peu de nettoyage Ă  faire. Peut-ĂȘtre d'aller voir un peu plus dans le dĂ©tail ce qui existe dans Org-capture pour simplifier certaines choses. On a tous un peu, enfin les programmeurs, on a tendance aussi Ă , comme on dit en français, Ă  rĂ©inventer la roue. On aime bien faire les choses de notre maniĂšre parce qu'elle est mieux. Parce que c'est la nĂŽtre, en fait. On la comprend plus facilement, tout simplement. Donc, probablement, allez voir s'il n'y a pas d'autres choses. Je vais continuer Ă  travailler sur mon interface Garmin pour que ça soit... Plus intĂ©grer pour ma visualisation, donc vĂ©rifier les courbes, je pense que je vais regarder. C'est peut-ĂȘtre intĂ©grer d'autres donnĂ©es physiologiques. Ce qui est pas mal, c'est que si on a, enfin moi c'est pas mon cas, mais si on a plusieurs, il n'y a pas de mot français, trackers, de donnĂ©es, on peut les intĂ©grer au mĂȘme endroit dans Emacs, Ă©videmment. En ayant la bonne interface, la bonne glue, la bonne colle pour intĂ©grer les donnĂ©es. Et puis je vais continuer, dĂšs que j'ai une cascade, une sĂ©quence de choses rĂ©pĂ©tĂ©es, Ă  essayer de les intĂ©grer sous forme de fonction dans Emacs. qui fait toujours dans cette vision d'orchestration. Je pense que je vais continuer parce que je l'ai fait. Par exemple, j'ai des fonctions pour gĂ©nĂ©rer des invoices parce que ça m'est venu assez naturellement d'avoir ça dans Emacs. parce que j'ai un esprit comme ça, mais avec du LaTeX, bien sĂ»r, parce que ça, c'est mon background acadĂ©mique c'est parce que je connais les packages. C'est pareil quand on connaĂźt un environnement, hein, quand on a un marteau, on a l'impression que tout est un clou, comme on dit, hein. C'est un peu ça. Je vais continuer ça. DĂšs qu'il y a quelque chose qui est un peu rĂ©pĂ©titif et qui est un peu ennuyeux Ă  faire, je pense que je vais l'intĂ©grer dans Emacs. Parce que l'outil me le permet trĂšs facilement. C'est facile de lire les sorties d'outils Unix, c'est facile de les combiner avec la programmation fonctionnelle, tout se passe bien. On les remet en forme, on Ă©change les donnĂ©es. Et ça, Lisp est chouette pour ça. Pour manipuler les donnĂ©es, c'est vachement bien. Pour moi, c'est encore plus simple que d'autres visions de la programmation. Je pense que ces deux aspects-lĂ , simplifier les tĂąches rĂ©pĂ©titives, donc ça, je continue en particulier, mĂȘme Ă  les faire avec des timers, parce qu'il y a des choses que je n'ai pas envie de rĂ©flĂ©chir. Il y a des choses auxquelles je rĂ©flĂ©chis, comme d'aller rĂ©cupĂ©rer... Donc, par exemple, toutes les pull requests qui ont reçu des commentaires. VoilĂ , mettre dans Emacs et me faire une petite note Org Mode avec les liens qui vont bien pour pouvoir... Ça fait une forme de... C'est des mini to-do list pour la journĂ©e, quoi. Qu'est-ce que je dois faire dans ma journĂ©e de programmeur d'un peu urgent ? Au lieu d'aller manuellement dans les dĂ©pĂŽts Git et aller voir s'il y a eu... Moi ça me va quand je ne vais pas sur les interfaces des navigateurs, j'aime bien. Je prĂ©fĂšre rester dans la manipulation de texte et dans l'abstraction. J'aime bien les outils locaux et Emacs me permet de faire comme si c'Ă©tait local.

Sacha: J'ai lu ta fonction pour générer ton rapport pour les stand-up qui ressemblait à tous les pull requests et d'autres données.

Richard: C'est ça, oui. On me demandait de faire ces rapports-là. Ce n'est pas un truc d'humain, ça. C'est un truc de machine. Ce n'est pas important. Donc, c'était des demandes. Quand on a des demandes administratives qu'on trouve à la limite de l'absurde ou qu'on ne considÚre pas comme importantes, c'est bien que la machine vous aide. Emacs me permet ça, mais tous les outils de script le permettent. J'aime bien l'avoir dans Emacs.

Sacha: Tu as d'autres collĂšgues qui utilisent Emacs ? Peut-ĂȘtre qui utilisent tes scripts ?

Richard: Mes scripts, c'est arrivĂ© par le passĂ©. Des choses que j'avais faites, j'avais distribuĂ© Ă  des Ă©tudiants justement en Caml. J'avais fait des petites choses pour simplifier, pour pouvoir rĂ©sumer vite. En Caml, on a deux types de fichiers. On doit dĂ©crire dans un fichier l'implĂ©mentation et dans un autre fichier ce qui est accessible comme API. Il y a une forme de duplication qui n'est pas trĂšs satisfaisante en tant qu'ĂȘtre humain. Donc, j'ai fait un script pour extraire l'information nĂ©cessaire du fichier oĂč on avait l'implĂ©mentation vers le fichier d'interface. Je l'ai diffusĂ© aux Ă©tudiants pour qu'ils puissent le rĂ©utiliser, pour que ça leur simplifie le dĂ©veloppement. J'ai peut-ĂȘtre deux ou trois autres choses qui ne viennent pas Ă  l'esprit, mais c'est assez limitĂ©. Et j'ai un collĂšgue qui utilise Emacs. Alors on n'est pas beaucoup, je suis dans une toute petite entreprise, on est six, donc on est un tiers d'utilisateurs Emacs. Un tiers, c'est Ă©norme sur une entreprise. Le reste, ils font tous du visual code, plus exactement du... Comment s'appelle ça ? Cursor.

Prot: Ah, Cursor, oui.

Richard: Personne n'est parfait.

Prot: C'est la mode, oui.

Richard: Mais lĂ  encore, en fait, Emacs est parfait pour l'IA. Mais c'est normal. Lisp, c'est un langage d'IA Ă  la base.

Prot: C'est normal.

Richard: Donc, Emacs Ă©tait en avance. On ne le savait pas. L'IA manipule presque tout de format textuel. Donc, c'est parfait pour Unix en gĂ©nĂ©ral et Emacs en particulier. Moi, j'utilise Claude Code et j'ai fait une petite interface aussi pour savoir toutes les instances de Claude qui tournent dans quel rĂ©pertoire avec quel pour pouvoir les ouvrir et aller les voir ou les tuer etc. Donc encore une fois, j'ai rĂ©utilisĂš Tabulated pour faire ça, parce que effectivement j'Ă©tais un peu contraint par Claude Code. Moi, j'utilise qui marche trĂšs bien, mais ça permet qu'une seule instance Ă  un seul buffer, donc j'ai un peu gĂ©nĂ©ralisĂ© pour avoir un Claude Multicode ou quelque chose comme ça. Ça permet d'utiliser plein d'instances qui les renomment automatiquement, on peut les renommer. J'ai un peu mon cockpit dans Emacs, mon dashboard textuel. C'est l'idĂ©e gĂ©nĂ©rale actuellement.

Sacha: J'ai un peu peur de permettre Ă  l'IA d'utiliser mon Emacs directement. C'est un peu dangereux, je pense.

Richard: Non, oui. Il y a d'autres soucis, mais on est incitĂ©. Bon, ça simplifie certaines choses, mais ça en complique d'autres. On pourrait en parler, mais ce n'est pas le sujet d'aujourd'hui. Ce n'est pas le sujet d'aujourd'hui, mais ça aide. En fait, moi, ça m'a enlevĂ© un frein pour ma crĂ©ation d'outils personnalisĂ©s dans Emacs quand mĂȘme. Est-ce que j'avais toujours une espĂšce de frein qui me disait, oh lĂ  lĂ , mais il va y avoir tout ça Ă  faire. Ça va prendre beaucoup de temps. Plein de choses, j'arrive Ă  conceptualiser, mais les dĂ©tails, je ne les connais pas. Donc l'IA me permet de remplir facilement les dĂ©tails en donnant le concept de ce que je veux et d'aller un peu regarder parfois, mais... Mais c'est pas tout le temps. Parfois, mais pas tout le temps. LĂ , il y a plusieurs choses. J'ai fait beaucoup de travail avec. Mais je reste souvent sur ma faim, comme on dit. Sceptique quant aux rĂ©sultats obtenus. C'est assez facile de... Je trouve que je me suis dĂ©jĂ  convaincu de certaines choses en travaillant avec IA, en revenant le jour d'aprĂšs en disant mais c'est pas bon du tout ça. A mon avis, c'est mĂȘme totalement faux. Et de retravailler un client en disant ah oui, effectivement, c'est totalement faux ce que j'avais dit. C'est vraiment le problĂšme de travailler avec ça. Tout le monde qui a un peu de recul le sait. Ces outils ont ce problĂšme-lĂ . Il y a ça aussi. Tu ne l'as peut-ĂȘtre pas vu. Je ne sais pas si je l'ai poussĂ©.

Sacha: Il y a un commentaire dans le chat. Aya a dit, dans mon école d'ingé, tout le monde utilise Vim ou Neovim. Emacs est considéré comme sauvage un peu.

Richard: Et c'est déjà... Moi, je trouve ça impressionnant que tout le monde utilise Vim ou Neovim. En réalité, en 2026, qu'il y ait tant d'utilisateurs que ça, de ces éditeurs qui sont...

Sacha: TrÚs limités. C'est de papi, c'est des grands-pÚres de l'informatique.

Prot: Oui, oui.

Richarde: Mais en fait, quand ĂȘtes pensĂ©e... Dont la vision est a quelque chose de singulier et c'est pour ça qu'ils perdurent. C'est pas juste parce qu'il y a un peu d'habitude probablement, mais c'est pas que ça. C'est qu'ils parlent, je pense, Ă  un certain type d'audience. Il y a vraiment des idĂ©es, je pense, qui conviennent Ă  un paquet de gens, des ingĂ©nieurs en particulier. Je vous avoue que si moi, on m'imposait un autre outil, je serais trĂšs triste. Ça serait difficile. En fait, c'est un peu ce que je considĂšre comme une nĂ©cessitĂ© au mĂ©tier d'ingĂ©nieur ou de programmeur, c'est d'avoir de l'autonomie dans ses choix, techniques en particulier. Et un des choix techniques, c'est son interface de programmation. C'est pour ça que je ne vais pas essayer de convaincre Ă  tout prix que quelqu'un qui utilise Visual Code a tort. Il n'a pas tort, il utilise l'outil qui est adaptĂ© pour lui. Je peux lui montrer Emacs, on peut rigoler en lui disant qu'il a tort, mais je n'irai pas jusqu'Ă  le considĂ©rer vraiment. Mais j'Ă©tais Ă©tonnĂ© qu'on soit deux Ă  utiliser Emacs. En Rust, je pense que c'est un environnement qui est moins courant. Les communautĂ©s de programmation ont aussi des habitudes par rapport aux Ă©diteurs. Et en Caml, Emacs... avait au passĂ© une majoritĂ©. Je crois qu'il y a beaucoup d'utilisateurs de Neovim ou de Vim maintenant. Notamment depuis qu'on s'est abstrait que le support du langage est passĂ© du cĂŽtĂ© LSP. Finalement, l'Ă©diteur n'est devenu pas trĂšs important pour avoir la qualitĂ© de support. Du coup, c'est un bon argument pour que je garde Emacs. Comme ça, j'ai mes raccourcis clavier, j'ai un environnement hyper dĂ©pouillĂ© parce que moi j'aime bien avoir quelque chose de trĂšs lisible et trĂšs flat. Pas de truc qui clignote ou de machin. Bon, vous pouvez voir que j'utilise un window manager aussi trĂšs tiling, donc j'ai vraiment un truc un peu spartiate. Et j'ai utilisĂ© plusieurs fois Mac OS. A chaque fois, ça s'est terminĂ© pareil. Cet environnement ne me laisse pas faire les choses comme je veux. J'en ai marre, je repars sur Linux.

Sacha: Tu es trĂšs particuliĂšre sur tes outils.

Richard: Oui, c'est-Ă -dire que j'aime bien ne pas me sentir restreint. Mais dans la vie, c'est pareil. J'aime bien la forme de libertĂ© que procure L'open source, encore une fois. Sous Linux, si je veux avoir un environnement Ă  la macOS, je peux aussi. Si c'est ça qui me convient comme utilisateur. Et c'est ça qui est important, moi. Qu'on me laisse le choix. Et moi, ce dont j'ai besoin, c'est vraiment un truc simple. Ou l'Ă©cran, ou mon interface avec le monde, c'est Emacs. C'est particulier, mais ici, dans ce petit monde oĂč on est lĂ , tous les trois et les auditeurs, je pense qu'on est plusieurs Ă  avoir un peu ce parti pris. MĂȘme quand j'Ă©tais sur Mac OS, c'Ă©tait... Mon principal problĂšme c'Ă©tait que je trouvais dĂ©sagrĂ©able, c'Ă©tait compliquĂ© pour moi de switcher entre Emacs et le navigateur. Je trouvais ça dĂ©sagrĂ©able, la façon de le faire sur macOS. LĂ , essentiellement, j'ai deux Ă©crans virtuels diffĂ©rents et il y en a un qu'avec un navigateur. Donc, je change de l'un Ă  l'autre et un par raccourci clavier. C'est sans doute possible sous macOS. Je le crois volontiers, mais je ne suis pas arrivĂ© Ă  quelque chose oĂč je me sens libre de le faire.

Sacha: En lisant ta configuration, j'ai noté que tu utilises EWW. Oui, un peu, oui.

Richard: DĂšs que c'est possible. C'est-Ă -dire pas tout le temps. En 2026. Oui, ça m'arrive assez souvent, via Elfeed en particulier. Parce qu'il y a un nombre de blogs qui redirigent uniquement oĂč on est obligĂ© d'aller sur la page. Donc beaucoup d'entrees... En fait, ça suffit pour lire et c'est ça me va. Et donc j'utilise en premier lieu EWW dans ce cas-lĂ . Sinon, c'est... Malheureusement, je n'arrive pas Ă  en faire un outil majeur au quotidien. Les interfaces web que j'utilise ont souvent besoin de JavaScript en 2026. Malheureusement, je ne vais pas pousser la liaison Firefox. J'utilise Firefox essentiellement, mais la liaison Firefox et Emacs, je ne vais pas pousser cet aspect-lĂ .

Sacha: Je donne l'exception SpookFox pour créer un lien entre le navigateur Firefox et Emacs.

Richard: Comment tu dis?

Sacha: SpookFox. SpookFox me donne le pouvoir d'exécuter le JavaScript à partir d'Emacs Lisp. pour retrouver des...

Richard: Je vais regarder...

Prot: Oui.

Richard: Tu vas me faire perdre du temps encore.

Sacha: Pardon, pardon. pour passer à une autre page ou à retrouver des données ou à toutes les choses.

Richard: Je pense que c'est exactement ce qu'il me faut. Je ne sais pas qui a fait ça, mais merci à cette personne.

Sacha: Quand je prĂ©pare le bulletin d'information Emacs News, je l'utilise pour [extraire] les liens sur Reddit. Oui, oui, oui. Au lieu de copier manuellement les liens moi-mĂȘme, je juste le sĂ©lectionne dans une liste de vertico.

Richard: Ça c'est bien, ça. C'est un usage que j'ai rĂ©guliĂšrement de rĂ©cupĂ©rer le lien qui est dans mon navigateur pour l'intĂ©grer dans une note ou quelconque. Effectivement, ça va ĂȘtre bien ça, je pense. On apprend tous les jours, c'est lĂ  qu'on mesure le degrĂ© de notre ignorance.

Sacha: C'est la raison que j'ai envie de plus de vidéos et de ressources intermédiaires sur Emacs parce que tout le monde a des choses qu'on peut apprendre. Dans Emacs... Toutes les vidéos en ce moment sont pour les débutants, mais si tu prends juste un peu plus d'étapes, tu peux découvrir beaucoup de sujets d'apprendre.

Richard: Oui, c'est vrai. On apprend tout le temps. Mais mĂȘme quand on est expert, je pense que... MĂȘme les experts apprennent parce qu'ils sont experts dans un sous-domaine. Ils ne connaissent pas tout. Dans la communautĂ© Emacs, il y a plein de gens qui connaissent des choses, qui ont fait des choses trĂšs particuliĂšres. MĂȘme eux, je pense, peuvent apprendre d'autres qui ont fait d'autres parties plus particuliĂšres.

Prot: Mais ça doit ĂȘtre un peu plus difficile de faire les vidĂ©os sur ce sujet-lĂ . Parce que... Qu'est-ce que tu vas dire ? Les prĂ©fĂ©rences sont particuliĂšres. Peut-ĂȘtre c'est plus difficile de dire, oh voilĂ , voici quelque chose pour tout le monde. Tu vas dire, voici quelque chose pour moi.

Richard: Ça marche. Ça peut servir de point... En fait, ça a une autre utilitĂ©. DĂ©jĂ , se rendre compte que c'est possible. Parce que parfois, on se dit juste, on n'a pas eu l'idĂ©e. Ah, mais on peut faire ça. Et comment on le fait? Il a utilisĂ© ça, ça et ça dans les mains. Ah, mais je ne savais pas que c'Ă©tait comme ça qu'on pouvait faire. Et donc, Ă  partir de ça, on dĂ©sassemble un peu les briques et on les rĂ©assemble pour nous diffĂ©remment. C'est d'autres utilitĂ©s, je pense.

Prot: Mais peut-ĂȘtre il y a les sĂ©ances en direct qui ont comme ça. Je ne sais pas, oui. Je n'ai pas cherchĂ©.

Richard: Moi non plus.

Sacha: Je suis Ă©tonnĂ©e que cette conversation marche, mĂȘme si je suis dĂ©butante, mĂȘme si Prot est un peu rouillĂ©.

Richard: Bon non, tu es pas... Alors, pour avoir une conversation d'une heure comme ça, tu n'es plus débutante. Non, il n'y a aucun souci à te comprendre en français. J'ai l'impression que tu n'as pas eu beaucoup de soucis de compréhension. C'est trÚs facile de te suivre. Moi, j'ai appris une autre langue un peu comme toi. Dans mon passé, je suis allé au Brésil. J'ai habité deux ans là-bas et je ne parlais pas portugais. Et j'étais prof de l'université. Donc, j'ai appris comme ça, en donnant des cours. Alors, un peu en apprenant des cours, bien sûr, de base. Mais aprÚs, toute l'oralité, la façon de parler, la facilité de parler et le vocabulaire, c'est en travaillant sur les cours. En parlant, comme tu es en train de le faire, là. Et maintenant, les gens ne savent pas si... Beaucoup de gens ont des doutes jusqu'à un certain point. Ils arrivent à voir que je ne suis pas brésilien. Mais ça marche. Non, mais ton français est trÚs bon. Il n'y a aucun souci.

Sacha: Tu disais que tu avais peut-ĂȘtre un peu peur sur ce... Peut-ĂȘtre qu'un jour, nous pourrons avoir des Emacs en portugais. Je ne sais pas. Je ne parle pas portugais.

Prot: L'année prochaine.

Richard: En grec, d'abord.

Prot: Le final boss.

Sacha: Mais je pense qu'avec l'aide de l'IA, c'est plus facile d'apprendre la langue Ă  ce moment.

Richard: C'est vrai que c'est un usage tout Ă  fait pertinent aussi, de ces outils. Je t'avoue, par exemple, l'usage de l'interview dont je t'avais parlĂ©, je n'y avais pas pensĂ©. Mais en fait, c'est trĂšs pertinent de l'utiliser comme adversaire d'une certaine façon. Dans un jeu, il y a beaucoup d'ingĂ©nieurs aussi qui crĂ©ent leur logiciel maintenant, un peu aussi pour maĂźtriser ce qu'ils font de façon conversationnelle avec l'IA. Donc en remettant, en disant, en lui faisant poser des questions, en crĂ©ant bric Ă  bric, au lieu de lui dire fais ça, d'aller prendre un cafĂ©, c'est bien aussi, parfois, mais ils le font pas Ă  pas, comme un outil pour dĂ©limiter, parce que c'est vrai que Parfois, les solutions sont intĂ©ressantes, dirons-nous. Ça peut ĂȘtre assez intĂ©ressant. J'ai dĂ©jĂ  eu le cas, mais beaucoup d'autres, c'est quand on lui dit « fais passer tel test », tu enlĂšves tout le code du test et puis on met juste « assert true ». VoilĂ , trĂšs bien. Ça passe.

Sacha: J'ai envie d'interface vocale et conversationnelle avec Emacs. Je pense que c'est trĂšs puissant.

Richard: Alors, j'y ai pensĂ©, mais je ne suis pas lĂ . Mais effectivement, j'ai des collĂšgues qui utilisent l'IA et qui lui parlent directement pour ĂȘtre encore plus efficace. Mais est-ce que c'est... Je me pose Ă  chaque fois la question si c'est... Est-ce que c'est vraiment le but de ce qu'on veut faire personnellement, comme ĂȘtre humain, quoi ? Est-ce que c'est vraiment ça, ĂȘtre le plus efficace possible ? LĂ , par exemple, on n'est pas efficace, mais c'est trĂšs bien. Mais ça a quand mĂȘme quelque chose de pertinent.

Sacha: Et il y a des commentaires au chat. J'ai totalement oubliĂ© de lire Ă  voix haute. Une conversation sur la gestion des fenĂȘtres, sur l'apprentissage de langue avec les algorithmes de rĂ©pĂ©tition espacĂ©e. Et aussi les amis qui utilisent Helix [plutĂŽt] que Emacs ou aussi Zed parce qu'il est plus [Ă  la] mode.

Richard: Surtout si on aime Rust. J'ai essayĂ©, mais c'est un peu comme tous les outils. J'ai peut-ĂȘtre pas assez de patience. J'ai passĂ© dĂ©jĂ  mon temps d'apprentissage dans Emacs et j'avoue ĂȘtre un peu rĂ©ticent, comme on dit.

Sacha: Oui, tu as beaucoup d'habitude d'Emacs et c'est difficile de passer à d'autres éditeurs.

Richard: Oui, et puis surtout, comme on disait tout Ă  l'heure, maintenant, il y a des couches d'abstraction. Il y a LSP, TreeSitter, qui en fait rendent le choix de l'Ă©diteur un peu... Plus proche d'un choix tout Ă  fait personnel. Et pas de capacitĂ© en fait. Les capacitĂ©s sont les mĂȘmes, elles sont produites par l'adaptateur LSP ou l'adaptateur tree-sitter. Du coup, il n'y a plus de frein Ă  utiliser celui qui nous plaĂźt le plus. Parce qu'on a des habitudes pour tout un tas de mauvaises raisons. Effectivement, comme j'utilise plein d'autres choses dans Emacs, pas juste la capacitĂ© d'Ă©diteur de programmation parce que c'est ça qu'on a moins en fait dans Visual Code ou mĂȘme peut-ĂȘtre dans Z, que je ne connais pas trĂšs bien. C'est le fait que ça soit plus qu'un Ă©diteur en rĂ©alitĂ©. C'est ce qu'il y a de plus que ça. Ça fait l'Ă©diteur de code. Oui, mais tellement plus. C'est vraiment proche d'un OS d'une certaine façon. Beaucoup de choses. C'est une couche d'abstraction lispienne au-dessus d'un OS avec un... Un tiling window manager pas terrible. Et voilĂ . Et l'Ă©dition quoi. Mais l'Ă©dition, en fait c'est l'Ă©dition de texte. Donc ça marche. Pour Ă©crire des papiers, c'est super, c'est trĂšs bien aussi. C'est comme ça que j'ai beaucoup utilisĂ© pendant trĂšs longtemps pour Ă©crire mes papiers scientifiques. Comme en informatique, on utilise LaTeX. Pareil, c'est souvent Emacs ou un autre Ă©diteur, peu importe finalement. Parce que derriĂšre, on a une espĂšce de makefile ou un truc. Je suis assez vieux pour utiliser des makefiles, moi. Tout s'emboĂźte assez bien dans Emacs. Il est nĂ© en mĂȘme temps que beaucoup d'outils donc finalement il arrive Ă  interagir trĂšs bien avec ces outils. C'est surtout ça que je pense qu'il importe, qu'il est bien. Mais probablement les autres Ă©diteurs y arrivent trĂšs bien aussi. Mais on n'a tous que 24 heures dans la journĂ©e. On choisit de perdre son temps sur la note hebdomadaire de Sacha et du coup on ne peut pas aller faire du visual code. VoilĂ .

Sacha: Donc c'est ma faute.

Richard: C'est ça. Non mais ça serait autre chose, tu sais, la procrastination avec... Elle est illimitée. Quand il y a des choses qu'on n'a pas envie de faire, on trouve toujours quelque chose de plus important à faire.

Sacha: Je ne sais pas comment je peux crĂ©er une traduction de notre conversation. Je pense que j'ai du mal Ă  la corriger parce que c'est difficile en français. Mais j'essaie. Oui, oui, oui, oui. J'adore utiliser WhisperX pour transcrire mes autres conversations en français parce que mĂȘme si elle demande beaucoup de corrections, c'est plus utile parce que je ne sais pas les mots, je ne sais pas... Ah! Il y a un... Un petit remarque. « Est-ce que vous ĂȘtes averti qu'on peut utiliser Emacs, Vim, etc. avec Termux dans votre poche avec le smartphone et synchroniser votre travail avec SyncThing? » J'utilise Orgzly Revived avec SyncThing. Tu utilises Emacs sur ton tĂ©lĂ©phone?

Richard: Je dĂ©teste utiliser mon tĂ©lĂ©phone. On ne voit rien. C'est dĂ©sagrĂ©able. On n'a pas de clavier. C'est horrible. Je n'aime pas utiliser mon tĂ©lĂ©phone. Je ne suis pas une personne. Je suis trop vieux, peut-ĂȘtre. Mais non, c'est trop petit. On ne voit pas assez de contexte. Je ne sais pas. Ça ne me convient pas, personnellement. J'essaie. Je fais Orgzly et Syncthing. Mais en rĂ©alitĂ©... Ce qui me convient mieux, c'est de prendre des notes Ă  la main quelque part et d'aller les rentrer aprĂšs. Et en plus, je crois que ça me dĂ©tend un peu plus de prendre la note Ă  la main. Je la retiens mieux. Des fois, je n'ai mĂȘme pas besoin de passer par l'Ă©tape intermĂ©diaire de la rentrĂ©e. Je trouve que je les oublie beaucoup plus facilement si je les note sur le tĂ©lĂ©phone ou sur un device de façon Ă©lectronique. Si je les note Ă  la main, du coup, Il y a quelqu'un qui est un peu connu, qui est dans la rĂ©flexion de comment on travaille, qui s'appelle Cal Newport. Lui, il fait beaucoup de notes Ă  la main quand mĂȘme dans son travail, mais il est chercheur, c'est pareil. C'est un peu une apologie aussi de la lenteur d'une certaine façon pour rĂ©flĂ©chir Ă  ce qu'on fait. J'ai mis en place Syncthing et mon Android n'arrĂȘte pas de le tuer parce qu'il ne fait rien. On va lui dire que ça fait je ne sais pas combien de temps que vous ne l'avez pas utilisĂ© donc je vais arrĂȘter cette permission et cette autre permission. Je suis au courant de tout ça. Je vais plutĂŽt passer du temps Ă  faire ma config Emacs. On va faire des interfaces pour gĂ©rer les finances dans Emacs. Et puis d'autres outils qui existent. Et puis on agrĂšge tout ça avec un makefile ou un just file. Et on obtient des interfaces assez sympas. Et ça suffit pour une personne en fait. On n'a pas tant d'opĂ©rations. Quand on rĂ©flĂ©chit, on n'a pas tant d'opĂ©rations que ça, le texte. Je pense que c'est un peu le constat de Prot sur Denote par rapport Ă  l'utilisation d'une base de donnĂ©es, c'est que... On produit pas tant d'informations que ça en fait. Pour qu'on ait besoin d'avoir des bases de donnĂ©es en plus au-dessus du file system et que les outils qui se cherchent directement dans le texte nous amĂšnent en fait trĂšs trĂšs loin par rapport Ă  la qualitĂ© et le contenu d'informations qu'on produit. Donc le tĂ©lĂ©phone, si je pouvais m'en passer. Si je pouvais me passer du smartphone, je le ferais. Mais il y a beaucoup de banques qui ne veulent pas qu'on se passe d'un smartphone et beaucoup d'autres intermĂ©diaires qui veulent vraiment qu'on ait leur application sur notre tĂ©lĂ©phone. Mais si je pouvais avoir que le tĂ©lĂ©phone, franchement, je pense que je le ferais maintenant. Chapeau ! Je suis Ă  ce point-lĂ . Je suis comme tout le monde, je perds du temps sur mon tĂ©lĂ©phone. Je me rends compte qu'il va toujours vouloir Ă©couter des trucs. A ratĂ© d'autres choses du coup. A ratĂ© ce que je suis en train de faire. A ratĂ© ce que me dit ma famille. Peut-ĂȘtre qu'il y a une petite remise en question personnelle sur moi, sur le multitasking, sur la multitĂąche. Je pense que je vois un peu tout ça. Moi, je trouve ça chouette quand mĂȘme au niveau technique de se dire on peut le faire et c'est possible. Mais je pense que j'ai un peu passĂ© cette Ă©tape-lĂ  oĂč je me dis je vais franchir pour dire je vais le mettre en place sur mon tĂ©lĂ©phone et je vais prendre le temps de le faire. Je pense que je ne ferai plus ça.

Sacha: Tu peux consacrer ton temps sur ton ordinateur pour le travail et aprÚs ça, c'est fini.

Richard: Oui, mais pas que. Enfin, mĂȘme pour d'autres choses. Il n'y a pas que du travail. Mais effectivement, je prĂ©fĂšre utiliser l'ordinateur comme interface numĂ©rique. C'est trop limitĂ© le tĂ©lĂ©phone pour moi. Et encore une fois, c'est un environnement qui est de plus en plus contraint. Si on veut pas... C'est pas si simple d'utiliser Lineage OS parce qu'il y a des applications qui vont peut-ĂȘtre plus fonctionner. Notamment les banques, par exemple, il y en a peut-ĂȘtre qui vont plus fonctionner parce qu'on n'a pas le bon OS. C'est un peu le mĂȘme truc dont on parlait. Je me sens contraint sur le tĂ©lĂ©phone et c'est le but. Un certain nombre d'entitĂ©s de rĂ©cupĂ©rer, Ă  travers cette contrainte, des donnĂ©es. Il est lĂ , mon tĂ©lĂ©phone, il n'est pas loin. Tu sais la justification facile pour cette chose-lĂ , c'est « mais si jamais on m'appelle pour ma fille ?

Prot: » Oui, oui, oui.

Richard: Moi, je suis nĂ© Ă  une Ă©poque, on est assez vieux pour se souvenir qu'Ă  une Ă©poque, on n'avait pas de tĂ©lĂ©phone portable. Et on arrivait quand mĂȘme Ă  appeler les gens. J'en dĂ©duis rien de particulier, mais je pense qu'on est capable de s'organiser raisonnablement ou de limiter nos usages, parce que ce n'est pas inutile, je ne dirais pas jusque-lĂ . Je pense qu'on l'utilise trop. Moi, je l'utilise trop. RĂ©sumons ça. Moi, je l'utilise trop et ça me fatigue.

Sacha: Quelle est-ce ta fille ?

Richard: Elle a 6 ans.

Sacha: Ah ! TrĂšs petite. Elle est jeune.

Richard: Elle est jeune, mais c'est quand mĂȘme dĂ©jĂ  trĂšs diffĂ©rent. Et on a passĂ© les Ă©tapes les plus J'ai envie de me dire qu'on a passĂ© les Ă©tapes les plus compliquĂ©es de la gestion par rapport Ă  l'organisation de la journĂ©e. Et la façon d'interagir, parce que lĂ , maintenant, elle est Ă  un stade oĂč la discussion est totalement possible. Avant, c'Ă©tait moins facile quand ils sont tout petits. En fait, j'ai deux filles. J'en ai une qui habite avec moi maintenant et l'autre qui est trĂšs grande, qui a habitĂ© avec sa maman, qui a 18 ans. Elle fait sa vie, elle est indĂ©pendante Ă  18 ans. Il n'y a plus besoin au quotidien de choses.

Sacha: Donc, quand ta fille demande ton attention, tu dois payer toute l'attention.

Richard: Oui, et parfois elle nous fait remarquer qu'on est sur le tĂ©lĂ©phone. Et en gĂ©nĂ©ral, ça nous suffit, dis-nous parce que c'est valable pour moi et mon Ă©pouse, mais ça nous suffit pour le poser. En fait, on a un endroit oĂč on le laisse charger qui est un peu Ă©loignĂ© de quelque part dans notre salon. On a un endroit pour les charger et ce n'est pas dans la chambre, c'est un peu loin. Du coup, ils sont souvent lĂ , quand mĂȘme. Souvent lĂ , et puis retournĂ©s, comme ça, ils sonnent pas. Moi, mon tĂ©lĂ©phone, il sonne jamais, de toute façon. Il est en vibreur, dĂ©jĂ , c'est pour te dire Ă  quel point j'aime cet outil. Il est en vibreur, donc il sonne pas. J'aime pas les gadgets qui rĂ©clament mon attention. Les pop-ups, les machins, ça me stresse. MĂȘme quand je suis dans une gare Ă  Paris, par exemple, je le sais, il y a des vidĂ©os qui tournent, ça m'agresse. Tout ça, toutes les notifications, les choses, tout ça. C'est pour ça que j'aime bien Emacs, parce qu'on peut en avoir si on veut, mais par dĂ©faut, on n'a rien. En fait, ce qui est bien avec Emacs, c'est que par dĂ©faut, il n'y a rien.

Sacha: À l'exception de Visible Bell, qui peut configurer à Visible Bell ou à d'autres options.

Richard: Et pour avoir quelque chose, il faut travailler et faire ses choix. Lire, suivre des gens, c'est [??]. Ça c'est chouette. Moi, ça me va bien et j'aime bien le fait qu'il y a ait rien que on pousse pas Ă  la perception ou Ă  la prise d'attention. C'est hyper nĂ©faste en fait. On le sait sur l'attention, sur la production intellectuelle. Mais Emacs a cette qualitĂ©-lĂ  oĂč... C'est un outil de travail, vraiment pour du travail. C'est-Ă -dire un travail profond oĂč on rĂ©flĂ©chit Ă  ce qu'on fait, c'est difficile, ça prend du temps. Et c'est mĂȘme pas tant la rapiditĂ© de taper au clavier qui est importante parce que ce qui prend du temps, c'est avoir la bonne idĂ©e. Donc aprĂšs, on peut taper vite ou lentement. Finalement, c'est presque insignifiant par rapport Ă  la durĂ©e de rĂ©flexion et de la production de la chose. Donc, je pense que c'est le genre d'environnement un peu zen que j'aime bien, moi.

Sacha: Emacs, l'éditeur zen !

Richard: Non, mais c'est vrai. Puis l'image du gnu avec la flĂ»te, franchement. MĂȘme Vi est comme ça. C'est des outils, c'est des choses, des outils. Il n'y a pas de superflu. On rajoute ce qu'on veut par-dessus et ça peut devenir un monstre. ou un truc trĂšs trĂšs limitĂ©. Moi j'aime bien ces outils qu'on peut configurer en fonction du temps et du travail qu'on y accorde. Et puis j'aime bien Lisp honnĂȘtement. C'est pas OCaml mais c'est pas loin quoi. C'est dans mon top 4 avec Haskell. Ah ça serait Rust maintenant.

Prot: Ah, trĂšs bien.

Richard: J'aime bien. Rust, c'est comme langage de programmation, j'aime bien. J'en fais. J'avoue que c'est... Ils ont trouvĂ© un bon Ă©quilibre dans les idĂ©es. Ils ont pris des bonnes idĂ©es lĂ  oĂč elles existent depuis longtemps. Mais au moins, ils ont rĂ©ussi Ă  les faire passer dans le mainstream et ça, c'est important. Ça prend du temps. Que les idĂ©es percolent, comme on dit, de lĂ  oĂč elles sont produites, qui est souvent dans le milieu acadĂ©mique, jusqu'Ă  un usage, disons, industriel ou gĂ©nĂ©ralisĂ©. C'est vrai pour tout un tas d'idĂ©es intellectuelles. Ce n'est pas vrai que pour l'informatique, en particulier. Je ne sais plus ce qu'on m'avait dit quand j'Ă©tais jeune Ă©tudiant en thĂšse. C'est quelque chose comme 40 ans, 50 ans. Par exemple, le typage, les algorithmes de typage oĂč on n'a pas besoin d'annoter un programme, c'est les annĂ©es 70. L'algorithme, ça fait 55 ans qu'on sait faire ça. De lĂ  Ă  le voir arriver dans un langage oĂč les gens se disent « Ah, c'est super, je n'ai pas besoin de le faire ». Quand les langages que les gens utilisent au quotidien, ça met du temps. C'est mĂȘme pas totalement prĂ©sent partout facilement. J'ai toujours connu ça en OCaml. Quand on Ă©crit une fonction, le style traditionnel d'Ă©crire une fonction d'implĂ©mentation, on n'annote pas les types. Parce qu'on sait qu'ils vont ĂȘtre infĂ©rĂ©s, ils vont ĂȘtre calculĂ©s. Par contre, on les met dans ce qui est l'interface avec l'utilisateur parce que ça fait partie de la documentation et du contrat avec l'utilisateur. Tu dois envoyer tel type de donnĂ©es pour que ça soit correct. Donc, les idĂ©es mettent du temps Ă  transiter. Enfin, c'est comme ça. Être acceptĂ©, en fait, il y a toujours une forme de rĂ©sistance dans les idĂ©es pour qu'elles arrivent. Je ne sais pas pourquoi on est lĂ , d'ailleurs, dans cette conversation, mais c'est intĂ©ressant. Nous sommes loin d'Emacs, mais c'est quand mĂȘme... Enfin, la vision qui a amenĂ© Ă  la crĂ©ation de Lisp. Lisp, c'est vraiment un langage zen au niveau de la syntaxe, mĂȘme si les gens rigolent du nombre de parenthĂšses. Mais au niveau de la syntaxe, c'est d'une Ă©lĂ©gance minimaliste incroyable. Il y a un cĂŽtĂ© esthĂ©tique plaisant dans cette façon de voir les choses moi je trouve. C'est pour ça que j'aime bien aussi produire un peu des Maxlis parce que je ne sais pas, il y a un truc, un cĂŽtĂ© satisfaisant intellectuellement et mĂȘme il y a une forme d'art. Il y a la simplification. L'Ă©lĂ©gance. Oui, l'Ă©lĂ©gance, la simplification du tout jusqu'au cĂŽtĂ© minimaliste. Alors moi, en fait, j'aime bien ça parce que quand j'ai Ă©tudiĂ© aussi des choses comme le lambda calcul ou des choses un peu Ă  la limite de la logique et de la philosophie. La frontiĂšre est trĂšs tĂ©nue en fait, en pratique. Et une des questions que les gens se posent, c'est de combien d'opĂ©rateurs on a besoin pour calculer tout ce qui est calculable ? Bah, en fait... Donc aprĂšs, c'est pas trĂšs pratique de programmer avec un opĂ©rateur. Ah donc ĂȘtre humain quoi. Nos interfaces, on a besoin que ça soit un peu plus riche. Mais c'est voilĂ , tout le reste est comme on dit en anglais du sucre syntaxique.

Prot: Hein.

Sacha: Oui, je pense que je préfÚre la simplicité d'utilisation du juste parenthÚse au lieu de beaucoup d'autres syntaxes.

Richard: Je suis d'accord. J'aime bien ça. AprĂšs, c'est un choix de conception et de design. On a toujours un Ă©quilibre entre la facilitĂ© d'exprimer l'idĂ©e dans le langage programmation ou pas. En fait... Donc, l'interface humaine, et puis la derriĂšre, la beautĂ© ou la simplicitĂ© d'implĂ©mentation pour la machine. C'est pour ça peut-ĂȘtre que les gens aiment bien l'IA, parce que c'est facile, le langage, c'est le langage naturel. En informatique, on sait depuis un certain temps, en philosophie aussi. Il est ambigu et du coup, ce n'est peut-ĂȘtre pas terrible si on veut spĂ©cifier des choses pour une machine. C'est pour ça que les langages de programmation existent. C'est pour qu'ils aient une sĂ©mantique bien dĂ©finie. C'est une partie des choses que j'ai Ă©tudiĂ©es. La sĂ©mantique, c'est important. Et la sĂ©mantique du langage naturel.

Prot: Non, non, c'est beaucoup plus difficile.

Richard: Elle est ambiguĂ« et c'est bien parce que c'est pour ça qu'il existe la littĂ©rature et la poĂ©sie et un tas de choses. C'est comme ça que ça existe. Sinon, si c'Ă©tait non ambigu, ce ne serait peut-ĂȘtre pas gĂ©nial ce genre. Il n'y aurait pas de blague non plus. On ne ferait pas de blague. De jeu de mots. Moi, je ne crois pas trop. J'ai un petit avis sur l'IA. Ce que j'ai Ă©tudiĂ©, c'Ă©tait en particulier la spĂ©cification des langages de programmation parce que dans les mĂ©thodes formelles, un des domaines d'application, c'est qu'on a un programme et on veut vĂ©rifier qu'il fait bien ce qu'on est censĂ© faire. DĂ©jĂ , on l'a Ă©crit en code, en langage en C, peu importe, mais on a un autre langage mathĂ©matique qui dĂ©crit ce qu'il est censĂ© faire, donc spĂ©cifier. Et j'ai l'impression qu'on va en arriver lĂ , on va en arriver lĂ  en IA, mais c'est une thĂšse qui est dĂ©fendue aussi par d'autres gens. C'est pas la mienne en fait. La vraie bridge, c'est le vrai pont Ă  bĂątir, c'est comment je spĂ©cifie ce que je veux de façon non ambiguĂ« pour vĂ©rifier que l'IA fait ce que je voulais qu'elle fasse. Mais on va arriver Ă  un langage de programmation en fait. Je ne sais pas lequel, mais en tout Ă©tat de cause, c'est ça la solution, c'est les spĂ©cifications. Peut-ĂȘtre un langage, ce sera les maths. Ce n'est pas toutes les personnes qui aiment l'utiliser ce langage-lĂ .

Sacha: Je préfÚre [l'algorithme déterministe], parce que les résultats imprévisibles de l'IA sont un peu difficiles de gérer.

Richard:

Oui, oui, je suis 100% d'accord sur ça.

C'est lĂ  oĂč les diffĂ©rentes visions qui disent, mais maintenant, avant on avait l'assembleur, on avait les langages haut niveau, maintenant on a l'IA qui est au-dessus. Non, non, c'est pas du tout la mĂȘme chose. Il n'y a pas une suite de sĂ©quences bien dĂ©finie qu'on peut mĂȘme dĂ©montrer, parce qu'on a des compilateurs prouvĂ©s. Toutes les Ă©tapes sont dĂ©montrĂ©es correctes par rapport Ă  ce qu'on pensait qu'elles devaient faire. On sait faire ça, mais avec l'IA, on ne sait pas faire ça. On ne saura jamais avec cette technique actuelle. C'est impossible, ce n'est pas prĂ©vu. On se probabilise, donc c'est intrinsĂšquement impossible. Mais c'est un outil intĂ©ressant malgrĂ© tout, pour tout un tas de choses.

Sacha: Nous conversons Ă  12 heures.

Prot: Il n'y a pas que lui.

Sacha: J'ai promis à ma fille que je prends une sieste avant qu'elle se réveille pour éviter tomber à la fatigue. Oui, oui, oui. La fatigue. Donc, je pense que je dois conclure la discussion.

Richard: Pas de souci, Sacha.

Sacha: Mais je veux le continuer toujours.

Prot: Je crois que ce point est bon.

Richard: Non, c'est y a pas de souci. C'est un plaisir et il y a des cont moi. Ma fille se lÚve jamais tard donc tu vois... Moi, à 7h30 en général, elle est réveillée. J'ai pas de matinée. Elle est pas assez vieille pour faire des grasses matinées comme on dit.

Sacha: Donc, merci beaucoup. Un grand merci.

Richard: De rien.

Sacha: Merci à vous deux, Richard et Prot. Et merci aussi, chers auditeurs, pour contribuer à vos questions, vos commentaires. Je pense que je peux publier l'enregistrement de toute la session, toute la discussion, si ça marche, si ça fonctionne.

Richard: On y croit, on y croit. On croise les doigts. On croise les doigts. Oui, oui, oui.

Sacha: À plus tard. Merci beaucoup.

Richard: Merci Ă  tous les deux, Sacha et Prot.

Prot: Merci, merci, Sacha. À bientît, à bientît. Au revoir.

Richard: Au revoir.

Chat

  • sachactube:​​ J'ai totalement oubliĂ© de commencer la diffusion en direct ! Je vais publier l'enregstrement.
  • alainlamourec6332:​ ​ca rigole
  • syshYarak:​ ​bonjour j'ai une petite question pour vous j'ai deja travaillĂ© pour emacs , avec la version prĂ©configurĂ©s spacemacs , orgmod etc 
.. je prĂ©fĂšre Ă©ditĂ© avec vim juste pour ne pas utiliser la souris,
  • syshYarak:​ ​ma question c'est la suivante, je pense que c'est une rabbit hole au lieu de focaliser sur les choses les plus importantes, au lieu de crĂ©er des projets etc on se concentre sur les dotfiles etc 
..
  • phyzixlab:​ ​Sacre bleu
  • protesilaos:​ ​Salut les gens!
  • alainlamourec6332:​ ​Salut Prot
  • JonKishore11:​​ Vous ne connaissez pas l'anglais ?
  • sachactube​​C'est: en français aujourd'hui, pour le pratiquer ! =) 8:28 AM@syshYarak​

​mr si tu veux sauver un ancien utilisateur d'emacs on me proposant un M2 ou une thĂšse , car je suis ingĂ©nieur au Maroc , prot je ne t'ai pas reconnu t'avais de Long cheveux,

  • protesilaos:​ ​Oui, maintenant mes cheveux sont courts. C'est une catastrophe, haha!
  • syshYarak:​ ​j'avais l'habitude de suivre tes cours de politique europĂ©enne prot. from emacs to politics
  • syshYarak:​ ​lisp programmation fonctionnel ?
  • ahyass​​oui: c'est du fonctionnel 8:42 AM@ahyass​

​dans mon Ă©cole d'ingĂ© tout le monde utilise vim/neovim, emacs est considĂ©rer comme sauvage un peu

  • ahyass:​ ​j'ai plus d'amis qui utilisent helix que emacs, mĂȘme zed est plus populaire j'ai l'impression
  • syshYarak:​ Gestionnaire de fenĂȘtres genre i3wn ou 
?
  • ahyass:​ ​niri est d'aprĂšs mon expĂ©rience le meilleur window manager
  • protesilaos:​ ​moi j'utilise herbstluftwm
  • syshYarak:​ ​i3wm on Windows et zellij come Terminal session manager au lieu de tmux , et glazewm dans ma windows machine
  • syshYarak:​ ​j'essaie de laisser les choses simples, car l'optimisation prĂ©maturĂ© et la source des pbs.
  • syshYarak:​ ​next step learning french with emacs , en intĂ©grant des algorithmes de rĂ©pĂ©tition espacĂ©
  • protesilaos:​ ​en ce sujet lĂ , il y a un paquet nouveau qui s'appelle "srs.el"
  • protesilaos:​ ​je croix que "package" est "paquet", mais je ne suis pas sur
  • syshYarak:​ ​oui c'est ça prot , de toute façon je t'ai compris t'inquiĂšte
  • syshYarak:​ ​j'ai une petite remarque est ce que vous ĂȘtes averti qu'on peut utiliser emacs vim etc avec termux dans votre poche avec le SMARTPHONE et synchroniser votre travail avec synchthing???
  • syshYarak:​ ​non , la confite en elle mĂȘme tu peux la synchroniser et compilĂ© sur termux ,
  • syshYarak:​ ​non mais plus tĂŽt une intĂ©gration d'ai au niveau du kernel pour ce qui est tout tĂąche, en ce qui concerne ce que vous voulez spĂ©cifiquement pour vous , un entraĂźnement SUBJECTIVE de chaque individu
  • syshYarak:​ ​sera envisageable pour rĂ©duire les erreurs pour chaque personne pour reprendre au prof
View Org source for this post

You can e-mail me at sacha@sachachua.com.

-1:-- Emacs Chat avec Richard Bonichon en français (Post Sacha Chua)--L0--C0--2026-08-06T19:30:46.000Z

Raymond Zeitler: Dedicate an Emacs Window to Its Buffer

Before I start writing in Org, I dedicate the window. This "protects" the content, preventing it from being replaced by something else. It ensures I can stay focused on my writing no matter what other buffers Emacs opens.

My usual workflow is to display help on the functions I write about. Emacs opens the help buffer in another window. That's good. But then if I click on the link to the source code that help references, that file will open in my writing window, and I lose focus. Dedicating the window prevents this.

I could dedicate a window manually by invoking toggle-window-dedicated (bound to C-x w d) every time I start writing. But because I clock in to anything I'm serious about, I let org-clock-in-hook to do it for me as shown below. Note that the hook calls set-window-dedicated-p rather than toggle-window-dedicated because the latter will un-dedicate a window that's already dedicated. I could configure org-clock-out-hook to un-dedicate the window; I'm debating whether it's necessary.

(add-hook 'org-clock-in-hook (lambda () (set-window-dedicated-p nil t)))

Interestingly, while I was writing this, JTR published his "Gems" article in which he writes about setting help-window-keep-selected to true "to keep help in its own dedicated window, so it won’t open in a separate window once we follow a link."1 Perhaps that’s his approach to the same issue.


1 Emacs Config Gems - Part 3

-1:-- Dedicate an Emacs Window to Its Buffer (Post Raymond Zeitler)--L0--C0--2026-08-06T17:46:17.556Z

Irreal: Displaying The Active Clock

Over at Ray on Emacs, Raymond Zeitler has an interesting post on displaying the Org clocked in status. The default is to display it in the mode line but Zeitler wanted to display it in the title bar too. It turns out you can turn it off, display it in the mode line, display it in the title bar, or display it in both the mode line and title bar. These choices are controlled by the org-clock-clocked-in-display variable.

If you regularly clock in your tasks, having flexibility in where the status is displayed could be useful. The problem is I couldn’t find any reference to this variable in the help system or in timeclock.el, which handles the seemingly related timeclock-mode-line-display.

I updated my packages to make sure I had the latest Org Mode (I’m on Org 9.8.8) but I got the same results. I’m guessing that Zeitler is using one of the Emacs 31 prereleases, which implements this. If you’re interested in this feature and are on Emacs 31Try it on your system and see what happens. If it works for you, leave a comment.

-1:-- Displaying The Active Clock (Post Irreal)--L0--C0--2026-08-06T14:28:40.000Z

Srijan Choudhary: Emacs: desktop-save-mode without the automatic restore

Emacs has a built-in way to save and restore sessions: the desktop.el library.

As the Emacs manual says, putting this in the init file enables automatic save and restore of sessions:

(desktop-save-mode 1)

But, I wanted a different behavior:

  • Automatically save the session
  • But don't restore it automatically

I wanted to only use the session feature to restore sessions that I closed by mistake, or where I forgot to finish something before quitting Emacs. By default, I wanted a fresh session every time.

But this also means that some session history has to be maintained; otherwise, a fresh session will start to write to the desktop file and then I will not be able to recover the old session.

By default, the way to do this is to not set desktop-save-mode, but manually call desktop-save when needed, and then call desktop-read when needed. But, if I forget to save, I cannot restore.

This elisp is what I came up with to make it work the way I want:

(defvar my/desktop-snapshot-keep 5
  "How many previous sessions to keep desktop snapshots for.")

(defun my/desktop--snapshots ()
  (nreverse (directory-files desktop-dirname t
                             (concat "\\`" (regexp-quote desktop-base-file-name)
                                     "\\.[0-9]\\{8\\}T[0-9]\\{6\\}\\'"))))

(defun my/desktop--take-snapshot ()
  (let ((live (desktop-full-file-name)))
    (when (file-exists-p live)
      (let ((dest (concat live (format-time-string
                                ".%Y%m%dT%H%M%S"
                                (file-attribute-modification-time
                                 (file-attributes live))))))
        (unless (file-exists-p dest)
          (copy-file live dest t t)))))
  (dolist (old (nthcdr my/desktop-snapshot-keep (my/desktop--snapshots)))
    (delete-file old)))

(defun my/desktop--label (file)
  (format "%s   %d buffers"
          (format-time-string "%Y-%m-%d %H:%M:%S"
                              (file-attribute-modification-time
                               (file-attributes file)))
          (with-temp-buffer
            (insert-file-contents file)
            (how-many "^(desktop-\\(?:create-buffer\\|append-buffer-args\\) "
                      (point-min) (point-max)))))

(add-hook 'emacs-startup-hook
          (lambda ()
            (require 'desktop)
            (setq desktop-dirname (expand-file-name user-emacs-directory))
            (my/desktop--take-snapshot)
            (desktop--get-file-modtime)
            (let ((owner (desktop-owner)))
              (unless (and owner (desktop--emacs-pid-running-p owner))
                (desktop-claim-lock)))
            (desktop-save-mode 1)))

(defun my/desktop-restore (file)
  "Restore the desktop snapshot FILE, prompting for one interactively."
  (interactive
   (progn
     (require 'desktop)
     (let* ((snapshots (or (my/desktop--snapshots)
                           (user-error "No desktop snapshots in %s"
                                       desktop-dirname)))
            (choices (mapcar (lambda (f) (cons (my/desktop--label f) f))
                             snapshots)))
       (list (cdr (assoc (completing-read "Restore desktop session: "
                                          choices nil t)
                         choices))))))
  (desktop-release-lock)
  (let ((desktop-base-file-name (file-name-nondirectory file)))
    (desktop-read (file-name-directory file)))
  (desktop--get-file-modtime))

Note that desktop-save-mode must not be enabled before after-init-hook fires, because that's where desktop.el decides to automatically restore. So, I enable it in emacs-startup-hook, which runs later. Other things inside my emacs-startup-hook lambda are workarounds for how desktop.el works, so they can be fragile if there are major changes to it.

The lock check avoids a stale lock from a crashed Emacs silently disabling auto-save, and naming snapshots after the desktop file's mtime means restarting without saving anything doesn't use up one of the five slots.

Here's what it looks like when I call my/desktop-restore:

Emacs minibuffer showing a list of sessions to choose for restoring. Each entry shows the timestamp of last snapshot and number of buffers in that session.

Of course, this can be made better by showing more information per session (like number of projects, names of last edited files or last visited buffers). Vertico/marginalia can show it nicely. Also maybe a section in emacs-dashboard to show recent sessions and click/enter to restore. Something for another day.

-1:-- Emacs: desktop-save-mode without the automatic restore (Post Srijan Choudhary)--L0--C0--2026-08-06T08:10:00.000Z

Raymond Zeitler: Display Active Clock in Emacs Frame Title

I thought it would be helpful to modify the title of the Emacs frame to display the Org task I'm clocked in to. It turns out to be a lot easier than it sounds -- just change one Org variable in Customize.

The variable is org-clock-clocked-in-display. Its default value is mode-line. This means that the active clock displays only in the mode line. But it can have one of three other values: nil, frame title, both.

I've set it to both. Now the clocked task displays in both the mode line and the frame title. It shows the clock duration in square brackets followed by the task heading in parentheses, as shown below.

Screenshot of a small part of author's Emacs frame.  It shows the title as [1:00] (Pay Medical Bills).  Below that is the menu and the first three lines of author's Org file.

This simple update has improved my productivity significantly. The prominent display of the clocked task reminds me of what I started to do before I went down yet another rabbit. Not that rabbit holes are all bad -- I was in a rabbit hole yesterday when I found org-clock-clocked-in-display.

Try it out!

-1:-- Display Active Clock in Emacs Frame Title (Post Raymond Zeitler)--L0--C0--2026-08-05T16:20:25.067Z

TAONAW - Emacs and Org Mode: Emacs Config Gems - Part 3

My actual configs start with pretty usual stuff you’d see across many other Emacs configs. As I was going through these however, I started to wonder how things work and why they ended up the way we have them today. In turn, that led to reading about the intention behind those, which led to more options I didn’t think about. Also, it’s kind of fun. I’ve made two more passes for this part alone in the last couple of weeks, and I could probably go for a third. When reading this post, if you want the good stuff (in my opinion), get lost in the footnotes as I did. There’s a lot to explore. I just scratched the surface.

Load Melpa

Melpa is where many Emacs packages live. The story behind it (from what I can tell) revolves around one of Emacs’ maintainers, Bozhidar Batsov, who pointed to Melpa at some point in 2012, when Emacs’s then go-to third-party package repository went offline. He is not its creator — Melpa has been around before this post — but this seems to be the turning point where Emacs package maintainers started to really use it. I don’t have good coder/repository maintainer knowledge, but from what I read, it’s built on the same idea as Homebrew (for Mac), which was familiar to many of the Emacs folks at the time.

So let’s get Melpa:

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)

UI and Fundamental Emacs tweaks:

Most Emacs folks with a config file like this like to kill the toolbar, scrollbar, and menu bar. I find that the menu bar makes Emacs look more like the other programs, especially in macOS1. Besides, it’s nice to look every now and then and be reminded of good Emacs kung-fu I forgot exists (org-sort, I’m sorry my friend, I’ll keep saying hi more often).

This is why the menu-bar is commented out in my config; I want it, but I also want to remember I could turn it off if I wanted:

(tool-bar-mode -1)
(scroll-bar-mode -1)
;; (menu-bar-mode -1) 

By default, help commands2 display the help buffer in a new window without selecting it. I find this annoying: if I bring up the help window, it’s usually because I want to scroll down to find something or copy (yank) something. On the other hand, if I just want to skim quickly in the help buffer, it’s helpful that the marker is on it for a quick q for quit.

In addition, we want to be able to navigate help menus as Emacs intended if we follow the links in a help buffer. help-window-keep-selected allows us to keep help in its own dedicated window, so it won’t open in a separate window once we follow a link. Going back to the original is the same as we do in other browser-like buffers in Emacs, with l (like in Eww, for example). Likewise, we can go forward with r. I should also expand here on various help options; they definitely deserve a mention, but this is another huge topic (you can get an idea from the footer) that will take a couple of weeks. I will come back to this someday.

(setq help-window-select t)
(setq help-window-keep-selected t)

Lisp is full of parentheses, and it’s easy to lose track. Turning show-paren-mode on means that standing on an open or closed parentheses highlights its matching counterpart, which is handy.

In addition, while we’re here: when we stand on an expression that is only showing a portion of an expression (meaning, we need to scroll down to see the rest) Emacs can highlight the expression for us to make sure we don’t get confused — this is the mixed option below for show-paren-style. If you want to see the whole expression highlighted every time you’re on it, there’s the option expression, which I’m leaving here for reference for myself. For now, I think it’s too much visual noise, especially since we’re using org-edit-special, which also highlights what we’re working on.

  (show-paren-mode t)
  (setq show-paren-style 'mixed)
;; (setq show-paren-style 'expression)

And now, a true Emacs classic. I don’t think I’ve seen a config without it: shortening “yes” or “no,” answer to “y” or “n” like any other program known to mankind. use-short-answers was introduced in Emacs 28.1, which is a more graceful way to do this, intended exactly for this purpose. Before that, back when I started to use Emacs, it was done with (fset 'yes-or-no-p 'y-or-n-p). If you have an older Emacs version, you’d need it.

;;  (fset 'yes-or-no-p 'y-or-n-p)
(setq use-short-answers t)

This one was annoying until I learned this option exists from someone else’s config years ago: “Emacs, please stop asking me if I want to kill process when exiting Emacs (Shell, etc.), just do it!” Yep.

(setq confirm-kill-processes nil)

Emacs has two annoying keyboard shortcuts that I should have disabled as soon as I started using it: C-x C-c (exit Emacs) and C-z (minimize Emacs). Both of them are too easy to press by mistake, especially C-z, which is undo in many other programs. If I had a penny for each time I minimized Emacs by mistake
 When we want to minimize Emacs (and why would you want to do that? Emacs deserves a prominent space on your screen), we can just do it by clicking the minimize window itself, shamefully using our mouse, as we do with other apps. And Exiting Emacs? With a shortcut that seems like it fits somewhere in org-mode? No thanks. Let’s disable those:

(global-unset-key (kbd "C-x C-c"))
(global-unset-key (kbd "C-z"))

Turn off the annoying error beep, which I first discovered in SUSE Linux by turning on a visual warning (a flash) instead. This will flash the top and bottom lines of our window instead of going “beep!”

(setq visible-bell t)

Turn on visual line mode so text lines “wrap” inside the frame and don’t continue beyond the window’s edge. This is essential; I can’t read in Emacs without it. And a newcomer I discovered recently: since Emacs 30, we also have global-visual-wrap-prefix-mode, which preserves indentation on wrapped lines. For example, in a list in org-mode (made of dashes one under the other), a long line of text that wraps will align under its starting point (dash) in the list instead of jumping back to column 0 (the start of the window, to the most left). This has been a huge pet peeve. Finally!

(global-visual-line-mode t)
(global-visual-wrap-prefix-mode t)

Winner mode (included in Emacs) is sort of “undo” for changes in windows’ layout in Emacs. C-c ← goes back to our previous setting, and C-c → will “redo” the layout we just left. I use it all the time as in “oops, I closed the wrong window”3.

(winner-mode t)

Saw this over at https://emacsredux.com/blog/2026/04/07/stealing-from-the-best-emacs-configs/. This is a nice little trick, and it requires a bit of reading to understand what exactly it does: preventing Emacs from deleting whatever we have in the system’s clipboard when we kill a line, so it’s still in the kill ring. Here’s an example to help you grasp the idea and why it’s useful:

  1. We’re visiting a website with our default browser and copy its URL because we want to write about it in Emacs
  2. We go to Emacs, and we kill the line we’re on because we need some space
  3. Crap! Now we lost our paste in the clipboard, and we have to go back to the browser and grab that URL again!
  4. Wait, which tab was it? Did we close it? Should we look in our browsing history? Ugh!

Not anymore! With this little guy, when we kill the line (step 2 above), Emacs “injects” it into the kill ring. Now, when we yank with C-y, we will still get the last line we killed, yes, butlook up the kill ring with M-y and voilà! Your URL is there. No need to go find that URL again:

(setq save-interprogram-paste-before-kill t)

You know how for years Emacs “jumped” when you scrolled down large embedded images in your org buffers? Let’s turn on pixel-scroll-precision-mode for pixel scrolling instead of the default line scrolling to fix this. It’s pretty much what it reads: the default old way would “scroll” (it’s actually not scrolling at all) by a line of text at a time. Since our image of, say, 600px in height is treated as a single line of text, it will jump to the end of it. With this option turned on, Emacs would read the pixels from your mouse wheels as you scroll, and we get the smooth scrolling we’re used to.

Interesting to know: moving up and down the line without a mouse (arrows, or C-p and C-n) is moving by text lines, utilizing auto-windows-vscroll and line-move, which basically does in Emacs what arrow movement seems to be doing in modern applications: these apply this principle from the other direction — they natively work with pixels, so they treat these arrow movements as a fixed number of pixel movements, which is approximately a line of text. So, when you move up and down a large image (or say a PDF) in a browser, the browser thinks “ok, the user is moving up one line of text, which is.. hm.. let’s see
 ah, it says it’s exactly 40 pixels, so let me show that”.

(pixel-scroll-precision-mode t)

test break

“Emacs is the editor of tinkerers and artisans; those who are eternally dissatisfied with all other tools because of their adamantine rigidity. Crafting, or shaping, your tools to meet your exacting needs is what Emacs excels at. Because of that, Emacs is – much to the chagrin of everyone who picks it up for the first time – squarely aimed at people who already know Emacs.”

In fact, if you’re curious about help and Emacs help, I suggest you head over there now and read that post. It expands on how to approach Emacs help by how to think Emacs, which is something that experienced Emacs users struggle to explain to newcomers.

As for the history of help in Emacs, I think it’s pretty safe to say it’s been there since the start, or at least since Emacs became intended for public use, sometime around the 1980s. By that point, most of the core help parts we know today (the tutorial, C-h t; the Emacs Manual, C-h R; as well as the framework itself) were already in place. The help system was there before GNU Emacs, back in the days of TECO Emacs that RMS worked on at MIT in the 1970s. You could browse the original code from then (preserved by MIT) and see how Stallman explained what certain commands do in emacs.doc inside that repository. Another interesting find about Emacs itself (and the help system that comes with it) is the EMACS paper written by RMS back in 1981. For the help system, take a look at page 17: “6. Self-Documentation and Extensibility” and the following chapter in page 18: “7. History”. Fascinating stuff.


  1. And here, dear reader, I fell down a deep rabbit hole, one that pushed this post a couple of days. There are two parts to this. The Emacs part, which I will explore at some point in the near future, has to do with Emacs’ menu itself, which is controlled by easymenu.el. This is an old Emacs package that’s been around since 1994, written by RMS himself — kind of. It was first created by Per Abrahamsen (who seems to be a bit of a mystery, but that’s digging for another day). In turn, this package was taken from lmenu.el, which was part of yet a different Emacs fork at the time. In a regular Emacs style, the menu bar can be completely reconstructed and changed — and that’s something I want to explore soon as a way to recall useful functions I keep forgetting exist (like having an “organize” menu with something like “org-sort” under it). This will be a fun project of its own for another day. Meanwhile, the other, bigger rabbit hole is the story of the GUI menu itself as we have it today. Apple has a big role here, back in the days before Steve Jobs left Apple and worked on the Lisa. This seems to be the first usage of a graphical interface in personal computers, and the menu, which was taken from Xerox, was a big part of it (there’s a short YouTube video there that would give you a quick brief of what happened). This means that I am right on keeping the menu in theme with the rest of the Mac apps, based on history! â†©ïžŽ

  2. Emacs’ built-in help deserves its own series of posts. Looking at it now, from the eyes of someone who used it for a couple of years, I find Micky’s description satisfying, reflecting what I felt at the time: â†©ïžŽ

  3. I forget how exactly, but some research into winner-mode history (turns out it’s been around since 1997 — also, a lot of goodies here to look into!) led me down the path of tabs in Emacs, tab-bar in particular. I didn’t think much about tabs in Emacs, but since I’ve been using Kubuntu for a while and experimented with its Workspaces, I understand the concept better. I looked into BSAG’s post, and it looks like you can hide the tabs while still displaying them on the mode line, and of course, you don’t have to use the mouse. The concept of having a whole workplace completed with its unique window arrangement available with a single keyboard shortcut is alluring. Now, instead of playing around with where and how I want my windows to display, I can just save (or re-create) those, and I always have a “work” environment vs a “personal” environment within the same Emacs frame. This can be a good organizational feature. I’m going to dig more into this one. â†©ïžŽ

-1:-- Emacs Config Gems - Part 3 (Post TAONAW - Emacs and Org Mode)--L0--C0--2026-08-05T13:06:09.000Z

Protesilaos: Emacs: the ‘speedbar’ built-in file explorer (Emacs 31)

Raw link: https://www.youtube.com/watch?v=Crn6x3RmmyQ

In this video I demonstrate the built-in ‘speedbar’ command. This is the file explorer that Emacs ships with. Starting with Emacs 31, the ‘speedbar’ can be configured to appear on the side of the frame. Whereas the default is to show up in a separate frame. To me, the default is impractical, whereas the new option turns ‘speedbar’ into a very useful piece of functionality.

-1:-- Emacs: the ‘speedbar’ built-in file explorer (Emacs 31) (Post Protesilaos)--L0--C0--2026-08-05T00:00:00.000Z

Charlie Holland: Gödel, Escher, Elisp: The Beauty of Macros

1. TLDR

escher-drawing-hands.jpg

If you are an Emacs user with a keen eye, you will have noticed that in Emacs Lisp, code is data. After all, 'Lisp' is shorthand for 'List Processing'. One of Elisp's most beautiful features is the fortuitous blur between the thing that is processing the list (the program) and the list itself (the data). The macro in Elisp is a utility that exploits this blur and allows you to leverage this dualism between program and data in many useful and fascinating ways.

In this post, I want to swoon about macros, explain what "homoiconic" actually means, demonstrate their ubiquity in Elisp, depict their beauty on a detour through Hofstadter's strange loops and Escher's prints, and finally show off some tooling (macroexpand, emacs-lisp-macroexpand, macrostep) that enhances both comprehension and appreciation of macros.

Here is the Escher imagery we'll be leaning on along the way:

2. Programs as Data, Data as Programs   emacs elisp lisp

The kernel of Lisp has a crystalline purity that not only appeals to the esthetic sense, but also makes Lisp a far more flexible language than most others.

— Douglas Hofstadter

An important word for this post is homoiconic. A language is homoiconic when its programs are written in the language's own data structures.

Few languages are homoiconic, and the Lisp family wears the property most proudly, with Emacs Lisp (Elisp) being the dialect many of us are most familiar with. In Elisp, source code is lists, symbols, strings, and numbers. Code looks exactly the same as lists you build with cons and take apart with car and cdr.

The distinction between program and data is exhibited by a specific, special character, the glorious ':

;; a program: evaluates to 3
(+ 1 2)

;; data: a list of three elements — a symbol and two numbers
'(+ 1 2)

The quote tells the evaluator not to run the form that follows, but to treat it as plain data (a list).

To emphasize that program and data are equivalent in Elisp, running eval on the quoted list (as in (eval '(+ 1 2))) will turn it into a program, where the function is addition, and its arguments are the numbers 1 and 2.

That dualism lies at the heart of the language. Any piece of code is one character away from being a value you can inspect, transform, and rebuild; and any suitably-shaped value is one function call away from being a program.

So in Elisp, we say Program = Data, even though that's a little too simplistic, because we saw how correctly the Lisp interpreter deciphers when a list is being represented as a program versus when it is being represented as data
. The point is the list: that's the unifying form. Maybe more appropriately, we can say the program and data take the same form, or as previously mentioned, Elisp's programs are written in Elisp's own data structures.

This post was motivated by a simultaneous obsession with Douglas Hofstadter's writing and Elisp macros, so be prepared for many depictive metaphors from one of Hofstadter's favourite artists, M.C. Escher. Here's the first:

Escher drew this kind of dualism as a woodcut. The ants of Möbius Strip II appear to march on both sides of a strip. The image is provocative enough at first glance, but I invite you to follow any one of them around and discover that the two sides are one continuous surface. Program and data are the two sides of Elisp's homoiconic Möbius.

escher-mobius-strip-ii.jpg

Figure 1: M.C. Escher, Möbius Strip II (1963). Two sides, one surface. © The M.C. Escher Company.

In most languages, metaprogramming lives in a separate layer with its own representation of code like templates, reflection APIs, token streams, quasi-quoted ASTs. Some of those layers are crude and some are genuinely sophisticated, but each is a wall between code and data. In Elisp there was never a wall to tunnel through. Elisp enables metaprogramming, but it's the same language, and the same data structures, all the way down.

3. What a Macro Actually Is   emacs elisp macros

Consider a regular function in Elisp. A function receives values and computes a value at runtime.

On the other hand, a macro receives code (the raw, unevaluated forms typed at its call site) and returns new code, which is then evaluated in its place. Macros run at expansion time, before your program does. I like to think of macros as little programs that write other programs given the arbitrary forms they can accept. The complexity of that form -> program projection is essentially infinite, or at least bounded by what you can express in Elisp, which is very likely bounded by your imagination.

The macro's form -> program toolkit is quasiquotation: backquote ` builds a code template, comma , inserts a computed piece, and ,@ splices in a list. Here's the smallest real macro I can write, a reimplementation of unless:

(defmacro my-unless (condition &rest body)
  "Run BODY unless CONDITION is non-nil."
  (declare (indent 1))
  `(if ,condition nil ,@body))

We can actually ask Emacs what this macro will get expanded to. The first code block is the call to macroexpand-1, the second is the expansion it returns:

(macroexpand-1
 '(my-unless (file-exists-p "~/notes")
    (make-directory "~/notes")
    (message "created it")))
(if (file-exists-p "~/notes") nil
  (make-directory "~/notes") (message "created it"))

To anticipate a common question: why couldn't my-unless be a function? Function arguments are evaluated eagerly, before the function ever sees them. A function version would evaluate (make-directory "~/notes") while its arguments were being prepared, before the condition could ever be consulted. So, when ~/notes already exists, instead of doing nothing it would signal a file-already-exists error, and the message would never run at all. In other words, the function receives the results of the body, but the point of using a macro here is to decide whether the body runs at all. A macro receives the body as inert data, so control flow itself is up for grabs. In this way, you are extending what the language can express.

4. You've Been Using Macros All Along   emacs elisp macros

Macros may seem specialist or eccentric
. I hope this surprises the Elispiens who are reading this! It certainly surprised me!

  • when and unless are macros over if.
  • dolist and dotimes are macros over while.
  • push, pop, and setf are macros that rewrite themselves into the right mutation for the place you provide them with.
  • with-current-buffer, with-temp-buffer, and ignore-errors are macros that wrap your code in the correct save-and-restore ceremony so you never have to type it.
  • Even defun is a macro!

The most justifiably famous macro in any Emacs config is use-package:

(use-package magit
  :bind ("C-c g" . magit-status)
  :hook (git-commit-mode . flyspell-mode))

:bind and :hook aren't Elisp, but rather keywords in a small configuration language, and the use-package macro is its 'compiler', expanding the declaration into the require calls, keymap bindings, hooks, and autoload deferrals that would otherwise need to be written out by hand in their full, verbose form.

The define-minor-mode macro is similar in this way. One declaration expands into a variable, an interactive toggle command, keymap wiring, and documentation. This is what is meant by macros letting you grow a language toward the problem. With macro use, your config can read more like a declarative description of what you want, because someone built a macro for that (in use-package's case, shout out to John Wiegley).

The most shocking instance in my deep dive was defun. Evaluate (macrop 'defun) and the result is t, indicating that, yes, defun is a macro (again, the first code block is the call to macroexpand-1, the second is the expansion it returns):

(macroexpand-1 '(defun greet (name) "Say hi." (message "Hi, %s" name)))
(defalias 'greet #'(lambda (name) "Say hi." (message "Hi, %s" name)))

Defining a function turns out to mean this:

  • build an anonymous function
  • alias a symbol to it

More surprises
.

Did you know that lambda itself is also a macro (albeit a delightfully small one that expands into a function-quoted version of itself)? Surely not my beloved defcustom? Yes, my fellow Emacsapien, that is also a macro.

(macroexpand-1
 '(defcustom chiply/favorite-lithograph "Drawing Hands"
    "Which Escher lithograph to contemplate while macroexpanding."
    :type 'string
    :group 'chiply))
(custom-declare-variable
 'chiply/favorite-lithograph '"Drawing Hands"
 "Which Escher lithograph to contemplate while macroexpanding."
 :type 'string :group 'chiply)

(If you try this in *scratch* or ielm you'll see something gnarlier: the default value comes back wrapped in (funcall #'(lambda () ...)). Under lexical binding; which is the default in *scratch*, ielm, and M-: since Emacs 27; defcustom wraps the default in a closure so Custom can re-evaluate it later. Org evaluated this block with dynamic binding, hence the simpler form above. Either way the point stands: defcustom is a macro, and one expansion away from a plain function call. Just know that macro's expansion can depend on the environment it expands in.)

cl-loop, that entire iteration mini-language, much overused by yours truly? That's also a macro!

If you want to see all the macros, just run this.

(let (names)
  (mapatoms (lambda (s) (when (macrop s) (push (symbol-name s) names))))
  (with-temp-buffer
    (setq fill-column 72)
    (insert (mapconcat #'identity (sort names #'string<) " "))
    (fill-region (point-min) (point-max))
    (buffer-string)))

It seems like all the code you are writing is somehow being compiled in place to other code, so where does this end? It ends at the special forms — if, let, setq, while, quote, save-excursion, condition-case, and their friends implemented in C. When you macroexpand any Elisp program all the way down, what remains is composed of special forms, plain function calls, and the variables and constants they operate on. The functions do the work (about fifteen hundred are C primitives like car and cons; the rest are written in Elisp). The special forms decide how evaluation flows. And every piece of syntax above that floor (when, dolist, setf, use-package, even defun) is macros written in Elisp. The foundation is C, but the architecture is built out of the tower's own bricks.

The distinction between special form and macro deserves closer inspection, because at the call site a macro and a special form are indistinguishable. Neither special forms nor macros evaluate their arguments the normal way, which is why when and if feel similar. The difference is clear when you introspect. when is a macro, so it is obliged to explain itself: macroexpand turns it into if. In contrast to when, if explains nothing about itself — it is an evaluation rule, wired into the interpreter's C. A macro must always expand away, whereas a special form is where expanding stops. Put another way, a macro is a special form you're allowed to write yourself, on the condition that it has to compile down to the real forms. The real ones number exactly twenty-two in the Emacs I'm writing this in (swap special-form-p for macrop into the census above to meet them), and cond, and, and or are among them.

Escher cut his Tower of Babel in 1928, and its subject is a construction project failing, because the builders stopped sharing a language. Elisp's tower stands for precisely the opposite reason: from use-package at the summit down to the special forms at the footing, every floor is written in the same tongue.

escher-tower-of-babel.jpg

Figure 2: M.C. Escher, Tower of Babel (1928). Babel's construction stalled when its builders' languages diverged; Elisp's tower keeps rising because every floor expresses the same language (Elisp). © The M.C. Escher Company.

5. Rolling Your Own   emacs elisp macros config

I think this is a common use case. Let's say you keep writing a command that sets a variable and reports what happened. Maybe you have one for debug-on-error, one for truncate-lines, etc
. The pattern of thought is: "give me a command that toggles this variable." Capturing the pattern in a macro is useful in this case:

(defmacro deftoggle (var)
  "Define a command `chiply/toggle-VAR' that toggles the variable VAR."
  `(defun ,(intern (format "chiply/toggle-%s" var)) ()
     ,(format "Toggle the variable `%s'." var)
     (interactive)
     (setq ,var (not ,var))
     (message "%s is now %s" ',var (if ,var "on" "off"))))

One line per toggle, forever after:

(deftoggle debug-on-error)
(deftoggle truncate-lines)

Expanding the first one shows what you actually wrote:

(macroexpand-1 '(deftoggle debug-on-error))
(defun chiply/toggle-debug-on-error nil
  "Toggle the variable `debug-on-error'." (interactive)
  (setq debug-on-error (not debug-on-error))
  (message "%s is now %s" 'debug-on-error
           (if debug-on-error "on" "off")))

Our single line macro invocation does a lot:

  • It interned a new symbol — M-x chiply/toggle-debug-on-error now exists as a command.
  • It wrote a docstring, computed at expansion time, that shows up properly in C-h f.
  • It emitted an interactive declaration.

Now, a fair objection: a plain function could have produced all three of these effects at runtime - defalias interns a symbol, accepts a docstring, and wraps an (interactive) lambda. What a function can't give you is the call site and the timing. You'd write (make-toggle 'debug-on-error), a quoted symbol handed to runtime machinery, and the byte compiler would never see the definition. The macro receives the bare name and leaves a real defun in the expanded source, where C-h f, the byte compiler, and every other source tool can find it!

You haven't merely written a helper, but more importantly, you've added a new defining form to the language, a small sibling of defun and defvar that communicates in the diction of your problem domain. That's another beauty of Elisp macros: the abstraction is expressed and interpreted at the same level as the primitives it imitates.

6. Strange Loops and Drawing Hands   emacs elisp hofstadter geb

I've been recently obsessed with the writing of Douglas Hofstadter, and he spent three of his Scientific American columns in 1983 teaching Lisp (the first, "Lisp: Atoms and Lists", survives online), later collected in Metamagical Themas. He opens with a mission statement:

Why is most AI work done in Lisp? There are many reasons, most of which are somewhat technical, but one of the best is quite simple: Lisp is crisp. Or as Marilyn Monroe said in The Seven-Year Itch, "I think it's just elegant!"

— Douglas Hofstadter, "Lisp: Atoms and Lists" (1983)

It's no coincidence that the author of the great book about self-reference (Gödel, Escher, Bach) fell for this language: Lisp is probably the most GEB-shaped artifact in computing.

The engine of GEB is Gödel numbering: encoding statements about arithmetic as arithmetic, painstakingly numbering every symbol until number theory could be made to talk about itself. (For a gentle tour of how the proof uses it, see Quanta's explainer; for this post, the gist is enough.)

It took a stroke of genius to build that bridge, because sentences and numbers live in different worlds. In Lisp, it seems, the bridge comes built-in, as the sentence already is the data structure. Hofstadter saw the temptation, and near the end of GEB he stages this exact argument, letting the Crab assume the burden of proof, in the book's most enchanting 'fugue':

Well, in the programming language LISP, you can talk about your own programs directly, instead of indirectly, because programs and data have exactly the same form. Gödel should have just thought up LISP, and then—

— the Crab, in Gödel, Escher, Bach (20th-anniversary ed.), p. 738

The Crab is making this post's argument: programs and data have exactly the same form, and quote is precisely the formalized quotation he goes on to wish Gödel had invented. But!

But the Author (Hofstadter) interrupts him:

Author: 
no reference is truly direct — every reference depends on SOME kind of coding scheme. It's just a question of how implicit it is. Therefore, no self-reference is direct, not even in LISP.

Hofstadter is right, of course. Look under a quoted form and there is still a code: reader syntax, interned symbols, and cons cells laid out in memory. Lisp didn't abolish Gödel's bridge, but arguably simplified it for the programming use case. It built the bridge so well, and sank it so deep beneath the syntax, that you can cross it naively.

A strange loop is Hofstadter's coinage, and GEB defines it in its opening pages:

"The 'Strange Loop' phenomenon occurs whenever, by moving upwards (or downwards) through the levels of some hierarchical system, we unexpectedly find ourselves right back where we started."

Escher's Drawing Hands is his canonical image of this phenomenon. In this hand-drawn drawing of drawing hands, each hand draws the hand that is drawing it, and is both sketcher and sketch at once. Elisp hides the same lithograph in its bootstrap. defmacro, the form you use to create macros, is itself a macro. The hand that draws hands is drawn; the macro that defines macros is a macro.

escher-drawing-hands.jpg

Figure 3: M.C. Escher, Drawing Hands (1948). Each hand draws the hand that draws it. (macrop 'defmacro) ⇒ t. © The M.C. Escher Company.

If the Drawing Hands image has you thinking about macros, know that the loops nest. A macro can expand into code that contains more macro calls — remember that defun hiding inside deftoggle? Take it one story higher:

(defmacro deftoggles (&rest vars)
  "Define a toggle command for each variable in VARS."
  `(progn ,@(mapcar (lambda (v) `(deftoggle ,v)) vars)))

(deftoggles debug-on-error truncate-lines)
;; ⇒ (progn (deftoggle debug-on-error) (deftoggle truncate-lines))
;; ⇒ ... (defun chiply/toggle-debug-on-error () ...)
;; ⇒ ... (defalias 'chiply/toggle-debug-on-error #'(lambda () ...))

A program writing a program writing a program writing a program. Hofstadter's running metaphor for the Lisp interpreter is a genie granting wishes, and even while introducing the language's basics, having just shown the reader that Lisp statements are themselves lists, he spots exactly this loop:


the Lisp genie, by manipulating lists and atoms, can actually construct new wishes by itself. Thus the object of a wish can be the construction — and subsequent evaluation — of a new wish!

— Douglas Hofstadter, "Lisp: Atoms and Lists" (1983)

A macro is precisely that: a wish whose object is a new wish.

This kind of macro expansion makes me think of Escher's Print Gallery, where a young man stands in a gallery looking at a print of a seaport, and the print swells outward until it contains the gallery, and the young man, inside it. Each level of a macro expansion is a picture that turns out to contain the room you were standing in.

Escher famously couldn't finish this paradox. At the center of the lithograph, where the loop closes on itself, he left a blank patch and signed his name. The Elisp tower has its blank patch too. When you expand all the way down, you bottom out at the special forms, where the language stops being written in itself and things move over to C.

escher-print-gallery.jpg

Figure 4: M.C. Escher, Print Gallery (1956). The print contains the gallery that contains its viewer; at the center, where the loop closes, Escher left a blank patch and his signature. © The M.C. Escher Company.

The program–data dualism has its own lithograph: Reptiles, where a lizard crawls out of a flat sketchbook drawing, climbs up over a book and a dodecahedron as a living, three-dimensional creature, and then climbs back into the page to become a drawing again. That is quote and eval exactly. A quoted form is the lizard on paper (inert, flat, safe to handle), whereas eval is when it climbs off the page and comes to life. Macros do their work on the paper lizards, rearranging drawings that will shortly be alive, their hearts beating in the Lisp interpreter.

escher-reptiles.jpg

Figure 5: M.C. Escher, Reptiles (1943). Off the page, around the desk, back onto the page. This is eval and quote as lithograph. © The M.C. Escher Company.

There's one more Hofstadter obsession that Lisp exhibits. GEB's deepest question is how meaning condenses out of meaningless symbol-shuffling, layer by layer. Lisp is unabashed about the importance of symbols here because its atoms are literally called symbols. Symbols are Elisp's first-class objects you can pass around, compare, and define (deftoggle interned one for you). And each floor of the expansion tower speaks its own language: the use-package form speaks configuration, its expansion speaks hooks and keymaps, and the floors below speak control flow (special forms again), until meaning has condensed all the way into machine operations. No floor is the "real" one. Instead, the whole thing is a tangled hierarchy that you can inhabit. With Emacs, you can ride up and down at will. Here's how.

7. Seeing Through the Magic   emacs elisp tooling

If macros were opaque, all of this would be unsettling, because you could create arbitrarily abstracted code-expanding-code that defies introspection. What keeps macros honest is that Emacs will show you the expansion at every level, as long as you know the utilities needed to make it do that. There's a passage late in GEB, where Hofstadter is explaining why introspection can't reach our own machinery, that makes the stakes of that vivid:

We feel self-programmed. Indeed, we couldn't feel any other way, for we are shielded from the lower levels, the neural tangle. Our thoughts seem to run about in their own space, creating new thoughts and modifying old ones, and we never notice any neurons helping us out! But that is to be expected. We can't.

An analogous double-entendre can happen with LISP programs that are designed to reach in and change their own structure. If you look at them on the LISP level, you will say that they change themselves; but if you shift levels, and think of LISP programs as data to the LISP interpreter (see chapter X), then in fact the sole program that is running is the interpreter, and the changes being made are merely changes in the pieces of data. The LISP interpreter itself is shielded from changes.

— Douglas Hofstadter, Gödel, Escher, Bach (20th-anniversary ed.), p. 692

escher-hand-with-reflecting-sphere.jpg

Figure 6: M.C. Escher, Hand with Reflecting Sphere (1935). The observer holds the sphere that contains the observer: introspection with the shield lifted. © The M.C. Escher Company.

The second paragraph is again evocative of Print Gallery's blank patch. However wildly your macros rewrite the language, the machinery below them is never touched. The first paragraph highlights a special way in which your editor (Emacs) is better off than your brain. We feel self-programmed but are shielded from our own neural tangle; we cannot watch our thoughts being implemented. In Emacs, the shield is optional.

Escher made a self-portrait of that privilege: Hand with Reflecting Sphere, the artist holding the mirror in which the artist, the room, and the holding hand are all visible at once. Every level of the expansion is there to be seen. In Emacs, these are the tools you can use to introspect macros and detangle the tangled hierarchy:

  • The functions. macroexpand-1 performs exactly one step of expansion — when becomes if, and stops. macroexpand keeps expanding the top-level form until it isn't a macro call anymore. macroexpand-all recurses into subforms too, grinding everything down to special forms and function calls. Evaluate them in *scratch* or ielm, wrapped in pp for readable output.
  • In place, in your buffer. M-x pp-macroexpand-last-sexp with point after a form pops the pretty-printed expansion into a separate buffer — the low-commitment option. M-x emacs-lisp-macroexpand with point before a form is the committed one: it replaces the form in your buffer with its expansion, properly indented. It's unbound by default and undo restores the original, so it's a safe and weirdly satisfying way to peel a layer off right where you're working.
  • Interactively: macrostep. macrostep (on MELPA) makes macro debugging feel like using a debugger. M-x macrostep-expand on a macro call shows the expansion inline, as an overlay. Press e to expand the next macro call inside the expansion, c to collapse a level, q to collapse everything and leave. Macro-generated symbols are highlighted, so you can see exactly which code came from your template and which came from the call site. When a macro you're writing misbehaves, stepping through its expansion layer by layer, in place, is usually all the debugging you need.

And if you want to know what running macrostep feels like, Escher printed that too. Metamorphosis II is a single strip, nearly four metres long, that begins with the word metamorphose, dissolves it into a checkerboard, the checkerboard into lizards, the lizards into honeycomb, bees, fish, birds, a town on the Mediterranean, a chessboard, and finally, at the far end, the word it began with. Stepping through an expansion is walking that strip: deftoggles to deftoggle to defun to defalias. Meaning gets transformed one panel at a time, and the first and final forms are both Elisp.

escher-metamorphosis-ii.jpg

Figure 7: M.C. Escher, Metamorphosis II (1939–1940), shown in four stacked rows. One form becomes another by lawful local steps, like a macro expansion laid out lengthwise. © The M.C. Escher Company.

8. With Great Power   emacs elisp macros

Hofstadter, watching definitions build on definitions in that same column, issues a warning: "The whole thing snowballs rather miraculously, and you can quickly become overwhelmed by the power you wield."

He's right, and power over syntax cuts both ways. A macro nobody else can read is a private language. A macro that evaluates its arguments twice, or accidentally captures a variable the caller was using (the classic fix is generating fresh symbols with gensym), fails in ways plain functions don't.

Escher drew this failure mode. A buggy macro is Escher's Belvedere, where every line of the expansion is locally reasonable, but where the whole is impossible. (Notice the boy on the bench in the foreground, calmly studying the impossible cube in his hands. That's you, mid-macroexpand.)

escher-belvedere.jpg

Figure 8: M.C. Escher, Belvedere (1958). Joints are locally sound, but the building is globally impossible. The classic shape of a macro bug. © The M.C. Escher Company.

And for the macro that expands into a call to itself with no base case, Escher supplied his classic staircase illusion, where the monks of Ascending and Descending climb a loop that rises forever and never exits.

escher-ascending-descending.jpg

Figure 9: M.C. Escher, Ascending and Descending (1960). A staircase that rises forever: the macro that expands into itself. © The M.C. Escher Company.

The Emacs community's rules of thumb are worth keeping in mind. Reach for a function first, and use a macro when you need to do something that a function can't, like controlling evaluation, establishing bindings, or defining new things. And keep expansions boring. The cleverness belongs in the macro's template, not its output.

I hope you notice these are the responsibilities of a language designer, because that's what a macro makes you.

9. Bending the Metal   emacs elisp lisp

Because programs are data in Elisp, the language can be reshaped in the language. The boundary between writing a program and designing a language dissolves.

Escher's Waterfall is a portrait of such a machine. The water falls, turns the wheel, and sets off along an aqueduct, where, three bends later, it pours over the top of its own fall again. The loop powers itself. That is what a self-extending language looks like from the outside: Elisp, extended by macros, written in Elisp.

escher-waterfall.jpg

Figure 10: M.C. Escher, Waterfall (1961). Every stretch of the channel runs downhill, and the water returns to the top of its own fall: a loop that powers itself. © The M.C. Escher Company.

-1:-- Gödel, Escher, Elisp: The Beauty of Macros (Post Charlie Holland)--L0--C0--2026-08-04T14:08:50.000Z

Andros Fenollosa: EWW, the Emacs browser you underestimate

The first time I opened a web page inside Emacs I thought it was a trick, a hack, a toy... studying it in depth I saw I was wrong. EWW is a browser written 100% in Emacs Lisp, with no external engine behind it (no WebKit, Blink or Gecko). It is absurdly lightweight, intelligently designed and, almost without meaning to, it hands you a platform to do scraping or automate web tasks in a few lines. A tool with enormous potential that many people don't know about, even within the Emacs community itself.

And the best part is that you already have it installed. It ships with Emacs by default. To launch it just run M-x eww and type a URL or a search term (it will open DuckDuckGo).

Is it a replacement for Chrome or Firefox? No, and it doesn't try to be. It plays in a different league.

Two pieces: EWW and SHR

What we call "the Emacs browser" is really two pieces working together.

  • EWW (eww.el) is the browser layer: URLs, history, bookmarks, forms, cookies, downloads and sessions.
  • SHR, or Simple HTML Renderer (shr.el), is the engine that turns HTML into text inside a buffer. And EWW is not the only one using it: Gnus for mail, elfeed for feeds, and quite a few other packages share it too.

Here's the key: SHR doesn't draw a page, it translates it. It takes the HTML and paints it as Emacs text, with its faces and its properties. What does it understand along the way? Quite a bit more than you'd imagine:

  • Rich text: b, i, em, strong, u, s, code, tt, mark, ins, del, sup, sub, abbr, bdo/bdi.
  • Structure: h1..h6, p, div, blockquote, pre, hr, ul/ol/li, dl/dt/dd.
  • Links and tables.
  • Images: it understands data: URIs (base64), srcset (it picks the resolution), cid: (mail), scaling with shr-max-image-proportion, animation and zoom. And if a src is broken, it falls back to its alt text, as it should.
  • MathML: it keeps the TeX annotation, it does not render the formula.

Forms are a curious case: SHR doesn't add them, EWW layers them on top via shr-external-rendering-functions. Thanks to that you can submit GET and POST forms, and even multipart/form-data to upload files.

Two things are missing from the list: JavaScript and CSS.

What EWW doesn't do (and why that's fine)

EWW is not meant to run modern web applications. Its limitations aren't an oversight, they are the reason it's so fast and so lightweight. But you'd better be clear about them before you get frustrated.

No JavaScript. This rules out, in one stroke, any SPA (React, Vue, Angular), infinite scroll, content that arrives via fetch or XHR, and most of today's web. If a page needs JS to paint itself, in EWW you'll see little or nothing.

No CSS. The code itself confesses it in its header: "It does not do CSS, JavaScript or anything advanced". In practice:

  • <style> sheets and <link rel=stylesheet> are ignored completely. Only the inline style attribute is read, and only if it contains color, display (specifically none) or border-collapse. Everything else (font-size, margin, padding, float, flex, grid, text-align...) is thrown in the bin.
  • Colors require (display-color-cells) >= 88. And the contrast system is surprisingly serious: it converts to CIE Lab and uses CIE DE2000 distance to make sure the text is readable.
  • There are no class or id selectors, no cascade, no specificity. Nothing.

The parser is not HTML5-conformant. It uses libxml2, which is tolerant but does not follow the HTML5 parsing algorithm to the letter. Manual patches are applied to plug the holes.

EWW is not for SPAs, online banking, JS dashboards, dynamic forms, anything that throws a "enable JavaScript to continue" at you, embedded video or audio, or layouts that are only legible thanks to CSS. It's not its turf, and forcing it is a waste of time.

Scraping out of the box

EWW leans on libxml-parse-html-region, which gives you back the DOM as an S-expression. And Emacs includes dom.el to walk it. That makes scraping trivial, and you don't even need to open EWW.

Look at this script. It extracts the headlines from the Hacker News front page:

(require 'dom)
(require 'url)
(require 'cl-lib)

(defun demo-scrape (url)
  "Download URL and return the Hacker News headlines as a list of conses.
Each element is (TITLE . HREF)."
  (with-current-buffer (url-retrieve-synchronously url t t 30)
    (goto-char (point-min))
    ;; Skip HTTP headers until the first blank line.
    (re-search-forward "\r?\n\r?\n" nil t)
    (let* ((dom (libxml-parse-html-region (point) (point-max)))
           ;; On HN each headline is <span class="titleline"><a>...</a>.
           (titles (dom-by-class dom "titleline")))
      (mapcar (lambda (node)
                (let ((a (dom-child-by-tag node 'a)))
                  (cons (string-trim (dom-texts a))   ; link text
                        (dom-attr a 'href))))          ; destination
              titles))))

(defun demo-scrape-hn ()
  "Download the Hacker News front page and show the headlines in a buffer."
  (interactive)
  (let ((items (demo-scrape "https://news.ycombinator.com/")))
    (with-output-to-temp-buffer "*HN headlines*"
      (princ (format "Headlines found: %d\n\n" (length items)))
      (cl-loop for (title . href) in items
               for i from 1
               do (princ (format "%2d. %s\n    %s\n\n" i title href))))))

;; Evaluating the buffer (M-x eval-buffer) runs it directly:
(demo-scrape-hn)

Evaluate it with M-x eval-buffer and a temporary buffer will pop up with the list of headlines and their links. No external libraries, nothing to install.

This is possible because dom.el gives you a handful of functions that do the heavy lifting: dom-by-tag, dom-by-class, dom-by-id, dom-child-by-tag, dom-attr, dom-text and dom-texts. And if instead of the raw HTML you want the already-rendered text (for example, to index the "readable" version of a page), you can run the DOM through shr-insert-document in a temporary buffer and keep buffer-string. This is, literally, the foundation on which elfeed or mu4e are built.

Designing "for EWW" is designing well

Let me switch perspective. So far we've talked about EWW as a reader. But what if you're the one publishing? What if you want your site to look flawless in there?

The good news is that designing for EWW isn't learning some weird dialect. It's going back to the principles of semantic HTML, the ones that should never have been abandoned. EWW renders HTML as a structured document, not as a canvas painted with CSS. Follow these ideas and, as a bonus, your site will be more accessible everywhere.

DOM order is on-screen order

SHR walks the tree in document order and inserts the text just as it finds it. There is no CSS reordering: float, flex, grid, order and position don't exist. Whatever you put first in the HTML appears first.

So place the main content as early as possible in the DOM, or at least right after opening the <body>. Long <nav> blocks and footers go at the end.

Mark up structure with tags, not with styles

SHR gives its own faces to h1..h6, b/strong, i/em, u, code, pre, blockquote, lists, mark and del/ins. Use them for what they mean, not for how they look:

  • Real headings <h1>..<h6> for hierarchy. Never a <div class="big">.
  • <ul>/<ol>/<li> for lists and <dl>/<dt>/<dd> for definitions.
  • <blockquote> for quotes (it indents) and <pre> for preformatted blocks or ASCII art (it disables reflow).
  • <code> for inline code (fixed-width face).

Watch out for the HTML5 semantic elements (article, section, nav, header, footer, main, aside, figure): they have no render of their own. They're treated as transparent containers and only contribute their textual content. They're fine for giving meaning to the document, but don't expect them to "show".

Don't rely on CSS for anything essential

You already know: only the inline style attribute is read, and only color, background-color, display and border-collapse. The rest is ignored. From that come three rules worth tattooing on yourself:

  • Your page must be legible with CSS completely disabled. If it isn't, that's not an EWW problem, it's an HTML problem.
  • Don't hide content with a display:none class. SHR won't apply it and that content will show up anyway. If you really need to hide something it would have to be style="display:none" inline, but that's bad practice. Better not to put that content in at all.
  • Don't convey information with color alone. Even though inline color works, it demands enough contrast (that strict CIE DE2000 filter) and on poor terminals it isn't applied at all. A "required field in red" or a "green = correct" vanishes. Always back it up with text or symbols.

And a consequence that sneaks in: spacing (margin, padding, line-height) doesn't exist. Separation comes from paragraph breaks. Structure with real <p> tags, not with stray <br> or empty divs.

Tables: for data only, never for layout

SHR draws <table> as a surprisingly good ASCII grid: it measures columns, distributes widths and even emulates colspan and rowspan. But it has its rules:

  • Use them only for real data. A layout table produces an absurd, illegible grid.
  • Watch the width. If the sum of the columns exceeds the frame, EWW just turns on truncate-lines and the experience degrades. Fewer columns and short cells fare much better.
  • Images inside cells aren't embedded in the cell (a buffer limitation): they're inserted after the table. If order matters, avoid images in there.

Images with alt and srcset

Yes, Emacs shows images in graphical buffers. But don't get cocky:

  • Always give a descriptive alt. It's what shows if the image is blocked, broken or if the user browses without images. In many EWW flows, the alt is the content.
  • srcset is supported: EWW picks the right resolution for the frame width, so offer it several.
  • Images load asynchronously over a placeholder, they don't block the text render. Don't rely on an image to communicate anything critical.
  • data: URIs (base64 included) work, handy for small embedded icons.

Forms that actually work

Forms are fine if they're pure HTML with action and method (GET or POST, including multipart/form-data for files):

  • No JavaScript submissions (onclick, fetch). Use a real <form> with its <input type="submit"> or <button>.
  • Put name on every field and value for the defaults. EWW collects by name.
  • The recognized text types (text, password, email, number, date, color and textarea itself...) are painted as editable fields. The rest degrade to text. checkbox, radio and select work.
  • Associate a <label> with each field: keyboard navigation will thank you.

Help the readable mode

If you want your article to look perfect with eww-readable, know your enemy. Its heuristic scores each node by word count, penalizes links (it subtracts their words), rewards images, and keeps the node with more than 100 words and the highest score.

The practical takeaway? Wrap the body of the article in a single container with lots of continuous text and don't chop it up into a thousand tiny divs full of links. An <article> or a <main> with long paragraphs wins. A tangle of <div> with navigation loses.

Headers and metadata that do count

Four small details that make a difference:

  • <title>: shown in EWW's header line. Always set it and make it descriptive.
  • <meta charset>: EWW uses it as an encoding fallback. Declare UTF-8.
  • <base>: respected, useful for resolving relative links.
  • HTTPS with a valid certificate: EWW colors the header-line title according to the TLS status. Serve your site over HTTPS.

So, what is it good for?

EWW is an excellent HTML document reader and a deliberately incomplete web browser. And once you accept that duality, it fits like a glove in a handful of scenarios:

  • Reading without leaving Emacs: documentation, blogs, articles, wikis, HTML man pages... with all your usual keys and with isearch.
  • Focused reading: the readable mode, with its word-density scoring, leaves the text and nothing else. No noise.
  • Low bandwidth and zero distractions: no ads, no JS, no pop-ups, no telemetry. Accessibility out of the box.
  • Feeds and mail with HTML: remember that SHR is what Gnus, elfeed and mu4e use underneath.
  • A single flow: search and open links from Emacs itself, with bookmarks, history, multiple buffers or tabs and sessions.
  • Scriptable: you parse the DOM from libxml-parse-html-region directly and automate whatever you want.

Its philosophy is the opposite of a modern browser. Instead of emulating a graphical rendering engine, it translates semantic HTML into Emacs text. Anything that is a "document" works very well and very fast. Anything that is a "web application" doesn't work at all. And that's the beauty of it: it won't pass the Acid3 test, but not out of deficiency, out of design.


Help me keep writing Every coffee gives me a push toward the next article. Sure, it's on me!

Send an email to comment+article-e0e00b4b@andros.dev to leave a comment. The subject will be ignored.

-1:-- EWW, the Emacs browser you underestimate (Post Andros Fenollosa)--L0--C0--2026-08-04T13:29:43.000Z

The Emacs Cat: Debugging in Emacs

Introduction

In my years of using Emacs, I’ve noticed a common pattern: developers who are highly proficient at editing source code in Emacs switch to a “normal IDE” (as they call it)—such as CLion or Visual Studio—when they need to debug their code. They usually explain this by saying that Emacs feels a bit weird for the task.

However, I’d much rather not leave Emacs if something can be done inside it.

In this post, I’ll try to show that debugging in Emacs is both simple and effective, especially after a few small adjustments to the default settings.

Debugging in Emacs revolves around two key components:

  1. GDB (GNU Debugger), the most popular and powerful debugger for C, C++, and other languages.
  2. GUD (Grand Unified Debugger), Emacs’ built-in interface since at least v19 that turns GDB into a well-integrated debugging environment inside Emacs, allowing you to debug your code without leaving the editor.

A Sample Debug Session

Below is an example of a typical debug session of mine.

In Emacs, I open a source code file (timepoint.c in this example) and run M-x gdb. GDB then prompts in the minibuffer for the path to the corresponding executable, as shown below.

Loading a program to debug. Click or tap to view the full-size picture.

After you enter the path to the executable—assuming it was built with the -g flag (i.e., compiled with debug information)—and press Enter , GDB prints some initial output and may ask whether it should automatically download missing debugging information from trusted online servers.

Downloading missing debugging information. Click or tap to view the full-size picture.

Because I don’t intend to debug system or third-party libraries, I simply press n to skip this step, which can occasionally freeze Emacs for a while.

The GUD dashboard appears. It usually consists of 6 windows.

  • Debugger, the GUD interaction buffer (or GDB shell);
  • C/*, the source code buffer;
  • Frames, the stack buffer, a list of stack frames of the program being debugged;
  • Locals, the local variables/registers buffer;
  • Inferior I/O, the input/output buffer (usually associated with stdin/stdout);
  • Breakpoints, the breakpoints/threads list.

GUD dashboard. Click or tap to view the full-size picture.

In my usual workflow, I type break main (or simply b main) in the GUD interaction buffer (Debugger) to set a breakpoint at the start of my program.

Setting initial breakpoint. Click or tap to view the full-size picture.

The new breakpoint shows up right away: as a red fringe marker next to the line in the source buffer (color varies by theme) and as an entry in the breakpoints list.

Now you can type run in the GUD interaction buffer. Execution will then stop at the first breakpoint (line 20 in this example).

GUD Keybindings

Frankly, I find the default GUD keybindings somewhat complex. For example, C-x C-a C-n is the globally defined key chord for gud-next — one of the most frequently used debugging commands. Having to type three keys while holding the Ctrl key feels excessive to me, so I prefer a single keystroke for this operation.

So, in my ~/.emacs, I’ve rebound the most frequently used GUD commands to F6 and its derivatives.

(global-set-key [(f6)] #'gud-next) ;; Execute the next single line.
(global-set-key [(control f6)] #'gud-step) ;; Enter the called function.
(global-set-key [(shift f6)] #'gud-cont) ;; Continue execution until hitting a breakpoint.
(global-set-key [(control shift f6)] #'gud-print) ;; Evaluate the expression at point.

I’ve kept the default keybindings for the less frequently used commands, such as setting a breakpoint (gud-break, C-x C-a C-b), continuing execution to the current line (gud-until, C-x C-a C-u), and so on.

Additionally, I’ve added a new keybinding for gud-watch (C-x C-a C-w), which watches the expression at point. This command has no default keybinding in GUD, at least in Emacs 29.3.

(global-set-key (kbd "C-x C-a C-w") #'gud-watch) ;; Watch the expression at point.

Debugging

Let’s continue with our sample debugging session.

We stopped at line 20, the first breakpoint in my program. Now I want to step through the function print_timepoint line by line. In the source code buffer, I move the cursor to line 9 and set a new breakpoint with C-x C-a C-b (gud-break). Then I continue execution with Shift + F6 (gud-cont) until the new breakpoint is hit.

After stepping through the function line by line with F6 (gud-next) until the end (line 16), I get the following output:

Debugging a function. Click or tap to view the full-size picture.

In the Locals buffer, you can see all local variables and their current values. The Inferior I/O buffer shows the program output. Everything looks correct: the tpoint variable has the value 0, which corresponds to the beginning of the Unix epoch (January 1, 1970).

Indeed, we could have inspected the print_timepoint function by simply stepping into it (gud-step, Ctrl + F6) directly from the first line of main, where the initial breakpoint was set. I used this example to demonstrate more GUD commands in action.

Now we can quit the debugging session by typing quit (or simply q) in the GUD interaction buffer (Debugger).

Of course, there’s no way to cover all the functions and commands available in GDB/Emacs GUD in one short post but I hope it provides a helpful introduction to using Emacs GUD for debugging your code.

You can find more information in the Running Debuggers Under Emacs manual; the GDB Cheat Sheet (PDF) is also worth having on hand.

Happy debugging in Emacs!

— The Emacs Cat.

-1:-- Debugging in Emacs (Post The Emacs Cat)--L0--C0--2026-08-04T08:47:40.000Z

Charles Choi: Announcing now-playing.el, an Emacs interface for the macOS Music app

For me, listening to music whenever I’m working on a computer is a commonplace, daresay essential activity. Much of my work is done using Emacs, so the idea of having it control music playback to mitigate an app switch seemed reasonable. Such was the motivation for my latest project, now-playing.el, a Transient interface for the macOS Music (nee iTunes) app.

img

now-playing.el takes inspiration from the many mini-client interfaces provided by Apple to control the Music app. The idea was to have a compact and simple interface:

  • Show what is currently playing (song, artist, album)
  • Offer basic controls (play/pause, next/previous track, volume control)
  • Optionally log what was played.

now-playing.el takes advantage of AppleScript support in the Music app, providing the needed controllability and observability of it from Emacs. The sequence diagram below illustrates how these programs relate to each other by showing a request/response transaction between Emacs and the Music app using the osascript command line tool.

img

If Emacs is built with NextStep (NS) support, then Emacs can send a direct AppleScript message to the Music app via ns-do-applescript to avoid making a shell call to osascript.

img

State synchronization for now-playing.el is fairly simple, with client updates done in a pull fashion. More details about what now-playing.el can do can be found in the now-playing.el User Guide.

Closing Thoughts

It is not coincidental that writing this mini-client for the Music app works into my recent explorations and musings on malleable computing with Emacs. As of this writing, now-playing.el weighs in at 326 lines of code (cloc measured), taking full advantage of Elisp libraries to construct the following client subsystems:

  • UI: Transient for menu, cus-edit.el for customization UI
  • Client Edge: shell-command-to-string to osascript, ns-do-applescript
  • Local Database: Elisp variables

now-playing.el explores integration with AppleScript, itself a mechanism to allow for orchestration between Cocoa applications. Expect some future posts documenting my explorations in this area, particularly with the more contemporary Apple Shortcuts and Intents.

now-playing.el v1.0 is now available on MELPA.

-1:-- Announcing now-playing.el, an Emacs interface for the macOS Music app (Post Charles Choi)--L0--C0--2026-08-03T17:55:00.000Z

Irreal: The Em Dash And Emacs

Irreal, as you all know, is an em-dash friendly site. Irreal has always liked them and now we like them even more because it puts a thumb in the eye of those mentally challenged folks who claim, erroneously, that “real people” don’t use em-dashes and their presence in a document is a sure sign of AI generated text.

It turns out that JTR over at The Art Of Not Asking Why is also an em-dash aficionado and has been struggling with how to enter them, especially when using Emacs. His final solution involves expand-abbrev but seems to me overly complicated. He types --- then immediately calls expand-abbrev by typing Ctrl+x `.

We here at Irreal have the same problem, of course, but solved it in what seems to me a much simpler way:

(defun jcs-insert-em-dash ()
  "Insert an em-dash at point"
  (interactive)
  (insert 8212))

and

(global-set-key (kbd "H--") #'jcs-insert-em-dash)

I have Hyper bound to the right ⌘ Cmd key so it’s really easy to invoke it: thumb on Hyper and index finger on - and it inserts an em-dash directly into the source exactly as JTR wanted.

I don’t claim my solution is better than JTR’s, only that it suits me better. It’s just another example of Emacs letting you have it your way.

-1:-- The Em Dash And Emacs (Post Irreal)--L0--C0--2026-08-03T14:37:58.000Z

Still working on Emacs Config Gems part 3. Fell into a deep rabbit hole and got lost for a couple of days, then climbed out just to discover another one I have to explore next. I wanted to crunch the first few tweaks of my Emacs config in one post, but there’s too much to explore. I’m getting there!

-1:--  (Post TAONAW - Emacs and Org Mode)--L0--C0--2026-08-03T12:21:03.000Z

Sacha Chua: 2026-08-03 Emacs news

: Updated pkal's link to Structured Changelogs for ELPA packages (request for feedback)

I particularly enjoyed the tweaks for EWW (Emacs Web Wowser) in this edition. Could be fun to take whatever page you're looking at in a different application and open it within Emacs, with syntax highlighting and maybe even the ability to copy or execute bits of code more easily. Could be handy during your search for knowledge, which is incidentally the Emacs Carnival theme for August. Enjoy!

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!

View Org source for this post

You can e-mail me at sacha@sachachua.com.

-1:-- 2026-08-03 Emacs news (Post Sacha Chua)--L0--C0--2026-08-03T10:57:58.000Z

TAONAW - Emacs and Org Mode: Em Dashes in org-mode and the Nuances of Abbrev

Since I confessed my enjoyment of em dash in my writing last week, I started using them more freely. On a Mac, it’s Option Shift Hyphen, as Sasha would tell you. In Linux, it’s a bit more involved: Ctrl Shift U to bring up a search for Unicode number reference, and then the number for em dash: 2014.

This is all good and well, but what about Emacs, where I write most of my text?

Emacs comes with abbrev-mode, a powerful text-expanding option that automatically converts something like “om” to “org-mode”, or even “fox” to “The quick brown fox jumps over the lazy dog” if I wanted to. But the em dash is a bit more tricky. I could, if I wanted, create an abbreviation like “em” to simply expand to “—”. But this doesn’t make much sense.

When converting org-mode to markdown (as I do when I post something), the built-in solution for Emacs’ markdown exporter is to convert --- (three dashes) to —, em dash — but this presents two annoyances. First, the built-in exporter would convert those to their character reference, as we just saw: &#2014;. I explained this more in-depth previously. Second, even after I fixed this issue by using pandoc, I still see --- in org-mode, not —. This looks like the kind of thing abbrev-mode was made for, right?

But it’s a bit more complicated. abbrev-mode triggers only when you type a space after a letter. So, “em” to — would work, but - to — would not, because a dash is not part of a word1.

The solution was simpler than I thought: expand-abbrev, which “Expands the abbrev before point, if there is an abbrev there. Effective when explicitly called even when ‘abbrev-mode’ is nil.” In other words, it calls expand-abbrev without needing to trigger it the usual way. We simply call the abbrev replacement directly.

Now whenever I want an em dash, I type --- first, and then I make sure the marker is right after the last dash, and call expand-abbrev, which in my config is tied to C-x ‘. I then get an em dash in Emacs, and the exporter in Emacs (or pandoc, in my case) leaves it alone.


  1. Prot has a related, interesting video about expanding abbrevs with non-word-like characters, which I already use. The problem here is that there’s nothing “word-like” in —. We can work with something like “!word” or “word!” because the mechanism that catches abbrevs will recognize a word-like character before or after the “!” (using regex, as explained in the post) and trigger it, but in the case we have above, there’s nothing that looks like a word to trigger it at all, so it does not work. â†©ïžŽ

-1:-- Em Dashes in org-mode and the Nuances of Abbrev (Post TAONAW - Emacs and Org Mode)--L0--C0--2026-08-02T14:07:04.000Z

Raymond Zeitler: One Space or Two?

HTML enforces the use of a single space to separate sentences. If you want to add another space, you need to use &nbsp;. I still remember how annoyed I was about that. Back in the century in which I took my technical writing course, two spaces were required. Of course, we weren't using computers very often; hand-written sentences needed to appear more separated than the words within.

I'm definitely not here to convince anyone to switch. Instead, I just want to share that I paid close attention to this detail when I was formulating my style guide for this blog. Should I continue with my out-of-date two-space habit? Or should I adopt the current convention?

I turned to Emacs itself for guidance. It turns out that the individuals who wrote Emacs comments, docstrings and help text used two spaces. Although many times they started each sentence on a new line.

It turns out that the content here mostly is one-space. I start out using two spaces in Org where most of this originates. But when I export to HTML, that second space vaporizes. That would seem like a bug to me.

The only place where you'll see evidence of my two-space style is in the comments and docstrings of my source code.

Am I the only person who nit picks about such details?


Thanks to Irreal for highlighting a customization from macosguru

-1:-- One Space or Two? (Post Raymond Zeitler)--L0--C0--2026-08-01T23:47:27.512Z

Marcin Borkowski: A fancier splash screen in terminal Emacs

I’ve been using Emacs in a terminal for some time now (an experience worth a blog post another day). One thing that bothered me a little was that the “splash screen” (what Emacs displays at the start) does not show the familiar Emacs logo. I decided to fix this.
-1:-- A fancier splash screen in terminal Emacs (Post Marcin Borkowski)--L0--C0--2026-08-01T05:13:48.000Z

Protesilaos: Emacs live with @linkarzu on his workflow, Org capture, and projects (2026-08-01 22:20 Europe/Athens)

Raw link: https://www.youtube.com/watch?v=WQbXKvBT8HY

In about 40 minutes from now I will do a live stream with Christian Arzu from the @linkarzu channel on YouTube. The video will be recorded.

The topic of our meeting revolves around how Christian uses NeoVim and Kitty to handle sessions and write fleeting thoughts. Then we will try to do something along those lines using built-in Emacs functionality.

Christian did a video a couple of days ago about this topic and here is my extensive commentary on it, with points that are useful in general: https://protesilaos.com/codelog/2026-07-31-re-linkarzu-what-i-need-from-emacs/.

-1:-- Emacs live with @linkarzu on his workflow, Org capture, and projects (2026-08-01 22:20 Europe/Athens) (Post Protesilaos)--L0--C0--2026-08-01T00:00:00.000Z

Ashish Panigrahi: Setting up offline email for Microsoft O365 with notmuch and emacs

Having to deal with Microsoft's outlook has been a growing pain with my computing needs. Of course, this is pertinent only for work email. For personal email, I use Migadu which has good standards for email unlike Microsoft's.

At work, I can only use either the official Outlook webmail or Thunderbird since those are the only clients that are whitelisted by the IT department at my university. Thunderbird is slightly better (it has a few problems of its own but I digress) but I would like to have an offline copy of all my emails, fully searchable with an indexed database provided by notmuch, which uses the excellent Xapian library for indexing. Notmuch is shipped as an emacs package in the form of notmuch.el, which is exactly what I like given that I'm moving most of my computing needs into emacs1.

I've taken inspiration from Fergus' excellent blogpost which implements the same in neomutt. The initial setup process is identical to Fergus' blogpost.

It should be noted that notmuch is only a mail indexer. It does not fetch mail, nor does it send mail. Those are handled by isync and msmtp, which are commandline programs.

Access authentication with O365

Since Thunderbird is still allowed to access O365's authentication, we will use the client ID provided from it (this is publicly available from Thunderbird's source code)2. For authentication for IMAP and SMTP, we will use XOAUTH, which is a simple authentication and security layer (SASL) more suited for email clients.

Tools like isync rely on SASL for authentication, for which we'll require an XOAUTH SASL plugin: https://github.com/moriyoshi/cyrus-sasl-xoauth2.

If you're on Arch, then this plugin is installable from the AUR:

paru -S cyrus-sasl-xoauth2-git

If not, then we can build it from source:

git clone https://github.com/moriyoshi/cyrus-sasl-xoauth2
cd cyrus-sasl-xoauth2/
./autogen.sh   # checks for requirements
./configure    # configure (here we use the defaults)
make           # compile
sudo make install     # install for root user

Token generation for OAuth

Microsoft has conditionally allowed API access to clients and the only way to get access for any client is to register the application in the Microsot Application portal, which is something only my org's IT department can do3. Fortunately, we can use Thunderbird's credentials to generate an access token for our purposes.

Another issue that comes up is the finite lifetime of these access tokens (typically an hour or two), which is cumbersome to generate each time one needs to download email. Fortunately, mutt comes with mutt_oauth2.py, a script to help in the automatic renewal of this token. This script helps in decrypting the token file and renewing it everytime it is invoked.

Fetching the initial token is fairly simple but before we do it, there are certain changes that we need to do to mutt_oauth2.py.

Look into the ENCRYPTION_PIPE variable (line 48) and make sure to specify your gpg key. If you don't have one, then generate one:

gpg --full-generate-key

Select the default options (ed25519 cypher if it allows) and make sure that the expiration of the key is set to 0 (no expiration). This makes your life easier but of course for security reasons, this is not a good practice.

Bring up your public key:

gpg --list-keys

Copy the second line (after the pub line) and paste it into mutt_oauth2.py

ENCRYPTION_PIPE = ['gpg', '--encrypt', '--recipient', 'YOUR-GPG-KEY']

After this, look at line 79. This includes a client_id for microsoft. For Thunderbird, the client id is 9e5f94bc-e8a4-4e73-b8be-63364c29d753. Leave the client_secret value as is. It should look like so:

'client_id': '9e5f94bc-e8a4-4e73-b8be-63364c29d753',
'client_secret': '',

Now we are ready to generate the access token. Simply run:

./mutt_oauth2.py OUTPUT_TOKEN_FILE --verbose --authorize

A series of prompts should appear. Select microsoft, localhostauthcode (or authcode), followed by your email address, after which you should automatically be redirected to a browser for adding your credentials for authentication. Doing so, should reveal the access token in your terminal. No need to copy it, it is present in your OUTPUT_TOKEN_FILE which is encrypted. To obtain the decrypted token, we run the script again with just the file name as an argument

./mutt_oauth2.py OUTPUT_TOKEN_FILE

A nice thing is that running this script with the token file also checks for expiry and renews it if necessary. This can be done multiple times without worry.

UPDATE (2026-06-19): About 20 days after I set this up, for whatever reason the token file expired on my personal laptop. I'm not entirely sure what happened but the fix for now was to regenerate the token again. I'll need to debug the exact cause to prevent it from happening again.

UPDATE (2026-07-29): It looks like this problem only appears on my personal laptop as it's not an authorized device and as such, 14 days is the maximum duration before which the token needs to be reauthorized. My office PC is within this "authorized" devices whitelist and thus doesn't need reauthentication after the initial setup.

Offline email setup

Now that we are done with the difficult part, we move onto setting up isync (the binary is called mbsync) which is available in most distributions. This program basically downloads your emails offline and synchronizes it with your email's remote IMAP servers. It supports multiple accounts too. The program is configurable with a ~/.mbsyncrc file4. I highly recommend reading the manual for it via man mbsync. Here's a starting template:

# -- Global defaults
# These will be applied to all accounts

# Create new mail in either location, so if the remote or local has mail
# and the other does not, then create it
Create Both
# never remote mail from either side
Remove None
# Remove messages marked for deletion from the local side on the
# remote. Do not ever delete local if marked for deletion in the
# remote. Prevents admins from deleting one's local mail
Expunge Far
Sync All
SyncState *
CopyArrivalDate yes
# No maximum number of messages
MaxMessages 0

# -- First email account
IMAPAccount university
Host outlook.office365.com
Port 993
User my-username@university.edu
AuthMechs XOAUTH2
PassCmd "~/.local/bin/mutt_oauth2.py ~/.local/bin/TOKEN"
# Use TLS
TLSType IMAPS
SystemCertificates yes
Timeout 10

# A store defines a collection of mailboxes, so we associate the
# remote IMAP mailbox with the account we just configured
IMAPStore university-remote
# Associate the store with our account
Account university

# Where are we going to keep the mail associated with this account
MaildirStore university-local
SubFolders Verbatim
Path ~/.local/share/mail/university/
Inbox ~/.local/share/mail/university/INBOX

# Channel to synchronize everything except "Sent" email
Channel uni-main
Far :university-remote:
Near :university-local:
# Which directories to synchronize
Patterns INBOX "Deleted Items" "Drafts"

# Channel to synchronize "Sent" email
Channel uni-sent
Far :university-remote:"Sent Items"
Near :university-local:Sent

# Group the two channels and sync everything with `mbsync NAME`
Group university
Channel uni-main
Channel uni-sent

# -- Second email account
IMAPAccount personal
...

Once you have everything configured, we can start downloading all our email by running:

mbsync university

The first time mbsync is run, it will take a fair amount of time, since you'll be downloading a lot of email (assuming you've been using your account for a long time). The subsequent runs would be just incremental downloads, so it's much faster.

After navigating to your local Maildir directory (~/.local/share/mail/university in my case), you should see all your emails downloaded and categorized into inbox, drafts, sent, and deleted-items folders.

A way to automate this to run a script periodically. I use systemd-timers where I have a script which is periodically run every 15 mins and notifies me if there's new email (I'll cover this later in the blogpost).

Sending mail via SMTP

Sending email is done via msmtp. It is configured by editing ~/.msmtprc5.

defaults
auth on
tls on
tls_trust_file system
logfile ~/.cache/msmtp.log
timeout 10

# -- First account
account university
tls_starttls on
host smtp.office365.com
port 587
auth xoauth2
user my-username@university.edu
passwordeval "~/.local/bin/mutt_oauth2.py ~/.local/bin/TOKEN"
from my-username@university.edu

# -- Second account
account personal

This is fairly self-explanatory. One thing to note is that tls_starttls should be on for this to work. I'm not very familiar with email security protocols like TLS and STARTTLS but from my understanding, STARTTLS is an automatic upgrade (if supported) from the more insecure TLS protocol. TLS however needs to be enabled for any email service, otherwise it won't work.

Now, we can test our configuration by sending email directly from the commandline. Save the contents of a file called example-mail as follows:

From: my-username@university.edu
To: user@example.com
Subject: Hello World

This is a test for msmtp.

And send the email by running:

cat example-mail | msmtp -t -a university

Indexing email offline with notmuch

We have receiving and sending email configured. How about reading and "using" email via an email client. In more technical terms, an email client is called a mail user agent (MUA), which is typically seen in email headers. This includes clients like Thunderbird, Apple mail, neomutt, etc. We will configure notmuch which indexes email and provides an interface for emacs natively with notmuch.el.

Notmuch is entirely tag based. Basic tags exist like unread, inbox, draft, sent but you can customize it with more tags to filter out emails from a particular email address, from a particular range of date, etc. Tags are heavily used and it's a different paradigm of handling email compared to your typical webmail interface. I won't go over the details of tagging in notmuch here for the sake of brevity (to be covered in another blogpost).

When first setting up notmuch, simply run:

notmuch setup

This will prompt you for basic information like your name, email address, Maildir directory, etc. Once this is done, notmuch needs to index your Maildir. Run the following:

notmuch new

This should be fairly fast, even if your Maildir is big. Notmuch is quick like that.

Now you can search an email entry via notmuch search. For example, I can search emails from a particular sender like so:

notmuch search 'from:friend@university.edu'

I would again advise you to go through the man pages (man notmuch-search) for more details.

Emacs setup for notmuch

Simply running M-x notmuch should give you a hello screen, where you can then select tags like inbox, unread to view their respective email. I have a fairly customized config for notmuch.el but below I provide a fairly good starting point for a more minimal notmuch interface6:

;; Notmuch for email
(use-package notmuch
  :load-path "/usr/share/emacs/site-lisp/"
  :ensure nil
  :defer t
  :commands (notmuch notmuch-mua-new-mail)
  :init
  ;; Search
  (setq notmuch-search-oldest-first nil)
  :config
  ; General UI
  (setq notmuch-show-logo nil
	notmuch-column-control 1.0
	notmuch-hello-auto-refresh t
	notmuch-hello-recent-searches-max 20
	notmuch-hello-thousands-separator ""
	notmuch-hello-sections '(notmuch-hello-insert-saved-searches)
	notmuch-show-all-tags-list t)

  ; Search
  (setq notmuch-search-result-format
        '(("date" . "%12s  ")
          ("count" . "%-7s  ")
          ("authors" . "%-20s  ")
          ("subject" . "%-80s  ")
          ("tags" . "(%s)")))
  (setq notmuch-tree-result-format
        '(("date" . "%12s  ")
          ("authors" . "%-20s  ")
          ((("tree" . "%s")
            ("subject" . "%s"))
           . " %-80s  ")
          ("tags" . "(%s)")))
  (setq notmuch-show-empty-saved-searches t)

  ; Tags
  (setq notmuch-archive-tags nil ; I don't archive email
	notmuch-message-replied-tags '("+replied")
	notmuch-message-forwarded-tags '("+forwarded")
	notmuch-show-mark-read-tags '("-unread")
	notmuch-draft-tags '("+draft")
	notmuch-draft-folder "university/Drafts"
	notmuch-draft-save-plaintext 'ask)

  ; Email composition
  (setq notmuch-mua-compose-in 'new-window)
  (setq notmuch-mua-hidden-headers nil)
  (setq notmuch-address-command 'internal)
  (setq notmuch-address-use-company nil)
  (setq notmuch-always-prompt-for-sender t)
  (setq notmuch-mua-cite-function
	'message-cite-original-without-signature)
  (setq notmuch-mua-user-agent-function nil)

  (setq notmuch-show-relative-dates t)
  (setq notmuch-show-all-multipart/alternative-parts nil)
  (setq notmuch-show-indent-messages-width 0)
  (setq notmuch-show-indent-multipart nil)
  (setq notmuch-show-part-button-default-action 'notmuch-show-view-part)
  (setq notmuch-wash-wrap-lines-length 120)
  (setq notmuch-unthreaded-show-out nil)
  (setq notmuch-message-headers '("To" "Cc" "Subject" "Date"))
  (setq notmuch-message-headers-visible t)

  :bind
  ( :map global-map
    ("C-c m m" . notmuch)
    ("C-x m" . notmuch-mua-new-mail) ; override `compose-mail'
    :map notmuch-search-mode-map
    ("/" . notmuch-search-filter) ; alias for l
    ("r" . notmuch-search-reply-to-thread) ; easier to reply to all by default
    ("R" . notmuch-search-reply-to-thread-sender)
    :map notmuch-show-mode-map
    ("r" . notmuch-show-reply) ; easier to reply to all by default
    ("R" . notmuch-show-reply-sender)
    :map notmuch-hello-mode-map
    ("J" . notmuch-jump-search)))

You're free to look at my init.el for my own customization for notmuch.el.

Automating email synchronization with systemd timers

Let's automate the email sync to happen every 15 mins (or whatever frequency you prefer). First we create a shell-script to download email via mbsync and also index the email with notmuch. Let's name it it syncmail.sh and place it in $HOME/.local/bin/.

#!/bin/sh
set -eu

# Set environment variable for notmuch config file
export NOTMUCH_CONFIG="$HOME/.config/notmuch/notmuch-config"

mbsync university

before=$(notmuch count --lastmod '*' | cut -f3)
notmuch new > /dev/null

query="lastmod:$((before + 1)).. and path:university/**"
count=$(notmuch count "$query")

if [ "$count" -gt 0 ]; then
    body=$(notmuch search --format=json --limit=5 "$query" \
	       | jq -r '.[] | "\(.authors): \(.subject)"')
    notify-send "New mail: $count" "$body"
fi

In addition to downloading email and indexing, the script also notifies through notify-send if there's new email along with a sender and subject in the notification. Make sure to make the script executable with

chmod +x ./syncmail.sh

Then we write the systemd script to run this script periodically. First we create a syncmail.service file in $HOME/.config/systemd/user/:

[Unit]
Description=Sync mail with mbsync and index with notmuch

[Service]
Type=oneshot
ExecStart=%h/.local/bin/syncmail.sh

Then we create a timer file (make sure it is named syncmail.timer) for actually running the script every n minutes.

[Unit]
Description=Run syncmail every 15 minutes

[Timer]
OnBootSec=2m
OnUnitActiveSec=15m
Persistent=true

[Install]
WantedBy=timers.target

The advantage over cronjobs is that if your system is asleep or shutdown, then booting up accomodates accordingly and runs the script after m minutes (2 minutes in my case).

Finally we enable the script with systemctl:

systemctl --user daemon-reload
systemctl --user enable --now syncmail.timer

Concluding remarks

Now you should have a working setup for using offline email for Microsoft's O365. This is fairly minimal but if you'd like to have encrypted emails, addressbooks, etc., please take a look at the original blogpost from Fergus.

A basic emailing etiquette I like to follow is to use plaintext as opposed to html. Read more on why this is better.

Special thanks to Marci for pointing out grammatical errors and typos.
  1. It's like the old adage from Vi advocates, "Emacs is a great operating system, lacking only a decent text editor". Although the latter part I would disagree with. ↩

  2. I just found out that Mozilla has made it very convoluted to find the source code and build Thunderbird locally. It uses mercurial instead of Git (in this day and age?). Relevant docs are here. ↩

  3. Even after asking countless times, they've rejected my request to include notmuch/emacs into the allowed clients list. Ah well, here we are. ↩

  4. Personally, I dislike that my $HOME directory gets cluttered with config files that don't respect the XDG specifications. I set it to $HOME/.config/mbsync/mbsyncrc by exporting the variable MBSYNCRC. ↩

  5. Same issue with this. I fix it to be at $HOME/.config/msmtp/config. ↩

  6. The default interface is too noisy for me, so I disable a lot of the bells and whistles. ↩

-1:-- Setting up offline email for Microsoft O365 with notmuch and emacs (Post Ashish Panigrahi)--L0--C0--2026-08-01T00:00:00.000Z

Please note that planet.emacslife.com aggregates blogs, and blog authors might mention or link to nonfree things. To add a feed to this page, please e-mail the RSS or ATOM feed URL to sacha@sachachua.com . Thank you!