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 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:
|
||||
:PROPERTIES:
|
||||
:EXPORT_FILE_NAME: f-el-v0-21-0-released
|
||||
|
||||
Reference in New Issue
Block a user