Irreal: Is Emacs An Operating System?

The joke about Emacs being an operating system is an old one but lately the idea seems to be being taken more seriously. Here’s the latest example. Significantly, the poster, Bi-Jean, is a self-confessed n00b who doesn’t work in the tech industry, just someone who likes playing with computers and is curious about the best ways of using them. The idea seems natural to Bi-Jean.

If you believe, as I do, that the best way of thinking of Emacs is as a latter-day Lisp Machine, the idea of it being an OS makes more sense. Specialized applications aside, there’s basically no function that you can’t implement from within Emacs except arguably a decent Web browser. From that perspective, the “real” OS is viewed as a set of device drivers for Emacs. It’s a point of view adopted by many Emacsers who claim not to care what OS it’s running on.

My own view, as someone who does almost everything from within Emacs, is that “My operating system is Emacs and Linux/macOS/Windows is just a set of device drivers” is a nice joke that captures an underlying truth but isn’t truly realistic. I always say that I do virtually everything in Emacs and Safari but the “virtually” provides a little wiggle room. For example, I use Fantastical to sync my calendar across all my devices, the Reminders app to set a reminder across all my devices, and the Apple Messages app for texting—although I do use Emacs to compose the text—so it’s not really Emacs all the way down.
Still, a case can be made that in an essential way, Emacs really is my OS. Perhaps more important is the fact that it doesn’t really matter. I do most of my work—other than browsing—from within Emacs and if that makes Emacs my operating system, fine but I also depend on macOS for more than just running Emacs.

-1:-- Is Emacs An Operating System? (Post Irreal)--L0--C0--2025-06-12T16:24:49.000Z

Anand Tamariya: Plan 9 Remote File Access from Emacs

 


Plan 9 Operating System uses 9p protocol for file access. This is an Elisp implementation of the protocol.

Plan 9 (9front distribution) is running in QEMU with NAT networking. Local port 12564 is forwarded to 9fs service port 564 in the virtual machine.

Code

References

  1. 9P Protocol
     

 

-1:-- Plan 9 Remote File Access from Emacs (Post Anand Tamariya)--L0--C0--2025-06-12T04:08:00.000Z

Irreal: The Mechanics Of Interacting With Journelly On The Mac

As you all know by now, I’m all in on Journelly. I use it to implement my memo book in which I record virtually everything that happens in my day. For me, one of its major benefits is that it uses Org mode markup to record its data and can (optionally) export it to the iCloud so that I can interact with it on my Mac, which sees the data as a normal Org file.

“Interact” means that I can read, edit, and add to the data in my memo book from any of my devices including my Mac. It’s a lot better than I expected it would be compared to my previous procedure of using the Apple Notes app. I find that I take better, more comprehensive notes and can easily add pictures and links to things on the Web.

That brings me to a post on the Emacs subreddit from TeeMcBee that asks how people interact with Journelly from their Mac. It’s a natural question, especially for those who haven’t been involved with Journelly from the beginning. In the comments, Álvero Ramírez offers up his own solution, which is similar but identical to mine. Our main difference is where we export the data to. The easiest thing is to simply choose iCloud Drive as your storage option. That’s what Ramírez does.

The problem with that option is that it stores the data at a place with a complicated path in the iCloud. Because of that, I chose to use the Other… option and directed it to a subdirectory of my Documents folder. I thought that that would avoid having to set symlink to the file. It turns out, though, that it was still easier to set a symlink so I recommend that you choose the iCloud Drive option and set a symlink to it from wherever is convenient.

The TL;DR of all this is to do the simplest thing for exporting your data and then read Ramírez’s post on setting up an Org mode template to capture Journelly entries from your Mac. Those two things will make using Journelly data on your Mac easy and pleasant..

-1:-- The Mechanics Of Interacting With Journelly On The Mac (Post Irreal)--L0--C0--2025-06-11T16:33:39.000Z

Christian Tietze: Emacs Carnival 2025-06: Take Two

To kickstart the Emacs Carnival, and as a hat tip to our recent inspiration, this month’s topic is borrowed from the June IndieWeb Blog Carnival: the topic is “Take Two”, hosted by Nick Simon:

Ever wish for a do-over? “Take two!” (or three, four, etc.) might be shouted by a film director or audio engineer looking to get a somewhat different outcome from a group of actors or musical performers. Would you like a second shot at something that didn’t land?

This is a perfect fit for Emacs users:

We usually don’t nail “it” on our first try – init.el bancruptcy; refactoring hacky Emacs Lisp code; leaving Emacs only to come back englightened much later; running two Emacsens in parallel. There are plenty of possible second takes when it comes to Emacs!

So for this month, our first community blog carnival, I want you to:

  • mediate on “Emacs” and “take two”,
  • blog about it,
  • then send me a link to your blog post.

That’s it! I’ll aggregate submissions for all of June in this post.

Don’t have a blog, yet?

Well, just start one already! :)

It’s the future of the internet!

Blogging is the future, and the future is now!

What’s a Blog Carnival, Again?

This is our first Emacs Carnival, so you may not know the format. A blog carnival is a fun way to tie together a community with shared writing prompts, and marvel at all the creative interpretations of the topic of the month. I’ve provided a couple of interpretations above, but you may think of something else entirely. That’s amazing, roll with it, that’s what makes this fun!

Thanks to Sacha Chua for her post “Working on the plumbing of a small web community” that was part of the May 2025 IndieWeb Carnival, and got me thinking why there’s no Emacs Carnival, yet, and for her encouragement to kickstart this.

For future Carnivals, check out the “Carnival” page on EmacsWiki . It includes instructions, and is our community space to coordinate participants and topic ideas.

Submissions

Comment below or DM/email me with your submission! I’ll collect submissions up to, and including, July 1st (Central European Time), so that every time zone has had a chance to meet the June 30th deadline :)

Bonus: Submit your indie blog post to Nick as well (he really said so)!

These have been submitted as of 2025-06-11:

  1. Kemal: Announcing Brainiac Project
  2. Jeremy Friesen: “Take Two”
  3. Carlos Pajuelo Rojo: “Take two on Emacs (Toma dos de Emacs)”

Hire me for freelance macOS/iOS work and consulting.

Buy my apps.

Receive new posts via email.

-1:-- Emacs Carnival 2025-06: Take Two (Post Christian Tietze)--L0--C0--2025-06-11T07:24:01.000Z

Srijan Choudhary: 2025-06-11-001

Quick note for me to generate #Emacs TAGS file for an #Erlang project:

find {src,apps,_build/default,$(dirname $(which erl))/../lib} -name "*.[he]rl" | xargs realpath --relative-to="$(pwd)" | etags.emacs -o TAGS -

The relative path ensures that this works over tramp as well.

-1:-- 2025-06-11-001 (Post Srijan Choudhary)--L0--C0--2025-06-11T02:35:00.000Z

Jeremy Friesen: Emacs: Take Two

This post is my contribution to the Emacs Carnival 2025-06: Take Two. With a sign-up list on the Carnival page of the EmacsWiki.

In I used Emacs 📖 for the second time…the time that it stuck. The first time was in . I was transitioning from a Microsoft and International Business Machines Corporation 📖 shop to a Linux 📖 shop. At the previous job, I used the tools offered: a green screen text editor for Report Program Generator programming language from IBM (IBM RPG 📖) , Microsoft Access/Visual Basic, and Plex (a case tool allowed multiple inheritance and could build either C or IBM RPG ) programs.

I’ve thought a lot, though never all that deep, about that decision to set Emacs aside. And wonder at that moment in had I chosen to adopt Emacs ; what might that path have been? For a few months after stepping away from Emacs I used JEdit 📖 . Then switched to Textmate 📖 in , in large part because that was the de facto editor of Ruby on Rails (Rails 📖) .

What would’ve made the then Emacs sticky enough for me to use? I was then in the process of learning PHP Programming Language (PHP 📖) and pre-Prototype Ajax calls. Sidenote Before jQuery there was Prototype and before that an even hotter mess. I remember adopting Rico. At home, I was using Lotus Notes to model data for Role Playing Games (RPGs 📖) .

Why Lotus Notes? It was the tool I had and knew. Further, the database and data were all in one file that I could use. A portability. Contrast with work, where I was dipping into the realm of Postgresql 📖 and MySQL.

Standing and running those locally was not quite something I wanted to pursue; and for my hobby I would’ve also needed an application. The person who nudged me to consider Emacs was also writing RPG tools, but was choosing to write in Python. Had they said “I’m writing this all in Emacs ”, I think I would’ve listened a bit more.

Reflecting on the following decade or so, I abandoned that Lotus Notes project; it worked well enough but I was losing access to the license to run it. I was on the path to making various Rails applications. So I spent time migrating that Lotus Notes application to a Rails application. But I abandoned that application and started up several successors; all abandoned.

For these personal projects, nothing quite stuck. Things came close in my gm-notepad: A command-line tool to help with your GM-ing. Started before I switched to Emacs , it was a Read-eval-print loop (REPL 📖) environment that could be used for note taking while running a game. And generating results from random tables (that could be created on the fly).

You can read about gm-notepad in Introducing GM Notepad: A Command Line Tool for GM-ing.

Had I been using Emacs just enough before Rails , what would’ve kept me from later jumping to Textmate ?

I would’ve had about four months to acclimate to Emacs . And in that time I would’ve needed to see the potential of a Lisp 📖 machine; namely its REPL and how I might be able to model that Lotus Notes application in Emacs . That was a likely crease.

Looking to the switch that stuck, from the to the four months later my Emacs config I made 231 commits into my Emacs configuration. During that time I had accumulated/created 3200 lines of Lisp. Granted, that 4 month window was one in which I had minimal job responsibilities and no social engagements; meaning lots of time for exploration.

Contrast with the time frame to , in which my children were quite young. We were also hosting twice a week events at our house and a full-time job that was very much new to me.

My available time would’ve been different.

I’m also unclear how I would’ve managed packages. And what packages were available? The baseline Emacs, with tutorial, is quite robust. The features of bare Emacs were “competitive” with my understanding of what I needed in a text editor.

I don’t know what Emacs 22 of would’ve felt like compared to me joining around Emacs 27. How many init.el bankruptcies might I have declared in those two decades?

Factors that might have helped:

First, learning about Structure and Interpretation of Computer Programs (SICP 📖) during that time. While I haven’t read SICP , knowing then that it described concepts in Scheme, a Lisp dialect, I might have pursued reading it. Sidenote I don’t feel the same compulsion now to read it as I would’ve then. But maybe I should seek out a print copy. I learned about it one year later, in .

Second, stumbling upon the EmacsWiki, mailing list, and Internet Relay Chat (IRC 📖) . That is finding the places where folks were troubleshooting their Emacs problems but also exploring how to extend Emacs .

Third, learning of Alex Schroeder, both involved in RPGs and Emacs , may have helped. That is finding just enough folks at the intersection of two aspects of my then (and current) interests. There are a few others.

I’m wondering how a younger me would’ve handled being a few months into Emacs and then seeing the flashy Textmate . Would that time with Emacs have been sticky enough to keep with it? And had I chosen Textmate , when it soured, would I have considered a return to Emacs ? Or would Sublime Text 📖 win out? What of Atom 📖 ?

It took me attending the funeral of three text editors to finally wake and pick Emacs ; but even then only after exploring Visual Studio Code (VS Code 📖) and again saying “nope” to Vim 📖 . Sidenote I can use Vim just well enough to favor it over something like Nano.

Adopting Emacs took me knowing the baseline of what I wanted from my editor and a prior memory of Emacs .

Would I know that without the years of practice? It also took experiencing skill obsolescence; each bit of learning how to extend an editor is useful but the specifics are often non-transferable.

Would I have the wisdom to pierce the veil of first Textmate then Sublime Text then Atom ? And see that by construction and design they would only be able to be a narrower subset of Emacs ’s capability? Could I have seen past the gloss and chrome?

Would I have considered the Lindy Effect 📖 ? Or understood the potential of the cumulative effect of my editor? Moving away from one editor has meant leaving behind knowledge of its configuration and extension; each their own foibles.

Would I have been able to see the difference of extending Emacs versus extending Textmate ? Emacs hits different than Textmate , Sublime Text , and Atom . Where Emacs ’s currency is buffers, lists, and functions; the others had hard-boundaries and Application Programming Interfaces (APIs 📖) .

About a year before leaving Atom , I set about writing an extension. My memory is that it was hellish process; and more than just needing to create two almost duplicate chunks of code/data to make much of anything happen.

Contrast Emacs , where extending is assumed, encouraged, consistent, and facilitated by powerful introspection. I’ve learned a lot by reading Emacs commands, seeing what they compose and choosing one of those “inner” functions from which to build.

That hits different than reading an editor’s extension API , which is the implementation teams means of stating “this is how you are allowed to change this program.”

I’ve also thought recently about I found a way to create order from my jumbled ideas. I use Emacs to think as well as help recall those thoughts. The functions I’ve written are a mix of help me write and help me find what I wrote.

Those functions provide breadcrumbs for further extensions; with the thought being that I’m most likely to extend/enhance functionality adjacent to or overlapping with a concept I’ve already “touched.”

-1:-- Emacs: Take Two (Post Jeremy Friesen)--L0--C0--2025-06-11T00:45:48.000Z

Protesilaos Stavrou: Emacs: modus-themes version 4.8.0

I just published the latest stable release of the Modus themes. The change log entry is reproduced further below. For any questions, you are welcome to contact me. I will now work to apply these same changes to emacs.git, so please wait a little longer for the updates to trickle down to you.


4.8.0 on 2025-06-11

This is a small release that corrects a mistake I made in the previous version. It also introduces some minor refinements.

Matching parentheses are easy to spot

In version 4.7.0, I made the mistake of merging some stylistic tweaks to show-paren-mode that I was experimenting with. The idea was to get a feel for how the subtle colouration of matching delimiters affects the usability of the themes. In short, it is not a good default for our purposes (though users have the option to override the applicable colours, as explained in the Modus themes manual).

Thanks to Morgan Willcock for reporting the unwanted change in issue 139: https://github.com/protesilaos/modus-themes/issues/139.

The bg-paren-match of modus-vivendi-tinted is a bit greener

We go from #5f789f to #4f7f9f. The latter fits better with the rest of the theme.

Refined the “mail” semantic mappings of the tinted themes

This concerns message.el and anything building on top of it, like Gnus, Mu4e, and Notmuch. I made modus-operandi-tinted and modus-vivendi-tinted use two colours that are more in line with the established patterns of their respective theme. The changes are small, but contribute to a more consistent experience.

A new property semantic mapping is available

By default, it uses the same colour as the variable. Users who want to have more refined colouration in supported modes (typically involving tree-sitter), can change the relevant “palette overrides” user option we provide, such as modus-themes-common-palette-overrides or modus-operandi-palette-overrides and related.

Thanks to Alexandr Semenov for requesting this in issue 141: https://github.com/protesilaos/modus-themes/issues/141.

My tmr package is now supported

Its faces were already consistent with the Modus themes, though now I cover them at the theme level to subject them to palette overrides.

The “ancient” Gnus messages are styled properly

Those are only ever seen if the user configures Gnus in a certain way and follows a specific workflow. They now get a subtle foreground value. This is in response to the issue 119 by sivaramn: https://github.com/protesilaos/modus-themes/issues/119.

The modus-themes-rotate command can now go backwards

When called with a prefix argument (C-u by default), this command will rotate the modus-themes-to-rotate from right to left. Otherwise, it goes from left to right.

Thanks to Jacob S. Gordon for the contribution. It was sent as a patch as part of issue 143: https://github.com/protesilaos/modus-themes/issues/143.

-1:-- Emacs: modus-themes version 4.8.0 (Post Protesilaos Stavrou)--L0--C0--2025-06-11T00:00:00.000Z

Irreal: Using Ramírez’s DWIM Tools

I’ve written several times about Álvaro Ramírez’s DWIM tools [1, 2, 3, 4, 5, 6] and their use in easily invoking command line utilities from the comfort of Emacs. Ramírez has a large collection of such utilities built on the DWIM Tool framework but I’ve never seen anyone else use it for their own work.

Now JTR over at The Art Of Not Asking Why has a post that describes his own use of DWIM Tools. JTR wanted to compress videos while preserving their resolution. That’s pretty easy to do using FFmpeg and JTR knew how to do it but he decided to see if he could use DWIM Tools for the job.

It turned out to be pretty easy as you can read at JTR’s post. The lesson I take from this is not that there’s another application available under the DWIM Tools umbrella but that it’s pretty easy to add one. If you have some command line utility that would be convenient to invoke from within Emacs, you should take a look at DWIM Tools. It’s available from Melpa and GitHub.

-1:-- Using Ramírez’s DWIM Tools (Post Irreal)--L0--C0--2025-06-10T16:48:24.000Z

Irreal: Learning To Love Emacs

My friend and erstwhile colleague Watts Martin has been seeking the one true path of light and virtue. After years of aborted attempts to embrace Emacs, he has, it seems, finally succeeded. Actually, snark aside, I understand his journey. It largely parallels mine.

Back when we were colleagues, I was still a Vim user but had already begun making feeble attempts to move to Emacs. It was always a silly thing, like the default scrolling behavior, that drove me away. In my case, it was finally moving to Lisp that pushed me over the edge to embracing Emacs. Martin’s journey was similar. He tried several times to move to Emacs but it just wouldn’t take, until it did.

While we Emacers can rejoice in another convert, Martin’s post is actually a balanced account of the strengths and weaknesses of Emacs. The downsides that Martin mentions are mostly the usual difficulties that n00bies encounter. Those of us who have made the journey from n00bie to journeyman can forget how hard it was at first. In particular, Martin calls out the difficulty of coercing Emacs into behaving as a “modern” editor by which he means using things like Tree-sitter and LSP. He complains, correctly, that there isn’t a good guide to help beginners configure Emacs to support a useful, modern workflow.

On the other hand, he notes that Emacs can molded into whatever you want it to be. It is, as I always say, a light weight Lisp Machine, although Martin doesn’t use that term. That fact, he says, makes it unlikely that folks who aren’t willing to “hack around with their editors” will ever adopt Emacs.

Martin ends by saying,

But the thing is, I think I also get Emacs. And once you get Emacs, there’s probably no going back.

I doubt he understands how true that is. He’s like a guy who’s fallen into quicksand and doesn’t realize it. For him, as for us, there is no escape.

-1:-- Learning To Love Emacs (Post Irreal)--L0--C0--2025-06-09T15:52:31.000Z

Sacha Chua: 2025-06-09 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, 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 comment on Mastodon or e-mail me at sacha@sachachua.com.

-1:-- 2025-06-09 Emacs news (Post Sacha Chua)--L0--C0--2025-06-09T12:22:23.000Z

TAONAW - Emacs and Org Mode: compressing mp4 files while keeping better quality with dwim in Emacs

I mentioned Rameriez’s dwim tools, and it’s only natural to do some IT for fun when I rest from IT at work on the weekend, Right…? Eh, don’t answer that.

One of the important and excellent things about Rameriez’s package is that it makes it easy to build something custom of your own using the “Lego blocks” he provided with the package.

For example, one of the commands that comes with the package is dwim-shell-commands-resize-video, which lets you resize the resolution of a video (and through that, its size). It does the job well, but I wanted something that compresses videos while retaining their resolution for quality. I know how to do this directly with ffmpeg, so I thought I’d give dwim a go, and got something working pretty quickly:

    (defun jtr/dwim-shell-command-compress-mp4-fast ()
      "Compresses mp4 down further using slow preset."
      (interactive)
      (dwim-shell-command-on-marked-files
       "Compresses MP4s with libx265 using slow preset to bring down size"
       "ffmpeg -i '<<f>>' -c:v libx265 -crf 25 -preset slow '<<fne>>_compressed.mp4'"
       :utils "ffmpeg"))

There are a couple of things at work here with ffmpeg:

First, libx265, which is a newer decoder than the default libx264. The newer version does a better job at retaining video quality when compressing, but at the cost of compatibility; some older systems might not be able to play the resulting MP4 file or say there’s something wrong with it until you install the needed decoder. If you’re playing with ffmpeg regularly, you probably won’t have a problem - but the people you send these videos to might, so keep that in mind.

Second, the slow preset. This increases the time it takes ffmpeg to work on the video as it combs through the frames more carefully. I forget exactly what it does, but I believe it grabs a smaller group of frames each time, so more frame groups (hence more time) with different compression values.

Lastly, the CRF value is at 25, a bit less than the default 28 for libx265, so a bit less compression. I can probably push it up a bit further, but the above already reduces the file size dramatically.

-1:-- compressing mp4 files while keeping better quality with dwim in Emacs (Post TAONAW - Emacs and Org Mode)--L0--C0--2025-06-07T22:00:59.000Z

Irreal: macOS Keybindings On Cocoa Ports

In response to my post macOS Keybindings In Emacs, Paul R. Jorgensen notes that not every macOS Emacs port has the OS bindings defined. In particular, those ports based on the Mac’s Cocoa interface don’t support them.

Jorgensen has his own post on the matter that goes into a bit more detail. As far as I can tell, unless your using Mitsuharu Yamamoto’s Emacs port for the mac this isn’t a problem but if you’re not using a NextStep based port, you’re probably going to have a problem using macOS keybindings in Emacs.

Not to worry though. If you want those keybindings and your port doesn’t provide them, Jorgensen shows you how to get them. His setup assumes the ⌘ Cmd key is mapped to Super so that, for instance, ⌘ Cmd+s is mapped to Super+s. If you have ⌘ Cmd mapped to something else, it may not work as well. For example, if you map ⌘ Cmd to Meta the way many people do, then ⌘ Cmd+v is going to get you a scroll up rather than a paste.

As I said in my original post, I don’t think that there’s a lot a value in having these bindings added to Emacs—but see hmelman’s comment for an contrary viewpoint—so I wouldn’t bother changing my mappings if you’re a ⌘ Cmd == Meta user. Regardless, as Jorgensen says, “Emacs is a wonderfully flexible tool, is it not?”

-1:-- macOS Keybindings On Cocoa Ports (Post Irreal)--L0--C0--2025-06-07T15:28:06.000Z

Paul Jorgensen: my/update-calendar-location-from-corelocationcli

I asked Charles Choi about adding corelocationcli similar to what journelly.el uses. We discussed it a bit. I went away and this is what the robot overlord helped me put together.

(defun my/update-calendar-location-from-corelocationcli ()
  "Update `calendar-latitude`, `calendar-longitude`, and `calendar-location-name`
from the output of the `CoreLocationCLI` command line utility. Made with ChatGPT."
  (interactive)
  (unless (executable-find "CoreLocationCLI")
    (error "CoreLocationCLI is not installed (try `brew install corelocationcli`)"))
  (with-temp-buffer
    (let ((exit-code (call-process "CoreLocationCLI" nil t nil
                                   "--format" "%latitude\t%longitude\t%thoroughfare")))
      (if (not (eq exit-code 0))
          (error "CoreLocationCLI failed to get location")
        (let* ((parts (split-string (buffer-string) "\t"))
               (lat (string-to-number (nth 0 parts)))
               (lon (string-to-number (nth 1 parts)))
               (desc (string-trim (nth 2 parts))))
          (setq calendar-latitude lat
                calendar-longitude lon
                calendar-location-name desc)
          (message "Updated calendar location: %s (%.4f, %.4f)"
                   calendar-location-name calendar-latitude calendar-longitude))))))

I think this works, so could call it when the calendar is invoked:

(add-hook 'calendar-mode-hook #'my/update-calendar-location-from-corelocationcli)

… or some such. Thoughts?

-1:-- my/update-calendar-location-from-corelocationcli (Post Paul Jorgensen)--L0--C0--2025-06-06T21:15:59.000Z

Irreal: macOS Keybindings In Emacs

I periodically publish reminders that

  1. macOS uses some common Emacs editing keystrokes by default, and that
  2. You can do much better by adding other Emacs keystrokes to those that macOS will recognize.

Here’s one such recent reminder. Now Bozhidar Batsov has turned the tables and revealed that Emacs also recognizes many macOS commands1. If you look in ns-win.el you’ll see a rather long list of macOS bindings that Emacs will recognize. You can, for example, save a file with ⌘ Cmd+s or start an incremental search with ⌘ Cmd+f. There’s a surprisingly large number of other such bindings. Take a look at Batsov’s post or ns-win.el for the details.

I didn’t know about any of this except for using ⌘ Cmd+f for isearch. I stumbled on that because I rebound Ctrl+s to swiper-isearch but sometimes wanted to do a regular incremental search. Even then, it didn’t click that Emacs was emulating macOS keybindings.

Other than that—and examples like it that other users may need—I can’t see the point of using those bindings. It seems like just another way of confusing my muscle memory. Of course, as I’ve confessed before, I’m very bad at handling multiple sets of keybindings.

For me, it makes more sense to make Emacs keybinding available to macOS rather than the other way around. Of course, you may disagree and want to standardize on macOS bindings. The great thing is that, as usual, Emacs2 let’s us have it our way.

Footnotes:

1

When it’s running on macOS, of course.

2

Well, in this case, macOS gets some credit for making it easy to use Emacs binding across the OS.

-1:-- macOS Keybindings In Emacs (Post Irreal)--L0--C0--2025-06-05T15:30:40.000Z

Irreal: Casual Timezone

Charles Choi has another great addition to his Casual Suite. This time he helps us with the common problem of figuring out what time it is in some other place. As Choi says, the Internet makes it common to communicate regularly with people from all over the world. Even the introverts at Irreal find themselves dealing with this.

Choi says that the most common way of dealing with the problem is with a clock app—which typically show times from all over the world—or just looking it up on the Internet. I do the latter. When I want to communicate with someone in, say, London, I simply search for something along the lines of “what time is it in London?”.

Choi notes that Emacs already has all the machinery to deal with this sort of thing. It just needs to be pulled together into a user accessible package. That’s what Casual Timezone does. It provides a myriad of ways to map the time at one place to the time at another.

At this point, the Casual Suite has so many useful apps that it’s probably best to simply install the whole suite even if there are some that you don’t use. Choi’s use of transient menus makes it easy to use them without having to deal with a bunch of bindings that you seldom use and probably won’t remember. Take a look at his post for an animation of Casual Timezone in action and see it it’s something that might fit your needs.

-1:-- Casual Timezone (Post Irreal)--L0--C0--2025-06-04T16:23:41.000Z

Paul Jorgensen: My emacs-mac macOS keybindings

Bozhidar Batsov has a post up about Little known macOS keybindings. It’s great with one large caveat: it’s only true for some Emacsen on macOS. There are two basic ports (not to be confused with macports or similar): NextStep (ns) and Cocoa (mac). A quick search will explain the names, but one might recognize the abbreviations if one has ever added some Mac-specific code in their config that includes something like:

;; FILE MANAGEMENT

(use-package emacs
  :if (memq window-system '(mac ns))
  :custom
  (mac-system-move-file-to-trash-use-finder t)
  )

Anywho, if you’re like me and running Mitsuharu Yamamoto’s emacs-mac port (homebrew macports), that is the Cocoa (mac) variant. Batsov’s post only applies to the NextStep (ns) variant. He told me uses the regular GNU Emacs, none of the ports. TBF Batsov’s post probably applies to most Emacs on macOS users regardless. ※ I might be totally wrong about this, so please, YMMV.

Here is a sample of what I do in my config to get (most) of these keybindings in my Emacs suited to my needs:

;; My Super (s-) maps
(use-package emacs
  :bind
  (
   ("C-s-SPC"   . nil                        ) ; blocked by Alfred for me; ns-do-show-character-palette in NS port
   ("M-s-h"     . nil                        ) ; ns-do-hide-others in NS port
   ("s-&"       . kill-current-buffer        )
   ("s-'"       . next-window-any-frame      )
   ("s-'"       . other-frame                )
   ("s-,"       . customize                  )
   ("s-0"       . text-scale-reset           )
   ("s-:"       . ispell                     )
   ("s-<"       . text-scale-decrease        )
   ("s-<down>"  . end-of-buffer              )
   ("s-<left>"  . backward-sentence          ) ; move-beginning-of-line in NS port
   ("s-<right>" . forward-sentence           ) ; move-end-of-line in NS port
   ("s-<up>"    . beginning-of-buffer        )
   ("s->"       . text-scale-increase        )
   ("s-?"       . info                       ) ; conflicts w/ MacOS
   ("s-C"       . nil                        ) ; conflicts w/ Named Keyboard Switcher; ns-popup-color-panel in NS port
   ("s-D"       . dired                      )
   ("s-E"       . edit-abbrevs               )
   ("s-H"       . nil                        ) ; ns-do-hide-others in NS port
   ("s-L"       . shell-command              )
   ("s-M"       . manual-entry               )
   ("s-S"       . write-file                 ) ; ns-write-file-using-panel in NS port
   ("s-Z"       . redo                       )
   ("s-a"       . mark-whole-buffer          )
   ("s-c"       . my-smart-copy-dwim         ) ; ns-copy-including-secondary in NS port
   ("s-d"       . nil                        ) ; isearch-repeat-backward in NS port
   ("s-e"       . isearch-yank-kill          ) ; blocked by my Keyboard Maestro macro top open Finder window
   ("s-f"       . consult-line-multi         ) ; isearch-forward in NS port
   ("s-g"       . er-keyboard-quit           )
   ("s-h"       . nil                        ) ; ns-do-hide-emacs in NS port
   ("s-j"       . exchange-point-and-mark    )
   ("s-k"       . kill-current-buffer        ) ; Xah has a better function for this
   ("s-l"       . goto-line                  )
   ("s-m"       . iconify-frame              )
   ("s-n"       . make-frame                 )
   ("s-o"       . mac-open-file-using-panel  ) ; ns-open-file-using-panel in NS port
   ("s-p"       . print-buffer               ) ; conflicts w/ MacOS print
   ("s-q"       . save-buffers-kill-emacs    ) ; TODO make this safer
   ("s-s"       . save-buffer                )
   ("s-t"       . menu-set-font              )
   ("s-u"       . revert-buffer              )
   ("s-v"       . xah-paste-or-paste-previous) ; yank in NS port
   ("s-w"       . xah-close-current-buffer   ) ; delete-frame in NS port
   ("s-x"       . my-smart-cut-dwim          )
   ("s-y"       . nil                        ) ; ns-paste-secondary on NS port
   ("s-z"       . undo                       )
   ("s-|"       . nil                        ) ; shell-command-on-region in NS port
   ("s-~"       . previous-frame             )
   :map org-mode-map
   (
    ("s-'"      . org-single-quote-region-or-point)
    ("s-+"      . cc/emphasize-strike-through     )
    ("s--"      . org-subscript-region-or-point   ) ; center-line in NS port
    ("s-<tab>"  . completion-at-point             )
    ("s-="      . cc/emphasize-verbatim           )
    ("s-C"      . cc/emphasize-code               )
    ("s-\""     . org-double-quote-region-or-point)
    ("s-^"      . org-superscript-region-or-point ) ; orig. kill-some-buffer
    ("s-_"      . cc/emphasize-underline          )
    ("s-b"      . cc/emphasize-bold               )
    ("s-e"      . cc/emphasize-dwim               )
    ("s-i"      . cc/emphasize-italic             )
    ("s-r"      . cc/emphasize-remove             )
    ("s-l"      . org-goto-line                   )
    )
   :map markdown-mode-map
   (
    ("s-<tab>"  . completion-at-point        )
    ("s-="      . cc/emphasize-verbatim      )
    ("s-C"      . cc/emphasize-code          )
    ("s-_"      . cc/emphasize-underline     )
    ("s-b"      . cc/emphasize-bold          )
    ("s-e"      . cc/emphasize-dwim          )
    ("s-i"      . cc/emphasize-italic        )
    ("s-s"      . cc/emphasize-strike-through)
    )
   )
  )

Some of the functions I call come from other bits of my config. ※ Where one sees ‘nil’ above is where there’s a conflict or where I’m not sure what I want on that keybinding yet.

Here’s a neat one that opens a file using the macOS dialog:

(defun mac-open-file-using-panel ()
    "A quick way to open files with your system file picker,

URL `https://christiantietze.de/posts/2022/12/use-file-open-dialog-for-file-actions/'
Created: 2025-06-04
Version: 2025-06-04"
    (interactive)
    (let ((last-nonmenu-event nil)
	  (use-dialog-box t)
	  (use-file-dialog t))
      (call-interactively #'find-file))
)

It is bound to s-o.

As before, one can tailor this to their needs.

If you do this or have a better approach, let me know!

-1:-- My emacs-mac macOS keybindings (Post Paul Jorgensen)--L0--C0--2025-06-04T15:09:30.000Z

TAONAW - Emacs and Org Mode: Journelly is having me try a new perspective

A couple of people wrote back to me regarding my last post about the challenges I have with Journelly (which, again, don’t really have anything to do with the app itself, but my workflow).

In an Email, HTH let me know that while Syncthing is not officially supported on iOS, there is an app that works and does the job just fine: SyncTrain. I tested it, and it successfully synced my files to my iPhone, iCloud not included. That’s an amazing find.

Meanwhile, I was thinking about how I can better streamline my process of refiling Journelly’s entries to my journal, where they are… archived. Duh! I can simply use org-mode to archive entries into my journal file. All I need to do is define the file I want them to archive into in the file options at the start of the file. Journelly even has an archive feature built in, but since I want to save my entries off the phone, it won’t work for me.

However, I realized I might not want to send my Journelly entries away. Journelly is convenient, and I use it constantly for notes. Having these available on my iPhone (where Journelly has an excellent search feature with tags) and on Emacs on the Mac at the same time is a boon to my productivity, not to mention, it just looks so nice on the phone.

So now I’m considering a different mental approach. Instead of refiling and moving entries away from Journelly, I’m going to try and expand on what I have there later. Some of this I already discussed before: things like meeting entries, for example, can be copied later to my dedicated meeting file, and activities can be copied to my event file, if I feel there’s more to add. The missing piece is expanding on “mind dumps” in Journelly that go into tangents. For that, I want to break the ideas into specific subjects with Denote later. For example, if I write an entry in the morning about Journelly and I’m realizing I’m rambling about the app and have ideas, I can later put these ideas into a “Journelly thoughts” note later with Denote, along with the appropriate keywords and attachments, as needed. This, I think, also covers the concern I have regarding privacy and iCloud, as the Journelly entry will just cover the initial nugget, where I will write some key points which I will later develop in a dedicated note off Apple’s servers.

This is all pretty new and raw in my head, so I’m going to try that out for the rest of the week and see how I feel.

-1:-- Journelly is having me try a new perspective (Post TAONAW - Emacs and Org Mode)--L0--C0--2025-06-04T14:35:00.000Z

James Dyer: Building Your Own Orderless Style Completion in Emacs Lisp

While packages like orderless provide flexible “any word, any order” completion, sometimes you want something lightweight and easy to tweak (well I do anyway). In this post, I’ll show you how to implement a simple orderless-like completion style using only Emacs Lisp, and how to integrate it smoothly into your workflow.

Traditional completion in Emacs often matches prefixes or substrings, but sometimes you want to type a few key parts of a word, in any order, and jump straight to your target. That’s what orderless and similar completion styles allow. But what if you want to write your own, or experiment with the logic?, well I will show you how…

Let’s walk through the logic:

(defun simple-orderless-completion (string table pred point)
  "Enhanced orderless completion with better partial matching."
  (let* ((words (split-string string "[-, ]+"))
         (patterns (mapcar (lambda (word)
                             (concat "\\b.*" (regexp-quote word) ".*"))
                           words))
         (full-regexp (mapconcat 'identity patterns "")))
    (if (string-empty-p string)
        (all-completions "" table pred)
      (cl-remove-if-not
       (lambda (candidate)
         (let ((case-fold-search completion-ignore-case))
           (and (cl-every (lambda (word)
                            (string-match-p
                             (concat "\\b.*" (regexp-quote word))
                             candidate))
                          words)
                t)))
       (all-completions "" table pred)))))

What’s Happening Here?

  • Word Splitting:

    The user’s input (a string) is split into words on spaces, dashes, or commas. This produces a list of “search terms.” This means that, in the minibuffer, the word separator can be any of these characters. I was initially really faffing around and struggling to work out how to insert a space between words in the minibuffer, as it seems to perform some form of completion. However, I eventually figured out that M-SPC actually inserts a space, allowing you to separate words. I use fido-mode, so I’m not sure if this is the same for other minibuffer completion systems.

    After initially adding in the comma separator however I found that I actually prefer it, it is easier to access and I don’t think any keywords, functions e.t.c will typically contain a comma?

  • Pattern Construction:

    For each word, a regex pattern is constructed: \\b.*WORD.*. This means: “find a word boundary, followed by any characters, then the word, then anything else.” This is a bit looser than strict word matching, and you can tune it.

  • Candidate Filtering:

    We generate all possible completions with all-completions and then filter them down. For a candidate to match, all the search terms (words) must appear somewhere, in any order.

  • Case Sensitivity:

    Matching respects completion-ignore-case, so your results will be case-insensitive if you want of course.

Registering and Using the Style

To make Emacs aware of your new completion style, add it to completion-styles-alist:

(add-to-list 'completion-styles-alist
             '(simple-orderless simple-orderless-completion
                                simple-orderless-completion))

Contextual Use: Minibuffer Only

You might not want this style everywhere (which I suspect is likely). For example, in file completion you might prefer strict prefix matching. So, let’s activate it only in the minibuffer:

(defun setup-minibuffer-completion-styles ()
  "Use orderless completion in minibuffer, regular completion elsewhere."
  ;; For minibuffer: use orderless first, then fallback to flex and basic
  (setq-local completion-styles '(basic simple-orderless flex substring)))

;; Hook into minibuffer setup
(add-hook 'minibuffer-setup-hook #'setup-minibuffer-completion-styles)

Tweaking and Extending

  • Pattern Tuning:

    The regexes can be made stricter or looser (e.g., remove \\b for more “fuzzy” matching).

  • Word Separators:

    You can split on other characters if your workflow uses different delimiters.

  • Order of Styles:

    Adjust the order in completion-styles to prefer your custom style over others. I found that if the simple-orderless style was listed first, pressing Tab to bring up the completions buffer doesn’t work, which I like to use sometimes, so that is why basic is first.

Conclusion

With just a handful of lines, you can build your own orderless-like completion style, giving you full control and transparency. This is a great starting point for experimenting with more advanced completion logic, and a good illustration of the power of Emacs’ built-in completion framework!

-1:-- Building Your Own Orderless Style Completion in Emacs Lisp (Post James Dyer)--L0--C0--2025-06-04T08:40:00.000Z

Irreal: Improving Keyboard-quit

Bozhidar Batsov is back with a quick tip that many of you will probably find useful. It’s an improvement to keyboard-quit or, as we all know and love it, Ctrl+g.

One of Batsov’s pet peeves is that keyboard-quit doesn’t function as expected when the minibuffer is active. Happily that and a few other infelicities are easily fixed as he shows in his post. The code that Batsov presents in his post is short. It’s more comment than code yet it does fix the problems that were annoying Batsov.

Here, from the code comments, is what his improved code does:

The DWIM behaviour of this command is as follows:

- When the region is active, disable it.
- When a minibuffer is open, but not focused, close the minibuffer.
- When the Completions buffer is selected, close it.
- In every other case use the regular `keyboard-quit'."

You don’t have to edit Emacs source code. You simply include his function in your init.el and remap Ctrl+g to it. It’s easy to try out his code and if you don’t like it, simply drop back to the default behavior by undoing the key sequence remapping.

-1:-- Improving Keyboard-quit (Post Irreal)--L0--C0--2025-06-03T15:36:25.000Z

Chris Maiorana: Obsidian users curious about Emacs

I just published a video about a Reddit post in which an Obsidian user asks about Emacs: pros and cons, and “aha” moments.

I’m not big on software supremacy type arguments. Whatever tool you decide to use is the best tool for you. I don’t see the point in forever touting one tool over another.

However, I don’t want to downplay the philosophical side of the argument. People who spend time carefully plotting out software choices are no different than laborers in any other field who want to pick the best tool for whatever job they’re doing.

For whatever reason (and I would be curious to get reader comments on this), users of open source tools tend to be more philosophical, I’ve noticed, than users of Windows or Mac products. What I mean by that is, FOSS users tend to value choice, and with that choice there is a greater assumption that you can make wise choices and unwise choices.

Quick example. A Mac user who needs to do some design work has no choice: they have to shell out for a Photoshop license. (They could consider using something like GIMP, but for most users that option would be too beyond the pale, and they might fear the difficulty of integrating a non-standard open source tool within their existing workflow.)

On the other hand, someone who has grown accustomed to open source tools takes on a whole different set of questions. “Can I use GIMP for my project? Of course, but do I need to use it?  Couldn’t I just assemble my graphical items into a script and pipe it into ffmpeg?  What is the best tool for this particular job? What is my ideal result? Should I favor speed or accuracy? Or both?”

Anyway… back to the Obsidian question.

Obsidian is a fine tool. If anyone is purely interested in taking notes and does not use Emacs already, I’d recommend just sticking with Obsidian. It does exactly what you need it to do.

However, if you’re using Emacs already, and you’re comfortable with the interface, I couldn’t think of a good reason to use Obsidian, unless you want to show off a cool hyperlinked graph of your notes and tags.

A few of the other points I mentioned in the video:

  • Emacs provides a superior writing environment.
  • You can code your own note system with Emacs lisp.
  • Emacs’s longevity makes it a safer choice for long term projects.

Whatever tool you decide to use, it’s always best to first take a step back and decide what your ideal outcome would be. Then you can more quickly sample different tools and get an idea of which one will work best for you.

As always, if you enjoy these topics you should subscribe to my newsletter.

The post Obsidian users curious about Emacs appeared first on The Daily Macro.

-1:-- Obsidian users curious about Emacs (Post Chris Maiorana)--L0--C0--2025-06-03T14:08:15.000Z

Emacs Redux: Tree-sitter powered code completion

Tree-sitter has taken the world of programming by a storm. Together with LSP, it’s probably the technology that has influenced the most programming editors and IDEs in the past several years. And now that Emacs 29+ comes with built-in Tree-sitter support I’ve been spending a lot of quality time with it, working on clojure-ts-mode and neocaml-mode.

There’s a lot I’d like to share with you about using Tree-sitter effectively, but today I’ll focus on a different topic. When most people hear about Tree-sitter they think of font-locking (syntax highlighting) and indentation powered by the abstract syntax tree (AST), generated by a Tree-sitter grammar. For a while I’ve also been thinking that the AST data can also be used for simple, yet reasonably accurate, code completion. (within the context of a single code buffer, that is) That’s definitely not nearly as powerful of what you’d normally get from a dedicated tool (e.g. an LSP server), as those usually have project-wide completion capabilities, but it’s pretty sweet given that it’s trivial to implement and doesn’t require any external dependencies.

Below, you’ll find a simple proof of concept for such a completion, in the context of clojure-ts-mode:1

(defvar clojure-ts--completion-query-globals
  (treesit-query-compile 'clojure
                         `((source
                            (list_lit
                             ((sym_lit) @sym
                              (:match ,clojure-ts--variable-definition-symbol-regexp @sym))
                             :anchor [(comment) (meta_lit) (old_meta_lit)] :*
                             :anchor ((sym_lit) @var-candidate)))
                           (source
                            (list_lit
                             ((sym_lit) @sym
                              (:match ,clojure-ts--function-type-regexp @sym))
                             :anchor [(comment) (meta_lit) (old_meta_lit)] :*
                             :anchor ((sym_lit) @fn-candidate))))))

(defconst clojure-ts--completion-annotations
  (list 'var-candidate " Global variable"
        'fn-candidate " Function"))

(defun clojure-ts--completion-annotation-function (candidate)
  (thread-last minibuffer-completion-table
               (alist-get candidate)
               (plist-get clojure-ts--completion-annotations)))

(defun clojure-ts-completion-at-point-function ()
  (when-let* ((bounds (bounds-of-thing-at-point 'symbol))
              (source (treesit-buffer-root-node 'clojure))
              (nodes (treesit-query-capture source clojure-ts--completion-query-globals)))
    (list (car bounds)
          (cdr bounds)
          (thread-last nodes
                 (seq-filter (lambda (item) (not (equal (car item) 'sym))))
                 (seq-map (lambda (item) (cons (treesit-node-text (cdr item) t) (car item)))))
          :exclusive 'no
          :annotation-function #'clojure-ts--completion-annotation-function)))

I hope you’ll agree that the code is both simple and easy to follow (especially if you know a bit about Tree-sitter queries and Emacs’s completion APIs). The meat of the example is clojure-ts--completion-annotation-function, the rest is just completion scaffolding.

And the result looks like this:

clojure-ts-completion.png

Not too shabby for 30 lines of code, right? With a bit more efforts this can be made smarter (e.g. to include local bindings as well), and potentially we can even be consulting all open buffers running clojure-ts-mode to fetch completion data from the as well. (although that’s probably an overkill)

Still, I think that’s an interesting use of Tree-sitter that some of you might find useful. It seems that Nic Ferrier has been playing with this idea recently as well - check out his recent video on the subject here.

In time Tree-sitter will redefine how we’re building Emacs major modes and what they can do.2 It’s still early days and sky is the limit. Exciting times ahead!

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

P.S. I plan to write more on the topic of Tree-sitter and how to use it in Emacs major modes, but in the mean time you might find some of my development notes useful:

  1. Kudos to Roman Rudakov, who put this prototype together earlier today after a short discussion we had on the topic. 

  2. I can easily imagine things like Tree-sitter based linters or complex refactoring commands. 

-1:-- Tree-sitter powered code completion (Post Emacs Redux)--L0--C0--2025-06-03T13:21:00.000Z

Emacs Redux: Little known macOS keybindings

Today’s article is going to be a bit more weird than usual… mostly because I’ve set to write about one topic, and ended up about writing something completely different in the end… Here we go!

TL;DR Many common macOS keybindings (e.g. Command-s, Command-z, Command-f, etc) work in Emacs. And, of course, it’s well known that macOS uses by default Emacs-like (readline) keybindings everywhere. (e.g. C-a and C-e)

I’m guessing 99% of Emacs users know that the most common ways to start isearch are with isearch-forward (C-s) and isearch-backward (C-r). That’s not the full story, though! While working on my recent isearch article I noticed that out-of-the-box there are two other keybindings for those commands:

  • s-f (isearch-forward)
  • s-F (isearch-backward)

Note: s in this context means Super, which is usually Win in Windows and Command in macOS.

When I saw those I was like “hmm, seems someone wanted to make Emacs a bit more approachable to macOS users coming other editors”. But here things got interesting…

I tried to find out where those extra keybindings were defined, and after a bit of digging I found them in the ns-win.el library1, which defines a ton of macOS-specific keybindings:

;; Here are some Nextstep-like bindings for command key sequences.
(define-key global-map [?\s-,] 'customize)
(define-key global-map [?\s-'] 'next-window-any-frame)
(define-key global-map [?\s-`] 'other-frame)
(define-key global-map [?\s-~] 'ns-prev-frame)
(define-key global-map [?\s--] 'center-line)
(define-key global-map [?\s-:] 'ispell)
(define-key global-map [?\s-?] 'info)
(define-key global-map [?\s-^] 'kill-some-buffers)
(define-key global-map [?\s-&] 'kill-current-buffer)
(define-key global-map [?\s-C] 'ns-popup-color-panel)
(define-key global-map [?\s-D] 'dired)
(define-key global-map [?\s-E] 'edit-abbrevs)
(define-key global-map [?\s-L] 'shell-command)
(define-key global-map [?\s-M] 'manual-entry)
(define-key global-map [?\s-S] 'ns-write-file-using-panel)
(define-key global-map [?\s-a] 'mark-whole-buffer)
(define-key global-map [?\s-c] 'ns-copy-including-secondary)
(define-key global-map [?\s-d] 'isearch-repeat-backward)
(define-key global-map [?\s-e] 'isearch-yank-kill)
(define-key global-map [?\s-f] 'isearch-forward)
(define-key esc-map [?\s-f] 'isearch-forward-regexp)
(define-key minibuffer-local-isearch-map [?\s-f]
  'isearch-forward-exit-minibuffer)
(define-key isearch-mode-map [?\s-f] 'isearch-repeat-forward)
(define-key global-map [?\s-F] 'isearch-backward)
(define-key esc-map [?\s-F] 'isearch-backward-regexp)
(define-key minibuffer-local-isearch-map [?\s-F]
  'isearch-reverse-exit-minibuffer)
(define-key isearch-mode-map [?\s-F] 'isearch-repeat-backward)
(define-key global-map [?\s-g] 'isearch-repeat-forward)
(define-key global-map [?\s-h] 'ns-do-hide-emacs)
(define-key global-map [?\s-H] 'ns-do-hide-others)
(define-key global-map [?\M-\s-h] 'ns-do-hide-others)
(define-key global-map [?\s-j] 'exchange-point-and-mark)
(define-key global-map [?\s-k] 'kill-current-buffer)
(define-key global-map [?\s-l] 'goto-line)
(define-key global-map [?\s-m] 'iconify-frame)
(define-key global-map [?\s-n] 'make-frame)
(define-key global-map [?\s-o] 'ns-open-file-using-panel)
(define-key global-map [?\s-p] 'ns-print-buffer)
(define-key global-map [?\s-q] 'save-buffers-kill-emacs)
(define-key global-map [?\s-s] 'save-buffer)
(define-key global-map [?\s-t] 'menu-set-font)
(define-key global-map [?\s-u] 'revert-buffer)
(define-key global-map [?\s-v] 'yank)
(define-key global-map [?\s-w] 'delete-frame)
(define-key global-map [?\s-x] 'kill-region)
(define-key global-map [?\s-y] 'ns-paste-secondary)
(define-key global-map [?\s-z] 'undo)
(define-key global-map [?\s-+] 'text-scale-adjust)
(define-key global-map [?\s-=] 'text-scale-adjust)
(define-key global-map [?\s--] 'text-scale-adjust)
(define-key global-map [?\s-0] 'text-scale-adjust)
(define-key global-map [?\s-|] 'shell-command-on-region)
(define-key global-map [s-kp-bar] 'shell-command-on-region)
(define-key global-map [?\C-\s- ] 'ns-do-show-character-palette)
(define-key global-map [s-right] 'move-end-of-line)
(define-key global-map [s-left] 'move-beginning-of-line)

(define-key global-map [home] 'beginning-of-buffer)
(define-key global-map [end] 'end-of-buffer)
(define-key global-map [kp-home] 'beginning-of-buffer)
(define-key global-map [kp-end] 'end-of-buffer)
(define-key global-map [kp-prior] 'scroll-down-command)
(define-key global-map [kp-next] 'scroll-up-command)

;; Allow shift-clicks to work similarly to under Nextstep.
(define-key global-map [S-mouse-1] 'mouse-save-then-kill)
(global-unset-key [S-down-mouse-1])

;; Special Nextstep-generated events are converted to function keys.  Here
;; are the bindings for them.  Note, these keys are actually declared in
;; x-setup-function-keys in common-win.
(define-key global-map [ns-power-off] 'save-buffers-kill-emacs)
(define-key global-map [ns-open-file] 'ns-find-file)
(define-key global-map [ns-open-temp-file] [ns-open-file])
(define-key global-map [ns-open-file-line] 'ns-open-file-select-line)
(define-key global-map [ns-spi-service-call] 'ns-spi-service-call)
(define-key global-map [ns-new-frame] 'make-frame)
(define-key global-map [ns-toggle-toolbar] 'ns-toggle-toolbar)
(define-key global-map [ns-show-prefs] '

Some of them look quite convenient (easy to press), so I might add a few to my daily work. I’m shocked I never trying any of the standard macOS keybindings for things like adjusting text size in Emacs. Or perhaps I tried them and then I forgot about them… :D

Still, even though I’m a macOS users (at least for the time being), I doubt I’ll end up using many of them. The reason for this is that I learned Emacs on Linux and I’m extremely used to the default keybindings. Between remembering all of those, and trying to master Vim (as of late), it’s hard to teach this old dog any new tricks. That being sad, I can imagine those keybindings being useful to many other people, especially if they haven’t learned Emacs on Linux 20 years ago.

Tip: Do a M-x find-library RET ns-win to see what else the library has in store for macOS users.

All of this is, of course, made possible by the fact that macOS relies heavily on the Command key which normally isn’t used in Emacs at all. For similar reasons it’s “easier” to copy/paste text from/in your shell on macOS, compared to Linux and Windows, as keybindings like Command + c and Command + v are not used by any shell.

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

P.S. After writing this article I was really amused that I’ve been using macOS on and off for over 10 years and I never bothered to try whether something like Command-s or Command-z works in Emacs! Oh, well… habits!

  1. Emacs stubbornly keeps refering to macOS by its ancient name NextStep in much of the code and its documentation. 

-1:-- Little known macOS keybindings (Post Emacs Redux)--L0--C0--2025-06-03T06:48:00.000Z

Tim Heaney: Hy PyO3!

Lately, I've been messing with Codelist Tools, a Rust library for working with medical codelists. Among other things, it uses PyO3 to provide bindings that enable its use from Python. I had not tried this before. It's fun! It occurred to me that it should also work from Hy, a Lisp dialect for Python. So, I gave it a try…and it does! Running either of these produces
-1:-- Hy PyO3! (Post Tim Heaney)--L0--C0--2025-06-03T00:00:00.000Z

Irreal: Why Does Emacs Take So Long To Load

Over at the Emacs subreddit, EachDaySameAsLast asks the perennial question: why does Emacs take so long to load. Actually, his question is, “Why do people say Emacs takes so long to load?” He has, he says, been using Emacs since its TECO days and has never, even in the old days, experienced overly long load times. To be sure, his configuration file is relatively short—about 100 lines—but Emacs loads for him in under 2 seconds.

Of course, as many of us have been saying and saying, none of that matters. For almost every user, Emacs shouldn’t be started very often: once a day at most, once every week or month typically.

As usual, the interesting part of the post is the comments. Almost everyone agrees: the load times don’t matter but if you use use-package and the defer option judiciously, your load time can be small too.

I’m beginning to feel as if I’m codependent with those people claiming that Emacs takes too long to load. I should probably just stop writing about it. Of course, it won’t matter. People—many of whom don’t even use Emacs—will keep repeating it.

But let me just repeat, with Batsov, that Emacs load time doesn’t matter. It really doesn’t.

-1:-- Why Does Emacs Take So Long To Load (Post Irreal)--L0--C0--2025-06-02T15:22:38.000Z

Sacha Chua: 2025-06-02 Emacs news

Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, r/planetemacs, 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:-- 2025-06-02 Emacs news (Post Sacha Chua)--L0--C0--2025-06-02T13:19:50.000Z

Charles Choi: Announcing Casual Timezone

Because the Internet, it is a blessing of our time that interacting with people in different time zones is commonplace. In this, the question is often raised: “what time is it there?” This is routinely answered using a clock app or a website.

While Emacs has long had the ability to make time zone calculations, it seemed overdue to have tooling that takes advantage of it.

Announcing Casual Timezone, now available as part of the Casual v2.5.0 update on MELPA.

The following screencast shows Casual Timezone in action, in this case a meeting planner (command: casual-timezone-planner) that compares the hours with your local time zone with that of another.

Casual Timezone also lets you directly ask:

  • “What time is it over there?” (command: casual-timezone-local-time-to-remote)
  • “That time over there, what is it here?” (command: casual-timezone-remote-time-to-local)

Note that at current, Casual Timezone only supports Unix-variant systems as it relies on the tz database. It has been tested on macOS 15.5 and Ubuntu Linux 22.04. Sorry Windows users, but I’m open for a PR for Windows support if a workaround for zoneinfo is available.

Closing Thoughts

With experience, I’ve learned to be humble about working with time APIs. While I’ve done much to ensure the results are accurate, I would not be surprised if there are bugs, especially for a first release. Let me know if you find any.

On reflection, putting Casual Timezone together was relatively easy as it was largely an exercise in integrating different Elisp packages:

  • From Org, the command org-read-date provided the date picker UI.
  • Built-in completion provided the UI for selecting a time zone.
  • vtable provided the table interface for casual-timezone-planner.
  • The table interface was configured as a derived mode to provide mode-specific behavior.
  • The built-in time functions were used for time zone calculations and formatting.
  • Transient provided support for menus.

Gonna call this an Elisp code-reuse success story.

References

-1:-- Announcing Casual Timezone (Post Charles Choi)--L0--C0--2025-06-02T13:00:00.000Z

Emacs Redux: Let’s make keyboard-quit smarter

I’ll be pretty brief today. keyboard-quit (C-g) is one of the most used commands, but unfortunately it’s not very smart. Most annoyingly, it doesn’t work as expected when the minibuffer is active.

Fortunately, fixing such problems (and then some) is trivial in Emacs:

(defun er-keyboard-quit ()
  "Smater version of the built-in `keyboard-quit'.

The generic `keyboard-quit' does not do the expected thing when
the minibuffer is open.  Whereas we want it to close the
minibuffer, even without explicitly focusing it."
  (interactive)
  (if (active-minibuffer-window)
      (if (minibufferp)
          (minibuffer-keyboard-quit)
        (abort-recursive-edit))
    (keyboard-quit)))

I’d suggest to just remap keyboard-quit to our improved version:

(global-set-key [remap keyboard-quit] #'er-keyboard-quit)

There are other ways to tackle this particular issue, of course, and different people might prefer an even more complicated version of the smarter keyboard-quit or one that does fewer things. One of my readers suggested in the comments a similar solution using an advice:

(define-advice keyboard-quit
    (:around (quit) quit-current-context)
  "Quit the current context.

When there is an active minibuffer and we are not inside it close
it.  When we are inside the minibuffer use the regular
`minibuffer-keyboard-quit' which quits any active region before
exiting.  When there is no minibuffer `keyboard-quit' unless we
are defining or executing a macro."
  (if (active-minibuffer-window)
      (if (minibufferp)
          (minibuffer-keyboard-quit)
        (abort-recursive-edit))
    (unless (or defining-kbd-macro
                executing-kbd-macro)
      (funcall-interactively quit))))

This has the benefit of directly modifying the original command, so you don’t really need to rebind anything. On the other hand - advices are arguably a bit more complicated to understand and debug. Personally, I like to replace functions in my own setup with versions that I prefer, as I think this makes the modifications more obvious.

Another option is a similar function from Prot:1

(defun prot/keyboard-quit-dwim ()
  "Do-What-I-Mean behaviour for a general `keyboard-quit'.

The generic `keyboard-quit' does not do the expected thing when
the minibuffer is open.  Whereas we want it to close the
minibuffer, even without explicitly focusing it.

The DWIM behaviour of this command is as follows:

- When the region is active, disable it.
- When a minibuffer is open, but not focused, close the minibuffer.
- When the Completions buffer is selected, close it.
- In every other case use the regular `keyboard-quit'."
  (interactive)
  (cond
   ((region-active-p)
    (keyboard-quit))
   ((derived-mode-p 'completion-list-mode)
    (delete-completion-window))
   ((> (minibuffer-depth) 0)
    (abort-recursive-edit))
   (t
    (keyboard-quit))))

I know this version of the command is quite popular in the wild, as many people follow Prot’s work, but looking at the code of the actual keyboard-quit it seems to me that Prot’s version is more complicated than it needs to be:

;; This executes C-g typed while Emacs is waiting for a command.
;; Quitting out of a program does not go through here;
;; that happens in the maybe_quit function at the C code level.
(defun keyboard-quit ()
  "Signal a `quit' condition.
During execution of Lisp code, this character causes a quit directly.
At top-level, as an editor command, this simply beeps."
  (interactive)
  ;; Avoid adding the region to the window selection.
  (setq saved-region-selection nil)
  (let (select-active-regions)
    (deactivate-mark))
  (if (fboundp 'kmacro-keyboard-quit)
      (kmacro-keyboard-quit))
  (when completion-in-region-mode
    (completion-in-region-mode -1))
  ;; Force the next redisplay cycle to remove the "Def" indicator from
  ;; all the mode lines.
  (if defining-kbd-macro
      (force-mode-line-update t))
  (setq defining-kbd-macro nil)
  (let ((debug-on-quit nil))
    (signal 'quit nil)))

As you can see it already handles things like the selected region and completion in region. But perhaps I’m missing what Prot was trying to achieve with his version.

Which of the three approaches do you prefer? How would you improve er-keyboard-quit-dwim further?

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

-1:-- Let’s make keyboard-quit smarter (Post Emacs Redux)--L0--C0--2025-06-01T20:39:00.000Z

TAONAW - Emacs and Org Mode: I wish I could use Journelly's new location features, but...

Journelly keeps getting updated with good features. One of the latest features I noticed (I’m not sure if it was part of the latest patch) is that locations tagged with entries can be revisited in iOS Maps from the app. This makes Journelly a good spot to save locations and integrate them with personal memories, to be revisited later on the map. I would like to use this (instead of, say, a saved of locations on Google Maps), but I can’t - for two reasons.

The first one, which I can work around, is that the list of entries on Journelly quickly becomes long, and finding where you were a couple of weeks ago requires some scrolling. While Journelly has a search option, I usually don’t remember the name of the place I’m searching for, which is why I’m searching for it in the first place. Still, I could probably look for who I was with at the time, or even better, use the tagging feature, which was introduced a couple of weeks ago, for, say, “#cafes” to filter down cafes only.

The other issue is more challenging: I don’t keep my notes in Journelly. I keep refiling my entries into my main journal file. That file, while still on my Mac, is not synced with iCloud. Call me paranoid, but I don’t trust Apple’s iCloud with my personal notes along with my pictures throughout the years. As far as I’m concerned, Apple just has a better PR department than Google and Microsoft, and they only care about their users' privacy as long as it’s what looks good in the news. Because of that, I am not comfortable with Journelly being my archive of notes. There could be other options besides iCloud, but as far as I know, they all involve a cloud company somewhere. On Android and macOS, I still use the excellent Syncthing, which doesn’t involve any cloud storage. However, Syncthing doesn’t work on iOS, so I’m out of luck.

Besides these two issues (which have nothing to do with the app), the app is terrific. It’s amazing how polished and responsive it is.

-1:-- I wish I could use Journelly's new location features, but...  (Post TAONAW - Emacs and Org Mode)--L0--C0--2025-06-01T20:13:39.000Z

Irreal: Web Browsing In Emacs

Joar Von Arndt has an interesting post on a subject that many Emacs users obsess about: how to bring Web browser functionality into Emacs. As, I’ve said many times, virtually all my tube time is either in Emacs or Safari. I would, of course, like to get that down to just Emacs. To be sure, I do use some other apps but my time with them is basically in the noise. Almost everything I do on the computer involves Emacs or the browser.

Von Arndt looks at eww, w3m, Xwidgets, and EAF. He discusses the pros and cons of each. He appears to think that eww—with some customization—is the best solution.

My solution is to use Xwidgets for rendering Email posts that need it and for my RSS feed via Elfeed. My email client, mu4e, makes it easy to switch between text and HTML rendered displays. It is, in a way, the best of both worlds. I can read most of my emails in plain text, as the elders decreed, but can switch to an HTML rendered display when I need to.

I use elfeed-webkit to display my RSS feed with Elfeed. It brings up each entry in a browser like display and, of course, can be easily be toggled on and off. It’s a bit fragile, as Von Arndt says, but it easier than invoking the brower for each entry.

The sad news is that there still isn’t a good solution but what solutions there are are getting better. Perhaps we will soon have a way of bringing the final major holdout into the Emacs fold.

-1:-- Web Browsing In Emacs (Post Irreal)--L0--C0--2025-06-01T14:46:41.000Z

Sacha Chua: Working on the plumbing in a small web community

The IndieWeb Carnival prompt for May is small web communities. I've been exploring some thoughts on how a little effort goes a long way to connecting a community. Sometimes I think of it as working on the plumbing so that ideas can flow more smoothly. It feels a little different from the direct contribution of knowledge or ideas. I also want to connect with other people who do this kind of thing.

Emacs is a text editor that has been around since the 1970s. It's highly programmable, so people have come up with all sorts of ways to modify it to do what they want. It's not just for programmers. My favourite examples include novelists and bakers and musicians who use Emacs in unexpected ways. Because Emacs is so flexible, community is important. The source code and documentation don't show all the possible workflows. As people figure things out by themselves and together, more possibilities open up.

I love tweaking Emacs to help me with different things I want to do, and I love learning about how other people use it too. I've been sharing my notes on Emacs on this blog since 2001 or so. In 2015, as I was getting ready to become a parent, I knew I was going to have much less time and focused attention, which meant less time playing with Emacs. Fortunately, around that time, John Wiegley (who was one of the maintainers of Emacs at the time) suggested that it would be helpful if I could keep an eye on community updates and summarize them. This worked well with the fragmentation of my time, since I could still speed-read updates and roughly categorize them.

Text from sketch

Community plumbing

You don't have to fill the pipes all by yourself. Just help things flow.

I want to share some of the things we're doing in the Emacs community so that I can convince you that building plumbing for your community can be fun, easy, and awesome. This is great because enthusiasm spreads.

virtuous cycle

  • Other places: YouTube, Reddit, HN, lobste.rs, Mastodon, PeerTube, mailing lists….
  • Blog aggregator
    • Planet Emacs Life (uses Planet Venus) - update: [2025-05-31 Sat] I wrote my own RSS feed aggregator instead.
  • Newsletter: Emacs News, 1-2 hours a week
    • summarize & group
    • announce calendar events
  • User groups
    • [often use Emacs News to get conversations going]
  • iCal & Org files: Emacs Calendar
  • Conference
    • EmacsConf: < USD 50 hosting costs + donated server + volunteer time

Tips:

  • Make it fun for yourself.
  • Build processes and tools.
  • Let people help

2024-01-31-05

Some more notes on the regular flows built up by this kind of community plumbing:

Daily: Lots of people post on reddit.com/r/emacs and on Mastodon with the #emacs hashtag. I also aggregate Emacs-related blog posts at planet.emacslife.com, taking over from planet.emacsen.org when Tess had DNS issues. There are a number of active channels on YouTube and occasionally some on PeerTube instances as well. I don't need to do much work to keep this flowing, just occasionally adding feeds to the aggregator for planet.emacslife.com.

Weekly: I collect posts from different sources, remove duplicates, combine links talking about the same thing, categorize the links, put them roughly in order, and post Emacs News to a website, an RSS feed, and a mailing list. This takes me maybe 1.5 hours each week. It's one of the highlights of my week. I get to learn about all sorts of cool things.

Weekly seems like a good rhythm for me considering how active the Emacs community is. Daily would be too much time. Monthly would lead to either too long of a post or too much lost in curation, and the conversations would be delayed.

Sometimes I feel a twinge of envy when I check out other people's newsletter posts with commentary or screenshots or synthesis. (So cool!) But hey, I'm still here posting Emacs News after almost ten years, so that's something. =) A long list of categorized links fits the time I've got and the way my mind works, and other people can put their own spin on things.

Monthly: There are a number of Emacs user groups, both virtual and in-person. Quite a few of them use Emacs News to get the discussion rolling or fill in gaps in conversation, which is wonderful.

Some meetups use meet.jit.si, Zoom, or Google Meet, but some are more comfortable on a self-hosted service using free software. I help by running a BigBlueButton web conferencing server that I can now automatically scale up and down on a schedule, so the base cost is about 60 USD/year. Scaling it up for each meetup costs about USD 0.43 for a 6-hour span. It's pretty automated now, which is good because I tend to forget things that are scheduled for specific dates. My schedule still hasn't settled down enough for me to host meetups, but I like to drop by once in a while.

Yearly: EmacsConf is the one big project I like to work on. It's completely online. It's more of a friendly get-together than a formal conference. I have fun trying to fit as many proposed talks as possible into the schedule. We nudge speakers to send us recorded presentations of 5-20 minutes (sometimes longer), although they can share live if they want to. A number of volunteers help us caption the videos. Each presentation is followed by Q&A over web conference, text chat, and/or collaborative document. Other volunteers handle checking in speakers and hosting the Q&A sessions.

It's a lot of fun for surprisingly little money. For the two-day conference itself, the website hosting cost for EmacsConf 2024 was about USD 56 and our setup was able to handle 400 viewers online (107 max simultaneous users in various web conferences).

EmacsConf takes more time. For me, it's about 1.5 hours a day for 4 months, but I think mostly that's because I have so much fun figuring out how to automate things and because I help with the captions. Lots of other people put time into preparing presentations, hosting Q&A, participating, etc. It's worth it, though.

I like doing this because it's a great excuse to nudge people to get cool stuff out of their head and into something they can share with other people, and it helps people connect with other people who are interested in the same things. Some Q&A sessions have run for hours and turned into ongoing collaborations. I like turning videos into captions and searchable text because I still don't have the time/patience to actually watch videos, so it's nice to be able to search. And it's wonderful gathering lots of people into the same virtual room and seeing the kind of enthusiasm and energy they share.

So yeah, community plumbing turns out to be pretty enjoyable. If this resonates with you, maybe you might want to see if your small web community could use a blog aggregator or a newsletter. Doesn't have to be anything fancy. You could start with a list of interesting links you've come across. I'm curious about what other people do in their communities to get ideas flowing!

Related: the community plumbing section of my blog post / livestream braindump.

View org source for this post

You can comment on Mastodon or e-mail me at sacha@sachachua.com.

-1:-- Working on the plumbing in a small web community (Post Sacha Chua)--L0--C0--2025-06-01T03:51:15.000Z

Protesilaos Stavrou: Emacs: spacious-padding version 0.7.0

This is a small release that makes spacious-padding-mode work as intended when used in tandem with the Emacs daemon and subsequent calls to emacsclient -c. I made the function responsible for triggering the “spacious padding” effects work with individual frames and then I responded to issue 33 by Lou Woell about integrating that with the server-after-make-frame-hook: https://github.com/protesilaos/spacious-padding/issues/33.

Additionally, the package now defines two faces that can be used to configure the user option spacious-padding-subtle-mode-line (read its documentation string for all the possible values it accepts).

Here is how they can be set (default value is nil):

(setq spacious-padding-subtle-mode-line
      '( :mode-line-active spacious-padding-subtle-mode-line-active
         :mode-line-inactive spacious-padding-subtle-mode-line-inactive))

Reload the spacious-padding-mode for changes to take effect.

When configured this way and with default styles they make the mode line use a minimalist overline with no background colour. The active mode line has a more noticeable border than the inactive ones. All my themes are designed to support this aesthetic (though themes can style those faces as they see fit).

About Spacious Padding

This package provides a global minor mode to increase the spacing/padding of Emacs windows and frames. The idea is to make editing and reading feel more comfortable. Enable the mode with M-x spacious-padding-mode. Adjust the exact spacing values by modifying the user option spacious-padding-widths.

Inspiration for this package comes from Nicolas Rougier’s impressive designs and Daniel Mendler’s org-modern package.

-1:-- Emacs: spacious-padding version 0.7.0 (Post Protesilaos Stavrou)--L0--C0--2025-06-01T00:00:00.000Z

Tim Heaney: Go to definition in Emacs

Today, I was reading Why Use Structured Errors in Rust Applications? and one of the issues discussed is jumping away from the code you're working on to look at the definition of the error. On the one hand, rust-analyzer makes it really easy to jump to the error, but on the other hand they felt that they sometimes had to do so unnecessarily. In the comments on lobste.rs, matklad mentioned that he recently adopted the habit of splitting the screen first and going to the definition in the split (in Emacs terms, in the other window).
-1:-- Go to definition in Emacs (Post Tim Heaney)--L0--C0--2025-06-01T00:00:00.000Z

Marcin Borkowski: Converting integers to ISO-8601 timestamps

Two weeks ago I wrote about using defcustom​’s :get and :set keywords, allowing the user to set an option containing a Unix timestamp (that is, a number) using an ISO-8601 timestamp. Today I am going to use such an option.
-1:-- Converting integers to ISO-8601 timestamps (Post Marcin Borkowski)--L0--C0--2025-05-31T18:40:14.000Z

Matt Maguire: Plain Text Accounting with Emacs – Part 3

My journey into using Hledger with Emacs to track my share investments continues. Last Time I looked at a way to track shares using a plain text file. Since then I have made some tweaks to my workflow as I gain more experience:

  • naming conventions that support multiple stock brokers
  • booking brokerage fees in a better way to support the Australian tax system.

Naming convention

Over the past month I was not overly impressed with my existing stock broker, which led me to explore other stock brokers that may offer a more reliable service at a cheaper rate. It is expensive to transfer stocks over to a new broker, so I decided to cap further investment at my current broker and instead make any new purchases at a different broker. This meant that I would need an account structure that lets me easily identify which share lots were purchased through which broker.

-1:-- Plain Text Accounting with Emacs – Part 3 (Post Matt Maguire)--L0--C0--2025-05-30T00: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!