docs(articles): Emacs 31 article
This commit is contained in:
51
.drone.yml
51
.drone.yml
@@ -1,51 +0,0 @@
|
|||||||
kind: pipeline
|
|
||||||
name: default
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build
|
|
||||||
image: silex/emacs:27-alpine
|
|
||||||
commands:
|
|
||||||
- apk add hugo git
|
|
||||||
- git submodule update --init --recursive
|
|
||||||
- mkdir blog
|
|
||||||
- emacs --script .export.el
|
|
||||||
- hugo -d blog
|
|
||||||
|
|
||||||
- name: deploy
|
|
||||||
image: appleboy/drone-scp
|
|
||||||
settings:
|
|
||||||
host:
|
|
||||||
from_secret: ssh_host
|
|
||||||
target:
|
|
||||||
from_secret: ssh_target
|
|
||||||
source: blog/*
|
|
||||||
strip_components: 1
|
|
||||||
username:
|
|
||||||
from_secret: ssh_username
|
|
||||||
password:
|
|
||||||
from_secret: ssh_password
|
|
||||||
port:
|
|
||||||
from_secret: ssh_port
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
||||||
|
|
||||||
- name: purge cache
|
|
||||||
image: jetrails/drone-cloudflare-caching
|
|
||||||
settings:
|
|
||||||
api_token:
|
|
||||||
from_secret: cloudflare_cache_api
|
|
||||||
zone_identifier:
|
|
||||||
from_secret: phundrak_com_zone_id
|
|
||||||
action: purge_files
|
|
||||||
list:
|
|
||||||
- https://blog.phundrak.com
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- master
|
|
||||||
event:
|
|
||||||
exclude:
|
|
||||||
- pull_request
|
|
||||||
@@ -808,6 +808,430 @@ Happy programming!
|
|||||||
|
|
||||||
* Emacs :@emacs:
|
* Emacs :@emacs:
|
||||||
|
|
||||||
|
** Emacs 31 is coming, and here’s what’s new! :dev:emacs:release:
|
||||||
|
:PROPERTIES:
|
||||||
|
:EXPORT_FILE_NAME: emacs-31-is-coming-heres-whats-new
|
||||||
|
:EXPORT_DATE: 2026-01-02
|
||||||
|
:EXPORT_OPTIONS: toc:2
|
||||||
|
:export_hugo_menu: :menu "main"
|
||||||
|
:END:
|
||||||
|
[[https://blog.phundrak.com/emacs-29-what-can-we-expect/][A few years ago]], I published a blog post regarding what was new in
|
||||||
|
Emacs 29 as it came close to being released. I missed the mark for
|
||||||
|
Emacs 30, but now, Emacs 31 is getting ready for release.
|
||||||
|
|
||||||
|
So, what can we expect for Emacs 31? Everything’s written in its =NEWS=
|
||||||
|
file, but here are some elements I think are important. Be warned,
|
||||||
|
although I’m not as hyped as I was for Emacs 29 that brought a few big
|
||||||
|
features, this article is quite a bit longer.
|
||||||
|
|
||||||
|
*** Breaking Change
|
||||||
|
|
||||||
|
**** Configuration
|
||||||
|
=site-start.el= will now load before your =early-init.el=, instead of
|
||||||
|
after it.
|
||||||
|
|
||||||
|
**** Python
|
||||||
|
=python-mode= will now default to calling =python= instead of =python3=,
|
||||||
|
though it will fall back to =python3= if =python= is not found. Most modern
|
||||||
|
systems no longer ship Python 2, and =python= most likely points to
|
||||||
|
Python 3. If =python= still points to Python 2 on your system, you *MUST*
|
||||||
|
change the value of =python-interpreter= and =python-shell-interpreter=.
|
||||||
|
|
||||||
|
As Python 2 has been EOL for five years now, its support is now
|
||||||
|
optional and disabled by default.
|
||||||
|
|
||||||
|
*** Editing
|
||||||
|
With the new option =kill-region-dwim= set to non-nil, calling
|
||||||
|
=kill-region= will now kill the last word instead of raising an error if
|
||||||
|
no region is selected.
|
||||||
|
|
||||||
|
Electric Pair mode got better: you can now set strings using multiple
|
||||||
|
characters in =electric-pair-pairs=, such as ='("r#\"" . "\"#")= to
|
||||||
|
surround a region with =r#"= and ="#=. And if you want an extra space
|
||||||
|
between your delimiters and the selected region, you can instead use
|
||||||
|
='("r#\"" "\"#" t)=. Also, providing a numerical prefix argument to
|
||||||
|
electric pair allows you to insert multiple delimiters at once. Now, I
|
||||||
|
just need mode-aware electric pairs to replace [[https://github.com/emacs-evil/evil-surround][evil-surround]].
|
||||||
|
|
||||||
|
Do you use =query-replace=? Well, you can now use =M-s t= to swap =FROM= and
|
||||||
|
=TO= during a =query-replace= or =query-replace-regexp=. And the original
|
||||||
|
=M-s= is now =M-s M-s= or =M-s s=.
|
||||||
|
|
||||||
|
And do you like always having the line you’re editing to be at the
|
||||||
|
centre of your window? Activate =center-line-mode=.
|
||||||
|
|
||||||
|
Accidentally hit =M-q= (=fill-paragraph=) and you want to undo it? Or you
|
||||||
|
simply want to “unfill” your paragraph? Simply invoke =unfill-paragraph=
|
||||||
|
(which I will probably bind to =M-Q=).
|
||||||
|
|
||||||
|
*** TTY Improvements
|
||||||
|
One of my biggest gripes with Emacs in the terminal is how limited it
|
||||||
|
feels to its GUI version. Child frames, for instance, are one of TTY
|
||||||
|
Emacs’ limitations. Or, rather, /was/.
|
||||||
|
|
||||||
|
Starting from Emacs 31, TTY Emacs will support child frames, thanks to
|
||||||
|
=tty-child-frames=. Hurray for Posframe and Corfu users among many
|
||||||
|
others!
|
||||||
|
|
||||||
|
The option =xterm-mouse-mode= is also now enabled by default in
|
||||||
|
terminals that support it, i.e. allowing Emacs to access the OS’
|
||||||
|
clipboard and mouse events. This means you can now bind mouse events
|
||||||
|
to Emacs functions, but at the cost of now having to rely entirely on
|
||||||
|
Emacs to copy and paste text instead of relying on your terminal
|
||||||
|
emulator.
|
||||||
|
|
||||||
|
Also, you can now rename your TTY frames to =F<number>=, though it will
|
||||||
|
throw an error if that name is already taken.
|
||||||
|
|
||||||
|
*** Proper Support for User Lisp Directories
|
||||||
|
Emacs will natively support your =user-lisp/= directory in your Emacs
|
||||||
|
config directory (either your =$HOME/.emacs.d/= or your
|
||||||
|
=$HOME/.config/emacs/= directories) by recursively byte-compiling all of
|
||||||
|
its =.el= files and adding them to your =load-path=. It will also look for
|
||||||
|
autoloaded elements like it would for other packages, so no need to
|
||||||
|
explicitely require your =.el= files anymore!
|
||||||
|
|
||||||
|
This feature can be disabled with =(setq user-lisp-auto-scrape nil)=, or
|
||||||
|
you can change the directory =user-lisp-directory= points to if your
|
||||||
|
personal Elisp files are stored somewhere else.
|
||||||
|
|
||||||
|
Very nice, thanks Emacs devs!
|
||||||
|
|
||||||
|
*** Visual Customization and Improvements
|
||||||
|
**** Display
|
||||||
|
The new char-table =special-mirror-table= allows you to define
|
||||||
|
replacement characters for characters Emacs may have trouble
|
||||||
|
displaying. I think that, for most native English speakers, this
|
||||||
|
feature might be pretty useless, but it can be very interesting if you
|
||||||
|
deal with glyphs that are not ASCII, especially if they are part of
|
||||||
|
your writing system (Arabic, Mandarin, Cyrillic, etc…).
|
||||||
|
|
||||||
|
I, for one, am excited for this, as I use Emacs for most of my
|
||||||
|
worldbuilding projects, which include conlanging (creating languages),
|
||||||
|
and it requires me sometimes using characters Emacs has troubles
|
||||||
|
representing. I also have some glyphs in my Linux that render properly
|
||||||
|
with certain fonts that Emacs cannot render well with the font it
|
||||||
|
uses, therefore not making the config all that readable (I’m looking
|
||||||
|
at you, [[https://labs.phundrak.com/phundrak/nix-config/src/commit/5514d347c754ea17dd2a3ecb40fed6a62182c7ea/users/modules/desktop/waybar.nix#L59-L71][my Waybar configuration]], which I should remove since I already
|
||||||
|
don’t use Waybar any more).
|
||||||
|
|
||||||
|
On the topic of display customization, a few font-locks were deprecated:
|
||||||
|
- =font-lock-builtin-face=
|
||||||
|
- =font-lock-comment-delimiter-face=
|
||||||
|
- =font-lock-comment-face=
|
||||||
|
- =font-lock-constant-face=
|
||||||
|
- =font-lock-doc-face=
|
||||||
|
- =font-lock-doc-markup-face=
|
||||||
|
- =font-lock-function-name-face=
|
||||||
|
- =font-lock-keyword-face=
|
||||||
|
- =font-lock-negation-char-face=
|
||||||
|
- =font-lock-preprocessor-face=
|
||||||
|
- =font-lock-string-face=
|
||||||
|
- =font-lock-type-face=
|
||||||
|
- =font-lock-variable-name-face=
|
||||||
|
- =font-lock-warning-face=
|
||||||
|
|
||||||
|
They all have equivalents, you should customize them instead of these
|
||||||
|
deprecated font-locks.
|
||||||
|
|
||||||
|
**** Windows
|
||||||
|
We get some new commands for manipulating our window layouts!
|
||||||
|
- =C-x w t= and =C-x w r <left>/<right>= to rotate the window layout
|
||||||
|
- =C-x w o <left>/<right>= to rotate the windows within the current
|
||||||
|
layout
|
||||||
|
- =C-x w f <left>/<right>/<up>/<down>= to flip the layout
|
||||||
|
|
||||||
|
And now, you can also indicate to Emacs to kill buffers when their
|
||||||
|
window is closed, thanks to the =kill-buffer-quit-windows= option. But I
|
||||||
|
think I’ll personally stick to =kill-buffer-and-window=, this new option
|
||||||
|
seems a bit overkill for me. Still, quite nice to have!
|
||||||
|
|
||||||
|
Some commands and functions will create new windows on their own.
|
||||||
|
Emacs’ current behaviour is to split below if possible, and split
|
||||||
|
right otherwise. But now, =split-window-preferred-direction= introduces
|
||||||
|
three values:
|
||||||
|
- ='longest= :: somewhat similar to the current behaviour, and the new
|
||||||
|
default value: split below if your window is taller than it is wide
|
||||||
|
(Emacs’ preferred direction whenever possible), split right
|
||||||
|
otherwise. But what if both options are possible? Well, now, you can
|
||||||
|
set =split-width-threshold= (now 150 instead of 160) and
|
||||||
|
=split-height-threshold= to determine the correct behaviour to follow.
|
||||||
|
- ='vertical= :: always split below
|
||||||
|
- ='horizontal= :: always split right
|
||||||
|
|
||||||
|
The new command =other-window-backward= is also finally here! Ever
|
||||||
|
wanted to go back to your initial window after =C-x o= (=other-window=)?
|
||||||
|
Just use =C-x O= to go back!
|
||||||
|
|
||||||
|
**** Frames
|
||||||
|
Ever wondered how much time you’ve spent in a frame, like how you can
|
||||||
|
already determine it with =window-use-time= (which I just discovered
|
||||||
|
now)? With Emacs 31, you can now use the function (not command)
|
||||||
|
=frame-use-time=.
|
||||||
|
|
||||||
|
=delete-frame= now sends you to your most recently used frame, not the
|
||||||
|
first one in the list of frames. A small change, but a welcome change.
|
||||||
|
|
||||||
|
The new command =split-frame= now allows you to create a new frame and
|
||||||
|
send windows of your current frame to this new frame. The command
|
||||||
|
=merge-frames=, on the other hand, brings back a frame’s windows into
|
||||||
|
another before killing it. Very nice if you want to bring back a TTY
|
||||||
|
frame into another GUI frame, and /vice versa/.
|
||||||
|
|
||||||
|
Also, frames cloned with =clone-frame= (which I just discovered exists)
|
||||||
|
are now aware which frame they were cloned from, and if they were
|
||||||
|
undeleted with =undelete-frame= (how many commands will I learn exist
|
||||||
|
while writing this article?). And all frames have now a unique ID,
|
||||||
|
much easier to refer to a specific frame in your Elisp code, such as
|
||||||
|
with the new commands =select-frame-by-id= or =undelete-frame-by-id=.
|
||||||
|
|
||||||
|
**** Mode Line
|
||||||
|
The mode line can now collapse its minor modes when setting
|
||||||
|
=mode-line-collapse-minor-modes= to non-nil, useful when it becomes to
|
||||||
|
feel bloated. By default, it’s =nil=, so it won’t change its default
|
||||||
|
behaviour. It also became much easier to customize, using
|
||||||
|
=mode-line-modes-delimiters= to change or remove the existing
|
||||||
|
delimiters. Writing new mode line themes is about to get a lot easier!
|
||||||
|
|
||||||
|
But what if you don’t want to see the mode line? Well, hide it with
|
||||||
|
=mode-line-invisible-mode=, and enjoy your distraction-free Emacs!
|
||||||
|
|
||||||
|
**** Tabs
|
||||||
|
When tabs were introduced in Emacs, I didn’t really see the point
|
||||||
|
initially, until I realized they’re somewhat similar to sub-frames
|
||||||
|
without actually creating new frames. Very nice if, like me, you
|
||||||
|
prefer to have a single frame despite working on several projects with
|
||||||
|
the same Emacs instance. But an issue I often encounter (might be a
|
||||||
|
skill issue on my part) is that they sometimes become quite bloated,
|
||||||
|
crossing over multiple projects, at which point I decide to create
|
||||||
|
another tab and restore one specific project to that tab, recreating
|
||||||
|
my window layout with the buffers I want. That’s a tad tedious.
|
||||||
|
|
||||||
|
Well now, you can invoke the command =split-tab= to clone your current
|
||||||
|
tab to a new one and keep your windows! And of course, it comes with
|
||||||
|
=merge-tabs=, in case you’re finally done with this specific issue your
|
||||||
|
tab was for, and you want to go back to the project’s general tab. And
|
||||||
|
in case you have a lot of tabs opened, =tab-bar-truncate= when set to
|
||||||
|
non-nil will now truncate your tabs list, instead of squishing them
|
||||||
|
together and avoid any ugly text wrapping.
|
||||||
|
|
||||||
|
The use-case =tab-line-mode= is, however, a bit more mysterious for me,
|
||||||
|
but I guess it makes sense when you come from editors like VS Code and
|
||||||
|
are used to see all your open files as tabs (not Emacs tabs, but more
|
||||||
|
what I expected tabs to be when they were first announced). And now,
|
||||||
|
you can use =tab-line-define-keys= and set it to =nil= to avoid
|
||||||
|
=tab-line-mode= redefine =C-x <left>/<right>= switch between the visual
|
||||||
|
tabs and go back to Emacs’ vanilla behaviour. You can also move your
|
||||||
|
tab’s position among your tabs in =tab-line-mode= with the new commands
|
||||||
|
=tab-line-move-tab-forward= and =tab-line-move-tab-backward=, which are
|
||||||
|
bount to =C-x M-<right>/<left>=. And you can also set
|
||||||
|
=tab-line-exclude-buffers= to exclude known buffers from the tabs, such
|
||||||
|
as =*scratch*= or =i-dont-want-my-boss-to-see-this-when-he-walks-by.txt=.
|
||||||
|
In fact, you can even have even more powerful filtering using
|
||||||
|
=tab-line-tabs-window-buffers-filter-function=. And using the option
|
||||||
|
=tab-line-close-modified-button-show=, you can see the close button
|
||||||
|
visually warning you the buffer has been modified but not saved. Nice.
|
||||||
|
|
||||||
|
Something I just learned is that you can close tabs with your mouse’s
|
||||||
|
middle click. But what if you made a mistake, clicked on the wrong
|
||||||
|
tab, and realized your mistake before releasing the button? Until
|
||||||
|
Emacs 30, that’s too late. Since Emacs 31, the tab will be deleted
|
||||||
|
once you release the button, so you can still move the mouse and
|
||||||
|
release the button either on the correct tab, or outside the tabs area
|
||||||
|
if you don’t want to close anything.
|
||||||
|
|
||||||
|
*** Completion Improvements
|
||||||
|
The =*Completions*= buffer can now be much faster, updating as you
|
||||||
|
write, given the =eager-update= completion property is non-nil. And if
|
||||||
|
you don’t like the default value of the property, you can override it
|
||||||
|
with =completion-category-overrides=. And you can force the
|
||||||
|
autocompletion to update eagerly with =(setq completion-eager-update t)=
|
||||||
|
(or any value that is non-nil, but why not just use =t=?), but that can
|
||||||
|
slow Emacs down; I turned it off on my ThinkPad X220 and its
|
||||||
|
Intel Core i5-2540M (yes, I still use it), but on for my main desktop
|
||||||
|
computer with its AMD Ryzen 7 9800X3D. I should upgrade my X220’s CPU
|
||||||
|
sometime. But fortunately, the =*Completions*= buffer still got a
|
||||||
|
performance upgrade, especially when many candidates exist, though
|
||||||
|
with one caveat (see below in this chapter).
|
||||||
|
|
||||||
|
You can also now separate what the up/down keys do from the left/write
|
||||||
|
keys when in the minibuffer! If you set the
|
||||||
|
=minibuffer-visible-completions= option to ='up-down=, you can now have
|
||||||
|
the up/down keys select different suggestions in the =*Completions*=
|
||||||
|
buffer, while the left/write keys moves your cursor in the minibuffer.
|
||||||
|
Similarly, the =M-<up>= and =M-<down>= keys now allow you to select
|
||||||
|
candidates in the =*Completions*= buffer, whether your completion is in
|
||||||
|
the minibuffer on in-buffer. And in all cases, =RET= now chooses the
|
||||||
|
completion you selected.
|
||||||
|
|
||||||
|
If you want to customize how the completion candidates are displayed,
|
||||||
|
you can now use =completions-format=: set it to ='vertical=, selecting the
|
||||||
|
next candidates means selecting the one below the one currently
|
||||||
|
selected, wrapping to the net column when you reached the bottom. But
|
||||||
|
setting it to ='horizontal= will keep the old behaviour intact,
|
||||||
|
selecting the next option right of your current selection when using
|
||||||
|
=M-<down>=. But be careful, setting =completions-format= to ='vertical= will
|
||||||
|
undo the improvements the =*Completions*= buffer received. Not an option
|
||||||
|
for my ThinkPad.
|
||||||
|
|
||||||
|
By the way, your selection is now consistent even if the =*Completions*=
|
||||||
|
buffer updates! It’s frustrating when you started selecting something,
|
||||||
|
but for some reason, something triggered a completions update, and now
|
||||||
|
you have to move again to what you were about to select.
|
||||||
|
|
||||||
|
*** Minibuffer Improvements
|
||||||
|
How many times have I tried to do something, only for Emacs to not do
|
||||||
|
what I wanted because the minibuffer was active but not actively
|
||||||
|
selected? Well now, =minibuffer-nonselected-mode= will warn you when you
|
||||||
|
should probably pay attention to the minibuffer, as it’s waiting for
|
||||||
|
your input. Especially useful when you /think/ it’s selected, but it’s
|
||||||
|
actually not.
|
||||||
|
|
||||||
|
*** Mouse Improvements
|
||||||
|
When selecting text with your mouse and invoking =context-menu-mode=,
|
||||||
|
you can now select =Send to...= to send your text selection, or even the
|
||||||
|
current file, to external applications!
|
||||||
|
|
||||||
|
*** Built-in Package Updates
|
||||||
|
**** Org Mode Updated to 9.8
|
||||||
|
You may already have Org Mode 9.8 if you don’t use Emacs’ builtin
|
||||||
|
package, but this new version comes with some nice new features, such
|
||||||
|
as a new babel backend for C#, customizable images alignment, fixed
|
||||||
|
and better LaTeX table export, and so on.
|
||||||
|
|
||||||
|
**** Project
|
||||||
|
No need for calling =M-x project-any-command M-x find-file= any more!
|
||||||
|
You can now call =project-root-find-file= instead. And no need for =M-x
|
||||||
|
project-any-command M-x customize-dirlocals=, you can use
|
||||||
|
=project-customize-dirlocals= instead.
|
||||||
|
|
||||||
|
The new command =project-find-matching-buffer= can also be useful when
|
||||||
|
switching, for instance, git worktrees of the same repository, or
|
||||||
|
simply repositories with a similar structure. You can customize its
|
||||||
|
behaviour with =project-find-matching-buffer-function=.
|
||||||
|
|
||||||
|
You can also only save a project’s files with =M-x
|
||||||
|
project-save-some-buffers= or =C-x p C-x s=, similarly to projectile’s
|
||||||
|
=projectile-save-project-buffers=.
|
||||||
|
|
||||||
|
**** Tree-sitter
|
||||||
|
The new option =treesit-enabled-modes= will enable all known tree-sitter
|
||||||
|
modes by default when set to =t=, or only the tree-sitter based modes in
|
||||||
|
the list given to it, such as =(setopt treesit-enabled-modes
|
||||||
|
'(c-ts-mode nix-ts-mode uiua-ts-mode)=. It may change
|
||||||
|
=major-mode-remap-alist= based on =treesit-major-mode-remap-alist= if
|
||||||
|
needed.
|
||||||
|
|
||||||
|
The user option =treesit-auto-install-grammar= is one step to replace
|
||||||
|
[[https://github.com/renzmann/treesit-auto][treesit-auto]], with =treesit-extra-load-path= being a list of directories
|
||||||
|
where grammars are installed. If you install a grammar with
|
||||||
|
=treesit-auto-install-grammar=, it will be installed in the first
|
||||||
|
directory. =treesit-language-source-alist= now supports keywords such as
|
||||||
|
=:commit=, in case the default commit selected doesn’t match what you
|
||||||
|
want (a bug you want to avoid, or which you may consider a feature).
|
||||||
|
|
||||||
|
By the way, discoverability of things to natively do with tree-sitter
|
||||||
|
has become better! Use =treesit-cycle-sexp-thing= to explore the
|
||||||
|
navigation commands you can call.
|
||||||
|
|
||||||
|
You can also use =treesit-language-remap-alist= to make Emacs language A
|
||||||
|
is language B, which would allow you to use B’s parser for A.
|
||||||
|
Especially useful if you know B is a superset of A, like Typescript is
|
||||||
|
a superset of JavaScript.
|
||||||
|
|
||||||
|
Tree-sitter also now properly supports lists and comments and allows
|
||||||
|
you to act on them!
|
||||||
|
|
||||||
|
It also now allows for better support of multiple programming
|
||||||
|
languages, such as =treesit-simple-indent-modify-rules= which unifies
|
||||||
|
across languages indentation rules,
|
||||||
|
=treesit-aggregated-simple-imenu-settings= for Imenu setup for multiple
|
||||||
|
languages, and =treesit-aggregated-outline-predicate= which indirectly
|
||||||
|
allows for =outline-minor-mode= for multiple languages. That’ll be quite
|
||||||
|
enjoyable when I’ll work on Vue files, with HTML, Typescript, and LESS
|
||||||
|
code all in the same file. Speaking of indentation, keep an eye on
|
||||||
|
=treesit-simple-indent-add-rules= and
|
||||||
|
=treesit-simple-indent-override-rules=.
|
||||||
|
|
||||||
|
***** Language Specifics
|
||||||
|
Doxygen is now supported by =c-ts-mode= and =java-ts-mode= if enabling
|
||||||
|
=c-ts-mode-enable-doxygen= and =java-ts-mode-enable-doxygen= respectively.
|
||||||
|
|
||||||
|
=go-ts-mode= now has unit test
|
||||||
|
support with a few new commands like =go-ts-mode-test-function-at-point=
|
||||||
|
which does exactly what you think it does,
|
||||||
|
|
||||||
|
=php-ts-mode= had a lot of work done: it now requires =mhtml-ts-mode=
|
||||||
|
instead of =js-ts-mode=, =css-ts-mode= and =html-ts-mode= directly, and it
|
||||||
|
now benefits greatly from the multilingual improvements I talked about
|
||||||
|
earlier.
|
||||||
|
|
||||||
|
=rust-ts-mode= now fontifies number suffixes as types (like =10_u32=) when
|
||||||
|
=rust-ts-mode-fontify-number-suffix-as-type= is non-nil.
|
||||||
|
|
||||||
|
*** Eshell
|
||||||
|
Eshell also got some improvements: =eshell-clear= is now a better
|
||||||
|
behaved =eshell/clear= alternative, while =eshell-execute-file= went from
|
||||||
|
function to command.
|
||||||
|
|
||||||
|
You can also set the stderr of =eshell-command= and =eshell-execute-file=.
|
||||||
|
|
||||||
|
The syntax of Eshell also got an upgrade: the =for= command can now loop
|
||||||
|
over integer ranges, such as =1..10= (first number included, last
|
||||||
|
excluded), and you can also use =else= in =if {condition} {true-command}
|
||||||
|
else {false-command}= (=else= remains optional). You can also now chain
|
||||||
|
=else if=, as the =false-command= can be its own if/else statement.
|
||||||
|
|
||||||
|
The history search got an improvement, with the ability to search with
|
||||||
|
regular expressions with the two new =eshell-isearch-backward-regexp=
|
||||||
|
and =eshell-isearch-forward-regexp=, or =M-r= for the backward search
|
||||||
|
while =M-s= is now freed.
|
||||||
|
|
||||||
|
You can also set inter-session history off by setting
|
||||||
|
=eshell-history-isearch= to nil (the default value), which will limit
|
||||||
|
isearch to the Eshell’s buffer content only. If set to =t=, it will
|
||||||
|
search in the input history only, and if set to ='dwim=, it will search
|
||||||
|
in the input history only if the point is after the last prompt.
|
||||||
|
|
||||||
|
*** A Few Additional Goodies
|
||||||
|
|
||||||
|
=emacs-lisp-mode= now supports semantic highlight when
|
||||||
|
=elisp-fontify-semantically= is non-nil.
|
||||||
|
|
||||||
|
A few years back, =setopt= came into Emacs as a better alternative to
|
||||||
|
=setq= for most variables declared with =defcustom=. Well, now,
|
||||||
|
=describe-variable= will tell you if a variable should be set with
|
||||||
|
=setopt=, or if other methods is alright.
|
||||||
|
|
||||||
|
Something my ThinkPad will be thankful of, and a lot of laptops also
|
||||||
|
will be, is the new option =native-comp-async-on-battery-power=: if set
|
||||||
|
to nil, Emacs will not attempt to use the asynchronous native
|
||||||
|
compilations if your laptop is running only on its battery. The
|
||||||
|
libraries that need compilation will be a tad slower, but you won’t
|
||||||
|
have to look for a power socket as soon as with Emacs 30. Especially
|
||||||
|
nice for those in the Northern Hemisphere who want to enjoy the
|
||||||
|
upcoming summer! Or if you’re one of the weirdos like me who enjoy the
|
||||||
|
cold more than the heat.
|
||||||
|
|
||||||
|
Something I’ll really appreciate is setting
|
||||||
|
=show-paren-not-in-comments-or-strings= to stop Emacs from highlighting
|
||||||
|
parenthesis and brackets in comments or strings.
|
||||||
|
|
||||||
|
Sending empty strings to =emacsclient= is now possible! Until Emacs 30,
|
||||||
|
passing an empty string was the same as not passing one it at all.
|
||||||
|
Now, Emacs will understand it!
|
||||||
|
|
||||||
|
Emacs now supports Unicode 17.0, in case you wanted to write something
|
||||||
|
with the Sidetic, Tolong Siki, Beria Erfe, or Tai Yo scripts. I was
|
||||||
|
prepared to make an emoji joke, but surprisingly, Unicode 17 did not
|
||||||
|
add any. Speaking of scripts, Emacs now support new input methods,
|
||||||
|
such =greek-polytonic= for polytonic and archaic Greek, but also quite a
|
||||||
|
few input methods for Northern Iroquoian languages, Burmese-based
|
||||||
|
languages, and Syriac languages. My inner amateur linguist approves
|
||||||
|
immensely!
|
||||||
|
|
||||||
|
Emacs now dislikes insecure protocols: its Network Security Manager
|
||||||
|
will warn you about TLS 1.1 and DHE and RSA key exchange.
|
||||||
** f.el v0.21.0 released! :dev:emacs:release:
|
** f.el v0.21.0 released! :dev:emacs:release:
|
||||||
:PROPERTIES:
|
:PROPERTIES:
|
||||||
:EXPORT_FILE_NAME: f-el-v0-21-0-released
|
:EXPORT_FILE_NAME: f-el-v0-21-0-released
|
||||||
|
|||||||
Reference in New Issue
Block a user