Marcin Borkowski: Org links’ targets
-1:-- Org links’ targets (Post Marcin Borkowski)--L0--C0--2026-02-21T17:07:05.000Z
-1:-- Org links’ targets (Post Marcin Borkowski)--L0--C0--2026-02-21T17:07:05.000Z
The fates are still punishing me for leaving home for travel. Today I had two errands to run:
The DMV is, of course, a red flag but it turned out taking 3 hours. Three hours at the DMV is no one’s idea of a good time. After I staggered out of the DMV I went to my provider to drop off the TV set top box. That should take about 5 minutes, right? Silly you and me. That took an hour and a half.
In any event, I’m exhausted and ready for bed so today’s post is going to be ultrashort. The other day I wrote about Prot’s post on using --init-directory as an aid in debugging. Serendipitously, I ran across this post about ready-player freezing. The developer, Álvaro Ramírez, asks the user to provide information on his configuration and Emacs version.
This is a perfect example of where Prot’s advice would be useful. The user could easily build and install a temporary init.el to eliminate everything but what’s needed to produce the problem. Doing so might even allow the user to discover the problem on their own.
-1:-- A Case In Point (Post Irreal)--L0--C0--2026-02-21T17:02:04.000Z
It’s been a while since Flycheck 35, but Flycheck 36 is finally here! This is a pretty big release with a lot of new features, bug fixes, and some much-needed cleanup of legacy checkers.
In fact, I’d say it’s the biggest and most important Flycheck release since I became the project’s primary maintainer a couple of years ago. For a while I had mostly gone with the flow (adding/improving linters and fixing bugs), but by now I feel more confident to make bigger and bolder changes.
Anyways, you’re probably interested to learn more about Flycheck 36, so let me walk you through the highlights.
We’ve added a couple of new checkers:
javascript-oxlint – a checker using oxlint, the
blazing-fast JavaScript/TypeScript linter written in Rust. If you haven’t
tried oxlint yet, you really should – it’s impressively fast.org-lint – an Org mode checker using Emacs’ built-in
org-lint. It detects issues
like invalid links, dead links, and duplicate IDs. This one went through a
rewrite mid-cycle to run in the current Emacs process instead of a --batch
subprocess, which eliminates false warnings for source block languages
provided by external packages.We’ve mitigated
CVE-2024-53920 in the
emacs-lisp checker by disabling local eval directives and restricting local
variables to safe values during byte-compilation. This was an important fix –
byte-compilation involves macro expansion, which means untrusted Elisp files
could potentially execute arbitrary code during syntax checking. A follow-up fix
for Emacs 30+ using trusted-content is in the works.1
The sh-shellcheck checker got some love in this release:
flycheck-shellcheck-infer-shell option to let ShellCheck auto-detect the shell dialectflycheck-shellcheck-args for passing extra command-line argumentsflycheck-shellcheck-enabled-checks to enable optional checks via --enableA bunch of small but welcome improvements:
flycheck-command-map now works as a prefix command with keymap-set and friends – no more need for the define-key workaroundrevert-buffer, so global-auto-revert-mode users get up-to-date diagnostics without manual interventionerrors|warnings|infos)python-ruff checker got an error explainer, so you can quickly look up what a rule meansreportGeneralTypeIssues) now show up as error IDsThis release includes a massive number of bug fixes – over 25 of them. Some highlights:
LC_ALL=C for checker processesrust checker on Windows (no more /dev/null errors)flycheck-navigation-minimum-level being ignored in some casespython-ruff, tex-chktex, emacs-lisp, and awk-gawk checkersCheck the release notes for the full list.
We’ve removed a number of checkers for tools that have been dead or deprecated for years:
typescript-tslint (deprecated since 2019, use ESLint with typescript-eslint)sass, scss, sass/scss-sass-lint, scss-lint (Ruby Sass is dead, use Stylelint)eruby-erubis, eruby-ruumba (Erubis abandoned since 2011)css-csslint (abandoned since ~2017, use Stylelint)coffee-coffeelint, protobuf-prototool, nix-linterIf you’re still using any of these tools… well, it’s probably time to upgrade!
flycheck.org got a visual refresh – we’ve switched from the old Alabaster Sphinx theme to Furo, which gives the site a clean, modern look with proper dark mode support and better mobile responsiveness. We’ve also added prominent GitHub links at the top of every page, making it easier to jump to the source or file issues.
I hate the old theme, so this one is a major win in my book! I’ve also took some effort to make sure the documentation accurately reflects the current state of project, as here and there things were out-of-sync.
I know that many people wrote Flycheck off when Flymake got tight integration with Eglot (they share a maintainer, after all), and I understand why – it’s hard to compete with something that’s built into Emacs and “just works” out of the box. But Flycheck continues to advance and evolve. We have excellent Eglot support via flycheck-eglot, a massive library of built-in checkers,2 and a feature set that Flymake still can’t match in many areas.
More importantly, Flycheck’s biggest strength has always been that it’s community-driven and easy to contribute to. Adding a new checker is straightforward, PRs get reviewed quickly, and you don’t have to go through the FSF copyright assignment process. That matters, and it’s why the project keeps growing.
I’m pretty happy with this release. The combination of new features, security hardening, and cleanup of dead checkers puts Flycheck in a much healthier state. Looking ahead to Flycheck 37, I’m thinking about tree-sitter integration, more new checkers (OCaml and Swift are already in the pipeline), and potentially dropping support for Emacs 27 so we can take advantage of newer APIs. The plan is still hazy, but it’s starting to take some shape…
As always, contributions are very welcome! If there’s a lint tool you use that Flycheck doesn’t support yet, PRs are the fastest way to make it happen. As mentioned above, Flycheck’s biggest strength remains its community, and are the community.
That’s all I have for you today. Keep hacking!
See https://www.flycheck.org/en/latest/languages.html for the full list. ↩
-1:-- Flycheck 36 (Post Meta Redux)--L0--C0--2026-02-21T13:20:00.000Z
Almost 3 years after the rebirth of adoc-mode I’m happy to announce that adoc-mode 0.8 is finally out! This is a massive release that has been cooking for way too long, but I think it was worth the wait.
Let me walk you through the highlights.
This was the flagship feature I teased at the end of my 0.7 announcement, and
it’s easily the most impactful change in this release. Source code blocks now get
fontified using the appropriate language major mode – Ruby code looks like it
does in ruby-mode, Python code looks like python-mode, and so on.
The feature is enabled out-of-the-box with a sensible default – only code blocks
of 5000 characters or fewer are fontified natively, to avoid performance
issues with very large blocks. You can set adoc-fontify-code-blocks-natively
to t if you want unlimited fontification, or to nil to disable it entirely.
You can now see images directly in your buffer instead of just staring at
image::path/to/screenshot.png[]. Image previews are displayed automatically
when you open a file (controlled by adoc-display-images), and you can toggle
them on and off with adoc-toggle-images.
Right-clicking on an image link gives you a context menu to generate or remove
the preview for that specific image. Remote images are supported too – set
adoc-display-remote-images to t if you want to fetch and display images from
URLs.
A couple of welcome additions here:
adoc-follow-thing-at-point (bound to C-c C-o and M-.) lets you follow
URLs (opens in browser), include:: macros (opens the referenced file), and
cross-references (jumps to the anchor). It’s one of those features that once
you have it, you can’t imagine living without.adoc-goto-ref-label (C-c C-a) jumps to an anchor by ID, with a smart
default pulled from the xref at point.imenu index is now hierarchical – headings are nested under their parent
sections, which makes navigating large documents much more pleasant.adoc-mode now highlights Asciidoctor-specific inline macros like kbd:[],
btn:[], menu:[], pass:[], stem:[], latexmath:[], and asciimath:[].
These were previously ignored by font-lock and would just blend in with regular
text.
I’m a heavy user of Antora, and I really appreciate this one.
This release squashes a lot of long-standing bugs:
auto-fill-mode from breaking section title lines.I’ve also spent some time cleaning up the internals:
adoc-mode-image.el and adoc-mode-tempo.el), making the main file more
manageable.The codebase is in much better shape than it was 3 years ago, but there’s still some room for improvement.
I did eventually act on that idea I mentioned in my 0.7 post – I created
asciidoc-mode, a tree-sitter-based
AsciiDoc major mode for Emacs 30.1+. It’s a very different beast from adoc-mode
– focused on the essentials (highlighting, navigation, folding) and leveraging
tree-sitter for accurate and performant parsing.
If you’re on Emacs 30+ and prefer a lighter-weight editing experience,
asciidoc-mode might be a good fit. If you want the full kitchen sink –
image previews, tempo templates, native code block highlighting – adoc-mode is
still the way to go. Both packages are maintained by me and they complement each
other nicely.
adoc-mode 0.8 is available on NonGNU ELPA, MELPA Stable,
and MELPA. Upgrading is just a M-x package-install away.
I’d like to thank everyone who contributed bug reports, pull requests, and feedback over the past 3 years. Open-source is a team sport and this release wouldn’t have happened without you. You rock!
That’s all I have for you today. Keep hacking! And keep writing… in AsciiDoc, of course!
-1:-- adoc-mode 0.8 (Post Meta Redux)--L0--C0--2026-02-21T10:15:00.000Z
Most Emacs Org users would concur that Org mode is a magnificent tool for capturing and communicating thought. That said, Org mode’s vast set of features can be daunting to master. A common guidance for new users is to take it slow: incrementally learn a subset of Org’s features as you need them.
A big reason for Org mode’s steep learning curve is that it adopts Emacs’ unfortunate culture of compelling users to memorize keybindings. Learning a distinct keybinding for each Org command (remember I said vast feature set?) is onerous, so a different tack is made: reuse the same keybinding but have it possess different behavior based on context. This context is usually tied to the type of structure the point (aka cursor) is in. For example, if the point is in a source block, the binding C-c C-c would execute it, but if the point is on a checkbox item, then C-c C-c would toggle its checked state. Taking this approach lowers the effort to recall a keybinding at the cost of recalling what its contextual behavior would be. In practice, using such overloaded keybindings is…okay. But I’d argue that we could have a more usable interface, leading to the point of this post:
Announcing support for Org mode in the v2.14.0 update for Casual, now available on MELPA.
Readers of this blog will know that Casual is my project to re-imagine the primary user interface for Emacs using keyboard-driven menus. If this is new to you, I highly recommend reading this introduction to it.
Primary to the design of the Casual Org menus is to be context-sensitive, only showing a subset of Org mode commands that are relevant. This set of context-sensitive commands is opinionated, but seeks to provide utility to users both new and experienced with Org.
Shown below is a demo of Casual Org at work:
While the design of this UI has been months in the making, there is nothing like real-world use and feedback. Constructive input is appreciated, especially if you are relatively new to using Org.
A great deal of thanks goes out to the maintainers of and contributors to Org mode and to the community that uses it. If you are able, please support it. Also, if you find Casual useful, I’d appreciate a coffee as well.
—
Video music: Burna Boy - Last Last (JON REYES FINDAWAY BLEND) | Jon Reyes
-1:-- Announcing Casual Org (Post Charles Choi)--L0--C0--2026-02-19T23:00:00.000Z
The standard advice people get when they complain about some bug or difficulty with Emacs is to restart it with -q or -Q to see if the problem persists. The problem with that advice is that the difficulty may be with a package. In that case you want to load at least the offending package and its configuration. That used to involve moving or renaming your init.el so that you could install the minimal init.el that produced the problem. As of Emacs 29 that got easier with the introduction of the --init-directory parameter that tells Emacs to load it’s configuration from a different directory.
Protesilaos Stavrou (Prot) has a nice post that explains how to use this feature when you experience a problem and want to file a bug report. The main problem, of course, is what to put in your new init.el. Prot recommends using use-package with :ensure t (and whatever configuration you’re using) to load the package.
Sometimes you might have to build the package from source rather than simply loading it from one of the ELPA repositories. Prot discusses how to do this using package-vc-install to grab the source directly from its git repository. He has some sample code showing how to do this.
Finally, he has some general recommendations that you can use to make the developer’s life a bit easier. On the other hand, if you are the package developer, the --init-directory trick can save a lot of time in locating bugs. In either case, take a look at Prot’s post. There’s a lot of good information in it.
-1:-- Using –init-directory To Debug (Post Irreal)--L0--C0--2026-02-19T17:30:42.000Z
-1:-- Introducing ~elfeed-summarize~ (Post Fritz Grabo)--L0--C0--2026-02-19T00:00:00.000Z
Last week I wrote about Álvaro Ramírez’s new Winpulse package. The purpose of the package is to flash the window receiving focus when you use the other-window command. I wrote that I chose a different solution—changing the color of the mode line—that I felt was better because it provided a lasting indication of the active window.
In his latest Bending Emacs video, Ramírez expounds a bit more on why he chose the solution he did. The main reason appears to be that he sometimes turns off the mode line in some of his windows so my solution obviously wouldn’t work in that situation. Take a look at his video to see his complete argument.
In my previous post on Winpulse, I noted that you could, of course, use both his and my solution. I don’t think that would be worthwhile for me but in his video, Ramírez mentions Pulsar, a package similar to Winpulse that flashes the current line of the buffer getting focus instead of the entire window.
That seems to me a be something I might want to do since it helps locate the point in the new window. As always, Emacs lets you have things exactly the way you want them.
Ramírez and I tend to like the same sorts of things so our disagreement on this issue initially puzzled me. The answer, I think, is that when he switches windows, he just cycles through all the windows in the frame. I, on the other hand, use ace-window that lets me choose the window I want to change to directly. Again, this is a matter of choice but it helps explain why he and I chose different solutions.
The Bending Emacs 11 video is 8 minutes and 45 seconds so it such be easy to find time for it. If you’d like an enhanced way of seeing what window you’re switching to, take a look
-1:-- Bending Emacs 11: Winpulse (Post Irreal)--L0--C0--2026-02-18T17:05:52.000Z
Speaking of things that don’t matter at all , over at the Emacs reddit, reddit_enjoyer_47 wants to know how big our init.el files are. Despite my dismissal of the question as of no importance, it turns out that the answers are interesting. The answers range from about 20 lines to about 7,000 lines. For the record, mine is 2527,
Most of the folks with large init files say they have been using Emacs for a long time. That make sense because the files just naturally accrete by adding small pieces that may outlive their usefulness. More importantly, though, long term users tend to adapt Emacs to their individual needs and the usual way of doing that is by adding packages and changing default options.
More interesting to me are users with tiny configurations. It’s hard for me to fathom how you can make good use of Emacs with a configuration that small. A couple of the responders with small inits either listed them or provided a link to it. They appear to be using Emacs as a single purpose editor, usually for coding in a specific language.
Others take pride in having a small config or perhaps consider it some sort of moral necessity. One even set himself a (small) limit an requires himself to refactor his config if it exceeds that limit. That’s fine, I suppose, but it seems to me that it merely serves to limit the usefulness of Emacs.
-1:-- Let’s Play How Big Is Your Emacs Config? (Post Irreal)--L0--C0--2026-02-18T01:10:24.000Z
Much of the maintenance work I do for my packages involves correspondence with users about potential bugs. Sometimes, a user will encounter a problem that I cannot reproduce on my end. I thus try to recreate the bug in a pristine environment and ask my correspondent to do the same.
This has become easier since Emacs 29, which introduced a command-line
flag called --init-directory. It is responsible for loading the
init.el that is present in the given directory. For example:
# From a terminal or shell, run something like this:
emacs --init-directory=/tmp/test-emacs/
In other words, you can keep your regular configuration intact while launching Emacs with another set of options.
Have a directory that is unrelated to your regular Emacs
configuration. Then write the init.el inside of it.
Because I do this frequently, I prefer to use the standard Linux path
/tmp/. Its files get deleted as soon as I switch off the computer,
which is exactly what I want in this case.
As such, if there is a bug with, say, the modus-themes, I will work
with this file path /tmp/modus-themes/init.el.
But the exact location of the directory does not matter, so choose what makes sense to you.
In that init file, include only the code that is needed to reproduce the bug.
Since you want to have the package installed, it makes sense to write
a use-package declaration for it. Include the :ensure t directive
as it instructs the built-in package manager to install the package if
it is not already available.
;; Contents of the init.el...
(use-package modus-themes
:ensure t
:config
(setq modus-themes-common-palette-overrides
'((fringe unspecified)
(border-mode-line-active unspecified)
(border-mode-line-inactive unspecified)))
(setq modus-vivendi-palette-overrides
'((bg-main "#1e1f22")
(fg-main "#bcbec4")))
(load-theme 'modus-vivendi t))
If you are using an alternative to package.el like straight or
elpaca, then the aforementioned :ensure t will likely not suffice:
you need to build the package from source. To this end, Emacs has the
function package-vc-install. Some of my recent packages have sample
code that relies on this approach. For instance:
(use-package gnome-accent-theme-switcher
:demand t
:init
;; Then upgrade it with the command `package-vc-upgrade' or `package-vc-upgrade-all'.
(unless (package-installed-p 'gnome-accent-theme-switcher)
(package-vc-install "https://github.com/protesilaos/gnome-accent-theme-switcher.git"))
:bind
(("<f5>" . gnome-accent-theme-switcher-toggle-mode)
("C-<f5>" . gnome-accent-theme-switcher-change-accent))
:config
(gnome-accent-theme-switcher-mode 1))
In the above snippet package-vc-install will pull the latest commit
from the main branch, though it can even get a specific commit. Read
its documentation with M-x describe-function.
What matters is that you fetch the version which you are running in your personaly configuration.
From the command-line, run something like the following:
emacs --init-directory=/tmp/test-emacs/
This will launch a new instance of Emacs. The use-package you placed
there will do the work to install the package. After that you are
ready to reproduce the bug in this clean setup.
To help the maintainer identify the source of the trouble, keep a record of all the steps you followed. Some bugs show up when the package is loaded, but others are triggered only after a specific action is performed.
Normally, Emacs will pop up a *Backtrace* buffer when it encounters
an error. Copy its contents and send them to the maintainer, together
with the init.el you used, and the list of the steps you followed.
It sometimes happens that you install a package and it is completely broken. Although this looks bad, it may not even be a bug, but an issue with the old bytecode you had on your system from the previous version of the package.
Do M-x package-delete, select the package, restart Emacs, and then
M-x package-install to install the package anew. If everything
works, then the problem is gone and you do not need to tell the
maintainer about it.
With this knowledge, you can provide high quality bug reports for the packages you rely on. Good luck!
-1:-- Emacs: confirm package bugs with –init-directory (Post Protesilaos Stavrou)--L0--C0--2026-02-18T00:00:00.000Z
At times, even purchased music excludes album covers in track metadata. For those instances, ready-player-mode offers M-x ready-player-download-album-artwork, which does as it says on the tin. The interactive command offers a couple of fetching providers (iTunes vs Internet Archive / MusicBrainz) to grab the album cover. The thing is, I often found myself trying one or the other provider, sometimes without luck. Today, I finally decided to add a third provider (Deezer) to the list. Even then, what's the point of manually trying each provider out when I can automatically try them all and return the result from the first successful one? And so that's what I did.
In addition to offering all providers, M-x ready-player-download-album-artwork now offers "Any", to download from the first successful provider. Now, why keep the option to request from a specific provider? Well, sometimes one provider has better artwork than another. If I don't like what "Any" returns, I can always request from a specific provider.
While on the subject, I also tidied the preview experience up and now display the thumbnail in the minibuffer. In any case, best to show rather than tell.

Enjoying your unrestricted music via Emacs and ready player mode? ✨sponsor✨ the project.
-1:-- Ready Player cover download improvements (Post Alvaro Ramirez)--L0--C0--2026-02-18T00:00:00.000Z
I've used projectile ever since I created my own Emacs config. I have a vague memory choosing it because some other package only supported it. (It might have been lsp-mode, but I'm not sure.) Anyway, now that I'm trying out eglot, again, I thought I might as well see if I can switch to project.el, which is included in Emacs nowadays.
Projectile allows using a file, .projectile, in the root of a project. This
makes it possible to turn a folder into a project without having to use version
control. It's possible to configure project.el to respect more VC markers than
what's built-in. This can be used to define a non-VC marker.
(setopt project-vc-extra-root-markers '(".projectile" ".git"))
Since I've set vc-handled-backends to nil (the default made VC interfere
with magit, so I turned it off completely) I had to add ".git" to make git
repos be recognised as projects too.
The first thing to solve was that the xref stack wasn't per project. Somewhat
disappointingly there only seems to be two options for xref-history-storage
shipped with Emacs
xref-global-historyxref-window-local-historyI had the same issue with projectile, and ended up writing my own package for it. For project.el I settled on using xref-project-history.
(use-package xref-project-history
:ensure (:type git
:repo "https://codeberg.org/imarko/xref-project-history.git"
:branch "master")
:custom
(xref-history-storage #'xref-project-history))
Projectile has a function for jumping between implementation and test. Not too
surprisingly it's called projectile-toggle-between-implementation-and-test. I
found some old emails in an archive suggesting that project.el might have had
something similar in the past, but if that's the case it's been removed by now.
When searching for a package I came across this email comparing tools for
finding related files. The author mentions two that are included with Emacs
ff-find-other-filefind-sibling-fileSo, there are options, but neither of them are made to work nicely with project.el out of the box. My most complicated use case seems to be in Haskell projects where modules for implementation and test live in separate (mirrored) folder hierarchies, e.g.
src
└── Sider
└── Data
├── Command.hs
├── Pipeline.hs
└── Resp.hs
test
└── Sider
└── Data
├── CommandSpec.hs
├── PipelineSpec.hs
└── RespSpec.hs
I'm not really sure how I'd configure find-sibling-rules, which are regular
expressions, to deal with folder hierarchies like this. To be honest, I didn't
really see a way of configuring ff-find-other-file at first either. Then I
happened on a post about switching between a module and its tests in Python.
With its help I came up with the following
(defun mes/setup-hs-ff ()
(when-let* ((proj-root (project-root (project-current)))
(rel-proj-root (-some--> (buffer-file-name)
(file-name-directory it)
(f-relative proj-root it)))
(sub-tree (car (f-split (f-relative (buffer-file-name) proj-root))))
(search-dirs (--> '("src" "test")
(remove sub-tree it)
(-map (lambda (p) (f-join proj-root p)) it)
(-select #'f-directory? it)
(-mapcat (lambda (p) (f-directories p nil t)) it)
(-map (lambda (p) (f-relative p proj-root)) it)
(-map (lambda (p) (f-join rel-proj-root p)) it))))
(setq-local ff-search-directories search-dirs
ff-other-file-alist '(("Spec\\.hs$" (".hs"))
("\\.hs$" ("Spec.hs"))))))
A few things to note
ff-other-file-alist is important, the first match is
chosen.(buffer-file-name) can, and really does, return nil at times, and
file-name-directory doesn't deal with anything but strings.ff-search-directories have to be relative to the file in the
current buffer, hence the rather involved varlist in the when-let*
expression.
With this in place I get the following values for ff-search-directories
src/Sider/Data/Command.hs("../../../test/Sider" "../../../test/Sider/Data")test/Sider/Data/CommandSpec.hs("../../../src/Sider" "../../../src/Sider/Data")
And ff-find-other-file works beautifully.
My setup with project.el now covers everything I used from projectile so I'm fairly confident I'll be happy keeping it.
-1:-- Switching to project.el (Post Magnus)--L0--C0--2026-02-17T23:09:00.000Z
Over the last year or so I’ve ended up with various SVG functions that I think may be of some general utility, so I’ve separated them out into its own file and put it on Microsoft Github.
Some are pretty involved, but most are pretty straightforward. Of course, one can add an infinite number of these, and the more flexible the functions are, the more you can just end up “open-coding” them for your specific project, but I think these have some utility, so there you go.
-1:-- A little collection of SVG tricks for Emacs (Post Lars Ingebrigtsen)--L0--C0--2026-02-17T21:34:05.000Z
I am happy to announce that my command line program for binding plain text writing files is live on my GitHub, with full documentation here, and I could not be happier with how it turned out.
But, you may ask, what is it, and why does it exist?
Quoting from the docs:
Binder applies source/build separation to writing—you author in plain text files and compile to a formatted manuscript.
This upends the word processing (or “WYSIWYG” editor) model that requires the writer to edit a build file (delivery format) as a source file. So you can write with the precision of a software engineer rather than the brute force labor of a printer’s devil.
There’s nothing wrong with using word processors like Microsoft Word, but these tools were designed for print formatting first and foremost. That’s why you have so many options for font sizes, page styles, and flow parameters, but very few text navigation or file organization features. Using such antiquated tools for writing today is like composing a novel by hand-setting movable type on a letterpress printer.
Composing in plain text frees you from those constraints and opens you up to the wide world of text editors with advanced text manipulation features, file and chapter organization, portability, and version control.
For my readers already familiar with Emacs and Org Mode, separating source files from build files is quite common. We can do that by exporting Org Mode documents to whatever format we’d like.
However, I wanted a tool that was text editor agnostic and focused more specifically on fiction writing and manuscript generation. So now, it doesn’t matter if you like Emacs, Vim, VS Code, Sublime, Gedit, or whatever, you can make good use of this program.
I particular like the --stats feature that outputs not only the total word count of all files, but also paragraph, sentence count, and a Flesch reading ease score.
Example output:
binder --stats Manuscript Statistics ────────────────────────────── Words: 45,678 Paragraphs: 1,234 Sentences: 2,345 Words/Paragraph: 37.0 Sentences/Paragraph: 1.9 Flesch Reading Ease: 65.2 (Standard)
Nice.
As always, thanks for reading. And be sure to check out my eBooks.
If you have any comments or questions feel free to drop them below.
The post Writing a novel in plain text has never been easier appeared first on Chris Maiorana.
-1:-- Writing a novel in plain text has never been easier (Post Chris Maiorana)--L0--C0--2026-02-17T05:00:41.000Z
~1450 words. ~7 minutes.
The various demos relating this were seriously getting out of hand. I hope to properly demo them, and provide some background.
I will try to keep improving and updating this page regularly.
PALE stands for “Picture and Animation Library for Emacs”, it grew out of struggles with rendering in Emacs Reader. Wherein quickly changing the page image would lead to memory leaks– the reason for the delay in implementing text-features (like selection and friends). We eventually decided that ‘tiling’ that is, dividing the page into smaller images would be a good solution, ( though we ended up finding an easier to implement solution later).
Divya was so excited by PALE's video playing that he just extracted PALE into a separate repository.
Minad (Daniel Mandler) saw Divya's posts, and basically said,
wow, that is so much work, actually I had an idea to add a canvas into Emacs long ago, let me just do that: here is a patch.
Minad ported Doom to Emacs.
Divya ported SuperTuxKart to Emacs.
Divya ported PALE to Canvas (no more tiling hacks).
Daniel added shaders to org-babel.
-1:-- PALE, Canvas, and Stuff demos (Post tusharhero)--L0--C0--2026-02-17T05:00:00.000Z
I recently built a little package to flash Emacs windows as you switch through them, so I might as well showcase it in a new Bending Emacs episode, so here it goes:
Bending Emacs Episode 11: winpulse
In addition to showcasing winpulse, we showed some of the built-in window-managing commands like:
C-x 3 split-window-rightC-x 2 split-window-belowC-x 0 delete-windowC-x ^ enlarge-windowC-x } enlarge-window-horizontallyC-x { shrink-window-horizontallyC-x o other-windowIt's worth noting the last four commands are can be optimized by repeat-mode. Check out Karthink's It Bears Repeating: Emacs 28 & Repeat Mode post.
Hope you enjoyed the video!
Liked the video? Please let me know. Got feedback? Leave me some comments.
Please go like my video, share with others, and subscribe to my channel.
If there's enough interest, I'll continue making more videos!
Enjoying this content or my projects? I am an indie dev. Help make it sustainable by ✨sponsoring✨
Need a blog? I can help with that. Maybe buy my iOS apps too ;)
-1:-- Bending Emacs - Episode 11: winpulse (Post Alvaro Ramirez)--L0--C0--2026-02-17T00:00:00.000Z
Last week, I wrote about Theena Kumaragurunathan’s post on writing Science Fiction with Emacs and how Emacs was the inspiration for the brain computer interface in his latest SF novel. In a followup post, Kumaragurunathan discusses the philosophical and design choices that make Emacs such a great tool for writers like him. He says,
Good UX comes from good design. The former is the harvest that comes
about from sowing in the latter.
He describes the manifestation of that principal in Emacs as,
Emacs feels timeless to me because it made a simple, stubborn choice
early on: let the user shape the tool.
He goes on to describe this as “giving the user agency” and explains how he’s exploited that agency to integrate Emacs with other tools, such as Org-roam and Hyperbole, to build himself a writing environment tailored specifically for him.
As well as being a novelist, Kumaragurunathan is also a screenwriter so he relies on two distinct Emacs modes for his writing:
There is, he says, no other writing environment that can support both long-form writing and screenwriting.
It’s a nice article and well worth spending a few minutes on. His discussion of how Emacs meets his writing needs and the writing environment he’s evolved from it is instructive and entertaining.
-1:-- Writing SF With Emacs, Part 2 (Post Irreal)--L0--C0--2026-02-16T21:56:37.000Z
I noticed that in all terminal emulators I tried (iTerm, Ghostty, kitty), I rely on a system-global shortcut to show me a session that I use whenever I need to terminalize something right now, right there, like ffmpeg something or bulk delete with a pattern or convert magick an image. I had this for ages, and I miss it when it’s not there.
I’ve had iTerm show this in the style of a classic Quake Console – yes, from the game; a console that slides in from the top of the screen, and which in games I mostly used for cheat codes. I used this a lot in Unreal to make the intro cinematic interactive and play in that cool castle. (Ghostty has settings that made the sizing a bit trickier but workable. But eventually Kitty’s settings convinced me to try a centered window instead of one sticking to the top. Kitty also convinced me of making the console not hide automatically when it loses focus, which makes pasting into it much nicer.)
A couple of week after trying terminal emulators, I inevitably wonder why I’m spawning a window that only shows zsh when so many file operations and image manipulation and … well, basically everything is nicer in Emacs.
Wouldn’t it be possible to dedicate a GUI window just to this purpose?

So here we are. It’s possible, and now it’s a package.
It took me a few hours to over-engineer a spec-driven approach to make this possible with the help of LLM’s, Claude Code in particular. I archived the whole history of the thought-process of planning and then let Claude Code orchestrate an implementation with subagents in ~50min while I went groceries shopping with my daughter. The whole process taught me how to make named Emacs daemon (aka server) sessions and use them in end-to-end testing without interfering with my own setup. I learned a bit about how Emacs frames can be configured. And it renewed my love for Emacs and its malleability – there were so many cool alternatives to implement the same feature along the way that it sometimes was genuinely hard to pick a path!
Having a stochastic apparatus come up with fringe ideas to use and configure the package made me curious to try a couple of these myself, too. So all in all, the Claude Code driven experience was a success for me.
I even like the tagline that was generated:
Press a key. Get Emacs. Press again. It’s gone.
That’s it.
Get the quake-frame.el package from Codeberg:
https://codeberg.org/ctietze/quake-frame.el
Note: I only tested this on macOS because I don’t have a Linux with any GUI ready at the moment.
Extensive documentation in the readme will tell you how to configure things, and it comes with recipes to get you started quickly.
Unlike other visor-style packages that existed already, this one is not animating anything. You could get transparency if you want with a simple tweak.
I still stick to the center location with a slight offset. I believe there’s value in caring for small UI details like this, to nudge the window a couple of percentage points off center. The window sizing should just work and make sense and do the right thing.
The customize group is self-documenting and covers all the settings.
You can reset the frame when you dismiss it, or restore whatever was inside. You could force it to always show your favorite eshell session.
In the end, it’s just managing a GUI window for you so that you can bind a system-global hotkey to it. (I use Keyboard Maestro on Mac.)
Hire me for freelance macOS/iOS work and consulting.
Buy my apps.
Receive new posts via email.
-1:-- Introducing quake-frame.el: My Take on a Terminal Visor, But Running Emacs (Post Christian Tietze)--L0--C0--2026-02-16T21:06:59.000Z
I've switched back to lsp-mode temporarily until I've had time to fix a few
things with my eglot setup. Returning prompted me to finally address an
irritating behaviour with lsp-ui-doc.
No matter what I set lsp-ui-doc-position to it ends up covering information
that I want to see. While waiting for a fix I decided to work around it. It
seems to me that this is exactly what advice is for.
I came up with the following to make sure the frame appears on the half of the
buffer where point isn't.
(defun my-lsp-ui-doc-wrapper (&rest _)
(let* ((pos-line (- (line-number-at-pos (point))
(line-number-at-pos (window-start))))
(pos (if (<= pos-line (/ (window-body-height) 2))
'bottom
'top)))
(setopt lsp-ui-doc-position pos)))
(advice-add 'lsp-ui-doc--move-frame :before #'my-lsp-ui-doc-wrapper)
-1:-- Using advice to limit lsp-ui-doc nuisance (Post Magnus)--L0--C0--2026-02-16T19:10:00.000Z
Lots of cool stuff this week! I'm looking forward to checking out the new futur library for async programming, and the developments around embedding graphics in a canvas in Emacs look interesting too (see the Multimedia section). Also, the discussion about making beginner configuration easier could be neat once the wrinkles are ironed out. Enjoy!
Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!
You can comment on Mastodon or e-mail me at sacha@sachachua.com.
-1:-- 2026-02-16 Emacs news (Post Sacha Chua)--L0--C0--2026-02-16T18:05:53.000Z
-1:-- Toy train timetable improvements – buttons (Post Marcin Borkowski)--L0--C0--2026-02-16T15:03:37.000Z
Tool calling has landed in ollama-buddy!, it’s originally not something I really thought I would end up doing, but as ollama has provided tool enabled models and an API for this feature then I felt obliged to add it. So now LLMs through ollama can now actually do things inside Emacs rather than just talk about them, my original “do things only in the chat buffer and copy and paste” might have gone right out the window in an effort to fully support the ollama API!
What is Tool Calling?
The basic idea is simple: instead of the model only generating text, it can request to invoke functions. You ask “what files are in my project?”, and instead of guessing, the model calls list_directory, gets the real answer, and responds with actual information.
This creates a conversational loop:
All of this is transparent - you just see the final response in the chat buffer.
The new ollama-buddy-tools.el module ships with 8 built-in tools:
Safe tools (read-only, enabled by default):
Unsafe tools (require safe mode off):
Safe mode is on by default, so the model can only read - it can’t modify anything unless you explicitly allow it, I think this is quite a nice simple implementation, at the moment I generally have safe mode off but always allowing confirmation for each tool action, but of course you can configure as necessary.
Example Session
With a tool-capable model like qwen3:8b and tools enabled (C-c W):
>> PROMPT: What defuns are defined in ollama-buddy-tools.el?
The model calls search_buffer with a regex pattern, gets the list of function definitions, and gives you a nicely formatted summary. No copy-pasting needed.
Custom Tools
You can register your own tools with ollama-buddy-tools-register:
(ollama-buddy-tools-register
'my-tool
"Description of what the tool does"
'((type . "object")
(required . ["param1"])
(properties . ((param1 . ((type . "string")
(description . "Parameter description"))))))
(lambda (args)
(let ((param1 (alist-get 'param1 args)))
(format "Result: %s" param1)))
t) ; t = safe tool
The registration API takes a name, description, JSON schema for parameters, an implementation function, and a safety flag. The model sees the schema and decides when to call your tool based on the conversation.
A ⚒ symbol now appears next to tool-capable models everywhere - header line, model selector (C-c m), and model management buffer (C-c M). This follows the same pattern as the existing ⊙ vision indicator, so you can see at a glance which models support tools.
That’s it. Pull a tool-capable model (qwen3, llama3.1, mistral, etc.) or use an online tool enabled model from ollama and start chatting. Next up is probably some web searching!, as again the ollama API supports this, so you will be able to pull in the latest from the interwebs to augment your prompt definition!
-1:-- Ollama Buddy v2.0 - LLMs can now call Emacs functions! (Post James Dyer)--L0--C0--2026-02-16T08:56:00.000Z
Vim is not just a text editor, it is an editing language that allows you to interact with text through logical key combinations.
The basis of Vim’s “language” is the “modal” system.
-1:-- Vim... beyond Vim (Post D.V.F.P.)--L0--C0--2026-02-16T00:00:00.000Z
People from the University of Oxford are organising events related to free software: FLOSS @ Oxford.
On Thursday, the 12th of March 2026, at 6 PM United Kingdom time (GMT) I will give a talk titled Computing in freedom with GNU Emacs. My intention is to introduce Emacs to a wide audience. Participation is open to everyone.
I will post a reminder as we get closer to the date of the event. Looking forward to it!
-1:-- Emacs: I will talk about Emacs and free software (FLOSS @ Oxford) (Post Protesilaos Stavrou)--L0--C0--2026-02-16T00:00:00.000Z
I've been using Emacs for a while now, and if it has taught me anything, it's not to settle.
Every time I open my configuration, I discover something I can do better, a shortcut I didn't know about, a package that changes the way I work. It has taught me to develop patience, not to take the easy path, because nothing works on the first try: I read, I test, I break, I fix. And in that process, without realizing it, I'm building something that is uniquely mine. I will die without having the perfect configuration, and that's a good thing.
This has changed my perception of software itself. For me, Emacs stopped being just an editor (or an Elisp interpreter, no need to get technical) a long time ago. I experience it as a protocol between my tools and myself. A virtual machine that adds a layer of isolation that allows me to work the way I want, regardless of the operating system. I create utilities in Elisp, not in the language compatible with my platform. I'm in a development environment that is also my working environment. It's strange and wonderful at the same time.
Then there's the community. I've met more people thanks to Emacs, or Org Mode, than any other platform or programming language. It's full of talent and people in love with the editor. I recommend exploring the mailing lists, IRC channels, or Org Social itself.
I don't want to leave you with any deep reflection, just to encourage you. It's not easy or fast, but it is rewarding.
-1:-- Emacs is a Fantasy Workstation (Post Andros Fenollosa)--L0--C0--2026-02-15T17:13:17.000Z
Regarding to Emacs crashing: AI found that my Drawin version of Emacs might be the cause. I’ve been using Emacs for Mac OS which ran darwin21.6.0 - old… (current version on macOS is 25.3.0)
The question is, is this really the problem, or more like the AI making stuff up? It makes sense to me that an Emacs build is based on a slightly older Darwin version, though I’m not an expert. Another reason for this suspicion is that the AI assistant recommended emacs-plus without considering emacs for macOS. I know both are solid based on my own research, and I used Emacs-plus (available with Homebrew) for a while. I’ve been using Emacs for macOS for about a year, and it’s been fine until I believe I updated to the latest macOS, which everyone seems to hate, so I wouldn’t be surprised if it has to do with macOS 26 more than anything else.
For now, I installed the latest version of Emacs for macOS, which was built on darwin23.2 - still behind, but not as bad. If this is what’s running Emacs 30.2 for so many Mac users, it further confirms my suspicion that the Darwin version is not really the issue. But maybe I’m wrong.
I posted my question on Reddit to get some feedback, and out of curiosity, see what the Darwin version is for Emacs-plus (don’t want to install it right now). Guess we’ll see.
-1:-- Emacs for macOS and Darwin versions (Post TAONAW - Emacs and Org Mode)--L0--C0--2026-02-15T15:59:07.000Z
Bozhidar Batsov has announced the release of the first version of Neocaml, an Emacs major mode for OCaml. Batsov is a big fan of OCaml but wasn’t happy with the existing Emacs major modes for it. So, of course, he started working on his own version. He’s now reached the point where he feels it’s ready to be shared so he’s released Version 0.1. It’s already on MELPA so it’s easy to install if you want to try it out.
Batsov’s post lays out what he feels was wrong with the existing implementations. You can read the details in his post but the TL;DR is that they’re either old and not well maintained or they use the old style font-locking and indentation mechanisms that have been replaced by TreeSitter.
Batsov says that tuareg still has more features than Neocaml but that Neocaml has all the features you’re apt to need. Batsov is, of course, still working on adding additional features including support for more file types and improvements to structured navigation using TreeSitter. He is, of course, very interested in bug reports and pull requests.
-1:-- Neocaml Released (Post Irreal)--L0--C0--2026-02-15T12:36:58.000Z
neocaml 0.1 is finally out! Almost a year
after I announced the
project,
I’m happy to report that it has matured to the point where I feel comfortable
calling it ready for action. Even better - neocaml recently landed in
MELPA, which means installing it is now as easy
as:
1
M-x package-install <RET> neocaml <RET>
That’s quite the journey from “a fun experimental project” to a proper Emacs package!
You might be wondering what’s wrong with the existing options. The short answer -
nothing is wrong per se, but neocaml offers a different set of trade-offs:
caml-mode is ancient and barely maintained. It lacks many features that
modern Emacs users expect and it probably should have been deprecated a long time ago.tuareg-mode is very powerful, but also very complex. It carries a lot of
legacy code and its regex-based font-locking and custom indentation engine show
their age. It’s a beast - in both the good and the bad sense of the word.neocaml aims to be a modern, lean alternative that fully embraces
TreeSitter. The codebase is small, well-documented, and easy to hack on. If
you’re running Emacs 29+ (and especially Emacs 30), TreeSitter is the future
and neocaml is built entirely around it.Of course, neocaml is the youngest of the bunch and it doesn’t yet match
Tuareg’s feature completeness. But for many OCaml workflows it’s already more
than sufficient, especially when combined with LSP support.
I’ve started the project mostly because I thought that the existing
Emacs tooling for OCaml was somewhat behind the times - e.g. both
caml-mode and tuareg-mode have features that are no longer needed
in the era of ocamllsp.
Let me now walk you through the highlights of version 0.1.
The current feature-set is relatively modest, but all the essential functionality one would expect from an Emacs major mode is there.
neocaml leverages TreeSitter for syntax highlighting, which is both more
accurate and more performant than the traditional regex-based approaches used by
caml-mode and tuareg-mode. The font-locking supports 4 customizable
intensity levels (controlled via treesit-font-lock-level, default 3), so you
can pick the amount of color that suits your taste.
Both .ml (source) and .mli (interface) files get their own major modes with
dedicated highlighting rules.
Indentation has always been tricky for OCaml modes, and I won’t pretend it’s
perfect yet, but neocaml’s TreeSitter-based indentation engine is already quite
usable. It also supports cycle-indent functionality, so hitting TAB repeatedly
will cycle through plausible indentation levels - a nice quality-of-life feature
when the indentation rules can’t fully determine the “right” indent.
If you prefer, you can still delegate indentation to external tools like
ocp-indent or even Tuareg’s indentation functions. Still, I think most people
will be quite satisfied with the built-in indentation logic.
neocaml provides proper structural navigation commands (beginning-of-defun,
end-of-defun, forward-sexp) powered by TreeSitter, plus imenu integration
definitions in a buffer has never been easier.
The older modes provide very similar functionality as well, of course,
but the use of TreeSitter in neocaml makes such commands more reliable and
robust.
No OCaml mode would be complete without REPL (toplevel) integration. neocaml-repl-minor-mode
provides all the essentials:
C-c C-z - Start or switch to the OCaml REPLC-c C-c - Send the current definitionC-c C-r - Send the selected regionC-c C-b - Send the entire bufferC-c C-p - Send a phrase (code until ;;)The default REPL is ocaml, but you can easily switch to utop via
neocaml-repl-program-name.
I’m still on the fence on whether I want to invest time into making the REPL-integration more powerful or keep it as simple as possible. Right now it’s definitely not a big priority for me, but I want to match what the other older OCaml modes offered in that regard.
neocaml works great with Eglot and
ocamllsp, automatically setting the appropriate language IDs for both .ml and
.mli files. Pair neocaml with
ocaml-eglot and you get a pretty
solid OCaml development experience.
The creation of LSP really simplified the lives of a major mode authors like me, as now many of the features that were historically major mode specific are provided by LSP clients out-of-the-box.
That’s also another reason why you probably want to leaner major mode like neocaml-mode.
But, wait, there’s more!
C-c C-a to quickly switch between .ml and .mli filesM-x neocaml-install-grammarsThere’s still plenty of work to do:
.mld)neocamlIf you’re following me, you probably know that I’m passionate about both Emacs
and OCaml. I hope that neocaml will be my way to contribute to the awesome
OCaml community.
I’m not sure how quickly things will move, but I’m committed to making neocaml
the best OCaml editing experience on Emacs. Time will tell how far I’ll get!
If you’re an OCaml programmer using Emacs, I’d love for you to take neocaml for
a spin. Install it from MELPA, kick the tires, and let me know what you think.
Bug reports, feature requests, and pull requests are all most welcome on
GitHub!
That’s all from me, folks! Keep hacking!
-1:-- Neocaml 0.1: Ready for Action (Post Bozhidar Batsov)--L0--C0--2026-02-14T16:34:00.000Z
With my boring productivity system storing any read later links I wanted a faster way to open the link on the current line. Pressing M x brought up search and then I could trigger org-agenda-open-link which would open the link in my default browser.
Too many keystrokes, so I mapped the same command to SPC l g which roughly translates in my head as link go.
Add this to config.el if you want a similar setup.
(map! :leader
:desc "Org open link at point"
"l g" #'org-agenda-open-link)
-1:-- Mapping org-agenda-open-link (Post Curtis McHale)--L0--C0--2026-02-14T08:27:00.000Z
My institution-calendar package for Emacs displays term+week
indicators in the *Calendar* buffer (which, by default, is produced
by the calendar command). This is useful, for example, for schools
who organise their work by terms, such as winter, spring, and summer,
with each having a set number of weeks. This is how the University of
Oxford will look like:
The package supports the universities of Oxford and Cambridge out-of-the-box, though users can define their own institutions. I have two institutions there to provide concrete examples. I am happy to add more, but the idea is for users to maintain their own data.
Below I show a complete example using data for a school in Austria.
To make this work, you first need to specify the data. This has the
same structure as institution-calendar-oxford-university-dates and
thus passes the test of institution-calendar-valid-data-p. Look at
the code for Oxford to get an idea. Here is a sample:
(defvar my-austrian-school-dates
'((2025 (wintersemester ( 9 8 2025) ( 2 6 2026))
(sommersemester ( 2 16 2026) ( 7 10 2026)))))
This is an Austrian school that has two terms for the academic year
starting in 2025: wintersemester and sommersemester. The symbols
for those terms can be anything. Internally, the package uses the
first letter to form the week indicator, followed by the number of the
week within the given term.
Each term defines a start date and an end date as a list of integers
of the form (MONTH DAY YEAR). I picked a form that is consistent
with the way calendar.el represents the date, otherwise I would have
used a different standard.
The variable institution-calendar-user-entities contains all
user-defined institutions and their corresponding calendar data. Each
entry is a cons cell of the form (ENTITY . CALENDAR-DATA), where
ENTITY is an arbitrary symbol and CALENDAR-DATA is the symbol of a
variable that holds the data, as shown in the previous section.
Here is how we can add to this list:
(add-to-list 'institution-calendar-user-entities (cons 'austrian-school 'my-austrian-school-dates))
In this example, I am calling the newly registered institution
austrian-school, which is how I can refer to it elsewhere. I am
associating this austrian-school with the calendar data of the
variable my-austrian-school-dates.
institution-calendar-mode work for your institutionWith the aforementioned in place, the user option institution-calendar-entity
can be set to the value of austrian-school:
(setopt institution-calendar-entity 'austrian-school)
If the institution-calendar-mode is enabled, then the regular
calendar command will display week indicators for this school. This
is good if you only need one calendar. But if you work with many
institutions and thus need to switch between their calendars, then
ignore this step and move to the next one. Or ignore it anyway if you
prefer to keep the M-x calendar intact.
The macro institution-calendar-define-convenience-command makes it
trivial to define a command that produces a calendar buffer for the
given institution. This is like M-x calendar with the minor mode
institution-calendar-mode enabled, except it does not alter the
output of the calendar—so you can use them both (or, anyhow, use
as many as the institutions you care about).
;; This defines the command `institution-calendar-austrian-school'.
;; Call `institution-calendar-austrian-school' with M-x or bind it to a key.
(institution-calendar-define-convenience-command austrian-school)
Once you evaluate this macro call, you will get the command
institution-calendar-austrian-school. Use that to produce a calendar
that works with the austrian-school in particular. If you are
curious, M-x institution-calendar-oxford-university will still do
the right thing for the University of Oxford. Same for the command
institution-calendar-cambridge-university.
The user option institution-calendar-include-intermonth-header adds
a header above the week numbers. By default, this only works with the
universities of Oxford and Cambridge. Though you can extend the
package to support your institution by adding to the value of the
variable institution-calendar-intermonth-headers. Thus:
(add-to-list 'institution-calendar-intermonth-headers (cons 'austrian-school "AU"))
You can skip this step if you do not plan to display the intermonth header. Those are not shown by default.
This is how your configuration of the institution-calendar may look like:
(use-package institution-calendar
:ensure nil ; not in a package archive
:init
;; Install it from source.
;; Then upgrade it with the command `package-vc-upgrade' or `package-vc-upgrade-all'.
(unless (package-installed-p 'institution-calendar)
(package-vc-install "https://github.com/protesilaos/institution-calendar.git"))
:config
(defvar my-austrian-school-dates
'((2025 (wintersemester ( 9 8 2025) ( 2 6 2026))
(sommersemester ( 2 16 2026) ( 7 10 2026)))))
(add-to-list 'institution-calendar-user-entities (cons 'austrian-school 'my-austrian-school-dates))
;; This defines the command `institution-calendar-austrian-school'.
;; Call `institution-calendar-austrian-school' with M-x or bind it to a key.
(institution-calendar-define-convenience-command austrian-school)
(setopt institution-calendar-include-extra-week-numbers t)
(setopt institution-calendar-include-intermonth-header nil)
;; These are optional, if you want `M-x calendar' to work for your institution.
(setopt institution-calendar-entity 'austrian-school)
(institution-calendar-mode 1))
-1:-- Emacs: add custom entity (Austrian school) to my ‘institution-calendar’ (Post Protesilaos Stavrou)--L0--C0--2026-02-14T00:00:00.000Z
Aimé Bertrand has an nice post on how he exports scheduled items in his org agenda to his macOS calendar. He mostly lives in Emacs and Org mode but, like, me also likes to have his appointments and other scheduled events in his macOS calendar. The main attraction for doing this to me is that it will sync all your appointments to all your devices as well as share it with appropriate other people. Sadly, Emacs doesn’t run on iOS and given Apple’s no interpreters policy, probably never will.
Bertrand wasn’t concerned with keeping the two calendars synced; he only wanted to export his Org scheduled events to the macOS calendar. This turned out to be harder than you might think. The existing solutions didn’t quite do what he needed so he decided to roll his own.
You can read his post for the details. He has a couple of different ways of approaching the problem. The details aside, the takeaway for me is the flexibility of Emacs and its ability to interact with other applications that may never have heard of Emacs.
If you’re using Emacs on a Mac and would like to ensure that all your Org scheduled events are reflected on the system calendar, take a look at Bertrand’s post for one way of solving the problem.
-1:-- Exporting From Org Agenda To macOS Calendar (Post Irreal)--L0--C0--2026-02-13T15:59:08.000Z
Raw link: https://www.youtube.com/watch?v=atKuEh3_ArA
In this short video I demonstate a new package for GNU Emacs that synchronises the Emacs theme with the GNOME settings for accent color and light/dark mode. Git repository here: https://github.com/protesilaos/gnome-accent-theme-switcher.
-1:-- Emacs: my GNOME accent color theme switcher package (Post Protesilaos Stavrou)--L0--C0--2026-02-13T00:00:00.000Z
Theena Kumaragurunathan, a filmmaker, photographer, and writer, has an interesting post on using Emacs for writing science fiction. There’s nothing new about that, if course. Several well known SF authors use Emacs. Kumaragurunathan’s post is interesting for two reasons:
The brain computer interface (BCI) is how the technical elite communicate with a sentient AI 500 years in the future. The BCI is more complicated and featureful than that described in Niven and Pournelle’s Oath of Fealty. Instead of dealing with buffers, it deals with thought patterns and, as with Emacs buffers, they can be manipulated in various ways by a programming language built into the BCI.
It’s an interesting concept but for those of us in 2026, the real value of Kumaragurunathan’s post is his journey from word processors to Emacs. The journey is one of a quest to control his writing environment. Many Irreal readers will relate even if they have to substitute “programming environment” for “writing environment”.
Kumaragurunathan is promising a followup post in which he will discuss his Emacs workflow and how he uses it for writing fiction, research notes, film scripts, and even for programming. I’m looking forward to it.
-1:-- Writing SF With Emacs (Post Irreal)--L0--C0--2026-02-12T16:11:09.000Z
Lin is a stylistic enhancement for Emacs’ built-in hl-line-mode. It
remaps the hl-line face (or equivalent) buffer-locally to a style that
is optimal for major modes where line selection is the primary mode of
interaction.
The idea is that hl-line-mode cannot work equally well for contexts
with competing priorities: (i) line selection, or (ii) simple line
highlight. In the former case, the current line needs to be made
prominent because it carries a specific meaning of some significance in
the given context: the user has to select a line. Whereas in the latter
case, the primary mode of interaction does not revolve around the line
highlight itself: it may be because the focus is on editing text or
reading through the buffer’s contents, so the current line highlight is
more of a reminder of the point’s location on the vertical axis.
linBelow are the release notes
This is the first tagged release since 2024-08-05. The package is in a stable state: it does everything it is meant to. This version makes some small refinements, mostly in how parts of the code are written. Though there also are some nice user-facing changes:
The lin-gnome-accent-color-mode synchronises the accent colour of
the GNOME desktop environment with Lin’ own lin-face. This happens
live, so any buffers that are already using the lin-mode (directly
or via lin-global-mode) will get the updated colour.
The user option lin-gnome-accent-color-override-foreground
controls whether the faces that correspond to GNOME accent colours
should override the underlying text colour or not. This is useful
for improved colour contrast. The default is to not override the
foreground. Setting lin-gnome-accent-color-override-foreground to
non-nil changes that so, for example, the lin-face will be set
to lin-red-override-fg instead of lin-red (of course, faces can
be modified by users/themes to override the foreground anyway, so
this is about the default behaviour).
New faces to style the current line when lin-mode is enabled
include lin-purple, lin-orange, and lin-slate. Those do not
override the underlying foreground colours by default. Whereas
lin-purple-override-fg, lin-orange-override-fg, and
lin-slate-override-fg apply their background while also setting
the foreground (remember that you always control which face to use
by changing the user option lin-face).
The lin-global-mode skips all private buffers. These are buffers
that users normally do not interact with directly. Their names are
prefixed with a space and, by default, are hidden from the view of
switch-to-buffer and related commands.
The default value of the user option lin-mode-hooks now includes
the world-clock-mode-hook and xref--xref-buffer-mode-hook. The
former relates to the command world-clock, while the latter is
used by any command that produces Grep-like results via the built-in
Xref infrastructure (for example, my Denote package does that for a
few of its commands). The lin-mode-hooks is a list of hooks for
major modes that should use the Lin style for the selection line
highlight.
-1:-- Emacs: Lin version 2.0.0 (Post Protesilaos Stavrou)--L0--C0--2026-02-12T00:00:00.000Z
If you’ve ever enabled a new theme and noticed your tab-bar faces stubbornly hanging onto old colours or custom tweaks, I have found often that the tab-bar, tab-bar-tab, and tab-bar-tab-inactive faces don’t always blend cleanly with freshly loaded themes — especially of the older variety (a bit like me) and especially ones that came out before the tab bar was introduced into Emacs.
So how about a simple solution?, Can I implement something, that whenever I load a theme, the tab-bar faces update based on the theme’s default faces to establish a visually pleasant and coherent look?
Yes, yes I can!; the result is a tiny Elisp enhancement that hooks directly into Emacs’ theme-loading process.
Firstly however we need to have a method that will reliably pass over the themes default faces to the tab-bar. Here’s the function that realigns the tab-bar styling with your active theme:
(defun selected-window-accent-sync-tab-bar-to-theme ()
"Synchronize tab-bar faces with the current theme."
(interactive)
(let ((default-bg (face-background 'default))
(default-fg (face-foreground 'default))
(inactive-fg (face-foreground 'mode-line-inactive)))
(custom-set-faces
`(tab-bar ((t (:inherit default :background ,default-bg :foreground ,default-fg))))
`(tab-bar-tab ((t (:inherit default :background ,default-fg :foreground ,default-bg))))
`(tab-bar-tab-inactive ((t (:inherit default :background ,default-bg :foreground ,inactive-fg)))))))
This simply rebuilds the key tab-bar faces so they derive their colours from the current theme’s normal face definitions, so any old themes should now not leave the tab bar faces hanging.
Now for the function activation; Emacs 29 introduced enable-theme-functions, a hook that runs every time a theme is enabled — perfect for our use case, but as always I have my eye on older Emacs versions, so lets fall back to a classic approach: advice on load-theme.
Here’s a version‑aware setup that does the right thing automatically:
(if (version<= "29.1" emacs-version)
;; Emacs 29.1+ — use the official theme hook
(add-hook 'enable-theme-functions
(lambda (_theme)
(selected-window-accent-sync-tab-bar-to-theme)))
;; Older Emacs — fall back to advising load-theme
(progn
(defun selected-window-accent-sync-tab-bar-to-theme--after (&rest _)
(selected-window-accent-sync-tab-bar-to-theme))
(advice-add 'load-theme :after
#'selected-window-accent-sync-tab-bar-to-theme--after)))
With this tweak in place, every time you change themes, your tab-bar instantly updates, colours stay consistent, clean, and theme‑accurate without you having to do anything at all! The downside to this of course is that any newer themes that were created after the advent of the tab bar in Emacs will have their tab-bar faces overridden, but for me this solution is good enough and gives a pleasant coherent visual tab bar experience.
Yay!, yet another Yak shaved!
-1:-- Automatically Syncing Emacs Tab Bar Styling With Your Theme (Post James Dyer)--L0--C0--2026-02-11T18:26:00.000Z
Álvaro Ramírez has a new Emacs app available. The app, winpulse, is his answer to keeping track of the active window. What happens is that every time the focus changes the new window flashes so you get a visual indication of the new window.
I had the same problem but solved it in a different way. I made the modeline of the active window a strikingly different color so that it’s easy to spot the one with focus. I like my solution better because the indication has longevity. If I get up and then return to my computer, I can immediately see which window is active. The nice thing about my solution is that it simply amounts to a set-face-attribute as you can see in my post or below.
None of this will come as news to Ramírez, of course. He simply prefers a different way of indicating the active window and, as always, Emacs makes it easy to have it your way.
Ramírez says the the app is brand new so it won’t be on Melpa yet but you can get it from its GitHup repository. If you like just having a momentary indication of the active window, Ramírez’s solution may be just what you’re looking for. If you prefer something a little stickier, changing the color of the modeline has worked very well for me. You could, I suppose even use both methods.
For the record, here’s the current code from my inet.el:
(set-face-attribute 'mode-line-active nil :foreground "black" :background "goldenrod" :box '(:line-width 1 :color "black"))
Unless you have a tan background, goldenrod probably isn’t the right color for you but you can experiment to see what works well with your theme.
-1:-- Winpulse (Post Irreal)--L0--C0--2026-02-11T15:10:11.000Z
This is about a new package of mine: institution-calendar. It is not
going to be available on GNU ELPA. Users will have to install it from
source (code for this is further below). The reason is that the
predecossor to this package, oxford-calendar, was not accepted:
I will consider my options going forward, with whatever that means for all my packages.
The institution-calendar package augments the M-x calendar buffer
to include indicators about the applicable term. Each term has week
numbers, which are displayed on the side of the regular calendar data.
The user option institution-calendar-entity specifies which
institution’s data to use. Currently, the value can be either
oxford-university or cambridge-university. Contact me and I will
add support for your institution.
Each term shows the week numbers it formally defines. For example, the
University of Oxford has three terms of 8 weeks each. When the user
option institution-calendar-include-extra-week-numbers is set to a
non-nil value, then an additional two weeks are added: week 0 for
one week before the term starts and an extra number after the term
ends. This is useful for scheduling purposes, such as to arrange
meetings in preparation of the work ahead or to report on what
happened.
The user option institution-calendar-include-intermonth-header
writes text above the institution’s week indicators. This makes it a
bit easier to tell them apart from the regular calendar data.
Enable the minor mode institution-calendar-mode to make all future
calls to M-x calendar use the relevant institution data.
If you do not want to affect the M-x calendar output, then use the
command institution-calendar: it is functionally equivalent to
having the aforementioned minor mode enabled, except it has no
permanent effect on M-x calendar—that will keep its original
appearance.
If, for whatever reason, you need to check the calendar of a specific
institution, then do M-x institution-calendar-cambridge-university
or M-x institution-calendar-oxford-university (more such commands
will be available to match any other institutions that this package
will support).
(use-package institution-calendar
:ensure nil ; not in a package archive
:init
(unless (package-installed-p 'institution-calendar)
(package-vc-install "https://github.com/protesilaos/institution-calendar.git"))
:commands
(institution-calendar
institution-calendar-cambridge-university
institution-calendar-oxford-university)
:config
(setopt institution-calendar-entity 'oxford-university)
(setopt institution-calendar-include-extra-week-numbers t)
(setopt institution-calendar-include-intermonth-header nil)
;; If you want to permanently change what M-x calendar shows, enable
;; this mode. Otherwise, use the relevant command from the
;; :commands listed above.
(institution-calendar-mode 1))
-1:-- Emacs: institution-calendar package (University of Oxford/Cambridge, etc.) (Post Protesilaos Stavrou)--L0--C0--2026-02-11T00:00:00.000Z
A while back, I made a post on Emacs Imenu configuration that made an unsafe assumption that any mode derived from prog-mode would support Imenu. Turns out, that’s not always true (for example, looking at you gnuplot-mode). This post shows how to deal with this using an error handler.
One such implementation of an error handler is the lambda expression shown below using condition-case.
1 2 3 4 5 6 | |
A couple of observations:
imenu-add-menubar-index to a mode derived from prog-mode.imenu-unavailable is caught, then a warning message is logged but not messaged to the mini-buffer.inhibit-message is used to avoid sending a warning message to the minibuffer (it will still be logged in *Messages*) to avoid noise from modes that do not support Imenu. (Thanks to bpalmer for this guidance.)If you use Emacs and this is the first time you’ve heard of Imenu, I highly recommend that you learn what it has to offer.
-1:-- Deburring Emacs Imenu GUI Configuration (Post Charles Choi)--L0--C0--2026-02-10T17:20:00.000Z
It’s been years since I wrote about Gilles Castel and his astounding ability to take LaTeX notes so fast that he was able to keep up with the the instructor in his Mathematics classes. Sadly, Castel died in 2022 but his blog—including the two posts [1, 2] that deal with taking Mathematics notes with the associated diagrams—is still up.
Castel used Vim so he didn’t have AUCTeX but he did have a large collection of UltiSnips snippets that he used to make entering LaTeX fast and relatively painless. One feature of UltiSnips that he leveraged was the ability to specify the trigger word with a regular expression. For example, he uses that capability to recognize subscripts so that a2 → a_2. See his post for other examples.
Naturally, we Emacs nerds went crazy and attempted to replicate his system in Emacs. Karthink had a particularly good solution using AUCTeX, CDLaTeX, and YASnippet. Still it would be nice to be able to specify triggers with a regex.
Over at the Emacs subreddit, nmorazotti has a solution. He’s put together a snippet package, Resnippets.el, that can recognize a regex as a trigger. If you’ve been yearning to try Castel’s approach to taking LaTeX notes, resnippets may be useful.
I won’t be using it for two reasons. First it’s LLM generated and I have a prejudice—rational or not—against AI generated code. Second, and probably more important, is that the snippets are all autoapplied. I HATE that. I want to explicitly invoke the snippet with a Tab. Actually, UltiSnips has this right. By default you invoke its snippet explicitly but you can, on an individual snippet basis, choose to have them invoked automatically.
I don’t know if anyone is still interested in all this but it was fun for me to revisit it.
-1:-- Snippets With Regular Expressions (Post Irreal)--L0--C0--2026-02-10T15:31:30.000Z
Links from reddit.com/r/emacs, r/orgmode, r/spacemacs, Mastodon #emacs, Bluesky #emacs, Hacker News, lobste.rs, programming.dev, lemmy.world, lemmy.ml, planet.emacslife.com, YouTube, the Emacs NEWS file, Emacs Calendar, and emacs-devel. Thanks to Andrés Ramírez for emacs-devel links. Do you have an Emacs-related link or announcement? Please e-mail me at sacha@sachachua.com. Thank you!
You can comment on Mastodon or e-mail me at sacha@sachachua.com.
-1:-- 2026-02-09 Emacs news (Post Sacha Chua)--L0--C0--2026-02-10T01:32:00.000Z
Hard to say officially, but I've been primarily using Emacs for roughly a couple of decades. Maybe my eyesight isn't what it used to be, or maybe I've just been wanting a stronger visual signal as I navigate through Emacs windows. Either way, today's the day I finally did something about it…
I asked around to see if a package already existed for this purpose. Folks shared a handful of great options:
I wanted my windows to temporarily flash when switching between them. Of these options, pulsar came closest, though highlighting the current line only.
This is Emacs, so I should be able to get the behavior I want by throwing some elisp at the problem. With that, I give you winpulse, a package to temporarily highlight focused Emacs windows.
This package is fresh out of the oven and likely has some edge cases I haven't yet considered. If you're still keen to check it out, it's available on GitHub.
Enjoying this package or my content? I'm an indie dev. Consider sponsoring to help make it sustainable.
-1:-- Introducing winpulse (Post Alvaro Ramirez)--L0--C0--2026-02-10T00:00:00.000Z
At the beginning of the year, I jokingly resolved that I wouldn’t change my blog platform more than once every three months. Technically, I’ve kept my word. But last week Kev Quirk introduced his new blogging platform, Pure Blog. I am constitutionally unable to resist trying new blogging platforms, so I set up a copy and started tinkering.
It’s nice! It’s not technically an SSG (it uses PHP), but it maintains content as YAML-fronted Markdown files, just like most SSGs. What attracted me most, originally, was that the whole thing felt like something I’d build, given the time and talent. It focused on the things I find important, so it was a good fit right off the bat.
Here’s mine, so far, running at pure.baty.net. I’m playing with fonts and colors a bit. Currently, it mimics my Emacs theme, ef-day.
Without too much fuss, Pure Blog behaves the way I want a blog to behave. It’s simple, yet complete for what I need. I do have a wishlist, though.
In fairness, the whole project was meant to scratch a particular itch for one person. I’m not complaining! Like I told Kev, “Can open, worms everywhere!” :)
But now what? Part of me wants to break my rule and move baty.net to Pure Blog. That would be an enormous project, because years of using different tools has brought a variety of front matter formats (TOML, YAML, dates, tags, etc).
Another option is to make a new blog, such as I have so far with pure.baty.net, but even though the domain is fitting and kind of funny, I think the novelty will wear off.
I’m thinking about replacing baty.blog with a fresh new Pure Blog and leaving the old site behind. I have the content saved, so while it’ll break links, at least the content is still out there somewhere.
Anyway, Kev’s made a nifty, simple, useful, and easy-to-host blogging tool with Pure Blog. I need to figure out what to do with it.
-1:-- Pure Blog (Post Jack Baty)--L0--C0--2026-02-09T13:21:17.000Z
These are my minimalist themes. They use few colours and will appear mostly monochromatic in many contexts. Styles involve the careful use of typography, such as italics and bold italics.
If you want maximalist themes in terms of colour, check my ef-themes
package. For something in-between, which I would consider the best
“default theme” for a text editor, opt for my modus-themes.
doric-themesBelow are the release notes.
doric-jade is a light theme with a predominantly green feel.
doric-copper is a dark theme with orange, magenta, and cyan colours.
I have update all screenshots: https://protesilaos.com/emacs/doric-themes-pictures.
The relevant faces now use a colour-coding scheme where TODO states are rendered in red while DONE are green.
This is done to ensure cross-theme consistency. Those faces communicate a certain state and, therefore, it is better to not have to relearn which colour means what while switching between the Doric themes.
~code~ faces stand out moreThis is done to differentiate them from =verbatim=. It is especially
important for users who choose to hide the markup with the user option
org-hide-emphasis-markers (I used to do that but realised that the
ambiguity was a problem in many cases, because ~code~ and =verbatim=
have different semantics in some exported formats).
This covers the regular Org headings as well as anything that performs the same function, such as in the Org agenda buffer.
All regular headings use the main foreground value. The document title and the Org agenda equivalent of that are rendered in an accent colour for greater effect.
Combined with the aforementioned revision of the TODO and DONE states, Org buffers are easier to read and work with.
The faces that communicate the current time and applicable filters are made more intense. The idea is to spot them more quickly.
Faces that pertain to diary or diary-style events no longer use italics to avoid exaggerations.
Blocked tasks are easier to spot.
The applicable query in the structure header is made more prominent.
Overall, Org agenda buffers should be easier to scan.
The active/available keys in the Org export dispatcher use more intense colours and have greater padding around them. This is what I also do with the Modus themes (and all derivatives) to improve the legibility of those keys.
The authors in log views and elsewhere have a distinct colour to stand out a bit more. Branches use consistent typography, while the current branch stands out more than the others.
Enabled and disabled keys use a green-red coding scheme.
Active values and arguments have a style that is the same across themes for the same reason as Org TODO and DONE.
Transient headings use the main foreground colour to not draw more attention than they need to.
Those are seen when writing a commit message in Magit.
The relevant face uses a distinct foreground. It no longer applies a bold weight, as that had the effect of making the buffers much busier than necessary.
Items that are marked for selection are rendered in a green style, while those marked for deletion are red.
This is done for cross-theme consistency, so that users do not have to think twice before performing the relevant operations.
doric-themes-with-colors macro for advanced usersThis macro is effectively the same as a let for binding the colours
of the active Doric theme. Advanced users can rely on this macro to
write functions that, for example, set the theme-specific red colour
value of a given face.
Symlinks in Dired buffers are easier to spot. Same for visited links in Info buffers.
Org definitions no longer override the foreground of any other face present in them. Same for the notmuch header in view buffers.
-1:-- Emacs: doric-themes version 1.0.0 (Post Protesilaos Stavrou)--L0--C0--2026-02-09T00:00:00.000Z
I am greatly fond of Org Mode. Everything happens in Org: tasks, notes, scheduling, you name it.
But here is the thing. I still want my events to show up in macOS Calendar. Why? Well, Calendar.app has nice widgets. It syncs to my iPhone. It sends me notifications that actually work. And sometimes, I just want to glance at my day without firing up Emacs. Also: Why not?
So the question becomes:
how do I get my Org scheduled items into Calendar.app without copy-pasting like some kind of animal?
org-caldav is the full-featured option – bidirectional sync via CalDAV. But iCloud authentication is painful, and it kept breaking on me. Life is too short.
org-mac-iCal syncs the wrong direction (Calendar → Org) and hasn’t been maintained since OS X 10.5.
Org’s built-in ox-icalendar just exports. You still need to automate it and get the file into Calendar somehow. That’s the gap I wanted to fill.
With a lot of coding assistant, a lot of (reverse) engineering and a lot of code review so that I do not break my stuff…
Enter org-to-cal – an Emacs package I wrote to solve exactly this. It exports Org items tagged with :ical: to macOS Calendar. Automatically. On save.
The package lives here: https://gitlab.com/aimebertrand/org-to-cal
The concept is simple:
:ical:Behind the scenes, it uses Org’s built-in ox-icalendar to generate a standard .ics file. Getting that file into Calendar is where it gets interesting.
I implemented two different approaches. Pick your poison.
A small HTTP server (Python, embedded in the package) serves the .ics file on localhost:8042. You subscribe to it in Calendar.app like any calendar subscription.
A LaunchAgent starts the server on reboot of the mac.
A Swift executable talks directly to EventKit (macOS’s calendar API). A LaunchAgent watches the .ics file and imports changes immediately.
Pros: Instant updates. No polling. Cons: Slightly more complex. Does not delete events (only creates/updates).
You can run both simultaneously if you want redundancy. I do.
Well i do not wanna bore you with all the details. The README.org is quite good and extensive.
The direct import method has a neat trick. It stores event UIDs in a uid_map.plist file and embeds them in the event notes as [org-uid:xxx]. This means if you sync via iCloud and the local UID mapping is lost, it can recover by searching the notes field.
Granted, this is an edge case. But when it works, it feels like magic.
Be advised:
This is one-way sync. Org → Calendar. If you edit events in Calendar.app, those changes will not come back to Org.
Also, the direct import method cannot delete events. If you remove the :ical: tag from an Org entry, the event stays in Calendar. You will have to delete it manually. ¯\_(ツ)_/¯
org-to-cal scratches a very specific itch of mine. I wanted my Org schedule in Calendar.app without thinking about it. Now it just happens.
The code is MIT licensed. Contributions welcome.
-1:-- org-to-cal - Syncing Org Mode to macOS Calendar (Post Aimé Bertrand)--L0--C0--2026-02-08T23:00:00.000Z
-1:-- [RFC] Rename :colnames header argument to :strip-colnames (Post Org Mode requests)--L0--C0--2026-02-08T11:07:45.000Z
After recently releasing magit-git-toolbelt, a Transient interface for git-toolbelt in magit, I’m happy to share another Magit extension I’ve been working on – magit-gh, an Emacs package that integrates the GitHub CLI (gh) into Magit. Similar to my former package, it provides a Transient menu interface to list, checkout, and view pull requests directly from Emacs without leaving your workflow.
If you work with pull requests on GitHub every day, you know the git checkout dance: you’re deep in flow and in a Magit buffer, you need to check on a PR, so you switch to a browser, find the repo, navigate to the PR tab, and then maybe come back to checkout the branch in eshell or even your terminal. It’s a small context switch, but it adds up.
Forge has been the defacto and established solution for this and it’s a fantastic and comprehensive package for interacting with Git forges from within Magit – it has all the bells and whistles for this workflow. If you need deep integration – tracking issues, managing pull requests, reading and writing comments, all stored locally in a light database – Forge is the right tool. I would highly recommend Forge over this package if that is your use case.
magit-gh takes a different approach. It delegates to the GitHub CLI (gh) for all GitHub interaction, which means:
emacsql, which can be tricky to set up (compiling native modules, resolving binary availability issues). magit-gh stores nothing locally.authinfo file (ideally encrypted with GPG). magit-gh piggybacks on gh auth login, which you have already configured from authenticating the first time.gh CLI.The trade-off is that magit-gh is far less featureful than Forge. It is intentionally a lightweight alternative for users who primarily want to list, checkout, and view pull requests without additional setup overhead.
You’ll need the GitHub CLI installed and authenticated first:
# macOS
brew install gh
# Linux (Fedora / RHEL / CentOS)
sudo dnf install gh
# Then authenticate
gh auth login
Then install magit-gh from MELPA:
M-x package-install RET magit-gh RET
Or with use-package:
(use-package magit-gh
:ensure t
:after magit)
From any Magit status buffer, press , to bring up the magit-gh Transient menu. You can also invoke it directly with M-x magit-gh. The menu is organized into Pull Request commands:
magit-gh
└── Pull Requests
├── l List open PRs
├── c Checkout PR
└── v View PR in browser
When you list open PRs (l), a dedicated buffer opens showing PR number, title, author, and branch name. From that buffer you can checkout a PR with RET or c, open it in your browser with v, refresh the list with g, or close the buffer with q.
If you don’t like the , key binding, you can set a custom one. Note that the variable must be set before the package loads so it needs to be in the init section:
(use-package magit-gh
:ensure t
:after magit
:init
(setq magit-gh-key ";")) ; Example setting key to ";" instead of the default ","
To increase the number of PRs fetched (default 30):
(use-package magit-gh
:ensure t
:after magit
:custom
(magit-gh-pr-limit 50))
Aside from bugs and visual improvements to the TUI, I would consider this package mostly feature complete. The current feature set is intentionally small, but I have plans to add support for listing closed/merged PRs, creating new PRs, viewing diffs and CI status, and eventually issue management – all through the gh CLI. You can track progress on the GitHub repo.
If you use Magit and the GitHub CLI, give magit-gh a try! It’s available on MELPA and the source is on GitHub. Contributions and feedback are always welcome! Hope this is useful!
-1:-- Introducing magit-gh (Post Jonathan Chu)--L0--C0--2026-02-08T05:00:00.000Z
Raw link: https://www.youtube.com/watch?v=3u6u6MVNydI
In this near-3-hour video I talk to Eric Frederickson about a broad range of issues that can be summed up under the theme of “cosmic consistency”. We start with a discussion about Eric’s endeavours with software development. I ask about Eric’s experience with free software and open source contributions, which makes us consider not just the programming side of things but also how there is a community-building component to the whole process. The development of GNU Emacs is a case in point. We explore how participating in free software is part coding part character building due to the social skills/interactions involved.
Our next big topic is art and creativity. Eric is a musician and has a keen interest in the artistic experience. Over the course of our talk we comment on ways to be creative, the different forms of expression we find from conservation to exploration, and how harmony is experienced. Many finer points here involve the sense of awe, how aesthetics cannot be reduced to words, that text alone disturbs us because we do not connect to a person’s emotional state, and more. Eric asks me what I think about the rhythm of life, also with regard to my way of choosing to live in the mountains and how all that underpins my creativity.
We share how myths and catchy stimuli play a key role in religiosity, as well as how religion cannot be reduced to a system of propositions: it also has a social aspect to it and a function of social reproduction. Our attention is focused on how people understand when not to take themselves too seriously. Examples we expound on involve Santa Claus and the Greek gods. In this regard I explain how Greek religion and Greek mythology are distinct, even if the latter draws inspiration from the former.
At many points we draw parallels between matters of human creation, such as art, and the natural order. For example, there is a way in which an idea stands the test of time when its application leads to viable results.
Eric has appeared before in this series: https://protesilaos.com/codelog/2025-07-23-prot-asks-eric-emacs-lisp-music-aesthetics-minnesota/.
My program “hms”, a featureful CLI time-duration calculator: https://emfred.com/programs/hms.
My piece of music “Flying Home”, which features recordings of birdcalls at various playback rates: https://emfred.com/audio/sbp4-05-Flying-Home.mp3.
My collection of music which includes “Flying Home”, called “Sketchbook, page 4”: https://emfred.com/sketchbook/pg4.
And finally, in case a listener would like to contact me: https://emfred.com/about/contact
In this video series, I talk to anybody who is interested to have a video call with me (so do contact me if you want!). The topics cover anything related to Emacs, technology, and life in general. More here: https://protesilaos.com/prot-asks.
-1:-- Prot Asks: Eric about free software, art, religion, and cosmic consistency (Post Protesilaos Stavrou)--L0--C0--2026-02-08T00: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!