New stuff in Emacs 30
Posted:
Whoa, the Emacs 30 release cycle has officially started (I totally missed when this was announced a month ago). We're still waiting on a pretest build, but that didn't stop me from reading through the NEWS file and highlighting some of my favorite changes.
These updates are hand-picked based on my interest, check out emacs-30/etc/NEWS for the full release notes.
Native compilation enabled by default
This is huge! At least, for those who haven't already been using this since the Emacs 28 opt-in. Native compilation has made a huge performance difference for me, so I'm happy to see it enabled by default.
Native (and faster) JSON support
You no longer need an external library (libjansson
) to work with
JSON in Emacs. On top of that, JSON parsing performance in Emacs is
significantly improved (the author provides that parsing is up to 8x
faster). This is all thanks to Géza Herman's contribution: I
created a faster JSON
parser. He
summarizes his changes later in that thread:
My parser creates Lisp objects during parsing, there is no intermediate step as Emacs has with jansson. With jansson, there are a lot of allocations, which my parser doesn't have (my parser has only two buffers, which exponentially grow. There are no other allocations). But even ignoring performance loss because of mallocs (on my dataset, 40% of CPU time goes into malloc/free), I think parsing should be faster, so maybe jansson is not a fast parser in the first place.
Great stuff.
use-package :vc
keyword
You can now install packages directly from version-controlled repositories (for those packages that aren't yet in ELPA or MELPA).
Example:
(use-package bbdb
:vc (:url "https://git.savannah.nongnu.org/git/bbdb.git"
:rev :newest))
This also means that you can opt into package updates based on commit
instead of latest release (e.g. :rev :newest
). I think this is
actually a sleeper feature of :vc
, since the default Emacs package
release/update cycle can be a little wonky at times.
If you want all of your :vc
packages to prefer the latest commit
(instead of the latest release), you can set
use-package-vc-prefer-newest
to t
.
Tree-sitter modes are declared as submodes
I had to read this change a few times before I grokked what it was
saying. Tree-sitter modes, e.g. js-ts-mode
, are now submodes of
their non-tree-sitter counterpart, e.g. js-mode
. That means any
configuration applied to the non-tree-sitter mode also applies to the
tree-sitter mode.
In other words, my .dir-locals.el
settings for js-mode
simply
apply to js-ts-mode
as well, without needing to write it
explicitly. It's a nice quality-of-life change.
Minibuffer QOL improvements
Some nice quality-of-life improvements for the default Emacs completions:
-
You can now use the arrow keys to navigate the completion buffer vertically (in addition to the
M-<up|down>
keybindings). -
Previous minibuffer completion selections are deselected when you begin typing again (to avoid accidentally hitting a previous selection).
-
completions-sort
has a new value:historical
. Completion candidates will be sorted by their order in minibuffer history so that recent candidates appear first.
Customize interface for dir-locals
There's now a customize interface for Directory Variables:
M-x customize-dirlocals
I always find myself forgetting the .dir-locals.el
syntax (even
though they're just lists!) so this is a surprisingly handy feature
for me.
New mode: visual-wrap-prefix-mode
Now this one is cool. I'm the kind of guy who uses auto-mode
for
everything because I haven't bothered to figure out how Emacs line
wrapping works. Everything I write hard breaks into newlines after 80
characters.
The new mode visual-wrap-prefix-mode
is like auto-mode
, except
that the breaks are for display purposes only. I think this is
incredibly useful when editing text that might be reviewed using a
diffing tool, since long lines tend to display more useful diffs than
a paragraph broken up with hard breaks. I'm actually pretty excited
about this change, maybe it will get me to stop using (markdown-mode . (( mode . auto-fill))
everywhere.
New command: replace-regexp-as-diff
You can now visualize regular expression replacements as diffs before they're accepted. This is actually incredible.
New package: which-key
Previously a package in GNU ELPA, which-key-mode
is now
built-in. With which-key-mode
enabled, after you begin a new command
(e.g. C-x
) and wait a few seconds, a minibuffer will pop up with a
list of possible keybinding completions. It's a super handy tool for
remembering some of the more esoteric modes.
New customizations
-
Show the current project (via
project.el
) in your modeline withproject-mode-line
. -
Add right-aligned modeline elements via
mode-line-format-right-align
. -
You can now customize the venerable
yes-or-no-p
function withyes-or-no-prompt
.
A few ELisp changes
There are a few small, yet impactful changes around help buffers and Emacs Lisp types that I think are worth noting.
describe-function
shows the function inferred type when available:
C-h f concat RET
(concat &rest SEQUENCES)
Type: (function (&rest sequence) string)
- Built-in types show their related classes:
C-h o integer RET
integer is a type (of kind ‘built-in-class’).
Inherits from ‘number’, ‘integer-or-marker’.
Children ‘fixnum’, ‘bignum’.
- The byte compiler warns if a file is missing the lexical binding directive. Lexical bindings have been included in ELisp for awhile now, so it's nice to see more effort being made towards making it the default.
;;; Foo mode -*- lexical-binding: t -*-
Read the full details
That wraps up my read-through. There's obviously way more changes included in Emacs 30, so I encourage you to check it out for yourself: NEWS.