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.