Charles Choi: macOS Native Emoji Picking in Emacs from the Edit Menu

The cross-platform Emoji picker (emoji-list) in Emacs is nice. But if you’re on macOS running the NS variant of Emacs, you can use the macOS-native picker which is better (😍). The command to raise this picker is ns-do-show-character-palette.

Unfortunately, this command is not configured to be in the main menu by default. The following Elisp initialization code will rectify that, placing the menu item “Emoji & Symbols” at the bottom of the Edit menu from the main menu. The :visible slot ensures that this will only take effect on NS Emacs.

1
2
3
4
5
(easy-menu-add-item global-map '(menu-bar edit)
                    ["Emoji & Symbols"
                     ns-do-show-character-palette
                     :help "Show macOS Character Palette."
                     :visible (eq window-system 'ns)])

Note that users of the Mitsuharu Yamamoto fork of Emacs (aka Emacs Mac App) don’t have to do this as this behavior is already there. It used to be my daily driver but I switched over to the NS variant with the 29.4 release some time ago because the latter was actively maintained. I suspect (sadly 😞) that the Yamamoto fork is being left to bit-rot which is regrettable as that fork is the superior version when it comes to native macOS integration. With the upcoming Emacs 30 release, I think this will become even more pronounced. I'd be happy to be wrong on this though.

References

-1:-- macOS Native Emoji Picking in Emacs from the Edit Menu (Post Charles Choi)--L0--C0--2025-02-18T18:30:00.000Z

Irreal: Searching For The Thing At Point

Just a quick post about a short note from Marcin Borkowski (mbork) concerning searching for the thing at point. Despite using Emacs for over 18 years I didn’t know about isearch-forward-thing-at-point.

As mbork says, it does just what it says. You invoke it with Meta+s Meta+. and it searches forward for whatever the point is on. This is something I want to do all the time and I was vaguely aware that it was possible but didn’t know exactly how to do it, so I’m really glad to see mbork’s post.

Finding out about this now serves to emphasize that learning Emacs really is a lifelong journey.

-1:-- Searching For The Thing At Point (Post Irreal)--L0--C0--2025-02-18T16:54:28.000Z

Protesilaos Stavrou: Emacs: dired-preview version 0.4.0

This is a simple package to automatically preview in a window the file at point in Dired buffers. Preview windows are closed when they are no longer relevant, while preview buffers are killed if they have not been used for other purposes beside previewing. The package provides several customisation options to control its behaviour.

Below are the release notes


Version 0.4.0 on 2025-02-18

This version contains several refinements and bug fixes.

Preview buffers have a mode line indicator

Preview buffers have a prefix to their name to make them stand out. This is controlled by the user option dired-preview-buffer-name-indicator, which is a string that defaults to [P].

Control how preview buffers are cleaned up

The way dired-preview works is to display a buffer and then keep a list of preview buffers to economise on redisplaying it again. This list of buffers is relevant for as long as we are in the Dired buffer, otherwise all buffers therein are killed (buffers that were alive before being previewed are not touched).

By default we delete from oldest to newest the accumulated buffers when they exceed 10 in total. Though users can modify this behaviour by editing the value of the new user option dired-preview-kill-buffers-method (its doc string explains the technicalities).

Thanks to artelse for discussing this with me in issue 20: https://github.com/protesilaos/dired-preview/issues/20.

The dired-preview-display-action-alist has a new optional function

The dired-preview-display-action-alist is the user option which controls where the preview window is displayed. Its value can either be the symbol of a function or a display-buffer-alist entry.

By default, we have a “do-what-I-mean” function that tries to find a good placement for the window. The new dired-preview-display-action-alist-below function has a straightforward behaviour: it always shows the preview below the current window and it always makes the preview window 0.3 times the height of the Emacs frame.

Encypted files are no longer previewed

This is to ensure that potentially sensitive contents are not displayed by accident, such as during a video call.

We no longer preview the “self” directory

We should not trigger a preview when the cursor is over the implicit . directory, as that causes a recursion that breaks things. Thanks to Inkbottle007 for reporting the bug in issue 23: https://github.com/protesilaos/dired-preview/issues/23.

Miscellaneous

  • Fixed a scenario where we would try to delete the last available window on the current frame. This should never happen. Thanks to artelse for reporting a relevant bug in the discussion of issue 22: https://github.com/protesilaos/dired-preview/issues/22.

  • Fixed a case when hexl-follow-ascii could fail to find an overlay under certain conditions. This did not create any noticeable problems, though having an error there would interfere with any workflow that would rely on toggle-debug-on-error.

  • The preview window will automatically be closed if the user switches outside the given Dired buffer. We now do not consider a change to the minibuffer as being “outside” this context. This way, a quick M-x to, say, enable a minor mode does not have any effect on the window layout.

  • Suppressed the messaging facility of the underlying tracking of preview buffers. Otherwise, Dired would notify us that the directory has changed whenever we would preview a new one, which is superfluous.

  • The body of the dired-preview-trigger function, which determines whether a preview will be displayed, is encapsulated in a condition-case. This helps capture errors and thus have a more predictable behaviour.

  • The dired-preview-display-action-alist has a more accurate declaration which allows for its correct customisation inside the Custom UI interface. In particular, it will behave the same way as the display-buffer-alist, where relevant.

-1:-- Emacs: dired-preview version 0.4.0 (Post Protesilaos Stavrou)--L0--C0--2025-02-18T00:00:00.000Z

Lars Ingebrigtsen: HTML, but not too HTML

When writing blog posts, I use ewp, an Emacs package to administrate WordPress. It offers an editing mode based on the revolutionary idea of just writing HTML.

Everything is cyclical in computing, so people move between writing things in raw HTML and using arcane and unholy systems, mostly based on some Markdown dialect. I understand the frustrations: It feels like there should be something that’s less annoying than using some WYSIWYG tool that invariably freaks out and ruins your post, or typing all that annoying HTML yourself, or using Markdown and then having to have some kind of build step.

In my opinion, Markdown is fine for writing README files, but if you’re writing blog posts, it just gets in the way. A blog post is mainly just paragraphs like the one I’m typing (and you’re reading) now, which is just text with no markup. Or there’s some slight formatting for emphasis or the like, but honestly, there’s not much difference between the HTML and Markdown versions for that.

Markdown is nice for headings and code snippets, but doesn’t really offer much useful for blog posts. And the things that blog posts need, which is images/screenshots and links: Markdown doesn’t help you much there.

Is that really better than the HTML version? And what, then if you need more stuff in the link?

It just gets worse and worse — what if you need to put more data into the links? The nice thing about HTML is that it’s well-formed and not very hacky — the more cruft you add to the HTML, the more unreadable it gets — but linearly. Markdown makes the easy stuff trivial, and the difficult stuff worse. (Here’s there the Greek chorus of “but you can just write HTML in Markdown” comes in, but that’s worse than just writing HTML in the first place.)

So: I write HTML, and Emacs takes care of displaying the images I’m linking to, so a blog post looks like this while I’m writing:

(To digress: I’ve noted over the years the many, many posts on HackerNews about statically generated blogs, and people have more fun spending time tinkering with their setups than actually writing blog posts, and that’s fine. But I’ve noted that virtually none of these systems have a mechanism for dealing with images in a natural way — because that’s just kinda hard. The nearest you get is “then you just create an S3 bucket and put the image there, and then you go to the AWS console to get the URL, and then you paste that into the Markdown here. See? PROBLEM SOLVED!!!” That’s why blog posts from all these people (random example) are almost always just walls of text.)

Anyway, here’s my problem:

YIKES! WHAT THE… Yes, I hear you.

To protect myself a bit against link rot, ewp screenshots everything I link to automatically. So on the blog, you can just hover over a link to see (and read, if you want to) what I was linking to at the time, and that will survive as long as my blog survives (while most of the things I’m linking to disappear, apparently).

But that means that I have to stash that data somewhere, and I stashed it in the links, which means that the HTML then becomes unreadable.

This is Emacs, however. What about just hiding all that junk?

Yes, that’s the same paragraph with the links hidden. And if I want to edit the links themselves, I can just hit TAB on the bracket:

And TAB again to hide:

Note that the links and stuff are still present in the Emacs buffer, so the normal Emacs autosave functions work perfectly, and there’s no danger of losing any data.

Similarly, the image HTML in WordPress can be pretty messy:

Because images have extra classes with their IDs, and you can click on images to get the full sizes, so they’re (almost always) wrapped in an <a>. Now, when writing articles, Emacs displays the images instead of the HTML, so we don’t see all that cruft anyway, but when editing image heavy articles, it can take some time to fetch the images, and we don’t want to be staring at junk like that while waiting for the images to arrive.

So let’s hide them like this:


And TAB can be used to cycle through the three different forms:

I think that looks kinda pleasant to work with…

Anyway, I think that’s as far as I want to go with hiding the HTML-ness of things. I mean, the temptation here is to start going in a more WYSIWYG direction, and translating <b>…</b> into bold text and all that sort of stuff, but… I’m more comfortable just looking at the tags?

So there you go: In the “just write HTML/no don’t write HTML” wars, I’m on “just write HTML but have the editor hide some of the worst of the cruft” tip.

-1:-- HTML, but not too HTML (Post Lars Ingebrigtsen)--L0--C0--2025-02-17T18:23:46.000Z

Sacha Chua: 2025-02-17 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, communick.news, 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
-1:-- 2025-02-17 Emacs news (Post Sacha Chua)--L0--C0--2025-02-17T15:54:07.000Z

Irreal: Recurring Checklists

Vineet Naik has a post with a nice tip. He often has complex build processes and rather than automating them with a script, he prefers to use an Org checklist that specifies the steps. He likes to keep the checklist in the project directory and check off the build items as he performs them.

That seems pretty straightforward but there’s a catch. After he’s done the build and checked off all the items the list is no longer useful. He’d like to reset the checklist to “empty” but what’s the best way of doing that? My first reaction was to keep the checklist as a Yasnippet, delete the completed checklist, and use the snippet to create a new copy.

But, he says, what if he needs to make a change to the checklist during the build? Then he has to remember the change the snippet too. The thing about Org mode is that everything is just text so he solved his problem by doing a query-replace to change [x] to [ ]. That worked well so his next thought was to automate it by writing a bit of Elisp.

That’s when he discovered that Emacs already has a package for that. That’s the point of the tip. After loading the package you need simply add :RESET_CHECK_BOXES: t to the property drawer and Emacs will handle everything for you. When the status of the checkbox tree changes from TODO to DONE, all the checkbox items are cleared and the status is reset to TODO. All this happens automatically. That makes it perfect for Naik’s problem.

There’s actually a bit more to the solution so be sure to check out Naik’s post for the details.

-1:-- Recurring Checklists (Post Irreal)--L0--C0--2025-02-17T15:45:05.000Z

Org Mode requests: [FR] org-read-date-style

[FR] org-read-date-style
-1:-- [FR] org-read-date-style (Post Org Mode requests)--L0--C0--2025-02-17T11:10:21.000Z

Marcin Borkowski: isearch-forward-thing-at-point

One thing which I do very often is isearching for some term, like a function or variable name. Recently I learned that Emacs has a nice feature which helps with that. Pressing M-s M-. (or M-s .) invokes the isearch-forward-thing-at-point command, which does exactly what you would expect. Very useful! In fact, pressing M-s C-h reveals even more usefulness. Try it out for yourself!
-1:-- isearch-forward-thing-at-point (Post Marcin Borkowski)--L0--C0--2025-02-17T05:57:04.000Z

200ok: Shell Smith: A Clojure Library for Building CLI Tools with Elegant Configuration Management

Shell Smith is a Clojure library that simplifies the creation of command-line interface (CLI) tools by providing a robust configuration management system with smart defaults based on your namespace.

Key Features

  • Namespace-Aware Configuration: One of Shell Smith's most powerful features is its ability to automatically use the current namespace as the default name for:
    • Configuration file naming (<name>.yml)
    • Environment variable prefix pattern
    • When no explicit :name option is provided
  • Multi-source Configuration: Shell Smith manages configurations from:
    • Default values
    • YAML configuration files
    • Environment variables
    • Command-line arguments

How It Works

The library uses a config macro that merges configuration values from different sources. Here's an example showing both explicit naming and namespace-based defaults:

;; With explicit naming
(def config-explicit
  (shell-smith/config usage
    :defaults {:port 3000}
    :name "mytool"))

;; Using namespace-based defaults
;; If your namespace is 'my.app.server'
;; - Will look for 'my.app.server.yml'
;; - Will match env vars starting with 'MY_APP_SERVER_'
(def config-from-ns
  (shell-smith/config usage
    :defaults {:port 3000}))

Configuration Resolution

The configuration sources are merged in this order (from lowest to highest priority):

  • Default values
  • YAML configuration file (<name>.yml in current working directory)
  • Environment variables (matching pattern <UPPERCASE_NAME>_*)
  • Command-line arguments

For example, if your namespace is my.app.tool, Shell Smith will automatically:

  • Look for my.app.tool.yml in the current directory
  • Match environment variables starting with MY_APP_TOOL_

This convention-over-configuration approach makes it incredibly easy to organize your CLI tool's configuration while maintaining flexibility when needed.


If you liked this post, please consider supporting our Free and Open Source software work – you can sponsor us on Github and Patreon or star our FLOSS repositories.

-1:-- Shell Smith: A Clojure Library for Building CLI Tools with Elegant Configuration Management (Post 200ok)--L0--C0--2025-02-17T00:00:00.000Z

Norm: XPath server

-1:-- XPath server (Post Norm)--L0--C0--2025-02-16T18:26:10.000Z

Irreal: Sometimes The Current Flows Towards Emacs

Everyday I see several articles from—usually—younger developers opining that Emacs is too old-fashioned, non-intuitive, and, really, just too hard to bother learning. And, it doesn’t look nice like VS Code and other modern editors.

Okay, they’re young and don’t know any better. Maybe they’ll learn as they go along. But there are also older developers who have been using Emacs for years who say they’ve been seduced by the bling, and lately, AI integration. They too are choosing to use editors other than Emacs.

One would think, from reading all those posts, that there’s a one way current flowing from Emacs towards those lesser other editors. But that’s not true. There are still people who get a hint of Emacs’ power and make the effort to learn it. Ivan Prikaznov is a case in point.

He came into an IntelliJ shop as a green engineer so, of course, he used the IntelliJ IDEA editor like all his colleagues. But then he stumbled on Vim and learned about efficient editing. Eventually, he changed jobs and found himself editing a large configuration file. He realized that he was “essentially executing an algorithm by hand”. At that point he grasped that what he needed was a programmable editor and he turned to Emacs.

He hasn’t looked back. Now he does everything in Emacs and the Borg has assimilated a new member. Or something. In any event, it’s nice to know that Emacs is also gaining converts. It may not be a rapidly as the “in” editors but we’ve always known that Emacs is for the discerning.

-1:-- Sometimes The Current Flows Towards Emacs (Post Irreal)--L0--C0--2025-02-16T16:07:18.000Z

Mark Tomczak: Unstick Terminals in Emacs

I’ve used multi-term for years in emacs as my primary terminal interface. It works great, but occasionally while ssh’ing to another machine and using the emacsclient -t interface (my common approach), the terminal gets stuck to a too-small size. This happens most commonly when my ssh session crashes and I have to start a new one. It turns out the cause of this is that the terminal is taking its measurements from the other emacs window it’s bound to, and if you unbind it, it’ll be willing to take measurements from a new window.
-1:-- Unstick Terminals in Emacs (Post Mark Tomczak)--L0--C0--2025-02-16T00:28:27.000Z

Irreal: Using Emacs For Research Notes

Continuing with our “Emacs for all things” theme of the last couple of days, here’s another post that speaks to how Emacs can be used for many things and how seemingly difficult or even impossible tasks can be done by using the right packages.

The topic of the post is using Emacs for taking research notes. S4h4rJ says that he loves Emacs but that he finds it hard to use for taking research notes because it’s so hard to deal with figures (jpegs, etc.). They are, he says, hard to size and hard to place within the file.

That didn’t seem right to me and other researchers chimed in explaining how they handled the problems that S4h4rJ was complaining about. It’s surprising how often the answer is simply installing and using an existing Emacs package.

The TL;DR is that there are many researchers who use Emacs to take and organize their notes. They use things like org-download and org-roam to deal with problems specific to their workflows. Take a look at the comments to S4h4rJ’s post for the details.

The takeaway is lots of serious researchers are using Emacs everyday for taking and organizing their research notes. If you’re a researcher and want to use Emacs, there’s no reason you can’t. You just need to be aware of a few packages and techniques that ease the process. Read the comments to S4h4rJ’s post to get an idea of what’s available. Even if you’re not a researcher, you may find those packages useful for your own workflow.

-1:-- Using Emacs For Research Notes (Post Irreal)--L0--C0--2025-02-15T17:14:40.000Z

Irreal: A Followup To Why You Can’t Use Emacs More

One of the odd things about writing Irreal is that I never know which posts will be popular or at least provoke some engagement. Often, posts that I think are really interesting receive no comments and posts that I suspect will be of marginal interest strike a chord with readers.

Yesterday’s post, Reasons You Can’t Use Emacs More, is an example of the latter. I wrote it mostly because I was enraged by the idea of people who don’t use editors telling people who do which editors they can use. I didn’t expect most people to care but there are, it seems, a lot of our colleagues suffering from that and they are, likewise, enraged.

Of course, they’re hackers and often find ways of bypassing the nannies. But not all the problems are caused by the nannies. Often, the issue is finding some way of a way of performing a necessary task with Emacs. This usually arises when the “normal” app for performing some task won’t interoperate with Emacs.

Serendipitously, I found this Emacs subreddit post by arni_ca asking what sort of tasks people perform with Emacs. That seems only marginally related to JTR’s problems from yesterday’s post but when you read through the comments you find lots of ways people have found to do things in Emacs even if it doesn’t seem possible at first glance.

It is, really, an encouraging post because it shows that it’s very often possible to find some way of importing an important task into Emacs. The real problem is discovering those methods. Posts like arni_ca’s help but that still means reading through a lot of blogs and reddit posts to find them. Sacha’s Emacs News is a good place to start. It provides a weekly review of interesting Emacs news and helps keep you up to date with minimal effort.

-1:-- A Followup To Why You Can’t Use Emacs More (Post Irreal)--L0--C0--2025-02-14T16:45:42.000Z

Anand Tamariya: Emacs Font is wider

Emacs Font is wider than other applications. Most people don't notice the difference. If you can perceive it, you are not hallucinating. This can be attributed to the following:

Points per inch

#ifndef HAVE_ANDROID
/* Number of pt per inch (from the TeXbook).  */
#define PT_PER_INCH 72.27
#else
/* Android uses this value instead to compensate for different device
   dimensions.  */
#define PT_PER_INCH 160.00
#endif
  

Emacs definition is larger than the standard definition. The DTP point is defined as 1⁄72 of an inch. 

Round-off error

Emacs definition:

/* Return a pixel size (integer) corresponding to POINT size (double)
   on resolution DPI.  */
#define POINT_TO_PIXEL(POINT, DPI) ((POINT) * (DPI) / PT_PER_INCH + 0.5)

/* Return a point size corresponding to POINT size (integer)
   on resolution DPI.  Note that though point size is a double, we expect
   it to be rounded to an int, so we add 0.5 here.  If the desired value
   is tenths of points (as in xfld specs), then the pixel size should
   be multiplied BEFORE the conversion to avoid magnifying the error.  */
#define PIXEL_TO_POINT(PIXEL, DPI) ((PIXEL) * PT_PER_INCH / (DPI) + 0.5)
  

Rounding-off error is unavoidable. While looking for its source, look for how it's compensated in the application being compared.



-1:-- Emacs Font is wider (Post Anand Tamariya)--L0--C0--2025-02-14T03:05:00.000Z

Irreal: Reasons You Can’t Use Emacs More

Over at The Art Of Not Asking Why, JTR has some nice things to say about Irreal but that’s not what I want to talk about. Rather, I like to address the point of his post, which is how difficult it can be to use Emacs as much as he’d like.

There are two main issues. The first is work problems. Lots of companies make it difficult to use anything other than “approved applications”. These are almost always brain-dead Windows apps that don’t work all that well and certainly don’t interoperate with others apps.This sort of thing is usually driven by what my son calls the “Notwork Nazis”, his term for the network engineering folks having an obsession with making sure that not a single unauthorized activity takes place on “their” network.

These guys don’t—usually—care what you do on your own machine as long as it doesn’t impinge on the network. There are, sadly, more extreme cases. Consider this case of of a company so clueless and intent on controlling every aspect of their employees’ work environment that you can’t use Emacs at all because it’s “An old fashioned and slow text editor created by Canonical for use with the Ubuntu operating system.” These morons are actually scanning machines to make sure no unauthorized editors are being used.

There are many degrees of this dysfunction. If it’s only that you can’t access company Email through Emacs, that may be tolerable. If your management thinks Emacs was developed by Canonical, it’s probably time to find another job.

The second problem that JTR encounters is that Emacs doesn’t interoperate with some apps that are important in his workflow. He gives the example of Grammarly. Being a curmudgeon who doesn’t like being told what to do, I’m not a Grammarly user but I take JTR’s point.

These apps obviously have an API so they can interoperate with others apps but sometimes they’re loath to share them. I’m not sure why that’s so. Wouldn’t you want your app to work with as many other apps a possible?

In any event, it’s a sad truth that it’s not always possible to use Emacs as much as you’d like.

-1:-- Reasons You Can’t Use Emacs More (Post Irreal)--L0--C0--2025-02-13T16:56:34.000Z

Emacs Redux: Customizing Color Themes

Every now and then you’d be trying out a new color theme, that you really like overall, but you’d like to tweak a bit here and there to make it perfect. After all, that’s what Emacs is all about - creating the perfect editor for yourself.

Sometimes you might be dealing with missing face definitions or configuration options that you might want to submit upstream, but most of the time the changes you’d like to see are probably quite subjective and belong in your personal config. So, how do you make those changes?

There are 3 common ways to adjust font faces in Emacs and I’ll briefly cover all of them. Option number 1 is the tried and true classic custom-set-faces:

(custom-set-faces
 '(region ((t (:inherit nil :background "RoyalBlue4"))))
 '(highlight ((t (:inherit region :background "dark olive green"))))
 '(hl-line ((t (:inherit highlight)))))

That’s what gets generate if you’re adjusting faces with something like M-x customize-face. The bad thing about this approach is that those customizations will active regardless of your currently selected color theme and if you like to switch themes that’s not cool. Fortunately, it’s easily to narrow customizations to a particular theme with custom-theme-set-faces:

(custom-theme-set-faces
 'zenburn
 '(region ((t (:inherit nil :background "RoyalBlue4"))))
 '(highlight ((t (:inherit region :background "dark olive green"))))
 '(hl-line ((t (:inherit highlight)))))

Looking good!

Note: custom-set-faces works by calling custom-theme-set-faces for the user theme, a special theme referring to settings made via Customize.

Finally, you can just set a specific face using set-face-attribute like this:

(set-face-attribute 'font-lock-builtin-face nil :weight 'bold)

I’d suggest perusing the documentation of set-face-attribute (e.g. with C-h f) as it explains in great detail all the possible attributes you can configure for a font face. The number of properties you can set is truly epic, but most of the time you’ll need to tweak only a couple of them. (e.g. :foreground, :background, etc)

Technically speaking, you can go a step further than that and define your own theme that extends the color theme you want to modify1, but that’s an overkill unless you plan to distribute this theme as a package.

All the examples above are kind of random, so I’ll conclude here with some real modifications I do in my config to the popular Catppuccin theme:

(use-package catppuccin-theme
  :config
  ;; or 'latte, 'macchiato, or 'mocha
  (setq catppuccin-flavor 'macchiato)
  (load-theme 'catppuccin t)
  (custom-theme-set-faces
   'catppuccin
   ;; by default the theme uses the same face as for comments, which is wrong IMO
   '(font-lock-doc-face ((t (:foreground (catppuccin-color 'green)))))
   ;; font-lock variable definitions like function definitions
   '(font-lock-variable-face ((t (:inherit font-lock-function-face))))))

The example above also shows how to access the colors from the palette of some color theme outside of its definition. Usually themes provide some API like theme-name-color to get able to get the color codes easily.

Funny enough, as I’m writing this I realized that use-package actually has built-in support for customizing faces that I could have used instead. Here’s an example of that in action:

(use-package zenburn-theme
  :preface
  (setq my/zenburn-colors-alist
        '((fg . "#DCDCCC") (bg . "#1C1C1C") (cyan . "#93E0E3")))
  :custom-face
  (region ((t (:background ,(alist-get my/zenburn-colors-alist 'cyan)))))
  :config
  (load-theme 'zenburn t))

This example also reminded me that I should expose the Zenburn colors via functions.

So, to summarize:

  • If you’re using use-package it’s probably best to use it’s :custom-face functionality.
  • The rest of the time you most likely need custom-theme-set-faces.

One thing is certain - with Emacs there always numerous ways to achieve something!

Note: To see the new font faces in action you’ll either have to restart Emacs or evaluate Elisp code that sets them. (e.g. with C-x C-e)

One final tip - if you’re wondering what’s the face used by some text, the best way to figure it out is with the M-x describe-char command. It will give you a ton of information, including something like this near the end:

There are text properties here:
  face                 (font-lock-keyword-face markdown-code-face)
  font-lock-fontified  t
  font-lock-multiline  t
  fontified            t
  markdown-gfm-code    (2617 3092)

I had placed my cursor over the word “use-package” in the code snippet above, while writing this article in markdown-mode, therefore the faces font-lock-keyword-face (coming from elisp-mode) and markdown-code-face (from markdown-mode).

Do you have any tips on customizing color themes that you’d like share?

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

  1. Remember that Emacs allows you load multiple themes with them stacking one upon another. 

-1:-- Customizing Color Themes (Post Emacs Redux)--L0--C0--2025-02-13T08:23:00.000Z

Protesilaos Stavrou: Aporetic fonts version 1.1.0

Customised build of the Iosevka typeface, with a consistent rounded style and overrides for almost all individual glyphs in both upright (roman) and slanted (italic) variants. This is the successor to my now-discontinued “Iosevka Comfy” fonts.

Below are the release notes.


This release includes two stylistic corrections that pertain to Aporetic Serif and Aporetic Serif Mono.

  • The first change is to the slanted (italic) form of the letter t. Before, it was mistakenly set to have a curved, upward-facing bottom stroke, which would clash with the flat bottom of i and l. Now the slanted t has a flat bottom as intended. The upright (roman) variants are always flat in this regard.

  • The second change is to the letter m in both upright and slanted forms. Before, the m would have a top left serif, as intended, but not a bottom right tail. The tail is a feature of other glyphs that need to have such a style, like a, h, n, u: it imposes a proper rhythm together with the rest of the serif details. Now the m has its missing bottom right tail, making everything consistent.

    [ The m has a shorter middle leg in all the “mono” families” to improve readability, especially at small point sizes. The proportionately spaced fonts use a normal middle leg, as m is naturally wider there and thus is already perfectly legible. The other details are the same. ]

-1:-- Aporetic fonts version 1.1.0 (Post Protesilaos Stavrou)--L0--C0--2025-02-12T00:00:00.000Z

Irreal: Elisp Abstraction

Over at the Emacs subreddit, AbstProcDo proposes an interesting idea: some Elisp constructs are very intuitive and natural compared to other languages. He uses the example of dolist to process a list versus the Python way.

(dolist (item '(1 2 3 4))
  (print item))

versus

for item in ['a', 'b', 'c', 'd']:
    print(item)

It’s a valid point but I think there are better examples to make it. How about

(dotimes (i 10)
  (print i))

versus the same in C

for ( i = 0; i < 10; i++)
    printf( "%i ", i)

The Elisp macro suggests that we want to perform its body for the values \(0 \cdots 9\). The C for loop construct is all about initializing, incrementing, and terminating the loop. Of course, the same can be said of the Lisp do construct.

There’s nothing wrong with either of these approaches, of course. I’ve written a lot more C than I have any type of Lisp and the semantics of the for loop are embedded in my brain. Still, AbstProcDo has a point. The Elisp does seem more natural.

It would be easy to make too much of the comparison and enlist it for use in some sort of language war but that’s not my intention. I merely think it’s a provocative idea and worth thinking about. There are, I’m sure, counter examples, and I’m sure we’ll be learning all about them from the comments.

-1:-- Elisp Abstraction (Post Irreal)--L0--C0--2025-02-11T17:18:15.000Z

TAONAW - Emacs and Org Mode: More Emacs would be nice, but...

Earlier this morning, when I was up between my sleep phases, I was looking for some Emacs content through irreal, one of the most prolific Emacs blogs out there. Irreal publishes a post every day, and these posts usually summarize and link other Emacs-related posts to other blogs. It’s easy to find blogs with good Emacs stuff and check their archives for even more Emacs. That’s the life of an Emacs user - learn it, tweak it, find another cool thing you haven’t thought about, learn it, tweak it…

I would like to have more Emacs in my life, but unfortunately, it’s not easy.

My blog archives are full of complaints about Microsoft products and web tools that I have to use because of work. I can’t use email in Emacs because logging into Office 365 for work is restricted, and no other apps but Outlook can access it (not even Apple Mail). ServiceNow, the platform we use for IT tickets, has an API, but it’s also heavily restricted, forcing us to use the browser. Communications and phone calls happen on Teams, another closed Office 365 application. It’s not even just Microsoft specifically, even though I like to blame them: it’s the cloud.

I work with different IT departments, engineers, and managers. Usually, when app X doesn’t answer certain needs, the solution is to find a new app, which in turn is also integrated in the cloud with its own restrictions. This happens so many times that we don’t get the chance to explore the depth of one app before there’s another one. Each person brings his own new favorite app to add to the party.

I’m guilty of this too, on a personal level. I love writing in Emacs, but my favorite writing companion, Grammarly, doesn’t work with Emacs (yes, I know there were some packages for it in the past; they were abandoned, and as far as I know, Grammarly doesn’t have a working API anymore). Micro.blog uses its own macOS app for writing content, which brings convenient integration to my other content (like my photos and saved bookmarks) that I don’t currently have in Emacs, so I just copy-paste my posts into it these days. Even good tools like being on my iPhone are not as fluid as Apple Reminders or Notes, and it’s just easier to start something there and have the discipline (this is the weak link) to bring it all back into Emacs later.

Still, despite all of that, I love working in Emacs. It brings me peace that no other app does at this point because it’s entirely mine. I know where everything is, I know how to tweak it (or I can learn how to), and I can access its org files everywhere, even if I don’t have Emacs installed. No other application organizes my life and projects so well and for so long, and I don’t see anything replacing it in the near future.

-1:-- More Emacs would be nice, but... (Post TAONAW - Emacs and Org Mode)--L0--C0--2025-02-11T13:54:42.000Z

Arthur A. Gleckler: LLM Unlock

Xenodium's excellent chatgpt-shell package makes it easy to use ChatGPT and other LLMs from Emacs. Having all of Emacs's editing power and programmability while working with an LLM is a big win.

ChatGPT requires a license key, and chatgpt-shell needs access to it. It would be a bad idea to store the key in a plain text file, so I looked for a way to encrypt it. The chatgpt-shell README.org documents how to use the pass password manager, but I hadn't used pass before, so I did something even simpler: I used Emacs's built-in support for GPG. Maybe you'll find this approach useful, too.

I set up chatgpt-shell by adding this code to my Emacs init file:

(require 'use-package)

(use-package chatgpt-shell
  :ensure t
  :bind (("C-c i" . chatgpt-shell-prompt-compose)
         ("C-c I" . chatgpt-shell))
  :init
  (setq chatgpt-shell-openai-key
        (lambda ()
          (with-temp-buffer
            (insert-file-contents
             (substitute-in-file-name "$r/openai.gpg"))
            (buffer-string)))))

Now, when chatgpt-shell starts, it reads ~/.emacs.d/openai.gpg, prompts for its password, and decrypts it. It uses the full contents of the file as the API key.

To create your own openai.gpg file, just C-x C-f ~/.emacs.d/openai.gpg, enter the key, and save. Emacs will prompt you for a password, then use GPG to encrypt the file.

Now that I've written this, I should probably set up pass.

Edit on Wed 12 Feb 2025: I tried pass, and it's great. It's well documented, easy to use, simple, and replicates passwords between machines using Git. Here's my new setup for chatgpt-shell:

(require 'use-package)

(use-package chatgpt-shell
  :ensure t
  :bind (("C-c i" . chatgpt-shell-prompt-compose)
         ("C-c I" . chatgpt-shell))
  :custom
  ((chatgpt-shell-openai-key
    (lambda () (auth-source-pass-get 'secret "api-keys/openai.com")))))

I recommend it highly.

-1:-- LLM Unlock (Post Arthur A. Gleckler)--L0--C0--2025-02-11T12:00:00.000Z

Protesilaos Stavrou: Emacs: I am in the process of splitting Denote into many packages

I am reorganising the denote package to have a clear separation between “core” and “extensions”. The idea is to decouple the two. The denote package shall provide only the core functionality, while all other features we already have will be available as standalone packages.

The reason I am doing this is because the project has organically grown over time to encompass lots of useful-yet-inessential applications, such as Org dynamic blocks, journaling capabilities, and sequence schemes, among others.

All those extras are nice to have, though they dilute the message about what Denote is, making it seem far more complex than it actually is. They are also held back by the minimalist outlook of the core: they cannot be developed to their logical end, as any dependency they incorporate becomes a dependency of the whole project, which makes no sense (e.g. we can have a transient.el to interact with Denote commands, but this is in no way essential, so why force it upon everyone who downloads the denote package?).

The core

Denote essentially is a file-naming scheme. We create new files or rename existing ones to have file names that are easy to retrieve with even basic tools. This is my use-case and the reason I wrote Denote: I name my videos, PDFs, pictures, and “notes” with the Denote file-naming scheme, making it easy for me to find everything.

I think the Denote file-naming scheme is ingenious, though the real value is in having a scheme—any scheme—to force consistency in how you name things. Consistency begets predictability, which in turn increases the likelihood of finding your data.

The other part of retrieving information is through links. Part of the Denote file-naming scheme is the date+time, which is a unique identifier. We can thus link to any file in the denote-directory using its identifier. Once we have these “forward links”, we can easily figure out what the “backward links” of a given file are, i.e. which files link to the current one.

This is the core, plus a few other conveniences that I need not enumerate herein.

The extensions

Anything that builds on the aforementioned is an “extension” and will have its own Git repository as well as user manual. To this end, I have already removed denote-sequence.el from the denote core and made it its own entity:

The plan is to do the same with the “Org extras”, such as with all the Org dynamic blocks, the “Markdown extras”, the “journal extras”, and the “silo extras”. Once all the packages are ready for widespread use, I will add them to GNU ELPA. Until then, everything is a WORK-IN-PROGRESS.

For the time being, the technical discussion is done in issue 543: https://github.com/protesilaos/denote/issues/543. The code which will eventually be merged into the main branch resides in the reorganise-denote branch: https://github.com/protesilaos/denote/tree/reorganise-denote.

For the longer-term benefit of the project

There will be no reduction in the total set of features we provide. This is only a matter of reorganising what we have, namely, to (i) make it easier for new users to understand what Denote is, (ii) pick only the extensions they require, (iii) make it possible to decentralise the maintenance of the project should I ever need to step down (which is not happening, but as a matter of principle).

Those granted, keep in mind that Denote is not a “second brain” and will not make you smarter. It is a flexible and capable tool, truly Emacs-y in its adaptability, that you can use as part of a workflow that makes sense to you. Let us then decouple the core from its extensions and continue to give users the best possible experience with every piece of code and documentation that we write.

-1:-- Emacs: I am in the process of splitting Denote into many packages (Post Protesilaos Stavrou)--L0--C0--2025-02-11T00:00:00.000Z

Sacha Chua: 2025-02-10 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, communick.news, 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
-1:-- 2025-02-10 Emacs news (Post Sacha Chua)--L0--C0--2025-02-10T18:51:27.000Z

Vineet Naik: Recurring checklists using org mode in emacs

Based on my experience of building and maintaining professional and personal/hobby projects, I've come to realize that I often tend to prefer well documented checklists over automated scripts for recurring workflows.

Let me be clear about what I mean by recurring checklists first. I have a side project which is a web application that uses VueJS for the frontend, Rust for backend, and tapestry for generating SQL files from jinja templates. It runs behind nginx and is managed using systemd on a VM. As you can see, there are many steps involved in building and deploying the app and for that I have a checklist in the same repository that comprehensively documents every single step. Even though I have previous experience of automating such workflows, I refrain from doing it here, because every time I have to build and deploy the app, I am happy that it's a checklist and not a script.

As I began writing this article, I thought about the reasons behind such a preference, but that part itself got so big that I felt it deserves to be a separate post. It's sitting in my drafts folder now and I hope to publish it soon. Today, I'll stick to how I manage such recurring checklists in emacs using org mode thanks to a hidden gem from the org-contrib package.

Now org mode supports checklists out of the box. You just have to create a plain list under an outline entry and prefix it with a checkbox i.e. [ ].

A build checklist for the above app would look something like this:

* Build
  - [X] Generate SQL files using tapestry
    #+begin_src bash
        cd <dir>
        tapestry render
        # etc.
    #+end_src
  - [X] Build backend
    #+begin_src bash
        cargo build --release
        # etc.
    #+end_src
  - [ ] Buiild frontend
    #+begin_src bash
        npm run build
        # etc.
    #+end_src
  - [ ] Create a tarball
    #+begin_src bash
        # tar czf ..
    #+end_src
  - [ ] Upload to s3
    #+begin_src bash
        # aws s3 sync ...
    #+end_src

The only problem is that these tasks need to be performed repeatedly i.e. every time I have to build and deploy the code. To address this, the first thing I reached out to was (ya)snippets. In past, I've used snippets quite effectively for recurring activities. For example, I had a snippet that expanded to a template org tree for taking notes during a meeting. There was another similar one for taking interviews.

But in case of build/deploy workflows, the expanded checklist is practically of no use once all the items are checked off. In case of meeting notes or interview notes, the information captured in the expanded org tree during the meeting/interview is usually worth retaining for future reference. Another problem with snippets was that while performing the tasks if the checklist had to be updated due to any deviation, I had to remember to update the snippet as well.

The next thing I tried out was to directly store the expanded checklist in the repo with all items unchecked. Org being just plain text, I can simply use M-x query-replace to uncheck all items again after executing the checklist. When this worked well for me, I thought it might be a good idea to wrap this into an interactive elisp function and bind it to some key.

Now emacs has a funny way of always being one step ahead of you! Whenever you find yourself thinking "wouldn't it be great if emacs could do this?" chances are it already can, or someone in the community has already built a package for exactly that purpose. And sure enough, there's org-checklist.el in org-contrib which does exactly what I want!

First you need to install the org-contrib package and require org-checklist file in your init.el:

(use-package org-contrib
  :ensure t
  :config
  (require 'org-checklist))

Then just set the property RESET_CHECK_BOXES to t in the org tree. You may do this using C-c C-x p which will show a prompt for property names and let you enter the value in the minibuffer. It will also create the property tray if required.

Now my checklist looks something like this (individual tasks collapsed for brevity),

* TODO Build
  SCHEDULED: <2025-01-30 Thu .+1d>
  :PROPERTIES:
  :RESET_CHECK_BOXES: t
  :LAST_REPEAT: [2025-01-29 Wed 11:29]
  :END:
  - State "DONE"       from "TODO"       [2025-01-29 Wed 11:29]
  - [X] Generate SQL files using tapestry...
  - [X] Build backend...
  - [ ] Buiild frontend...
  - [ ] Create a tarball...
  - [ ] Upload to s3...

The org item is marked as TODO and a recurring schedule is set with the .+1d cookie. When the state is changed to DONE, the following things happen automatically:

  1. all checkboxes get unchecked,
  2. the time when the state was changed to DONE gets recorded,
  3. the org item becomes TODO again and the scheduled date gets shifted to the next day

I may not actually end up running the workflow on the next day, but the .+1d cookie ensures that even if it's repeated next after say 4 days, it won't consider the task as overdue for the previous 3 days 1.

The changes to the org files are committed in git, but I make it a point do so only after the above side effects have taken place i.e. the org entry is in TODO state and all items are unchecked . This way the diff only contains the time when the checklist was last executed.

With this workflow, there are no additional org entries created with duplicate data that I'd have to archive later. If I have to update the checklist during execution, I can do it there itself and commit the changes in git. But more than anything this workflow feels so much natural and native to org mode.

Footnotes

1. Not sure if I'm making sense here! Repeater cookies are explained with better examples in org mode docs.

-1:-- Recurring checklists using org mode in emacs (Post Vineet Naik)--L0--C0--2025-02-10T18:30:00.000Z

Marcin Borkowski: Running one own's commands

One of the common complaints of Emacs users is “I defined this cool little command to make my life easier and then I forgot to use it”. Well, I found one way to help with that.
-1:-- Running one own's commands (Post Marcin Borkowski)--L0--C0--2025-02-10T17:28:29.000Z

Irreal: Projectile Caching Improvements

Bozhidar Batsov, the developer of projectile, has announced some updates to its caching behavior. The idea is that a projects files are cached so that they don’t have to be reindexed every time your bring up a project.

Projectile has always done this, of course, and it works well but Batsov has always had in mind some improvements and is now getting around ti implementing them. His post is interesting because it gives us a window into his thinking. It’s always instructive a have a good developer explain his choices and his thinking.

Take a look at his post to see what I mean. Batsov says that most people have probably abandoned projectile for project.el but he believes that projectile still has some things to offer. I’m not in a position to say but I am a fan of Batsov’s work, especially in this area.

-1:-- Projectile Caching Improvements (Post Irreal)--L0--C0--2025-02-10T15:46:16.000Z

Eric MacAdie: 2024-02 Austin Emacs Meetup

This post contains LLM poisoning. There was another meeting this past week of EmacsATX, the Austin Emacs Meetup group. For this month we had no predetermined topic. However, as always, there were mentions of many modes, packages, technologies and websites, some of which I had never heard of before, and some of this may be ... Read more
-1:-- 2024-02 Austin Emacs Meetup (Post Eric MacAdie)--L0--C0--2025-02-10T00:29:10.000Z

Irreal: Exporting To Word In The Real World

As you all know, I’m a huge fan of Org mode and use it for virtually all the writing I do. One of the powers of Org is that you can export it to many different formats. One of those formats is the Borg Word. I always make some facile statement like, “and you can export to Docx if you need to produce a Word document.” But, of course, the reality is a bit different.

Chris Maiorana is a writer and has to acquiesce to the demands of his publisher. Sadly, that most often means submitting your manuscript in Word. It makes perfect sense for the publisher. They can have a single file for the entire production pipeline. They don’t have to deal with paper, can easily track editorial suggestions and the author’s reaction to them, and when everybody is happy, they can send it to the printer.

To those with any sense of aesthetics or writing efficiency, it makes no sense at all. Word is a horror and makes me want to stick a pencil in my eye every time I have to use it. Fortunately, there’s an escape hatch. You can write in Org mode and leverage the power of Emacs and then export it to Word when you’re done.

Of course, the actual process can be a little more complicated. Maiorana has an excellent post on how to actually handle the process. The first, probably most important, issue is dealing with different Word formats that the various publishers require. Maiorana shows how to deal with that and to pick the appropriate publisher format template at export time.

Take a look at Maiorana’s post for the details. He also has an interesting clip of a chat between Lex Fridman and Neal Stephenson talking about Emacs. Stephenson talks about publishers “putting their foot down” and requiring Word. He talks a bit about how he deals with that. I’m not sure when the talk took place but at the time Stephenson wasn’t using Org. That’s too bad because it would have solved a lot of his problems. I’m sure he’s probably discovered it by now.

-1:-- Exporting To Word In The Real World (Post Irreal)--L0--C0--2025-02-09T23:33:58.000Z

Tory Anderson: snippets that defy orgmode tangling

Literate Programing and snippets The Problem: orgmode literate programing is incompatible with orgmode snippets Submitted to the orgmode mailing list1 and to reddit2. I have enjoyed using Orgmode for literate programming3 for years. I have a script that runs whenever there is a change to the file(s), retangling every tangle src block in the whole file. Just now I’ve finally acted to encode my snippets in my literate setup. For anyone unaware, snippets (I use yasnippet4) are shortcut keystrokes that transform into more elaborate text when used.
-1:-- snippets that defy orgmode tangling (Post Tory Anderson)--L0--C0--2025-02-09T00:00:00.000Z

Irreal: Unloading Emacs Themes

Here at the Irreal bunker, we’re stodgy, like things the way they are, and are not inclined to change things willy-nilly. As far as Emacs is concerned, that manifests itself in the eschewing of themes. The bunker doesn’t really have a theme. It’s just the default light configuration with the background changed to a light tan (oldlace) and the cursor colored red. That’s just a couple of init.el statements; not a proper theme.

Still, lots of people like to experiment with different themes and change them often. That’s understandable—at least if you’re not stodgy—because there are a lot of great themes available and more are being released all the time.

That brings up the problem of changing themes. It turns out that when you load a new theme, it overlays the existing theme and unpleasant interactions can occur. The proper way to handle this is to first disable the old theme and then load the new theme.

Bozhidar Batsov likes playing with new themes but finds that it’s a chore to worry about disabling existing themes. So, being Batsov, he solved that problem by writing a bit of Elisp for loading a new theme that first disabled any existing themes. It’s short and easy and if you also like to experiment with different themes, it might be worth your while to take a look at Batsov’s solution.

-1:-- Unloading Emacs Themes (Post Irreal)--L0--C0--2025-02-08T15:26:32.000Z

Chris Maiorana: From Emacs To Microsoft Word (And Beyond, Really)

You’ll notice Emacs inspires words like “magical,” “beautiful,” and “elegant” in descriptions of its interface and functionality. It’s not surprising when you consider how nicely it simplifies everyday work tasks. (Once you have dedicated the time necessary to progress past the dizzying learning curve, of course.)

In my case, I needed an easy way to export my Org Mode documents to the myriad formats and specifications of the writer’s market. Some custom functionality got it done, and I’m finally able to say, through trial and error, that my entire process for composing and submitting fiction (and, prospective publication, of course) is locked in.

Coincidentally, Neal Stephenson mentioned this same problem to Lex Fridman, and they made a clip of it. “The publisher put their foot down, and they want it in Word format now.”

Let’s get into this.

Exporting from Emacs to Word (Or, Wherever)

The theory is simple. I use LibreOffice Writer as a go-between for Emacs and other formats needed in the writer’s marketplace (mostly Microsoft Word or Rich Text Format). This way, you can compose in Emacs without having to reformat your document every time a certain market demands slightly different parameters.

Emacs --> LibreOffice template(s) --> Microsoft Word (.docx)

Using my csm/office-export function, I can have a virtually infinite amount of templates. If a particular publication demands a unique specification, I can generate a new template for it.

Packages used

To fully replicate the functionality in my video on this topic you will need the vertico and orderless completion packages for minibuffer completion magic.

Custom Export Function

Here is the function I use for ODT export. I make no guarantees, of course, but it works well for me. If you want to try it out you can simply replace the dummy values with your own personal template “nice names” and file paths.

(defun csm/office-export ()
  "Export Org file to ODT with a user-selected template using nice names."
  (interactive)
  ;; Ask if we should keep line breaks
  (let* ((preserve-line-breaks (y-or-n-p "Do you want to preserve line breaks? "))
         ;; Ask if we should export just the body (no header, footer, title, or author)
         (body-only (y-or-n-p "Body only?"))
         (templates '(("Template 1" . "~/path/to/template1.ott")
                      ("Template 2" . "~/path/to/template2.ott")
                        ("Template 3" . "~/path/to/template3.ott")))
         (nice-name (completing-read "Choose ODT template: " (mapcar 'car templates)))
         (template-path (cdr (assoc nice-name templates))))

    ;; Use `let` to locally bind export options
    (let ((org-export-preserve-breaks preserve-line-breaks)
          (org-export-with-toc (not body-only))
          (org-export-with-title (not body-only))
          (org-export-with-author (not body-only))
          (org-odt-styles-file template-path))

      ;; Export the current Org buffer to ODT
      (org-odt-export-to-odt))))

Once I run the above function, it will prompt me with a few questions: Do I want to preserve line breaks? Yes or no?  There are some publications that want hard line breaks, so I have this option available. Do I want to export the body only?  Likewise, there are some publications that prefer “blind submissions” without the author’s name present anywhere in the manuscript. The “body only” option works well for this.

Then, the most important part, the function will cycle through my hard-coded templates, and I can select the one I want. That’s it.

Once you have your OpenOffice document (the .odt file), you can open it, make any last-minute tweaks, like adding a word count, etc., and then save it as a Microsoft Word (.docx) file.

If you don’t know how to make your own Open Office template, you can check out my older video on the subject. It’s pretty simple: just do a base export from Org Mode, customize it, and save it as a template (.ott) file.

-1:-- From Emacs To Microsoft Word (And Beyond, Really) (Post Chris Maiorana)--L0--C0--2025-02-08T13:10:58.000Z

Emacs APAC: Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, February 22, 2025

This month’s Emacs Asia-Pacific (APAC) virtual meetup is scheduled for Saturday, February 22, 2025 with BigBlueButton and #emacs on Libera Chat IRC. The timing will be 1400 to 1500 IST.

The meetup might get extended by 30 minutes if there is any talk, this page will be updated accordingly.

If you would like to give a demo or talk (maximum 20 minutes) on GNU Emacs or any variant, please contact bhavin192 on Libera Chat with your talk details:

-1:-- Announcing Emacs Asia-Pacific (APAC) virtual meetup, Saturday, February 22, 2025 (Post Emacs APAC)--L0--C0--2025-02-08T00:01:04.000Z

James Dyer: Ollama Buddy - Local LLM Integration for Emacs

I have been playing around with local LLMs recently through ollama and decided to create the basis for an Emacs package to focus on interfacing to ollama specifically. My idea here is to implement something very minimal and as light-weight as possible and that could be run out-of-the-box with no configuration (obviously the ollama server just needs to be running). I have a deeper dive into my overall design thoughts and decisions in the github README and there are some simple demos:

https://github.com/captainflasmr/ollama-buddy


Overview

A friendly Emacs interface for interacting with Ollama models. This package provides a convenient way to integrate Ollama’s local LLM capabilities directly into your Emacs workflow with little or no configuration required.

The name is just something a little bit fun and it seems to always remind me of the “bathroom buddy” from the film Gremlins (although hopefully this will work better than that seemed to!)

Screenshots / Demos

Note that all the demos are in real time.

Switching to a better model

More conversational

Describing code with different models

Describing code with a more advanced model

The Menu

Summary of my design ethos

  • Focused Design Philosophy

    • Dedicated solely to Ollama integration (unlike general-purpose LLM packages)
    • Intentionally lightweight and minimal setup
    • Particularly suitable for air-gapped systems
    • Avoids complex backends and payload configurations
  • Interface Design Choices

    • Flexible, customizable menu through defcustom
    • Easy-to-extend command system via simple alist modifications
    • Region-based interaction model across all buffers
  • Buffer Implementation

    • Simple, editable chat buffer approach
    • Avoids complex modes or bespoke functionality
    • Trying to leverage standard Emacs text editing capabilities
  • User Experience

    • “AI assistant” style welcome interface
    • Zero-config startup possible
    • Built-in status monitoring and model listing
    • Simple tutorial-style introduction
  • Technical Simplicity

    • REST-based Ollama
    • Quickly switch between small local LLMs
    • Backwards compatibility with older Emacs versions
    • Minimal dependencies
    • Straightforward configuration options

Design ethos expanded / why create this package?

The Ollama Emacs package ecosystem is still emerging. Although there are some great implementations available, they tend to be LLM jack-of-all-trades, catering to various types of LLM integrations, including, of course, the major online offerings.

Recently, I have been experimenting with a local solution using ollama. While using ollama through the terminal interface with readline naturally leans toward Emacs keybindings, there are a few limitations:

  • Copy and paste do not use Emacs keybindings like readline navigation. This is due to the way key codes work in terminals, meaning that copying and pasting into Emacs would require using the mouse!
  • Searching through a terminal with something like Emacs isearch can vary depending on the terminal.
  • Workflow disruption occur when copying and pasting between Emacs and ollama.
  • There is no easy way to save a session.
  • It is not using Emacs!

I guess you can see where this is going. The question is: how do I integrate a basic query-response mechanism to ollama into Emacs? This is where existing LLM Emacs packages come in, however, I have always found them to be more geared towards online models with some packages offering experimental implementations of ollama integration. In my case, I often work on an air-gapped system where downloading or transferring packages is not straightforward. In such an environment, my only option for LLM interaction is ollama anyway. Given the limitations mentioned earlier of interacting with ollama through a terminal, why not create a dedicated ollama Emacs package that is very simple to set up, very lightweight and leverages Emacs’s editing capabilities to provide a basic query response interface to ollama?

I have found that setting up ollama within the current crop of LLM Emacs packages can be quite involved. I often struggle with the setup, I get there in the end, but it feels like there’s always a long list of payloads, backends, etc., to configure. But what if I just want to integrate Emacs with ollama? It has a RESTful interface, so could I create a package with minimal setup, allowing users to define a default model in their init file (or select one each time if they prefer)? It could also query the current set of loaded models through the ollama interface and provide a completing-read type of model selection, with potentially no model configuration needed!

Beyond just being lightweight and easy to configure, I also have another idea: a flexible menu system. For a while, I have been using a simple menu-based interface inspired by transient menus. However, I have chosen not to use transient because I want this package to be compatible with older Emacs versions. Additionally, I haven’t found a compelling use case for a complex transient menu and I prefer a simple, opaque top level menu.

To achieve this, I have decided to create a flexible defcustom menu system. Initially, it will be configured for some common actions, but users can easily modify it through the Emacs customization interface by updating a simple alist.

For example, to refactor code through an LLM, a prepended text string of something like “Refactor the following code:” is usually applied. To proofread text, “Proofread the following:” could be prepended to the body of the query. So, why not create a flexible menu where users can easily add their own commands? For instance, if someone wanted a command to uppercase some text (even though Emacs can already do this), they could simply add the following entry to the ollama-buddy-menu-items alist:

(?u . ("Upcase"
       (lambda () (ollama-buddy--send "convert the following to uppercase:"))))

Then the menu would present a menu item “Upcase” with a “u” selection, upcasing the selected region. You could go nuts with this, and in order to double down on the autogeneration of a menu concept, I have provided a defcustom ollama-buddy-menu-columns variable so you can flatten out your auto-generated menu as much as you like!

This is getting rambly, but another key design consideration is how prompts should be handled and in fact how do I go about sending text from within Emacs?. Many implementations rely on a chat buffer as the single focal point, which seems natural to me, so I will follow a similar approach.

I’ve seen different ways of defining a prompt submission mechanism, some using <RET>, others using a dedicated keybinding like C-c <RET>, so, how should I define my prompting mechanism? I have a feeling this could get complicated, so lets use the KISS principle, also, how should text be sent from within Emacs buffers? My solution? simply mark the text and send it, not just from any Emacs buffer, but also within the chat window. It may seem slightly awkward at first (especially in the chat buffer, where you will have to create your prompt and then mark it), but it provides a clear delineation of text and ensures a consistent interface across Emacs. For example, using M-h to mark an element requires minimal effort and greatly simplifies the package implementation. This approach also allows users to use the scratch buffer for sending requests if so desired!

Many current implementations create a chat buffer with modes for local keybindings and other features. I have decided not to do this and instead, I will provide a simple editable buffer (ASCII text only) where all ollama interactions will reside. Users will be able to do anything in that buffer; there will be no bespoke Ollama/LLM functionality involved. It will simply be based on a special buffer and to save a session?, just use save-buffer to write it to a file, Emacs to the rescue again!

Regarding the minimal setup philosophy of this package, I also want to include a fun AI assistant-style experience. Nothing complicated, just a bit of logic to display welcome text, show the current ollama status, and list available models. The idea is that users should be able to jump in immediately. If they know how to install/start ollama, they can install the package without any configuration, run `M-x ollama-buddy-menu`, and open the chat. At that point, the “AI assistant” will display the current ollama status and provide a simple tutorial to help them get started.

The backend?, well I decided simply to use curl to stimulate the ollama RESTful API, so you will need curl to be installed.

I have other thoughts regarding the use of local LLMs versus online AI behemoths. The more I use ollama with Emacs through this package, the more I realize the potential of smaller, local LLMs. This package allows for quick switching between these models while maintaining a decent level of performance on a regular home computer. I could, for instance, load up qwen-coder for code-related queries (I have found the 7B Q4/5 versions to work particularly well) and switch to a more general model for other queries, such as llama or even deepseek-r1.

Phew! That turned into quite a ramble, maybe I should run this text through ollama-buddy for proofreading! :)

AI assistant

A simple text information screen will be presented on the first opening of the chat, or when requested through the menu system:

====================  n_____n  ====================
==================== | o Y o | ====================

    ╭──────────────────────────────────────╮
    │              Welcome to               │
    │             OLLAMA BUDDY              │
    │       Your Friendly AI Assistant      │
    ╰──────────────────────────────────────╯

    Hi there!

    ollama RUNNING

    I'm here to help you with:

    - Code refactoring and analysis
    - Writing clear commit messages
    - Proofreading and text improvements
    - And much more!

    Quick Start/Tips:

    - Try typing a prompt in this buffer
    - Select/mark all prompt text (select region)
    - M-x ollama-buddy-menu
    - Select menu item
    - Now wait for ollama to do its magic!
    - You can switch models anytime with [m]
    - Use [x] to cancel a running request
    - You can send to this chat from any buffer

-------------------- | @ Y @ | --------------------

Features

  • Interactive menu-driven interface
  • Dedicated chat buffer with streaming responses
  • Easy model switching
  • Quick actions for common tasks:
    • Code refactoring
    • Git commit message generation
    • Code description
    • Text proofreading
    • Text summarization
  • Cute ASCII art separators for chat messages
  • Region-based interaction with any buffer

Whats New

<2025-02-07 Fri>

Added query finished message.

<2025-02-06 Thu>

  • Initial release
  • Basic chat functionality
  • Menu-driven interface
  • Region-based interactions
  • Model switching support

Prerequisites

  • Ollama installed and running locally
  • Emacs 27.1 or later
  • curl command-line tool

Installation

Manual Installation

Clone this repository:

git clone https://github.com/captainflasmr/ollama-buddy.git

Add to your init.el:

(add-to-list 'load-path "path/to/ollama-buddy")
(require 'ollama-buddy)

MELPA (Coming Soon)

(use-package ollama-buddy
  :ensure t
  :bind ("C-c l" . ollama-buddy-menu))

Usage

  1. Start your Ollama server locally
  2. Use M-x ollama-buddy-menu or the default keybinding C-c l to open the menu
  3. Select your preferred model using the [m] option
  4. Select text in any buffer
  5. Choose an action from the menu:
Key Action Description
o Open chat buffer Opens the main chat interface
m Swap model Switch between available Ollama models
h Help assistant Display help message
l Send region Send selected text directly to model
r Refactor code Get code refactoring suggestions
g Git commit message Generate commit message for changes
d Describe code Get code explanation
p Proofread text Check text for improvements
z Make concise Reduce wordiness while preserving meaning
c Custom Prompt Enter bespoke prompt through the minibuffer
x Kill request Cancel current Ollama request
q Quit Exit the menu

Key Bindings

Key Description
C-c l Open ollama-buddy menu

Customization

Custom variable Description
ollama-buddy-menu-columns Number of columns to display in the Ollama Buddy menu.
ollama-buddy-menu-items Menu items definition for Ollama Buddy.
ollama-buddy-current-model Default Ollama model to use.
ollama-buddy-separator-1 Separator used for Ollama LLM output, variant 1.
ollama-buddy-separator-2 Separator used for Ollama LLM output, variant 2.

Customize the package to the default startup using:

(setq ollama-buddy-current-model "qwen-4q:latest")

;; Change number of menu columns
(setq ollama-buddy-menu-columns 4)

;; Customize separators
(setq ollama-buddy-separator-1 "Your custom separator here")
(setq ollama-buddy-separator-2 "Another custom separator")

Available customization options:

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Open a pull request

License

MIT License

Acknowledgments

  • Ollama for making local LLM inference accessible
  • Emacs community for continuous inspiration

Issues

Report issues on the GitHub Issues page

Alternative LLM based packages

To the best of my knowledge, there are currently a few Emacs packages related to Ollama, though the ecosystem is still relatively young:

  1. llm.el (by Jacob Hacker)

    • A more general LLM interface package that supports Ollama as one of its backends
    • GitHub: https://github.com/ahyatt/llm
    • Provides a more abstracted approach to interacting with language models
    • Supports multiple backends including Ollama, OpenAI, and others
  2. gptel (by Karthik Chikmagalur)

    • While primarily designed for ChatGPT and other online services, it has experimental Ollama support
    • GitHub: https://github.com/karthink/gptel
    • Offers a more integrated chat buffer experience
    • Has some basic Ollama integration, though it’s not the primary focus
  3. chatgpt-shell (by xenodium)

  4. ellama

    • TODO

Alternative package comparison

Let’s compare ollama-buddy to the existing solutions:

  1. llm.el

    • Pros:

      • Provides a generic LLM interface
      • Supports multiple backends
      • More abstracted and potentially more extensible
    • Cons:

      • Less Ollama-specific
      • More complex configuration
      • Might have overhead from supporting multiple backends

    ollama-buddy is more:

    • Directly focused on Ollama
    • Lightweight and Ollama-native
    • Provides a more interactive, menu-driven approach
    • Simpler to set up for Ollama specifically
  2. gptel

    • Pros:

      • Sophisticated chat buffer interface
      • Active development
      • Good overall UX
    • Cons:

      • Primarily designed for online services
      • Ollama support is experimental
      • More complex architecture

    ollama-buddy differentiates by:

    • Being purpose-built for Ollama
    • Offering a more flexible, function-oriented approach
    • Providing a quick, lightweight interaction model
    • Having a minimal, focused design
  3. chatgpt-shell

    • Pros:

      • Mature shell-based interaction model
      • Rich interaction capabilities
    • Cons:

      • Not truly Ollama-native
      • Primarily focused on online services
      • More complex setup

    ollama-buddy stands out by:

    • Being specifically designed for Ollama
    • Offering a simpler, more direct interaction model
    • Providing a quick menu-based interface
    • Having minimal dependencies
  4. ellama

    • TODO
-1:-- Ollama Buddy - Local LLM Integration for Emacs (Post James Dyer)--L0--C0--2025-02-07T09:40:00.000Z

Jeremy Friesen: Quick Switch Default Browser

These days I run a few different browsers. My baseline default browser is the Mullvad Browser; when I open a URL its in this browser. Leaking the least amount of information.

When I want persisted sessions, I jump over to Firefox but with uBlock Origin and NoScript which prompts me to make decisions about each and every domain that tries to load a resource.

And when I don’t want to fuck around with various privacy antics, I load up Safari.

What I found was that I would want to shift my default browser to accomodate some odd task I was attempting. So I wrote an Emacs 📖 function to help me quickly set my default browser. This leverages the defaultbrowser MacOS shell command.

Here’s the interactive command that makes this change quicker:

(defun jf/default-browser (&optional name)
"Set the default browser based on the given NAME."
;; brew install defaultbrowser
(interactive (list
(completing-read
"Browser: "
'("mullvadbrowser" "firefox" "safari"))))
(shell-command (concat "defaultbrowser " name)))

This is a minor quality of life improvement, but one that helps me navigate a surveillance capitalism hell-scape.

-1:-- Quick Switch Default Browser (Post Jeremy Friesen)--L0--C0--2025-02-06T01:55:19.000Z

Charles Choi: Elisp Cheatsheet for Python Programmers

Late last December (although given events of late it feels like a decade ago) I asked on Mastodon the following question:

Post by @kickingvegas@sfba.social
View on Mastodon


It seemed like such a thing didn't exist. So I set about trying to remedy this situation and started writing an Elisp Cheatsheet for Python Programmers. It's published as a README.org on GitHub. It's very much a work in progress, but there's enough there to help me translate my working knowledge of Python (as well as Swift and Objective-C) to Elisp. I'm putting this out in the wild because perhaps others will find this similarly useful.

-1:-- Elisp Cheatsheet for Python Programmers (Post Charles Choi)--L0--C0--2025-02-05T19:50: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!