summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore31
-rw-r--r--README2
-rw-r--r--admin/coccinelle/process.cocci110
-rwxr-xr-xbuild-aux/gitlog-to-changelog2
-rwxr-xr-xbuild-aux/install-sh8
-rw-r--r--build-aux/ndk-build-helper-1.mk4
-rw-r--r--build-aux/ndk-build-helper-2.mk4
-rw-r--r--build-aux/ndk-build-helper.mk2
-rw-r--r--build-aux/ndk-module-extract.awk18
-rw-r--r--configure.ac43
-rw-r--r--cross/ndk-build/Makefile.in2
-rw-r--r--cross/ndk-build/ndk-resolve.mk1
-rw-r--r--doc/lispref/commands.texi19
-rw-r--r--doc/lispref/display.texi6
-rw-r--r--doc/misc/efaq.texi5
-rw-r--r--doc/misc/erc.texi2
-rw-r--r--doc/misc/eww.texi9
-rw-r--r--etc/NEWS3105
-rw-r--r--etc/NEWS.303145
-rw-r--r--etc/refcards/ru-refcard.tex2
-rw-r--r--exec/Makefile.in9
-rw-r--r--exec/README3
-rw-r--r--exec/configure.ac31
-rw-r--r--exec/exec.c14
-rw-r--r--exec/exec.h15
-rw-r--r--exec/exec1.c6
-rw-r--r--exec/loader-x86.s187
-rw-r--r--exec/loader-x86_64.s215
-rw-r--r--exec/mipsel-user.h14
-rw-r--r--exec/trace.c880
-rw-r--r--java/Makefile.in10
-rw-r--r--lib/acl-internal.c15
-rw-r--r--lib/gnulib.mk.in17
-rw-r--r--lib/stddef.in.h5
-rw-r--r--lib/stdio.in.h145
-rw-r--r--lib/strftime.c395
-rw-r--r--lib/strnlen.c16
-rw-r--r--lib/time-internal.h21
-rw-r--r--lib/time.in.h17
-rw-r--r--lib/time_rz.c44
-rw-r--r--lib/timespec-add.c30
-rw-r--r--lib/timespec-sub.c29
-rw-r--r--lisp/autoinsert.el6
-rw-r--r--lisp/completion-preview.el144
-rw-r--r--lisp/cus-edit.el2
-rw-r--r--lisp/doc-view.el7
-rw-r--r--lisp/emacs-lisp/checkdoc.el1
-rw-r--r--lisp/erc/erc.el4
-rw-r--r--lisp/eshell/esh-proc.el50
-rw-r--r--lisp/eshell/eshell.el88
-rw-r--r--lisp/gnus/canlock.el2
-rw-r--r--lisp/international/quail.el15
-rw-r--r--lisp/international/utf7.el1
-rw-r--r--lisp/net/eww.el9
-rw-r--r--lisp/net/hmac-md5.el1
-rw-r--r--lisp/net/shr.el233
-rw-r--r--lisp/org/ob-processing.el1
-rw-r--r--lisp/org/org-feed.el1
-rw-r--r--lisp/progmodes/grep.el16
-rw-r--r--lisp/progmodes/lua-ts-mode.el8
-rw-r--r--lisp/progmodes/perl-mode.el9
-rw-r--r--lisp/progmodes/python.el10
-rw-r--r--lisp/subr.el10
-rw-r--r--lisp/textmodes/reftex-global.el23
-rw-r--r--lisp/textmodes/reftex-index.el21
-rw-r--r--lisp/textmodes/reftex-sel.el18
-rw-r--r--lisp/textmodes/reftex-toc.el18
-rw-r--r--lisp/textmodes/reftex.el6
-rw-r--r--lisp/textmodes/rst.el1
-rw-r--r--lisp/touch-screen.el120
-rw-r--r--lisp/version.el23
-rw-r--r--lisp/whitespace.el16
-rw-r--r--m4/canonicalize.m48
-rw-r--r--m4/gnulib-comp.m41
-rw-r--r--m4/largefile.m46
-rw-r--r--m4/ndk-build.m478
-rw-r--r--m4/nstrftime.m46
-rw-r--r--m4/printf-posix-rpl.m426
-rw-r--r--m4/readlinkat.m44
-rw-r--r--m4/stddef_h.m49
-rw-r--r--m4/stdio_h.m48
-rw-r--r--m4/time_h.m43
-rw-r--r--m4/time_rz.m43
-rw-r--r--m4/tm_gmtoff.m426
-rw-r--r--m4/wchar_t.m425
-rw-r--r--msdos/sed2v2.inp2
-rw-r--r--msdos/sedlibmk.inp1
-rw-r--r--nt/README.W322
-rw-r--r--src/emacs-module.h.in17
-rw-r--r--src/emacs.c29
-rw-r--r--src/fns.c23
-rw-r--r--src/lisp.h6
-rw-r--r--src/lread.c6
-rw-r--r--src/marker.c44
-rw-r--r--src/module-env-30.h3
-rw-r--r--src/module-env-31.h3
-rw-r--r--src/pdumper.c17
-rw-r--r--src/puresize.h2
-rw-r--r--src/sysdep.c14
-rw-r--r--src/xdisp.c37
-rw-r--r--test/infra/Dockerfile.emba1
-rw-r--r--test/infra/Makefile.in17
-rw-r--r--test/infra/gitlab-ci.yml2
-rw-r--r--test/infra/test-jobs.yml6
-rw-r--r--test/lisp/completion-preview-tests.el145
-rw-r--r--test/lisp/eshell/eshell-tests.el21
-rw-r--r--test/lisp/net/rfc2104-tests.el2
-rw-r--r--test/lisp/net/shr-tests.el15
-rw-r--r--test/lisp/whitespace-tests.el15
-rwxr-xr-xtest/manual/indent/perl.perl4
-rw-r--r--test/src/fns-tests.el20
111 files changed, 5753 insertions, 4406 deletions
diff --git a/.gitignore b/.gitignore
index eb76ff330b8..833e88a3aa7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,14 +18,15 @@
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
-# Currently we assume only Git 1.7.1 (April 2010) or later, so this
-# file does not rely on "**" in patterns. The "**" feature was added
-# in Git 1.8.2 (March 2013).
-
-
-# Personal customization.
-.dir-locals-2.el
-.no-advice-on-failure
+# Ignore all dot-files except for those under version control.
+.*
+!.clang-format
+!.clangd
+!.dir-locals.el
+!.gitattributes
+!.gitignore
+!.gitlab-ci.yml
+!.mailmap
# Built by 'autogen.sh'.
/aclocal.m4
@@ -119,8 +120,8 @@ cross/ndk-build/ndk-build.mk
cross/ndk-build/*.o
# Lisp-level sources built by 'make'.
-*cus-load.el
-*loaddefs.el
+lisp/**/*cus-load.el
+lisp/**/*loaddefs.el
lisp/cedet/semantic/bovine/c-by.el
lisp/cedet/semantic/bovine/make-by.el
lisp/cedet/semantic/bovine/scm-by.el
@@ -319,7 +320,6 @@ gnustmp*
*.orig
*.swp
*~
-.#*
\#*\#
ChangeLog
[0-9]*.patch
@@ -368,17 +368,8 @@ lib-src/seccomp-filter-exec.pfc
# Ignore directory made by admin/make-manuals.
/manual/
-# Ignore Finder files on MacOS.
-.DS_Store
-
-# Ignore a directory used by dap-mode.
-.vscode
/test/gmp.h
-# GDB history
-.gdb_history
-_gdb_history
-
# Files ignored in exec/.
exec/aclocal.m4
exec/config.guess
diff --git a/README b/README
index 54da3587754..2fc84ca6620 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ Copyright (C) 2001-2024 Free Software Foundation, Inc.
See the end of the file for license conditions.
-This directory tree holds version 30.0.60 of GNU Emacs, the extensible,
+This directory tree holds version 31.0.50 of GNU Emacs, the extensible,
customizable, self-documenting real-time display editor.
The file INSTALL in this directory says how to build and install GNU
diff --git a/admin/coccinelle/process.cocci b/admin/coccinelle/process.cocci
deleted file mode 100644
index bf295ab7b6f..00000000000
--- a/admin/coccinelle/process.cocci
+++ /dev/null
@@ -1,110 +0,0 @@
-// Change direct access to Lisp_Object fields of struct Lisp_Process to PVAR.
-@@
-struct Lisp_Process *P;
-Lisp_Object O;
-@@
-(
-- P->tty_name
-+ PVAR (P, tty_name)
-|
-- P->name
-+ PVAR (P, name)
-|
-- P->command
-+ PVAR (P, command)
-|
-- P->filter
-+ PVAR (P, filter)
-|
-- P->sentinel
-+ PVAR (P, sentinel)
-|
-- P->log
-+ PVAR (P, log)
-|
-- P->buffer
-+ PVAR (P, buffer)
-|
-- P->childp
-+ PVAR (P, childp)
-|
-- P->plist
-+ PVAR (P, plist)
-|
-- P->type
-+ PVAR (P, type)
-|
-- P->mark
-+ PVAR (P, mark)
-|
-- P->status
-+ PVAR (P, status)
-|
-- P->decode_coding_system
-+ PVAR (P, decode_coding_system)
-|
-- P->decoding_buf
-+ PVAR (P, decoding_buf)
-|
-- P->encode_coding_system
-+ PVAR (P, encode_coding_system)
-|
-- P->encoding_buf
-+ PVAR (P, encoding_buf)
-|
-- P->write_queue
-+ PVAR (P, write_queue)
-
-|
-
-- XPROCESS (O)->tty_name
-+ PVAR (XPROCESS (O), tty_name)
-|
-- XPROCESS (O)->name
-+ PVAR (XPROCESS (O), name)
-|
-- XPROCESS (O)->command
-+ PVAR (XPROCESS (O), command)
-|
-- XPROCESS (O)->filter
-+ PVAR (XPROCESS (O), filter)
-|
-- XPROCESS (O)->sentinel
-+ PVAR (XPROCESS (O), sentinel)
-|
-- XPROCESS (O)->log
-+ PVAR (XPROCESS (O), log)
-|
-- XPROCESS (O)->buffer
-+ PVAR (XPROCESS (O), buffer)
-|
-- XPROCESS (O)->childp
-+ PVAR (XPROCESS (O), childp)
-|
-- XPROCESS (O)->plist
-+ PVAR (XPROCESS (O), plist)
-|
-- XPROCESS (O)->type
-+ PVAR (XPROCESS (O), type)
-|
-- XPROCESS (O)->mark
-+ PVAR (XPROCESS (O), mark)
-|
-- XPROCESS (O)->status
-+ PVAR (XPROCESS (O), status)
-|
-- XPROCESS (O)->decode_coding_system
-+ PVAR (XPROCESS (O), decode_coding_system)
-|
-- XPROCESS (O)->decoding_buf
-+ PVAR (XPROCESS (O), decoding_buf)
-|
-- XPROCESS (O)->encode_coding_system
-+ PVAR (XPROCESS (O), encode_coding_system)
-|
-- XPROCESS (O)->encoding_buf
-+ PVAR (XPROCESS (O), encoding_buf)
-|
-- XPROCESS (O)->write_queue
-+ PVAR (XPROCESS (O), write_queue)
-)
diff --git a/build-aux/gitlog-to-changelog b/build-aux/gitlog-to-changelog
index 16a9405a7cb..49e7ef95cef 100755
--- a/build-aux/gitlog-to-changelog
+++ b/build-aux/gitlog-to-changelog
@@ -495,7 +495,7 @@ sub git_dir_option($)
# Complain about any unused entry in the --amend=F specified file.
my $fail = 0;
- foreach my $sha (keys %$amend_code)
+ foreach my $sha (sort keys %$amend_code)
{
warn "$ME:$amend_file: unused entry: $sha\n";
$fail = 1;
diff --git a/build-aux/install-sh b/build-aux/install-sh
index 7c56c9c0151..b1d7a6f67f6 100755
--- a/build-aux/install-sh
+++ b/build-aux/install-sh
@@ -1,7 +1,7 @@
#!/bin/sh
# install - install a program, script, or datafile
-scriptversion=2023-11-23.18; # UTC
+scriptversion=2024-06-19.01; # UTC
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
@@ -170,7 +170,7 @@ while test $# -ne 0; do
-T) is_target_a_directory=never;;
- --version) echo "$0 $scriptversion"; exit $?;;
+ --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;;
--) shift
break;;
@@ -345,7 +345,7 @@ do
' 0
# Because "mkdir -p" follows existing symlinks and we likely work
- # directly in world-writeable /tmp, make sure that the '$tmpdir'
+ # directly in world-writable /tmp, make sure that the '$tmpdir'
# directory is successfully created first before we actually test
# 'mkdir -p'.
if (umask $mkdir_umask &&
@@ -353,7 +353,7 @@ do
exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
then
if test -z "$dir_arg" || {
- # Check for POSIX incompatibilities with -m.
+ # Check for POSIX incompatibility with -m.
# HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
# other-writable bit of parent directory when it shouldn't.
# FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
diff --git a/build-aux/ndk-build-helper-1.mk b/build-aux/ndk-build-helper-1.mk
index 985f7cddfaf..4420eb433f4 100644
--- a/build-aux/ndk-build-helper-1.mk
+++ b/build-aux/ndk-build-helper-1.mk
@@ -35,7 +35,7 @@ NDK_CXX_FLAG_$(LOCAL_MODULE) :=
$(info Building $(build_kind))
$(info $(LOCAL_MODULE))
-$(info $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI))))
+$(info $(addprefix $(LOCAL_PATH:%/=%)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI))))
ifeq ($(filter-out lib%,$(LOCAL_MODULE)),)
NDK_SO_NAMES = $(LOCAL_MODULE)_emacs.so
@@ -106,7 +106,7 @@ endif
$(info $(foreach dir,$(NDK_INCLUDES),-I$(dir)))
$(info $(LOCAL_EXPORT_CFLAGS))
-$(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR)/,$(NDK_A_NAMES))) -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname)))
+$(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR:%/=%)/,$(NDK_A_NAMES))) -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname)))
$(info $(NDK_SO_NAMES))
$(info $(NDK_CXX_FLAG_$(LOCAL_MODULE)))
$(info End)
diff --git a/build-aux/ndk-build-helper-2.mk b/build-aux/ndk-build-helper-2.mk
index 697740b3d45..b8d22f5952d 100644
--- a/build-aux/ndk-build-helper-2.mk
+++ b/build-aux/ndk-build-helper-2.mk
@@ -29,7 +29,7 @@ NDK_CXX_FLAG_$(LOCAL_MODULE) :=
$(info Building $(build_kind))
$(info $(LOCAL_MODULE))
-$(info $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI))))
+$(info $(addprefix $(LOCAL_PATH:%/=%)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI))))
ifeq ($(filter-out lib%,$(LOCAL_MODULE)),)
NDK_A_NAMES = $(LOCAL_MODULE).a
@@ -99,7 +99,7 @@ endif
$(info $(foreach dir,$(NDK_INCLUDES),-I$(dir)))
$(info $(LOCAL_EXPORT_CFLAGS))
-$(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR)/,$(NDK_A_NAMES))) $(and $(NDK_SO_NAMES), -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname))))
+$(info $(LOCAL_EXPORT_LDFLAGS) $(abspath $(addprefix $(NDK_BUILD_DIR:%/=%)/,$(NDK_A_NAMES))) $(and $(NDK_SO_NAMES), -L$(abspath $(NDK_BUILD_DIR)) $(foreach soname,$(NDK_SO_NAMES),-l:$(soname))))
$(info $(NDK_A_NAMES) $(NDK_SO_NAMES))
$(info $(NDK_CXX_FLAG_$(LOCAL_MODULE)))
$(info End)
diff --git a/build-aux/ndk-build-helper.mk b/build-aux/ndk-build-helper.mk
index 521e1b24ce3..b4746dd623f 100644
--- a/build-aux/ndk-build-helper.mk
+++ b/build-aux/ndk-build-helper.mk
@@ -42,7 +42,7 @@ EMACS_SRCDIR := $(absname $(EMACS_SRCDIR))
# my-dir is a function that returns the Android module directory. If
# no Android.mk has been loaded, use ANDROID_MODULE_DIRECTORY.
-my-dir = $(or $(and $(local-makefile),$(dir $(local-makefile))),$(ANDROID_MODULE_DIRECTORY))
+my-dir = $(patsubst %/,%,$(or $(and $(local-makefile),$(dir $(local-makefile))),$(ANDROID_MODULE_DIRECTORY)))
# Return all Android.mk files under the first arg.
all-makefiles-under = $(wildcard $(1)/*/Android.mk)
diff --git a/build-aux/ndk-module-extract.awk b/build-aux/ndk-module-extract.awk
index 6ff30973d67..b57bf74001d 100644
--- a/build-aux/ndk-module-extract.awk
+++ b/build-aux/ndk-module-extract.awk
@@ -55,14 +55,14 @@
/^End$/ {
if (name == MODULE && (kind == "shared" || kind == "static"))
{
- printf "module_name=%s\n", name
- printf "module_kind=%s\n", kind
- printf "module_src=\"%s\"\n", src
- printf "module_includes=\"%s\"\n", includes
- printf "module_cflags=\"%s\"\n", cflags
- printf "module_ldflags=\"%s\"\n", ldflags
- printf "module_target=\"%s\"\n", target
- printf "module_cxx_deps=\"%s\"\n", cxx_deps
+ printf "module_name=%s;", name
+ printf "module_kind=%s;", kind
+ printf "module_src=\"%s\";", src
+ printf "module_includes=\"%s\";", includes
+ printf "module_cflags=\"%s\";", cflags
+ printf "module_ldflags=\"%s\";", ldflags
+ printf "module_target=\"%s\";", target
+ printf "module_cxx_deps=\"%s\";", cxx_deps
}
src = ""
@@ -83,6 +83,6 @@
imports = ""
# Strip off leading whitespace.
gsub (/^[ \t]+/, "", makefile_imports)
- printf "module_imports=\"%s\"\n", makefile_imports
+ printf "module_imports=\"%s\";", makefile_imports
makefile_imports = ""
}
diff --git a/configure.ac b/configure.ac
index 3ee332521f6..909f5786c9a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
AC_PREREQ([2.65])
dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el.
-AC_INIT([GNU Emacs], [30.0.60], [bug-gnu-emacs@gnu.org], [],
+AC_INIT([GNU Emacs], [31.0.50], [bug-gnu-emacs@gnu.org], [],
[https://www.gnu.org/software/emacs/])
if test "$XCONFIGURE" = "android"; then
@@ -197,11 +197,17 @@ AS_IF([test "$XCONFIGURE" = "android"],[
AC_MSG_NOTICE([configuring in `exec'])
+ # Derive a name for a cache file for this configure script from the
+ # current, if specified.
+ exec_cache_file=
+ AS_CASE([$cache_file], [/dev/null | ""], [],
+ [[[\\/]* | ?:[\\/]*]], [exec_cache_file="--cache-file=$cache_file.2"],
+ [*], [exec_cache_file="--cache-file=../$cache_file.2"])
OLDCWD=`pwd`
cd exec
$CONFIG_SHELL $emacs_srcdir/exec/configure \
--host=$host "CC=$CC" "LD=$CC" "AS=$CC" \
- "AR=$AR" "CFLAGS=$CFLAGS"
+ "AR=$AR" "CFLAGS=$CFLAGS" $exec_cache_file
emacs_val=$?
cd $OLDCWD
@@ -1263,6 +1269,11 @@ packages targeting Android 2.2.])])
emacs_val="--enable-check-lisp-object-type=$enable_check_lisp_object_type"
passthrough="$passthrough $emacs_val"
+ # And derive a name for the recursive configure invocation's cache
+ # file if one should be specified for this.
+ AS_IF([test -n "$cache_file" && test "$cache_file" != "/dev/null"],
+ [passthrough="$passthrough --cache-file=$cache_file.1"])
+
AS_IF([test "x$with_mailutils" = "xyes"], [emacs_use_mailutils=yes])
AC_SUBST([emacs_use_mailutils])
@@ -1600,6 +1611,30 @@ AC_DEFUN([gl_TYPE_OFF64_T],
[HAVE_OFF64_T=1
AC_SUBST([HAVE_OFF64_T])])
+# `strnlen' cannot accept nlen greater than the size of the object S
+# on Android 2.2 and earlier.
+m4_define([ORIGINAL_AC_FUNC_STRNLEN], m4_defn([AC_FUNC_STRNLEN]))
+AC_DEFUN([AC_FUNC_STRNLEN], [
+AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_CACHE_CHECK([for strnlen capable of accepting large limits],
+ [emacs_cv_func_strnlen_working],
+ [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [[
+ volatile size_t (*strnlen_pointer) (const char *s, size_t) = &strnlen;
+ if ((*strnlen_pointer) ("", -1) != 0)
+ return 1;
+ return 0;
+]])],[emacs_cv_func_strnlen_working=yes],
+ [emacs_cv_func_strnlen_working=no],
+ [# Guess no on Android 21 and earlier, yes elsewhere.
+ AS_IF([test -n "$ANDROID_SDK" && test "$ANDROID_SDK" -lt 22],
+ [emacs_cv_func_strnlen_working=no],
+ [emacs_cv_func_strnlen_working='guessing yes'])])])
+AS_IF([test "$emacs_cv_func_strnlen_working" != "no"],
+ [ORIGINAL_AC_FUNC_STRNLEN],
+ [ac_cv_func_strnlen_working=no
+ AC_LIBOBJ([strnlen])])])
+
# Initialize gnulib right after choosing the compiler.
dnl Amongst other things, this sets AR and ARFLAGS.
gl_EARLY
@@ -5059,12 +5094,14 @@ AC_SUBST_FILE([module_env_snippet_27])
AC_SUBST_FILE([module_env_snippet_28])
AC_SUBST_FILE([module_env_snippet_29])
AC_SUBST_FILE([module_env_snippet_30])
+AC_SUBST_FILE([module_env_snippet_31])
module_env_snippet_25="$srcdir/src/module-env-25.h"
module_env_snippet_26="$srcdir/src/module-env-26.h"
module_env_snippet_27="$srcdir/src/module-env-27.h"
module_env_snippet_28="$srcdir/src/module-env-28.h"
module_env_snippet_29="$srcdir/src/module-env-29.h"
module_env_snippet_30="$srcdir/src/module-env-30.h"
+module_env_snippet_31="$srcdir/src/module-env-31.h"
emacs_major_version=`AS_ECHO([$PACKAGE_VERSION]) | sed 's/[[.]].*//'`
AC_SUBST([emacs_major_version])
@@ -5925,7 +5962,7 @@ LIBS="$LIB_PTHREAD $LIB_MATH $LIBS"
AC_CHECK_FUNCS([accept4 fchdir gethostname \
getrusage get_current_dir_name \
lrand48 random rint tcdrain trunc \
-select getpagesize setlocale newlocale \
+select getpagesize newlocale \
getrlimit setrlimit shutdown \
pthread_sigmask strsignal setitimer \
sendto recvfrom getsockname getifaddrs freeifaddrs \
diff --git a/cross/ndk-build/Makefile.in b/cross/ndk-build/Makefile.in
index 0970a765b45..b5eac9bd089 100644
--- a/cross/ndk-build/Makefile.in
+++ b/cross/ndk-build/Makefile.in
@@ -79,7 +79,7 @@ local-makefile = $$(NDK_LAST_MAKEFILE)
# my-dir is a function that returns the Android module directory. If
# no Android.mk has been loaded, use the directory of the Makefile
# being included.
-my-dir = $$(or $$(and $$(local-makefile),$$(dir $$(local-makefile))),$(dir $(1)))
+my-dir = $$(patsubst %/,%,$$(or $$(and $$(local-makefile),$$(dir $$(local-makefile))),$(dir $(1))))
# Return all Android.mk files under the first arg.
all-makefiles-under = $$(wildcard $$(1)/*/Android.mk)
diff --git a/cross/ndk-build/ndk-resolve.mk b/cross/ndk-build/ndk-resolve.mk
index 896c29f7f90..289e3a8a003 100644
--- a/cross/ndk-build/ndk-resolve.mk
+++ b/cross/ndk-build/ndk-resolve.mk
@@ -50,7 +50,6 @@ ifeq ($$(filter $(1)$(and $(3),whole),$$(NDK_RESOLVED_CFLAGS_$(LOCAL_MODULE))),)
# Always mark this module's cflags as having been resolved, even if
# this is a whole library.
NDK_RESOLVED_CFLAGS_$(LOCAL_MODULE) += $(1)
-
NDK_CFLAGS_$(LOCAL_MODULE) += $(NDK_LOCAL_EXPORT_CFLAGS_$(1))
NDK_CFLAGS_$(LOCAL_MODULE) += $(addprefix -I,$(NDK_LOCAL_EXPORT_C_INCLUDES_$(1)))
endif
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index a9da6c75367..6ddb70a3b9f 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2128,7 +2128,7 @@ motion and mouse motion.
However, some commands bound to
@code{down-mouse-1}--@code{mouse-drag-region}, for example--either
conflict with defined touch screen gestures (such as ``long-press to
-drag''), or with user expectations for touch input, and shouldn't
+drag''), or with user expectations for touch input, and should not
subject the touch sequence to simple translation. If a command whose
name contains the property (@pxref{Symbol Properties})
@code{ignored-mouse-command} is encountered or there is no command
@@ -2146,13 +2146,20 @@ compromise for packages which assume @code{mouse-drag-region} has
already set point to the location of any mouse click and selected the
window where it took place.
-To prevent unwanted @code{mouse-1} events arriving after a mouse menu
-is dismissed (@pxref{Mouse Menus}), Emacs also avoids simple
+To prevent unwanted @code{mouse-1} events from arriving after a mouse
+menu is dismissed (@pxref{Mouse Menus}), Emacs also disables simple
translation if @code{down-mouse-1} is bound to a keymap, making it a
prefix key. In lieu of simple translation, it translates the closing
-@code{touchscreen-end} to a @code{down-mouse-1} event with the
-starting position of the touch sequence, consequently displaying
-the mouse menu.
+@code{touchscreen-end} to a @code{down-mouse-1} event with the starting
+position of the touch sequence, consequently displaying the mouse menu.
+
+@vindex @code{touch-screen-simple-mouse-conversion}
+Simple conversion will be enabled without regard to the existence of
+command or menu bindings if the variable
+@code{touch-screen-simple-mouse-conversion} is bound or set to a
+non-@code{nil} value, as, for example, it may be by a caller of
+@code{read-key} expecting to receive @code{mouse-movement} and
+@code{drag-mouse-1} events.
@cindex @code{mouse-1-menu-command}, a symbol property
Since certain commands are also bound to @code{down-mouse-1} for the
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 55885b7438d..6e4b727a2bd 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5214,8 +5214,10 @@ specifications.
This convenience function can be used to get a specific display
property, no matter whether the @code{display} property is a vector, a
list or a simple property. This is like @code{get-text-property}
-(@pxref{Examining Properties}), but works on the @code{display}
-property only.
+(@pxref{Examining Properties}), but works on the @code{display} property
+only. For properties with a single value (e.g.@: @code{height}, this
+returns the value itself; for properties with a list of values (e.g.@:
+@code{slice}), this returns the list of values.
@var{position} is the position in the buffer or string to examine, and
@var{prop} is the @code{display} property to return. The optional
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index f56888aac3f..73bc2442678 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -2932,9 +2932,8 @@ For instance, to write all these things to
@file{~/.emacs.d/aux/}:
@lisp
-(when (>= emacs-major-version 28)
- (setq lock-file-name-transforms
- '(("\\`/.*/\\([^/]+\\)\\'" "~/.emacs.d/aux/\\1" t))))
+(setq lock-file-name-transforms
+ '(("\\`/.*/\\([^/]+\\)\\'" "~/.emacs.d/aux/\\1" t)))
(setq auto-save-file-name-transforms
'(("\\`/.*/\\([^/]+\\)\\'" "~/.emacs.d/aux/\\1" t)))
(setq backup-directory-alist
diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi
index 858e1ba34dc..75138a9963f 100644
--- a/doc/misc/erc.texi
+++ b/doc/misc/erc.texi
@@ -2,7 +2,7 @@
@c %**start of header
@setfilename ../../info/erc.info
@settitle ERC Manual
-@set ERCVER 5.6.0.30.1
+@set ERCVER 5.6.1
@set ERCDIST as distributed with Emacs @value{EMACSVER}
@include docstyle.texi
@syncodeindex fn cp
diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi
index eec6b3c3299..e0c6b7d610b 100644
--- a/doc/misc/eww.texi
+++ b/doc/misc/eww.texi
@@ -373,6 +373,15 @@ customizing @code{shr-blocked-images}.
@code{shr-inhibit-images}. If this variable is @code{nil}, display
the ``ALT'' text of images instead.
+@vindex shr-sliced-image-height
+ To make scrolling up/down past images more intuititve, EWW splits
+large images into several rows. This way, you can scroll individually
+past each slice, instead of jumping past the entire image. EWW slices
+images that take up more than @code{shr-sliced-image-height} of the
+height of the window they are displayed in. For example, a value of 0.7
+means that images are allowed to take up 70% of the height of the window
+before being sliced.
+
@vindex shr-color-visible-distance-min
@vindex shr-color-visible-luminance-min
@cindex Contrast
diff --git a/etc/NEWS b/etc/NEWS
index 31d69ddabab..3d2b86cfb6a 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -6,10 +6,10 @@ See the end of the file for license conditions.
Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'.
If possible, use 'M-x report-emacs-bug'.
-This file is about changes in Emacs version 30.
+This file is about changes in Emacs version 31.
See file HISTORY for a list of GNU Emacs versions and release dates.
-See files NEWS.29, NEWS.28, ..., NEWS.18, and NEWS.1-17 for changes
+See files NEWS.30, NEWS.29, ..., NEWS.18, and NEWS.1-17 for changes
in older Emacs versions.
You can narrow news to a specific version by calling 'view-emacs-news'
@@ -22,3102 +22,71 @@ When you add a new item, use the appropriate mark if you are sure it
applies, and please also update docstrings as needed.
-* Installation Changes in Emacs 30.1
-
----
-** Native compilation is now enabled by default.
-'configure' will enable the Emacs Lisp native compiler, so long as
-libgccjit is present and functional on the system. To disable native
-compilation, configure Emacs with the option:
-
- ./configure --with-native-compilation=no
-
-+++
-** Emacs has been ported to the Android operating system.
-This requires Emacs to be compiled on another computer. The Android
-NDK, SDK, and a suitable Java compiler must also be installed.
-
-See the file "java/INSTALL" for more details.
-
----
-** Native JSON support is now always available; libjansson is no longer used.
-No external library is required. The '--with-json' configure option has
-been removed. 'json-available-p' now always returns non-nil and is only
-kept for compatibility.
-
----
-** Emacs now defaults to the ossaudio library for sound on NetBSD and OpenBSD.
-Previously, configure used ALSA libraries if installed on the system
-when configured '--with-sound=yes' (which is the default), with fallback
-to libossaudio. The libossaudio library included with the base system
-is now used even if ALSA is found to avoid relying on external packages
-and to resolve potential incompatibilities between GNU/Linux and *BSD
-versions of ALSA. Use '--with-sound=alsa' to build with ALSA on these
-operating systems instead.
+* Installation Changes in Emacs 31.1
-* Startup Changes in Emacs 30.1
-
----
-** On GNU/Linux, Emacs is now the default application for 'org-protocol'.
-Org mode provides a way to quickly capture bookmarks, notes, and links
-using 'emacsclient':
-
- emacsclient "org-protocol://store-link?url=URL&title=TITLE"
-
-Previously, users had to manually configure their GNU/Linux desktop
-environment to open 'org-protocol' links in Emacs. These links should
-now open in Emacs automatically, as the "emacsclient.desktop" file now
-arranges for Emacs to be the default application for the 'org-protocol'
-URI scheme. See the Org mode manual, Info node "(org) Protocols" for
-more details.
-
-+++
-** New variable lets Lisp code read emacsclient arguments.
-When '--eval' is passed to emacsclient and Emacs is evaluating each
-argument, the new variable 'server-eval-args-left' is set to those
-arguments not yet evaluated. It can be used by Lisp code to 'pop'
-arguments and process them by the function called in the '--eval'
-expression, which is useful when those arguments contain arbitrary
-characters that otherwise might require elaborate and error-prone
-escaping (to protect them from the shell).
+* Startup Changes in Emacs 31.1
-* Incompatible Changes in Emacs 30.1
-
----
-** Tree-Sitter modes are now declared as submodes of the non-TS modes.
-In order to help the use of those Tree-Sitter modes, they are now
-declared to have the corresponding non-Tree-Sitter mode as an
-additional parent.
-This way, things like ".dir-locals.el" settings, and YASnippet
-collections of snippets automatically apply to the new Tree-Sitter modes.
-
-Note that those modes still do not inherit from the non-TS mode, so
-configuration settings installed via mode hooks are not affected.
-
----
-** Mouse wheel events should now always be 'wheel-up/down/left/right'.
-At those places where the old 'mouse-4/5/6/7' events could still occur
-(i.e., X11 input in the absence of XInput2, and 'xterm-mouse-mode'),
-we remap them to the corresponding 'wheel-up/down/left/right' event,
-according to the new user option 'mouse-wheel-buttons'.
-The old variables 'mouse-wheel-up-event', 'mouse-wheel-down-event',
-'mouse-wheel-left-event', and 'mouse-wheel-right-event' are thereby
-obsolete.
-
-+++
-** 'completion-auto-help' now affects 'icomplete-in-buffer'.
-Previously, 'completion-auto-help' mostly affected only minibuffer
-completion. Now, if 'completion-auto-help' has the value 'lazy', then
-Icomplete's in-buffer display of possible completions will only appear
-after the 'completion-at-point' command has been invoked twice, and if
-'completion-auto-help' is nil, then Icomplete's in-buffer display is
-completely suppressed. Thus, if you use 'icomplete-in-buffer', ensure
-'completion-auto-help' is not customized to 'lazy' or nil.
-
-+++
-** The "*Completions*" buffer now always accompanies 'icomplete-in-buffer'.
-Previously, it was not consistent whether the "*Completions*" buffer would
-appear when using 'icomplete-in-buffer'. Now the "*Completions*" buffer
-and Icomplete's in-buffer display of possible completions always
-appear together. If you would prefer to see only Icomplete's
-in-buffer display, and not the "*Completions*" buffer, you can add this
-to your init file:
-
- (advice-add 'completion-at-point :after #'minibuffer-hide-completions)
-
----
-** The default process filter was rewritten in native code.
-The round-trip through the Lisp function
-'internal-default-process-filter' is skipped when the process filter is
-the default one. It is reimplemented in native code, reducing GC churn.
-To undo this change, set 'fast-read-process-output' to nil.
-
-+++
-** The Network Security Manager now warns about 3DES by default.
-This cypher is no longer recommended owing to a major vulnerability
-disclosed in 2016, and its small 112 bit key size. Emacs now warns
-about its use also when 'network-security-level' is set to 'medium'
-(the default). See 'network-security-protocol-checks'.
-
----
-** The Network Security Manager now warns about <2048 bits in DH key exchange.
-Emacs used to warn for Diffie-Hellman key exchanges with prime numbers
-smaller than 1024 bits. Since more servers now support it, this
-number has been bumped to 2048 bits.
-
-+++
-** URL now never sends user email addresses in HTTP requests.
-Emacs never sent email addresses by default, but it used to be
-possible to customize 'url-privacy-level' so that the users email
-address was sent along in HTTP requests. This feature has now been
-removed, as it was considered more dangerous than useful. RFC 9110
-(§ 10.1.2) also recommends against it. The user option
-'url-personal-mail-address' is now also obsolete.
-
-To send an email address in the header of individual HTTP requests,
-see the variable 'url-request-extra-headers'.
+* Changes in Emacs 31.1
-* Changes in Emacs 30.1
-
----
-** Emacs now supports Unicode Standard version 15.1.
-
-+++
-** Emacs now comes with Org v9.7.
-See the file "etc/ORG-NEWS" for user-visible changes in Org.
-
-+++
-** Improved support for touchscreen devices.
-On systems that understand them (at present X, Android, PGTK, and
-MS-Windows), many touch screen gestures are now implemented and
-translated into mouse or gesture events, and support for tapping tool
-bar buttons and opening menus has been added. Countless packages, such
-as Dired and Custom, have been adjusted to better understand touch
-screen input.
-
-+++
-** Support for styled underline face attributes.
-These are implemented as new values of the 'style' attribute in a face
-underline specification, 'double-line', 'dots', and 'dashes', and are
-available on GUI systems. If your terminal's termcap or terminfo
-database entry defines the 'Su' or 'Smulx' capability, Emacs will also
-emit the prescribed escape sequence to render faces with such styles on
-TTY frames.
-
----
-** Support for underline colors on TTY frames.
-Colors specified in the underline face will now also be displayed on TTY
-frames on terminals that support the 'Su' or 'Smulx' capabilities.
-
-+++
-** Modeline elements can now be right-aligned.
-Anything following the symbol 'mode-line-format-right-align' in
-'mode-line-format' will be right-aligned. Exactly where it is
-right-aligned to is controlled by the new user option
-'mode-line-right-align-edge'.
-
----
-** X selection requests are now handled much faster and asynchronously.
-This means it should be less necessary to disable the likes of
-'select-active-regions' when Emacs is running over a slow network
-connection.
-
----
-** Emacs now updates invisible frames that are made visible by a compositor.
-If an invisible or an iconified frame is shown to the user by the
-compositing manager, Emacs will now redisplay such a frame even though
-'frame-visible-p' returns nil or 'icon' for it. This can happen, for
-example, as part of preview for iconified frames.
-
-+++
-** Most file notification backends detect unmounting of a watched filesystem.
-The only exception is w32notify.
-
-+++
-** The ':map' property of images is now recomputed when image is transformed.
-Images with clickable maps now work as expected after you run commands
-such as 'image-increase-size', 'image-decrease-size', 'image-rotate',
-'image-flip-horizontally', and 'image-flip-vertically'.
-Set the new user option 'image-recompute-map-p' to nil to prevent Emacs
-from recomputing image maps.
-
-** Minibuffer and Completions
-
-+++
-*** New commands 'previous-line-completion' and 'next-line-completion'.
-Bound to '<up>' and '<down>' arrow keys, respectively, they navigate
-the "*Completions*" buffer vertically by lines, wrapping at the
-top/bottom when 'completion-auto-wrap' is non-nil.
-
-+++
-*** New user option 'minibuffer-visible-completions'.
-When customized to non-nil, you can use arrow keys in the minibuffer
-to navigate the completions displayed in the "*Completions*" window.
-Typing 'RET' selects the highlighted candidate. 'C-g' hides the
-completions window. When the completions window is not visible,
-then all these keys have their usual meaning in the minibuffer.
-This option is supported for in-buffer completion as well.
-
----
-*** Selected completion candidates are deselected on typing.
-When you type at the minibuffer prompt, the current completion
-candidate will be un-highlighted, and point in the "*Completions*" window
-will be moved off that candidate. 'minibuffer-choose-completion'
-('M-RET') will still choose a previously-selected completion
-candidate, but the new command 'minibuffer-choose-completion-or-exit'
-(bound to 'RET' by 'minibuffer-visible-completions') will exit with
-the minibuffer contents instead. This deselection behavior can be
-controlled with the new user option 'completion-auto-deselect', which
-is t by default.
-
-+++
-*** New value 'historical' for user option 'completions-sort'.
-When 'completions-sort' is set to 'historical', completion candidates
-will be first sorted alphabetically, and then re-sorted by their order
-in the minibuffer history, with more recent candidates appearing first.
-
-+++
-*** 'completion-category-overrides' supports more metadata.
-The new supported completion properties are 'cycle-sort-function',
-'display-sort-function', 'annotation-function', 'affixation-function',
-and 'group-function'. You can now customize them for any category in
-'completion-category-overrides' that will override the properties
-defined in completion metadata.
-
-+++
-*** 'completion-extra-properties' supports more metadata.
-The new supported completion properties are 'category',
-'group-function', 'display-sort-function', and 'cycle-sort-function'.
-
-** Windows
-
-+++
-*** New command 'toggle-window-dedicated'.
-This makes it easy to interactively mark a specific window as
-dedicated, so it won't be reused by 'display-buffer'. This can be
-useful for complicated window setups. It is bound to 'C-x w d'
-globally.
-
-+++
-*** "d" in the mode line now indicates that the window is dedicated.
-Windows have always been able to be dedicated to a specific buffer;
-see 'window-dedicated-p'. Now the mode line indicates the dedicated
-status of a window, with "d" appearing in the mode line if a window is
-dedicated and "D" if the window is strongly dedicated. This indicator
-appears before the buffer name, and after the buffer modification and
-remote buffer indicators (usually "---" together).
-
-+++
-*** New action alist entry 'some-window' for 'display-buffer'.
-It specifies which window 'display-buffer-use-some-window' should prefer.
-For example, when 'display-buffer-base-action' is customized to
-'(nil . ((some-window . mru)))', then a buffer will be displayed
-in the same most recently used window from consecutive calls of
-'display-buffer' (in a configuration with more than two windows).
-
-+++
-*** New action alist entry 'category' for 'display-buffer'.
-If the caller of 'display-buffer' passes '(category . symbol)'
-in its 'action' argument, you can match the displayed buffer
-by adding '(category . symbol)' to the condition part of
-'display-buffer-alist' entries.
-
-+++
-*** New action alist entry 'post-command-select-window' for 'display-buffer'.
-It specifies whether the window of the displayed buffer should be
-selected or deselected at the end of executing the current command.
-
-+++
-*** New variable 'window-restore-killed-buffer-windows'.
-It specifies how 'set-window-configuration' and 'window-state-put'
-should proceed with windows whose buffer was killed after the
-corresponding configuration or state was recorded.
-
----
-*** New variable 'window-point-context-set-function'.
-It can be used to set a context for window point in all windows by
-'window-point-context-set' before calling 'current-window-configuration'
-and 'window-state-get'. Then later another new variable
-'window-point-context-use-function' can be used by
-'window-point-context-use' after 'set-window-configuration' and
-'window-state-put' to restore positions of window points
-according to the context stored in a window parameter.
-
-+++
-*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
-'set-window-cursor-type' sets a per-window cursor type, and
-'window-cursor-type' queries this setting for a given window. Windows
-are always created with a 'window-cursor-type' of t, which means to
-consult the variable 'cursor-type' as before.
-
----
-*** The user option 'display-comint-buffer-action' is now obsolete.
-You can use a '(category . comint)' condition in 'display-buffer-alist'
-to match buffers displayed by comint-related commands. Another
-user option 'display-tex-shell-buffer-action' is obsolete too
-for which you can use '(category . tex-shell)'.
-
-** Tool bars
-
-+++
-*** Tool bars can now be placed on the bottom on more systems.
-The 'tool-bar-position' frame parameter can be set to 'bottom' on all
-window systems other than macOS and GNUstep (Nextstep).
-
-+++
-*** New global minor mode 'modifier-bar-mode'.
-When this minor mode is enabled, the tool bar displays buttons
-representing modifier keys. Clicking on these buttons applies the
-corresponding modifiers to the next input event.
-
-+++
-*** New user option 'tool-bar-always-show-default'.
-When non-nil, the tool bar at the top of a frame does not show buffer
-local customization of the tool bar. The default value is nil.
-
-** Tab Bars and Tab Lines
-
----
-*** New user option 'tab-bar-select-restore-context'.
-It uses 'window-point-context-set' to save contexts where
-window points were located before switching away from the tab,
-and 'window-point-context-use' to restore positions of window
-points after switching back to that tab.
-
----
-*** New user option 'tab-bar-select-restore-windows'.
-It defines what to do with windows whose buffer was killed since the tab
-was last selected. By default it displays a placeholder buffer
-with the name " *Old buffer <name>*" that provides information about
-the name of the killed buffer that was displayed in that window.
-
----
-*** New user option 'tab-bar-tab-name-format-functions'.
-It can be used to add, remove and reorder functions that change the
-appearance of every tab on the tab bar.
-
----
-*** New user option 'tab-line-tabs-buffer-group-function'.
-It provides two choices to group tab buffers by major mode and by
-project name.
-
----
-*** New hook 'tab-bar-tab-post-select-functions'.
-
----
-*** New keymap 'tab-bar-mode-map'.
-By default it contains a keybinding 'C-TAB' to switch tabs, but only
-when 'C-TAB' is not bound globally. You can unbind it if it conflicts
-with 'C-TAB' in other modes.
-
----
-*** New keymap 'tab-line-mode-map'.
-By default it contains keybindings for switching tabs: 'C-x <left>',
-'C-x <right>', 'C-x C-<left>', 'C-x C-<right>'. You can unbind them if
-you want to use these keys for the commands 'previous-buffer' and
-'next-buffer'.
-
----
-*** Default list of tabs is changed to support a fixed order.
-This means that 'tab-line-tabs-fixed-window-buffers', the new default
-tabs function, is like the previous 'tab-line-tabs-window-buffers' where
-both of them show only buffers that were previously displayed in the
-window. But the difference is that the new function always keeps the
-original order of buffers on the tab line, even after switching between
-these buffers. You can drag the tabs and release at a new position
-to manually reorder the buffers on the tab line.
-
----
-*** Buffers on group tabs are now sorted alphabetically.
-This will keep the fixed order of tabs, even after switching between
-them.
-
-** Help
-
-+++
-*** New command 'help-find-source'.
-Switch to a buffer visiting the source of what is being described in
-"*Help*". It is bound to 'C-h 4 s' globally.
-
----
-*** New user option 'describe-bindings-outline-rules'.
-This user option controls outline visibility in the output buffer of
-'describe-bindings' when 'describe-bindings-outline' is non-nil.
-
----
-*** 'describe-function' shows the function inferred type when available.
-For native compiled Lisp functions, 'describe-function' prints (after
-the signature) the automatically inferred function type as well.
-
----
-*** 'describe-function' now shows the type of the function object.
-The text used to say things like "car is a built-in function" whereas it
-now says "car is a primitive-function" where "primitive-function" is the
-the name of the symbol returned by 'cl-type-of'. You can click on those
-words to get information about that type.
-
----
-*** 'C-h m' ('describe-mode') uses outlining by default.
-Set 'describe-mode-outline' to nil to get back the old behavior.
-
----
-*** 'C-h k' ('describe-key') shows Unicode name.
-For keybindings which produce single characters via translation or input
-methods, 'C-h k' now shows the Unicode name of the produced character in
-addition to the character itself, e.g.
-
-'C-h k C-x 8 E' =>
-
- € 'EURO SIGN' (translated from C-x 8 E)
-
----
-*** 'C-h b' ('describe-bindings') shows Unicode names.
-For keybindings which produce single characters via translation (such as
-those using the 'C-x 8' or 'A-' prefix, or 'dead-acute', 'dead-grave',
-etc), the Unicode names will now be shown in addition to the character
-itself, i.e.
-
- A-! ¡ INVERTED EXCLAMATION MARK
- A-$ ¤ CURRENCY SIGN
-
-and so on.
-
-+++
-*** Multi-character key echo now ends with a suggestion to use Help.
-Customize 'echo-keystrokes-help' to nil to prevent that.
-
-** Customize
-
-+++
-*** New command 'customize-dirlocals'.
-This command pops up a buffer to edit the settings in ".dir-locals.el".
-
----
-*** New command 'customize-toggle-option'.
-This command can toggle boolean options for the duration of a session.
-
-+++
-*** New prefix argument for modifying directory-local variables.
-The commands 'add-dir-local-variable', 'delete-dir-local-variable' and
-'copy-file-locals-to-dir-locals' now take an optional prefix argument,
-to enter the file name where you want to modify directory-local
-variables.
-
-+++
-*** New user option 'safe-local-variable-directories'.
-This user option names directories in which Emacs will treat all
-directory-local variables as safe.
-
-+++
-** CL Print
-
-+++
-*** There is a new chapter in the CL manual documenting cl-print.el.
-See the Info node "(cl) Printing".
-
-+++
-*** You can expand the "..." truncation everywhere.
-The code that allowed "..." to be expanded in the "*Backtrace*" buffer
-should now work anywhere the data is generated by 'cl-print'.
-
-+++
-*** The 'backtrace-ellipsis' button is replaced by 'cl-print-ellipsis'.
-
-+++
-*** hash-tables' contents can be expanded via the ellipsis.
-
-+++
-*** Modes can control the expansion via 'cl-print-expand-ellipsis-function'.
-
-+++
-*** New setting 'raw' for 'cl-print-compiled'.
-This setting causes byte-compiled functions to be printed in full by
-'prin1'. A button on this output can be activated to disassemble the
-function.
-
-** Miscellaneous
-
-+++
-*** New command 'kill-matching-buffers-no-ask'.
-This works like 'kill-matching-buffers', but without asking for
-confirmation.
-
-+++
-*** 'recover-file' can show diffs between auto save file and current file.
-When answering the prompt with "diff" or "=", it now shows the diffs
-between the auto save file and the current file.
-
-+++
-*** 'read-passwd' can toggle the visibility of passwords.
-Use 'TAB' in the minibuffer to show or hide the password.
-Alternatively, click the new show-password icon on the mode-line with
-'mouse-1' to toggle the visibility of the password.
-
-*** 'advice-remove' is now an interactive command.
-When called interactively, 'advice-remove' now prompts for an advised
-function to the advice to remove.
-
----
-*** New user option 'uniquify-dirname-transform'.
-This can be used to customize how buffer names are uniquified, by
-making arbitrary transforms on the buffer's directory name (whose
-components are used to uniquify buffer names when they clash). You
-can use this to distinguish between buffers visiting files with the
-same base name that belong to different projects by using the provided
-transform function 'project-uniquify-dirname-transform'.
-
-+++
-*** New user option 'remote-file-name-inhibit-delete-by-moving-to-trash'.
-When non-nil, this option suppresses moving remote files to the local
-trash when deleting. Default is nil.
-
----
-*** New user option 'remote-file-name-inhibit-auto-save'.
-If this user option is non-nil, 'auto-save-mode' will not auto-save
-remote buffers. The default is nil.
-
-+++
-*** New user option 'remote-file-name-access-timeout'.
-If a positive number, this option limits the call of 'access-file'
-for remote files to that number of seconds. Default is nil.
-
-+++
-*** New user option 'yes-or-no-prompt'.
-This allows the user to customize the prompt that is appended by
-'yes-or-no-p' when asking questions. The default value is
-"(yes or no) ".
-
----
-*** New user option 'menu-bar-close-window'.
-When non-nil, selecting "Close" from the "File" menu or clicking
-"Close" in the tool bar will result in the current window being
-deleted, if possible. The default is nil, and these gestures kill the
-buffer shown in the current window, but don't delete the window.
-
----
-*** New face 'display-time-date-and-time'.
-This is used for displaying the time and date components of
-'display-time-mode'.
-
----
-*** New face 'appt-notification' for 'appt-display-mode-line'.
-It can be used to customize the look of the appointment notification
-displayed on the mode line when 'appt-display-mode-line' is non-nil.
-
----
-*** New icon images for general use.
-Several symbolic icons have been added to "etc/images/symbols",
-including plus, minus, check-mark, star, etc.
-
----
-*** Emacs now recognizes shebang lines that pass '-S'/'--split-string' to 'env'.
-When visiting a script that invokes 'env -S INTERPRETER ARGS...' in
-its shebang line, Emacs will now skip over 'env -S' and deduce the
-major mode based on the interpreter after 'env -S'.
-
-*** 'insert-directory-program' is now a user option.
-On *BSD and macOS systems, this user option now defaults to the "gls"
-executable, if it exists. This should remove the need to change its
-value when installing GNU coreutils using something like ports or
-Homebrew.
-
-+++
-*** 'write-region-inhibit-fsync' now defaults to t in interactive mode.
-This is the default in batch mode since Emacs 24.
-
----
-*** The default value of 'read-process-output-max' was increased to 65536.
-
-+++
-*** 'url-gateway-broken-resolution' is now obsolete.
-This option was intended for use on SunOS 4.x and Ultrix systems,
-neither of which have been supported by Emacs since version 23.1.
-The user option 'url-gateway-nslookup-program' and the command
-'url-gateway-nslookup-host' are consequently also obsolete.
+* Editing Changes in Emacs 31.1
-* Editing Changes in Emacs 30.1
-
-+++
-** New minor mode 'visual-wrap-prefix-mode'.
-When enabled, continuation lines displayed for a wrapped long line
-will receive a 'wrap-prefix' automatically computed from the line's
-surrounding context, such that continuation lines are indented on
-display as if they were filled with 'M-q' or similar. Unlike 'M-q',
-the indentation only happens on display, and doesn't change the buffer
-text in any way. The global minor mode
-'global-visual-wrap-prefix-mode' enables this minor mode in all
-buffers.
-
-(This minor mode is the 'adaptive-wrap' ELPA package renamed and
-lightly edited for inclusion in Emacs.)
-
-+++
-** New global minor mode 'kill-ring-deindent-mode'.
-When enabled, text being saved to the kill ring will be de-indented by
-the column number at its start. For example, saving the entire
-function call within an indented block:
-
-foo ()
-{
- long_function_with_several_arguments (argument_1_compute (),
- argument_2_compute (),
- argument_3_compute ());
-}
-
-will save this to the kill ring:
-
-long_function_with_several_arguments (argument_1_compute (),
- argument_2_compute (),
- argument_3_compute ())
-
-This omits the two columns of extra indentation that would otherwise be
-copied from the second and third lines and saved to the kill ring.
-
----
-** New command 'replace-regexp-as-diff'.
-It reads a regexp to search for and a string to replace with, then
-displays a buffer with replacements as diffs. After reviewing the
-changes in the output buffer you can apply the replacements as
-a patch to the current file buffer. There are also new commands
-'multi-file-replace-regexp-as-diff' that shows as diffs replacements
-in a list of specified files, and 'dired-do-replace-regexp-as-diff'
-that shows as diffs replacements in the marked files in Dired.
-
-+++
-** New mode of prompting for register names and showing preview.
-The new user option 'register-use-preview' can be customized to the
-value t or insist to request a different user interface of prompting for
-register names and previewing the registers: Emacs will require
-confirmation for overwriting the value of a register, and will show
-the preview of registers without delay. You can also customize this
-new option to disable the preview completely.
-
-The default value of 'register-use-preview' preserves the behavior of
-Emacs 29 and before. See the Info node "(emacs) Registers" for more
-details about the new UI and its variants.
-
-+++
-** New advanced macro counter commands.
-New commands have been added to implement advanced macro counter
-functions.
-
-The commands 'C-x C-k C-r l' and 'C-x C-k C-r s' load and save the
-macro counter from and to a number register, respectively.
-
-The commands 'C-x C-k C-r a =', 'C-x C-k C-r a <', and 'C-x C-k C-r a >'
-compare the macro counter with the contents of a number register and
-increment the counter by an optional prefix if the comparison succeeds.
-
-The commands 'C-x C-k C-q =', 'C-x C-k C-q <', and 'C-x C-k C-q >'
-compare the macro counter with an optional prefix and terminate the
-macro if the comparison succeeds.
-
-+++
-** New mode 'kmacro-menu-mode' and new command 'list-keyboard-macros'.
-The new command 'list-keyboard-macros' is the keyboard-macro version
-of commands like 'list-buffers' and 'list-processes', creating a listing
-of the currently existing keyboards macros using the new mode
-'kmacro-menu-mode'. It allows rearranging the macros in the ring,
-duplicating them, deleting them, and editing their counters, formats,
-and keys.
-
----
-** On X, Emacs now supports input methods which perform "string conversion".
-This means an input method can now ask Emacs to delete text
-surrounding point and replace it with something else, as well as query
-Emacs for surrounding text. If your input method allows you to "undo"
-mistaken compositions, this will now work as well.
-
----
-** New user option 'duplicate-region-final-position'.
-It controls the placement of point and the region after duplicating a
-region with 'duplicate-dwim'.
-
-+++
-** New user option 'mouse-prefer-closest-glyph'.
-When enabled, clicking or dragging with the mouse will put the point
-or start the drag in front of the buffer position corresponding to the
-glyph with the closest X coordinate to the click or start of the drag.
-In other words, if the mouse pointer is in the right half of a glyph,
-point will be put after the buffer position corresponding to that glyph,
-whereas if the mouse pointer is in the left half of a glyph, point
-will be put in front the buffer position corresponding to that glyph.
-By default this is disabled.
-
----
-** New pre-defined values for 'electric-quote-chars'.
-The available customization options for 'electric-quote-chars' have been
-updated with common pairs of quotation characters, including "‘", "’",
-"“", "”", "«", "»", "‹", "›", "‚", "„", "「", "」", "『", and "』".
-The default is unchanged.
-
-+++
-** 'M-TAB' now invokes 'completion-at-point' in Text mode.
-By default, Text mode no longer binds 'M-TAB' to 'ispell-complete-word'.
-Instead, this mode arranges for 'completion-at-point', globally bound to
-'M-TAB', to perform word completion as well. You can have Text mode
-binding 'M-TAB' to 'ispell-complete-word' as it did in previous Emacs
-versions, or disable Ispell word completion in Text mode altogether, by
-customizing the new user option 'text-mode-ispell-word-completion'.
-
-** Internationalization
-
----
-*** Mode-line mnemonics for some coding-systems have changed.
-The mode-line mnemonic for 'utf-7' is now the lowercase 'u', to be
-consistent with the other encodings of this family.
-
-The mode-line mnemonic for 'koi8-u' is now 'У', U+0423 CYRILLIC
-CAPITAL LETTER U, to distinguish between this encoding and the
-UTF-8/UTF-16 family.
-
-If your terminal cannot display 'У', or if you want to get the old
-behavior back for any other reason, you can do that using the
-'coding-system-put' function. For example, the following restores the
-previous behavior of showing 'U' in the mode line for 'koi8-u':
-
- (coding-system-put 'koi8-u :mnemonic ?U)
-
----
-*** 'vietnamese-tcvn' is now a coding system alias for 'vietnamese-vscii'.
-VSCII-1 and TCVN-5712 are different names for the same character
-encoding. Therefore, the duplicate coding system definition has been
-dropped in favor of an alias.
-
-The mode-line mnemonic for 'vietnamese-vscii' and its aliases is the
-lowercase letter "v".
-
----
-*** Users in CJK locales can control width of some non-CJK characters.
-Some characters are considered by Unicode as "ambiguous" with respect
-to their display width: either "full-width" (i.e., taking 2 columns on
-display) or "narrow" (taking 1 column). The actual width depends on
-the fonts used for these characters by Emacs or (for text-mode frames)
-by the terminal emulator. Traditionally, font sets in CJK locales
-were set up so as to display these characters as full-width, and thus
-Emacs modified the char-width table in those locales to follow suit.
-Lately, the tendency is to display these characters as narrow. The
-new user option 'cjk-ambiguous-chars-are-wide' allows users to control
-whether Emacs considers these characters as full-width (the default)
-or narrow (if the variable is customized to the nil value).
-
-This setting affects the results of 'string-width' and similar
-functions in CJK locales.
-
----
-*** New input methods for the Urdu, Pashto, and Sindhi languages.
-These languages are spoken in Pakistan and Afghanistan.
-
----
-*** New input method "english-colemak".
-This input method supports the Colemak keyboard layout.
-
----
-*** Additional 'C-x 8' key translations for "æ" and "Æ".
-These characters can now be input with 'C-x 8 a e' and 'C-x 8 A E',
-respectively, in addition to the existing translations 'C-x 8 / e' and
-'C-x 8 / E'.
-
----
-*** New 'C-x 8' key translations for "low" quotes "„", and "‚".
-These can now be entered with 'C-x , "' and 'C-x , ''.
-
----
-*** New German language 'C-x 8' key translations for quotation marks.
-The characters "„", "“", and "”" can now be entered with 'C-x 8 v',
-'C-x 8 b' and 'C-x 8 n'. The single versions "‚", "‘", and "’" can now
-be entered with 'C-x 8 V', 'C-x 8 B' and 'C-x 8 N'. These characters
-are used for the official German quoting style. Using them requires
-activating German language support via 'iso-transl-set-language'.
-
----
-*** "latin-prefix" and "latin-postfix" quotation marks additions.
-These input methods can now produce single, double and "low" left and
-right quotation marks:
-
- "‘", "’", "“", "”", "„", and "‚"
+* Changes in Specialized Modes and Packages in Emacs 31.1
-by using "[", "]", and "," for "left", "right", and "low" respectively
-to modify "'" and """.
+** Whitespace
---
-*** "latin-prefix" and "latin-postfix" guillemets support.
-These input methods can now produce single guillemets "‹" and "›". For
-"latin-prefix" use "~~<" and "~~>", for "latin-postfix" use "<~" and
-">~". Double guillemets ("«" and "»") were already supported.
-
----
-*** New French language 'C-x 8' key translations for "‹" and "›".
-These characters can now be entered using 'C-x 8 ~ <' and 'C-x 8 ~ >',
-respectively, after activating French language support via
-'iso-transl-set-language'. Double guillemets were already supported via
-'C-x 8 <' and 'C-x 8 >'
-
----
-*** Additional 'C-x 8' key translation for Euro "€" currency symbol.
-This can now be entered using 'C-x 8 E' in addition to the existing
-'C-x 8 * E' translation.
-
-
-* Changes in Specialized Modes and Packages in Emacs 30.1
-
-** Outline mode
-
-+++
-*** New commands to show/hide outlines by regexp.
-'C-c / h' ('outline-hide-by-heading-regexp') asks for a regexp and then
-hides the body lines of all outlines whose heading lines match the
-regexp. 'C-c / s' ('outline-show-by-heading-regexp') does the inverse:
-it shows the bodies of outlines that matched a regexp.
-
-+++
-*** 'outline-minor-mode' is supported in tree-sitter major modes.
-It can be used in all tree-sitter major modes that set either the
-variable 'treesit-simple-imenu-settings' or 'treesit-outline-predicate'.
-
-** Info
-
----
-*** New user option 'Info-url-alist'.
-This user option associates manual names with URLs. It affects the
-'Info-goto-node-web' command. By default, associations for all
-Emacs-included manuals are set. Further associations can be added for
-arbitrary Info manuals.
-
----
-*** Emacs can now display Info manuals compressed with 'lzip'.
-This requires the 'lzip' program to be installed on your system.
-
-** GUD (Grand Unified Debugger)
-
-+++
-*** New user option 'gud-highlight-current-line'.
-When enabled, GUD will visually emphasize the line being executed upon
-pauses in the debuggee's execution, such as those occasioned by
-breakpoints being hit.
-
-+++
-*** New command 'lldb'.
-Run the LLDB debugger, analogous to the 'gud-gdb' command.
-
----
-*** Variable order and truncation can now be configured in 'gdb-many-windows'.
-The new user option 'gdb-locals-table-row-config' allows users to
-configure the order and max length of various properties in the local
-variables buffer when using 'gdb-many-windows'.
-
-By default, this user option is set to write the properties in the order:
-'name', 'type' and 'value', where the 'name' and 'type' are truncated to 20
-characters, and the 'value' is truncated according to the value of
-'gdb-locals-value-limit'.
-
-If you want to get back the old behavior, set the user option to the value
-
- (setopt gdb-locals-table-row-config
- `((type . 0) (name . 0) (value . ,gdb-locals-value-limit)))
-
-+++
-*** New user option 'gdb-display-io-buffer'.
-If this is nil, command 'gdb' will neither create nor display a separate
-buffer for the I/O of the program being debugged, but will instead
-redirect the program's interaction to the GDB execution buffer. The
-default is t, to preserve previous behavior.
-
-** Grep
-
-+++
-*** New user option 'grep-use-headings'.
-When non-nil, the output of Grep is split into sections, one for each
-file, instead of having file names prefixed to each line. It is
-equivalent to the '--heading' option of some tools such as 'git grep'
-and 'rg'. The headings are displayed using the new 'grep-heading' face.
-The default is nil.
-
-** Compilation mode
-
----
-*** The 'omake' matching rule is now disabled by default.
-This is because it partly acts by modifying other rules which may
-occasionally be surprising. It can be re-enabled by adding 'omake' to
-'compilation-error-regexp-alist'.
-
----
-*** Lua errors and stack traces are now recognized.
-Compilation mode now recognizes Lua language errors and stack traces.
-Every Lua error is recognized as a compilation error, and every Lua
-stack frame is recognized as a compilation info.
-
-** Project
-
-+++
-*** New user option 'project-mode-line'.
-When non-nil, display the name of the current project on the mode
-line. Clicking 'mouse-1' on the project name pops up the project
-menu. The default value is nil.
-
----
-*** New user option 'project-file-history-behavior'.
-Customizing it to 'relativize' makes commands like 'project-find-file'
-and 'project-find-dir' display previous history entries relative to
-the current project.
-
---
-*** New user option 'project-key-prompt-style'.
-The look of the key prompt in the project switcher has been changed
-slightly. To get the previous one, set this option to 'brackets'.
-
----
-*** Function 'project-try-vc' tries harder to find the responsible VCS.
-When 'project-vc-extra-root-markers' is non-nil, and causes a
-subdirectory project to be detected which is not a VCS root, Project now
-additionally traverses the parent directories until a VCS root is found
-(if any), so that the ignore rules for that repository are used, and
-the file listing's performance is still optimized.
-
-+++
-*** New commands 'project-any-command' and 'project-prefix-or-any-command'.
-The former is now bound to 'C-x p o' by default.
-The latter is designed primarily for use as a value of
-'project-switch-commands'. If instead of a short menu you prefer to
-have access to all keys defined inside 'project-prefix-map', as well
-as global bindings (to run other commands inside the project root),
-you can add this to your init script:
-
- (setopt project-switch-commands #'project-prefix-or-any-command)
-
----
-*** New variable 'project-files-relative-names'.
-If it is non-nil, 'project-files' can return file names relative to the
-project root. Project backends can use this to improve the performance
-of their 'project-files' implementation.
-
-** VC
-
----
-*** Log-Edit buffers now display a tool bar.
-This tool bar contains items for committing log entries and editing or
-generating log entries, among other editing operations.
-
----
-*** New user option 'vc-git-shortlog-switches'.
-This is a string or a list of strings that specifies the Git log
-switches for shortlogs, such as the one produced by 'C-x v L'.
-'vc-git-log-switches' is no longer used for shortlogs.
-
----
-*** New value 'no-backend' for user option 'vc-display-status'.
-With this value only the revision number is displayed on the mode-line.
-
----
-*** Obsolete command 'vc-switch-backend' re-added as 'vc-change-backend'.
-The command was previously obsoleted and unbound in Emacs 28.
-
----
-*** Support for viewing VC change history across renames.
-When a fileset's VC change history ends at a rename, 'C-x v l' now
-prints the old name(s) and shows a button which jumps to the history of
-the files under the old names. This feature is supported for Git and
-Hg. Naturally, 'vc-git-print-log-follow' should be nil for this to work
-(or '--follow' should not be in 'vc-hg-log-switches', in Hg's case).
-Unlike when the '--follow' switch is used, commands to see the diff of
-the old revision ('d'), to check out an old file version ('f') or to
-annotate it ('a'), also work on revisions which precede renames.
-
----
-*** 'vc-annotate' now abbreviates the Git revision in the buffer name.
-When using the Git backend, 'vc-annotate' will use an abbreviated
-revision identifier in its buffer name. To restore the previous
-behavior, set user option 'vc-annotate-use-short-revision' to nil.
-
----
-*** New user option 'vc-git-file-name-changes-switches'.
-It allows tweaking the thresholds for rename and copy detection.
-
-** Diff mode
-
----
-*** New user option 'diff-refine-nonmodified'.
-When this is non-nil, 'diff-refine-hunk' will highlight lines that were
-added or removed in their entirety (as opposed to modified lines, where
-some parts of the line were modified), using the same faces as for
-highlighting the words added and removed within modified lines. The
-default value is nil.
-
-+++
-*** 'diff-ignore-whitespace-hunk' can now be applied to all hunks.
-When called with a non-nil prefix argument,
-'diff-ignore-whitespace-hunk' now iterates over all the hunks in the
-current diff, regenerating them without whitespace changes.
-
-+++
-*** New user option 'diff-ignore-whitespace-switches'.
-This allows changing which type of whitespace changes are ignored when
-regenerating hunks with 'diff-ignore-whitespace-hunk'. Defaults to
-the previously hard-coded "-b".
-
-+++
-*** New command 'diff-apply-buffer' bound to 'C-c RET a'.
-It applies the diff in the entire diff buffer and
-saves all modified file buffers.
-
-** Dired
-
----
-*** New user option 'dired-movement-style'.
-When non-nil, make 'dired-next-line', 'dired-previous-line',
-'dired-next-dirline', 'dired-prev-dirline' skip empty lines.
-It also controls how to move point when encountering a boundary
-(e.g., if every line is visible, invoking 'dired-next-line' at
-the last line will move to the first line). The default is nil.
-
----
-*** New user option 'dired-filename-display-length'.
-It is an integer representing the maximum display length of file names.
-The middle part of a file name whose length exceeds the restriction is
-hidden and an ellipsis is displayed instead. A value of 'window'
-means using the right edge of window as the display restriction. The
-default is nil.
-
----
-*** New user option 'shell-command-guess-functions'.
-It defines how to populate a list of commands available
-for 'M-!', 'M-&', '!', '&' and the context menu "Open With"
-based on marked files in Dired. Possible backends are
-'dired-guess-default', MIME types, XDG configuration
-and a universal command such as "open" or "start"
-that delegates to the OS.
-
-+++
-*** New command 'dired-do-open'.
-This command is bound to 'E' (mnemonics "External"). Also it can be
-used by clicking "Open" in the context menu; it "opens" the marked or
-clicked on files according to the OS conventions. For example, on
-systems supporting XDG, this runs 'xdg-open' on the files.
-
-+++
-*** New variable 'dired-guess-shell-alist-optional'.
-It contains commands for external viewers and players for various media
-formats, moved to this list from 'dired-guess-shell-alist-default'.
-
----
-*** The default value of 'dired-omit-size-limit' was increased.
-After performance improvements to omitting in large directories, the new
-default value is 300k, up from 100k. This means 'dired-omit-mode' will
-omit files in directories whose directory listing is up to 300 kilobytes
-in size.
-
-+++
-*** 'dired-listing-switches' handles connection-local values if exist.
-This allows to customize different switches for different remote machines.
-
-** Ediff
-
----
-*** New user option 'ediff-floating-control-frame'.
-If non-nil, try making the control frame be floating rather than tiled.
-
-Many X tiling window managers make the Ediff control frame a tiled
-window equal in size to the main Emacs frame, which works poorly.
-This option is useful to set if you use such a window manager.
-
-** Buffer Selection
-
----
-*** New user option 'bs-default-action-list'.
-You can now configure how to display the "*buffer-selection*" buffer
-using this new option. (Or set 'display-buffer-alist' directly.)
+*** 'whitespace-cleanup' now adds missing newline at end of file.
+If 'whitespace-style' includes 'missing-newline-at-eof (which is the
+default), the 'whitespace-cleanup' function will now add the newline.
** Eshell
-+++
-*** You can now run Eshell scripts in batch mode.
-By adding the following interpreter directive to an Eshell script, you
-can make it executable like other shell scripts:
-
- #!/usr/bin/env -S emacs --batch -f eshell-batch-file
-
-+++
-*** New builtin Eshell command 'compile'.
-This command runs another command, sending its output to a compilation
-buffer when the command would output interactively. This can be useful
-when defining aliases so that they produce a compilation buffer when
-appropriate, but still allow piping the output elsewhere if desired.
-For more information, see the "(eshell) Built-ins" node in the Eshell
-manual.
-
-+++
-*** Eshell's 'env' command now supports running commands.
-Like in many other shells, Eshell's 'env' command now lets you run a
-command passed as arguments to 'env'. If you pass any initial
-arguments of the form 'VAR=VALUE', 'env' will first set 'VAR' to
-'VALUE' before running the command.
-
----
-*** Eshell's 'umask' command now supports setting the mask symbolically.
-Now, you can pass an argument like "u+w,o-r" to Eshell's 'umask'
-command, which will give write permission for owners of newly-created
-files and deny read permission for users who are not members of the
-file's group. See the Info node "(coreutils) File permissions" for
-more information on this notation.
-
----
-*** Performance improvements for interactive output in Eshell.
-Interactive output in Eshell should now be significantly faster,
-especially for commands that can print large amounts of output
-(e.g. "cat"). For external commands, Eshell saves time by only looking
-for password prompts in the last 256 characters of each block of output.
-To restore the previous behavior when checking for password prompts, set
-'eshell-password-prompt-max-length' to 'most-positive-fixnum'.
-
----
-*** Eshell built-in commands can now display progress.
-Eshell built-in commands like "cat" and "ls" now update the display
-periodically while running to show their progress.
-
-+++
-*** New special reference type '#<marker POSITION BUFFER>'.
-This special reference type returns a marker at 'POSITION' in
-'BUFFER'. You can insert it by typing or using the new interactive
-command 'eshell-insert-marker'. You can also insert special
-references of any type using the new interactive command
-'eshell-insert-special-reference'. See the "(eshell) Arguments" node
-in the Eshell manual for more details.
-
-+++
-*** New splice operator for Eshell dollar expansions.
-Dollar expansions in Eshell now let you splice the elements of the
-expansion in-place using '$@expr'. This makes it easier to fill lists
-of arguments into a command, such as when defining aliases. For more
-information, see the "(eshell) Dollars Expansion" node in the Eshell
-manual.
-
-+++
-*** You can now splice Eshell globs in-place into argument lists.
-By setting 'eshell-glob-splice-results' to a non-nil value, Eshell
-will expand glob results in-place as if you had typed each matching
-file name individually. For more information, see the "(eshell)
-Globbing" node in the Eshell manual.
-
-+++
-*** Eshell now supports negative numbers and ranges for indices.
-Now, you can retrieve the last element of a list with '$my-list[-1]'
-or get a sublist of elements 2 through 4 with '$my-list[2..5]'. For
-more information, see the "(eshell) Dollars Expansion" node in the
-Eshell manual.
-
-+++
-*** Eshell commands can now be explicitly-remote (or local).
-By prefixing a command name in Eshell with a remote identifier, like
-"/ssh:user@remote:whoami", you can now run commands on a particular
-host no matter your current directory. Likewise, you can run a
-command on your local system no matter your current directory via
-"/local:whoami". For more information, see the "(eshell) Remote Access"
-node in the Eshell manual.
-
-+++
-*** Eshell's '$UID' and '$GID' variables are now connection-aware.
-Now, when expanding '$UID' or '$GID' in a remote directory, the value
-is the user or group ID associated with the remote connection.
-
----
-*** Eshell now uses 'field' properties in its output.
-In particular, this means that pressing the '<home>' key moves the
-point to the beginning of your input, not the beginning of the whole
-line. If you want to go back to the old behavior, add something like
-this to your configuration:
-
- (keymap-set eshell-mode-map "<home>" #'eshell-bol-ignoring-prompt)
-
-This also means you no longer need to adjust 'eshell-prompt-regexp'
-when customizing your Eshell prompt.
-
----
-*** You can now properly unload Eshell.
-Calling '(unload-feature 'eshell)' no longer signals an error, and now
-correctly unloads Eshell and all of its modules.
-
-+++
-*** 'eshell-read-aliases-list' is now an interactive command.
-After manually editing 'eshell-aliases-file', you can use this command
-to load the edited aliases.
-
-+++
-*** 'rgrep' is now a builtin Eshell command.
-Running 'rgrep' in Eshell now uses the Emacs grep facility instead of
-calling external rgrep.
-
-+++
-*** If a command exits abnormally, the Eshell prompt now shows its exit code.
-
-+++
-*** New user option 'eshell-history-append'.
-If non-nil, each Eshell session will save history by appending new
-entries of that session to the history file rather than overwriting
-the file with the whole history of the session. The default is nil.
-
-** Pcomplete
-
----
-*** New user option 'pcomplete-remote-file-ignore'.
-When this option is non-nil, remote file names are not completed by
-Pcomplete. Packages, like 'shell-mode', could set this in order to
-suppress remote file name completion at all.
-
----
-*** Completion for the 'doas' command has been added.
-Command completion for 'doas' in Eshell and Shell mode will now work.
-
-** Shell mode
-
-+++
-*** New user option 'shell-get-old-input-include-continuation-lines'.
-When this user option is non-nil, 'shell-get-old-input' ('C-RET')
-includes multiple shell "\" continuation lines from command output.
-Default is nil.
-
-+++
-*** New user option 'shell-history-file-name'.
-When this user option is set to t, 'shell-mode' does not read the shell
-history file. Setting this user option to a string specifies the name
-of the shell history file to be read. A nil value triggers reading the
-environment variable 'HISTFILE'.
-
-In a 'shell' buffer, this user option is connection-local.
-
----
-*** Performance improvements for interactive output.
-Interactive output in Shell mode now scans more selectively for password
-prompts by only examining the last 256 characters of each block of
-output, reducing the time spent when printing large amounts of output.
-To restore the old behavior, set 'comint-password-prompt-max-length' to
-'most-positive-fixnum'.
-
-** Prog mode
-
-+++
-*** New command 'prog-fill-reindent-defun'.
-This command either fills a single paragraph in a defun, such as a
-docstring, or a comment, or (re)indents the surrounding defun if point
-is not in a comment or a string. By default, it is bound to 'M-q' in
-'prog-mode' and all its descendants.
-
-** Imenu
-
-+++
-*** New user option 'imenu-flatten'.
-It controls whether to flatten the list of sections in an imenu, and
-how to display the sections in the flattened list.
-
-+++
-*** The sort order of Imenu completions can now be customized.
-You can customize the user option 'completion-category-overrides'
-and set 'display-sort-function' for the category 'imenu'.
-
-** Which Function mode
-
-+++
-*** Which Function mode can now display function names on the header line.
-The new user option 'which-func-display' allows choosing where the
-function name is displayed. The default is 'mode' to display in the
-mode line. 'header' will display in the header line;
-'mode-and-header' displays in both the header line and mode line.
-
-+++
-*** New user option 'which-func-update-delay'.
-This replaces the user option 'idle-update-delay', which was previously
-used to control the delay before 'which-function-mode' updated its
-display. The user option 'idle-update-delay', which was only used by
-Which Function mode, is now obsolete.
-
-** Tramp
-
-+++
-*** Tramp methods can be optional.
-An optional connection method is not enabled by default. The user must
-enable it explicitly by the 'tramp-enable-method' command. The existing
-methods "fcp", "krlogin", " ksu" and "nc" are optional now.
-
-+++
-*** New optional connection method "androidsu".
-This provides access to system files with elevated privileges granted by
-the idiosyncratic 'su' implementations and system utilities customary on
-Android.
-
-+++
-*** New optional connection method "run0".
-This connection method is similar to "sudo", but it uses the
-'systemd-run' program internally.
-
-+++
-*** New connection methods "dockercp" and "podmancp".
-These are the external methods counterparts of "docker" and "podman".
-
-+++
-*** New optional connection methods for containers.
-There are new optional connection methods "toolbox", "distrobox",
-"flatpak", "apptainer" and "nspawn". They allow accessing system
-containers provided by Toolbox or Distrobox, sandboxes provided by
-Flatpak, instances managed by Apptainer, or accessing systemd-based
-light-weight containers..
-
-+++
-*** Connection method "kubernetes" supports now optional container name.
-The host name for Kubernetes connections can be of kind [CONTAINER.]POD,
-in order to specify a dedicated container. If there is just the pod
-name, the first container in the pod is taken. The new user options
-'tramp-kubernetes-context' and 'tramp-kubernetes-namespace' allow
-accessing pods with different context or namespace but the default one.
-
-+++
-*** Rename 'tramp-use-ssh-controlmaster-options' to 'tramp-use-connection-share'.
-The old name still exists as obsolete variable alias. This user
-option controls now connection sharing for both ssh-based and
-plink-based methods. It allows the values t, nil, and 'suppress'.
-The latter suppresses also "ControlMaster" settings in the user's
-"~/.ssh/config" file, or connection share configuration in PuTTY
-sessions, respectively.
-
-+++
-*** New command 'tramp-cleanup-some-buffers'.
-It kills only a subset of opened remote buffers, subject to the user
-option 'tramp-cleanup-some-buffers-hook'.
-
-+++
-*** New command 'inhibit-remote-files'.
-This command disables the handling of file names with the special
-remote file name syntax. It should be applied only when remote files
-won't be used in this Emacs instance. It provides a slightly improved
-performance of file name handling in Emacs.
-
-+++
-*** New macro 'without-remote-files'.
-This macro could wrap code which handles local files only. Due to the
-temporary deactivation of remote files, it results in a slightly
-improved performance of file name handling in Emacs.
-
-+++
-*** New user option 'tramp-completion-multi-hop-methods'.
-It contains a list of connection methods for which completion should
-be attempted at the end of a multi-hop chain. This allows completion
-candidates to include a list of, for example, containers running on a
-remote docker host.
-
-+++
-*** New command 'tramp-revert-buffer-with-sudo'.
-It reverts the current buffer to visit with "sudo" permissions. The
-buffer must either visit a file, or it must run 'dired-mode'. Another
-method but "sudo" can be configured with user option
-'tramp-file-name-with-method'.
-
-+++
-*** Direct asynchronous processes are indicated by a connection-local variable.
-If direct asynchronous processes shall be used, set the connection-local
-variable 'tramp-direct-async-process' to a non-nil value. This has been
-changed, in previous Emacs versions this was indicated by the now
-deprecated connection property "direct-async-process". See the Tramp
-manual "(tramp) Improving performance of asynchronous remote processes".
-
----
-*** Direct asynchronous processes use 'tramp-remote-path'.
-When a direct asynchronous process is invoked, it uses 'tramp-remote-path'
-for setting the remote 'PATH' environment variable.
-
-** EWW
-
----
-*** New mouse bindings in EWW buffers.
-Certain form elements that were displayed as buttons, yet could only be
-activated by keyboard input, are now operable using 'mouse-2'. With
-"Submit" buttons, this triggers submission of the form, while clicks on
-other classes of buttons either toggle their values or prompt for user
-input, as the case may be.
-
----
-*** EWW text input fields and areas are now fields.
-In consequence, movement commands and OS input method features now
-recognize and confine their activities to the text input field around
-point. See also the Info node "(elisp) Fields".
-
-+++
-*** 'eww-open-file' can now display the file in a new buffer.
-By default, the command reuses the "*eww*" buffer, but if called with
-the new argument NEW-BUFFER non-nil, it will use a new buffer instead.
-Interactively, invoke 'eww-open-file' with a prefix argument to
-activate this behavior.
-
----
-*** 'eww' URL or keyword prompt now has tab completion.
-The interactive minibuffer prompt when invoking 'eww' now has support
-for tab completion.
-
-+++
-*** 'eww' URL and keyword prompt now completes suggested URIs and bookmarks.
-The interactive minibuffer prompt when invoking 'eww' now provides
-completions from 'eww-suggest-uris'. 'eww-suggest-uris' now includes
-bookmark URIs.
-
-+++
-*** New command 'eww-copy-alternate-url'.
-It copies an alternate link on the page currently visited in EWW into
-the kill ring. Alternate links are optional metadata that HTML pages
-use for linking to their alternative representations, such as
-translated versions or associated RSS feeds.
-
-+++
-*** 'eww-open-in-new-buffer' supports the prefix argument.
-When invoked with the prefix argument ('C-u'),
-'eww-open-in-new-buffer' will not make the new buffer the current one.
-This is useful for continuing reading the URL in the current buffer
-when the new URL is fetched.
-
----
-*** History navigation in EWW now behaves as in other browsers.
-Previously, when navigating back and forward through page history, EWW
-would add a duplicate entry to the end of the history list each time.
-This made it impossible to navigate to the "end" of the history list.
-Now, navigating through history in EWW simply changes your position in
-the history list, allowing you to reach the end as expected. In
-addition, when browsing to a new page from a "historical" one (i.e., a
-page loaded by navigating back through history), EWW deletes the history
-entries newer than the current page. To change the behavior when
-browsing from "historical" pages, you can customize
-'eww-before-browse-history-function'.
-
-+++
-*** 'eww-readable' now toggles display of the readable parts of a web page.
-When called interactively, 'eww-readable' toggles whether to display
-only the readable parts of a page or the full page. With a positive
-prefix argument, it always displays the readable parts, and with a zero
-or negative prefix, it always displays the full page.
-
-+++
-*** New user option 'eww-readable-urls'.
-This is a list of regular expressions matching the URLs where EWW should
-display only the readable parts by default. For more details, see
-"(eww) Basics" in the EWW manual.
-
----
-*** New user option 'eww-readable-adds-to-history'.
-When non-nil (the default), calling 'eww-readable' adds a new entry to
-the EWW page history.
-
-** Go-ts mode
-
-+++
-*** New command 'go-ts-mode-docstring'.
-This command adds a docstring comment to the current defun. If a
-comment already exists, point is only moved to the comment. It is
-bound to 'C-c C-d' in 'go-ts-mode'.
-
-** Man mode
-
-+++
-*** New user option 'Man-prefer-synchronous-call'.
-When this is non-nil, run the 'man' command synchronously rather than
-asynchronously (which is the default behavior).
-
-+++
-*** New user option 'Man-support-remote-systems'.
-This option controls whether the man page is formatted on the remote
-system when the current buffer's default-directory is remote. You can
-invoke the 'man' command with a prefix argument to countermand the
-value of this option for the current invocation of 'man'.
-
-** DocView
-
----
-*** New face 'doc-view-svg-face'.
-This replaces 'doc-view-svg-foreground' and 'doc-view-svg-background'.
-If you don't like the colors produced by the default definition of
-this new face when DocView displays documents, customize this face to
-restore the colors you were used to, or to get colors more to your
-liking.
-
----
-*** DocView buffers now display a new tool bar.
-This tool bar contains options for searching and navigating within the
-document, replacing the incompatible items for incremental search and
-editing within the default tool bar displayed in the past.
-
-** Shortdoc
-
-+++
-*** New function 'shortdoc-function-examples'.
-This function returns examples of use of a given Emacs Lisp function
-from the available shortdoc information.
-
-+++
-*** New function 'shortdoc-help-fns-examples-function'.
-This function inserts into the current buffer examples of use of a
-given Emacs Lisp function, which it gleans from the shortdoc
-information. If you want 'describe-function' ('C-h f') to insert
-examples of using the function into regular "*Help*" buffers, add the
-following to your init file:
-
- (add-hook 'help-fns-describe-function-functions
- #'shortdoc-help-fns-examples-function)
-
-** Package
-
----
-*** New user option 'package-vc-register-as-project'.
-When non-nil, it will automatically register every package as a
-project, that you can quickly select using 'project-switch-project'
-('C-x p p').
-
----
-*** New user option 'package-vc-allow-build-commands'.
-Controls for which packages Emacs runs extra build commands when
-installing directly from the package VCS repository.
-
----
-*** New command 'package-vc-log-incoming'.
-This commands displays incoming changes for a VC package without
-modifying the current checkout.
-
----
-*** New command to start an inferior Emacs loading only specific packages.
-The new command 'package-isolate' will start a new Emacs process, as
-a sub-process of Emacs where you invoke the command, in a way that
-causes the new process to load only some of the installed packages.
-The command prompts for the packages to activate in this
-sub-process, and is intended for testing Emacs and/or the packages
-in a clean environment.
-
-** Flymake
-
-+++
-*** New user option 'flymake-indicator-type'.
-This user option controls which error indicator type Flymake should use
-in current buffer. Depending on your preference, this can either use
-fringes or margins for indicating errors.
-
-+++
-*** New user option 'flymake-margin-indicators-string'.
-It controls, for each error type, the string and its face to display as
-the margin indicator.
-
-+++
-*** New user option 'flymake-autoresize-margins'.
-If non-nil, Flymake will resize the margins when 'flymake-mode' is
-turned on or off.
-Only relevant if 'flymake-indicator-type' is set to 'margins'.
-
-+++
-*** New user option 'flymake-margin-indicator-position'.
-It controls which margin (left or right) is used for margin
-indicators.
-
-+++
-*** New user option 'flymake-show-diagnostics-at-end-of-line'.
-When non-nil, Flymake shows summarized descriptions of diagnostics at
-the end of the line. Depending on your preference, this can either be
-distracting and easily confused with actual code, or a significant
-early aid that relieves you from moving the buffer or reaching for the
-mouse to consult an error message.
-
-** Flyspell
-
-+++
-*** New user option 'flyspell-check-changes'.
-When non-nil, Flyspell mode spell-checks only words that you edited; it
-does not check unedited words just because you move point across them.
-
----
-** JS mode.
-The binding 'M-.' has been removed from the major mode keymaps in
-'js-mode' and 'js-ts-mode', having it default to the global binding
-which calls 'xref-find-definitions'. If the previous one worked
-better for you, use 'define-key' in your init script to bind
-'js-find-symbol' to that combination again.
-
----
-** Json mode.
-'js-json-mode' does not derive from 'js-mode' any more so as not
-to confuse tools like Eglot or YASnippet into thinking that those
-buffers contain Javascript code.
-
-** Python mode
-
----
-*** New user option 'python-indent-block-paren-deeper'.
-If non-nil, increase the indentation of the lines inside parens in a
-header of a block when they are indented to the same level as the body
-of the block:
-
- if (some_expression
- and another_expression):
- do_something()
-
-instead of:
-
- if (some_expression
- and another_expression):
- do_something()
-
----
-*** New user option 'python-interpreter-args'.
-This allows the user to specify command line arguments to the non
-interactive Python interpreter specified by 'python-interpreter'.
-
----
-*** New function 'python-shell-send-block'.
-It sends the python block delimited by 'python-nav-beginning-of-block'
-and 'python-nav-end-of-block' to the inferior Python process.
-
-** Inferior Python mode
-
----
-*** Default value of 'python-shell-compilation-regexp-alist' is changed.
-Support for Python's ExceptionGroup has been added, so in the Python
-shell, the line indicating the source of an error in the error messages
-from ExceptionGroup will be recognized as well.
-
-** Eldoc
-
----
-*** 'eldoc' no longer truncates to a single line by default.
-Previously, the entire docstring was not available to eldoc, which made
-'eldoc-echo-area-use-multiline-p' ineffective. The old behavior may be
-kept by customizing 'eldoc-echo-area-use-multiline-p'.
-
----
-** Scheme mode.
-Scheme mode now handles the regular expression literal '#/regexp/' that
-is available in some Scheme implementations.
-Also, it should now handle nested sexp-comments.
-
-** Use package
-
-+++
-*** New ':vc' keyword.
-This keyword enables the user to install packages using package-vc.el.
-
-+++
-*** New user option 'use-package-vc-prefer-newest'.
-This allows the user to always install the newest commit of a package
-when using the ':vc' keyword.
-
-** Gnus
-
-+++
-*** New backend 'nnfeed'.
-This allows backend developers to easily create new backends for web
-feeds, as inheriting backends of 'nnfeed'.
-
-+++
-*** New backend 'nnatom'.
-This allow users to add Atom Syndication Format feeds to Gnus as
-servers.
-
-*** The 'nnweb-type' option 'gmane' has been removed.
-The gmane.org website is, sadly, down since a number of years with no
-prospect of it coming back. Therefore, it is no longer valid to set
-the server variable 'nnweb-type' to 'gmane'.
-
----
-*** New user option 'gnus-mode-line-logo'.
-This allows the user to either disable the display of any logo or
-specify which logo will be displayed as part of the
-buffer-identification in the mode-line of Gnus buffers.
-
-** Rmail
-
----
-*** New commands for reading mailing lists.
-The new Rmail commands 'rmail-mailing-list-post',
-'rmail-mailing-list-unsubscribe', 'rmail-mailing-list-help', and
-'rmail-mailing-list-archive' allow, respectively, posting to,
-unsubscribing from, requesting help about, and browsing the archives
-of, the mailing list from which the current email message was
-delivered.
-
-** Dictionary
-
----
-*** New user option 'dictionary-search-interface'.
-Controls how the 'dictionary-search' command prompts for and displays
-dictionary definitions. Customize this user option to 'help' to have
-'dictionary-search' display definitions in a "*Help*" buffer and
-provide dictionary-based minibuffer completion for word selection.
-
----
-*** New user option 'dictionary-read-word-prompt'.
-This allows the user to customize the prompt that is used by
-'dictionary-search' when asking for a word to search in the
-dictionaries.
-
----
-*** New user option 'dictionary-display-definition-function'.
-This allows the user to customize the way in which 'dictionary-search'
-displays word definitions. If non-nil, this user option should be set
-to a function that displays a word definition obtained from a
-dictionary server. The new function
-'dictionary-display-definition-in-help-buffer' can be used to display
-the definition in a "*Help*" buffer, instead of the default
-"*Dictionary*" buffer.
-
----
-*** New user option 'dictionary-read-word-function'.
-This allows the user to customize the way in which 'dictionary-search'
-prompts for a word to search in the dictionary. This user option
-should be set to a function that lets the user select a word and
-returns it as a string. The new function
-'dictionary-completing-read-word' can be used to prompt with
-completion based on dictionary matches.
-
----
-*** New user option 'dictionary-read-dictionary-function'.
-This allows the user to customize the way in which 'dictionary-search'
-prompts for a dictionary to search in. This user option should be set
-to a function that lets the user select a dictionary and returns its
-name as a string. The new function
-'dictionary-completing-read-dictionary' can be used to prompt with
-completion based on dictionaries that the server supports.
-
----
-*** The default value of 'dictionary-tooltip-dictionary' has changed.
-The new default value is t, which means use the same dictionary as the
-value of 'dictionary-default-dictionary'. The previous default value
-was nil, which effectively disabled 'dictionary-tooltip-mode', even if
-the mode was turned on.
-
-** Pp
-
-+++
-*** New 'pp-default-function' user option replaces 'pp-use-max-width'.
-Its default value is 'pp-fill', a new default pretty-printing function,
-which tries to obey 'fill-column'.
-
----
-*** 'pp-to-string' takes an additional PP-FUNCTION argument.
-This argument specifies the prettifying algorithm to use.
-
----
-*** 'pp' and 'pp-to-string' now always include a terminating newline.
-In the past they included a terminating newline in most cases but not all.
-
-** Emacs Lisp mode
-
----
-*** ',@' now has 'prefix' syntax.
-Previously, the '@' character, which normally has 'symbol' syntax,
-would combine with a following Lisp symbol and interfere with symbol
-searching.
-
-+++
-*** 'emacs-lisp-docstring-fill-column' now defaults to 72.
-It was previously 65. The new default formats documentation strings to
-fit on fewer lines without negatively impacting readability.
-
-** CPerl mode
-
----
-*** Subroutine signatures are now supported.
-CPerl mode fontifies subroutine signatures like variable declarations
-which makes them visually distinct from subroutine prototypes.
-
----
-*** Syntax of Perl up to version 5.40 is supported.
-CPerl mode supports the new keywords for exception handling and the
-object oriented syntax which were added in Perl 5.36, 5.38 and 5.40.
-
----
-*** New user option 'cperl-fontify-trailer'.
-This user option takes the values 'perl-code' or 'comment' and treats
-text after an "__END__" or "__DATA__" token accordingly. The default
-value of 'perl-code' is useful for trailing POD and for AutoSplit
-modules, the value 'comment' makes CPerl mode treat trailers as
-comment, like Perl mode does.
-
----
-*** New command 'cperl-file-style'.
-This command sets the indentation style for the current buffer. To
-change the default style, either use the user option with the same name
-or use the command 'cperl-set-style'.
-
----
-*** New minor mode 'cperl-extra-paired-delimiters-mode'.
-Perl 5.36 and newer allows using more than 200 non-ASCII paired
-delimiters for quote-like constructs, e.g. "q«text»". Use this minor
-mode in buffers where this feature is activated.
-
----
-*** Commands using the Perl Info manual are obsolete.
-The Perl documentation in Info format is no longer distributed with
-Perl or on CPAN since more than 10 years. Perl documentation can be
-read with 'cperl-perldoc' instead.
-
----
-*** Highlighting trailing whitespace has been removed.
-The user option 'cperl-invalid-face' is now obsolete, and does
-nothing. See the user option 'show-trailing-whitespace' instead.
-
-** Emacs Sessions (Desktop)
-
-+++
-*** Restoring buffers visiting remote files can now time out.
-When a buffer is restored which visits a remote file, the restoration
-of the session could hang if the remote host is off-line or slow to
-respond. Setting the user option 'remote-file-name-access-timeout' to
-a positive number will abandon the attempt to restore such buffers
-after a timeout of that many seconds, thus allowing the rest of
-desktop restoration to continue.
-
-** Recentf
-
-+++
-*** Checking recent remote files can now time out.
-Similarly to buffer restoration by Desktop, 'recentf-mode' checking
-of the accessibility of remote files can now time out if
-'remote-file-name-access-timeout' is set to a positive number.
-
-** Image Dired
-
-+++
-*** New user option 'image-dired-thumb-naming'.
-You can now configure how thumbnails are named using this option.
-
-** ERT
-
-+++
-*** New macro 'skip-when' to skip 'ert-deftest' tests.
-This can help to avoid some awkward skip conditions. For example
-'(skip-unless (not noninteractive))' can be changed to the easier
-to read '(skip-when noninteractive)'.
-
-+++
-*** Syntax highlighting unit testing support.
-An ERT extension ('ert-font-lock') now provides support for face
-assignment unit testing. For more information, see the "(ert) Syntax
-Highlighting Tests" node in the ERT manual.
-
-** Socks
-
-+++
-*** Socks supports version 4a.
-The 'socks-server' user option accepts '4a' as a value for its version
-field.
-
-** Edmacro
-
-+++
-*** New command 'edmacro-set-macro-to-region-lines'.
-Bound to 'C-c C-r', this command replaces the macro text with the
-lines of the region. If needed, the region is extended to include
-whole lines. If the region ends at the beginning of a line, that last
-line is excluded.
-
-+++
-*** New user option 'edmacro-reverse-macro-lines'.
-When this is non-nil, the lines of key sequences are displayed with
-the most recent line first. This is can be useful when working with
-macros with many lines, such as from 'kmacro-edit-lossage'.
-
-** Calc
-
-+++
-*** Calc parses fractions written using U+2044 FRACTION SLASH.
-Fractions of the form "123⁄456" are handled as if written "123:456".
-Note in particular the difference in behavior from U+2215 DIVISION SLASH
-and U+002F SOLIDUS, which result in division rather than a rational
-fraction. In addition, precomposed fraction characters, such as ½
-(U+00BD VULGAR FRACTION ONE HALF), are also recognized as rational
-fractions. (They have been recognized since 2004, but it looks like it
-was never mentioned in the NEWS, or even the Calc manual.)
-
-** IELM
-
----
-*** IELM now remembers input history between sessions.
-The new user option 'ielm-history-file-name' is the name of the file
-where IELM input history will be saved. Customize it to nil to revert
-to the old behavior of not remembering input history between sessions.
-
-** EasyPG
-
-+++
-*** New user option 'epa-keys-select-method'.
-This allows the user to customize the key selection method, which can be
-either by using a pop-up buffer or from the minibuffer. The pop-up
-buffer method is the default, which preserves previous behavior.
-
-** Widget
-
-+++
-*** New face 'widget-unselected'.
-Customize this face to a non-default value to visually distinguish the
-labels of unselected active radio-button or checkbox widgets from the
-labels of unselected inactive widgets (the default value inherits from
-the 'widget-inactive' face).
-
-+++
-*** New user option 'widget-skip-inactive'.
-If non-nil, moving point forward or backward between widgets by typing
-'TAB' or 'S-TAB' skips over inactive widgets. The default value is nil.
-
-** Ruby mode
-
----
-*** New user option 'ruby-rubocop-use-bundler'.
-By default it retains the previous behavior: read the contents of
-Gemfile and act accordingly. But you can also set it to t or nil to
-skip the check.
-
-** Thingatpt
-
----
-*** New variables for providing custom thingatpt implementations.
-The new variables 'bounds-of-thing-at-point-provider-alist' and
-'forward-thing-provider-alist' now allow defining custom implementations
-of 'bounds-of-thing-at-point' and 'forward-thing', respectively.
-
----
-*** New helper functions for text property-based thingatpt providers.
-The new helper functions 'thing-at-point-for-char-property',
-'bounds-of-thing-at-point-for-char-property', and
-'forward-thing-for-char-property' can help to implement custom thingatpt
-providers for "things" that are defined by text properties.
-
---
-*** 'bug-reference-mode' now supports 'thing-at-point'.
-Now, calling '(thing-at-point 'url)' when point is on a bug reference
-will return the URL for that bug.
-
-** Miscellaneous
-
-+++
-*** New user option 'rcirc-log-time-format'.
-This allows for rcirc logs to use a custom timestamp format, which the
-chat buffers use by default.
+*** New option 'eshell-command-async-buffer'.
+This option lets you tell 'eshell-command' how to respond if its output
+buffer is already in use by another invocation of 'eshell-command', much
+like 'async-shell-command-buffer' does for 'shell-command'. By default,
+this will prompt for confirmation before creating a new buffer when
+necessary. To restore the previous behavior, set this option to
+'confirm-kill-process'.
----
-*** New user option 'Buffer-menu-group-by'.
-It controls how buffers are divided into groups that are displayed with
-headings using Outline minor mode. Using commands that mark buffers
-on the outline heading line will mark all buffers in the outline.
+** SHR
+++
-*** New command 'Buffer-menu-toggle-internal'.
-This command toggles the display of internal buffers in Buffer Menu mode;
-that is, buffers not visiting a file and whose names start with a space.
-Previously, such buffers were never shown. This command is bound to 'I'
-in Buffer Menu mode.
-
----
-*** 'ffap-lax-url' now defaults to nil.
-Previously, it was set to t, but this broke remote file name detection.
-
----
-*** More control on automatic update of Proced buffers.
-The user option 'proced-auto-update-flag' can now be set to two
-additional values, which control automatic updates of Proced buffers
-that are not displayed in some window.
-
----
-*** nXML Mode now comes with schemas for Mono/.NET development.
-The following new XML schemas are now supported:
-- MSBuild project files
-- Dotnet package properties files
-- Dotnet resource extension files
-- Dotnet Application config files
-- Nuget config file
-- Nuget package specification file
-- Nuget packages config file
+*** SHR now slices large images into rows.
+Sliced images allow for more intuitive scrolling up/down by letting you
+scroll past each slice, instead of jumping past the entire image.
+Previously, SHR sliced images when zoomed to their original size, no
+matter how large or small that was). Now, SHR slices any images taller
+than 'shr-sliced-image-height'. For more information, see the "(eww)
+Advanced" node in the EWW manual.
---
-*** color.el now supports the Oklab color representation.
-
-+++
-*** New user option 'xwidget-webkit-disable-javascript'.
-This allows disabling JavaScript in xwidget Webkit sessions.
-
----
-*** 'ls-lisp--insert-directory' supports more long options of 'ls'.
-'ls-lisp--insert-directory', the ls-lisp implementation of
-'insert-directory', now supports the '--time=TIME' and '--sort=time'
-options of GNU 'ls'.
-
----
-*** 'M-x ping' can now give additional flags to the 'ping' program.
-Typing 'C-u M-x ping' prompts first for the host, and then for the flags
-to give to the 'ping' command.
-
----
-*** Webjump now assumes URIs are HTTPS instead of HTTP.
-For links in 'webjump-sites' without an explicit URI scheme, it was
-previously assumed that they should be prefixed with "http://". Such
-URIs are now prefixed with "https://" instead.
-
----
-*** Added prefixes in titdic-cnv library.
-Most of the variables and functions in the file have been renamed to
-make sure they all use a 'tit-' namespace prefix.
-
----
-*** 'xref-revert-buffer' is now an alias of 'revert-buffer'.
-The Xref buffer now sets up 'revert-buffer-function' such that
-'revert-buffer' behaves like 'xref-revert-buffer' did in previous Emacs
-versions, and the latter is now an alias of the former.
-
----
-*** The Makefile browser is now obsolete.
-The command 'makefile-switch-to-browser' command is now obsolete,
-together with related commands used in the "*Macros and Targets*"
-buffer. We recommend using an alternative like 'imenu' instead.
+*** You can now customize the image zoom levels to cycle through.
+By customizing 'shr-image-zoom-levels', you can change the list of zoom
+levels that SHR cycles through when calling 'shr-zoom-image'.
-* New Modes and Packages in Emacs 30.1
-
-** New major modes based on the tree-sitter library
-
-+++
-*** New major mode 'elixir-ts-mode'.
-A major mode based on the tree-sitter library for editing Elixir files.
-
-+++
-*** New major mode 'heex-ts-mode'.
-A major mode based on the tree-sitter library for editing HEEx files.
-
-+++
-*** New major mode 'html-ts-mode'.
-An optional major mode based on the tree-sitter library for editing
-HTML files.
-
-+++
-*** New major mode 'lua-ts-mode'.
-A major mode based on the tree-sitter library for editing Lua files.
-
-+++
-*** New major mode 'php-ts-mode'.
-A major mode based on the tree-sitter library for editing PHP files.
-
-+++
-** New package EditorConfig.
-This package provides support for the EditorConfig standard,
-an editor-neutral way to provide directory local (project-wide) settings.
-It is enabled via a new global minor mode 'editorconfig-mode'
-which makes Emacs obey the '.editorconfig' files.
-There is also a new major mode 'editorconfig-conf-mode'
-to edit those configuration files.
-
-+++
-** New global minor mode 'etags-regen-mode'.
-This minor mode generates the tags table automatically based on the
-current project configuration, and later updates it as you edit the
-files and save the changes.
-
-+++
-** New package 'which-key'.
-The 'which-key' package from GNU ELPA is now included in Emacs. It
-implements the global minor mode 'which-key-mode' that displays a table
-of key bindings upon entering a partial key chord and waiting for a
-moment. For example, after enabling the minor mode, if you enter 'C-x'
-and wait for one second, the minibuffer will expand with all available
-key bindings that follow 'C-x' (or as many as space allows).
-
-+++
-** New minor mode 'completion-preview-mode'.
-This minor mode shows you symbol completion suggestions as you type,
-using an inline preview. New user options in the 'completion-preview'
-customization group control exactly when Emacs displays this preview.
-'completion-preview-mode' is buffer-local, to enable it globally use
-'global-completion-preview-mode'.
-
-+++
-** New package Window-Tool-Bar.
-This provides a new minor mode, 'window-tool-bar-mode'. When this minor
-mode is enabled, a tool bar is displayed at the top of a window. To
-conserve space, no tool bar is shown if 'tool-bar-map' is nil. The
-global minor mode 'global-window-tool-bar-mode' enables this minor mode
-in all buffers.
-
-+++
-** New library Track-Changes.
-This library is a layer of abstraction above 'before-change-functions'
-and 'after-change-functions' which provides a superset of
-the functionality of 'after-change-functions':
-- It provides the actual previous text rather than only its length.
-- It takes care of accumulating and bundling changes until a time when
- its client finds it convenient to react to them.
-- It detects most cases where some changes were not properly
- reported (calls to 'before/after-change-functions' that are
- incorrectly paired, missing, etc...) and reports them adequately.
-
-+++
-** New global minor mode 'minibuffer-regexp-mode'.
-This is a minor mode for editing regular expressions in the minibuffer,
-for example in 'query-replace-regexp'. It correctly highlights parens
-via 'show-paren-mode' and 'blink-matching-paren' in a user-friendly way,
-avoids reporting alleged paren mismatches and makes sexp navigation more
-intuitive.
-
----
-** The highly accessible Modus themes collection has eight items.
-The 'modus-operandi' and 'modus-vivendi' are the main themes that have
-been part of Emacs since version 28. The former is light, the latter
-dark. In addition to these, we now have 'modus-operandi-tinted' and
-'modus-vivendi-tinted' for easier legibility, as well as
-'modus-operandi-deuteranopia', 'modus-vivendi-deuteranopia',
-'modus-operandi-tritanopia', and 'modus-vivendi-tritanopia' to cover
-the needs of users with red-green or blue-yellow color deficiency.
-The Info manual "(modus-themes) Top" describes the details and
-showcases all their user options.
-
-+++
-** New library PEG.
-Emacs now includes a library for writing Parsing Expression
-Grammars (PEG), an approach to text parsing that provides more structure
-than regular expressions, but less complexity than context-free
-grammars. The Info manual "(elisp) Parsing Expression Grammars" has
-documentation and examples.
-
----
-** New major mode 'shell-command-mode'.
-This mode is used by default for the output of asynchronous 'shell-command'.
-To revert to the previous behavior, set the (also new) variable
-'async-shell-command-mode' to 'shell-mode'. Any hooks or mode-specific
-variables used should be adapted appropriately.
-
-+++
-** New package Compat.
-Emacs now comes with a stub implementation of the
-forwards-compatibility Compat package from GNU ELPA. This allows
-built-in packages to use the library more effectively, and helps
-preventing the installation of Compat if unnecessary.
+* New Modes and Packages in Emacs 31.1
-* Incompatible Lisp Changes in Emacs 30.1
-
-+++
-** Evaluating a 'lambda' returns an object of type 'interpreted-function'.
-Instead of representing interpreted functions as lists that start with
-either 'lambda' or 'closure', Emacs now represents them as objects
-of their own 'interpreted-function' type, which is very similar
-to 'byte-code-function' objects (the argument list, docstring, and
-interactive forms are placed in the same slots).
-Lists that start with 'lambda' are now used only for non-evaluated
-functions (in other words, for source code), but for backward compatibility
-reasons, 'functionp' still recognizes them as functions and you can
-still call them as before.
-Thus code that attempts to "dig" into the internal structure of an
-interpreted function's object with the likes of 'car' or 'cdr' will
-no longer work and will need to use 'aref' instead to extract its
-various subparts (when 'interactive-form', 'documentation', and
-'help-function-arglist' aren't adequate).
-
----
-** The escape sequence '\x' not followed by hex digits is now an error.
-Previously, '\x' without at least one hex digit denoted character code
-zero (NUL) but as this was neither intended nor documented or even
-known by anyone, it is now treated as an error by the Lisp reader.
-
----
-** 'subr-native-elisp-p' is renamed to 'native-comp-function-p'.
-The previous name still exists but is marked as obsolete.
-
-+++
-** 'define-globalized-minor-mode' requires that modes use 'run-mode-hooks'.
-Minor modes defined with 'define-globalized-minor-mode', such as
-'global-font-lock-mode', will not be enabled any more in those buffers
-whose major modes fail to use 'run-mode-hooks'. Major modes defined
-with 'define-derived-mode' are not affected. 'run-mode-hooks' has been the
-recommended way to run major mode hooks since Emacs 22.
-
-+++
-** 'buffer-match-p' and 'match-buffers' take '&rest ARGS'.
-They used to take a single '&optional ARG' and were documented to use
-an unreliable hack to try and support condition predicates that
-don't accept this optional ARG.
-The new semantics makes no such accommodation, but the code still
-supports it (with a warning) for backward compatibility.
-
----
-** 'post-gc-hook' runs after updating 'gcs-done' and 'gc-elapsed'.
-
----
-** Connection-local variables are applied in buffers visiting remote files.
-This overrides possible directory-local or file-local variables with
-the same name.
-
-+++
-** 'copy-tree' now copies records when its optional 2nd argument is non-nil.
-
-+++
-** Regexp zero-width assertions followed by operators are better defined.
-Previously, regexps such as "xy\\B*" would have ill-defined behavior.
-Now any operator following a zero-width assertion applies to that
-assertion only (which is useless). For historical compatibility, an
-operator character following '^' or '\`' becomes literal, but we
-advise against relying on this.
-
-+++
-** Infinities and NaNs no longer act as symbols on non-IEEE platforms.
-On old platforms like the VAX that do not support IEEE floating-point,
-tokens like '0.0e+NaN' and '1.0e+INF' are no longer read as symbols.
-Instead, the Lisp reader approximates an infinity with the nearest
-finite value, and a NaN with some other non-numeric object that
-provokes an error if used numerically.
-
-+++
-** Conversion of strings to and from byte-arrays works with multibyte strings.
-The functions 'dbus-string-to-byte-array' and
-'dbus-byte-array-to-string' now accept and return multibyte Lisp
-strings, encoding to UTF-8 and decoding from UTF-8 internally. This
-means that the argument to 'dbus-byte-array-to-string' must be a valid
-UTF-8 byte sequence, and the optional parameter MULTIBYTE of
-'dbus-byte-array-to-string' is now obsolete and unused. The argument of
-'dbus-string-to-byte-array' should be a regular Lisp string, not a
-unibyte string.
-
-+++
-** 'minibuffer-allow-text-properties' now can be set buffer-local.
-'read-from-minibuffer' and functions that use it can take the
-buffer-local value from the minibuffer.
-
-+++
-** 'minibuffer-allow-text-properties' also affects completions.
-When it has a non-nil value, then completion functions like
-'completing-read' don't discard text properties from the returned
-completion candidate.
-
-+++
-** X color support compatibility aliases are now obsolete.
-The compatibility aliases 'x-defined-colors', 'x-color-defined-p',
-'x-color-values', and 'x-display-color-p' are now obsolete.
-
-+++
-** 'easy-mmode-define-{minor,global}-mode' aliases are now obsolete.
-Use 'define-minor-mode' and 'define-globalized-minor-mode' instead.
-
-+++
-** The 'millisec' argument of 'sleep-for' is now obsolete.
-Use a float value for the first argument instead.
-
----
-** User options 'eshell-NAME-unload-hook' are now obsolete.
-These hooks were named incorrectly, and so they never actually ran
-when unloading the corresponding feature. Instead, you should use
-hooks named after the feature name, like 'esh-mode-unload-hook'.
-
-** User options 'eshell-process-wait-{seconds,milliseconds}' are now obsolete.
-Instead, use 'eshell-process-wait-time', which supports floating-point
-values.
-
----
-** User option 'tramp-completion-reread-directory-timeout' has been removed.
-This user option has been obsoleted in Emacs 27, use
-'remote-file-name-inhibit-cache' instead.
-
-+++
-** The obsolete calling convention of 'sit-for' has been removed.
-That convention was: '(sit-for SECONDS MILLISEC &optional NODISP)'.
-
----
-** 'defadvice' is marked as obsolete.
-See the "(elisp) Porting Old Advice" Info node for help converting
-them to use 'advice-add' or 'define-advice' instead.
-
----
-** 'cl-old-struct-compat-mode' is marked as obsolete.
-You may need to recompile your code if it was compiled with Emacs < 24.3.
-
----
-** Old derived.el functions removed.
-The following functions have been deleted because they were only used
-by code compiled with Emacs < 21:
-'derived-mode-init-mode-variables', 'derived-mode-merge-abbrev-tables',
-'derived-mode-merge-keymaps', 'derived-mode-merge-syntax-tables',
-'derived-mode-run-hooks', 'derived-mode-set-abbrev-table',
-'derived-mode-set-keymap', 'derived-mode-set-syntax-table',
-'derived-mode-setup-function-name'.
+* Incompatible Lisp Changes in Emacs 31.1
-* Lisp Changes in Emacs 30.1
-
-+++
-** The 'wheel-up/down/left/right' events are now bound unconditionally.
-The 'mouse-wheel-up/down/left/right-event' variables are thus used only
-to specify the 'mouse-4/5/6/7' events that might still happen to be
-generated by some old packages (or if 'mouse-wheel-buttons' has been set
-to nil).
-
----
-** Xterm Mouse mode now emits 'wheel-up/down/right/left' events.
-This is instead of 'mouse-4/5/6/7' events for the mouse wheel. It uses
-the new variable 'mouse-wheel-buttons' to decide which button maps to
-which wheel event (if any).
-
----
-** In batch mode, tracing now sends the trace to stdout.
-
-+++
-** New hook 'hack-dir-local-get-variables-functions'.
-This can be used to provide support for other directory-local settings
-beside ".dir-locals.el".
-
-+++
-** 'auto-coding-functions' can know the name of the file.
-The functions on this hook can now find the name of the file to
-which the text belongs by consulting the variable 'auto-coding-file-name'.
-
-+++
-** New user option 'compilation-safety' to control safety of native code.
-It is now possible to control how safe is the code generated by native
-compilation, by customizing this user option. It is also possible to
-control this at function granularity by using the new 'safety' parameter
-in the function's 'declare' form.
-
-+++
-** New types 'closure' and 'interpreted-function'.
-'interpreted-function' is the new type used for interpreted functions,
-and 'closure' is the common parent type of 'interpreted-function'
-and 'byte-code-function'.
-
-Those new types come with the associated new predicates 'closurep' and
-'interpreted-function-p' as well as a new constructor
-'make-interpreted-closure'.
-
----
-** New function 'help-fns-function-name'.
-For named functions, it just returns the name and otherwise
-it returns a short "unique" string that identifies the function.
-In either case, the string is propertized so clicking on it gives
-further details.
-
-+++
-** New function 'char-to-name'.
-This is a convenience function to return the Unicode name of a char (if
-it has one).
-
-+++
-** New function 'cl-type-of'.
-This function is like 'type-of' except that it sometimes returns
-a more precise type. For example, for nil and t it returns 'null'
-and 'boolean' respectively, instead of just 'symbol'.
-
-+++
-** New functions 'primitive-function-p' and 'cl-functionp'.
-'primitive-function-p' is like 'subr-primitive-p' except that it returns
-t only if the argument is a function rather than a special-form,
-and 'cl-functionp' is like 'functionp' except it returns nil
-for lists and symbols.
-
----
-** Built-in types now have corresponding classes.
-At the Lisp level, this means that things like '(cl-find-class 'integer)'
-will now return a class object, and at the UI level it means that
-things like 'C-h o integer RET' will show some information about that type.
-
----
-** New variable 'major-mode-remap-defaults' and function 'major-mode-remap'.
-The first is like Emacs-29's 'major-mode-remap-alist' but to be set by
-packages (instead of users). The second looks up those two variables.
-
-+++
-** Pcase's functions (in 'pred' and 'app') can specify the argument position.
-For example, instead of '(pred (< 5))' you can write '(pred (> _ 5))'.
-
-+++
-** 'define-advice' now sets the new advice's 'name' property to NAME.
-Named advices defined with 'define-advice' can now be removed with
-'(advice-remove SYMBOL NAME)' in addition to '(advice-remove SYMBOL
-SYMBOL@NAME)'.
-
-+++
-** New function 'require-with-check' to detect new versions shadowing.
-This is like 'require', but it checks whether the argument 'feature'
-is already loaded, in which case it either signals an error or
-forcibly reloads the file that defines the feature.
-
-+++
-** New variable 'lisp-eval-depth-reserve'.
-It puts a limit to the amount by which Emacs can temporarily increase
-'max-lisp-eval-depth' when handling signals.
-
-+++
-** New special form 'handler-bind'.
-It provides a functionality similar to 'condition-case' except it runs
-the handler code without unwinding the stack, such that we can record
-the backtrace and other dynamic state at the point of the error. See
-the Info node "(elisp) Handling Errors".
-
-+++
-** New text properties add tooltips on fringes.
-It is now possible to provide tooltips on fringes by adding special text
-properties 'left-fringe-help' and 'right-fringe-help'. See the "(elisp)
-Special Properties" Info node in the Emacs Lisp Reference Manual for
-more details.
-
-+++
-** New 'display-buffer' action alist entry 'pop-up-frames'.
-This has the same effect as the variable of the same name and takes
-precedence over the variable when present.
-
----
-** New function 'merge-ordered-lists'.
-Mostly used internally to do a kind of topological sort of
-inheritance hierarchies.
-
-+++
-** 'drop' is now an alias for the function 'nthcdr'.
-
-+++
-** New polymorphic comparison function 'value<'.
-This function returns non-nil if the first argument is less than the
-second. It works for any two values of the same type with reasonable
-ordering for numbers, strings, symbols, bool-vectors, markers, buffers
-and processes. Conses, lists, vectors and records are ordered
-lexicographically.
-It is intended as a convenient ordering predicate for sorting, and is
-likely to be faster than hand-written Lisp functions.
-
-+++
-** New 'sort' arguments and features.
-The 'sort' function can now be called using the signature
-
- (sort SEQ &rest KEYWORD-ARGUMENTS)
-
-where arguments after the first are keyword/value pairs, all optional:
-':key' specifies a function that produces the sorting key from an element,
-':lessp' specifies the ordering predicate, defaulting to 'value<',
-':reverse' is used to reverse the sorting order,
-':in-place is used for in-place sorting, as the default is now to
-sort a copy of the input.
-
-The new signature is less error-prone and reduces the need to write
-ordering predicates by hand. We recommend that you use the ':key'
-argument instead of ':lessp' unless a suitable ordering predicate is
-already available. This can also be used for multi-key sorting:
-
- (sort seq :key (lambda (x) (list (age x) (size x) (cost x))))
-
-sorts by the return value of 'age', then by 'size', then by 'cost'.
-
-The old signature, '(sort SEQ PREDICATE)', can still be used and sorts
-its input in-place as before.
-
-** New API for 'derived-mode-p' and control of the graph of major modes.
-
-+++
-*** 'derived-mode-p' now takes the list of modes as a single argument.
-The same holds for 'provided-mode-derived-p'.
-The old calling convention where multiple modes are passed as
-separate arguments is deprecated.
-
-+++
-*** New functions to access the graph of major modes.
-While 'define-derived-mode' still only supports single inheritance,
-modes can declare additional parents (for tests like 'derived-mode-p')
-with 'derived-mode-add-parents'.
-Accessing the 'derived-mode-parent' property directly is now
-deprecated in favor of the new functions 'derived-mode-set-parent'
-and 'derived-mode-all-parents'.
-
-+++
-** Drag-and-drop functions can now be called once for compound drops.
-It is now possible for drag-and-drop handler functions to respond to
-drops incorporating more than one URL. Functions capable of this must
-set their 'dnd-multiple-handler' symbol properties to a non-nil value.
-See the Info node "(elisp) Drag and Drop".
-
-The function 'dnd-handle-one-url' has been made obsolete, since it
-cannot take these new handlers into account.
-
-+++
-** 'notifications-notify' can use Icon Naming Specification for ':app-icon'.
-You can use a symbol as the value for ':app-icon' to provide icon name
-without specifying a file, like this:
-
- (notifications-notify
- :title "I am playing music" :app-icon 'multimedia-player)
-
----
-** New function 're-disassemble' to see the innards of a regexp.
-If you built Emacs with '--enable-checking', you can use this to help
-debug either your regexp performance problems or the regexp engine.
-
-+++
-** XLFDs are no longer restricted to 255 characters.
-'font-xlfd-name' now returns an XLFD even if it is greater than 255
-characters in length, provided that the LONG_XLFDs argument is true.
-Other features in Emacs which employ XLFDs have been modified to
-produce and understand XLFDs larger than 255 characters.
-
-+++
-** New macro 'static-if' for conditional evaluation of code.
-This macro hides a form from the evaluator or byte-compiler based on a
-compile-time condition. This is handy for avoiding byte-compilation
-warnings about code that will never actually run under some conditions.
-
-+++
-** Desktop notifications are now supported on the Haiku operating system.
-The new function 'haiku-notifications-notify' provides a subset of the
-capabilities of the 'notifications-notify' function in a manner
-analogous to 'w32-notification-notify'.
-
-** New Haiku specific variable 'haiku-pass-control-tab-to-system'.
-This sets whether Emacs should pass 'C-TAB' on to the system instead of
-handling it, fixing a problem where window switching would not activate
-if an Emacs frame had focus on the Haiku operating system.
-
-+++
-** New value 'if-regular' for the REPLACE argument to 'insert-file-contents'.
-It results in 'insert-file-contents' erasing the buffer instead of
-preserving markers if the file being inserted is not a regular file,
-rather than signaling an error.
-
-+++
-** New variable 'current-key-remap-sequence'.
-It is bound to the key sequence that caused a call to a function bound
-within 'function-key-map' or 'input-decode-map' around those calls.
-
-+++
-** The function 'key-translate' can now remove translations.
-If the second argument TO is nil, the existing key translation is
-removed.
-
-+++
-** New variables describing the names of built in programs.
-The new variables 'ctags-program-name', 'ebrowse-program-name',
-'etags-program-name', 'hexl-program-name', 'emacsclient-program-name'
-'movemail-program-name', and 'rcs2log-program-name' should be used
-instead of "ctags", "ebrowse", "etags", "hexl", "emacsclient", and
-"rcs2log", when starting one of these built in programs in a subprocess.
-
-+++
-** New variable 'case-symbols-as-words' affects case operations for symbols.
-If non-nil, then case operations such as 'upcase-initials' or
-'replace-match' (with nil FIXEDCASE) will treat the entire symbol name
-as a single word. This is useful for programming languages and styles
-where only the first letter of a symbol's name is ever capitalized.
-The default value of this variable is nil.
-
----
-** Bytecode is now always loaded eagerly.
-Bytecode compiled with older Emacs versions for lazy loading using
-'byte-compile-dynamic' is now loaded all at once.
-As a consequence, 'fetch-bytecode' has no use, does nothing, and is
-now obsolete. The variable 'byte-compile-dynamic' has no effect any
-more; compilation will always yield bytecode for eager loading.
-
-+++
-** Returned strings from functions and macros are never docstrings.
-Functions and macros whose bodies consist of a single string literal now
-only return that string, and will not use it as a docstring. Example:
-
- (defun sing-a-song ()
- "Sing a song.")
-
-The above function returns the string "Sing a song." and has no
-docstring. Previously, that string was used as both the docstring and
-return value, which was never what the programmer wanted. If you want
-the string to be a docstring, add an explicit return value.
-
-This change applies to 'defun', 'defsubst', 'defmacro' and 'lambda'
-forms; other defining forms such as 'cl-defun' already worked this way.
-
-** New or changed byte-compilation warnings
-
----
-*** Warn about missing 'lexical-binding' directive.
-The compiler now warns if an Elisp file lacks the standard
-'-*- lexical-binding: ... -*-' cookie on the first line.
-This line typically looks something like
-
- ;;; My little pony mode -*- lexical-binding: t -*-
-
-It is needed to inform the compiler about which dialect of ELisp
-your code is using: the modern dialect with lexical binding or
-the old dialect with only dynamic binding.
-
-Lexical binding avoids some name conflicts and allows the compiler to
-detect more mistakes and generate more efficient code, so it is
-recommended. For how to adapt your code to lexical binding, see the
-manual section "(elisp) Converting to Lexical Binding".
-
-If your code cannot be converted to lexical binding, you can insert
-the line
-
- ;;; -*- lexical-binding: nil -*-
-
-first in the file to declare that it uses the old dialect.
-
----
-*** Warn about empty bodies for more special forms and macros.
-The compiler now warns about an empty body argument to 'when',
-'unless', 'ignore-error' and 'with-suppressed-warnings' in addition to
-the existing warnings for 'let' and 'let*'. Example:
-
- (when (> x 2))
-
-This warning can be suppressed using 'with-suppressed-warnings' with
-the warning name 'empty-body'.
-
----
-*** Warn about quoted error names in 'condition-case' and 'ignore-error'.
-The compiler now warns about quoted condition (error) names
-in 'condition-case' and 'ignore-error'. Example:
-
- (condition-case nil
- (/ x y)
- ('arith-error "division by zero"))
-
-Quoting them adds the error name 'quote' to those handled or ignored
-respectively, which was probably not intended.
-
----
-*** Warn about comparison with literal constants without defined identity.
-The compiler now warns about comparisons by identity with a literal
-string, cons, vector, record, function, large integer or float as this
-may not match any value at all. Example:
-
- (eq x "hello")
-
-Only literals for symbols and small integers (fixnums), including
-characters, are guaranteed to have a consistent (unique) identity.
-This warning applies to 'eq', 'eql', 'memq', 'memql', 'assq', 'rassq',
-'remq' and 'delq'.
-
-To compare by (structural) value, use 'equal', 'member', 'assoc',
-'rassoc', 'remove' or 'delete' instead. Floats and bignums can also
-be compared using 'eql', '=' and 'memql'. Function literals cannot be
-compared reliably at all.
-
-This warning can be suppressed using 'with-suppressed-warnings' with
-the warning name 'suspicious'.
-
----
-*** Warn about 'condition-case' without handlers.
-The compiler now warns when the 'condition-case' form is used without
-any actual handlers, as in
-
- (condition-case nil (read buffer))
-
-because it has no effect other than the execution of the body form.
-In particular, no errors are caught or suppressed. If the intention
-was to catch all errors, add an explicit handler for 'error', or use
-'ignore-error' or 'ignore-errors'.
-
-This warning can be suppressed using 'with-suppressed-warnings' with
-the warning name 'suspicious'.
-
----
-*** Warn about 'unwind-protect' without unwind forms.
-The compiler now warns when the 'unwind-protect' form is used without
-any unwind forms, as in
-
- (unwind-protect (read buffer))
-
-because the behavior is identical to that of the argument; there is
-no protection of any kind. Perhaps the intended unwind forms have
-been misplaced or forgotten, or the use of 'unwind-protect' could be
-simplified away.
-
-This warning can be suppressed using 'with-suppressed-warnings' with
-the warning name 'suspicious'.
-
----
-*** Warn about useless trailing 'cond' clauses.
-The compiler now warns when a 'cond' form contains clauses following a
-default (unconditional) clause. Example:
-
- (cond ((= x 0) (say "none"))
- (t (say "some"))
- (say "goodbye"))
-
-Such a clause will never be executed, and is likely to be a mistake,
-perhaps due to misplaced parens.
-
-This warning can be suppressed using 'with-suppressed-warnings' with
-the warning name 'suspicious'.
-
----
-*** Warn about mutation of constant values.
-The compiler now warns about code that modifies program constants in
-some obvious cases. Examples:
-
- (setcar '(1 2) 7)
- (aset [3 4] 0 8)
- (aset "abc" 1 ?d)
-
-Such code may have unpredictable behavior because the constants are part
-of the program and are not data structures generated afresh during
-execution; the compiler does not expect them to change.
-
-To avoid the warning, operate on an object created by the program
-(maybe a copy of the constant), or use a non-destructive operation
-instead.
-
-This warning can be suppressed using 'with-suppressed-warnings' with
-the warning name 'mutate-constant'.
-
----
-*** Warn about more ignored function return values.
-The compiler now warns when the return value from certain functions is
-implicitly ignored. Example:
-
- (progn (nreverse my-list) my-list)
-
-will elicit a warning because it is usually pointless to call
-'nreverse' on a list without using the returned value.
-
-To silence the warning, make use of the value in some way, such as
-assigning it to a variable. You can also wrap the function call in
-'(ignore ...)', or use 'with-suppressed-warnings' with the warning
-name 'ignored-return-value'.
-
-The warning will only be issued for calls to functions declared
-'important-return-value' or 'side-effect-free' (but not 'error-free').
-
----
-*** Warn about docstrings that contain control characters.
-The compiler now warns about docstrings with control characters other
-than newline and tab. This is often a result of improper escaping.
-Example:
-
- (defun my-fun ()
- "Uses c:\remote\dir\files and the key \C-x."
- ...)
-
-where the docstring contains the four control characters 'CR', 'DEL',
-'FF' and 'C-x'.
-
-The warning name is 'docstrings-control-chars'.
-
----
-*** The warning about wide docstrings can now be disabled separately.
-Its warning name is 'docstrings-wide'.
-
-+++
-** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases.
-Previously, 'fset', 'defalias' and 'defvaralias' could be made to
-build circular function and variable indirection chains as in
-
- (defalias 'able 'baker)
- (defalias 'baker 'able)
-
-but trying to use them would sometimes make Emacs hang. Now, an attempt
-to create such a loop results in an error.
-
-Since circular alias chains now cannot occur, 'function-alias-p',
-'indirect-function' and 'indirect-variable' will never signal an error.
-Their 'noerror' arguments have no effect and are therefore obsolete.
-
-** Touch Screen support
-
-+++
-*** 'x-popup-menu' now understands touch screen events.
-When a 'touchscreen-begin' or 'touchscreen-end' event is passed as the
-POSITION argument, it will behave as if that event was a mouse event.
-
-+++
-*** New functions for handling touch screen events.
-The new functions 'touch-screen-track-tap' and 'touch-screen-track-drag'
-handle tracking common touch screen gestures from within a command.
-
-+++
-*** New parameter to 'touchscreen-end' events.
-CANCEL non-nil establishes that the touch sequence has been intercepted
-by programs such as window managers and should be ignored with Emacs.
-
----
-** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill.
-
-+++
-** New variable 'secondary-tool-bar-map'.
-If non-nil, this variable contains a keymap of menu items that are
-displayed along tool bar items defined by 'tool-bar-map'. These items
-are displayed below the tool bar if the value of 'tool-bar-position' is
-'top', and above it if the value is 'bottom'. This is used by
-'modifier-bar-mode'.
-
----
-** New variable 'completion-lazy-hilit'.
-Lisp programs that present completion candidates may bind this
-variable non-nil around calls to functions such as
-'completion-all-completions'. This tells the underlying completion
-styles to skip eager fontification of completion candidates, which
-improves performance. Such a Lisp program can then use the
-'completion-lazy-hilit' function to fontify candidates just in time.
-
-+++
-** New primitive 'buffer-last-name'.
-It returns the name of a buffer before the last time it was renamed or
-killed.
-
-+++
-** New primitive 'marker-last-position'.
-It returns the last position of a marker in its buffer even if that
-buffer has been killed. ('marker-position' would return nil in that
-case.)
-
-** Functions and variables to transpose sexps
-
----
-*** New helper variable 'transpose-sexps-function'.
-Lisp programs can now set this variable to customize the behavior of the
-'transpose-sexps' command.
-
----
-*** New function 'transpose-sexps-default-function'.
-The previous implementation of 'transpose-sexps' was moved into its own
-function, to be used in 'transpose-sexps-function'.
-
----
-*** New function 'treesit-transpose-sexps'.
-Tree-sitter now unconditionally sets 'transpose-sexps-function' for all
-tree-sitter enabled modes to this function.
-
-** Functions and variables to move by program statements
-
-+++
-*** New variable 'forward-sentence-function'.
-Major modes can now set this variable to customize the behavior of the
-'forward-sentence' command.
-
----
-*** New function 'forward-sentence-default-function'.
-The previous implementation of 'forward-sentence' is moved into its
-own function, to be bound by 'forward-sentence-function'.
-
-+++
-*** New function 'treesit-forward-sentence'.
-All tree-sitter enabled modes that define 'sentence' in
-'treesit-thing-settings' now set 'forward-sentence-function' to call
-'treesit-forward-sentence'.
-
-** Functions and variables to move by program sexps
-
-+++
-*** New function 'treesit-forward-sexp'.
-Tree-sitter conditionally sets 'forward-sexp-function' for major modes
-that have defined 'sexp' in 'treesit-thing-settings' to enable
-sexp-related motion commands.
-
----
-** New user option 'native-comp-async-warnings-errors-kind'.
-It allows control of what kinds of warnings and errors from asynchronous
-native compilation are reported to the parent Emacs process. The
-default is to report all errors and only important warnings. If you
-were used to customizing 'native-comp-async-report-warnings-errors' to
-nil or 'silent', we suggest that you now leave it at its default value,
-and see if you get only warnings that matter.
-
-** Function 'declare' forms
-
-+++
-*** New 'ftype' function declaration.
-The declaration '(ftype TYPE)' specifies the type of a function.
-Example:
-
- (defun hello (x y)
- (declare (ftype (function (integer boolean) string)))
- ...)
-
-specifies that the function takes two arguments, an integer and a
-boolean, and returns a string. If the compilation happens with
-'compilation-safety' set to zero, this information can be used by the
-native compiler to produce better code, but specifying an incorrect type
-may lead to Emacs crashing. See the Info node "(elisp) Declare Form"
-for further information.
-
-+++
-*** New 'important-return-value' function declaration and property.
-The declaration '(important-return-value t)' sets the
-'important-return-value' property which indicates that the function
-return value should probably not be thrown away implicitly.
-
-+++
-** New functions 'file-user-uid' and 'file-group-gid'.
-These functions are like 'user-uid' and 'group-gid', respectively, but
-are aware of file name handlers, so they will return the remote UID or
-GID for remote files (or -1 if the connection has no associated user).
-
-+++
-** 'treesit-font-lock-rules' now accepts additional global keywords.
-When supplied with ':default-language LANGUAGE', rules after it will
-default to use 'LANGUAGE'.
-
----
-** New optional argument to 'modify-dir-local-variable'.
-A 5th argument, optional, has been added to
-'modify-dir-local-variable'. It can be used to specify which
-dir-locals file to modify.
-
-** Connection local variables
-
-+++
-*** New macros 'connection-local-p' and 'connection-local-value'.
-The former macro returns non-nil if a variable has a connection-local
-binding. The latter macro returns the connection-local value of a
-variable if any, or its current value.
-
-** Hash tables
-
-+++
-*** ':rehash-size' and ':rehash-threshold' args no longer have any effect.
-These keyword arguments are now ignored by 'make-hash-table'. Emacs
-manages the memory for all hash table objects in the same way.
-The functions 'hash-table-rehash-size' and 'hash-table-rehash-threshold'
-remain for compatibility but now always return the old default values.
-
-+++
-*** The printed representation has been shrunk and simplified.
-The 'test' parameter is omitted if it is 'eql' (the default), as is
-'data' if empty. 'rehash-size', 'rehash-threshold' and 'size' are
-always omitted, and ignored if present when the object is read back in.
-
-** Obarrays
-
-+++
-*** New obarray type.
-Obarrays are now represented by an opaque type instead of using vectors.
-They are created by 'obarray-make' and manage their internal storage
-automatically, which means that the size parameter to 'obarray-make' can
-safely be omitted. That is, they do not become slower as they fill up.
-
-The old vector representation is still accepted by functions operating
-on obarrays, but 'obarrayp' only returns t for obarray objects.
-'type-of' now returns 'obarray' for obarray objects.
-
-Old code which (incorrectly) created "obarrays" as Lisp vectors filled
-with something other than 0, as in '(make-vector N nil)', will no longer
-work, and should be rewritten to use 'obarray-make'. Alternatively, you
-can fill the vector with 0.
-
-+++
-*** New function 'obarray-clear' removes all symbols from an obarray.
-
----
-*** 'obarray-size' and 'obarray-default-size' are now obsolete.
-They pertained to the internal storage size which is now irrelevant.
-
-+++
-** 'treesit-install-language-grammar' can handle local directory instead of URL.
-It is now possible to pass a directory of a local repository as URL
-inside 'treesit-language-source-alist', so that calling
-'treesit-install-language-grammar' would avoid cloning the repository.
-It may be useful, for example, for the purposes of bisecting a
-treesitter grammar.
-
-+++
-** New buffer-local variable 'tabulated-list-groups'.
-It controls display and separate sorting of groups of entries.
-
-+++
-** New variable 'revert-buffer-restore-functions'.
-It helps to preserve various states after reverting the buffer.
-
----
-** New text property 'context-menu-functions'.
-Like the variable with the same name, it adds menus from the list that
-is the value of the property to context menus shown when clicking on the
-text which as this property.
-
----
-** Detecting the end of an iteration of a keyboard macro.
-'read-event', 'read-char', and 'read-char-exclusive' no longer return -1
-when called at the end of an iteration of the execution of a keyboard
-macro. Instead, they will transparently continue reading available input
-(e.g., from the keyboard). If you need to detect the end of a macro
-iteration, check the following condition before calling one of the
-aforementioned functions:
-
- (and (arrayp executing-kbd-macro)
- (>= executing-kbd-macro-index (length executing-kbd-macro)))
-
-+++
-** 'vtable-update-object' updates an existing object with just two arguments.
-It is now possible to update the representation of an object in a vtable
-by calling 'vtable-update-object' with just the vtable and the object as
-arguments. (Previously, the OLD-OBJECT argument was required which, in
-this case, would mean repeating the object in the argument list.) When
-replacing an object with a different one, passing both the new and old
-objects is still necessary.
-
-** 'vtable-insert-object' can insert "before" or at an index.
-The signature of 'vtable-insert-object' has changed and is now:
-
- (vtable-insert-object TABLE OBJECT &optional LOCATION BEFORE)
-
-LOCATION corresponds to the old AFTER-OBJECT argument; if BEFORE is
-non-nil, the new object is inserted before the LOCATION object, making
-it possible to insert a new object at the top of the table. (Before,
-this was not possible.) In addition, LOCATION can be an integer, a
-(zero-based) index into the table at which the new object is inserted
-(BEFORE is ignored in this case).
-
-+++
-** New function 'sqlite-execute-batch'.
-This function lets the user execute multiple SQL statements in one go.
-It is useful, for example, when a Lisp program needs to evaluate an
-entire SQL file.
-
-** JSON
-
----
-*** The parser keeps duplicated object keys in alist and plist output.
-A JSON object such as '{"a":1,"a":2}' will now be translated into the
-Lisp values '((a . 1) (a . 2))' or '(:a 1 :a 2)' if alist or plist
-object types are requested.
-
----
-*** The parser sometimes signals different types of errors.
-It will now signal 'json-utf8-decode-error' for inputs that are not
-correctly UTF-8 encoded.
-
----
-*** The parser and encoder now accept arbitrarily large integers.
-Previously, they were limited to the range of signed 64-bit integers.
-
-** New tree-sitter functions and variables for defining and using "things"
-
-+++
-*** New variable 'treesit-thing-settings'.
-It allows modes to define "things" like 'defun', 'text', 'sexp', and
-'sentence' for navigation commands and tree-traversal functions.
-
-+++
-*** New functions for navigating "things".
-There are new navigation functions 'treesit-thing-prev',
-'treesit-thing-next', 'treesit-navigate-thing',
-'treesit-beginning-of-thing', and 'treesit-end-of-thing'.
-
-+++
-*** New functions 'treesit-thing-at', 'treesit-thing-at-point'.
-
-+++
-*** Tree-traversing functions.
-The functions 'treesit-search-subtree', 'treesit-search-forward',
-'treesit-search-forward-goto', and 'treesit-induce-sparse-tree' now
-accept more kinds of predicates. Lisp programs can now use thing
-symbols (defined in 'treesit-thing-settings') and any thing definitions
-for the predicate argument.
-
-** Other tree-sitter function and variable changes
-
-+++
-*** 'treesit-parser-list' now takes additional optional arguments.
-The additional arguments are LANGUAGE and TAG. If LANGUAGE is given,
-only return parsers for that language. If TAG is given, only return
-parsers with that tag. Note that passing nil as tag doesn't mean return
-all parsers, but rather "all parsers with no tags".
-
-+++
-*** New variable 'treesit-primary-parser'.
-This variable should be set by multi-langauge major modes before calling
-'treesit-major-mode-setup', in order for tree-sitter integration
-functionalities to operate correctly.
+* Lisp Changes in Emacs 31.1
-* Changes in Emacs 30.1 on Non-Free Operating Systems
-
-** MS-Windows
-
-+++
-*** You can now opt out of following MS-Windows' Dark mode.
-By default, Emacs on MS-Windows follows the system's Dark mode for its
-title bars' and scroll bars' appearance. If the new user option
-'w32-follow-system-dark-mode' is customized to the nil value, Emacs
-will disregard the system's Dark mode and will always use the default
-Light mode.
-
----
-*** You can now use Image-Dired even if the 'convert' program is not installed.
-If you don't have GraphicsMagick or ImageMagick installed, and thus the
-'gm convert'/'convert' program is not available, Emacs on MS-Windows
-will now use its own function 'w32image-create-thumbnail' to create
-thumbnail images and show them in the thumbnail buffer. Unlike with
-using 'convert', this fallback method is synchronous, so Emacs will wait
-until all the thumbnails are created and displayed, before showing them.
+* Changes in Emacs 31.1 on Non-Free Operating Systems
---
-*** Emacs on MS-Windows now supports the ':stipple' face attribute.
+** Process execution has been optimized on Android.
+The run-time performance of subprocesses on recent Android releases
+where a userspace executable loader is required has been optimized on
+systems featuring Linux 3.5.0 and above.
----------------------------------------------------------------------
diff --git a/etc/NEWS.30 b/etc/NEWS.30
new file mode 100644
index 00000000000..31d69ddabab
--- /dev/null
+++ b/etc/NEWS.30
@@ -0,0 +1,3145 @@
+GNU Emacs NEWS -- history of user-visible changes.
+
+Copyright (C) 2022-2024 Free Software Foundation, Inc.
+See the end of the file for license conditions.
+
+Please send Emacs bug reports to 'bug-gnu-emacs@gnu.org'.
+If possible, use 'M-x report-emacs-bug'.
+
+This file is about changes in Emacs version 30.
+
+See file HISTORY for a list of GNU Emacs versions and release dates.
+See files NEWS.29, NEWS.28, ..., NEWS.18, and NEWS.1-17 for changes
+in older Emacs versions.
+
+You can narrow news to a specific version by calling 'view-emacs-news'
+with a prefix argument or by typing 'C-u C-h C-n'.
+
+Temporary note:
++++ indicates that all relevant manuals in doc/ have been updated.
+--- means no change in the manuals is needed.
+When you add a new item, use the appropriate mark if you are sure it
+applies, and please also update docstrings as needed.
+
+
+* Installation Changes in Emacs 30.1
+
+---
+** Native compilation is now enabled by default.
+'configure' will enable the Emacs Lisp native compiler, so long as
+libgccjit is present and functional on the system. To disable native
+compilation, configure Emacs with the option:
+
+ ./configure --with-native-compilation=no
+
++++
+** Emacs has been ported to the Android operating system.
+This requires Emacs to be compiled on another computer. The Android
+NDK, SDK, and a suitable Java compiler must also be installed.
+
+See the file "java/INSTALL" for more details.
+
+---
+** Native JSON support is now always available; libjansson is no longer used.
+No external library is required. The '--with-json' configure option has
+been removed. 'json-available-p' now always returns non-nil and is only
+kept for compatibility.
+
+---
+** Emacs now defaults to the ossaudio library for sound on NetBSD and OpenBSD.
+Previously, configure used ALSA libraries if installed on the system
+when configured '--with-sound=yes' (which is the default), with fallback
+to libossaudio. The libossaudio library included with the base system
+is now used even if ALSA is found to avoid relying on external packages
+and to resolve potential incompatibilities between GNU/Linux and *BSD
+versions of ALSA. Use '--with-sound=alsa' to build with ALSA on these
+operating systems instead.
+
+
+* Startup Changes in Emacs 30.1
+
+---
+** On GNU/Linux, Emacs is now the default application for 'org-protocol'.
+Org mode provides a way to quickly capture bookmarks, notes, and links
+using 'emacsclient':
+
+ emacsclient "org-protocol://store-link?url=URL&title=TITLE"
+
+Previously, users had to manually configure their GNU/Linux desktop
+environment to open 'org-protocol' links in Emacs. These links should
+now open in Emacs automatically, as the "emacsclient.desktop" file now
+arranges for Emacs to be the default application for the 'org-protocol'
+URI scheme. See the Org mode manual, Info node "(org) Protocols" for
+more details.
+
++++
+** New variable lets Lisp code read emacsclient arguments.
+When '--eval' is passed to emacsclient and Emacs is evaluating each
+argument, the new variable 'server-eval-args-left' is set to those
+arguments not yet evaluated. It can be used by Lisp code to 'pop'
+arguments and process them by the function called in the '--eval'
+expression, which is useful when those arguments contain arbitrary
+characters that otherwise might require elaborate and error-prone
+escaping (to protect them from the shell).
+
+
+* Incompatible Changes in Emacs 30.1
+
+---
+** Tree-Sitter modes are now declared as submodes of the non-TS modes.
+In order to help the use of those Tree-Sitter modes, they are now
+declared to have the corresponding non-Tree-Sitter mode as an
+additional parent.
+This way, things like ".dir-locals.el" settings, and YASnippet
+collections of snippets automatically apply to the new Tree-Sitter modes.
+
+Note that those modes still do not inherit from the non-TS mode, so
+configuration settings installed via mode hooks are not affected.
+
+---
+** Mouse wheel events should now always be 'wheel-up/down/left/right'.
+At those places where the old 'mouse-4/5/6/7' events could still occur
+(i.e., X11 input in the absence of XInput2, and 'xterm-mouse-mode'),
+we remap them to the corresponding 'wheel-up/down/left/right' event,
+according to the new user option 'mouse-wheel-buttons'.
+The old variables 'mouse-wheel-up-event', 'mouse-wheel-down-event',
+'mouse-wheel-left-event', and 'mouse-wheel-right-event' are thereby
+obsolete.
+
++++
+** 'completion-auto-help' now affects 'icomplete-in-buffer'.
+Previously, 'completion-auto-help' mostly affected only minibuffer
+completion. Now, if 'completion-auto-help' has the value 'lazy', then
+Icomplete's in-buffer display of possible completions will only appear
+after the 'completion-at-point' command has been invoked twice, and if
+'completion-auto-help' is nil, then Icomplete's in-buffer display is
+completely suppressed. Thus, if you use 'icomplete-in-buffer', ensure
+'completion-auto-help' is not customized to 'lazy' or nil.
+
++++
+** The "*Completions*" buffer now always accompanies 'icomplete-in-buffer'.
+Previously, it was not consistent whether the "*Completions*" buffer would
+appear when using 'icomplete-in-buffer'. Now the "*Completions*" buffer
+and Icomplete's in-buffer display of possible completions always
+appear together. If you would prefer to see only Icomplete's
+in-buffer display, and not the "*Completions*" buffer, you can add this
+to your init file:
+
+ (advice-add 'completion-at-point :after #'minibuffer-hide-completions)
+
+---
+** The default process filter was rewritten in native code.
+The round-trip through the Lisp function
+'internal-default-process-filter' is skipped when the process filter is
+the default one. It is reimplemented in native code, reducing GC churn.
+To undo this change, set 'fast-read-process-output' to nil.
+
++++
+** The Network Security Manager now warns about 3DES by default.
+This cypher is no longer recommended owing to a major vulnerability
+disclosed in 2016, and its small 112 bit key size. Emacs now warns
+about its use also when 'network-security-level' is set to 'medium'
+(the default). See 'network-security-protocol-checks'.
+
+---
+** The Network Security Manager now warns about <2048 bits in DH key exchange.
+Emacs used to warn for Diffie-Hellman key exchanges with prime numbers
+smaller than 1024 bits. Since more servers now support it, this
+number has been bumped to 2048 bits.
+
++++
+** URL now never sends user email addresses in HTTP requests.
+Emacs never sent email addresses by default, but it used to be
+possible to customize 'url-privacy-level' so that the users email
+address was sent along in HTTP requests. This feature has now been
+removed, as it was considered more dangerous than useful. RFC 9110
+(§ 10.1.2) also recommends against it. The user option
+'url-personal-mail-address' is now also obsolete.
+
+To send an email address in the header of individual HTTP requests,
+see the variable 'url-request-extra-headers'.
+
+
+* Changes in Emacs 30.1
+
+---
+** Emacs now supports Unicode Standard version 15.1.
+
++++
+** Emacs now comes with Org v9.7.
+See the file "etc/ORG-NEWS" for user-visible changes in Org.
+
++++
+** Improved support for touchscreen devices.
+On systems that understand them (at present X, Android, PGTK, and
+MS-Windows), many touch screen gestures are now implemented and
+translated into mouse or gesture events, and support for tapping tool
+bar buttons and opening menus has been added. Countless packages, such
+as Dired and Custom, have been adjusted to better understand touch
+screen input.
+
++++
+** Support for styled underline face attributes.
+These are implemented as new values of the 'style' attribute in a face
+underline specification, 'double-line', 'dots', and 'dashes', and are
+available on GUI systems. If your terminal's termcap or terminfo
+database entry defines the 'Su' or 'Smulx' capability, Emacs will also
+emit the prescribed escape sequence to render faces with such styles on
+TTY frames.
+
+---
+** Support for underline colors on TTY frames.
+Colors specified in the underline face will now also be displayed on TTY
+frames on terminals that support the 'Su' or 'Smulx' capabilities.
+
++++
+** Modeline elements can now be right-aligned.
+Anything following the symbol 'mode-line-format-right-align' in
+'mode-line-format' will be right-aligned. Exactly where it is
+right-aligned to is controlled by the new user option
+'mode-line-right-align-edge'.
+
+---
+** X selection requests are now handled much faster and asynchronously.
+This means it should be less necessary to disable the likes of
+'select-active-regions' when Emacs is running over a slow network
+connection.
+
+---
+** Emacs now updates invisible frames that are made visible by a compositor.
+If an invisible or an iconified frame is shown to the user by the
+compositing manager, Emacs will now redisplay such a frame even though
+'frame-visible-p' returns nil or 'icon' for it. This can happen, for
+example, as part of preview for iconified frames.
+
++++
+** Most file notification backends detect unmounting of a watched filesystem.
+The only exception is w32notify.
+
++++
+** The ':map' property of images is now recomputed when image is transformed.
+Images with clickable maps now work as expected after you run commands
+such as 'image-increase-size', 'image-decrease-size', 'image-rotate',
+'image-flip-horizontally', and 'image-flip-vertically'.
+Set the new user option 'image-recompute-map-p' to nil to prevent Emacs
+from recomputing image maps.
+
+** Minibuffer and Completions
+
++++
+*** New commands 'previous-line-completion' and 'next-line-completion'.
+Bound to '<up>' and '<down>' arrow keys, respectively, they navigate
+the "*Completions*" buffer vertically by lines, wrapping at the
+top/bottom when 'completion-auto-wrap' is non-nil.
+
++++
+*** New user option 'minibuffer-visible-completions'.
+When customized to non-nil, you can use arrow keys in the minibuffer
+to navigate the completions displayed in the "*Completions*" window.
+Typing 'RET' selects the highlighted candidate. 'C-g' hides the
+completions window. When the completions window is not visible,
+then all these keys have their usual meaning in the minibuffer.
+This option is supported for in-buffer completion as well.
+
+---
+*** Selected completion candidates are deselected on typing.
+When you type at the minibuffer prompt, the current completion
+candidate will be un-highlighted, and point in the "*Completions*" window
+will be moved off that candidate. 'minibuffer-choose-completion'
+('M-RET') will still choose a previously-selected completion
+candidate, but the new command 'minibuffer-choose-completion-or-exit'
+(bound to 'RET' by 'minibuffer-visible-completions') will exit with
+the minibuffer contents instead. This deselection behavior can be
+controlled with the new user option 'completion-auto-deselect', which
+is t by default.
+
++++
+*** New value 'historical' for user option 'completions-sort'.
+When 'completions-sort' is set to 'historical', completion candidates
+will be first sorted alphabetically, and then re-sorted by their order
+in the minibuffer history, with more recent candidates appearing first.
+
++++
+*** 'completion-category-overrides' supports more metadata.
+The new supported completion properties are 'cycle-sort-function',
+'display-sort-function', 'annotation-function', 'affixation-function',
+and 'group-function'. You can now customize them for any category in
+'completion-category-overrides' that will override the properties
+defined in completion metadata.
+
++++
+*** 'completion-extra-properties' supports more metadata.
+The new supported completion properties are 'category',
+'group-function', 'display-sort-function', and 'cycle-sort-function'.
+
+** Windows
+
++++
+*** New command 'toggle-window-dedicated'.
+This makes it easy to interactively mark a specific window as
+dedicated, so it won't be reused by 'display-buffer'. This can be
+useful for complicated window setups. It is bound to 'C-x w d'
+globally.
+
++++
+*** "d" in the mode line now indicates that the window is dedicated.
+Windows have always been able to be dedicated to a specific buffer;
+see 'window-dedicated-p'. Now the mode line indicates the dedicated
+status of a window, with "d" appearing in the mode line if a window is
+dedicated and "D" if the window is strongly dedicated. This indicator
+appears before the buffer name, and after the buffer modification and
+remote buffer indicators (usually "---" together).
+
++++
+*** New action alist entry 'some-window' for 'display-buffer'.
+It specifies which window 'display-buffer-use-some-window' should prefer.
+For example, when 'display-buffer-base-action' is customized to
+'(nil . ((some-window . mru)))', then a buffer will be displayed
+in the same most recently used window from consecutive calls of
+'display-buffer' (in a configuration with more than two windows).
+
++++
+*** New action alist entry 'category' for 'display-buffer'.
+If the caller of 'display-buffer' passes '(category . symbol)'
+in its 'action' argument, you can match the displayed buffer
+by adding '(category . symbol)' to the condition part of
+'display-buffer-alist' entries.
+
++++
+*** New action alist entry 'post-command-select-window' for 'display-buffer'.
+It specifies whether the window of the displayed buffer should be
+selected or deselected at the end of executing the current command.
+
++++
+*** New variable 'window-restore-killed-buffer-windows'.
+It specifies how 'set-window-configuration' and 'window-state-put'
+should proceed with windows whose buffer was killed after the
+corresponding configuration or state was recorded.
+
+---
+*** New variable 'window-point-context-set-function'.
+It can be used to set a context for window point in all windows by
+'window-point-context-set' before calling 'current-window-configuration'
+and 'window-state-get'. Then later another new variable
+'window-point-context-use-function' can be used by
+'window-point-context-use' after 'set-window-configuration' and
+'window-state-put' to restore positions of window points
+according to the context stored in a window parameter.
+
++++
+*** New functions 'set-window-cursor-type' and 'window-cursor-type'.
+'set-window-cursor-type' sets a per-window cursor type, and
+'window-cursor-type' queries this setting for a given window. Windows
+are always created with a 'window-cursor-type' of t, which means to
+consult the variable 'cursor-type' as before.
+
+---
+*** The user option 'display-comint-buffer-action' is now obsolete.
+You can use a '(category . comint)' condition in 'display-buffer-alist'
+to match buffers displayed by comint-related commands. Another
+user option 'display-tex-shell-buffer-action' is obsolete too
+for which you can use '(category . tex-shell)'.
+
+** Tool bars
+
++++
+*** Tool bars can now be placed on the bottom on more systems.
+The 'tool-bar-position' frame parameter can be set to 'bottom' on all
+window systems other than macOS and GNUstep (Nextstep).
+
++++
+*** New global minor mode 'modifier-bar-mode'.
+When this minor mode is enabled, the tool bar displays buttons
+representing modifier keys. Clicking on these buttons applies the
+corresponding modifiers to the next input event.
+
++++
+*** New user option 'tool-bar-always-show-default'.
+When non-nil, the tool bar at the top of a frame does not show buffer
+local customization of the tool bar. The default value is nil.
+
+** Tab Bars and Tab Lines
+
+---
+*** New user option 'tab-bar-select-restore-context'.
+It uses 'window-point-context-set' to save contexts where
+window points were located before switching away from the tab,
+and 'window-point-context-use' to restore positions of window
+points after switching back to that tab.
+
+---
+*** New user option 'tab-bar-select-restore-windows'.
+It defines what to do with windows whose buffer was killed since the tab
+was last selected. By default it displays a placeholder buffer
+with the name " *Old buffer <name>*" that provides information about
+the name of the killed buffer that was displayed in that window.
+
+---
+*** New user option 'tab-bar-tab-name-format-functions'.
+It can be used to add, remove and reorder functions that change the
+appearance of every tab on the tab bar.
+
+---
+*** New user option 'tab-line-tabs-buffer-group-function'.
+It provides two choices to group tab buffers by major mode and by
+project name.
+
+---
+*** New hook 'tab-bar-tab-post-select-functions'.
+
+---
+*** New keymap 'tab-bar-mode-map'.
+By default it contains a keybinding 'C-TAB' to switch tabs, but only
+when 'C-TAB' is not bound globally. You can unbind it if it conflicts
+with 'C-TAB' in other modes.
+
+---
+*** New keymap 'tab-line-mode-map'.
+By default it contains keybindings for switching tabs: 'C-x <left>',
+'C-x <right>', 'C-x C-<left>', 'C-x C-<right>'. You can unbind them if
+you want to use these keys for the commands 'previous-buffer' and
+'next-buffer'.
+
+---
+*** Default list of tabs is changed to support a fixed order.
+This means that 'tab-line-tabs-fixed-window-buffers', the new default
+tabs function, is like the previous 'tab-line-tabs-window-buffers' where
+both of them show only buffers that were previously displayed in the
+window. But the difference is that the new function always keeps the
+original order of buffers on the tab line, even after switching between
+these buffers. You can drag the tabs and release at a new position
+to manually reorder the buffers on the tab line.
+
+---
+*** Buffers on group tabs are now sorted alphabetically.
+This will keep the fixed order of tabs, even after switching between
+them.
+
+** Help
+
++++
+*** New command 'help-find-source'.
+Switch to a buffer visiting the source of what is being described in
+"*Help*". It is bound to 'C-h 4 s' globally.
+
+---
+*** New user option 'describe-bindings-outline-rules'.
+This user option controls outline visibility in the output buffer of
+'describe-bindings' when 'describe-bindings-outline' is non-nil.
+
+---
+*** 'describe-function' shows the function inferred type when available.
+For native compiled Lisp functions, 'describe-function' prints (after
+the signature) the automatically inferred function type as well.
+
+---
+*** 'describe-function' now shows the type of the function object.
+The text used to say things like "car is a built-in function" whereas it
+now says "car is a primitive-function" where "primitive-function" is the
+the name of the symbol returned by 'cl-type-of'. You can click on those
+words to get information about that type.
+
+---
+*** 'C-h m' ('describe-mode') uses outlining by default.
+Set 'describe-mode-outline' to nil to get back the old behavior.
+
+---
+*** 'C-h k' ('describe-key') shows Unicode name.
+For keybindings which produce single characters via translation or input
+methods, 'C-h k' now shows the Unicode name of the produced character in
+addition to the character itself, e.g.
+
+'C-h k C-x 8 E' =>
+
+ € 'EURO SIGN' (translated from C-x 8 E)
+
+---
+*** 'C-h b' ('describe-bindings') shows Unicode names.
+For keybindings which produce single characters via translation (such as
+those using the 'C-x 8' or 'A-' prefix, or 'dead-acute', 'dead-grave',
+etc), the Unicode names will now be shown in addition to the character
+itself, i.e.
+
+ A-! ¡ INVERTED EXCLAMATION MARK
+ A-$ ¤ CURRENCY SIGN
+
+and so on.
+
++++
+*** Multi-character key echo now ends with a suggestion to use Help.
+Customize 'echo-keystrokes-help' to nil to prevent that.
+
+** Customize
+
++++
+*** New command 'customize-dirlocals'.
+This command pops up a buffer to edit the settings in ".dir-locals.el".
+
+---
+*** New command 'customize-toggle-option'.
+This command can toggle boolean options for the duration of a session.
+
++++
+*** New prefix argument for modifying directory-local variables.
+The commands 'add-dir-local-variable', 'delete-dir-local-variable' and
+'copy-file-locals-to-dir-locals' now take an optional prefix argument,
+to enter the file name where you want to modify directory-local
+variables.
+
++++
+*** New user option 'safe-local-variable-directories'.
+This user option names directories in which Emacs will treat all
+directory-local variables as safe.
+
++++
+** CL Print
+
++++
+*** There is a new chapter in the CL manual documenting cl-print.el.
+See the Info node "(cl) Printing".
+
++++
+*** You can expand the "..." truncation everywhere.
+The code that allowed "..." to be expanded in the "*Backtrace*" buffer
+should now work anywhere the data is generated by 'cl-print'.
+
++++
+*** The 'backtrace-ellipsis' button is replaced by 'cl-print-ellipsis'.
+
++++
+*** hash-tables' contents can be expanded via the ellipsis.
+
++++
+*** Modes can control the expansion via 'cl-print-expand-ellipsis-function'.
+
++++
+*** New setting 'raw' for 'cl-print-compiled'.
+This setting causes byte-compiled functions to be printed in full by
+'prin1'. A button on this output can be activated to disassemble the
+function.
+
+** Miscellaneous
+
++++
+*** New command 'kill-matching-buffers-no-ask'.
+This works like 'kill-matching-buffers', but without asking for
+confirmation.
+
++++
+*** 'recover-file' can show diffs between auto save file and current file.
+When answering the prompt with "diff" or "=", it now shows the diffs
+between the auto save file and the current file.
+
++++
+*** 'read-passwd' can toggle the visibility of passwords.
+Use 'TAB' in the minibuffer to show or hide the password.
+Alternatively, click the new show-password icon on the mode-line with
+'mouse-1' to toggle the visibility of the password.
+
+*** 'advice-remove' is now an interactive command.
+When called interactively, 'advice-remove' now prompts for an advised
+function to the advice to remove.
+
+---
+*** New user option 'uniquify-dirname-transform'.
+This can be used to customize how buffer names are uniquified, by
+making arbitrary transforms on the buffer's directory name (whose
+components are used to uniquify buffer names when they clash). You
+can use this to distinguish between buffers visiting files with the
+same base name that belong to different projects by using the provided
+transform function 'project-uniquify-dirname-transform'.
+
++++
+*** New user option 'remote-file-name-inhibit-delete-by-moving-to-trash'.
+When non-nil, this option suppresses moving remote files to the local
+trash when deleting. Default is nil.
+
+---
+*** New user option 'remote-file-name-inhibit-auto-save'.
+If this user option is non-nil, 'auto-save-mode' will not auto-save
+remote buffers. The default is nil.
+
++++
+*** New user option 'remote-file-name-access-timeout'.
+If a positive number, this option limits the call of 'access-file'
+for remote files to that number of seconds. Default is nil.
+
++++
+*** New user option 'yes-or-no-prompt'.
+This allows the user to customize the prompt that is appended by
+'yes-or-no-p' when asking questions. The default value is
+"(yes or no) ".
+
+---
+*** New user option 'menu-bar-close-window'.
+When non-nil, selecting "Close" from the "File" menu or clicking
+"Close" in the tool bar will result in the current window being
+deleted, if possible. The default is nil, and these gestures kill the
+buffer shown in the current window, but don't delete the window.
+
+---
+*** New face 'display-time-date-and-time'.
+This is used for displaying the time and date components of
+'display-time-mode'.
+
+---
+*** New face 'appt-notification' for 'appt-display-mode-line'.
+It can be used to customize the look of the appointment notification
+displayed on the mode line when 'appt-display-mode-line' is non-nil.
+
+---
+*** New icon images for general use.
+Several symbolic icons have been added to "etc/images/symbols",
+including plus, minus, check-mark, star, etc.
+
+---
+*** Emacs now recognizes shebang lines that pass '-S'/'--split-string' to 'env'.
+When visiting a script that invokes 'env -S INTERPRETER ARGS...' in
+its shebang line, Emacs will now skip over 'env -S' and deduce the
+major mode based on the interpreter after 'env -S'.
+
+*** 'insert-directory-program' is now a user option.
+On *BSD and macOS systems, this user option now defaults to the "gls"
+executable, if it exists. This should remove the need to change its
+value when installing GNU coreutils using something like ports or
+Homebrew.
+
++++
+*** 'write-region-inhibit-fsync' now defaults to t in interactive mode.
+This is the default in batch mode since Emacs 24.
+
+---
+*** The default value of 'read-process-output-max' was increased to 65536.
+
++++
+*** 'url-gateway-broken-resolution' is now obsolete.
+This option was intended for use on SunOS 4.x and Ultrix systems,
+neither of which have been supported by Emacs since version 23.1.
+The user option 'url-gateway-nslookup-program' and the command
+'url-gateway-nslookup-host' are consequently also obsolete.
+
+
+* Editing Changes in Emacs 30.1
+
++++
+** New minor mode 'visual-wrap-prefix-mode'.
+When enabled, continuation lines displayed for a wrapped long line
+will receive a 'wrap-prefix' automatically computed from the line's
+surrounding context, such that continuation lines are indented on
+display as if they were filled with 'M-q' or similar. Unlike 'M-q',
+the indentation only happens on display, and doesn't change the buffer
+text in any way. The global minor mode
+'global-visual-wrap-prefix-mode' enables this minor mode in all
+buffers.
+
+(This minor mode is the 'adaptive-wrap' ELPA package renamed and
+lightly edited for inclusion in Emacs.)
+
++++
+** New global minor mode 'kill-ring-deindent-mode'.
+When enabled, text being saved to the kill ring will be de-indented by
+the column number at its start. For example, saving the entire
+function call within an indented block:
+
+foo ()
+{
+ long_function_with_several_arguments (argument_1_compute (),
+ argument_2_compute (),
+ argument_3_compute ());
+}
+
+will save this to the kill ring:
+
+long_function_with_several_arguments (argument_1_compute (),
+ argument_2_compute (),
+ argument_3_compute ())
+
+This omits the two columns of extra indentation that would otherwise be
+copied from the second and third lines and saved to the kill ring.
+
+---
+** New command 'replace-regexp-as-diff'.
+It reads a regexp to search for and a string to replace with, then
+displays a buffer with replacements as diffs. After reviewing the
+changes in the output buffer you can apply the replacements as
+a patch to the current file buffer. There are also new commands
+'multi-file-replace-regexp-as-diff' that shows as diffs replacements
+in a list of specified files, and 'dired-do-replace-regexp-as-diff'
+that shows as diffs replacements in the marked files in Dired.
+
++++
+** New mode of prompting for register names and showing preview.
+The new user option 'register-use-preview' can be customized to the
+value t or insist to request a different user interface of prompting for
+register names and previewing the registers: Emacs will require
+confirmation for overwriting the value of a register, and will show
+the preview of registers without delay. You can also customize this
+new option to disable the preview completely.
+
+The default value of 'register-use-preview' preserves the behavior of
+Emacs 29 and before. See the Info node "(emacs) Registers" for more
+details about the new UI and its variants.
+
++++
+** New advanced macro counter commands.
+New commands have been added to implement advanced macro counter
+functions.
+
+The commands 'C-x C-k C-r l' and 'C-x C-k C-r s' load and save the
+macro counter from and to a number register, respectively.
+
+The commands 'C-x C-k C-r a =', 'C-x C-k C-r a <', and 'C-x C-k C-r a >'
+compare the macro counter with the contents of a number register and
+increment the counter by an optional prefix if the comparison succeeds.
+
+The commands 'C-x C-k C-q =', 'C-x C-k C-q <', and 'C-x C-k C-q >'
+compare the macro counter with an optional prefix and terminate the
+macro if the comparison succeeds.
+
++++
+** New mode 'kmacro-menu-mode' and new command 'list-keyboard-macros'.
+The new command 'list-keyboard-macros' is the keyboard-macro version
+of commands like 'list-buffers' and 'list-processes', creating a listing
+of the currently existing keyboards macros using the new mode
+'kmacro-menu-mode'. It allows rearranging the macros in the ring,
+duplicating them, deleting them, and editing their counters, formats,
+and keys.
+
+---
+** On X, Emacs now supports input methods which perform "string conversion".
+This means an input method can now ask Emacs to delete text
+surrounding point and replace it with something else, as well as query
+Emacs for surrounding text. If your input method allows you to "undo"
+mistaken compositions, this will now work as well.
+
+---
+** New user option 'duplicate-region-final-position'.
+It controls the placement of point and the region after duplicating a
+region with 'duplicate-dwim'.
+
++++
+** New user option 'mouse-prefer-closest-glyph'.
+When enabled, clicking or dragging with the mouse will put the point
+or start the drag in front of the buffer position corresponding to the
+glyph with the closest X coordinate to the click or start of the drag.
+In other words, if the mouse pointer is in the right half of a glyph,
+point will be put after the buffer position corresponding to that glyph,
+whereas if the mouse pointer is in the left half of a glyph, point
+will be put in front the buffer position corresponding to that glyph.
+By default this is disabled.
+
+---
+** New pre-defined values for 'electric-quote-chars'.
+The available customization options for 'electric-quote-chars' have been
+updated with common pairs of quotation characters, including "‘", "’",
+"“", "”", "«", "»", "‹", "›", "‚", "„", "「", "」", "『", and "』".
+The default is unchanged.
+
++++
+** 'M-TAB' now invokes 'completion-at-point' in Text mode.
+By default, Text mode no longer binds 'M-TAB' to 'ispell-complete-word'.
+Instead, this mode arranges for 'completion-at-point', globally bound to
+'M-TAB', to perform word completion as well. You can have Text mode
+binding 'M-TAB' to 'ispell-complete-word' as it did in previous Emacs
+versions, or disable Ispell word completion in Text mode altogether, by
+customizing the new user option 'text-mode-ispell-word-completion'.
+
+** Internationalization
+
+---
+*** Mode-line mnemonics for some coding-systems have changed.
+The mode-line mnemonic for 'utf-7' is now the lowercase 'u', to be
+consistent with the other encodings of this family.
+
+The mode-line mnemonic for 'koi8-u' is now 'У', U+0423 CYRILLIC
+CAPITAL LETTER U, to distinguish between this encoding and the
+UTF-8/UTF-16 family.
+
+If your terminal cannot display 'У', or if you want to get the old
+behavior back for any other reason, you can do that using the
+'coding-system-put' function. For example, the following restores the
+previous behavior of showing 'U' in the mode line for 'koi8-u':
+
+ (coding-system-put 'koi8-u :mnemonic ?U)
+
+---
+*** 'vietnamese-tcvn' is now a coding system alias for 'vietnamese-vscii'.
+VSCII-1 and TCVN-5712 are different names for the same character
+encoding. Therefore, the duplicate coding system definition has been
+dropped in favor of an alias.
+
+The mode-line mnemonic for 'vietnamese-vscii' and its aliases is the
+lowercase letter "v".
+
+---
+*** Users in CJK locales can control width of some non-CJK characters.
+Some characters are considered by Unicode as "ambiguous" with respect
+to their display width: either "full-width" (i.e., taking 2 columns on
+display) or "narrow" (taking 1 column). The actual width depends on
+the fonts used for these characters by Emacs or (for text-mode frames)
+by the terminal emulator. Traditionally, font sets in CJK locales
+were set up so as to display these characters as full-width, and thus
+Emacs modified the char-width table in those locales to follow suit.
+Lately, the tendency is to display these characters as narrow. The
+new user option 'cjk-ambiguous-chars-are-wide' allows users to control
+whether Emacs considers these characters as full-width (the default)
+or narrow (if the variable is customized to the nil value).
+
+This setting affects the results of 'string-width' and similar
+functions in CJK locales.
+
+---
+*** New input methods for the Urdu, Pashto, and Sindhi languages.
+These languages are spoken in Pakistan and Afghanistan.
+
+---
+*** New input method "english-colemak".
+This input method supports the Colemak keyboard layout.
+
+---
+*** Additional 'C-x 8' key translations for "æ" and "Æ".
+These characters can now be input with 'C-x 8 a e' and 'C-x 8 A E',
+respectively, in addition to the existing translations 'C-x 8 / e' and
+'C-x 8 / E'.
+
+---
+*** New 'C-x 8' key translations for "low" quotes "„", and "‚".
+These can now be entered with 'C-x , "' and 'C-x , ''.
+
+---
+*** New German language 'C-x 8' key translations for quotation marks.
+The characters "„", "“", and "”" can now be entered with 'C-x 8 v',
+'C-x 8 b' and 'C-x 8 n'. The single versions "‚", "‘", and "’" can now
+be entered with 'C-x 8 V', 'C-x 8 B' and 'C-x 8 N'. These characters
+are used for the official German quoting style. Using them requires
+activating German language support via 'iso-transl-set-language'.
+
+---
+*** "latin-prefix" and "latin-postfix" quotation marks additions.
+These input methods can now produce single, double and "low" left and
+right quotation marks:
+
+ "‘", "’", "“", "”", "„", and "‚"
+
+by using "[", "]", and "," for "left", "right", and "low" respectively
+to modify "'" and """.
+
+---
+*** "latin-prefix" and "latin-postfix" guillemets support.
+These input methods can now produce single guillemets "‹" and "›". For
+"latin-prefix" use "~~<" and "~~>", for "latin-postfix" use "<~" and
+">~". Double guillemets ("«" and "»") were already supported.
+
+---
+*** New French language 'C-x 8' key translations for "‹" and "›".
+These characters can now be entered using 'C-x 8 ~ <' and 'C-x 8 ~ >',
+respectively, after activating French language support via
+'iso-transl-set-language'. Double guillemets were already supported via
+'C-x 8 <' and 'C-x 8 >'
+
+---
+*** Additional 'C-x 8' key translation for Euro "€" currency symbol.
+This can now be entered using 'C-x 8 E' in addition to the existing
+'C-x 8 * E' translation.
+
+
+* Changes in Specialized Modes and Packages in Emacs 30.1
+
+** Outline mode
+
++++
+*** New commands to show/hide outlines by regexp.
+'C-c / h' ('outline-hide-by-heading-regexp') asks for a regexp and then
+hides the body lines of all outlines whose heading lines match the
+regexp. 'C-c / s' ('outline-show-by-heading-regexp') does the inverse:
+it shows the bodies of outlines that matched a regexp.
+
++++
+*** 'outline-minor-mode' is supported in tree-sitter major modes.
+It can be used in all tree-sitter major modes that set either the
+variable 'treesit-simple-imenu-settings' or 'treesit-outline-predicate'.
+
+** Info
+
+---
+*** New user option 'Info-url-alist'.
+This user option associates manual names with URLs. It affects the
+'Info-goto-node-web' command. By default, associations for all
+Emacs-included manuals are set. Further associations can be added for
+arbitrary Info manuals.
+
+---
+*** Emacs can now display Info manuals compressed with 'lzip'.
+This requires the 'lzip' program to be installed on your system.
+
+** GUD (Grand Unified Debugger)
+
++++
+*** New user option 'gud-highlight-current-line'.
+When enabled, GUD will visually emphasize the line being executed upon
+pauses in the debuggee's execution, such as those occasioned by
+breakpoints being hit.
+
++++
+*** New command 'lldb'.
+Run the LLDB debugger, analogous to the 'gud-gdb' command.
+
+---
+*** Variable order and truncation can now be configured in 'gdb-many-windows'.
+The new user option 'gdb-locals-table-row-config' allows users to
+configure the order and max length of various properties in the local
+variables buffer when using 'gdb-many-windows'.
+
+By default, this user option is set to write the properties in the order:
+'name', 'type' and 'value', where the 'name' and 'type' are truncated to 20
+characters, and the 'value' is truncated according to the value of
+'gdb-locals-value-limit'.
+
+If you want to get back the old behavior, set the user option to the value
+
+ (setopt gdb-locals-table-row-config
+ `((type . 0) (name . 0) (value . ,gdb-locals-value-limit)))
+
++++
+*** New user option 'gdb-display-io-buffer'.
+If this is nil, command 'gdb' will neither create nor display a separate
+buffer for the I/O of the program being debugged, but will instead
+redirect the program's interaction to the GDB execution buffer. The
+default is t, to preserve previous behavior.
+
+** Grep
+
++++
+*** New user option 'grep-use-headings'.
+When non-nil, the output of Grep is split into sections, one for each
+file, instead of having file names prefixed to each line. It is
+equivalent to the '--heading' option of some tools such as 'git grep'
+and 'rg'. The headings are displayed using the new 'grep-heading' face.
+The default is nil.
+
+** Compilation mode
+
+---
+*** The 'omake' matching rule is now disabled by default.
+This is because it partly acts by modifying other rules which may
+occasionally be surprising. It can be re-enabled by adding 'omake' to
+'compilation-error-regexp-alist'.
+
+---
+*** Lua errors and stack traces are now recognized.
+Compilation mode now recognizes Lua language errors and stack traces.
+Every Lua error is recognized as a compilation error, and every Lua
+stack frame is recognized as a compilation info.
+
+** Project
+
++++
+*** New user option 'project-mode-line'.
+When non-nil, display the name of the current project on the mode
+line. Clicking 'mouse-1' on the project name pops up the project
+menu. The default value is nil.
+
+---
+*** New user option 'project-file-history-behavior'.
+Customizing it to 'relativize' makes commands like 'project-find-file'
+and 'project-find-dir' display previous history entries relative to
+the current project.
+
+--
+*** New user option 'project-key-prompt-style'.
+The look of the key prompt in the project switcher has been changed
+slightly. To get the previous one, set this option to 'brackets'.
+
+---
+*** Function 'project-try-vc' tries harder to find the responsible VCS.
+When 'project-vc-extra-root-markers' is non-nil, and causes a
+subdirectory project to be detected which is not a VCS root, Project now
+additionally traverses the parent directories until a VCS root is found
+(if any), so that the ignore rules for that repository are used, and
+the file listing's performance is still optimized.
+
++++
+*** New commands 'project-any-command' and 'project-prefix-or-any-command'.
+The former is now bound to 'C-x p o' by default.
+The latter is designed primarily for use as a value of
+'project-switch-commands'. If instead of a short menu you prefer to
+have access to all keys defined inside 'project-prefix-map', as well
+as global bindings (to run other commands inside the project root),
+you can add this to your init script:
+
+ (setopt project-switch-commands #'project-prefix-or-any-command)
+
+---
+*** New variable 'project-files-relative-names'.
+If it is non-nil, 'project-files' can return file names relative to the
+project root. Project backends can use this to improve the performance
+of their 'project-files' implementation.
+
+** VC
+
+---
+*** Log-Edit buffers now display a tool bar.
+This tool bar contains items for committing log entries and editing or
+generating log entries, among other editing operations.
+
+---
+*** New user option 'vc-git-shortlog-switches'.
+This is a string or a list of strings that specifies the Git log
+switches for shortlogs, such as the one produced by 'C-x v L'.
+'vc-git-log-switches' is no longer used for shortlogs.
+
+---
+*** New value 'no-backend' for user option 'vc-display-status'.
+With this value only the revision number is displayed on the mode-line.
+
+---
+*** Obsolete command 'vc-switch-backend' re-added as 'vc-change-backend'.
+The command was previously obsoleted and unbound in Emacs 28.
+
+---
+*** Support for viewing VC change history across renames.
+When a fileset's VC change history ends at a rename, 'C-x v l' now
+prints the old name(s) and shows a button which jumps to the history of
+the files under the old names. This feature is supported for Git and
+Hg. Naturally, 'vc-git-print-log-follow' should be nil for this to work
+(or '--follow' should not be in 'vc-hg-log-switches', in Hg's case).
+Unlike when the '--follow' switch is used, commands to see the diff of
+the old revision ('d'), to check out an old file version ('f') or to
+annotate it ('a'), also work on revisions which precede renames.
+
+---
+*** 'vc-annotate' now abbreviates the Git revision in the buffer name.
+When using the Git backend, 'vc-annotate' will use an abbreviated
+revision identifier in its buffer name. To restore the previous
+behavior, set user option 'vc-annotate-use-short-revision' to nil.
+
+---
+*** New user option 'vc-git-file-name-changes-switches'.
+It allows tweaking the thresholds for rename and copy detection.
+
+** Diff mode
+
+---
+*** New user option 'diff-refine-nonmodified'.
+When this is non-nil, 'diff-refine-hunk' will highlight lines that were
+added or removed in their entirety (as opposed to modified lines, where
+some parts of the line were modified), using the same faces as for
+highlighting the words added and removed within modified lines. The
+default value is nil.
+
++++
+*** 'diff-ignore-whitespace-hunk' can now be applied to all hunks.
+When called with a non-nil prefix argument,
+'diff-ignore-whitespace-hunk' now iterates over all the hunks in the
+current diff, regenerating them without whitespace changes.
+
++++
+*** New user option 'diff-ignore-whitespace-switches'.
+This allows changing which type of whitespace changes are ignored when
+regenerating hunks with 'diff-ignore-whitespace-hunk'. Defaults to
+the previously hard-coded "-b".
+
++++
+*** New command 'diff-apply-buffer' bound to 'C-c RET a'.
+It applies the diff in the entire diff buffer and
+saves all modified file buffers.
+
+** Dired
+
+---
+*** New user option 'dired-movement-style'.
+When non-nil, make 'dired-next-line', 'dired-previous-line',
+'dired-next-dirline', 'dired-prev-dirline' skip empty lines.
+It also controls how to move point when encountering a boundary
+(e.g., if every line is visible, invoking 'dired-next-line' at
+the last line will move to the first line). The default is nil.
+
+---
+*** New user option 'dired-filename-display-length'.
+It is an integer representing the maximum display length of file names.
+The middle part of a file name whose length exceeds the restriction is
+hidden and an ellipsis is displayed instead. A value of 'window'
+means using the right edge of window as the display restriction. The
+default is nil.
+
+---
+*** New user option 'shell-command-guess-functions'.
+It defines how to populate a list of commands available
+for 'M-!', 'M-&', '!', '&' and the context menu "Open With"
+based on marked files in Dired. Possible backends are
+'dired-guess-default', MIME types, XDG configuration
+and a universal command such as "open" or "start"
+that delegates to the OS.
+
++++
+*** New command 'dired-do-open'.
+This command is bound to 'E' (mnemonics "External"). Also it can be
+used by clicking "Open" in the context menu; it "opens" the marked or
+clicked on files according to the OS conventions. For example, on
+systems supporting XDG, this runs 'xdg-open' on the files.
+
++++
+*** New variable 'dired-guess-shell-alist-optional'.
+It contains commands for external viewers and players for various media
+formats, moved to this list from 'dired-guess-shell-alist-default'.
+
+---
+*** The default value of 'dired-omit-size-limit' was increased.
+After performance improvements to omitting in large directories, the new
+default value is 300k, up from 100k. This means 'dired-omit-mode' will
+omit files in directories whose directory listing is up to 300 kilobytes
+in size.
+
++++
+*** 'dired-listing-switches' handles connection-local values if exist.
+This allows to customize different switches for different remote machines.
+
+** Ediff
+
+---
+*** New user option 'ediff-floating-control-frame'.
+If non-nil, try making the control frame be floating rather than tiled.
+
+Many X tiling window managers make the Ediff control frame a tiled
+window equal in size to the main Emacs frame, which works poorly.
+This option is useful to set if you use such a window manager.
+
+** Buffer Selection
+
+---
+*** New user option 'bs-default-action-list'.
+You can now configure how to display the "*buffer-selection*" buffer
+using this new option. (Or set 'display-buffer-alist' directly.)
+
+** Eshell
+
++++
+*** You can now run Eshell scripts in batch mode.
+By adding the following interpreter directive to an Eshell script, you
+can make it executable like other shell scripts:
+
+ #!/usr/bin/env -S emacs --batch -f eshell-batch-file
+
++++
+*** New builtin Eshell command 'compile'.
+This command runs another command, sending its output to a compilation
+buffer when the command would output interactively. This can be useful
+when defining aliases so that they produce a compilation buffer when
+appropriate, but still allow piping the output elsewhere if desired.
+For more information, see the "(eshell) Built-ins" node in the Eshell
+manual.
+
++++
+*** Eshell's 'env' command now supports running commands.
+Like in many other shells, Eshell's 'env' command now lets you run a
+command passed as arguments to 'env'. If you pass any initial
+arguments of the form 'VAR=VALUE', 'env' will first set 'VAR' to
+'VALUE' before running the command.
+
+---
+*** Eshell's 'umask' command now supports setting the mask symbolically.
+Now, you can pass an argument like "u+w,o-r" to Eshell's 'umask'
+command, which will give write permission for owners of newly-created
+files and deny read permission for users who are not members of the
+file's group. See the Info node "(coreutils) File permissions" for
+more information on this notation.
+
+---
+*** Performance improvements for interactive output in Eshell.
+Interactive output in Eshell should now be significantly faster,
+especially for commands that can print large amounts of output
+(e.g. "cat"). For external commands, Eshell saves time by only looking
+for password prompts in the last 256 characters of each block of output.
+To restore the previous behavior when checking for password prompts, set
+'eshell-password-prompt-max-length' to 'most-positive-fixnum'.
+
+---
+*** Eshell built-in commands can now display progress.
+Eshell built-in commands like "cat" and "ls" now update the display
+periodically while running to show their progress.
+
++++
+*** New special reference type '#<marker POSITION BUFFER>'.
+This special reference type returns a marker at 'POSITION' in
+'BUFFER'. You can insert it by typing or using the new interactive
+command 'eshell-insert-marker'. You can also insert special
+references of any type using the new interactive command
+'eshell-insert-special-reference'. See the "(eshell) Arguments" node
+in the Eshell manual for more details.
+
++++
+*** New splice operator for Eshell dollar expansions.
+Dollar expansions in Eshell now let you splice the elements of the
+expansion in-place using '$@expr'. This makes it easier to fill lists
+of arguments into a command, such as when defining aliases. For more
+information, see the "(eshell) Dollars Expansion" node in the Eshell
+manual.
+
++++
+*** You can now splice Eshell globs in-place into argument lists.
+By setting 'eshell-glob-splice-results' to a non-nil value, Eshell
+will expand glob results in-place as if you had typed each matching
+file name individually. For more information, see the "(eshell)
+Globbing" node in the Eshell manual.
+
++++
+*** Eshell now supports negative numbers and ranges for indices.
+Now, you can retrieve the last element of a list with '$my-list[-1]'
+or get a sublist of elements 2 through 4 with '$my-list[2..5]'. For
+more information, see the "(eshell) Dollars Expansion" node in the
+Eshell manual.
+
++++
+*** Eshell commands can now be explicitly-remote (or local).
+By prefixing a command name in Eshell with a remote identifier, like
+"/ssh:user@remote:whoami", you can now run commands on a particular
+host no matter your current directory. Likewise, you can run a
+command on your local system no matter your current directory via
+"/local:whoami". For more information, see the "(eshell) Remote Access"
+node in the Eshell manual.
+
++++
+*** Eshell's '$UID' and '$GID' variables are now connection-aware.
+Now, when expanding '$UID' or '$GID' in a remote directory, the value
+is the user or group ID associated with the remote connection.
+
+---
+*** Eshell now uses 'field' properties in its output.
+In particular, this means that pressing the '<home>' key moves the
+point to the beginning of your input, not the beginning of the whole
+line. If you want to go back to the old behavior, add something like
+this to your configuration:
+
+ (keymap-set eshell-mode-map "<home>" #'eshell-bol-ignoring-prompt)
+
+This also means you no longer need to adjust 'eshell-prompt-regexp'
+when customizing your Eshell prompt.
+
+---
+*** You can now properly unload Eshell.
+Calling '(unload-feature 'eshell)' no longer signals an error, and now
+correctly unloads Eshell and all of its modules.
+
++++
+*** 'eshell-read-aliases-list' is now an interactive command.
+After manually editing 'eshell-aliases-file', you can use this command
+to load the edited aliases.
+
++++
+*** 'rgrep' is now a builtin Eshell command.
+Running 'rgrep' in Eshell now uses the Emacs grep facility instead of
+calling external rgrep.
+
++++
+*** If a command exits abnormally, the Eshell prompt now shows its exit code.
+
++++
+*** New user option 'eshell-history-append'.
+If non-nil, each Eshell session will save history by appending new
+entries of that session to the history file rather than overwriting
+the file with the whole history of the session. The default is nil.
+
+** Pcomplete
+
+---
+*** New user option 'pcomplete-remote-file-ignore'.
+When this option is non-nil, remote file names are not completed by
+Pcomplete. Packages, like 'shell-mode', could set this in order to
+suppress remote file name completion at all.
+
+---
+*** Completion for the 'doas' command has been added.
+Command completion for 'doas' in Eshell and Shell mode will now work.
+
+** Shell mode
+
++++
+*** New user option 'shell-get-old-input-include-continuation-lines'.
+When this user option is non-nil, 'shell-get-old-input' ('C-RET')
+includes multiple shell "\" continuation lines from command output.
+Default is nil.
+
++++
+*** New user option 'shell-history-file-name'.
+When this user option is set to t, 'shell-mode' does not read the shell
+history file. Setting this user option to a string specifies the name
+of the shell history file to be read. A nil value triggers reading the
+environment variable 'HISTFILE'.
+
+In a 'shell' buffer, this user option is connection-local.
+
+---
+*** Performance improvements for interactive output.
+Interactive output in Shell mode now scans more selectively for password
+prompts by only examining the last 256 characters of each block of
+output, reducing the time spent when printing large amounts of output.
+To restore the old behavior, set 'comint-password-prompt-max-length' to
+'most-positive-fixnum'.
+
+** Prog mode
+
++++
+*** New command 'prog-fill-reindent-defun'.
+This command either fills a single paragraph in a defun, such as a
+docstring, or a comment, or (re)indents the surrounding defun if point
+is not in a comment or a string. By default, it is bound to 'M-q' in
+'prog-mode' and all its descendants.
+
+** Imenu
+
++++
+*** New user option 'imenu-flatten'.
+It controls whether to flatten the list of sections in an imenu, and
+how to display the sections in the flattened list.
+
++++
+*** The sort order of Imenu completions can now be customized.
+You can customize the user option 'completion-category-overrides'
+and set 'display-sort-function' for the category 'imenu'.
+
+** Which Function mode
+
++++
+*** Which Function mode can now display function names on the header line.
+The new user option 'which-func-display' allows choosing where the
+function name is displayed. The default is 'mode' to display in the
+mode line. 'header' will display in the header line;
+'mode-and-header' displays in both the header line and mode line.
+
++++
+*** New user option 'which-func-update-delay'.
+This replaces the user option 'idle-update-delay', which was previously
+used to control the delay before 'which-function-mode' updated its
+display. The user option 'idle-update-delay', which was only used by
+Which Function mode, is now obsolete.
+
+** Tramp
+
++++
+*** Tramp methods can be optional.
+An optional connection method is not enabled by default. The user must
+enable it explicitly by the 'tramp-enable-method' command. The existing
+methods "fcp", "krlogin", " ksu" and "nc" are optional now.
+
++++
+*** New optional connection method "androidsu".
+This provides access to system files with elevated privileges granted by
+the idiosyncratic 'su' implementations and system utilities customary on
+Android.
+
++++
+*** New optional connection method "run0".
+This connection method is similar to "sudo", but it uses the
+'systemd-run' program internally.
+
++++
+*** New connection methods "dockercp" and "podmancp".
+These are the external methods counterparts of "docker" and "podman".
+
++++
+*** New optional connection methods for containers.
+There are new optional connection methods "toolbox", "distrobox",
+"flatpak", "apptainer" and "nspawn". They allow accessing system
+containers provided by Toolbox or Distrobox, sandboxes provided by
+Flatpak, instances managed by Apptainer, or accessing systemd-based
+light-weight containers..
+
++++
+*** Connection method "kubernetes" supports now optional container name.
+The host name for Kubernetes connections can be of kind [CONTAINER.]POD,
+in order to specify a dedicated container. If there is just the pod
+name, the first container in the pod is taken. The new user options
+'tramp-kubernetes-context' and 'tramp-kubernetes-namespace' allow
+accessing pods with different context or namespace but the default one.
+
++++
+*** Rename 'tramp-use-ssh-controlmaster-options' to 'tramp-use-connection-share'.
+The old name still exists as obsolete variable alias. This user
+option controls now connection sharing for both ssh-based and
+plink-based methods. It allows the values t, nil, and 'suppress'.
+The latter suppresses also "ControlMaster" settings in the user's
+"~/.ssh/config" file, or connection share configuration in PuTTY
+sessions, respectively.
+
++++
+*** New command 'tramp-cleanup-some-buffers'.
+It kills only a subset of opened remote buffers, subject to the user
+option 'tramp-cleanup-some-buffers-hook'.
+
++++
+*** New command 'inhibit-remote-files'.
+This command disables the handling of file names with the special
+remote file name syntax. It should be applied only when remote files
+won't be used in this Emacs instance. It provides a slightly improved
+performance of file name handling in Emacs.
+
++++
+*** New macro 'without-remote-files'.
+This macro could wrap code which handles local files only. Due to the
+temporary deactivation of remote files, it results in a slightly
+improved performance of file name handling in Emacs.
+
++++
+*** New user option 'tramp-completion-multi-hop-methods'.
+It contains a list of connection methods for which completion should
+be attempted at the end of a multi-hop chain. This allows completion
+candidates to include a list of, for example, containers running on a
+remote docker host.
+
++++
+*** New command 'tramp-revert-buffer-with-sudo'.
+It reverts the current buffer to visit with "sudo" permissions. The
+buffer must either visit a file, or it must run 'dired-mode'. Another
+method but "sudo" can be configured with user option
+'tramp-file-name-with-method'.
+
++++
+*** Direct asynchronous processes are indicated by a connection-local variable.
+If direct asynchronous processes shall be used, set the connection-local
+variable 'tramp-direct-async-process' to a non-nil value. This has been
+changed, in previous Emacs versions this was indicated by the now
+deprecated connection property "direct-async-process". See the Tramp
+manual "(tramp) Improving performance of asynchronous remote processes".
+
+---
+*** Direct asynchronous processes use 'tramp-remote-path'.
+When a direct asynchronous process is invoked, it uses 'tramp-remote-path'
+for setting the remote 'PATH' environment variable.
+
+** EWW
+
+---
+*** New mouse bindings in EWW buffers.
+Certain form elements that were displayed as buttons, yet could only be
+activated by keyboard input, are now operable using 'mouse-2'. With
+"Submit" buttons, this triggers submission of the form, while clicks on
+other classes of buttons either toggle their values or prompt for user
+input, as the case may be.
+
+---
+*** EWW text input fields and areas are now fields.
+In consequence, movement commands and OS input method features now
+recognize and confine their activities to the text input field around
+point. See also the Info node "(elisp) Fields".
+
++++
+*** 'eww-open-file' can now display the file in a new buffer.
+By default, the command reuses the "*eww*" buffer, but if called with
+the new argument NEW-BUFFER non-nil, it will use a new buffer instead.
+Interactively, invoke 'eww-open-file' with a prefix argument to
+activate this behavior.
+
+---
+*** 'eww' URL or keyword prompt now has tab completion.
+The interactive minibuffer prompt when invoking 'eww' now has support
+for tab completion.
+
++++
+*** 'eww' URL and keyword prompt now completes suggested URIs and bookmarks.
+The interactive minibuffer prompt when invoking 'eww' now provides
+completions from 'eww-suggest-uris'. 'eww-suggest-uris' now includes
+bookmark URIs.
+
++++
+*** New command 'eww-copy-alternate-url'.
+It copies an alternate link on the page currently visited in EWW into
+the kill ring. Alternate links are optional metadata that HTML pages
+use for linking to their alternative representations, such as
+translated versions or associated RSS feeds.
+
++++
+*** 'eww-open-in-new-buffer' supports the prefix argument.
+When invoked with the prefix argument ('C-u'),
+'eww-open-in-new-buffer' will not make the new buffer the current one.
+This is useful for continuing reading the URL in the current buffer
+when the new URL is fetched.
+
+---
+*** History navigation in EWW now behaves as in other browsers.
+Previously, when navigating back and forward through page history, EWW
+would add a duplicate entry to the end of the history list each time.
+This made it impossible to navigate to the "end" of the history list.
+Now, navigating through history in EWW simply changes your position in
+the history list, allowing you to reach the end as expected. In
+addition, when browsing to a new page from a "historical" one (i.e., a
+page loaded by navigating back through history), EWW deletes the history
+entries newer than the current page. To change the behavior when
+browsing from "historical" pages, you can customize
+'eww-before-browse-history-function'.
+
++++
+*** 'eww-readable' now toggles display of the readable parts of a web page.
+When called interactively, 'eww-readable' toggles whether to display
+only the readable parts of a page or the full page. With a positive
+prefix argument, it always displays the readable parts, and with a zero
+or negative prefix, it always displays the full page.
+
++++
+*** New user option 'eww-readable-urls'.
+This is a list of regular expressions matching the URLs where EWW should
+display only the readable parts by default. For more details, see
+"(eww) Basics" in the EWW manual.
+
+---
+*** New user option 'eww-readable-adds-to-history'.
+When non-nil (the default), calling 'eww-readable' adds a new entry to
+the EWW page history.
+
+** Go-ts mode
+
++++
+*** New command 'go-ts-mode-docstring'.
+This command adds a docstring comment to the current defun. If a
+comment already exists, point is only moved to the comment. It is
+bound to 'C-c C-d' in 'go-ts-mode'.
+
+** Man mode
+
++++
+*** New user option 'Man-prefer-synchronous-call'.
+When this is non-nil, run the 'man' command synchronously rather than
+asynchronously (which is the default behavior).
+
++++
+*** New user option 'Man-support-remote-systems'.
+This option controls whether the man page is formatted on the remote
+system when the current buffer's default-directory is remote. You can
+invoke the 'man' command with a prefix argument to countermand the
+value of this option for the current invocation of 'man'.
+
+** DocView
+
+---
+*** New face 'doc-view-svg-face'.
+This replaces 'doc-view-svg-foreground' and 'doc-view-svg-background'.
+If you don't like the colors produced by the default definition of
+this new face when DocView displays documents, customize this face to
+restore the colors you were used to, or to get colors more to your
+liking.
+
+---
+*** DocView buffers now display a new tool bar.
+This tool bar contains options for searching and navigating within the
+document, replacing the incompatible items for incremental search and
+editing within the default tool bar displayed in the past.
+
+** Shortdoc
+
++++
+*** New function 'shortdoc-function-examples'.
+This function returns examples of use of a given Emacs Lisp function
+from the available shortdoc information.
+
++++
+*** New function 'shortdoc-help-fns-examples-function'.
+This function inserts into the current buffer examples of use of a
+given Emacs Lisp function, which it gleans from the shortdoc
+information. If you want 'describe-function' ('C-h f') to insert
+examples of using the function into regular "*Help*" buffers, add the
+following to your init file:
+
+ (add-hook 'help-fns-describe-function-functions
+ #'shortdoc-help-fns-examples-function)
+
+** Package
+
+---
+*** New user option 'package-vc-register-as-project'.
+When non-nil, it will automatically register every package as a
+project, that you can quickly select using 'project-switch-project'
+('C-x p p').
+
+---
+*** New user option 'package-vc-allow-build-commands'.
+Controls for which packages Emacs runs extra build commands when
+installing directly from the package VCS repository.
+
+---
+*** New command 'package-vc-log-incoming'.
+This commands displays incoming changes for a VC package without
+modifying the current checkout.
+
+---
+*** New command to start an inferior Emacs loading only specific packages.
+The new command 'package-isolate' will start a new Emacs process, as
+a sub-process of Emacs where you invoke the command, in a way that
+causes the new process to load only some of the installed packages.
+The command prompts for the packages to activate in this
+sub-process, and is intended for testing Emacs and/or the packages
+in a clean environment.
+
+** Flymake
+
++++
+*** New user option 'flymake-indicator-type'.
+This user option controls which error indicator type Flymake should use
+in current buffer. Depending on your preference, this can either use
+fringes or margins for indicating errors.
+
++++
+*** New user option 'flymake-margin-indicators-string'.
+It controls, for each error type, the string and its face to display as
+the margin indicator.
+
++++
+*** New user option 'flymake-autoresize-margins'.
+If non-nil, Flymake will resize the margins when 'flymake-mode' is
+turned on or off.
+Only relevant if 'flymake-indicator-type' is set to 'margins'.
+
++++
+*** New user option 'flymake-margin-indicator-position'.
+It controls which margin (left or right) is used for margin
+indicators.
+
++++
+*** New user option 'flymake-show-diagnostics-at-end-of-line'.
+When non-nil, Flymake shows summarized descriptions of diagnostics at
+the end of the line. Depending on your preference, this can either be
+distracting and easily confused with actual code, or a significant
+early aid that relieves you from moving the buffer or reaching for the
+mouse to consult an error message.
+
+** Flyspell
+
++++
+*** New user option 'flyspell-check-changes'.
+When non-nil, Flyspell mode spell-checks only words that you edited; it
+does not check unedited words just because you move point across them.
+
+---
+** JS mode.
+The binding 'M-.' has been removed from the major mode keymaps in
+'js-mode' and 'js-ts-mode', having it default to the global binding
+which calls 'xref-find-definitions'. If the previous one worked
+better for you, use 'define-key' in your init script to bind
+'js-find-symbol' to that combination again.
+
+---
+** Json mode.
+'js-json-mode' does not derive from 'js-mode' any more so as not
+to confuse tools like Eglot or YASnippet into thinking that those
+buffers contain Javascript code.
+
+** Python mode
+
+---
+*** New user option 'python-indent-block-paren-deeper'.
+If non-nil, increase the indentation of the lines inside parens in a
+header of a block when they are indented to the same level as the body
+of the block:
+
+ if (some_expression
+ and another_expression):
+ do_something()
+
+instead of:
+
+ if (some_expression
+ and another_expression):
+ do_something()
+
+---
+*** New user option 'python-interpreter-args'.
+This allows the user to specify command line arguments to the non
+interactive Python interpreter specified by 'python-interpreter'.
+
+---
+*** New function 'python-shell-send-block'.
+It sends the python block delimited by 'python-nav-beginning-of-block'
+and 'python-nav-end-of-block' to the inferior Python process.
+
+** Inferior Python mode
+
+---
+*** Default value of 'python-shell-compilation-regexp-alist' is changed.
+Support for Python's ExceptionGroup has been added, so in the Python
+shell, the line indicating the source of an error in the error messages
+from ExceptionGroup will be recognized as well.
+
+** Eldoc
+
+---
+*** 'eldoc' no longer truncates to a single line by default.
+Previously, the entire docstring was not available to eldoc, which made
+'eldoc-echo-area-use-multiline-p' ineffective. The old behavior may be
+kept by customizing 'eldoc-echo-area-use-multiline-p'.
+
+---
+** Scheme mode.
+Scheme mode now handles the regular expression literal '#/regexp/' that
+is available in some Scheme implementations.
+Also, it should now handle nested sexp-comments.
+
+** Use package
+
++++
+*** New ':vc' keyword.
+This keyword enables the user to install packages using package-vc.el.
+
++++
+*** New user option 'use-package-vc-prefer-newest'.
+This allows the user to always install the newest commit of a package
+when using the ':vc' keyword.
+
+** Gnus
+
++++
+*** New backend 'nnfeed'.
+This allows backend developers to easily create new backends for web
+feeds, as inheriting backends of 'nnfeed'.
+
++++
+*** New backend 'nnatom'.
+This allow users to add Atom Syndication Format feeds to Gnus as
+servers.
+
+*** The 'nnweb-type' option 'gmane' has been removed.
+The gmane.org website is, sadly, down since a number of years with no
+prospect of it coming back. Therefore, it is no longer valid to set
+the server variable 'nnweb-type' to 'gmane'.
+
+---
+*** New user option 'gnus-mode-line-logo'.
+This allows the user to either disable the display of any logo or
+specify which logo will be displayed as part of the
+buffer-identification in the mode-line of Gnus buffers.
+
+** Rmail
+
+---
+*** New commands for reading mailing lists.
+The new Rmail commands 'rmail-mailing-list-post',
+'rmail-mailing-list-unsubscribe', 'rmail-mailing-list-help', and
+'rmail-mailing-list-archive' allow, respectively, posting to,
+unsubscribing from, requesting help about, and browsing the archives
+of, the mailing list from which the current email message was
+delivered.
+
+** Dictionary
+
+---
+*** New user option 'dictionary-search-interface'.
+Controls how the 'dictionary-search' command prompts for and displays
+dictionary definitions. Customize this user option to 'help' to have
+'dictionary-search' display definitions in a "*Help*" buffer and
+provide dictionary-based minibuffer completion for word selection.
+
+---
+*** New user option 'dictionary-read-word-prompt'.
+This allows the user to customize the prompt that is used by
+'dictionary-search' when asking for a word to search in the
+dictionaries.
+
+---
+*** New user option 'dictionary-display-definition-function'.
+This allows the user to customize the way in which 'dictionary-search'
+displays word definitions. If non-nil, this user option should be set
+to a function that displays a word definition obtained from a
+dictionary server. The new function
+'dictionary-display-definition-in-help-buffer' can be used to display
+the definition in a "*Help*" buffer, instead of the default
+"*Dictionary*" buffer.
+
+---
+*** New user option 'dictionary-read-word-function'.
+This allows the user to customize the way in which 'dictionary-search'
+prompts for a word to search in the dictionary. This user option
+should be set to a function that lets the user select a word and
+returns it as a string. The new function
+'dictionary-completing-read-word' can be used to prompt with
+completion based on dictionary matches.
+
+---
+*** New user option 'dictionary-read-dictionary-function'.
+This allows the user to customize the way in which 'dictionary-search'
+prompts for a dictionary to search in. This user option should be set
+to a function that lets the user select a dictionary and returns its
+name as a string. The new function
+'dictionary-completing-read-dictionary' can be used to prompt with
+completion based on dictionaries that the server supports.
+
+---
+*** The default value of 'dictionary-tooltip-dictionary' has changed.
+The new default value is t, which means use the same dictionary as the
+value of 'dictionary-default-dictionary'. The previous default value
+was nil, which effectively disabled 'dictionary-tooltip-mode', even if
+the mode was turned on.
+
+** Pp
+
++++
+*** New 'pp-default-function' user option replaces 'pp-use-max-width'.
+Its default value is 'pp-fill', a new default pretty-printing function,
+which tries to obey 'fill-column'.
+
+---
+*** 'pp-to-string' takes an additional PP-FUNCTION argument.
+This argument specifies the prettifying algorithm to use.
+
+---
+*** 'pp' and 'pp-to-string' now always include a terminating newline.
+In the past they included a terminating newline in most cases but not all.
+
+** Emacs Lisp mode
+
+---
+*** ',@' now has 'prefix' syntax.
+Previously, the '@' character, which normally has 'symbol' syntax,
+would combine with a following Lisp symbol and interfere with symbol
+searching.
+
++++
+*** 'emacs-lisp-docstring-fill-column' now defaults to 72.
+It was previously 65. The new default formats documentation strings to
+fit on fewer lines without negatively impacting readability.
+
+** CPerl mode
+
+---
+*** Subroutine signatures are now supported.
+CPerl mode fontifies subroutine signatures like variable declarations
+which makes them visually distinct from subroutine prototypes.
+
+---
+*** Syntax of Perl up to version 5.40 is supported.
+CPerl mode supports the new keywords for exception handling and the
+object oriented syntax which were added in Perl 5.36, 5.38 and 5.40.
+
+---
+*** New user option 'cperl-fontify-trailer'.
+This user option takes the values 'perl-code' or 'comment' and treats
+text after an "__END__" or "__DATA__" token accordingly. The default
+value of 'perl-code' is useful for trailing POD and for AutoSplit
+modules, the value 'comment' makes CPerl mode treat trailers as
+comment, like Perl mode does.
+
+---
+*** New command 'cperl-file-style'.
+This command sets the indentation style for the current buffer. To
+change the default style, either use the user option with the same name
+or use the command 'cperl-set-style'.
+
+---
+*** New minor mode 'cperl-extra-paired-delimiters-mode'.
+Perl 5.36 and newer allows using more than 200 non-ASCII paired
+delimiters for quote-like constructs, e.g. "q«text»". Use this minor
+mode in buffers where this feature is activated.
+
+---
+*** Commands using the Perl Info manual are obsolete.
+The Perl documentation in Info format is no longer distributed with
+Perl or on CPAN since more than 10 years. Perl documentation can be
+read with 'cperl-perldoc' instead.
+
+---
+*** Highlighting trailing whitespace has been removed.
+The user option 'cperl-invalid-face' is now obsolete, and does
+nothing. See the user option 'show-trailing-whitespace' instead.
+
+** Emacs Sessions (Desktop)
+
++++
+*** Restoring buffers visiting remote files can now time out.
+When a buffer is restored which visits a remote file, the restoration
+of the session could hang if the remote host is off-line or slow to
+respond. Setting the user option 'remote-file-name-access-timeout' to
+a positive number will abandon the attempt to restore such buffers
+after a timeout of that many seconds, thus allowing the rest of
+desktop restoration to continue.
+
+** Recentf
+
++++
+*** Checking recent remote files can now time out.
+Similarly to buffer restoration by Desktop, 'recentf-mode' checking
+of the accessibility of remote files can now time out if
+'remote-file-name-access-timeout' is set to a positive number.
+
+** Image Dired
+
++++
+*** New user option 'image-dired-thumb-naming'.
+You can now configure how thumbnails are named using this option.
+
+** ERT
+
++++
+*** New macro 'skip-when' to skip 'ert-deftest' tests.
+This can help to avoid some awkward skip conditions. For example
+'(skip-unless (not noninteractive))' can be changed to the easier
+to read '(skip-when noninteractive)'.
+
++++
+*** Syntax highlighting unit testing support.
+An ERT extension ('ert-font-lock') now provides support for face
+assignment unit testing. For more information, see the "(ert) Syntax
+Highlighting Tests" node in the ERT manual.
+
+** Socks
+
++++
+*** Socks supports version 4a.
+The 'socks-server' user option accepts '4a' as a value for its version
+field.
+
+** Edmacro
+
++++
+*** New command 'edmacro-set-macro-to-region-lines'.
+Bound to 'C-c C-r', this command replaces the macro text with the
+lines of the region. If needed, the region is extended to include
+whole lines. If the region ends at the beginning of a line, that last
+line is excluded.
+
++++
+*** New user option 'edmacro-reverse-macro-lines'.
+When this is non-nil, the lines of key sequences are displayed with
+the most recent line first. This is can be useful when working with
+macros with many lines, such as from 'kmacro-edit-lossage'.
+
+** Calc
+
++++
+*** Calc parses fractions written using U+2044 FRACTION SLASH.
+Fractions of the form "123⁄456" are handled as if written "123:456".
+Note in particular the difference in behavior from U+2215 DIVISION SLASH
+and U+002F SOLIDUS, which result in division rather than a rational
+fraction. In addition, precomposed fraction characters, such as ½
+(U+00BD VULGAR FRACTION ONE HALF), are also recognized as rational
+fractions. (They have been recognized since 2004, but it looks like it
+was never mentioned in the NEWS, or even the Calc manual.)
+
+** IELM
+
+---
+*** IELM now remembers input history between sessions.
+The new user option 'ielm-history-file-name' is the name of the file
+where IELM input history will be saved. Customize it to nil to revert
+to the old behavior of not remembering input history between sessions.
+
+** EasyPG
+
++++
+*** New user option 'epa-keys-select-method'.
+This allows the user to customize the key selection method, which can be
+either by using a pop-up buffer or from the minibuffer. The pop-up
+buffer method is the default, which preserves previous behavior.
+
+** Widget
+
++++
+*** New face 'widget-unselected'.
+Customize this face to a non-default value to visually distinguish the
+labels of unselected active radio-button or checkbox widgets from the
+labels of unselected inactive widgets (the default value inherits from
+the 'widget-inactive' face).
+
++++
+*** New user option 'widget-skip-inactive'.
+If non-nil, moving point forward or backward between widgets by typing
+'TAB' or 'S-TAB' skips over inactive widgets. The default value is nil.
+
+** Ruby mode
+
+---
+*** New user option 'ruby-rubocop-use-bundler'.
+By default it retains the previous behavior: read the contents of
+Gemfile and act accordingly. But you can also set it to t or nil to
+skip the check.
+
+** Thingatpt
+
+---
+*** New variables for providing custom thingatpt implementations.
+The new variables 'bounds-of-thing-at-point-provider-alist' and
+'forward-thing-provider-alist' now allow defining custom implementations
+of 'bounds-of-thing-at-point' and 'forward-thing', respectively.
+
+---
+*** New helper functions for text property-based thingatpt providers.
+The new helper functions 'thing-at-point-for-char-property',
+'bounds-of-thing-at-point-for-char-property', and
+'forward-thing-for-char-property' can help to implement custom thingatpt
+providers for "things" that are defined by text properties.
+
+---
+*** 'bug-reference-mode' now supports 'thing-at-point'.
+Now, calling '(thing-at-point 'url)' when point is on a bug reference
+will return the URL for that bug.
+
+** Miscellaneous
+
++++
+*** New user option 'rcirc-log-time-format'.
+This allows for rcirc logs to use a custom timestamp format, which the
+chat buffers use by default.
+
+---
+*** New user option 'Buffer-menu-group-by'.
+It controls how buffers are divided into groups that are displayed with
+headings using Outline minor mode. Using commands that mark buffers
+on the outline heading line will mark all buffers in the outline.
+
++++
+*** New command 'Buffer-menu-toggle-internal'.
+This command toggles the display of internal buffers in Buffer Menu mode;
+that is, buffers not visiting a file and whose names start with a space.
+Previously, such buffers were never shown. This command is bound to 'I'
+in Buffer Menu mode.
+
+---
+*** 'ffap-lax-url' now defaults to nil.
+Previously, it was set to t, but this broke remote file name detection.
+
+---
+*** More control on automatic update of Proced buffers.
+The user option 'proced-auto-update-flag' can now be set to two
+additional values, which control automatic updates of Proced buffers
+that are not displayed in some window.
+
+---
+*** nXML Mode now comes with schemas for Mono/.NET development.
+The following new XML schemas are now supported:
+- MSBuild project files
+- Dotnet package properties files
+- Dotnet resource extension files
+- Dotnet Application config files
+- Nuget config file
+- Nuget package specification file
+- Nuget packages config file
+
+---
+*** color.el now supports the Oklab color representation.
+
++++
+*** New user option 'xwidget-webkit-disable-javascript'.
+This allows disabling JavaScript in xwidget Webkit sessions.
+
+---
+*** 'ls-lisp--insert-directory' supports more long options of 'ls'.
+'ls-lisp--insert-directory', the ls-lisp implementation of
+'insert-directory', now supports the '--time=TIME' and '--sort=time'
+options of GNU 'ls'.
+
+---
+*** 'M-x ping' can now give additional flags to the 'ping' program.
+Typing 'C-u M-x ping' prompts first for the host, and then for the flags
+to give to the 'ping' command.
+
+---
+*** Webjump now assumes URIs are HTTPS instead of HTTP.
+For links in 'webjump-sites' without an explicit URI scheme, it was
+previously assumed that they should be prefixed with "http://". Such
+URIs are now prefixed with "https://" instead.
+
+---
+*** Added prefixes in titdic-cnv library.
+Most of the variables and functions in the file have been renamed to
+make sure they all use a 'tit-' namespace prefix.
+
+---
+*** 'xref-revert-buffer' is now an alias of 'revert-buffer'.
+The Xref buffer now sets up 'revert-buffer-function' such that
+'revert-buffer' behaves like 'xref-revert-buffer' did in previous Emacs
+versions, and the latter is now an alias of the former.
+
+---
+*** The Makefile browser is now obsolete.
+The command 'makefile-switch-to-browser' command is now obsolete,
+together with related commands used in the "*Macros and Targets*"
+buffer. We recommend using an alternative like 'imenu' instead.
+
+
+* New Modes and Packages in Emacs 30.1
+
+** New major modes based on the tree-sitter library
+
++++
+*** New major mode 'elixir-ts-mode'.
+A major mode based on the tree-sitter library for editing Elixir files.
+
++++
+*** New major mode 'heex-ts-mode'.
+A major mode based on the tree-sitter library for editing HEEx files.
+
++++
+*** New major mode 'html-ts-mode'.
+An optional major mode based on the tree-sitter library for editing
+HTML files.
+
++++
+*** New major mode 'lua-ts-mode'.
+A major mode based on the tree-sitter library for editing Lua files.
+
++++
+*** New major mode 'php-ts-mode'.
+A major mode based on the tree-sitter library for editing PHP files.
+
++++
+** New package EditorConfig.
+This package provides support for the EditorConfig standard,
+an editor-neutral way to provide directory local (project-wide) settings.
+It is enabled via a new global minor mode 'editorconfig-mode'
+which makes Emacs obey the '.editorconfig' files.
+There is also a new major mode 'editorconfig-conf-mode'
+to edit those configuration files.
+
++++
+** New global minor mode 'etags-regen-mode'.
+This minor mode generates the tags table automatically based on the
+current project configuration, and later updates it as you edit the
+files and save the changes.
+
++++
+** New package 'which-key'.
+The 'which-key' package from GNU ELPA is now included in Emacs. It
+implements the global minor mode 'which-key-mode' that displays a table
+of key bindings upon entering a partial key chord and waiting for a
+moment. For example, after enabling the minor mode, if you enter 'C-x'
+and wait for one second, the minibuffer will expand with all available
+key bindings that follow 'C-x' (or as many as space allows).
+
++++
+** New minor mode 'completion-preview-mode'.
+This minor mode shows you symbol completion suggestions as you type,
+using an inline preview. New user options in the 'completion-preview'
+customization group control exactly when Emacs displays this preview.
+'completion-preview-mode' is buffer-local, to enable it globally use
+'global-completion-preview-mode'.
+
++++
+** New package Window-Tool-Bar.
+This provides a new minor mode, 'window-tool-bar-mode'. When this minor
+mode is enabled, a tool bar is displayed at the top of a window. To
+conserve space, no tool bar is shown if 'tool-bar-map' is nil. The
+global minor mode 'global-window-tool-bar-mode' enables this minor mode
+in all buffers.
+
++++
+** New library Track-Changes.
+This library is a layer of abstraction above 'before-change-functions'
+and 'after-change-functions' which provides a superset of
+the functionality of 'after-change-functions':
+- It provides the actual previous text rather than only its length.
+- It takes care of accumulating and bundling changes until a time when
+ its client finds it convenient to react to them.
+- It detects most cases where some changes were not properly
+ reported (calls to 'before/after-change-functions' that are
+ incorrectly paired, missing, etc...) and reports them adequately.
+
++++
+** New global minor mode 'minibuffer-regexp-mode'.
+This is a minor mode for editing regular expressions in the minibuffer,
+for example in 'query-replace-regexp'. It correctly highlights parens
+via 'show-paren-mode' and 'blink-matching-paren' in a user-friendly way,
+avoids reporting alleged paren mismatches and makes sexp navigation more
+intuitive.
+
+---
+** The highly accessible Modus themes collection has eight items.
+The 'modus-operandi' and 'modus-vivendi' are the main themes that have
+been part of Emacs since version 28. The former is light, the latter
+dark. In addition to these, we now have 'modus-operandi-tinted' and
+'modus-vivendi-tinted' for easier legibility, as well as
+'modus-operandi-deuteranopia', 'modus-vivendi-deuteranopia',
+'modus-operandi-tritanopia', and 'modus-vivendi-tritanopia' to cover
+the needs of users with red-green or blue-yellow color deficiency.
+The Info manual "(modus-themes) Top" describes the details and
+showcases all their user options.
+
++++
+** New library PEG.
+Emacs now includes a library for writing Parsing Expression
+Grammars (PEG), an approach to text parsing that provides more structure
+than regular expressions, but less complexity than context-free
+grammars. The Info manual "(elisp) Parsing Expression Grammars" has
+documentation and examples.
+
+---
+** New major mode 'shell-command-mode'.
+This mode is used by default for the output of asynchronous 'shell-command'.
+To revert to the previous behavior, set the (also new) variable
+'async-shell-command-mode' to 'shell-mode'. Any hooks or mode-specific
+variables used should be adapted appropriately.
+
++++
+** New package Compat.
+Emacs now comes with a stub implementation of the
+forwards-compatibility Compat package from GNU ELPA. This allows
+built-in packages to use the library more effectively, and helps
+preventing the installation of Compat if unnecessary.
+
+
+* Incompatible Lisp Changes in Emacs 30.1
+
++++
+** Evaluating a 'lambda' returns an object of type 'interpreted-function'.
+Instead of representing interpreted functions as lists that start with
+either 'lambda' or 'closure', Emacs now represents them as objects
+of their own 'interpreted-function' type, which is very similar
+to 'byte-code-function' objects (the argument list, docstring, and
+interactive forms are placed in the same slots).
+Lists that start with 'lambda' are now used only for non-evaluated
+functions (in other words, for source code), but for backward compatibility
+reasons, 'functionp' still recognizes them as functions and you can
+still call them as before.
+Thus code that attempts to "dig" into the internal structure of an
+interpreted function's object with the likes of 'car' or 'cdr' will
+no longer work and will need to use 'aref' instead to extract its
+various subparts (when 'interactive-form', 'documentation', and
+'help-function-arglist' aren't adequate).
+
+---
+** The escape sequence '\x' not followed by hex digits is now an error.
+Previously, '\x' without at least one hex digit denoted character code
+zero (NUL) but as this was neither intended nor documented or even
+known by anyone, it is now treated as an error by the Lisp reader.
+
+---
+** 'subr-native-elisp-p' is renamed to 'native-comp-function-p'.
+The previous name still exists but is marked as obsolete.
+
++++
+** 'define-globalized-minor-mode' requires that modes use 'run-mode-hooks'.
+Minor modes defined with 'define-globalized-minor-mode', such as
+'global-font-lock-mode', will not be enabled any more in those buffers
+whose major modes fail to use 'run-mode-hooks'. Major modes defined
+with 'define-derived-mode' are not affected. 'run-mode-hooks' has been the
+recommended way to run major mode hooks since Emacs 22.
+
++++
+** 'buffer-match-p' and 'match-buffers' take '&rest ARGS'.
+They used to take a single '&optional ARG' and were documented to use
+an unreliable hack to try and support condition predicates that
+don't accept this optional ARG.
+The new semantics makes no such accommodation, but the code still
+supports it (with a warning) for backward compatibility.
+
+---
+** 'post-gc-hook' runs after updating 'gcs-done' and 'gc-elapsed'.
+
+---
+** Connection-local variables are applied in buffers visiting remote files.
+This overrides possible directory-local or file-local variables with
+the same name.
+
++++
+** 'copy-tree' now copies records when its optional 2nd argument is non-nil.
+
++++
+** Regexp zero-width assertions followed by operators are better defined.
+Previously, regexps such as "xy\\B*" would have ill-defined behavior.
+Now any operator following a zero-width assertion applies to that
+assertion only (which is useless). For historical compatibility, an
+operator character following '^' or '\`' becomes literal, but we
+advise against relying on this.
+
++++
+** Infinities and NaNs no longer act as symbols on non-IEEE platforms.
+On old platforms like the VAX that do not support IEEE floating-point,
+tokens like '0.0e+NaN' and '1.0e+INF' are no longer read as symbols.
+Instead, the Lisp reader approximates an infinity with the nearest
+finite value, and a NaN with some other non-numeric object that
+provokes an error if used numerically.
+
++++
+** Conversion of strings to and from byte-arrays works with multibyte strings.
+The functions 'dbus-string-to-byte-array' and
+'dbus-byte-array-to-string' now accept and return multibyte Lisp
+strings, encoding to UTF-8 and decoding from UTF-8 internally. This
+means that the argument to 'dbus-byte-array-to-string' must be a valid
+UTF-8 byte sequence, and the optional parameter MULTIBYTE of
+'dbus-byte-array-to-string' is now obsolete and unused. The argument of
+'dbus-string-to-byte-array' should be a regular Lisp string, not a
+unibyte string.
+
++++
+** 'minibuffer-allow-text-properties' now can be set buffer-local.
+'read-from-minibuffer' and functions that use it can take the
+buffer-local value from the minibuffer.
+
++++
+** 'minibuffer-allow-text-properties' also affects completions.
+When it has a non-nil value, then completion functions like
+'completing-read' don't discard text properties from the returned
+completion candidate.
+
++++
+** X color support compatibility aliases are now obsolete.
+The compatibility aliases 'x-defined-colors', 'x-color-defined-p',
+'x-color-values', and 'x-display-color-p' are now obsolete.
+
++++
+** 'easy-mmode-define-{minor,global}-mode' aliases are now obsolete.
+Use 'define-minor-mode' and 'define-globalized-minor-mode' instead.
+
++++
+** The 'millisec' argument of 'sleep-for' is now obsolete.
+Use a float value for the first argument instead.
+
+---
+** User options 'eshell-NAME-unload-hook' are now obsolete.
+These hooks were named incorrectly, and so they never actually ran
+when unloading the corresponding feature. Instead, you should use
+hooks named after the feature name, like 'esh-mode-unload-hook'.
+
+** User options 'eshell-process-wait-{seconds,milliseconds}' are now obsolete.
+Instead, use 'eshell-process-wait-time', which supports floating-point
+values.
+
+---
+** User option 'tramp-completion-reread-directory-timeout' has been removed.
+This user option has been obsoleted in Emacs 27, use
+'remote-file-name-inhibit-cache' instead.
+
++++
+** The obsolete calling convention of 'sit-for' has been removed.
+That convention was: '(sit-for SECONDS MILLISEC &optional NODISP)'.
+
+---
+** 'defadvice' is marked as obsolete.
+See the "(elisp) Porting Old Advice" Info node for help converting
+them to use 'advice-add' or 'define-advice' instead.
+
+---
+** 'cl-old-struct-compat-mode' is marked as obsolete.
+You may need to recompile your code if it was compiled with Emacs < 24.3.
+
+---
+** Old derived.el functions removed.
+The following functions have been deleted because they were only used
+by code compiled with Emacs < 21:
+'derived-mode-init-mode-variables', 'derived-mode-merge-abbrev-tables',
+'derived-mode-merge-keymaps', 'derived-mode-merge-syntax-tables',
+'derived-mode-run-hooks', 'derived-mode-set-abbrev-table',
+'derived-mode-set-keymap', 'derived-mode-set-syntax-table',
+'derived-mode-setup-function-name'.
+
+
+* Lisp Changes in Emacs 30.1
+
++++
+** The 'wheel-up/down/left/right' events are now bound unconditionally.
+The 'mouse-wheel-up/down/left/right-event' variables are thus used only
+to specify the 'mouse-4/5/6/7' events that might still happen to be
+generated by some old packages (or if 'mouse-wheel-buttons' has been set
+to nil).
+
+---
+** Xterm Mouse mode now emits 'wheel-up/down/right/left' events.
+This is instead of 'mouse-4/5/6/7' events for the mouse wheel. It uses
+the new variable 'mouse-wheel-buttons' to decide which button maps to
+which wheel event (if any).
+
+---
+** In batch mode, tracing now sends the trace to stdout.
+
++++
+** New hook 'hack-dir-local-get-variables-functions'.
+This can be used to provide support for other directory-local settings
+beside ".dir-locals.el".
+
++++
+** 'auto-coding-functions' can know the name of the file.
+The functions on this hook can now find the name of the file to
+which the text belongs by consulting the variable 'auto-coding-file-name'.
+
++++
+** New user option 'compilation-safety' to control safety of native code.
+It is now possible to control how safe is the code generated by native
+compilation, by customizing this user option. It is also possible to
+control this at function granularity by using the new 'safety' parameter
+in the function's 'declare' form.
+
++++
+** New types 'closure' and 'interpreted-function'.
+'interpreted-function' is the new type used for interpreted functions,
+and 'closure' is the common parent type of 'interpreted-function'
+and 'byte-code-function'.
+
+Those new types come with the associated new predicates 'closurep' and
+'interpreted-function-p' as well as a new constructor
+'make-interpreted-closure'.
+
+---
+** New function 'help-fns-function-name'.
+For named functions, it just returns the name and otherwise
+it returns a short "unique" string that identifies the function.
+In either case, the string is propertized so clicking on it gives
+further details.
+
++++
+** New function 'char-to-name'.
+This is a convenience function to return the Unicode name of a char (if
+it has one).
+
++++
+** New function 'cl-type-of'.
+This function is like 'type-of' except that it sometimes returns
+a more precise type. For example, for nil and t it returns 'null'
+and 'boolean' respectively, instead of just 'symbol'.
+
++++
+** New functions 'primitive-function-p' and 'cl-functionp'.
+'primitive-function-p' is like 'subr-primitive-p' except that it returns
+t only if the argument is a function rather than a special-form,
+and 'cl-functionp' is like 'functionp' except it returns nil
+for lists and symbols.
+
+---
+** Built-in types now have corresponding classes.
+At the Lisp level, this means that things like '(cl-find-class 'integer)'
+will now return a class object, and at the UI level it means that
+things like 'C-h o integer RET' will show some information about that type.
+
+---
+** New variable 'major-mode-remap-defaults' and function 'major-mode-remap'.
+The first is like Emacs-29's 'major-mode-remap-alist' but to be set by
+packages (instead of users). The second looks up those two variables.
+
++++
+** Pcase's functions (in 'pred' and 'app') can specify the argument position.
+For example, instead of '(pred (< 5))' you can write '(pred (> _ 5))'.
+
++++
+** 'define-advice' now sets the new advice's 'name' property to NAME.
+Named advices defined with 'define-advice' can now be removed with
+'(advice-remove SYMBOL NAME)' in addition to '(advice-remove SYMBOL
+SYMBOL@NAME)'.
+
++++
+** New function 'require-with-check' to detect new versions shadowing.
+This is like 'require', but it checks whether the argument 'feature'
+is already loaded, in which case it either signals an error or
+forcibly reloads the file that defines the feature.
+
++++
+** New variable 'lisp-eval-depth-reserve'.
+It puts a limit to the amount by which Emacs can temporarily increase
+'max-lisp-eval-depth' when handling signals.
+
++++
+** New special form 'handler-bind'.
+It provides a functionality similar to 'condition-case' except it runs
+the handler code without unwinding the stack, such that we can record
+the backtrace and other dynamic state at the point of the error. See
+the Info node "(elisp) Handling Errors".
+
++++
+** New text properties add tooltips on fringes.
+It is now possible to provide tooltips on fringes by adding special text
+properties 'left-fringe-help' and 'right-fringe-help'. See the "(elisp)
+Special Properties" Info node in the Emacs Lisp Reference Manual for
+more details.
+
++++
+** New 'display-buffer' action alist entry 'pop-up-frames'.
+This has the same effect as the variable of the same name and takes
+precedence over the variable when present.
+
+---
+** New function 'merge-ordered-lists'.
+Mostly used internally to do a kind of topological sort of
+inheritance hierarchies.
+
++++
+** 'drop' is now an alias for the function 'nthcdr'.
+
++++
+** New polymorphic comparison function 'value<'.
+This function returns non-nil if the first argument is less than the
+second. It works for any two values of the same type with reasonable
+ordering for numbers, strings, symbols, bool-vectors, markers, buffers
+and processes. Conses, lists, vectors and records are ordered
+lexicographically.
+It is intended as a convenient ordering predicate for sorting, and is
+likely to be faster than hand-written Lisp functions.
+
++++
+** New 'sort' arguments and features.
+The 'sort' function can now be called using the signature
+
+ (sort SEQ &rest KEYWORD-ARGUMENTS)
+
+where arguments after the first are keyword/value pairs, all optional:
+':key' specifies a function that produces the sorting key from an element,
+':lessp' specifies the ordering predicate, defaulting to 'value<',
+':reverse' is used to reverse the sorting order,
+':in-place is used for in-place sorting, as the default is now to
+sort a copy of the input.
+
+The new signature is less error-prone and reduces the need to write
+ordering predicates by hand. We recommend that you use the ':key'
+argument instead of ':lessp' unless a suitable ordering predicate is
+already available. This can also be used for multi-key sorting:
+
+ (sort seq :key (lambda (x) (list (age x) (size x) (cost x))))
+
+sorts by the return value of 'age', then by 'size', then by 'cost'.
+
+The old signature, '(sort SEQ PREDICATE)', can still be used and sorts
+its input in-place as before.
+
+** New API for 'derived-mode-p' and control of the graph of major modes.
+
++++
+*** 'derived-mode-p' now takes the list of modes as a single argument.
+The same holds for 'provided-mode-derived-p'.
+The old calling convention where multiple modes are passed as
+separate arguments is deprecated.
+
++++
+*** New functions to access the graph of major modes.
+While 'define-derived-mode' still only supports single inheritance,
+modes can declare additional parents (for tests like 'derived-mode-p')
+with 'derived-mode-add-parents'.
+Accessing the 'derived-mode-parent' property directly is now
+deprecated in favor of the new functions 'derived-mode-set-parent'
+and 'derived-mode-all-parents'.
+
++++
+** Drag-and-drop functions can now be called once for compound drops.
+It is now possible for drag-and-drop handler functions to respond to
+drops incorporating more than one URL. Functions capable of this must
+set their 'dnd-multiple-handler' symbol properties to a non-nil value.
+See the Info node "(elisp) Drag and Drop".
+
+The function 'dnd-handle-one-url' has been made obsolete, since it
+cannot take these new handlers into account.
+
++++
+** 'notifications-notify' can use Icon Naming Specification for ':app-icon'.
+You can use a symbol as the value for ':app-icon' to provide icon name
+without specifying a file, like this:
+
+ (notifications-notify
+ :title "I am playing music" :app-icon 'multimedia-player)
+
+---
+** New function 're-disassemble' to see the innards of a regexp.
+If you built Emacs with '--enable-checking', you can use this to help
+debug either your regexp performance problems or the regexp engine.
+
++++
+** XLFDs are no longer restricted to 255 characters.
+'font-xlfd-name' now returns an XLFD even if it is greater than 255
+characters in length, provided that the LONG_XLFDs argument is true.
+Other features in Emacs which employ XLFDs have been modified to
+produce and understand XLFDs larger than 255 characters.
+
++++
+** New macro 'static-if' for conditional evaluation of code.
+This macro hides a form from the evaluator or byte-compiler based on a
+compile-time condition. This is handy for avoiding byte-compilation
+warnings about code that will never actually run under some conditions.
+
++++
+** Desktop notifications are now supported on the Haiku operating system.
+The new function 'haiku-notifications-notify' provides a subset of the
+capabilities of the 'notifications-notify' function in a manner
+analogous to 'w32-notification-notify'.
+
+** New Haiku specific variable 'haiku-pass-control-tab-to-system'.
+This sets whether Emacs should pass 'C-TAB' on to the system instead of
+handling it, fixing a problem where window switching would not activate
+if an Emacs frame had focus on the Haiku operating system.
+
++++
+** New value 'if-regular' for the REPLACE argument to 'insert-file-contents'.
+It results in 'insert-file-contents' erasing the buffer instead of
+preserving markers if the file being inserted is not a regular file,
+rather than signaling an error.
+
++++
+** New variable 'current-key-remap-sequence'.
+It is bound to the key sequence that caused a call to a function bound
+within 'function-key-map' or 'input-decode-map' around those calls.
+
++++
+** The function 'key-translate' can now remove translations.
+If the second argument TO is nil, the existing key translation is
+removed.
+
++++
+** New variables describing the names of built in programs.
+The new variables 'ctags-program-name', 'ebrowse-program-name',
+'etags-program-name', 'hexl-program-name', 'emacsclient-program-name'
+'movemail-program-name', and 'rcs2log-program-name' should be used
+instead of "ctags", "ebrowse", "etags", "hexl", "emacsclient", and
+"rcs2log", when starting one of these built in programs in a subprocess.
+
++++
+** New variable 'case-symbols-as-words' affects case operations for symbols.
+If non-nil, then case operations such as 'upcase-initials' or
+'replace-match' (with nil FIXEDCASE) will treat the entire symbol name
+as a single word. This is useful for programming languages and styles
+where only the first letter of a symbol's name is ever capitalized.
+The default value of this variable is nil.
+
+---
+** Bytecode is now always loaded eagerly.
+Bytecode compiled with older Emacs versions for lazy loading using
+'byte-compile-dynamic' is now loaded all at once.
+As a consequence, 'fetch-bytecode' has no use, does nothing, and is
+now obsolete. The variable 'byte-compile-dynamic' has no effect any
+more; compilation will always yield bytecode for eager loading.
+
++++
+** Returned strings from functions and macros are never docstrings.
+Functions and macros whose bodies consist of a single string literal now
+only return that string, and will not use it as a docstring. Example:
+
+ (defun sing-a-song ()
+ "Sing a song.")
+
+The above function returns the string "Sing a song." and has no
+docstring. Previously, that string was used as both the docstring and
+return value, which was never what the programmer wanted. If you want
+the string to be a docstring, add an explicit return value.
+
+This change applies to 'defun', 'defsubst', 'defmacro' and 'lambda'
+forms; other defining forms such as 'cl-defun' already worked this way.
+
+** New or changed byte-compilation warnings
+
+---
+*** Warn about missing 'lexical-binding' directive.
+The compiler now warns if an Elisp file lacks the standard
+'-*- lexical-binding: ... -*-' cookie on the first line.
+This line typically looks something like
+
+ ;;; My little pony mode -*- lexical-binding: t -*-
+
+It is needed to inform the compiler about which dialect of ELisp
+your code is using: the modern dialect with lexical binding or
+the old dialect with only dynamic binding.
+
+Lexical binding avoids some name conflicts and allows the compiler to
+detect more mistakes and generate more efficient code, so it is
+recommended. For how to adapt your code to lexical binding, see the
+manual section "(elisp) Converting to Lexical Binding".
+
+If your code cannot be converted to lexical binding, you can insert
+the line
+
+ ;;; -*- lexical-binding: nil -*-
+
+first in the file to declare that it uses the old dialect.
+
+---
+*** Warn about empty bodies for more special forms and macros.
+The compiler now warns about an empty body argument to 'when',
+'unless', 'ignore-error' and 'with-suppressed-warnings' in addition to
+the existing warnings for 'let' and 'let*'. Example:
+
+ (when (> x 2))
+
+This warning can be suppressed using 'with-suppressed-warnings' with
+the warning name 'empty-body'.
+
+---
+*** Warn about quoted error names in 'condition-case' and 'ignore-error'.
+The compiler now warns about quoted condition (error) names
+in 'condition-case' and 'ignore-error'. Example:
+
+ (condition-case nil
+ (/ x y)
+ ('arith-error "division by zero"))
+
+Quoting them adds the error name 'quote' to those handled or ignored
+respectively, which was probably not intended.
+
+---
+*** Warn about comparison with literal constants without defined identity.
+The compiler now warns about comparisons by identity with a literal
+string, cons, vector, record, function, large integer or float as this
+may not match any value at all. Example:
+
+ (eq x "hello")
+
+Only literals for symbols and small integers (fixnums), including
+characters, are guaranteed to have a consistent (unique) identity.
+This warning applies to 'eq', 'eql', 'memq', 'memql', 'assq', 'rassq',
+'remq' and 'delq'.
+
+To compare by (structural) value, use 'equal', 'member', 'assoc',
+'rassoc', 'remove' or 'delete' instead. Floats and bignums can also
+be compared using 'eql', '=' and 'memql'. Function literals cannot be
+compared reliably at all.
+
+This warning can be suppressed using 'with-suppressed-warnings' with
+the warning name 'suspicious'.
+
+---
+*** Warn about 'condition-case' without handlers.
+The compiler now warns when the 'condition-case' form is used without
+any actual handlers, as in
+
+ (condition-case nil (read buffer))
+
+because it has no effect other than the execution of the body form.
+In particular, no errors are caught or suppressed. If the intention
+was to catch all errors, add an explicit handler for 'error', or use
+'ignore-error' or 'ignore-errors'.
+
+This warning can be suppressed using 'with-suppressed-warnings' with
+the warning name 'suspicious'.
+
+---
+*** Warn about 'unwind-protect' without unwind forms.
+The compiler now warns when the 'unwind-protect' form is used without
+any unwind forms, as in
+
+ (unwind-protect (read buffer))
+
+because the behavior is identical to that of the argument; there is
+no protection of any kind. Perhaps the intended unwind forms have
+been misplaced or forgotten, or the use of 'unwind-protect' could be
+simplified away.
+
+This warning can be suppressed using 'with-suppressed-warnings' with
+the warning name 'suspicious'.
+
+---
+*** Warn about useless trailing 'cond' clauses.
+The compiler now warns when a 'cond' form contains clauses following a
+default (unconditional) clause. Example:
+
+ (cond ((= x 0) (say "none"))
+ (t (say "some"))
+ (say "goodbye"))
+
+Such a clause will never be executed, and is likely to be a mistake,
+perhaps due to misplaced parens.
+
+This warning can be suppressed using 'with-suppressed-warnings' with
+the warning name 'suspicious'.
+
+---
+*** Warn about mutation of constant values.
+The compiler now warns about code that modifies program constants in
+some obvious cases. Examples:
+
+ (setcar '(1 2) 7)
+ (aset [3 4] 0 8)
+ (aset "abc" 1 ?d)
+
+Such code may have unpredictable behavior because the constants are part
+of the program and are not data structures generated afresh during
+execution; the compiler does not expect them to change.
+
+To avoid the warning, operate on an object created by the program
+(maybe a copy of the constant), or use a non-destructive operation
+instead.
+
+This warning can be suppressed using 'with-suppressed-warnings' with
+the warning name 'mutate-constant'.
+
+---
+*** Warn about more ignored function return values.
+The compiler now warns when the return value from certain functions is
+implicitly ignored. Example:
+
+ (progn (nreverse my-list) my-list)
+
+will elicit a warning because it is usually pointless to call
+'nreverse' on a list without using the returned value.
+
+To silence the warning, make use of the value in some way, such as
+assigning it to a variable. You can also wrap the function call in
+'(ignore ...)', or use 'with-suppressed-warnings' with the warning
+name 'ignored-return-value'.
+
+The warning will only be issued for calls to functions declared
+'important-return-value' or 'side-effect-free' (but not 'error-free').
+
+---
+*** Warn about docstrings that contain control characters.
+The compiler now warns about docstrings with control characters other
+than newline and tab. This is often a result of improper escaping.
+Example:
+
+ (defun my-fun ()
+ "Uses c:\remote\dir\files and the key \C-x."
+ ...)
+
+where the docstring contains the four control characters 'CR', 'DEL',
+'FF' and 'C-x'.
+
+The warning name is 'docstrings-control-chars'.
+
+---
+*** The warning about wide docstrings can now be disabled separately.
+Its warning name is 'docstrings-wide'.
+
++++
+** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases.
+Previously, 'fset', 'defalias' and 'defvaralias' could be made to
+build circular function and variable indirection chains as in
+
+ (defalias 'able 'baker)
+ (defalias 'baker 'able)
+
+but trying to use them would sometimes make Emacs hang. Now, an attempt
+to create such a loop results in an error.
+
+Since circular alias chains now cannot occur, 'function-alias-p',
+'indirect-function' and 'indirect-variable' will never signal an error.
+Their 'noerror' arguments have no effect and are therefore obsolete.
+
+** Touch Screen support
+
++++
+*** 'x-popup-menu' now understands touch screen events.
+When a 'touchscreen-begin' or 'touchscreen-end' event is passed as the
+POSITION argument, it will behave as if that event was a mouse event.
+
++++
+*** New functions for handling touch screen events.
+The new functions 'touch-screen-track-tap' and 'touch-screen-track-drag'
+handle tracking common touch screen gestures from within a command.
+
++++
+*** New parameter to 'touchscreen-end' events.
+CANCEL non-nil establishes that the touch sequence has been intercepted
+by programs such as window managers and should be ignored with Emacs.
+
+---
+** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill.
+
++++
+** New variable 'secondary-tool-bar-map'.
+If non-nil, this variable contains a keymap of menu items that are
+displayed along tool bar items defined by 'tool-bar-map'. These items
+are displayed below the tool bar if the value of 'tool-bar-position' is
+'top', and above it if the value is 'bottom'. This is used by
+'modifier-bar-mode'.
+
+---
+** New variable 'completion-lazy-hilit'.
+Lisp programs that present completion candidates may bind this
+variable non-nil around calls to functions such as
+'completion-all-completions'. This tells the underlying completion
+styles to skip eager fontification of completion candidates, which
+improves performance. Such a Lisp program can then use the
+'completion-lazy-hilit' function to fontify candidates just in time.
+
++++
+** New primitive 'buffer-last-name'.
+It returns the name of a buffer before the last time it was renamed or
+killed.
+
++++
+** New primitive 'marker-last-position'.
+It returns the last position of a marker in its buffer even if that
+buffer has been killed. ('marker-position' would return nil in that
+case.)
+
+** Functions and variables to transpose sexps
+
+---
+*** New helper variable 'transpose-sexps-function'.
+Lisp programs can now set this variable to customize the behavior of the
+'transpose-sexps' command.
+
+---
+*** New function 'transpose-sexps-default-function'.
+The previous implementation of 'transpose-sexps' was moved into its own
+function, to be used in 'transpose-sexps-function'.
+
+---
+*** New function 'treesit-transpose-sexps'.
+Tree-sitter now unconditionally sets 'transpose-sexps-function' for all
+tree-sitter enabled modes to this function.
+
+** Functions and variables to move by program statements
+
++++
+*** New variable 'forward-sentence-function'.
+Major modes can now set this variable to customize the behavior of the
+'forward-sentence' command.
+
+---
+*** New function 'forward-sentence-default-function'.
+The previous implementation of 'forward-sentence' is moved into its
+own function, to be bound by 'forward-sentence-function'.
+
++++
+*** New function 'treesit-forward-sentence'.
+All tree-sitter enabled modes that define 'sentence' in
+'treesit-thing-settings' now set 'forward-sentence-function' to call
+'treesit-forward-sentence'.
+
+** Functions and variables to move by program sexps
+
++++
+*** New function 'treesit-forward-sexp'.
+Tree-sitter conditionally sets 'forward-sexp-function' for major modes
+that have defined 'sexp' in 'treesit-thing-settings' to enable
+sexp-related motion commands.
+
+---
+** New user option 'native-comp-async-warnings-errors-kind'.
+It allows control of what kinds of warnings and errors from asynchronous
+native compilation are reported to the parent Emacs process. The
+default is to report all errors and only important warnings. If you
+were used to customizing 'native-comp-async-report-warnings-errors' to
+nil or 'silent', we suggest that you now leave it at its default value,
+and see if you get only warnings that matter.
+
+** Function 'declare' forms
+
++++
+*** New 'ftype' function declaration.
+The declaration '(ftype TYPE)' specifies the type of a function.
+Example:
+
+ (defun hello (x y)
+ (declare (ftype (function (integer boolean) string)))
+ ...)
+
+specifies that the function takes two arguments, an integer and a
+boolean, and returns a string. If the compilation happens with
+'compilation-safety' set to zero, this information can be used by the
+native compiler to produce better code, but specifying an incorrect type
+may lead to Emacs crashing. See the Info node "(elisp) Declare Form"
+for further information.
+
++++
+*** New 'important-return-value' function declaration and property.
+The declaration '(important-return-value t)' sets the
+'important-return-value' property which indicates that the function
+return value should probably not be thrown away implicitly.
+
++++
+** New functions 'file-user-uid' and 'file-group-gid'.
+These functions are like 'user-uid' and 'group-gid', respectively, but
+are aware of file name handlers, so they will return the remote UID or
+GID for remote files (or -1 if the connection has no associated user).
+
++++
+** 'treesit-font-lock-rules' now accepts additional global keywords.
+When supplied with ':default-language LANGUAGE', rules after it will
+default to use 'LANGUAGE'.
+
+---
+** New optional argument to 'modify-dir-local-variable'.
+A 5th argument, optional, has been added to
+'modify-dir-local-variable'. It can be used to specify which
+dir-locals file to modify.
+
+** Connection local variables
+
++++
+*** New macros 'connection-local-p' and 'connection-local-value'.
+The former macro returns non-nil if a variable has a connection-local
+binding. The latter macro returns the connection-local value of a
+variable if any, or its current value.
+
+** Hash tables
+
++++
+*** ':rehash-size' and ':rehash-threshold' args no longer have any effect.
+These keyword arguments are now ignored by 'make-hash-table'. Emacs
+manages the memory for all hash table objects in the same way.
+The functions 'hash-table-rehash-size' and 'hash-table-rehash-threshold'
+remain for compatibility but now always return the old default values.
+
++++
+*** The printed representation has been shrunk and simplified.
+The 'test' parameter is omitted if it is 'eql' (the default), as is
+'data' if empty. 'rehash-size', 'rehash-threshold' and 'size' are
+always omitted, and ignored if present when the object is read back in.
+
+** Obarrays
+
++++
+*** New obarray type.
+Obarrays are now represented by an opaque type instead of using vectors.
+They are created by 'obarray-make' and manage their internal storage
+automatically, which means that the size parameter to 'obarray-make' can
+safely be omitted. That is, they do not become slower as they fill up.
+
+The old vector representation is still accepted by functions operating
+on obarrays, but 'obarrayp' only returns t for obarray objects.
+'type-of' now returns 'obarray' for obarray objects.
+
+Old code which (incorrectly) created "obarrays" as Lisp vectors filled
+with something other than 0, as in '(make-vector N nil)', will no longer
+work, and should be rewritten to use 'obarray-make'. Alternatively, you
+can fill the vector with 0.
+
++++
+*** New function 'obarray-clear' removes all symbols from an obarray.
+
+---
+*** 'obarray-size' and 'obarray-default-size' are now obsolete.
+They pertained to the internal storage size which is now irrelevant.
+
++++
+** 'treesit-install-language-grammar' can handle local directory instead of URL.
+It is now possible to pass a directory of a local repository as URL
+inside 'treesit-language-source-alist', so that calling
+'treesit-install-language-grammar' would avoid cloning the repository.
+It may be useful, for example, for the purposes of bisecting a
+treesitter grammar.
+
++++
+** New buffer-local variable 'tabulated-list-groups'.
+It controls display and separate sorting of groups of entries.
+
++++
+** New variable 'revert-buffer-restore-functions'.
+It helps to preserve various states after reverting the buffer.
+
+---
+** New text property 'context-menu-functions'.
+Like the variable with the same name, it adds menus from the list that
+is the value of the property to context menus shown when clicking on the
+text which as this property.
+
+---
+** Detecting the end of an iteration of a keyboard macro.
+'read-event', 'read-char', and 'read-char-exclusive' no longer return -1
+when called at the end of an iteration of the execution of a keyboard
+macro. Instead, they will transparently continue reading available input
+(e.g., from the keyboard). If you need to detect the end of a macro
+iteration, check the following condition before calling one of the
+aforementioned functions:
+
+ (and (arrayp executing-kbd-macro)
+ (>= executing-kbd-macro-index (length executing-kbd-macro)))
+
++++
+** 'vtable-update-object' updates an existing object with just two arguments.
+It is now possible to update the representation of an object in a vtable
+by calling 'vtable-update-object' with just the vtable and the object as
+arguments. (Previously, the OLD-OBJECT argument was required which, in
+this case, would mean repeating the object in the argument list.) When
+replacing an object with a different one, passing both the new and old
+objects is still necessary.
+
+** 'vtable-insert-object' can insert "before" or at an index.
+The signature of 'vtable-insert-object' has changed and is now:
+
+ (vtable-insert-object TABLE OBJECT &optional LOCATION BEFORE)
+
+LOCATION corresponds to the old AFTER-OBJECT argument; if BEFORE is
+non-nil, the new object is inserted before the LOCATION object, making
+it possible to insert a new object at the top of the table. (Before,
+this was not possible.) In addition, LOCATION can be an integer, a
+(zero-based) index into the table at which the new object is inserted
+(BEFORE is ignored in this case).
+
++++
+** New function 'sqlite-execute-batch'.
+This function lets the user execute multiple SQL statements in one go.
+It is useful, for example, when a Lisp program needs to evaluate an
+entire SQL file.
+
+** JSON
+
+---
+*** The parser keeps duplicated object keys in alist and plist output.
+A JSON object such as '{"a":1,"a":2}' will now be translated into the
+Lisp values '((a . 1) (a . 2))' or '(:a 1 :a 2)' if alist or plist
+object types are requested.
+
+---
+*** The parser sometimes signals different types of errors.
+It will now signal 'json-utf8-decode-error' for inputs that are not
+correctly UTF-8 encoded.
+
+---
+*** The parser and encoder now accept arbitrarily large integers.
+Previously, they were limited to the range of signed 64-bit integers.
+
+** New tree-sitter functions and variables for defining and using "things"
+
++++
+*** New variable 'treesit-thing-settings'.
+It allows modes to define "things" like 'defun', 'text', 'sexp', and
+'sentence' for navigation commands and tree-traversal functions.
+
++++
+*** New functions for navigating "things".
+There are new navigation functions 'treesit-thing-prev',
+'treesit-thing-next', 'treesit-navigate-thing',
+'treesit-beginning-of-thing', and 'treesit-end-of-thing'.
+
++++
+*** New functions 'treesit-thing-at', 'treesit-thing-at-point'.
+
++++
+*** Tree-traversing functions.
+The functions 'treesit-search-subtree', 'treesit-search-forward',
+'treesit-search-forward-goto', and 'treesit-induce-sparse-tree' now
+accept more kinds of predicates. Lisp programs can now use thing
+symbols (defined in 'treesit-thing-settings') and any thing definitions
+for the predicate argument.
+
+** Other tree-sitter function and variable changes
+
++++
+*** 'treesit-parser-list' now takes additional optional arguments.
+The additional arguments are LANGUAGE and TAG. If LANGUAGE is given,
+only return parsers for that language. If TAG is given, only return
+parsers with that tag. Note that passing nil as tag doesn't mean return
+all parsers, but rather "all parsers with no tags".
+
++++
+*** New variable 'treesit-primary-parser'.
+This variable should be set by multi-langauge major modes before calling
+'treesit-major-mode-setup', in order for tree-sitter integration
+functionalities to operate correctly.
+
+
+* Changes in Emacs 30.1 on Non-Free Operating Systems
+
+** MS-Windows
+
++++
+*** You can now opt out of following MS-Windows' Dark mode.
+By default, Emacs on MS-Windows follows the system's Dark mode for its
+title bars' and scroll bars' appearance. If the new user option
+'w32-follow-system-dark-mode' is customized to the nil value, Emacs
+will disregard the system's Dark mode and will always use the default
+Light mode.
+
+---
+*** You can now use Image-Dired even if the 'convert' program is not installed.
+If you don't have GraphicsMagick or ImageMagick installed, and thus the
+'gm convert'/'convert' program is not available, Emacs on MS-Windows
+will now use its own function 'w32image-create-thumbnail' to create
+thumbnail images and show them in the thumbnail buffer. Unlike with
+using 'convert', this fallback method is synchronous, so Emacs will wait
+until all the thumbnails are created and displayed, before showing them.
+
+---
+*** Emacs on MS-Windows now supports the ':stipple' face attribute.
+
+
+----------------------------------------------------------------------
+This file is part of GNU Emacs.
+
+GNU Emacs is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+GNU Emacs is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+
+Local variables:
+coding: utf-8
+mode: outline
+mode: emacs-news
+paragraph-separate: "[ ]"
+end:
diff --git a/etc/refcards/ru-refcard.tex b/etc/refcards/ru-refcard.tex
index a394688a8a0..a013f7695ed 100644
--- a/etc/refcards/ru-refcard.tex
+++ b/etc/refcards/ru-refcard.tex
@@ -40,7 +40,7 @@
\newlength{\ColThreeWidth}
\setlength{\ColThreeWidth}{25mm}
-\newcommand{\versionemacs}[0]{30} % version of Emacs this is for
+\newcommand{\versionemacs}[0]{31} % version of Emacs this is for
\newcommand{\cyear}[0]{2024} % copyright year
\newcommand\shortcopyrightnotice[0]{\vskip 1ex plus 2 fill
diff --git a/exec/Makefile.in b/exec/Makefile.in
index 36f0c0c74a9..7e681c0c3d8 100644
--- a/exec/Makefile.in
+++ b/exec/Makefile.in
@@ -44,6 +44,9 @@ FIND_DELETE = @FIND_DELETE@
OBJS = @OBJS@
LOADOBJS = $(patsubst %.s,%.o,$(LOADER))
+# Compilation parameters.
+ is_mips = @is_mips@
+
# Set up automatic dependency tracking.
AUTO_DEPEND = @AUTO_DEPEND@
@@ -82,6 +85,8 @@ Makefile: config.status Makefile.in
.SUFFIXES: .c .s
.c.o:
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEPFLAGS) -I. -I$(srcdir) $< -o $@
+
+ifeq ($(is_mips),yes)
.s.o:
$(M4) $< > $(notdir $<).s
$(AS) $(ASFLAGS) $(notdir $<).s -o $@
@@ -91,6 +96,10 @@ Makefile: config.status Makefile.in
config-mips.m4: config-mips.m4.in
cd $(srcdir) && ./config.status $@
$(LOADOBJS): config-mips.m4
+else
+.s.o:
+ $(AS) $(ASFLAGS) $< -o $@
+endif
# Set up rules to build libexec.a.
diff --git a/exec/README b/exec/README
index f7eb21cfc84..a1534503247 100644
--- a/exec/README
+++ b/exec/README
@@ -1,3 +1,6 @@
This directory holds the source code to a library used to replace the
`execve' and `execveat' system calls, used by the Android port of
Emacs to start executables without intervention from the system.
+
+The most edifying resource for developers will be GDB, or to be precise,
+the Linux target implementations for architectures of interest.
diff --git a/exec/configure.ac b/exec/configure.ac
index a473a1dc633..c3e895740be 100644
--- a/exec/configure.ac
+++ b/exec/configure.ac
@@ -42,11 +42,6 @@ General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */])
-AC_ARG_WITH([reentrancy],
- [AS_HELP_STRING([--with-reentrancy],
- [Generate library which can be used within a signal handler.])],
- [AC_DEFINE([REENTRANT], [1])])
-
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_PROG_CPP
@@ -74,9 +69,9 @@ AC_CHECK_FUNC([process_vm_readv],
]])])])
AC_CHECK_HEADERS([sys/param.h sys/uio.h])
AC_CHECK_MEMBERS([siginfo_t.si_syscall], [], [],
- [[
+[[
#include <signal.h>
- ]])
+]])
AH_BOTTOM([
#ifdef HAVE_STDBOOL_H
@@ -120,6 +115,7 @@ AH_TEMPLATE([SYSCALL_ARG2_REG], [Define to register holding arg2 to system calls
AH_TEMPLATE([SYSCALL_ARG3_REG], [Define to register holding arg3 to system calls.])
AH_TEMPLATE([SYSCALL_RET_REG], [Define to register holding value of system calls.])
AH_TEMPLATE([STACK_POINTER], [Define to register holding the stack pointer.])
+AH_TEMPLATE([PROGRAM_COUNTER], [Define to register holding the program counter.])
AH_TEMPLATE([EXEC_SYSCALL], [Define to number of the `exec' system call.])
AH_TEMPLATE([USER_WORD], [Define to word type used by tracees.])
AH_TEMPLATE([USER_SWORD], [Define to signed word type used by tracees.])
@@ -134,7 +130,8 @@ AH_TEMPLATE([READLINK_SYSCALL], [Define to number of the `readlink' system call.
AH_TEMPLATE([READLINKAT_SYSCALL], [Define to number of the `readlinkat' system call.])
AH_TEMPLATE([OPEN_SYSCALL], [Define to number of the `open' system call.])
AH_TEMPLATE([OPENAT_SYSCALL], [Define to number of the `openat' system call.])
-AH_TEMPLATE([REENTRANT], [Define to 1 if the library is used within a signal handler.])
+AH_TEMPLATE([HAVE_SECCOMP], [Define to 1 if secure computing filters are available
+to accelerate interception of system calls.])
AC_CANONICAL_HOST
@@ -250,6 +247,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [rdx])
AC_DEFINE([SYSCALL_ARG3_REG], [r10])
AC_DEFINE([STACK_POINTER], [rsp])
+ AC_DEFINE([PROGRAM_COUNTER], [rip])
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -283,6 +281,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [edx])
AC_DEFINE([SYSCALL_ARG3_REG], [esi])
AC_DEFINE([STACK_POINTER], [esp])
+ AC_DEFINE([PROGRAM_COUNTER], [eip])
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -314,6 +313,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [[regs[2]]])
AC_DEFINE([SYSCALL_ARG3_REG], [[regs[3]]])
AC_DEFINE([STACK_POINTER], [sp])
+ AC_DEFINE([PROGRAM_COUNTER], [pc])
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -346,6 +346,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [[uregs[2]]])
AC_DEFINE([SYSCALL_ARG3_REG], [[uregs[3]]])
AC_DEFINE([STACK_POINTER], [[uregs[13]]])
+ AC_DEFINE([PROGRAM_COUNTER], [[uregs[15]]])
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -371,6 +372,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [[uregs[2]]])
AC_DEFINE([SYSCALL_ARG3_REG], [[uregs[3]]])
AC_DEFINE([STACK_POINTER], [[uregs[13]]])
+ AC_DEFINE([STACK_POINTER], [[uregs[15]]])
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -402,6 +404,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [[gregs[4]]]) # a2
AC_DEFINE([SYSCALL_ARG3_REG], [[gregs[5]]]) # a3
AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp
+ AC_DEFINE([PROGRAM_COUNTER], [[cp0_epc]]) # pc
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -432,6 +435,7 @@ AS_CASE([$host], [x86_64-*linux*],
AC_DEFINE([SYSCALL_ARG2_REG], [[gregs[4]]]) # a2
AC_DEFINE([SYSCALL_ARG3_REG], [[gregs[5]]]) # a3
AC_DEFINE([STACK_POINTER], [[gregs[29]]]) # sp
+ AC_DEFINE([PROGRAM_COUNTER], [[cp0_epc]]) # pc
AC_DEFINE([EXEC_SYSCALL], [__NR_execve])
AC_DEFINE([USER_WORD], [uintptr_t])
AC_DEFINE([USER_SWORD], [intptr_t])
@@ -480,6 +484,12 @@ AC_ARG_VAR([LOADERFLAGS], [Flags used to link the loader.])
AC_ARG_VAR([ARFLAGS], [Flags for the archiver.])
AC_ARG_VAR([ASFLAGS], [Flags for the assembler.])
+# Search for seccomp headers and declarations.
+AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h],
+ [AC_CHECK_DECLS([SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, SECCOMP_RET_TRACE],
+ [AC_DEFINE([HAVE_SECCOMP], [1])], [],
+ [[#include <linux/seccomp.h>]])])
+
# Make the assembler optimize for code size. Don't do this on MIPS,
# as the assembler code manages branch delays manually.
@@ -547,7 +557,9 @@ FIND_DELETE=$exec_cv_find_delete
AC_SUBST([FIND_DELETE])
AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([Makefile config-mips.m4])
+AC_CONFIG_FILES([Makefile])
+AS_IF([test "x$is_mips" = xyes],
+ [AC_CONFIG_FILES ([config-mips.m4])])
AC_SUBST([AUTO_DEPEND])
AC_SUBST([LOADERFLAGS])
@@ -556,5 +568,6 @@ AC_SUBST([ASFLAGS])
AC_SUBST([exec_loader])
AC_SUBST([MIPS_N32])
AC_SUBST([OBJS])
+AC_SUBST([is_mips])
AC_OUTPUT
diff --git a/exec/exec.c b/exec/exec.c
index cbe22d4f18c..775a8b06b96 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -292,7 +292,9 @@ write_load_command (program_header *header, bool use_alternate,
struct exec_map_command command1;
USER_WORD start, end;
bool need_command1;
+#ifndef PAGE_MASK
static long pagesize;
+#endif /* !PAGE_MASK */
/* First, write the commands necessary to map the specified segment
itself.
@@ -306,14 +308,14 @@ write_load_command (program_header *header, bool use_alternate,
#ifdef HAVE_GETPAGESIZE
if (!pagesize)
pagesize = getpagesize ();
-#else /* HAVE_GETPAGESIZE */
+#else /* !HAVE_GETPAGESIZE */
if (!pagesize)
pagesize = sysconf (_SC_PAGESIZE);
-#endif /* HAVE_GETPAGESIZE */
+#endif /* !HAVE_GETPAGESIZE */
#define PAGE_MASK (~(pagesize - 1))
#define PAGE_SIZE (pagesize)
-#endif /* PAGE_MASK */
+#endif /* !PAGE_MASK */
start = header->p_vaddr & PAGE_MASK;
end = ((header->p_vaddr + header->p_filesz
@@ -895,10 +897,6 @@ format_pid (char *in, unsigned int pid)
with #!; in that case, find the program to open and use that
instead.
- If REENTRANT is not defined, NAME is actually a buffer of size
- PATH_MAX + 80. In that case, copy over the file name actually
- opened.
-
Next, read the executable header, and add the necessary memory
mappings for each file. Finally, return the action data and its
size in *SIZE.
@@ -978,9 +976,7 @@ exec_0 (char *name, struct exec_tracee *tracee,
memcpy (rewrite, name, strnlen (name, remaining));
/* Replace name with buffer1. */
-#ifndef REENTRANT
strcpy (name, buffer1);
-#endif /* REENTRANT */
}
}
diff --git a/exec/exec.h b/exec/exec.h
index 3ce06c35311..59963587573 100644
--- a/exec/exec.h
+++ b/exec/exec.h
@@ -152,6 +152,16 @@ struct exec_tracee
completion. */
USER_WORD sp;
+ /* Name of the executable being run. */
+ char *exec_file;
+
+ /* Pointer to a storage area holding instructions for loading an
+ executable if an `exec' system call is outstanding, or NULL. */
+ char *exec_data;
+
+ /* Number of bytes in exec_data. */
+ size_t data_size;
+
/* The thread ID of this process. */
pid_t pid;
@@ -162,11 +172,6 @@ struct exec_tracee
/* Whether or not the tracee has been created but is not yet
processed by `handle_clone'. */
bool new_child : 1;
-
-#ifndef REENTRANT
- /* Name of the executable being run. */
- char *exec_file;
-#endif /* !REENTRANT */
};
diff --git a/exec/exec1.c b/exec/exec1.c
index aaff9a94c62..cbd756d3d5c 100644
--- a/exec/exec1.c
+++ b/exec/exec1.c
@@ -42,6 +42,9 @@ main (int argc, char **argv)
extern char **environ;
int wstatus;
+ /* Provide the file name of the loader. */
+ exec_init (argv[1]);
+
pid1 = getpid ();
pid = fork ();
@@ -58,9 +61,6 @@ main (int argc, char **argv)
}
else
{
- /* Provide the file name of the loader. */
- exec_init (argv[1]);
-
if (after_fork (pid))
exit (127);
diff --git a/exec/loader-x86.s b/exec/loader-x86.s
index 216bc88f976..3d132dd99e8 100644
--- a/exec/loader-x86.s
+++ b/exec/loader-x86.s
@@ -1,71 +1,68 @@
-define(`CC', `
-dnl')
-
-CC Copyright (C) 2023-2024 Free Software Foundation, Inc.
-CC
-CC This file is part of GNU Emacs.
-CC
-CC GNU Emacs is free software: you can redistribute it and/or modify
-CC it under the terms of the GNU General Public License as published
-CC by the Free Software Foundation, either version 3 of the License,
-CC or (at your option) any later version.
-CC
-CC GNU Emacs is distributed in the hope that it will be useful, but
-CC WITHOUT ANY WARRANTY; without even the implied warranty of
-CC MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-CC General Public License for more details.
-CC
-CC You should have received a copy of the GNU General Public License
-CC along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+# Copyright (C) 2023-2024 Free Software Foundation, Inc.
+#
+# This file is part of GNU Emacs.
+#
+# GNU Emacs is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License,
+# or (at your option) any later version.
+#
+# GNU Emacs is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
.section .text
.global _start
_start:
-dnl movl $162, %eax CC SYS_nanosleep
-dnl leal timespec, %ebx
-dnl xorl %ecx, %ecx
-dnl int $0x80
- leal 8(%esp), %ebp CC ebp = start of load area
- subl $8, %esp CC (%esp) = primary fd, 4(%esp) = secondary fd
+# movl $162, %eax # SYS_nanosleep
+# leal timespec, %ebx
+# xorl %ecx, %ecx
+# int $0x80
+ leal 8(%esp), %ebp # ebp = start of load area
+ subl $8, %esp # (%esp) = primary fd, 4(%esp) = secondary fd
movl $-1, 4(%esp)
.next_action:
- movl (%ebp), %edx CC edx = action number
+ movl (%ebp), %edx # edx = action number
andl $-17, %edx
- cmpl $0, %edx CC open file?
+ cmpl $0, %edx # open file?
je .open_file
- cmpl $3, %edx CC jump?
+ cmpl $3, %edx # jump?
je .rest_of_exec
- cmpl $4, %edx CC anonymous mmap?
+ cmpl $4, %edx # anonymous mmap?
je .do_mmap_anon
.do_mmap:
subl $24, %esp
- movl $90, %eax CC SYS_old_mmap
+ movl $90, %eax # SYS_old_mmap
movl %esp, %ebx
- movl 4(%ebp), %ecx CC address
+ movl 4(%ebp), %ecx # address
movl %ecx, (%esp)
- movl 16(%ebp), %ecx CC length
+ movl 16(%ebp), %ecx # length
movl %ecx, 4(%esp)
- movl 12(%ebp), %ecx CC protection
+ movl 12(%ebp), %ecx # protection
movl %ecx, 8(%esp)
- movl 20(%ebp), %ecx CC flags
+ movl 20(%ebp), %ecx # flags
movl %ecx, 12(%esp)
- testl $16, (%ebp) CC primary?
+ testl $16, (%ebp) # primary?
movl 28(%esp), %ecx
cmovzl 24(%esp), %ecx
- movl %ecx, 16(%esp) CC fd
- movl 8(%ebp), %ecx CC offset
+ movl %ecx, 16(%esp) # fd
+ movl 8(%ebp), %ecx # offset
movl %ecx, 20(%esp)
.do_mmap_1:
int $0x80
- addl $24, %esp CC restore esp
- cmpl $-1, %eax CC mmap failed?
+ addl $24, %esp # restore esp
+ cmpl $-1, %eax # mmap failed?
je .perror
- movl 24(%ebp), %ecx CC clear
+ movl 24(%ebp), %ecx # clear
testl %ecx, %ecx
jz .continue
- movl 4(%ebp), %esi CC start of mapping
- addl 16(%ebp), %esi CC end of mapping
- subl %ecx, %esi CC start of clear area
+ movl 4(%ebp), %esi # start of mapping
+ addl 16(%ebp), %esi # end of mapping
+ subl %ecx, %esi # start of clear area
.again:
testl %ecx, %ecx
jz .continue
@@ -77,58 +74,58 @@ dnl int $0x80
jmp .next_action
.do_mmap_anon:
subl $24, %esp
- movl $90, %eax CC SYS_old_mmap
+ movl $90, %eax # SYS_old_mmap
movl %esp, %ebx
- movl 4(%ebp), %ecx CC address
+ movl 4(%ebp), %ecx # address
movl %ecx, (%esp)
- movl 16(%ebp), %ecx CC length
+ movl 16(%ebp), %ecx # length
movl %ecx, 4(%esp)
- movl 12(%ebp), %ecx CC protection
+ movl 12(%ebp), %ecx # protection
movl %ecx, 8(%esp)
- movl 20(%ebp), %ecx CC flags
+ movl 20(%ebp), %ecx # flags
movl %ecx, 12(%esp)
- movl $-1, 16(%esp) CC fd
- movl 8(%ebp), %ecx CC offset
+ movl $-1, 16(%esp) # fd
+ movl 8(%ebp), %ecx # offset
movl %ecx, 20(%esp)
jmp .do_mmap_1
.open_file:
- movl $5, %eax CC SYS_open
- leal 4(%ebp), %ebx CC ebx = %esp + 8
+ movl $5, %eax # SYS_open
+ leal 4(%ebp), %ebx # ebx = %esp + 8
pushl %ebx
- xorl %ecx, %ecx CC flags = O_RDONLY
- xorl %edx, %edx CC mode = 0
+ xorl %ecx, %ecx # flags = O_RDONLY
+ xorl %edx, %edx # mode = 0
int $0x80
- cmpl $-1, %eax CC open failed?
+ cmpl $-1, %eax # open failed?
jle .perror
- movl %ebp, %esi CC (esi) = original action number
- popl %ebp CC ebp = start of string
- movl %ebp, %ecx CC char past separator
+ movl %ebp, %esi # (esi) = original action number
+ popl %ebp # ebp = start of string
+ movl %ebp, %ecx # char past separator
decl %ebp
.nextc:
incl %ebp
- movb (%ebp), %dl CC dl = *ebp
- cmpb $47, %dl CC dl == '\?'?
+ movb (%ebp), %dl # dl = *ebp
+ cmpb $47, %dl # dl == '\?'?
jne .nextc1
- leal 1(%ebp), %ecx CC ecx = char past separator
+ leal 1(%ebp), %ecx # ecx = char past separator
.nextc1:
- cmpb $0, %dl CC dl == 0?
+ cmpb $0, %dl # dl == 0?
jne .nextc
- addl $4, %ebp CC adjust past ebp prior to rounding
- andl $-4, %ebp CC round ebp up to the next long
- testl $16, (%esi) CC original action number & 16?
+ addl $4, %ebp # adjust past ebp prior to rounding
+ andl $-4, %ebp # round ebp up to the next long
+ testl $16, (%esi) # original action number & 16?
jz .primary
- movl %eax, 4(%esp) CC secondary fd = eax
+ movl %eax, 4(%esp) # secondary fd = eax
jmp .next_action
.primary:
pushl %ebp
- xorl %esi, %esi CC arg3
- movl %eax, 4(%esp) CC primary fd = eax
- xorl %edx, %edx CC arg2
- movl $15, %ebx CC PR_SET_NAME, arg1 = ecx
- xorl %edi, %edi CC arg4
- movl $172, %eax CC SYS_prctl
- xorl %ebp, %ebp CC arg5
- int $0x80 CC syscall
+ xorl %esi, %esi # arg3
+ movl %eax, 4(%esp) # primary fd = eax
+ xorl %edx, %edx # arg2
+ movl $15, %ebx # PR_SET_NAME, arg1 = ecx
+ xorl %edi, %edi # arg4
+ movl $172, %eax # SYS_prctl
+ xorl %ebp, %ebp # arg5
+ int $0x80 # syscall
popl %ebp
jmp .next_action
.perror:
@@ -137,28 +134,28 @@ dnl int $0x80
movl $1, %eax
int $0x80
.rest_of_exec:
- movl 8(%esp), %ecx CC ecx = original stack pointer
- movl (%ecx), %esi CC esi = argc
- leal 8(%ecx, %esi, 4), %ecx CC ecx = start of environ
+ movl 8(%esp), %ecx # ecx = original stack pointer
+ movl (%ecx), %esi # esi = argc
+ leal 8(%ecx, %esi, 4), %ecx # ecx = start of environ
.skip_environ:
- movl (%ecx), %esi CC envp[N]
+ movl (%ecx), %esi # envp[N]
addl $4, %ecx
- testl %esi, %esi CC envp[n] ?
- jnz .skip_environ CC otherwise, esi is now at the start of auxv
+ testl %esi, %esi # envp[n] ?
+ jnz .skip_environ # otherwise, esi is now at the start of auxv
.one_auxv:
- movl (%ecx), %esi CC auxv type
- leal 8(%ecx), %ecx CC skip to next auxv
- testl %esi, %esi CC is 0?
+ movl (%ecx), %esi # auxv type
+ leal 8(%ecx), %ecx # skip to next auxv
+ testl %esi, %esi # is 0?
jz .cleanup
- cmpl $3, %esi CC is AT_PHDR
+ cmpl $3, %esi # is AT_PHDR
je .replace_phdr
- cmpl $4, %esi CC is AT_PHENT?
+ cmpl $4, %esi # is AT_PHENT?
je .replace_phent
- cmpl $5, %esi CC is AT_PHNUM?
+ cmpl $5, %esi # is AT_PHNUM?
je .replace_phnum
- cmpl $9, %esi CC is AT_ENTRY?
+ cmpl $9, %esi # is AT_ENTRY?
je .replace_entry
- cmpl $7, %esi CC is AT_BASE
+ cmpl $7, %esi # is AT_BASE
je .replace_base
jmp .one_auxv
.replace_phdr:
@@ -182,21 +179,21 @@ dnl int $0x80
movl %esi, -4(%ecx)
jmp .one_auxv
.cleanup:
- movl $6, %eax CC SYS_close
- cmpl $-1, 4(%esp) CC see if interpreter fd is set
+ movl $6, %eax # SYS_close
+ cmpl $-1, 4(%esp) # see if interpreter fd is set
je .cleanup_1
movl 4(%esp), %ebx
int $0x80
- movl $6, %eax CC SYS_close
+ movl $6, %eax # SYS_close
.cleanup_1:
movl (%esp), %ebx
int $0x80
.enter:
pushl $0
- popfl CC restore floating point state
- movl 8(%esp), %esp CC restore initial stack pointer
- xorl %edx, %edx CC clear rtld_fini
- jmpl *4(%ebp) CC entry
+ popfl # restore floating point state
+ movl 8(%esp), %esp # restore initial stack pointer
+ xorl %edx, %edx # clear rtld_fini
+ jmpl *4(%ebp) # entry
timespec:
.long 10
diff --git a/exec/loader-x86_64.s b/exec/loader-x86_64.s
index 2ef779e4504..ea2958b91e0 100644
--- a/exec/loader-x86_64.s
+++ b/exec/loader-x86_64.s
@@ -1,64 +1,61 @@
-define(`CC', `
-dnl')
-
-CC Copyright (C) 2023-2024 Free Software Foundation, Inc.
-CC
-CC This file is part of GNU Emacs.
-CC
-CC GNU Emacs is free software: you can redistribute it and/or modify
-CC it under the terms of the GNU General Public License as published
-CC by the Free Software Foundation, either version 3 of the License,
-CC or (at your option) any later version.
-CC
-CC GNU Emacs is distributed in the hope that it will be useful, but
-CC WITHOUT ANY WARRANTY; without even the implied warranty of
-CC MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-CC General Public License for more details.
-CC
-CC You should have received a copy of the GNU General Public License
-CC along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+# Copyright (C) 2023-2024 Free Software Foundation, Inc.
+#
+# This file is part of GNU Emacs.
+#
+# GNU Emacs is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published
+# by the Free Software Foundation, either version 3 of the License,
+# or (at your option) any later version.
+#
+# GNU Emacs is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
.section .text
.global _start
_start:
-dnl movq $35, %rax CC SYS_nanosleep
-dnl leaq timespec(%rip), %rdi
-dnl xorq %rsi, %rsi
-dnl syscall
- popq %r13 CC original SP
- popq %r15 CC size of load area.
- movq $-1, %r12 CC r12 is the interpreter fd
+# movq $35, %rax # SYS_nanosleep
+# leaq timespec(%rip), %rdi
+# xorq %rsi, %rsi
+# syscall
+ popq %r13 # original SP
+ popq %r15 # size of load area.
+ movq $-1, %r12 # r12 is the interpreter fd
.next_action:
- movq (%rsp), %r14 CC action number
- movq %r14, %r15 CC original action number
+ movq (%rsp), %r14 # action number
+ movq %r14, %r15 # original action number
andq $-17, %r14
- cmpq $0, %r14 CC open file?
+ cmpq $0, %r14 # open file?
je .open_file
- cmpq $3, %r14 CC jump?
+ cmpq $3, %r14 # jump?
je .rest_of_exec
- cmpq $4, %r14 CC anonymous mmap?
+ cmpq $4, %r14 # anonymous mmap?
je .do_mmap_anon
.do_mmap:
- movq $9, %rax CC SYS_mmap
- movq 8(%rsp), %rdi CC address
- movq 16(%rsp), %r9 CC offset
- movq 24(%rsp), %rdx CC protection
- movq 32(%rsp), %rsi CC length
- movq 40(%rsp), %r10 CC flags
- CC set r8 to the primary fd unless r15 & 16
+ movq $9, %rax # SYS_mmap
+ movq 8(%rsp), %rdi # address
+ movq 16(%rsp), %r9 # offset
+ movq 24(%rsp), %rdx # protection
+ movq 32(%rsp), %rsi # length
+ movq 40(%rsp), %r10 # flags
+ # set r8 to the primary fd unless r15 & 16
testq $16, %r15
movq %r12, %r8
cmovzq %rbx, %r8
.do_mmap_1:
syscall
- cmpq $-1, %rax CC mmap failed
+ cmpq $-1, %rax # mmap failed
je .perror
- movq 48(%rsp), %r9 CC clear
+ movq 48(%rsp), %r9 # clear
testq %r9, %r9
jz .continue
- movq 8(%rsp), %r10 CC start of mapping
- addq 32(%rsp), %r10 CC end of mapping
- subq %r9, %r10 CC start of clear area
+ movq 8(%rsp), %r10 # start of mapping
+ addq 32(%rsp), %r10 # end of mapping
+ subq %r9, %r10 # start of clear area
.again:
testq %r9, %r9
jz .continue
@@ -69,124 +66,124 @@ dnl syscall
leaq 56(%rsp), %rsp
jmp .next_action
.do_mmap_anon:
- movq $9, %rax CC SYS_mmap
- movq 8(%rsp), %rdi CC address
- movq 16(%rsp), %r9 CC offset
- movq 24(%rsp), %rdx CC protection
- movq 32(%rsp), %rsi CC length
- movq 40(%rsp), %r10 CC flags
- movq $-1, %r8 CC -1
+ movq $9, %rax # SYS_mmap
+ movq 8(%rsp), %rdi # address
+ movq 16(%rsp), %r9 # offset
+ movq 24(%rsp), %rdx # protection
+ movq 32(%rsp), %rsi # length
+ movq 40(%rsp), %r10 # flags
+ movq $-1, %r8 # -1
jmp .do_mmap_1
.open_file:
- movq $2, %rax CC SYS_open
- leaq 8(%rsp), %rdi CC rdi = %rsp + 8
- xorq %rsi, %rsi CC flags = O_RDONLY
- xorq %rdx, %rdx CC mode = 0
+ movq $2, %rax # SYS_open
+ leaq 8(%rsp), %rdi # rdi = %rsp + 8
+ xorq %rsi, %rsi # flags = O_RDONLY
+ xorq %rdx, %rdx # mode = 0
syscall
- cmpq $-1, %rax CC open failed
+ cmpq $-1, %rax # open failed
jle .perror
- movq %rdi, %rsp CC rsp = start of string
+ movq %rdi, %rsp # rsp = start of string
subq $1, %rsp
- movq %rsp, %r14 CC r14 = start of string
+ movq %rsp, %r14 # r14 = start of string
.nextc:
addq $1, %rsp
- movb (%rsp), %dil CC rdi = *rsp
- cmpb $47, %dil CC *rsp == '/'?
+ movb (%rsp), %dil # rdi = *rsp
+ cmpb $47, %dil # *rsp == '/'?
jne .nextc1
- movq %rsp, %r14 CC r14 = rsp
- addq $1, %r14 CC r14 = char past separator
+ movq %rsp, %r14 # r14 = rsp
+ addq $1, %r14 # r14 = char past separator
.nextc1:
- cmpb $0, %dil CC *rsp == 0?
+ cmpb $0, %dil # *rsp == 0?
jne .nextc
- addq $8, %rsp CC adjust past rsp prior to rounding
- andq $-8, %rsp CC round rsp up to the next quad
- testq $16, %r15 CC r15 & 16?
+ addq $8, %rsp # adjust past rsp prior to rounding
+ andq $-8, %rsp # round rsp up to the next quad
+ testq $16, %r15 # r15 & 16?
jz .primary
- movq %rax, %r12 CC otherwise, move fd to r12
+ movq %rax, %r12 # otherwise, move fd to r12
jmp .next_action
.primary:
- movq %rax, %rbx CC if not, move fd to rbx
- movq $157, %rax CC SYS_prctl
- movq $15, %rdi CC PR_SET_NAME
- movq %r14, %rsi CC arg1
- xorq %rdx, %rdx CC arg2
- xorq %r10, %r10 CC arg3
- xorq %r8, %r8 CC arg4
- xorq %r9, %r9 CC arg5
+ movq %rax, %rbx # if not, move fd to rbx
+ movq $157, %rax # SYS_prctl
+ movq $15, %rdi # PR_SET_NAME
+ movq %r14, %rsi # arg1
+ xorq %rdx, %rdx # arg2
+ xorq %r10, %r10 # arg3
+ xorq %r8, %r8 # arg4
+ xorq %r9, %r9 # arg5
syscall
jmp .next_action
.perror:
- movq %rax, %r12 CC error code
+ movq %rax, %r12 # error code
negq %r12
- movq $1, %rax CC SYS_write
- movq $1, %rdi CC stdout
- leaq error(%rip), %rsi CC buffer
- movq $23, %rdx CC count
+ movq $1, %rax # SYS_write
+ movq $1, %rdi # stdout
+ leaq error(%rip), %rsi # buffer
+ movq $23, %rdx # count
syscall
- movq $60, %rax CC SYS_exit
- movq %r12, %rdi CC code
+ movq $60, %rax # SYS_exit
+ movq %r12, %rdi # code
syscall
-.rest_of_exec: CC rsp now points to six quads:
- movq %rsp, %r8 CC now, they are r8
- movq %r13, %rsp CC restore SP
- popq %r10 CC argc
- leaq 8(%rsp,%r10,8), %rsp CC now at start of environ
+.rest_of_exec: # rsp now points to six quads:
+ movq %rsp, %r8 # now, they are r8
+ movq %r13, %rsp # restore SP
+ popq %r10 # argc
+ leaq 8(%rsp,%r10,8), %rsp # now at start of environ
.skip_environ:
- popq %r10 CC envp[N]
- testq %r10, %r10 CC envp[n]?
- jnz .skip_environ CC otherwise, rsp is now at the start of auxv
+ popq %r10 # envp[N]
+ testq %r10, %r10 # envp[n]?
+ jnz .skip_environ # otherwise, rsp is now at the start of auxv
.one_auxv:
- popq %rcx CC auxv type
- addq $8, %rsp CC skip value
- testq %rcx, %rcx CC is 0?
+ popq %rcx # auxv type
+ addq $8, %rsp # skip value
+ testq %rcx, %rcx # is 0?
jz .cleanup
- cmpq $3, %rcx CC is AT_PHDR?
+ cmpq $3, %rcx # is AT_PHDR?
je .replace_phdr
- cmpq $4, %rcx CC is AT_PHENT?
+ cmpq $4, %rcx # is AT_PHENT?
je .replace_phent
- cmpq $5, %rcx CC is AT_PHNUM?
+ cmpq $5, %rcx # is AT_PHNUM?
je .replace_phnum
- cmpq $9, %rcx CC is AT_ENTRY?
+ cmpq $9, %rcx # is AT_ENTRY?
je .replace_entry
- cmpq $7, %rcx CC is AT_BASE?
+ cmpq $7, %rcx # is AT_BASE?
je .replace_base
jmp .one_auxv
.replace_phdr:
movq 40(%r8), %r9
- movq %r9, -8(%rsp) CC set at_phdr
+ movq %r9, -8(%rsp) # set at_phdr
jmp .one_auxv
.replace_phent:
movq 24(%r8), %r9
- movq %r9, -8(%rsp) CC set at_phent
+ movq %r9, -8(%rsp) # set at_phent
jmp .one_auxv
.replace_phnum:
movq 32(%r8), %r9
- movq %r9, -8(%rsp) CC set at_phnum
+ movq %r9, -8(%rsp) # set at_phnum
jmp .one_auxv
.replace_entry:
movq 16(%r8), %r9
- movq %r9, -8(%rsp) CC set at_entry
+ movq %r9, -8(%rsp) # set at_entry
jmp .one_auxv
.replace_base:
movq 48(%r8), %r9
- movq %r9, -8(%rsp) CC set at_base
+ movq %r9, -8(%rsp) # set at_base
jmp .one_auxv
.cleanup:
- movq $3, %rax CC SYS_close
- cmpq $-1, %r12 CC see if interpreter fd is set
+ movq $3, %rax # SYS_close
+ cmpq $-1, %r12 # see if interpreter fd is set
je .cleanup_1
movq %r12, %rdi
syscall
- movq $3, %rax CC SYS_close
+ movq $3, %rax # SYS_close
.cleanup_1:
movq %rbx, %rdi
syscall
.enter:
pushq $0
- popfq CC clear FP state
- movq %r13, %rsp CC restore SP
- xorq %rdx, %rdx CC clear rtld_fini
- jmpq *8(%r8) CC entry
+ popfq # clear FP state
+ movq %r13, %rsp # restore SP
+ xorq %rdx, %rdx # clear rtld_fini
+ jmpq *8(%r8) # entry
error:
.ascii "_start: internal error."
diff --git a/exec/mipsel-user.h b/exec/mipsel-user.h
index 04f4a2a5089..14d8f6d0d5e 100644
--- a/exec/mipsel-user.h
+++ b/exec/mipsel-user.h
@@ -24,10 +24,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/user.h>
-#ifndef ELF_NGREG
-#define ELF_NGREG 45
-#endif /* ELF_NGREG */
-
/* This file defines a structure containing user mode general purpose
@@ -36,7 +32,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
struct mipsel_regs
{
/* General purpose registers. */
- uint64_t gregs[ELF_NGREG];
+ uint64_t gregs[32];
+
+ /* Saved special registers. */
+ uint64_t lo;
+ uint64_t hi;
+ uint64_t cp0_epc;
+ uint64_t cp0_badvaddr;
+ uint64_t cp0_status;
+ uint64_t cp0_cause;
};
#endif /* _MIPSEL_USER_H_ */
diff --git a/exec/trace.c b/exec/trace.c
index 05d862f5b9f..2af6d867efe 100644
--- a/exec/trace.c
+++ b/exec/trace.c
@@ -49,11 +49,21 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#ifndef SYS_SECCOMP
#define SYS_SECCOMP 1
-#endif /* SYS_SECCOMP */
+#endif /* !defined SYS_SECCOMP */
#ifndef PTRACE_GETEVENTMSG
#define PTRACE_GETEVENTMSG 0x4201
-#endif /* PTRACE_GETEVENTMSG */
+#endif /* !defined PTRACE_GETEVENTMSG */
+
+#ifdef HAVE_SECCOMP
+#include <linux/seccomp.h>
+#include <linux/filter.h>
+
+#include <sys/utsname.h>
+#include <sys/prctl.h>
+
+#include <stdio.h>
+#endif /* !defined HAVE_SECCOMP */
@@ -70,6 +80,15 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* Number of tracees children are allowed to create. */
#define MAX_TRACEES 4096
+#ifdef HAVE_SECCOMP
+
+/* Whether to enable seccomp acceleration. */
+static bool use_seccomp_p;
+
+#else /* !HAVE_SECCOMP */
+#define use_seccomp_p (false)
+#endif /* HAVE_SECCOMP */
+
#ifdef __aarch64__
/* Place PID's registers into *REGS. Return 1 upon failure, else
@@ -105,8 +124,7 @@ aarch64_set_regs (pid_t pid, USER_REGS_STRUCT *regs,
iov.iov_base = regs;
iov.iov_len = sizeof *regs;
- rc = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS,
- &iov);
+ rc = ptrace (PTRACE_SETREGSET, pid, NT_PRSTATUS, &iov);
if (rc < 0)
return 1;
@@ -367,14 +385,17 @@ remove_tracee (struct exec_tracee *tracee)
/* Link the tracee onto the list of free tracees. */
tracee->next = free_tracees;
-#ifndef REENTRANT
/* Free the exec file, if any. */
free (tracee->exec_file);
tracee->exec_file = NULL;
-#endif /* REENTRANT */
- free_tracees = tracee;
+ /* Likewise with any loader instructions that might be
+ present. */
+ free (tracee->exec_data);
+ tracee->exec_data = NULL;
+ /* Return this tracee to the list of free ones. */
+ free_tracees = tracee;
return;
}
else
@@ -419,7 +440,6 @@ find_tracee (pid_t process)
static void
handle_clone_prepare (struct exec_tracee *parent)
{
-#ifndef REENTRANT
long rc;
unsigned long pid;
struct exec_tracee *tracee;
@@ -440,7 +460,8 @@ handle_clone_prepare (struct exec_tracee *parent)
assert (tracee->new_child);
tracee->new_child = false;
tracee->exec_file = NULL;
- ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, 0, 0);
if (parent->exec_file)
tracee->exec_file = strdup (parent->exec_file);
@@ -457,12 +478,9 @@ handle_clone_prepare (struct exec_tracee *parent)
tracee = &static_tracees[tracees];
tracees++;
}
-#ifndef REENTRANT
- /* Try to allocate a tracee using `malloc' if this library is
- not being built to run inside a signal handler. */
+ /* Try to allocate a tracee using `malloc'. */
else if ((tracee = malloc (sizeof *tracee)))
;
-#endif /* REENTRANT */
else
return;
@@ -477,7 +495,6 @@ handle_clone_prepare (struct exec_tracee *parent)
if (parent->exec_file)
tracee->exec_file = strdup (parent->exec_file);
-#endif /* REENTRANT */
}
/* Handle the completion of a `clone' or `clone3' system call,
@@ -513,21 +530,18 @@ handle_clone (struct exec_tracee *tracee, pid_t pid)
tracee = &static_tracees[tracees];
tracees++;
}
-#ifndef REENTRANT
- /* Try to allocate a tracee using `malloc' if this library is
- not being built to run inside a signal handler. */
+ /* Try to allocate a tracee using `malloc'. */
else if ((tracee = malloc (sizeof *tracee)))
;
-#endif /* REENTRANT */
else
return 1;
tracee->pid = pid;
tracee->next = tracing_processes;
tracee->waiting_for_syscall = false;
-#ifndef REENTRANT
tracee->exec_file = NULL;
-#endif /* REENTRANT */
+ tracee->exec_data = NULL;
+ tracee->data_size = 0;
tracing_processes = tracee;
tracee->new_child = true;
@@ -549,6 +563,11 @@ handle_clone (struct exec_tracee *tracee, pid_t pid)
flags |= PTRACE_O_TRACESYSGOOD;
flags |= PTRACE_O_TRACEEXIT;
+#ifdef HAVE_SECCOMP
+ if (use_seccomp_p)
+ flags |= PTRACE_O_TRACESECCOMP;
+#endif /* HAVE_SECCOMP */
+
rc = ptrace (PTRACE_SETOPTIONS, pid, 0, flags);
if (rc)
@@ -559,7 +578,8 @@ handle_clone (struct exec_tracee *tracee, pid_t pid)
/* The new tracee is currently stopped. Continue it until the next
system call. */
- rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, 0);
if (rc)
goto bail;
@@ -618,9 +638,11 @@ check_signal (struct exec_tracee *tracee, int status)
{
if (siginfo.si_code < 0)
/* SIGTRAP delivered from userspace. Pass it on. */
- ptrace (PTRACE_SYSCALL, tracee->pid, 0, SIGTRAP);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, 0, SIGTRAP);
else
- ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, 0, 0);
return 1;
}
@@ -639,26 +661,28 @@ check_signal (struct exec_tracee *tracee, int status)
it. */
#ifdef HAVE_SIGINFO_T_SI_SYSCALL
#ifndef __arm__
- ptrace (PTRACE_SYSCALL, tracee->pid,
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid,
0, ((siginfo.si_code == SYS_SECCOMP
&& siginfo.si_syscall == -1)
? 0 : status));
#else /* __arm__ */
- ptrace (PTRACE_SYSCALL, tracee->pid,
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid,
0, ((siginfo.si_code == SYS_SECCOMP
&& siginfo.si_syscall == 222)
? 0 : status));
#endif /* !__arm__ */
#else /* !HAVE_SIGINFO_T_SI_SYSCALL */
/* Drop this signal, since what caused it is unknown. */
- ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid,
+ 0, 0);
#endif /* HAVE_SIGINFO_T_SI_SYSCALL */
return 1;
#endif /* SIGSYS */
default:
/* Continue the process until the next syscall. */
- ptrace (PTRACE_SYSCALL, tracee->pid, 0, status);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, 0, status);
return 1;
}
@@ -667,17 +691,16 @@ check_signal (struct exec_tracee *tracee, int status)
-/* Handle an `exec' system call from the given TRACEE. REGS are the
- tracee's current user-mode registers.
+/* Handle the first stage of an `exec' system call from the given
+ TRACEE. REGS are the tracee's current user-mode registers.
Rewrite the system call arguments to use the loader binary. Then,
- continue the system call until the loader is loaded. Write the
- information necessary to load the original executable into the
- loader's stack.
+ resume the process till the loader is loaded and about to begin
+ execution. Save instructions to load the original executable into
+ TRACEE->exec_data.
Value is 0 upon success, 1 upon a generic failure before the loader
- is loaded, 2 if the process has stopped, and 3 if something failed,
- but it is too late to handle it.
+ is loaded.
Set errno appropriately upon returning a generic failure. */
@@ -687,16 +710,10 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
char buffer[PATH_MAX + 80], *area;
USER_REGS_STRUCT original;
size_t size, loader_size;
- USER_WORD loader, size1, sp;
- int rc, wstatus;
- siginfo_t siginfo;
-
- /* Save the old stack pointer. */
- sp = regs->STACK_POINTER;
+ USER_WORD loader;
/* Read the file name. */
- read_memory (tracee, buffer, PATH_MAX,
- regs->SYSCALL_ARG_REG);
+ read_memory (tracee, buffer, PATH_MAX, regs->SYSCALL_ARG_REG);
/* Make sure BUFFER is NULL terminated. */
@@ -722,8 +739,18 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
return 1;
}
- /* Rewrite the first argument to point to the loader. */
+ /* Save this area in the tracee. */
+ assert (!tracee->exec_data);
+ tracee->exec_data = malloc (size);
+ if (!tracee->exec_data)
+ {
+ errno = ENOMEM;
+ return 1;
+ }
+ memcpy (tracee->exec_data, area, size);
+ tracee->data_size = size;
+ /* Rewrite the first argument to point to the loader. */
loader_size = strlen (loader_name) + 1;
loader = user_alloca (tracee, &original, regs,
loader_size);
@@ -731,14 +758,14 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
if (!loader)
{
errno = ENOMEM;
- return 1;
+ goto free_data_error;
}
if (user_copy (tracee, (unsigned char *) loader_name,
loader, loader_size))
{
errno = EIO;
- return 1;
+ goto free_data_error;
}
regs->SYSCALL_ARG_REG = loader;
@@ -748,151 +775,118 @@ handle_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
if (aarch64_set_regs (tracee->pid, regs, false))
{
errno = EIO;
- return 1;
+ goto free_data_error;
}
#else /* !__aarch64__ */
- if (ptrace (PTRACE_SETREGS, tracee->pid, NULL,
- regs))
+ if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs))
{
errno = EIO;
- return 1;
+ goto free_data_error;
}
#endif /* __aarch64__ */
- /* Continue the system call until loader starts. */
+ /* Resume the process till the loader is executed. */
if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL))
{
errno = EIO;
- return 1;
+ goto free_data_error;
}
-#ifndef REENTRANT
- /* Now that the loader has started, record the value to use for
- /proc/self/exe. Don't give up just because strdup fails.
+ /* Now that the loader has been executed, record the value to
+ substitute for /proc/self/exe. Don't give up just because strdup
+ fails.
Note that exec_0 copies the absolute file name into buffer. */
if (tracee->exec_file)
free (tracee->exec_file);
tracee->exec_file = strdup (buffer);
-#endif /* REENTRANT */
-
- again:
- rc = waitpid (tracee->pid, &wstatus, __WALL);
- if (rc == -1 && errno == EINTR)
- goto again;
-
- if (rc < 0)
- return 1;
-
- if (!WIFSTOPPED (wstatus))
- /* The process has been killed in response to a signal.
- In this case, simply return 2. */
- return 2;
- else
- {
- /* Then, check if STATUS is not a syscall-stop, and try again if
- it isn't. */
- rc = check_signal (tracee, wstatus);
-
- if (rc == -1)
- return 2;
- else if (rc)
- goto again;
-
- /* Retrieve the signal information and determine whether or not
- the system call has completed. */
-
- if (ptrace (PTRACE_GETSIGINFO, tracee->pid, 0,
- &siginfo))
- return 3;
-
- if (!syscall_trap_p (&siginfo))
- {
- /* Continue. */
- if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0))
- return 3;
-
- goto again;
- }
- }
-
-#ifdef __aarch64__
-
- if (aarch64_get_regs (tracee->pid, &original))
- return 3;
+ return 0;
-#else /* !__aarch64__ */
+ free_data_error:
+ free (tracee->exec_data);
+ tracee->exec_data = NULL;
+ return 1;
+}
- /* The system call has now completed. Get the registers again. */
+/* Complete an `exec' system call issued by TRACEE. Write the
+ instructions stored in TRACEE->exec_data to an appropriate location
+ in TRACEE's stack, and resume TRACEE, releasing TRACEE->exec_data.
+ REGS should be the TRACEE's user registers. If the reissued system
+ call did not succeed in starting the executable loader, restore
+ TRACEE->sp (recorded by process_system_call or seccomp_system_call),
+ and resume execution, so that the failure may be reported. */
- if (ptrace (PTRACE_GETREGS, tracee->pid, NULL,
- &original))
- return 3;
+static void
+finish_exec (struct exec_tracee *tracee, USER_REGS_STRUCT *regs)
+{
+ USER_WORD size1, loader;
+ USER_REGS_STRUCT original;
-#endif /* __aarch64__ */
+ size1 = tracee->data_size;
- *regs = original;
+ /* Record the registers' values as they originally were. */
+ memcpy (&original, regs, sizeof *regs);
- /* Upon failure, wait for the next system call and return
- success. */
+ /* Any non-zero value of `original.SYSCALL_RET_REG' indicates that the
+ reissued `exec' call was unsuccessful, and the loader is not
+ executing. Restore the previous stack pointer and permit the
+ tracee to run to completion. */
if (original.SYSCALL_RET_REG)
{
- /* Restore the original stack pointer. */
- regs->STACK_POINTER = sp;
-
+ regs->STACK_POINTER = tracee->sp;
#ifdef __aarch64__
aarch64_set_regs (tracee->pid, regs, false);
#else /* !__aarch64__ */
ptrace (PTRACE_SETREGS, tracee->pid, NULL, regs);
#endif /* __aarch64__ */
- goto exec_failure;
+ /* Continue; not much in the way of remediation is available if
+ either of PTRACE_SETREGS and this resumption fails. */
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, 0, 0);
+ goto error;
}
/* Write the loader area to the stack, followed by its size and the
original stack pointer. */
loader = user_alloca (tracee, &original, regs,
- size + sizeof loader * 2);
+ size1 + sizeof loader * 2);
if (!loader)
- return 3;
-
- size1 = size;
+ goto error;
#ifndef STACK_GROWS_DOWNWARDS
-
- NOT_IMPLEMENTED;
-
+ not implemented, you lose.
#else /* STACK_GROWS_DOWNWARDS */
- if (user_copy (tracee, (unsigned char *) area,
- loader + sizeof size1 * 2, size)
+ if (user_copy (tracee, (unsigned char *) tracee->exec_data,
+ loader + sizeof size1 * 2, size1)
|| user_copy (tracee, (unsigned char *) &size1,
loader + sizeof size1, sizeof size1))
- return 3;
+ goto error;
size1 = original.STACK_POINTER;
if (user_copy (tracee, (unsigned char *) &size1,
loader, sizeof size1))
- return 3;
+ goto error;
#endif /* STACK_GROWS_DOWNWARDS */
/* Continue. */
- if (ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0))
- return 3;
-
- return 0;
+ if (ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, 0, 0))
+ goto error;
- exec_failure:
- return 3;
+ error:
+ free (tracee->exec_data);
+ tracee->exec_data = NULL;
}
@@ -1007,13 +1001,6 @@ static int
handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs,
struct exec_tracee *tracee, USER_WORD *result)
{
-#ifdef REENTRANT
- /* readlinkat cannot be handled specially when the library is built
- to be reentrant, as the file name information cannot be
- recorded. */
- return 0;
-#else /* !REENTRANT */
-
char buffer[PATH_MAX + 1];
USER_WORD address, return_buffer, size;
size_t length;
@@ -1086,7 +1073,6 @@ handle_readlinkat (USER_WORD callno, USER_REGS_STRUCT *regs,
*result = length;
return 2;
-#endif /* REENTRANT */
}
/* Handle an `open' or `openat' system call.
@@ -1104,12 +1090,6 @@ static int
handle_openat (USER_WORD callno, USER_REGS_STRUCT *regs,
struct exec_tracee *tracee, USER_WORD *result)
{
-#ifdef REENTRANT
- /* readlinkat cannot be handled specially when the library is built
- to be reentrant, as the file name information cannot be
- recorded. */
- return 0;
-#else /* !REENTRANT */
char buffer[PATH_MAX + 1];
USER_WORD address;
size_t length;
@@ -1199,7 +1179,6 @@ handle_openat (USER_WORD callno, USER_REGS_STRUCT *regs,
fail:
errno = EIO;
return 1;
-#endif /* REENTRANT */
}
/* Process the system call at which TRACEE is stopped. If the system
@@ -1229,30 +1208,43 @@ process_system_call (struct exec_tracee *tracee)
/* Save the stack pointer. */
sp = regs.STACK_POINTER;
- /* Now dispatch based on the system call. */
- callno = regs.SYSCALL_NUM_REG;
+ /* Now dispatch based on the system call. If TRACEE->exec_data is
+ set, this must be exec, whatever the value of SYSCALL_NUM_REG,
+ which is erased when exec loads another image. */
+
+ callno = (!tracee->exec_data ? regs.SYSCALL_NUM_REG : EXEC_SYSCALL);
switch (callno)
{
case EXEC_SYSCALL:
- /* exec system calls should be handled synchronously. */
- assert (!tracee->waiting_for_syscall);
- rc = handle_exec (tracee, &regs);
-
- switch (rc)
+ if (!tracee->waiting_for_syscall)
{
- case 3:
- /* It's too late to do anything about this error,. */
- break;
+ /* The outstanding syscall flag must not be inconsistent with
+ the presence of instructions for the loader. */
+ assert (!tracee->exec_data);
+ rc = handle_exec (tracee, &regs);
- case 2:
- /* The process has gone away. */
- remove_tracee (tracee);
- break;
+ if (rc)
+ /* An error has occurred; errno is set to the error. */
+ goto report_syscall_error;
+
+ /* The process has been resumed. Assert that the instructions
+ for loading this executable have been generated and
+ recorded, and set waiting_for_syscall. */
+ tracee->waiting_for_syscall = true;
+ assert (tracee->exec_data);
- case 1:
- /* An error has occurred; errno is set to the error. */
- goto report_syscall_error;
+ /* Record the initial stack pointer also. */
+ tracee->sp = sp;
+ }
+ else
+ {
+ assert (tracee->exec_data);
+ finish_exec (tracee, &regs);
+
+ /* The process has been resumed and has become capable of
+ executing independently. */
+ tracee->waiting_for_syscall = false;
}
break;
@@ -1311,7 +1303,7 @@ process_system_call (struct exec_tracee *tracee)
regs.STACK_POINTER = tracee->sp;
#ifdef __aarch64__
- if (aarch64_set_regs (tracee->pid, &regs, true))
+ if (aarch64_set_regs (tracee->pid, &regs, false))
return;
#else /* !__aarch64__ */
if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, &regs))
@@ -1327,11 +1319,35 @@ process_system_call (struct exec_tracee *tracee)
will DTRT upon the next call to PTRACE_SYSCALL after the
syscall-trap signal is delivered. */
- rc = ptrace (PTRACE_SYSCALL, tracee->pid,
+ rc = ptrace (((use_seccomp_p
+ /* open and openat are not processed synchronously,
+ nor can they afford to dispense with
+ post-syscall finalization. */
+
+ && ((callno != OPENAT_SYSCALL
+#ifdef OPEN_SYSCALL
+ && callno != OPEN_SYSCALL
+#endif /* OPEN_SYSCALL */
+ )
+ /* Since syscall initialization should be
+ reserved for seccomp_system_call, resume the
+ process if this system call is already
+ complete. */
+ || !tracee->waiting_for_syscall))
+ ? PTRACE_CONT : PTRACE_SYSCALL), tracee->pid,
NULL, NULL);
if (rc < 0)
return;
+#ifdef HAVE_SECCOMP
+ if (!(use_seccomp_p
+ && ((callno != OPENAT_SYSCALL
+#ifdef OPEN_SYSCALL
+ && callno != OPEN_SYSCALL
+#endif /* OPEN_SYSCALL */
+ )
+ || !tracee->waiting_for_syscall)))
+#endif /* !HAVE_SECCOMP */
tracee->waiting_for_syscall = !tracee->waiting_for_syscall;
}
@@ -1345,9 +1361,10 @@ process_system_call (struct exec_tracee *tracee)
reporting_error = false;
common:
- /* Reporting an error or emulating a system call works by setting
- the system call number to -1, letting it continue, and then
- substituting errno for ENOSYS in the case of an error.
+ /* Reporting an error or emulating a system call works by replacing
+ the system call number with -1 or another nonexistent syscall,
+ letting it continue, and then substituting errno for ENOSYS in the
+ case of an error.
Make sure that the stack pointer is restored to its original
position upon exit, or bad things can happen. */
@@ -1426,13 +1443,13 @@ process_system_call (struct exec_tracee *tracee)
#endif /* __aarch64__ */
/* Now wait for the next system call to happen. */
- ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, NULL, NULL);
}
else
{
/* No error is being reported. Return the result in the
appropriate registers. */
-
#ifdef __mips__
/* MIPS systems place errno in v0 and set a3 to 1. */
regs.gregs[2] = result;
@@ -1449,14 +1466,367 @@ process_system_call (struct exec_tracee *tracee)
#endif /* __aarch64__ */
/* Now wait for the next system call to happen. */
- ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ tracee->pid, NULL, NULL);
}
}
+#ifdef HAVE_SECCOMP
+
+/* Seccomp acceleration.
+
+ Seccomp enables selectively filtering signals so that the tracing
+ process is only notified of such system calls as it is interested in
+ intercepting, i.e., exec and open*. This improves performance
+ enormously over the traditional approach of pausing the tracee before
+ each system call. */
+
+/* Whether the kernel's version is 4.7.x or earlier. */
+static bool kernel_4_7_or_earlier;
+
+/* Array of system calls this module is interested in intercepting. */
+static int interesting_syscalls[] =
+ {
+ EXEC_SYSCALL,
+#ifdef OPEN_SYSCALL
+ OPEN_SYSCALL,
+#endif /* OPEN_SYSCALL */
+ OPENAT_SYSCALL,
+#ifdef READLINK_SYSCALL
+ READLINK_SYSCALL,
+#endif /* READLINK_SYSCALL */
+ READLINKAT_SYSCALL,
+ };
+
+/* Number of elements in an array. */
+#define ARRAYELTS(arr) (sizeof (arr) / sizeof (arr)[0])
+
+/* Install a secure computing filter that will notify attached tracers
+ when a system call of interest to this module is received. Value is
+ 0 if successful, 1 otherwise. */
+
+static int
+establish_seccomp_filter (void)
+{
+ struct sock_filter statements[1 + ARRAYELTS (interesting_syscalls) + 2];
+ struct sock_fprog program;
+ int index, rc;
+
+ index = 0;
+
+ /* As the exec wrapper will reject executables for an inappropriate
+ architecture, verifying the same here would only be redundant.
+ Proceed to load the current system call number. */
+
+ statements[index++] = ((struct sock_filter)
+ BPF_STMT (BPF_LD + BPF_W + BPF_ABS,
+ offsetof (struct seccomp_data, nr)));
+
+ /* Search for system calls of interest. */
+
+ statements[index]
+ = ((struct sock_filter)
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, EXEC_SYSCALL,
+ ARRAYELTS (interesting_syscalls), 0)); index++;
+#ifdef OPEN_SYSCALL
+ statements[index]
+ = ((struct sock_filter)
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, OPEN_SYSCALL,
+ ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++;
+#endif /* OPEN_SYSCALL */
+ statements[index]
+ = ((struct sock_filter)
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, OPENAT_SYSCALL,
+ ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++;
+#ifdef READLINK_SYSCALL
+ statements[index]
+ = ((struct sock_filter)
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, READLINK_SYSCALL,
+ ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++;
+#endif /* READLINK_SYSCALL */
+ statements[index]
+ = ((struct sock_filter)
+ BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, READLINKAT_SYSCALL,
+ ARRAYELTS (interesting_syscalls) - index + 1, 0)); index++;
+
+ /* If not intercepted above, permit this system call to execute as
+ normal. */
+ statements[index++]
+ = (struct sock_filter) BPF_STMT (BPF_RET + BPF_K, SECCOMP_RET_ALLOW);
+ statements[index++]
+ = (struct sock_filter) BPF_STMT (BPF_RET + BPF_K, SECCOMP_RET_TRACE);
+
+ rc = prctl (PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ if (rc)
+ return 1;
+
+ program.len = ARRAYELTS (statements);
+ program.filter = statements;
+ rc = prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &program);
+ if (rc)
+ return 1;
+
+ return 0;
+}
+
+/* Intercept or resume and dismiss the system call at which TRACEE is
+ paused, similarly to process_system_call. */
+
+static void
+seccomp_system_call (struct exec_tracee *tracee)
+{
+ USER_REGS_STRUCT regs;
+ int rc, wstatus, save_errno;
+ USER_WORD callno, sp;
+ USER_WORD result;
+ bool reporting_error;
+
+ if (kernel_4_7_or_earlier)
+ {
+ /* On kernel 4.7 and earlier, following a PTRACE_EVENT_SECCOMP by
+ a PTRACE_SYSCALL will give rise to a syscall-entry stop event,
+ and seccomp filters will be suppressed till the system call
+ runs its course. */
+ ptrace (PTRACE_SYSCALL, tracee->pid, 0, 0);
+ return;
+ }
+
+#ifdef __aarch64__
+ rc = aarch64_get_regs (tracee->pid, &regs);
+#else /* !__aarch64__ */
+ rc = ptrace (PTRACE_GETREGS, tracee->pid, NULL,
+ &regs);
+#endif /* __aarch64__ */
+
+ /* TODO: what to do if this fails? */
+ if (rc < 0)
+ return;
+
+ /* On kernel 4.8, processes resumed after being paused so as to
+ produce a PTRACE_EVENT_SECCOMP will execute till the system call
+ completes, or indefinitely if resumed with PTRACE_CONT.
+
+ In this context processes are resumed with PTRACE_CONT unless it is
+ an `open' syscall that is being intercepted, which, if successfully
+ intercepted, they must receive adjustments to their stack pointer
+ upon completion of said system call. */
+ assert (!tracee->waiting_for_syscall);
+
+ /* Save the stack pointer. */
+ sp = regs.STACK_POINTER;
+
+ /* Now dispatch based on the system call. */
+ callno = regs.SYSCALL_NUM_REG;
+ switch (callno)
+ {
+ case EXEC_SYSCALL:
+ assert (!tracee->exec_data);
+ rc = handle_exec (tracee, &regs);
+
+ if (rc)
+ /* An error has occurred; errno is set to the error. */
+ goto report_syscall_error;
+
+ /* The process has been resumed. Assert that the instructions for
+ loading this executable have been generated and recorded, and
+ set waiting_for_syscall. */
+ tracee->waiting_for_syscall = true;
+ assert (tracee->exec_data);
+
+ /* Record the initial stack pointer also. */
+ tracee->sp = sp;
+ break;
+
+#ifdef READLINK_SYSCALL
+ case READLINK_SYSCALL:
+#endif /* READLINK_SYSCALL */
+ case READLINKAT_SYSCALL:
+ /* Handle this readlinkat system call. */
+ rc = handle_readlinkat (callno, &regs, tracee,
+ &result);
+
+ /* rc means the same as in `handle_exec'. */
+
+ if (rc == 1)
+ goto report_syscall_error;
+ else if (rc == 2)
+ goto emulate_syscall;
+
+ goto continue_syscall;
+
+#ifdef OPEN_SYSCALL
+ case OPEN_SYSCALL:
+#endif /* OPEN_SYSCALL */
+ case OPENAT_SYSCALL:
+ /* Handle this open system call. */
+ rc = handle_openat (callno, &regs, tracee, &result);
+
+ /* rc means the same as in `handle_exec', except that `open'
+ is never emulated. */
+
+ if (rc == 1)
+ goto report_syscall_error;
+
+ /* The stack pointer must be restored after it was modified
+ by `user_alloca'; record sp in TRACEE, which will be
+ restored after this system call completes. */
+ tracee->sp = sp;
+
+ /* As such, arrange to enter `process_system_call' on its
+ completion. */
+ rc = ptrace (PTRACE_SYSCALL, tracee->pid,
+ NULL, NULL);
+ if (rc < 0)
+ return;
+
+ tracee->waiting_for_syscall = !tracee->waiting_for_syscall;
+ break;
+
+ default:
+ continue_syscall:
+ rc = ptrace (PTRACE_CONT, tracee->pid, NULL, NULL);
+ if (rc < 0)
+ return;
+ }
+
+ return;
+
+ report_syscall_error:
+ reporting_error = true;
+ goto common;
+
+ emulate_syscall:
+ reporting_error = false;
+ common:
+
+ /* Reporting an error or emulating a system call works by replacing
+ the system call number with -1 or another nonexistent syscall,
+ letting it continue, and then substituting errno for ENOSYS in the
+ case of an error.
+
+ Make sure that the stack pointer is restored to its original
+ position upon exit, or bad things can happen. */
+
+ /* First, save errno; system calls below will clobber it. */
+ save_errno = errno;
+
+ regs.SYSCALL_NUM_REG = -1;
+ regs.STACK_POINTER = sp;
+
+#ifdef __aarch64__
+ if (aarch64_set_regs (tracee->pid, &regs, true))
+ return;
+#else /* !__aarch64__ */
+
+#ifdef __arm__
+ /* On ARM systems, a special request is used to update the system
+ call number as known to the kernel. In addition, the system call
+ number must be valid, so use `tuxcall'. Hopefully, nobody will
+ run this on a kernel with Tux. */
+
+ if (ptrace (PTRACE_SET_SYSCALL, tracee->pid, NULL, 222))
+ return;
+#endif /* __arm__ */
+
+ if (ptrace (PTRACE_SETREGS, tracee->pid, NULL, &regs))
+ return;
+#endif /* __aarch64__ */
+
+ /* Do this invalid system call. */
+ if (ptrace (PTRACE_SYSCALL, tracee->pid, NULL, NULL))
+ return;
+
+ again1:
+ rc = waitpid (tracee->pid, &wstatus, __WALL);
+ if (rc == -1 && errno == EINTR)
+ goto again1;
+
+ /* Return if waitpid fails. */
+
+ if (rc == -1)
+ return;
+
+ /* If the process received a signal, see if the signal is SIGSYS
+ and/or from seccomp. If so, discard it. */
+
+ if (WIFSTOPPED (wstatus))
+ {
+ rc = check_signal (tracee, wstatus);
+
+ if (rc == -1)
+ return;
+ else if (rc)
+ goto again1;
+ }
+
+ if (!WIFSTOPPED (wstatus))
+ /* The process has been killed in response to a signal. In this
+ case, simply unlink the tracee and return. */
+ remove_tracee (tracee);
+ else if (reporting_error)
+ {
+#ifdef __mips__
+ /* MIPS systems place errno in v0 and set a3 to 1. */
+ regs.gregs[2] = save_errno;
+ regs.gregs[7] = 1;
+#else /* !__mips__ */
+ regs.SYSCALL_RET_REG = -save_errno;
+#endif /* __mips__ */
+
+ /* Report errno. */
+#ifdef __aarch64__
+ aarch64_set_regs (tracee->pid, &regs, false);
+#else /* !__aarch64__ */
+ ptrace (PTRACE_SETREGS, tracee->pid, NULL, &regs);
+#endif /* __aarch64__ */
+
+ /* Resume the process till the next interception by its filter. */
+ ptrace (PTRACE_CONT, tracee->pid, NULL, NULL);
+ }
+ else
+ {
+ /* No error is being reported. Return the result in the
+ appropriate registers. */
+
+#ifdef __mips__
+ /* MIPS systems place errno in v0 and set a3 to 1. */
+ regs.gregs[2] = result;
+ regs.gregs[7] = 0;
+#else /* !__mips__ */
+ regs.SYSCALL_RET_REG = result;
+#endif /* __mips__ */
+
+ /* Report errno. */
+#ifdef __aarch64__
+ aarch64_set_regs (tracee->pid, &regs, false);
+#else /* !__aarch64__ */
+ ptrace (PTRACE_SETREGS, tracee->pid, NULL, &regs);
+#endif /* __aarch64__ */
+
+ /* Resume the process till the next interception by its filter. */
+ ptrace (PTRACE_CONT, tracee->pid, NULL, NULL);
+ }
+}
+
+#ifndef PTRACE_EVENT_SECCOMP
+#define PTRACE_EVENT_SECCOMP 7
+#endif /* !PTRACE_EVENT_SECCOMP */
+
+#ifndef PTRACE_O_TRACESECCOMP
+#define PTRACE_O_TRACESECCOMP (1 << PTRACE_EVENT_SECCOMP)
+#endif /* !PTRACE_O_TRACESECCOMP */
+
+#ifndef SIGSYS
+#define SIGSYS 31
+#endif /* !SIGSYS */
+#endif /* HAVE_SECCOMP */
+
+
+
/* Like `execve', but asks the parent to begin tracing this thread.
- Fail if tracing is unsuccessful. */
+ Fail by returning a non-zero value if tracing is unsuccessful. */
int
tracing_execve (const char *file, char *const *argv,
@@ -1471,6 +1841,13 @@ tracing_execve (const char *file, char *const *argv,
/* Notify the parent to enter signal-delivery-stop. */
raise (SIGSTOP);
+
+#ifdef HAVE_SECCOMP
+ /* Install the seccomp filter. */
+ if (use_seccomp_p && establish_seccomp_filter ())
+ return 1;
+#endif /* HAVE_SECCOMP */
+
return execve (file, argv, envp);
}
@@ -1486,6 +1863,10 @@ after_fork (pid_t pid)
{
int wstatus, rc, flags;
struct exec_tracee *tracee;
+#if defined HAVE_SECCOMP && __ANDROID__
+ int statusarg;
+ USER_REGS_STRUCT regs;
+#endif /* defined HAVE_SECCOMP && __ANDROID__ */
/* First, wait for something to happen to PID. */
again:
@@ -1510,6 +1891,10 @@ after_fork (pid_t pid)
flags |= PTRACE_O_TRACEFORK;
flags |= PTRACE_O_TRACESYSGOOD;
flags |= PTRACE_O_TRACEEXIT;
+#ifdef HAVE_SECCOMP
+ if (use_seccomp_p)
+ flags |= PTRACE_O_TRACESECCOMP;
+#endif /* HAVE_SECCOMP */
rc = ptrace (PTRACE_SETOPTIONS, pid, 0, flags);
@@ -1521,12 +1906,86 @@ after_fork (pid_t pid)
return 1;
}
- /* Request that the child stop upon the next system call. */
- rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
+#if defined HAVE_SECCOMP && __ANDROID__
+ /* Certain Android kernels have received backports of those new
+ PTRACE_EVENT_SECCOMP semantics which were introduced in kernel
+ version 4.8, so that it is necessary to actively establish which
+ variant is in place. */
+
+ if (kernel_4_7_or_earlier && use_seccomp_p)
+ {
+ /* Request that the child stop upon the next `exec' system call,
+ one of which is assumed to always be issued by the child, as
+ below, but await the next stop, and examine its contents.
+ Anciently, the syscall-stop preceeded events marked
+ PTRACE_EVENT_SECCOMP, whereas this sequence is reversed in
+ 4.8+, and in releases with these changes backported. */
+
+ rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ if (rc)
+ return 1;
+
+ while (true)
+ {
+ rc = waitpid (pid, &wstatus, __WALL);
+ if (rc != pid)
+ return 1;
+
+ if (WIFSTOPPED (wstatus))
+ {
+ /* Verify that this system call is `exec', not one issued
+ between PTRACE_TRACEME and `exec' intercepted by
+ PTRACE_SYSCALL. */
+#ifdef __aarch64__
+ rc = aarch64_get_regs (pid, &regs);
+#else /* !__aarch64__ */
+ rc = ptrace (PTRACE_GETREGS, pid, NULL, &regs);
+#endif /* __aarch64__ */
+ if (rc)
+ return 1;
+
+ if (regs.SYSCALL_NUM_REG == EXEC_SYSCALL)
+ {
+ statusarg = ((wstatus & 0xfff00) >> 8);
+
+ if (statusarg == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8)))
+ {
+ /* The first event to be delivered is a seccomp
+ stop, indicating that this is an unmodified
+ <4.7 kernel. Return to await the subsequent
+ syscall-stop, which should be received and
+ acted on by process_system_call. */
+ rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ break;
+ }
+ else if (statusarg == (SIGTRAP | 0x80))
+ {
+ /* Syscall-traps take priority. This is a
+ doctored 4.7 kernel. */
+ kernel_4_7_or_earlier = false;
+ rc = ptrace (PTRACE_CONT, pid, 0, 0);
+ break;
+ }
+ }
+
+ rc = ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ if (rc)
+ return 1;
+ }
+ else
+ return 1;
+ }
+ }
+ else
+#endif /* HAVE_SECCOMP && __ANDROID__ */
+ /* Request that the child stop upon the next system call, or the
+ next filter event. */
+ rc = ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, 0);
if (rc)
return 1;
- /* Enter the child in `tracing_processes'. */
+ /* Enroll the child into `tracing_processes'. */
if (free_tracees)
{
@@ -1543,9 +2002,9 @@ after_fork (pid_t pid)
tracee->next = tracing_processes;
tracee->waiting_for_syscall = false;
tracee->new_child = false;
-#ifndef REENTRANT
tracee->exec_file = NULL;
-#endif /* REENTRANT */
+ tracee->exec_data = NULL;
+ tracee->data_size = 0;
tracing_processes = tracee;
return 0;
}
@@ -1604,9 +2063,11 @@ exec_waitpid (pid_t pid, int *wstatus, int options)
{
if (siginfo.si_code < 0)
/* SIGTRAP delivered from userspace. Pass it on. */
- ptrace (PTRACE_SYSCALL, pid, 0, SIGTRAP);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, SIGTRAP);
else
- ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, 0);
return -1;
}
@@ -1644,8 +2105,16 @@ exec_waitpid (pid_t pid, int *wstatus, int options)
/* These events are handled by tracing SIGSTOP signals sent
to unknown tracees. Make sure not to pass through
status, as there's no signal really being delivered. */
- ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), pid, 0, 0);
+ return -1;
+
+#ifdef HAVE_SECCOMP
+ case SIGTRAP | (PTRACE_EVENT_SECCOMP << 8):
+ /* Intercept and process this system call if the event was
+ produced by our filter. */
+ seccomp_system_call (tracee);
return -1;
+#endif /* HAVE_SECCOMP */
#ifdef SIGSYS
case SIGSYS:
@@ -1657,24 +2126,28 @@ exec_waitpid (pid_t pid, int *wstatus, int options)
it. */
#ifdef HAVE_SIGINFO_T_SI_SYSCALL
#ifndef __arm__
- ptrace (PTRACE_SYSCALL, pid, 0, ((siginfo.si_code == SYS_SECCOMP
- && siginfo.si_syscall == -1)
- ? 0 : status));
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, ((siginfo.si_code == SYS_SECCOMP
+ && siginfo.si_syscall == -1)
+ ? 0 : status));
#else /* __arm__ */
- ptrace (PTRACE_SYSCALL, pid, 0, ((siginfo.si_code == SYS_SECCOMP
- && siginfo.si_syscall == 222)
- ? 0 : status));
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, ((siginfo.si_code == SYS_SECCOMP
+ && siginfo.si_syscall == 222)
+ ? 0 : status));
#endif /* !__arm__ */
#else /* !HAVE_SIGINFO_T_SI_SYSCALL */
/* Drop this signal, since what caused it is unknown. */
- ptrace (PTRACE_SYSCALL, pid, 0, 0);
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL), pid,
+ 0, 0);
#endif /* HAVE_SIGINFO_T_SI_SYSCALL */
return -1;
#endif /* SIGSYS */
default:
- /* Continue the process until the next syscall. */
- ptrace (PTRACE_SYSCALL, pid, 0, status);
+ /* Resume the process as appropriate. */
+ ptrace ((use_seccomp_p ? PTRACE_CONT : PTRACE_SYSCALL),
+ pid, 0, status);
return -1;
}
}
@@ -1698,5 +2171,36 @@ exec_waitpid (pid_t pid, int *wstatus, int options)
void
exec_init (const char *loader)
{
+#ifdef HAVE_SECCOMP
+ struct utsname u;
+ int major, minor;
+#endif /* HAVE_SECCOMP */
+
loader_name = loader;
+#ifdef HAVE_SECCOMP
+ errno = 0;
+ prctl (PR_GET_SECCOMP);
+
+ /* PR_GET_SECCOMP should not set errno if the kernel was configured
+ with support for seccomp. */
+ if (!errno)
+ use_seccomp_p = true;
+ else
+ return;
+
+ /* Establish whether the kernel is 4.7.x or older. */
+ uname (&u);
+ if ((sscanf (u.release, "%d.%d", &major, &minor) == 2))
+ {
+ /* Certain required ptrace features were introduced in kernel
+ 3.5. */
+ if (major < 3 || (major == 3 && minor < 5))
+ use_seccomp_p = false;
+ else
+ {
+ if (major < 4 || (major == 4 && minor <= 7))
+ kernel_4_7_or_earlier = true;
+ }
+ }
+#endif /* HAVE_SECCOMP */
}
diff --git a/java/Makefile.in b/java/Makefile.in
index 465f99162ec..3d5165d3186 100644
--- a/java/Makefile.in
+++ b/java/Makefile.in
@@ -57,7 +57,6 @@ else
GZIP_PROG =
endif
-
# Android 4.3 and earlier require Emacs to be signed with a different
# digital signature algorithm.
@@ -77,6 +76,11 @@ else
AAPT_ASSET_ARGS =
endif
+# This will be replaced by `--no-build-details' if details of the build
+# system are not to be recorded in generated packages.
+BUILD_DETAILS = @BUILD_DETAILS@
+GEN_BUILD_DETAILS := $(if $(BUILD_DETAILS),true ||,)
+
SIGN_EMACS = -keystore $(srcdir)/emacs.keystore -storepass \
emacs1 $(JARSIGNER_FLAGS)
SIGN_EMACS_V2 = sign --v2-signing-enabled --ks \
@@ -249,13 +253,13 @@ install_temp: $(CROSS_BINS) $(CROSS_LIBS) $(RESOURCE_FILES) \
| xargs ${GZIP_PROG} -9n ; \
}
# Produce metadata files providing build information and suchlike.
- $(AM_V_SILENT) \
+ -$(AM_V_SILENT) $(GEN_BUILD_DETAILS) \
{ (cd $(top_srcdir) \
&& git rev-parse HEAD || echo "Unknown") \
&& (git rev-parse --abbrev-ref HEAD \
|| echo "Unknown") } 2> /dev/null > \
install_temp/assets/version
- $(AM_V_SILENT) \
+ -$(AM_V_SILENT) $(GEN_BUILD_DETAILS) \
{ hostname; date +%s; } > install_temp/assets/build_info
# Produce the file index.
$(AM_V_SILENT) $(libsrc)/asset-directory-tool \
diff --git a/lib/acl-internal.c b/lib/acl-internal.c
index 9ebb6e544b0..ae5398306af 100644
--- a/lib/acl-internal.c
+++ b/lib/acl-internal.c
@@ -89,6 +89,14 @@ acl_access_nontrivial (acl_t acl)
group:Administrators:rwx
mask::r-x
other::r-x
+ or
+ user::rwx
+ group::r-x
+ group:SYSTEM:rwx
+ group:Administrators:rwx
+ group:Users:rwx
+ mask::rwx
+ other::r-x
*/
case ACL_GROUP:
{
@@ -105,9 +113,12 @@ acl_access_nontrivial (acl_t acl)
/* Ignore the ace if the group_sid is one of
- S-1-5-18 (group "SYSTEM")
- S-1-5-32-544 (group "Administrators")
- Cf. <https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids> */
+ - S-1-5-32-545 (group "Users")
+ Cf. <https://learn.microsoft.com/en-us/windows/win32/secauthz/well-known-sids>
+ and look at the output of the 'mkgroup' command. */
ignorable = (strcmp (group_sid, "S-1-5-18") == 0
- || strcmp (group_sid, "S-1-5-32-544") == 0);
+ || strcmp (group_sid, "S-1-5-32-544") == 0
+ || strcmp (group_sid, "S-1-5-32-545") == 0);
}
}
if (!ignorable)
diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in
index 832b245edc2..948269e744d 100644
--- a/lib/gnulib.mk.in
+++ b/lib/gnulib.mk.in
@@ -545,6 +545,7 @@ GL_GNULIB_NANOSLEEP = @GL_GNULIB_NANOSLEEP@
GL_GNULIB_NONBLOCKING = @GL_GNULIB_NONBLOCKING@
GL_GNULIB_OBSTACK_PRINTF = @GL_GNULIB_OBSTACK_PRINTF@
GL_GNULIB_OBSTACK_PRINTF_POSIX = @GL_GNULIB_OBSTACK_PRINTF_POSIX@
+GL_GNULIB_OBSTACK_ZPRINTF = @GL_GNULIB_OBSTACK_ZPRINTF@
GL_GNULIB_OPEN = @GL_GNULIB_OPEN@
GL_GNULIB_OPENAT = @GL_GNULIB_OPENAT@
GL_GNULIB_OPENDIR = @GL_GNULIB_OPENDIR@
@@ -645,6 +646,7 @@ GL_GNULIB_TIME_RZ = @GL_GNULIB_TIME_RZ@
GL_GNULIB_TMPFILE = @GL_GNULIB_TMPFILE@
GL_GNULIB_TRUNCATE = @GL_GNULIB_TRUNCATE@
GL_GNULIB_TTYNAME_R = @GL_GNULIB_TTYNAME_R@
+GL_GNULIB_TZNAME = @GL_GNULIB_TZNAME@
GL_GNULIB_TZSET = @GL_GNULIB_TZSET@
GL_GNULIB_UNISTD_H_GETOPT = @GL_GNULIB_UNISTD_H_GETOPT@
GL_GNULIB_UNISTD_H_NONBLOCKING = @GL_GNULIB_UNISTD_H_NONBLOCKING@
@@ -656,6 +658,7 @@ GL_GNULIB_UNSETENV = @GL_GNULIB_UNSETENV@
GL_GNULIB_USLEEP = @GL_GNULIB_USLEEP@
GL_GNULIB_UTIMENSAT = @GL_GNULIB_UTIMENSAT@
GL_GNULIB_VASPRINTF = @GL_GNULIB_VASPRINTF@
+GL_GNULIB_VAZSPRINTF = @GL_GNULIB_VAZSPRINTF@
GL_GNULIB_VDPRINTF = @GL_GNULIB_VDPRINTF@
GL_GNULIB_VFPRINTF = @GL_GNULIB_VFPRINTF@
GL_GNULIB_VFPRINTF_POSIX = @GL_GNULIB_VFPRINTF_POSIX@
@@ -665,8 +668,12 @@ GL_GNULIB_VPRINTF_POSIX = @GL_GNULIB_VPRINTF_POSIX@
GL_GNULIB_VSCANF = @GL_GNULIB_VSCANF@
GL_GNULIB_VSNPRINTF = @GL_GNULIB_VSNPRINTF@
GL_GNULIB_VSPRINTF_POSIX = @GL_GNULIB_VSPRINTF_POSIX@
+GL_GNULIB_VZSNPRINTF = @GL_GNULIB_VZSNPRINTF@
+GL_GNULIB_VZSPRINTF = @GL_GNULIB_VZSPRINTF@
GL_GNULIB_WCTOMB = @GL_GNULIB_WCTOMB@
GL_GNULIB_WRITE = @GL_GNULIB_WRITE@
+GL_GNULIB_ZSNPRINTF = @GL_GNULIB_ZSNPRINTF@
+GL_GNULIB_ZSPRINTF = @GL_GNULIB_ZSPRINTF@
GL_GNULIB__EXIT = @GL_GNULIB__EXIT@
GL_STDC_BIT_CEIL = @GL_STDC_BIT_CEIL@
GL_STDC_BIT_FLOOR = @GL_STDC_BIT_FLOOR@
@@ -928,7 +935,6 @@ HAVE_UTIMENSAT = @HAVE_UTIMENSAT@
HAVE_VASPRINTF = @HAVE_VASPRINTF@
HAVE_VDPRINTF = @HAVE_VDPRINTF@
HAVE_WCHAR_H = @HAVE_WCHAR_H@
-HAVE_WCHAR_T = @HAVE_WCHAR_T@
HAVE_WINSOCK2_H = @HAVE_WINSOCK2_H@
HAVE_XSERVER = @HAVE_XSERVER@
HAVE__EXIT = @HAVE__EXIT@
@@ -1412,6 +1418,7 @@ XSYNC_CFLAGS = @XSYNC_CFLAGS@
XSYNC_LIBS = @XSYNC_LIBS@
XWIDGETS_OBJ = @XWIDGETS_OBJ@
X_TOOLKIT_TYPE = @X_TOOLKIT_TYPE@
+ZIP = @ZIP@
ZIPALIGN = @ZIPALIGN@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
@@ -3200,7 +3207,6 @@ stddef.h: stddef.in.h $(top_builddir)/config.status
-e 's|@''STDDEF_NOT_IDEMPOTENT''@|$(STDDEF_NOT_IDEMPOTENT)|g' \
-e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
-e 's|@''HAVE_MAX_ALIGN_T''@|$(HAVE_MAX_ALIGN_T)|g' \
- -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
$(srcdir)/stddef.in.h > $@-t
$(AM_V_at)mv $@-t $@
else
@@ -3305,6 +3311,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_GETLINE''@/$(GL_GNULIB_GETLINE)/g' \
-e 's/@''GNULIB_OBSTACK_PRINTF''@/$(GL_GNULIB_OBSTACK_PRINTF)/g' \
-e 's/@''GNULIB_OBSTACK_PRINTF_POSIX''@/$(GL_GNULIB_OBSTACK_PRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_OBSTACK_ZPRINTF''@/$(GL_GNULIB_OBSTACK_ZPRINTF)/g' \
-e 's/@''GNULIB_PCLOSE''@/$(GL_GNULIB_PCLOSE)/g' \
-e 's/@''GNULIB_PERROR''@/$(GL_GNULIB_PERROR)/g' \
-e 's/@''GNULIB_POPEN''@/$(GL_GNULIB_POPEN)/g' \
@@ -3323,6 +3330,7 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_STDIO_H_SIGPIPE''@/$(GL_GNULIB_STDIO_H_SIGPIPE)/g' \
-e 's/@''GNULIB_TMPFILE''@/$(GL_GNULIB_TMPFILE)/g' \
-e 's/@''GNULIB_VASPRINTF''@/$(GL_GNULIB_VASPRINTF)/g' \
+ -e 's/@''GNULIB_VAZSPRINTF''@/$(GL_GNULIB_VAZSPRINTF)/g' \
-e 's/@''GNULIB_VDPRINTF''@/$(GL_GNULIB_VDPRINTF)/g' \
-e 's/@''GNULIB_VFPRINTF''@/$(GL_GNULIB_VFPRINTF)/g' \
-e 's/@''GNULIB_VFPRINTF_POSIX''@/$(GL_GNULIB_VFPRINTF_POSIX)/g' \
@@ -3332,6 +3340,10 @@ stdio.h: stdio.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's/@''GNULIB_VPRINTF_POSIX''@/$(GL_GNULIB_VPRINTF_POSIX)/g' \
-e 's/@''GNULIB_VSNPRINTF''@/$(GL_GNULIB_VSNPRINTF)/g' \
-e 's/@''GNULIB_VSPRINTF_POSIX''@/$(GL_GNULIB_VSPRINTF_POSIX)/g' \
+ -e 's/@''GNULIB_VZSNPRINTF''@/$(GL_GNULIB_VZSNPRINTF)/g' \
+ -e 's/@''GNULIB_VZSPRINTF''@/$(GL_GNULIB_VZSPRINTF)/g' \
+ -e 's/@''GNULIB_ZSNPRINTF''@/$(GL_GNULIB_ZSNPRINTF)/g' \
+ -e 's/@''GNULIB_ZSPRINTF''@/$(GL_GNULIB_ZSPRINTF)/g' \
-e 's/@''GNULIB_MDA_FCLOSEALL''@/$(GL_GNULIB_MDA_FCLOSEALL)/g' \
-e 's/@''GNULIB_MDA_FDOPEN''@/$(GL_GNULIB_MDA_FDOPEN)/g' \
-e 's/@''GNULIB_MDA_FILENO''@/$(GL_GNULIB_MDA_FILENO)/g' \
@@ -4005,6 +4017,7 @@ time.h: time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(
-e 's/@''GNULIB_TIMESPEC_GETRES''@/$(GL_GNULIB_TIMESPEC_GETRES)/g' \
-e 's/@''GNULIB_TIME_R''@/$(GL_GNULIB_TIME_R)/g' \
-e 's/@''GNULIB_TIME_RZ''@/$(GL_GNULIB_TIME_RZ)/g' \
+ -e 's/@''GNULIB_TZNAME''@/$(GL_GNULIB_TZNAME)/g' \
-e 's/@''GNULIB_TZSET''@/$(GL_GNULIB_TZSET)/g' \
-e 's/@''GNULIB_MDA_TZSET''@/$(GL_GNULIB_MDA_TZSET)/g' \
-e 's|@''HAVE_DECL_LOCALTIME_R''@|$(HAVE_DECL_LOCALTIME_R)|g' \
diff --git a/lib/stddef.in.h b/lib/stddef.in.h
index 63bb500e262..0abc4497043 100644
--- a/lib/stddef.in.h
+++ b/lib/stddef.in.h
@@ -149,11 +149,6 @@ typedef long max_align_t;
# endif
#endif
-/* Some platforms lack wchar_t. */
-#if !@HAVE_WCHAR_T@
-# define wchar_t int
-#endif
-
/* Some platforms lack max_align_t. The check for _GCC_MAX_ALIGN_T is
a hack in case the configure-time test was done with g++ even though
we are currently compiling with gcc.
diff --git a/lib/stdio.in.h b/lib/stdio.in.h
index 1c0c9661bfe..cf2d8c999bc 100644
--- a/lib/stdio.in.h
+++ b/lib/stdio.in.h
@@ -1075,13 +1075,39 @@ _GL_CXXALIASWARN (getw);
# endif
#endif
+#if @GNULIB_OBSTACK_ZPRINTF@
+struct obstack;
+/* Grows an obstack with formatted output. Returns the number of
+ bytes added to OBS. No trailing nul byte is added, and the
+ object should be closed with obstack_finish before use.
+ Upon memory allocation error, calls obstack_alloc_failed_handler.
+ Upon other error, returns -1 with errno set.
+
+ Failure code EOVERFLOW can only occur when a width > INT_MAX is used.
+ Therefore, if the format string is valid and does not use %ls/%lc
+ directives nor widths, the only possible failure code is through
+ obstack_alloc_failed_handler. */
+_GL_FUNCDECL_SYS (obstack_zprintf, ptrdiff_t,
+ (struct obstack *obs, const char *format, ...)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (obstack_zprintf, ptrdiff_t,
+ (struct obstack *obs, const char *format, ...));
+_GL_FUNCDECL_SYS (obstack_vzprintf, ptrdiff_t,
+ (struct obstack *obs, const char *format, va_list args)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (obstack_vzprintf, ptrdiff_t,
+ (struct obstack *obs, const char *format, va_list args));
+#endif
+
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
struct obstack;
-/* Grow an obstack with formatted output. Return the number of
+/* Grows an obstack with formatted output. Returns the number of
bytes added to OBS. No trailing nul byte is added, and the
- object should be closed with obstack_finish before use. Upon
- memory allocation error, call obstack_alloc_failed_handler. Upon
- other error, return -1. */
+ object should be closed with obstack_finish before use.
+ Upon memory allocation error, calls obstack_alloc_failed_handler.
+ Upon other error, returns -1. */
# if @REPLACE_OBSTACK_PRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define obstack_printf rpl_obstack_printf
@@ -1433,7 +1459,31 @@ _GL_CXXALIASWARN (scanf);
# endif
#endif
+#if @GNULIB_ZSNPRINTF@
+/* Prints formatted output to string STR. Similar to sprintf, but the
+ additional parameter SIZE limits how much is written into STR.
+ STR may be NULL, in which case nothing will be written.
+ Returns the string length of the formatted string (which may be larger
+ than SIZE). Upon failure, returns -1 with errno set.
+ Failure code EOVERFLOW can only occur when a width > INT_MAX is used.
+ Therefore, if the format string is valid and does not use %ls/%lc
+ directives nor widths, the only possible failure code is ENOMEM. */
+_GL_FUNCDECL_SYS (zsnprintf, ptrdiff_t,
+ (char *restrict str, size_t size,
+ const char *restrict format, ...)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 4)
+ _GL_ARG_NONNULL ((3)));
+_GL_CXXALIAS_SYS (zsnprintf, ptrdiff_t,
+ (char *restrict str, size_t size,
+ const char *restrict format, ...));
+#endif
+
#if @GNULIB_SNPRINTF@
+/* Prints formatted output to string STR. Similar to sprintf, but the
+ additional parameter SIZE limits how much is written into STR.
+ STR may be NULL, in which case nothing will be written.
+ Returns the string length of the formatted string (which may be larger
+ than SIZE). Upon failure, returns a negative value. */
# if @REPLACE_SNPRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define snprintf rpl_snprintf
@@ -1470,6 +1520,23 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - "
# endif
#endif
+#if @GNULIB_ZSPRINTF@
+/* Prints formatted output to string STR.
+ Returns the string length of the formatted string. Upon failure,
+ returns -1 with errno set.
+ Failure code EOVERFLOW can only occur when a width > INT_MAX is used.
+ Therefore, if the format string is valid and does not use %ls/%lc
+ directives nor widths, the only possible failure code is ENOMEM. */
+_GL_FUNCDECL_SYS (zsprintf, ptrdiff_t,
+ (char *restrict str,
+ const char *restrict format, ...)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (zsprintf, ptrdiff_t,
+ (char *restrict str,
+ const char *restrict format, ...));
+#endif
+
/* Some people would argue that all sprintf uses should be warned about
(for example, OpenBSD issues a link warning for it),
since it can cause security holes due to buffer overruns.
@@ -1480,6 +1547,9 @@ _GL_WARN_ON_USE (snprintf, "snprintf is unportable - "
GNULIB_POSIXCHECK is defined. */
#if @GNULIB_SPRINTF_POSIX@
+/* Prints formatted output to string STR.
+ Returns the string length of the formatted string. Upon failure,
+ returns a negative value. */
# if @REPLACE_SPRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define sprintf rpl_sprintf
@@ -1559,6 +1629,29 @@ _GL_WARN_ON_USE (tmpfile, "tmpfile is not usable on mingw - "
# endif
#endif
+#if @GNULIB_VAZSPRINTF@
+/* Prints formatted output to a string dynamically allocated with malloc().
+ If the memory allocation succeeds, it stores the address of the string in
+ *RESULT and returns the number of resulting bytes, excluding the trailing
+ NUL. Upon memory allocation error, or some other error, it returns -1
+ with errno set.
+ Failure code EOVERFLOW can only occur when a width > INT_MAX is used.
+ Therefore, if the format string is valid and does not use %ls/%lc
+ directives nor widths, the only possible failure code is ENOMEM. */
+_GL_FUNCDECL_SYS (azsprintf, ptrdiff_t,
+ (char **result, const char *format, ...)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 3)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (azsprintf, ptrdiff_t,
+ (char **result, const char *format, ...));
+_GL_FUNCDECL_SYS (vazsprintf, ptrdiff_t,
+ (char **result, const char *format, va_list args)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (vazsprintf, ptrdiff_t,
+ (char **result, const char *format, va_list args));
+#endif
+
#if @GNULIB_VASPRINTF@
/* Write formatted output to a string dynamically allocated with malloc().
If the memory allocation succeeds, store the address of the string in
@@ -1769,7 +1862,31 @@ _GL_CXXALIASWARN (vscanf);
# endif
#endif
+#if @GNULIB_VZSNPRINTF@
+/* Prints formatted output to string STR. Similar to sprintf, but the
+ additional parameter SIZE limits how much is written into STR.
+ STR may be NULL, in which case nothing will be written.
+ Returns the string length of the formatted string (which may be larger
+ than SIZE). Upon failure, returns -1 with errno set.
+ Failure code EOVERFLOW can only occur when a width > INT_MAX is used.
+ Therefore, if the format string is valid and does not use %ls/%lc
+ directives nor widths, the only possible failure code is ENOMEM. */
+_GL_FUNCDECL_SYS (vzsnprintf, ptrdiff_t,
+ (char *restrict str, size_t size,
+ const char *restrict format, va_list args)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (3, 0)
+ _GL_ARG_NONNULL ((3)));
+_GL_CXXALIAS_SYS (vzsnprintf, ptrdiff_t,
+ (char *restrict str, size_t size,
+ const char *restrict format, va_list args));
+#endif
+
#if @GNULIB_VSNPRINTF@
+/* Prints formatted output to string STR. Similar to vsprintf, but the
+ additional parameter SIZE limits how much is written into STR.
+ STR may be NULL, in which case nothing will be written.
+ Returns the string length of the formatted string (which may be larger
+ than SIZE). Upon failure, returns a negative value. */
# if @REPLACE_VSNPRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define vsnprintf rpl_vsnprintf
@@ -1806,7 +1923,27 @@ _GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - "
# endif
#endif
+#if @GNULIB_VZSPRINTF@
+/* Prints formatted output to string STR.
+ Returns the string length of the formatted string. Upon failure,
+ returns -1 with errno set.
+ Failure code EOVERFLOW can only occur when a width > INT_MAX is used.
+ Therefore, if the format string is valid and does not use %ls/%lc
+ directives nor widths, the only possible failure code is ENOMEM. */
+_GL_FUNCDECL_SYS (vzsprintf, ptrdiff_t,
+ (char *restrict str,
+ const char *restrict format, va_list args)
+ _GL_ATTRIBUTE_FORMAT_PRINTF_STANDARD (2, 0)
+ _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_SYS (vzsprintf, ptrdiff_t,
+ (char *restrict str,
+ const char *restrict format, va_list args));
+#endif
+
#if @GNULIB_VSPRINTF_POSIX@
+/* Prints formatted output to string STR.
+ Returns the string length of the formatted string. Upon failure,
+ returns a negative value. */
# if @REPLACE_VSPRINTF@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# define vsprintf rpl_vsprintf
diff --git a/lib/strftime.c b/lib/strftime.c
index 5f1e76833f7..9b1b27a1fc8 100644
--- a/lib/strftime.c
+++ b/lib/strftime.c
@@ -25,9 +25,8 @@
#ifdef _LIBC
# define USE_IN_EXTENDED_LOCALE_MODEL 1
# define HAVE_STRUCT_ERA_ENTRY 1
-# define HAVE_TM_GMTOFF 1
+# define HAVE_STRUCT_TM_TM_GMTOFF 1
# define HAVE_STRUCT_TM_TM_ZONE 1
-# define HAVE_TZNAME 1
# include "../locale/localeinfo.h"
#else
# include <libc-config.h>
@@ -60,10 +59,6 @@
#include <errno.h>
#include <time.h>
-#if HAVE_TZNAME && !HAVE_DECL_TZNAME
-extern char *tzname[];
-#endif
-
/* Do multibyte processing if multibyte encodings are supported, unless
multibyte sequences are safe in formats. Multibyte sequences are
safe if they cannot contain byte sequences that look like format
@@ -87,18 +82,16 @@ extern char *tzname[];
#endif
#include <limits.h>
+#include <locale.h>
#include <stdckdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
-#if USE_C_LOCALE && HAVE_STRFTIME_L
-# include <locale.h>
-#endif
-
#if (defined __NetBSD__ || defined __sun) && REQUIRE_GNUISH_STRFTIME_AM_PM
-# include <locale.h>
# include "localename.h"
+#elif defined _WIN32 && !defined __CYGWIN__
+# include <wchar.h>
#endif
#include "attribute.h"
@@ -377,6 +370,15 @@ memcpy_uppcase (CHAR_T *dest, const CHAR_T *src, size_t len LOCALE_PARAM)
#endif
+/* Note: We assume that HAVE_STRFTIME_LZ implies HAVE_STRFTIME_L.
+ Otherwise, we would have to write (HAVE_STRFTIME_L || HAVE_STRFTIME_LZ)
+ instead of HAVE_STRFTIME_L everywhere. */
+
+/* Define to 1 if we can use the system's native functions that takes a
+ timezone_t argument. As of 2024, this is only true on NetBSD. */
+#define HAVE_NATIVE_TIME_Z \
+ (USE_C_LOCALE && HAVE_STRFTIME_L ? HAVE_STRFTIME_LZ : HAVE_STRFTIME_Z)
+
#if USE_C_LOCALE && HAVE_STRFTIME_L
/* Cache for the C locale object.
@@ -396,6 +398,27 @@ c_locale (void)
#endif
+#if HAVE_NATIVE_TIME_Z
+
+/* On NetBSD a null tz has undefined behavior, so use a non-null tz.
+ Cache the UTC time zone object in a volatile variable for improved
+ thread safety. This is good enough in practice, although in theory
+ stdatomic.h should be used. */
+static volatile timezone_t utc_timezone_cache;
+
+/* Return the UTC time zone object, or (timezone_t) 0 with errno set
+ if it cannot be created. */
+static timezone_t
+utc_timezone (void)
+{
+ timezone_t tz = utc_timezone_cache;
+ if (!tz)
+ utc_timezone_cache = tz = tzalloc ("UTC0");
+ return tz;
+}
+
+#endif
+
#if (defined __NetBSD__ || defined __sun) && REQUIRE_GNUISH_STRFTIME_AM_PM
@@ -747,7 +770,7 @@ should_remove_ampm (void)
#endif
-#if ! HAVE_TM_GMTOFF
+#if ! HAVE_STRUCT_TM_TM_GMTOFF
/* Yield the difference between *A and *B,
measured in seconds, ignoring leap seconds. */
# define tm_diff ftime_tm_diff
@@ -772,7 +795,7 @@ tm_diff (const struct tm *a, const struct tm *b)
+ (a->tm_min - b->tm_min))
+ (a->tm_sec - b->tm_sec));
}
-#endif /* ! HAVE_TM_GMTOFF */
+#endif
@@ -810,9 +833,9 @@ static CHAR_T const c_month_names[][sizeof "September"] =
#endif
-/* When compiling this file, GNU applications can #define my_strftime
- to a symbol (typically nstrftime) to get an extended strftime with
- extra arguments TZ and NS. */
+/* When compiling this file, Gnulib-using applications should #define
+ my_strftime to a symbol (typically nstrftime) to name their
+ extended strftime with extra arguments TZ and NS. */
#ifdef my_strftime
# define extra_args , tz, ns
@@ -837,6 +860,200 @@ static size_t __strftime_internal (STREAM_OR_CHAR_T *, STRFTIME_ARG (size_t)
bool, enum pad_style, int, bool *
extra_args_spec LOCALE_PARAM);
+#if !defined _LIBC \
+ && (!(USE_C_LOCALE && !HAVE_STRFTIME_L) || !HAVE_STRUCT_TM_TM_ZONE)
+
+/* Make sure we're calling the actual underlying strftime.
+ In some cases, time.h contains something like
+ "#define strftime rpl_strftime". */
+# ifdef strftime
+# undef strftime
+# endif
+
+/* Assuming the time zone is TZ, store into UBUF, of size UBUFSIZE, a
+ ' ' followed by the result of calling strftime with the format
+ "%MF" where M is MODIFIER (or is omitted if !MODIFIER) and F is
+ FORMAT_CHAR, along with the time information specified by *TP.
+ Return the number of bytes stored if successful, zero otherwise. */
+static size_t
+underlying_strftime (timezone_t tz, char *ubuf, size_t ubufsize,
+ char modifier, char format_char, struct tm const *tp)
+{
+ /* The relevant information is available only via the
+ underlying strftime implementation, so use that. */
+ char ufmt[5];
+ char *u = ufmt;
+
+ /* The space helps distinguish strftime failure from empty
+ output. */
+ *u++ = ' ';
+ *u++ = '%';
+ *u = modifier;
+ u += !!modifier;
+ *u++ = format_char;
+ *u = '\0';
+
+# if HAVE_NATIVE_TIME_Z
+ if (!tz)
+ {
+ tz = utc_timezone ();
+ if (!tz)
+ return 0; /* errno is set here */
+ }
+# endif
+
+# if !HAVE_NATIVE_TIME_Z
+ if (tz && tz != local_tz)
+ {
+ tz = set_tz (tz);
+ if (!tz)
+ return 0;
+ }
+# endif
+
+ size_t len;
+# if USE_C_LOCALE && HAVE_STRFTIME_L
+ locale_t locale = c_locale ();
+ if (!locale)
+ return 0; /* errno is set here */
+# if HAVE_STRFTIME_LZ
+ len = strftime_lz (tz, ubuf, ubufsize, ufmt, tp, locale);
+# else
+ len = strftime_l (ubuf, ubufsize, ufmt, tp, locale);
+# endif
+# else
+# if HAVE_STRFTIME_Z
+ len = strftime_z (tz, ubuf, ubufsize, ufmt, tp);
+# else
+ len = strftime (ubuf, ubufsize, ufmt, tp);
+# endif
+# endif
+
+# if !HAVE_NATIVE_TIME_Z
+ if (tz && !revert_tz (tz))
+ return 0;
+# endif
+
+ if (len != 0)
+ {
+# if ((__GLIBC__ == 2 && __GLIBC_MINOR__ < 31) \
+ || defined __NetBSD__ || defined __sun)
+ /* glibc < 2.31, NetBSD, Solaris */
+ if (format_char == 'c')
+ {
+ /* The output of the strftime %c directive consists of the
+ date, the time, and the time zone. But the time zone is
+ wrong, since neither TZ nor ZONE was passed as argument.
+ Therefore, remove the the last space-delimited word.
+ In order not to accidentally remove a date or a year
+ (that contains no letter) or an AM/PM indicator (that has
+ length 2), remove that last word only if it contains a
+ letter and has length >= 3. */
+ char *space;
+ for (space = ubuf + len - 1; *space != ' '; space--)
+ continue;
+ if (space > ubuf)
+ {
+ /* Found a space. */
+ if (strlen (space + 1) >= 3)
+ {
+ /* The last word has length >= 3. */
+ bool found_letter = false;
+ const char *p;
+ for (p = space + 1; *p != '\0'; p++)
+ if ((*p >= 'A' && *p <= 'Z')
+ || (*p >= 'a' && *p <= 'z'))
+ {
+ found_letter = true;
+ break;
+ }
+ if (found_letter)
+ {
+ /* The last word contains a letter. */
+ *space = '\0';
+ len = space - ubuf;
+ }
+ }
+ }
+ }
+# if (defined __NetBSD__ || defined __sun) && REQUIRE_GNUISH_STRFTIME_AM_PM
+ /* The output of the strftime %p and %r directives contains
+ an AM/PM indicator even for locales where it is not
+ suitable, such as French. Remove this indicator. */
+ if (format_char == 'p')
+ {
+ bool found_ampm = (len > 1);
+ if (found_ampm && should_remove_ampm ())
+ {
+ ubuf[1] = '\0';
+ len = 1;
+ }
+ }
+ else if (format_char == 'r')
+ {
+ char last_char = ubuf[len - 1];
+ bool found_ampm = !(last_char >= '0' && last_char <= '9');
+ if (found_ampm && should_remove_ampm ())
+ {
+ char *space;
+ for (space = ubuf + len - 1; *space != ' '; space--)
+ continue;
+ if (space > ubuf)
+ {
+ *space = '\0';
+ len = space - ubuf;
+ }
+ }
+ }
+# endif
+# endif
+ }
+ return len;
+}
+#endif
+
+/* Return a time zone abbreviation for TZ. Use BUF, of size BUFSIZE,
+ to store it if needed. If MODIFIER use the strftime format
+ "%mZ" to format it, where m is the MODIFIER; otherwise
+ use plain "%Z". Format an abbreviation appropriate for
+ TP and EXTRA_ARGS_SPEC. Return the empty string on failure. */
+static char const *
+get_tm_zone (timezone_t tz, char *ubuf, int ubufsize, int modifier,
+ struct tm const *tp)
+{
+#if HAVE_STRUCT_TM_TM_ZONE
+ /* The POSIX test suite assumes that setting
+ the environment variable TZ to a new value before calling strftime()
+ will influence the result (the %Z format) even if the information in
+ *TP is computed with a totally different time zone.
+ This is bogus: though POSIX allows bad behavior like this,
+ POSIX does not require it. Do the right thing instead. */
+ return tp->tm_zone;
+#else
+ if (!tz)
+ return "UTC";
+
+# if !HAVE_NATIVE_TIME_Z
+ timezone_t old_tz = tz;
+ if (tz != local_tz)
+ {
+ old_tz = set_tz (tz);
+ if (!old_tz)
+ return "";
+ }
+# endif
+
+ int zsize = underlying_strftime (tz, ubuf, ubufsize, 0, 'Z', tp);
+
+# if !HAVE_NATIVE_TIME_Z
+ if (!revert_tz (old_tz))
+ return "";
+# endif
+
+ return zsize ? ubuf + 1 : "";
+#endif
+}
+
/* Write information from TP into S according to the format
string FORMAT, writing no more that MAXSIZE characters
(including the terminating '\0') and returning number of
@@ -927,10 +1144,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11))
# define ap_len 2
#endif
-#if HAVE_TZNAME
- char **tzname_vec = tzname;
-#endif
- const char *zone;
size_t i = 0;
STREAM_OR_CHAR_T *p = s;
const CHAR_T *f;
@@ -938,47 +1151,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
const char *format_end = NULL;
#endif
- zone = NULL;
-#if HAVE_STRUCT_TM_TM_ZONE
- /* The POSIX test suite assumes that setting
- the environment variable TZ to a new value before calling strftime()
- will influence the result (the %Z format) even if the information in
- TP is computed with a totally different time zone.
- This is bogus: though POSIX allows bad behavior like this,
- POSIX does not require it. Do the right thing instead. */
- zone = (const char *) tp->tm_zone;
-#endif
-#if HAVE_TZNAME
- if (!tz)
- {
- if (! (zone && *zone))
- zone = "GMT";
- }
- else
- {
-# if !HAVE_STRUCT_TM_TM_ZONE
- /* Infer the zone name from *TZ instead of from TZNAME. */
- tzname_vec = tz->tzname_copy;
-# endif
- }
- /* The tzset() call might have changed the value. */
- if (!(zone && *zone) && tp->tm_isdst >= 0)
- {
- /* POSIX.1 requires that local time zone information be used as
- though strftime called tzset. */
-# ifndef my_strftime
- if (!*tzset_called)
- {
- tzset ();
- *tzset_called = true;
- }
-# endif
- zone = tzname_vec[tp->tm_isdst != 0];
- }
-#endif
- if (! zone)
- zone = "";
-
if (hour12 > 12)
hour12 -= 12;
else
@@ -1293,7 +1465,21 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
subfmt = L_("%a %b %e %H:%M:%S %Y");
#elif defined _WIN32 && !defined __CYGWIN__
/* On native Windows, "%c" is "%d/%m/%Y %H:%M:%S" by default. */
- subfmt = L_("%a %b %e %H:%M:%S %Y");
+ bool is_c_locale;
+ /* This code is equivalent to is_c_locale = !hard_locale (LC_TIME). */
+# if defined _MSC_VER
+ const wchar_t *locale = _wsetlocale (LC_TIME, NULL);
+ is_c_locale =
+ (wcscmp (locale, L"C") == 0 || wcscmp (locale, L"POSIX") == 0);
+# else
+ const char *locale = setlocale (LC_TIME, NULL);
+ is_c_locale =
+ (strcmp (locale, "C") == 0 || strcmp (locale, "POSIX") == 0);
+# endif
+ if (is_c_locale)
+ subfmt = L_("%a %b %e %H:%M:%S %Y");
+ else
+ subfmt = L_("%a %e %b %Y %H:%M:%S");
#else
goto underlying_strftime;
#endif
@@ -1314,40 +1500,13 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
}
break;
-#if !((defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY) || (USE_C_LOCALE && !HAVE_STRFTIME_L))
+#if !defined _LIBC && !(USE_C_LOCALE && !HAVE_STRFTIME_L)
underlying_strftime:
{
- /* The relevant information is available only via the
- underlying strftime implementation, so use that. */
- char ufmt[5];
- char *u = ufmt;
char ubuf[1024]; /* enough for any single format in practice */
size_t len;
- /* Make sure we're calling the actual underlying strftime.
- In some cases, config.h contains something like
- "#define strftime rpl_strftime". */
-# ifdef strftime
-# undef strftime
- size_t strftime (char *, size_t, const char *, struct tm const *);
-# endif
-
- /* The space helps distinguish strftime failure from empty
- output. */
- *u++ = ' ';
- *u++ = '%';
- if (modifier != 0)
- *u++ = modifier;
- *u++ = format_char;
- *u = '\0';
-
-# if USE_C_LOCALE /* implies HAVE_STRFTIME_L */
- locale_t locale = c_locale ();
- if (!locale)
- return 0; /* errno is set here */
- len = strftime_l (ubuf, sizeof ubuf, ufmt, tp, locale);
-# else
- len = strftime (ubuf, sizeof ubuf, ufmt, tp);
-# endif
+ len = underlying_strftime (tz, ubuf, sizeof ubuf,
+ modifier, format_char, tp);
if (len != 0)
{
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 31) || defined __NetBSD__ || defined __sun /* glibc < 2.31, NetBSD, Solaris */
@@ -1715,7 +1874,8 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
#elif USE_C_LOCALE && !HAVE_STRFTIME_L
subfmt = L_("%I:%M:%S %p");
goto subformat;
-#elif (defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ || (defined _WIN32 && !defined __CYGWIN__)
+#elif ((defined __APPLE__ && defined __MACH__) || defined __FreeBSD__ \
+ || (defined _WIN32 && !defined __CYGWIN__))
/* macOS, FreeBSD, native Windows strftime() may produce empty output
for "%r". */
subfmt = L_("%I:%M:%S %p");
@@ -1927,8 +2087,30 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
to_lowcase = true;
}
+ {
+ char const *zone;
+#ifdef _LIBC
+ zone = tp->tm_zone;
+ /* The tzset() call might have changed the value. */
+ if (!(zone && *zone) && tp->tm_isdst >= 0)
+ {
+ /* POSIX.1 requires that local time zone information be used as
+ though strftime called tzset. */
+ if (!*tzset_called)
+ {
+ tzset ();
+ *tzset_called = true;
+ }
+ zone = tp->tm_isdst <= 1 ? tzname[tp->tm_isdst] : "?";
+ }
+ if (! zone)
+ zone = "";
+#else
+ char zonebuf[128]; /* Enough for any time zone abbreviation. */
+ zone = get_tm_zone (tz, zonebuf, sizeof zonebuf, modifier, tp);
+#endif
+
#ifdef COMPILE_WIDE
- {
/* The zone string is always given in multibyte form. We have
to convert it to wide character. */
size_t w = pad == NO_PAD || width < 0 ? 0 : width;
@@ -1956,10 +2138,10 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
p += incr;
}
i += incr;
- }
#else
- cpy (strlen (zone), zone);
+ cpy (strlen (zone), zone);
#endif
+ }
break;
case L_(':'):
@@ -1984,7 +2166,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
int hour_diff;
int min_diff;
int sec_diff;
-#if HAVE_TM_GMTOFF
+#if HAVE_STRUCT_TM_TM_GMTOFF
diff = tp->tm_gmtoff;
#else
if (!tz)
@@ -1995,16 +2177,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
struct tm ltm;
time_t lt;
- /* POSIX.1 requires that local time zone information be used as
- though strftime called tzset. */
-# ifndef my_strftime
- if (!*tzset_called)
- {
- tzset ();
- *tzset_called = true;
- }
-# endif
-
ltm = *tp;
ltm.tm_wday = -1;
lt = mktime_z (tz, &ltm);
@@ -2014,7 +2186,14 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
}
#endif
- negative_number = diff < 0 || (diff == 0 && *zone == '-');
+ negative_number = diff < 0;
+ if (diff == 0)
+ {
+ char zonebuf[128]; /* Enough for any time zone abbreviation. */
+ negative_number = (*get_tm_zone (tz, zonebuf, sizeof zonebuf,
+ 0, tp)
+ == '-');
+ }
hour_diff = diff / 60 / 60;
min_diff = diff / 60 % 60;
sec_diff = diff % 60;
diff --git a/lib/strnlen.c b/lib/strnlen.c
index 80857ec22b0..5231e4c595d 100644
--- a/lib/strnlen.c
+++ b/lib/strnlen.c
@@ -1,6 +1,5 @@
/* Find the length of STRING, but scan at most MAXLEN characters.
Copyright (C) 2005-2007, 2009-2024 Free Software Foundation, Inc.
- Written by Simon Josefsson.
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
@@ -19,12 +18,17 @@
#include <string.h>
-/* Find the length of STRING, but scan at most MAXLEN characters.
- If no '\0' terminator is found in that many characters, return MAXLEN. */
+/* Find the length of S, but scan at most MAXLEN bytes.
+ S must be a string if it starts with fewer than MAXLEN initialized bytes.
+ If no '\0' terminator is found in that many bytes, return MAXLEN. */
size_t
-strnlen (const char *string, size_t maxlen)
+strnlen (const char *s, size_t maxlen)
{
- const char *end = memchr (string, '\0', maxlen);
- return end ? (size_t) (end - string) : maxlen;
+ /* Do not use memchr, because on some platforms memchr has
+ undefined behavior if MAXLEN exceeds the number of bytes in S. */
+ size_t i;
+ for (i = 0; i < maxlen && s[i]; i++)
+ continue;
+ return i;
}
diff --git a/lib/time-internal.h b/lib/time-internal.h
index 816684a1172..3d778ba50ec 100644
--- a/lib/time-internal.h
+++ b/lib/time-internal.h
@@ -17,6 +17,9 @@
/* Written by Paul Eggert. */
+/* This file is for Gnulib internal use only.
+ Applications should not use it. */
+
/* A time zone rule. */
struct tm_zone
{
@@ -24,12 +27,6 @@ struct tm_zone
members are zero. */
struct tm_zone *next;
-#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE
- /* Copies of recent strings taken from tzname[0] and tzname[1].
- The copies are in ABBRS, so that they survive tzset. Null if unknown. */
- char *tzname_copy[2];
-#endif
-
/* If nonzero, the rule represents the TZ environment variable set
to the first "abbreviation" (this may be the empty string).
Otherwise, it represents an unset TZ. */
@@ -41,9 +38,17 @@ struct tm_zone
actually a TZ environment value) may be empty. Otherwise all
strings must be nonempty.
- Abbreviations are stored here because otherwise the values of
- tm_zone and/or tzname would be dead after changing TZ and calling
+ Abbreviations are stored here even on platforms with tm_zone, because
+ otherwise tm_zone values would be dead after changing TZ and calling
tzset. Abbreviations never move once allocated, and are live
until tzfree is called. */
char abbrs[FLEXIBLE_ARRAY_MEMBER];
};
+
+timezone_t set_tz (timezone_t);
+bool revert_tz (timezone_t);
+
+/* Magic cookie timezone_t value, for local time. It differs from
+ NULL and from all other timezone_t values. Only the address
+ matters; the pointer is never dereferenced. */
+#define local_tz ((timezone_t) 1)
diff --git a/lib/time.in.h b/lib/time.in.h
index df99c8abca9..b91018937ad 100644
--- a/lib/time.in.h
+++ b/lib/time.in.h
@@ -122,6 +122,23 @@ struct __time_t_must_be_integral {
# endif
# endif
+# if @GNULIB_TZNAME@
+/* tzname[0..1]: Abbreviated time zone names, set by the tzset() function. */
+# if NEED_DECL_TZNAME
+extern
+# ifdef __cplusplus
+ "C"
+# endif
+ char *tzname[];
+# endif
+# if defined _WIN32 && !defined __CYGWIN__
+/* On native Windows, map 'tzname' to '_tzname' etc., so that -loldnames is not
+ required. */
+# undef tzname
+# define tzname _tzname
+# endif
+# endif
+
/* Set *TS to the current time, and return BASE.
Upon failure, return 0. */
# if @GNULIB_TIMESPEC_GET@
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 468d7539ce1..a6523e1285b 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -44,11 +44,6 @@ enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
used. */
enum { ABBR_SIZE_MIN = DEFAULT_MXFAST - offsetof (struct tm_zone, abbrs) };
-/* Magic cookie timezone_t value, for local time. It differs from
- NULL and from all other timezone_t values. Only the address
- matters; the pointer is never dereferenced. */
-static timezone_t const local_tz = (timezone_t) 1;
-
/* Copy to ABBRS the abbreviation at ABBR with size ABBR_SIZE (this
includes its trailing null byte). Append an extra null byte to
mark the end of ABBRS. */
@@ -70,9 +65,6 @@ tzalloc (char const *name)
if (tz)
{
tz->next = NULL;
-#if HAVE_TZNAME && !HAVE_STRUCT_TM_TM_ZONE
- tz->tzname_copy[0] = tz->tzname_copy[1] = NULL;
-#endif
tz->tz_is_set = !!name;
tz->abbrs[0] = '\0';
if (name)
@@ -81,33 +73,16 @@ tzalloc (char const *name)
return tz;
}
-/* Save into TZ any nontrivial time zone abbreviation used by TM, and
- update *TM (if HAVE_STRUCT_TM_TM_ZONE) or *TZ (if
- !HAVE_STRUCT_TM_TM_ZONE && HAVE_TZNAME) if they use the abbreviation.
+/* If HAVE_STRUCT_TM_TM_ZONE, save into TZ any nontrivial time zone
+ abbreviation used by TM, and update *TM to contain the saved abbreviation.
Return true if successful, false (setting errno) otherwise. */
static bool
save_abbr (timezone_t tz, struct tm *tm)
{
-#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME
- char const *zone = NULL;
+#if HAVE_STRUCT_TM_TM_ZONE
+ char const *zone = tm->tm_zone;
char *zone_copy = (char *) "";
-# if HAVE_TZNAME
- int tzname_index = -1;
-# endif
-
-# if HAVE_STRUCT_TM_TM_ZONE
- zone = tm->tm_zone;
-# endif
-
-# if HAVE_TZNAME
- if (! (zone && *zone) && 0 <= tm->tm_isdst)
- {
- tzname_index = tm->tm_isdst != 0;
- zone = tzname[tzname_index];
- }
-# endif
-
/* No need to replace null zones, or zones within the struct tm. */
if (!zone || ((char *) tm <= zone && zone < (char *) (tm + 1)))
return true;
@@ -144,12 +119,7 @@ save_abbr (timezone_t tz, struct tm *tm)
}
/* Replace the zone name so that its lifetime matches that of TZ. */
-# if HAVE_STRUCT_TM_TM_ZONE
tm->tm_zone = zone_copy;
-# else
- if (0 <= tzname_index)
- tz->tzname_copy[tzname_index] = zone_copy;
-# endif
#endif
return true;
@@ -202,7 +172,7 @@ change_env (timezone_t tz)
Return LOCAL_TZ if the time zone setting is already correct.
Otherwise return a newly allocated time zone representing the old
setting, or NULL (setting errno) on failure. */
-static timezone_t
+timezone_t
set_tz (timezone_t tz)
{
char *env_tz = getenv_TZ ();
@@ -229,7 +199,7 @@ set_tz (timezone_t tz)
/* Restore an old setting returned by set_tz. It must not be null.
Return true (preserving errno) if successful, false (setting errno)
otherwise. */
-static bool
+bool
revert_tz (timezone_t tz)
{
if (tz == local_tz)
@@ -302,9 +272,7 @@ mktime_z (timezone_t tz, struct tm *tm)
tm_1.tm_isdst = tm->tm_isdst;
time_t t = mktime (&tm_1);
bool ok = 0 <= tm_1.tm_yday;
-#if HAVE_STRUCT_TM_TM_ZONE || HAVE_TZNAME
ok = ok && save_abbr (tz, &tm_1);
-#endif
if (revert_tz (old_tz) && ok)
{
*tm = tm_1;
diff --git a/lib/timespec-add.c b/lib/timespec-add.c
index e10c19842cd..50683187117 100644
--- a/lib/timespec-add.c
+++ b/lib/timespec-add.c
@@ -29,34 +29,22 @@
struct timespec
timespec_add (struct timespec a, struct timespec b)
{
- time_t rs = a.tv_sec;
- time_t bs = b.tv_sec;
- int ns = a.tv_nsec + b.tv_nsec;
- int nsd = ns - TIMESPEC_HZ;
- int rns = ns;
-
- if (0 <= nsd)
- {
- rns = nsd;
- time_t bs1;
- if (!ckd_add (&bs1, bs, 1))
- bs = bs1;
- else if (rs < 0)
- rs++;
- else
- goto high_overflow;
- }
-
- if (ckd_add (&rs, rs, bs))
+ int nssum = a.tv_nsec + b.tv_nsec;
+ int carry = TIMESPEC_HZ <= nssum;
+ time_t rs;
+ int rns;
+ bool v = ckd_add (&rs, a.tv_sec, b.tv_sec);
+ if (v == ckd_add (&rs, rs, carry))
+ rns = nssum - TIMESPEC_HZ * carry;
+ else
{
- if (bs < 0)
+ if ((TYPE_MINIMUM (time_t) + TYPE_MAXIMUM (time_t)) / 2 < rs)
{
rs = TYPE_MINIMUM (time_t);
rns = 0;
}
else
{
- high_overflow:
rs = TYPE_MAXIMUM (time_t);
rns = TIMESPEC_HZ - 1;
}
diff --git a/lib/timespec-sub.c b/lib/timespec-sub.c
index 315cc638369..f6d948780e4 100644
--- a/lib/timespec-sub.c
+++ b/lib/timespec-sub.c
@@ -30,28 +30,17 @@
struct timespec
timespec_sub (struct timespec a, struct timespec b)
{
- time_t rs = a.tv_sec;
- time_t bs = b.tv_sec;
- int ns = a.tv_nsec - b.tv_nsec;
- int rns = ns;
-
- if (ns < 0)
- {
- rns = ns + TIMESPEC_HZ;
- time_t bs1;
- if (!ckd_add (&bs1, bs, 1))
- bs = bs1;
- else if (- TYPE_SIGNED (time_t) < rs)
- rs--;
- else
- goto low_overflow;
- }
-
- if (ckd_sub (&rs, rs, bs))
+ int nsdiff = a.tv_nsec - b.tv_nsec;
+ bool borrow = nsdiff < 0;
+ time_t rs;
+ int rns;
+ bool v = ckd_sub (&rs, a.tv_sec, b.tv_sec);
+ if (v == ckd_sub (&rs, rs, borrow))
+ rns = nsdiff + TIMESPEC_HZ * borrow;
+ else
{
- if (0 < bs)
+ if ((TYPE_MINIMUM (time_t) + TYPE_MAXIMUM (time_t)) / 2 < rs)
{
- low_overflow:
rs = TYPE_MINIMUM (time_t);
rns = 0;
}
diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el
index f2631422c62..6b7dcad3899 100644
--- a/lisp/autoinsert.el
+++ b/lisp/autoinsert.el
@@ -166,18 +166,18 @@ If this contains a %s, that will be replaced by the matching rule."
(replace-match (capitalize (user-login-name)) t t))
'(end-of-line 1) " <" (progn user-mail-address) ">\n")
- (".dir-locals.el"
+ ((,(rx ".dir-locals" (? "-2") ".el") . "Directory Local Variables")
nil
";;; Directory Local Variables -*- no-byte-compile: t; -*-\n"
";;; For more information see (info \"(emacs) Directory Variables\")\n\n"
"(("
- '(setq v1 (let (modes)
+ '(setq v1 (let ((modes '("nil")))
(mapatoms (lambda (mode)
(let ((name (symbol-name mode)))
(when (string-match "-mode\\'" name)
(push name modes)))))
(sort modes 'string<)))
- (completing-read "Local variables for mode: " v1 nil t)
+ (completing-read "Local variables for mode: " v1 nil 'confirm)
" . (("
(let ((all-variables
(apropos-internal ".*"
diff --git a/lisp/completion-preview.el b/lisp/completion-preview.el
index caebb9d01e3..0e32beef5d0 100644
--- a/lisp/completion-preview.el
+++ b/lisp/completion-preview.el
@@ -49,6 +49,29 @@
;; prefix (so nothing is underlined in the preview), it displays a list
;; of all matching completion candidates.
;;
+;; You can also insert only the first word of the completion candidate
+;; with the command `completion-preview-insert-word'. With a numeric
+;; prefix argument, it inserts that many words instead of just the one.
+;; This command is not bound by default, but you may want to bind it to
+;; M-f (or remap `forward-word') in `completion-preview-active-mode-map'
+;; since it's very much like a `forward-word' that also moves "into" the
+;; completion preview. To define your own command that inserts part of
+;; a completion candidate by moving "into" the completion preview, use
+;; the function `completion-preview-partial-insert'. For example, you
+;; can define a command that completes exactly one symbol as follows:
+;;
+;; (defun my-completion-preview-insert-symbol ()
+;; (interactive)
+;; (completion-preview-partial-insert #'forward-symbol 1))
+;;
+;; Similarly to `completion-preview-insert-word', the command
+;; `completion-preview-insert-sexp' lets you complete by one or more
+;; balanced expressions. The definition of this command is very similar
+;; to the simple example above, expect it uses `forward-sexp' rather
+;; than `forward-symbol'. This command can be useful when you're using
+;; Completion Preview mode with long, complex completion candidates,
+;; such as entire shell commands from the shell history.
+;;
;; If you set the user option `completion-preview-exact-match-only' to
;; non-nil, Completion Preview mode only suggests a completion
;; candidate when its the only possible completion for the (partial)
@@ -90,7 +113,9 @@ first candidate, and you can cycle between the candidates with
delete-backward-char
backward-delete-char-untabify
analyze-text-conversion
- completion-preview-complete)
+ completion-preview-complete
+ completion-preview-insert-word
+ completion-preview-insert-sexp)
"List of commands that should trigger completion preview."
:type '(repeat (function :tag "Command" :value self-insert-command))
:version "30.1")
@@ -163,6 +188,8 @@ If this is nil, display the completion preview without delay."
"M-i" #'completion-preview-complete
;; "M-n" #'completion-preview-next-candidate
;; "M-p" #'completion-preview-prev-candidate
+ ;; "<remap> <forward-word>" #'completion-preview-insert-word
+ ;; "<remap> <forward-sexp>" #'completion-preview-insert-sexp
)
(defun completion-preview--ignore ()
@@ -444,24 +471,102 @@ point, otherwise hide it."
(completion-preview--show)
(completion-preview-active-mode -1)))))
+(defun completion-preview--barf-if-no-preview ()
+ "Signal a `user-error' if completion preview is not active."
+ (unless completion-preview-active-mode
+ (user-error "No current completion preview")))
+
(defun completion-preview-insert ()
"Insert the completion candidate that the preview is showing."
(interactive)
- (if completion-preview-active-mode
+ (completion-preview--barf-if-no-preview)
+ (let* ((pre (completion-preview--get 'completion-preview-base))
+ (end (completion-preview--get 'completion-preview-end))
+ (ind (completion-preview--get 'completion-preview-index))
+ (all (completion-preview--get 'completion-preview-suffixes))
+ (com (completion-preview--get 'completion-preview-common))
+ (efn (plist-get (completion-preview--get 'completion-preview-props)
+ :exit-function))
+ (aft (completion-preview--get 'after-string))
+ (str (concat pre com (nth ind all))))
+ (completion-preview-active-mode -1)
+ (goto-char end)
+ (insert-and-inherit (substring-no-properties aft))
+ (when (functionp efn) (funcall efn str 'finished))))
+
+(defun completion-preview-partial-insert (fun &rest args)
+ "Insert part of the current completion preview candidate.
+
+This function calls FUN with arguments ARGS, after temporarily inserting
+the entire current completion preview candidate. FUN should move point:
+if it moves point forward into the completion text, this function
+inserts the prefix of the completion candidate up to that point.
+Beyond moving point, FUN should not modify the current buffer."
+ (completion-preview--barf-if-no-preview)
+ (let* ((end (completion-preview--get 'completion-preview-end))
+ (aft (completion-preview--get 'after-string))
+ (eoc (+ end (length aft))))
+ ;; Keep region active, if it is already. This lets commands that
+ ;; call this function interact correctly with `shift-select-mode'.
+ (let ((deactivate-mark nil))
+ ;; Partially insert current completion candidate.
+ (catch 'abort-atomic-change
+ (atomic-change-group
+ (let ((change-group (prepare-change-group)))
+ (save-excursion
+ (goto-char end)
+ ;; Temporarily insert the full completion candidate.
+ (insert-and-inherit (substring-no-properties aft)))
+ ;; Set point to the end of the prefix that we want to keep.
+ (apply fun args)
+ (unless (< end (point))
+ ;; Point didn't advance into the completion, so abort change
+ ;; to avoid littering `buffer-undo-list' with a nop entry.
+ (throw 'abort-atomic-change nil))
+ ;; Delete the rest.
+ (delete-region (min (point) eoc) eoc)
+ ;; Combine into one change group.
+ (undo-amalgamate-change-group change-group)))))
+ ;; Cleanup.
+ (cond
+ ;; If we kept the entire completion candidate, call :exit-function.
+ ((<= eoc (point))
(let* ((pre (completion-preview--get 'completion-preview-base))
- (end (completion-preview--get 'completion-preview-end))
(ind (completion-preview--get 'completion-preview-index))
(all (completion-preview--get 'completion-preview-suffixes))
(com (completion-preview--get 'completion-preview-common))
- (efn (plist-get (completion-preview--get 'completion-preview-props)
- :exit-function))
- (aft (completion-preview--get 'after-string))
- (str (concat pre com (nth ind all))))
+ (efn (plist-get
+ (completion-preview--get 'completion-preview-props)
+ :exit-function)))
(completion-preview-active-mode -1)
- (goto-char end)
- (insert (substring-no-properties aft))
- (when (functionp efn) (funcall efn str 'finished)))
- (user-error "No current completion preview")))
+ (when (functionp efn) (funcall efn (concat pre com (nth ind all))
+ 'finished))))
+ ;; If we kept anything, update preview overlay accordingly.
+ ((< end (point))
+ (completion-preview--inhibit-update)
+ (overlay-put (completion-preview--make-overlay
+ (point)
+ (propertize
+ (substring aft (- (point) end))
+ 'mouse-face 'completion-preview-highlight
+ 'keymap completion-preview--mouse-map))
+ 'completion-preview-end (point)))
+ ;; If we kept nothing, do nothing.
+ )))
+
+(defun completion-preview-insert-word (&optional n)
+ "Insert the first N words of the current completion preview candidate.
+
+Interactively, N is the numeric prefix argument, and it defaults to 1."
+ (interactive "^p")
+ (completion-preview-partial-insert #'forward-word n))
+
+(defun completion-preview-insert-sexp (&optional n)
+ "Insert the first N s-expressions of the current completion preview candidate.
+
+Interactively, N is the numeric prefix argument, and it defaults to 1."
+ (interactive "^p")
+ (completion-preview-partial-insert #'forward-sexp n 'interactive))
(defun completion-preview-complete ()
"Complete up to the longest common prefix of all completion candidates.
@@ -472,8 +577,7 @@ candidates unless `completion-auto-help' is nil. If you repeat this
command again when the completions list is visible, it scrolls the
completions list."
(interactive)
- (unless completion-preview-active-mode
- (user-error "No current completion preview"))
+ (completion-preview--barf-if-no-preview)
(let* ((beg (completion-preview--get 'completion-preview-beg))
(end (completion-preview--get 'completion-preview-end))
(com (completion-preview--get 'completion-preview-common))
@@ -512,7 +616,7 @@ completions list."
(completion-preview--inhibit-update)
(completion-at-point))
;; Otherwise, insert the common prefix and update the preview.
- (insert ins)
+ (insert-and-inherit ins)
(let ((suf (nth cur all))
(pos (point)))
(if (or (string-empty-p suf) (null suf))
@@ -578,15 +682,21 @@ prefix argument and defaults to 1."
(message (format-spec completion-preview-message-format
`((?i . ,(1+ new)) (?n . ,len))))))))
-(defun completion-preview--active-p (_symbol buffer)
- "Check if the completion preview is currently shown in BUFFER."
+(defun completion-preview-active-p (_symbol buffer)
+ "Check if the completion preview is currently shown in BUFFER.
+
+The first argument, SYMBOL, is ignored. You can use this function as
+the `completion-predicate' property of commands that you define that
+should only be available when the completion preview is active."
(buffer-local-value 'completion-preview-active-mode buffer))
(dolist (cmd '(completion-preview-insert
+ completion-preview-insert-word
+ completion-preview-insert-sexp
completion-preview-complete
completion-preview-prev-candidate
completion-preview-next-candidate))
- (put cmd 'completion-predicate #'completion-preview--active-p))
+ (put cmd 'completion-predicate #'completion-preview-active-p))
;;;###autoload
(define-minor-mode completion-preview-mode
diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el
index 469f4334b44..5fd3629e57d 100644
--- a/lisp/cus-edit.el
+++ b/lisp/cus-edit.el
@@ -1280,7 +1280,7 @@ Show the buffer in another window, but don't select it."
(unless (eq symbol basevar)
(message "`%s' is an alias for `%s'" symbol basevar))))
-(defvar customize-changed-options-previous-release "29.4"
+(defvar customize-changed-options-previous-release "30.1"
"Version for `customize-changed' to refer back to by default.")
;; Packages will update this variable, so make it available.
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 4ae9a5e6629..f96b1bad886 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1511,15 +1511,18 @@ to do that. To reset the slice use `doc-view-reset-slice'."
;; Redisplay
(doc-view-goto-page (doc-view-current-page)))
+(defvar touch-screen-simple-mouse-conversion) ; Defined in touch-screen.el.
+
(defun doc-view-set-slice-using-mouse ()
"Set the slice of the images that should be displayed.
You set the slice by pressing mouse-1 at its top-left corner and
dragging it to its bottom-right corner. See also
`doc-view-set-slice' and `doc-view-reset-slice'."
(interactive)
- (let (x y w h done)
+ (let ((touch-screen-simple-mouse-conversion t)
+ x y w h done)
(while (not done)
- (let ((e (read-event
+ (let ((e (read-key
(concat "Press mouse-1 at the top-left corner and "
"drag it to the bottom-right corner!"))))
(when (eq (car e) 'drag-mouse-1)
diff --git a/lisp/emacs-lisp/checkdoc.el b/lisp/emacs-lisp/checkdoc.el
index c22dfb2eb26..bda5150cf07 100644
--- a/lisp/emacs-lisp/checkdoc.el
+++ b/lisp/emacs-lisp/checkdoc.el
@@ -289,6 +289,7 @@ made in the style guide relating to order."
Currently, all recognized keywords must be on `finder-known-keywords'."
:version "25.1"
:type 'boolean)
+;;;###autoload(put 'checkdoc-package-keywords-flag 'safe-local-variable #'booleanp)
(defvar checkdoc-style-functions nil
"Hook run after the standard style check is completed.
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index b0be96d7b35..359f206f1ab 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -12,7 +12,7 @@
;; David Edmondson (dme@dme.org)
;; Michael Olson (mwolson@gnu.org)
;; Kelvin White (kwhite@gnu.org)
-;; Version: 5.6.0.30.1
+;; Version: 5.6.1-git
;; Package-Requires: ((emacs "27.1") (compat "29.1.4.5"))
;; Keywords: IRC, chat, client, Internet
;; URL: https://www.gnu.org/software/emacs/erc.html
@@ -70,7 +70,7 @@
(require 'auth-source)
(eval-when-compile (require 'subr-x))
-(defconst erc-version "5.6.0.30.1"
+(defconst erc-version "5.6.1-git"
"This version of ERC.")
(defvar erc-official-location
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index 2ff41c3d409..a5e9de79907 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -530,30 +530,34 @@ PROC is the process that's exiting. STRING is the exit message."
(not (process-live-p proc))))
(finish-io
(lambda ()
- (with-current-buffer (process-buffer proc)
- (if (or (process-get proc :eshell-busy)
- (and wait-for-stderr (car stderr-live)))
- (progn
+ (if (buffer-live-p (process-buffer proc))
+ (with-current-buffer (process-buffer proc)
+ (if (or (process-get proc :eshell-busy)
+ (and wait-for-stderr (car stderr-live)))
+ (progn
+ (eshell-debug-command 'process
+ "i/o busy for process `%s'" proc)
+ (run-at-time 0 nil finish-io))
+ (when data
+ (ignore-error eshell-pipe-broken
+ (eshell-output-object
+ data index handles)))
+ (eshell-close-handles
+ status
+ (when status (list 'quote (= status 0)))
+ handles)
+ ;; Clear the handles to mark that we're 100%
+ ;; finished with the I/O for this process.
+ (process-put proc :eshell-handles nil)
(eshell-debug-command 'process
- "i/o busy for process `%s'" proc)
- (run-at-time 0 nil finish-io))
- (when data
- (ignore-error eshell-pipe-broken
- (eshell-output-object
- data index handles)))
- (eshell-close-handles
- status
- (when status (list 'quote (= status 0)))
- handles)
- ;; Clear the handles to mark that we're 100%
- ;; finished with the I/O for this process.
- (process-put proc :eshell-handles nil)
- (eshell-debug-command 'process
- "finished external process `%s'" proc)
- (if primary
- (run-hook-with-args 'eshell-kill-hook
- proc string)
- (setcar stderr-live nil)))))))
+ "finished external process `%s'" proc)
+ (if primary
+ (run-hook-with-args 'eshell-kill-hook
+ proc string)
+ (setcar stderr-live nil))))
+ (eshell-debug-command 'process
+ "buffer for external process `%s' already killed"
+ proc)))))
(funcall finish-io)))
(when-let ((entry (assq proc eshell-process-list)))
(eshell-remove-process-entry entry))))))
diff --git a/lisp/eshell/eshell.el b/lisp/eshell/eshell.el
index 18e05a371a4..568f6745067 100644
--- a/lisp/eshell/eshell.el
+++ b/lisp/eshell/eshell.el
@@ -216,6 +216,34 @@ named \"*eshell*<2>\"."
:type 'string
:group 'eshell)
+(defcustom eshell-command-async-buffer 'confirm-new-buffer
+ "What to do when the output buffer is used by another shell command.
+This option specifies how to resolve the conflict where a new command
+wants to direct its output to the buffer whose name is stored
+in `eshell-command-buffer-name-async', but that buffer is already
+taken by another running shell command.
+
+The value `confirm-kill-process' is used to ask for confirmation before
+killing the already running process and running a new process in the
+same buffer, `confirm-new-buffer' for confirmation before running the
+command in a new buffer with a name other than the default buffer name,
+`new-buffer' for doing the same without confirmation,
+`confirm-rename-buffer' for confirmation before renaming the existing
+output buffer and running a new command in the default buffer,
+`rename-buffer' for doing the same without confirmation."
+ :type '(choice (const :tag "Confirm killing of running command"
+ confirm-kill-process)
+ (const :tag "Confirm creation of a new buffer"
+ confirm-new-buffer)
+ (const :tag "Create a new buffer"
+ new-buffer)
+ (const :tag "Confirm renaming of existing buffer"
+ confirm-rename-buffer)
+ (const :tag "Rename the existing buffer"
+ rename-buffer))
+ :group 'eshell
+ :version "31.1")
+
;;;_* Running Eshell
;;
;; There are only three commands used to invoke Eshell. The first two
@@ -283,11 +311,19 @@ information on Eshell, see Info node `(eshell)Top'."
(eshell-command-mode +1))
(read-from-minibuffer prompt))))
+(defvar eshell-command-buffer-name-async "*Eshell Async Command Output*")
+(defvar eshell-command-buffer-name-sync "*Eshell Command Output*")
+
;;;###autoload
(defun eshell-command (command &optional to-current-buffer)
"Execute the Eshell command string COMMAND.
If TO-CURRENT-BUFFER is non-nil (interactively, with the prefix
-argument), then insert output into the current buffer at point."
+argument), then insert output into the current buffer at point.
+
+When \"&\" is added at end of command, the command is async and its output
+appears in a specific buffer. You can customize
+`eshell-command-async-buffer' to specify what to do when this output
+buffer is already taken by another running shell command."
(interactive (list (eshell-read-command)
current-prefix-arg))
(save-excursion
@@ -301,18 +337,46 @@ argument), then insert output into the current buffer at point."
(eshell-current-subjob-p))
,(eshell-parse-command command))
command))
- intr
- (bufname (if (eq (car-safe proc) :eshell-background)
- "*Eshell Async Command Output*"
- (setq intr t)
- "*Eshell Command Output*")))
- (if (buffer-live-p (get-buffer bufname))
- (kill-buffer bufname))
- (rename-buffer bufname)
+ (async (eq (car-safe proc) :eshell-background))
+ (bufname (cond
+ (to-current-buffer nil)
+ (async eshell-command-buffer-name-async)
+ (t eshell-command-buffer-name-sync)))
+ unique)
+ (when bufname
+ (when (buffer-live-p (get-buffer bufname))
+ (cond
+ ((with-current-buffer bufname
+ (and (null eshell-foreground-command)
+ (null eshell-background-commands)))
+ ;; The old buffer is done executing; kill it so we can
+ ;; take its place.
+ (kill-buffer bufname))
+ ((eq eshell-command-async-buffer 'confirm-kill-process)
+ (shell-command--same-buffer-confirm "Kill it")
+ (with-current-buffer bufname
+ ;; Stop all the processes in the old buffer (there may
+ ;; be several).
+ (eshell-process-interact #'interrupt-process t))
+ (accept-process-output)
+ (kill-buffer bufname))
+ ((eq eshell-command-async-buffer 'confirm-new-buffer)
+ (shell-command--same-buffer-confirm "Use a new buffer")
+ (setq unique t))
+ ((eq eshell-command-async-buffer 'new-buffer)
+ (setq unique t))
+ ((eq eshell-command-async-buffer 'confirm-rename-buffer)
+ (shell-command--same-buffer-confirm "Rename it")
+ (with-current-buffer bufname
+ (rename-uniquely)))
+ ((eq eshell-command-async-buffer 'rename-buffer)
+ (with-current-buffer bufname
+ (rename-uniquely)))))
+ (rename-buffer bufname unique))
;; things get a little coarse here, since the desire is to
;; make the output as attractive as possible, with no
;; extraneous newlines
- (when intr
+ (unless async
(apply #'eshell-wait-for-process (cadr eshell-foreground-command))
(cl-assert (not eshell-foreground-command))
(goto-char (point-max))
@@ -320,7 +384,7 @@ argument), then insert output into the current buffer at point."
(delete-char -1)))
(cl-assert (and buf (buffer-live-p buf)))
(unless to-current-buffer
- (let ((len (if (not intr) 2
+ (let ((len (if async 2
(count-lines (point-min) (point-max)))))
(cond
((= len 0)
@@ -336,7 +400,7 @@ argument), then insert output into the current buffer at point."
;; cause the output buffer to take up as little screen
;; real-estate as possible, if temp buffer resizing is
;; enabled
- (and intr temp-buffer-resize-mode
+ (and (not async) temp-buffer-resize-mode
(resize-temp-buffer-window)))))))))))
;;;###autoload
diff --git a/lisp/gnus/canlock.el b/lisp/gnus/canlock.el
index 02744a7f0a5..39ae6809a55 100644
--- a/lisp/gnus/canlock.el
+++ b/lisp/gnus/canlock.el
@@ -41,8 +41,6 @@
;;; Code:
-(require 'sha1)
-
(defvar mail-header-separator)
(defgroup canlock nil
diff --git a/lisp/international/quail.el b/lisp/international/quail.el
index 48d2ccb8828..cb7aa89b252 100644
--- a/lisp/international/quail.el
+++ b/lisp/international/quail.el
@@ -1334,9 +1334,13 @@ If STR has `advice' text property, append the following special event:
(quail-setup-overlays (quail-conversion-keymap))
(with-silent-modifications
(unwind-protect
- (let ((input-string (if (quail-conversion-keymap)
+ (let* (;; `with-silent-modifications' inhibits the modification
+ ;; hooks, but that's a part of `with-silent-modifications'
+ ;; we don't actually want here (bug#70541).
+ (inhibit-modification-hooks nil)
+ (input-string (if (quail-conversion-keymap)
(quail-start-conversion key)
- (quail-start-translation key))))
+ (quail-start-translation key))))
(setq quail-guidance-str "")
(when (and (stringp input-string)
(> (length input-string) 0))
@@ -1871,10 +1875,9 @@ sequence counting from the head."
(defsubst quail-point-in-conversion-region ()
"Return non-nil value if the point is in conversion region of Quail mode."
- (let (start pos)
- (and (setq start (overlay-start quail-conv-overlay))
- (>= (setq pos (point)) start)
- (<= pos (overlay-end quail-conv-overlay)))))
+ (let ((start (overlay-start quail-conv-overlay)))
+ (and start
+ (<= start (point) (overlay-end quail-conv-overlay)))))
(defun quail-conversion-backward-char ()
(interactive)
diff --git a/lisp/international/utf7.el b/lisp/international/utf7.el
index 63009b0744a..2b23bee1038 100644
--- a/lisp/international/utf7.el
+++ b/lisp/international/utf7.el
@@ -63,7 +63,6 @@
;;; Code:
-(require 'base64)
(require 'mm-util)
(defconst utf7-direct-encoding-chars " -%'-*,-[]-}"
diff --git a/lisp/net/eww.el b/lisp/net/eww.el
index 94bfd333fa9..907b35f8565 100644
--- a/lisp/net/eww.el
+++ b/lisp/net/eww.el
@@ -1370,8 +1370,13 @@ within text input fields."
(save-excursion
(goto-char (point-min))
(while-let ((match (text-property-search-forward
- 'display nil (lambda (_ value) (imagep value)))))
- (let* ((image (prop-match-value match))
+ 'display nil
+ (lambda (_ value)
+ (and value (get-display-property
+ nil 'image nil value))))))
+ (let* ((image (cons 'image
+ (get-display-property nil 'image nil
+ (prop-match-value match))))
(original-scale (or (image-property image :original-scale)
(setf (image-property image :original-scale)
(or (image-property image :scale)
diff --git a/lisp/net/hmac-md5.el b/lisp/net/hmac-md5.el
index 1c4ac24a9c4..af323b0d2b0 100644
--- a/lisp/net/hmac-md5.el
+++ b/lisp/net/hmac-md5.el
@@ -29,7 +29,6 @@
(eval-when-compile (require 'hmac-def))
(require 'hex-util) ; (decode-hex-string STRING)
-(require 'md5) ; expects (md5 STRING)
(defun md5-binary (string)
"Return the MD5 of STRING in binary form."
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 3dadcb9a09b..ea3d8deeff8 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -58,6 +58,20 @@ fit these criteria."
:version "24.1"
:type 'float)
+(defcustom shr-sliced-image-height 0.9
+ "How tall images can be before slicing in relation to the window they're in.
+A value of 0.7 means that images are allowed to take up 70% of the
+height of the window before being sliced by `insert-sliced-image'. If
+nil, never slice images.
+
+Sliced images allow for more intuitive scrolling up/down by letting you
+scroll past each slice, instead of jumping past the entire image.
+Alternately, you can use `pixel-scroll-precision-mode' to scroll
+pixel-wise past images, in which case you can set this option to nil."
+ :version "31.1"
+ :type '(choice (const :tag "Never slice images")
+ float))
+
(defcustom shr-allowed-images nil
"If non-nil, only images that match this regexp are displayed.
If nil, all URLs are allowed. Also see `shr-blocked-images'."
@@ -205,6 +219,25 @@ interpreted as a multiple of the height of default font."
:version "30.1"
:type '(choice (const nil) (cons number number)))
+(defcustom shr-image-zoom-levels '(fit original fill-height)
+ "A list of image zoom levels to cycle through with `shr-zoom-image'.
+The first element in the list is the initial zoom level. Each element
+can be one of the following symbols:
+
+* `fit': Display the image at its original size as requested by the
+ page, shrinking it to fit in the current window if necessary.
+* `original': Display the image at its original size as requested by the
+ page.
+* `image': Display the image at its full size (ignoring the width/height
+ specified by the HTML).
+* `fill-height': Display the image zoomed to fill the height of the
+current window."
+ :version "31.1"
+ :type '(set (choice (const :tag "Fit to window size" fit)
+ (const :tag "Original size" original)
+ (const :tag "Full image size" image)
+ (const :tag "Fill window height" fill-height))))
+
(defvar shr-content-function nil
"If bound, this should be a function that will return the content.
This is used for cid: URLs, and the function is called with the
@@ -607,35 +640,60 @@ the URL of the image to the kill buffer instead."
(list (current-buffer) (1- (point)) (point-marker))
t))))
-(defun shr-zoom-image ()
- "Cycle the image size.
+(defvar shr-image-zoom-level-alist
+ `((fit "Zoom to fit" shr-rescale-image)
+ (original "Zoom to original size" shr--image-zoom-original-size)
+ (image "Zoom to full image size" shr--image-zoom-image-size)
+ (fill-height "Zoom to fill window height" shr--image-zoom-fill-height))
+ "An alist of possible image zoom levels.
+Each element is of the form (SYMBOL DESC FUNCTION). SYMBOL is the
+symbol identifying this level, as used by `shr-image-zoom-levels' (which
+see). DESC is a string describing the level.
+
+FUNCTION is a function that returns a properly-zoomed image; it takes
+the following arguments:
+
+* DATA: The image data in string form.
+* CONTENT-TYPE: The content-type of the image, if any.
+* WIDTH: The width as specified by the HTML \"width\" attribute, if any.
+* HEIGHT: The height as specified by the HTML \"height\" attribute, if
+ any.")
+
+(defun shr-zoom-image (&optional position zoom-level)
+ "Change the zoom level of the image at POSITION.
+
The size will cycle through the default size, the original size, and
full-buffer size."
- (interactive)
- (let ((url (get-text-property (point) 'image-url)))
+ (interactive "d")
+ (unless position (setq position (point)))
+ (let ((url (get-text-property position 'image-url)))
(if (not url)
(message "No image under point")
- (let* ((end (or (next-single-property-change (point) 'image-url)
+ (unless zoom-level
+ (let ((last-zoom (get-text-property position 'image-zoom)))
+ (setq zoom-level (or (cadr (memq last-zoom shr-image-zoom-levels))
+ (car shr-image-zoom-levels)))))
+ (let* ((end (or (next-single-property-change position 'image-url)
(point-max)))
(start (or (previous-single-property-change end 'image-url)
(point-min)))
- (size (get-text-property (point) 'image-size))
- (next-size (cond ((or (eq size 'default)
- (null size))
- 'original)
- ((eq size 'original)
- 'full)
- ((eq size 'full)
- 'default)))
+ (dom-size (get-text-property position 'image-dom-size))
+ (flags `( :zoom ,zoom-level
+ :width ,(car dom-size)
+ :height ,(cdr dom-size)))
(buffer-read-only nil))
;; Delete the old picture.
(put-text-property start end 'display nil)
- (message "Inserting %s..." url)
- (url-retrieve url #'shr-image-fetched
- `(,(current-buffer) ,start
- ,(set-marker (make-marker) end)
- ((size . ,next-size)))
- t)))))
+ (message "%s" (cadr (assq zoom-level shr-image-zoom-level-alist)))
+ (if (and (not shr-ignore-cache)
+ (url-is-cached url))
+ (shr-replace-image (shr-get-image-data url) start
+ (set-marker (make-marker) end) flags)
+ (url-retrieve url #'shr-image-fetched
+ `(,(current-buffer) ,start
+ ,(set-marker (make-marker) end)
+ ,flags)
+ t))))))
;;; Utility functions.
@@ -1056,6 +1114,25 @@ the mouse click event."
(expand-file-name (file-name-nondirectory url)
directory)))))
+(defun shr-replace-image (data start end &optional flags)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (let ((alt (buffer-substring start end))
+ (properties (text-properties-at start))
+ ;; We don't want to record these changes.
+ (buffer-undo-list t)
+ (inhibit-read-only t))
+ (remove-overlays start end)
+ (delete-region start end)
+ (goto-char start)
+ (funcall shr-put-image-function data alt flags)
+ (while properties
+ (let ((type (pop properties))
+ (value (pop properties)))
+ (unless (memq type '(display image-zoom))
+ (put-text-property start (point) type value))))))))
+
(defun shr-image-fetched (status buffer start end &optional flags)
(let ((image-buffer (current-buffer)))
(when (and (buffer-name buffer)
@@ -1066,23 +1143,7 @@ the mouse click event."
(search-forward "\r\n\r\n" nil t))
(let ((data (shr-parse-image-data)))
(with-current-buffer buffer
- (save-excursion
- (save-restriction
- (widen)
- (let ((alt (buffer-substring start end))
- (properties (text-properties-at start))
- ;; We don't want to record these changes.
- (buffer-undo-list t)
- (inhibit-read-only t))
- (remove-overlays start end)
- (delete-region start end)
- (goto-char start)
- (funcall shr-put-image-function data alt flags)
- (while properties
- (let ((type (pop properties))
- (value (pop properties)))
- (unless (memq type '(display image-size))
- (put-text-property start (point) type value)))))))))))
+ (shr-replace-image data start end flags)))))
(kill-buffer image-buffer)))
(defun shr-image-from-data (data)
@@ -1118,9 +1179,21 @@ the mouse click event."
(defun shr-put-image (spec alt &optional flags)
"Insert image SPEC with a string ALT. Return image.
SPEC is either an image data blob, or a list where the first
-element is the data blob and the second element is the content-type."
+element is the data blob and the second element is the content-type.
+
+FLAGS is a property list specifying optional parameters for the image.
+You can specify the following optional properties:
+
+* `:zoom': The zoom level for the image. One of `default', `original',
+ or `full'.
+* `:width': The width of the image as specified by the HTML \"width\"
+ attribute.
+* `:height': The height of the image as specified by the HTML
+ \"height\" attribute."
(if (display-graphic-p)
- (let* ((size (cdr (assq 'size flags)))
+ (let* ((zoom (or (plist-get flags :zoom)
+ (car shr-image-zoom-levels)))
+ (zoom-function (nth 2 (assq zoom shr-image-zoom-level-alist)))
(data (if (consp spec)
(car spec)
spec))
@@ -1128,22 +1201,15 @@ element is the data blob and the second element is the content-type."
(cadr spec)))
(start (point))
(image (cond
- ((eq size 'original)
- (create-image data nil t :ascent shr-image-ascent
- :format content-type))
((eq content-type 'image/svg+xml)
(when (image-type-available-p 'svg)
(create-image data 'svg t :ascent shr-image-ascent)))
- ((eq size 'full)
- (ignore-errors
- (shr-rescale-image data content-type
- (plist-get flags :width)
- (plist-get flags :height))))
- (t
- (ignore-errors
- (shr-rescale-image data content-type
- (plist-get flags :width)
- (plist-get flags :height)))))))
+ (zoom-function
+ (ignore-errors
+ (funcall zoom-function data content-type
+ (plist-get flags :width)
+ (plist-get flags :height))))
+ (t (error "Unrecognized zoom level %s" zoom)))))
(when image
;; The trailing space can confuse shr-insert into not
;; putting any space after inline images.
@@ -1157,20 +1223,28 @@ element is the data blob and the second element is the content-type."
(when (and (> (current-column) 0)
(not inline))
(insert "\n"))
- (let ((image-pos (point)))
- (if (eq size 'original)
+ (let ((image-pos (point))
+ image-height body-height)
+ (if (and shr-sliced-image-height
+ (setq image-height (cdr (image-size image t))
+ body-height (window-body-height
+ (get-buffer-window (current-buffer))
+ t))
+ (> (/ image-height body-height 1.0)
+ shr-sliced-image-height))
;; Normally, we try to keep the buffer text the same
;; by preserving ALT. With a sliced image, we have to
;; repeat the text for each line, so we can't do that.
;; Just use "*" for the string to insert instead.
(progn
- (insert-sliced-image image "*" nil 20 1)
+ (insert-sliced-image
+ image "*" nil (/ image-height (default-line-height)) 1)
(let ((overlay (make-overlay start (point))))
;; Avoid displaying unsightly decorations on the
;; image slices.
(overlay-put overlay 'face 'shr-sliced-image)))
(insert-image image alt))
- (put-text-property start (point) 'image-size size)
+ (put-text-property start (point) 'image-zoom zoom)
(when (and (not inline) shr-max-inline-image-size)
(insert "\n"))
(when (and shr-image-animate
@@ -1208,27 +1282,33 @@ width/height instead."
(or max-height
(- (nth 3 edges) (nth 1 edges))))))
(scaling (image-compute-scaling-factor image-scaling-factor)))
- (when (or (and width
- (> width max-width))
- (and height
- (> height max-height)))
- (setq width nil
- height nil))
- (if (and width height
- (< (* width scaling) max-width)
- (< (* height scaling) max-height))
- (create-image
- data (shr--image-type) t
- :ascent shr-image-ascent
- :width width
- :height height
- :format content-type)
- (create-image
- data (shr--image-type) t
- :ascent shr-image-ascent
- :max-width max-width
- :max-height max-height
- :format content-type)))))
+ (when (and width (> (* width scaling) max-width))
+ (setq width nil))
+ (when (and height (> (* height scaling) max-height))
+ (setq height nil))
+ (create-image
+ data (shr--image-type) t
+ :ascent shr-image-ascent
+ :width width
+ :height height
+ :max-width max-width
+ :max-height max-height
+ :format content-type))))
+
+(defun shr--image-zoom-original-size (data content-type width height)
+ (create-image data (shr--image-type) t :ascent shr-image-ascent
+ :width width :height height :format content-type))
+
+(defun shr--image-zoom-image-size (data content-type _width _height)
+ (create-image data nil t :ascent shr-image-ascent :format content-type))
+
+(defun shr--image-zoom-fill-height (data content-type _width _height)
+ (let* ((edges (window-inside-pixel-edges
+ (get-buffer-window (current-buffer))))
+ (height (truncate (* shr-max-image-proportion
+ (- (nth 3 edges) (nth 1 edges))))))
+ (create-image data (shr--image-type) t :ascent shr-image-ascent
+ :height height :format content-type)))
;; url-cache-extract autoloads url-cache.
(declare-function url-cache-create-filename "url-cache" (url))
@@ -1885,6 +1965,7 @@ The preference is a float determined from `shr-prefer-media-type'."
(put-text-property start (point) 'keymap shr-image-map)
(put-text-property start (point) 'shr-alt alt)
(put-text-property start (point) 'image-url url)
+ (put-text-property start (point) 'image-dom-size (cons width height))
(put-text-property start (point) 'image-displayer
(shr-image-displayer shr-content-function))
(put-text-property start (point) 'help-echo
diff --git a/lisp/org/ob-processing.el b/lisp/org/ob-processing.el
index 2733b1d1f6d..f7326f0eea7 100644
--- a/lisp/org/ob-processing.el
+++ b/lisp/org/ob-processing.el
@@ -56,7 +56,6 @@
(org-assert-version)
(require 'ob)
-(require 'sha1)
(declare-function processing-sketch-run "ext:processing-mode" ())
diff --git a/lisp/org/org-feed.el b/lisp/org/org-feed.el
index 4077afa0d3c..c90174f0fa7 100644
--- a/lisp/org/org-feed.el
+++ b/lisp/org/org-feed.el
@@ -92,7 +92,6 @@
(org-assert-version)
(require 'org)
-(require 'sha1)
(declare-function url-retrieve-synchronously "url"
(url &optional silent inhibit-cookies timeout))
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index e8d1e692d0f..d2d0baa235c 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -827,15 +827,23 @@ The value depends on `grep-command', `grep-template',
(unless grep-find-use-xargs
(setq grep-find-use-xargs
(cond
- ((grep-probe find-program
- `(nil nil nil ,(null-device) "-exec" "echo"
- "{}" "+"))
- 'exec-plus)
+ ;; For performance, we want:
+ ;; A. Run grep on batches of files (instead of one grep per file)
+ ;; B. If the directory is large and we need multiple batches,
+ ;; run find in parallel with a running grep.
+ ;; "find | xargs grep" gives both A and B
((and
+ (not (eq system-type 'windows-nt))
(grep-probe
find-program `(nil nil nil ,(null-device) "-print0"))
(grep-probe xargs-program '(nil nil nil "-0" "echo")))
'gnu)
+ ;; "find -exec {} +" gives A but not B
+ ((grep-probe find-program
+ `(nil nil nil ,(null-device) "-exec" "echo"
+ "{}" "+"))
+ 'exec-plus)
+ ;; "find -exec {} ;" gives neither A nor B.
(t
'exec))))
(unless grep-find-command
diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el
index 8d0f49c2d89..06daadbc1fd 100644
--- a/lisp/progmodes/lua-ts-mode.el
+++ b/lisp/progmodes/lua-ts-mode.el
@@ -722,10 +722,10 @@ Calls REPORT-FN directly."
(defvar lua-ts-mode-map
(let ((map (make-sparse-keymap "Lua")))
- (define-key map "\C-c\C-n" 'lua-ts-inferior-lua)
- (define-key map "\C-c\C-c" 'lua-ts-send-buffer)
- (define-key map "\C-c\C-l" 'lua-ts-send-file)
- (define-key map "\C-c\C-r" 'lua-ts-send-region)
+ (keymap-set map "C-c C-n" 'lua-ts-inferior-lua)
+ (keymap-set map "C-c C-c" 'lua-ts-send-buffer)
+ (keymap-set map "C-c C-l" 'lua-ts-send-file)
+ (keymap-set map "C-c C-r" 'lua-ts-send-region)
map)
"Keymap for `lua-ts-mode' buffers.")
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 68685fb6625..ff71970d41b 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -1130,14 +1130,7 @@ Returns (parse-state) if line starts inside a string."
;; add the perl-brace-imaginary-offset.
(progn (skip-chars-backward " \t")
(if (bolp) 0 perl-brace-imaginary-offset))
- ;; If the openbrace is preceded by a parenthesized exp,
- ;; move to the beginning of that;
- ;; possibly a different line
- (progn
- (if (eq (preceding-char) ?\))
- (forward-sexp -1))
- ;; Get initial indentation of the line we are on.
- (current-indentation)))))))))
+ (perl-indent-new-calculate 'virtual))))))))
(defun perl-backward-to-noncomment ()
"Move point backward to after the first non-white-space, skipping comments."
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 89eefd1f08a..73d6bdd2d2d 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -7042,6 +7042,7 @@ Add import for undefined name `%s' (empty to skip): "
(defvar electric-indent-inhibit)
(defvar prettify-symbols-alist)
+(defvar python--installed-grep-hook nil)
;;;###autoload
(define-derived-mode python-base-mode prog-mode "Python"
@@ -7126,6 +7127,15 @@ implementations: `python-mode' and `python-ts-mode'."
"`outline-level' function for Python mode."
(1+ (/ (current-indentation) python-indent-offset))))
+ (unless python--installed-grep-hook
+ (setq python--installed-grep-hook t)
+ (with-eval-after-load 'grep
+ (defvar grep-files-aliases)
+ (defvar grep-find-ignored-directories)
+ (cl-pushnew '("py" . "*.py") grep-files-aliases :test #'equal)
+ (dolist (dir '(".tox" ".venv" ".mypy_cache" ".ruff_cache"))
+ (cl-pushnew dir grep-find-ignored-directories))))
+
(setq-local prettify-symbols-alist python-prettify-symbols-alist)
(make-local-variable 'python-shell-internal-buffer)
diff --git a/lisp/subr.el b/lisp/subr.el
index ab388630a91..36b5353b577 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3338,7 +3338,15 @@ only unbound fallback disabled is downcasing of the last event."
;; though read-key-sequence thinks we should wait
;; for more input to decide how to interpret the
;; current input.
- (throw 'read-key keys)))))))
+ ;;
+ ;; As this treatment will completely defeat the
+ ;; purpose of touch screen event conversion,
+ ;; dispense with this timeout when the first
+ ;; event in this vector is a touch-screen event.
+ (unless (memq (car-safe (aref keys 0)) '(touchscreen-begin
+ touchscreen-update
+ touchscreen-end))
+ (throw 'read-key keys))))))))
(unwind-protect
(progn
(use-global-map
diff --git a/lisp/textmodes/reftex-global.el b/lisp/textmodes/reftex-global.el
index 0eaffec3b54..7b4407ec336 100644
--- a/lisp/textmodes/reftex-global.el
+++ b/lisp/textmodes/reftex-global.el
@@ -152,7 +152,7 @@ No active TAGS table is required."
(setq dlist (reftex-uniquify-by-car dlist))
(if (null dlist) (error "No duplicate labels in document"))
(switch-to-buffer-other-window "*Duplicate Labels*")
- (set (make-local-variable 'TeX-master) master)
+ (setq-local TeX-master master)
(erase-buffer)
(insert " MULTIPLE LABELS IN CURRENT DOCUMENT:\n")
(insert
@@ -492,17 +492,16 @@ With no argument, this command toggles
(with-current-buffer crt-buf
(when reftex-mode
(if (boundp 'multi-isearch-next-buffer-function)
- (set (make-local-variable
- 'multi-isearch-next-buffer-function)
- #'reftex-isearch-switch-to-next-file)
- (set (make-local-variable 'isearch-wrap-function)
- #'reftex-isearch-wrap-function)
- (set (make-local-variable 'isearch-search-fun-function)
- (lambda () #'reftex-isearch-isearch-search))
- (set (make-local-variable 'isearch-push-state-function)
- #'reftex-isearch-push-state-function)
- (set (make-local-variable 'isearch-next-buffer-function)
- #'reftex-isearch-switch-to-next-file))
+ (setq-local multi-isearch-next-buffer-function
+ #'reftex-isearch-switch-to-next-file)
+ (setq-local isearch-wrap-function
+ #'reftex-isearch-wrap-function)
+ (setq-local isearch-search-fun-function
+ (lambda () #'reftex-isearch-isearch-search))
+ (setq-local isearch-push-state-function
+ #'reftex-isearch-push-state-function)
+ (setq-local isearch-next-buffer-function
+ #'reftex-isearch-switch-to-next-file))
(setq reftex-isearch-minor-mode t))))
(add-hook 'reftex-mode-hook #'reftex-isearch-minor-mode))
(dolist (crt-buf (buffer-list))
diff --git a/lisp/textmodes/reftex-index.el b/lisp/textmodes/reftex-index.el
index a93afd63855..db476ff5c0b 100644
--- a/lisp/textmodes/reftex-index.el
+++ b/lisp/textmodes/reftex-index.el
@@ -387,9 +387,9 @@ Press `?' for a summary of important key bindings, or check the menu.
Here are all local bindings.
\\{reftex-index-mode-map}"
- (set (make-local-variable 'revert-buffer-function) #'reftex-index-revert)
- (set (make-local-variable 'reftex-index-restriction-data) nil)
- (set (make-local-variable 'reftex-index-restriction-indicator) nil)
+ (setq-local revert-buffer-function #'reftex-index-revert)
+ (setq-local reftex-index-restriction-data nil)
+ (setq-local reftex-index-restriction-indicator nil)
(setq mode-line-format
(list "---- " 'mode-line-buffer-identification
" " 'global-mode-string
@@ -511,9 +511,9 @@ With prefix 3, restrict index to region."
;; If the buffer is currently restricted, empty it to force update.
(when reftex-index-restriction-data
(reftex-erase-buffer))
- (set (make-local-variable 'reftex-last-index-file) calling-file)
- (set (make-local-variable 'reftex-index-tag) index-tag)
- (set (make-local-variable 'reftex-docstruct-symbol) docstruct-symbol)
+ (setq-local reftex-last-index-file calling-file)
+ (setq-local reftex-index-tag index-tag)
+ (setq-local reftex-docstruct-symbol docstruct-symbol)
(if restriction
(setq reftex-index-restriction-indicator (car restriction)
reftex-index-restriction-data (cdr restriction))
@@ -1303,8 +1303,7 @@ If the buffer is non-empty, delete the old header first."
(lambda (a _b) (equal (car a) default-macro))))
macro entry key repeat)
- (if master (set (make-local-variable 'TeX-master)
- (file-name-nondirectory master)))
+ (when master (setq-local TeX-master (file-name-nondirectory master)))
(when (> (buffer-size) 0)
(goto-char 1)
@@ -1387,9 +1386,9 @@ Here are all local bindings.
\\{reftex-index-phrases-mode-map}"
:syntax-table reftex-index-phrases-syntax-table
- (set (make-local-variable 'font-lock-defaults)
- reftex-index-phrases-font-lock-defaults)
- (set (make-local-variable 'reftex-index-phrases-marker) (make-marker)))
+ (setq-local font-lock-defaults
+ reftex-index-phrases-font-lock-defaults)
+ (setq-local reftex-index-phrases-marker (make-marker)))
;; (add-hook 'reftex-index-phrases-mode-hook #'turn-on-font-lock)
(defun reftex-index-next-phrase (&optional arg)
diff --git a/lisp/textmodes/reftex-sel.el b/lisp/textmodes/reftex-sel.el
index fa36543daf4..aec89448481 100644
--- a/lisp/textmodes/reftex-sel.el
+++ b/lisp/textmodes/reftex-sel.el
@@ -97,7 +97,7 @@ Press `?' for a summary of important key bindings.
During a selection process, these are the local bindings.
\\{reftex-select-label-mode-map}"
- (set (make-local-variable 'reftex-select-marked) nil)
+ (setq-local reftex-select-marked nil)
(when (syntax-table-p reftex-latex-syntax-table)
(set-syntax-table reftex-latex-syntax-table))
;; We do not set a local map - reftex-select-item does this.
@@ -136,7 +136,7 @@ Press `?' for a summary of important key bindings.
During a selection process, these are the local bindings.
\\{reftex-select-label-mode-map}"
- (set (make-local-variable 'reftex-select-marked) nil)
+ (setq-local reftex-select-marked nil)
;; We do not set a local map - reftex-select-item does this.
)
@@ -236,9 +236,9 @@ During a selection process, these are the local bindings.
(concat "\\`" (regexp-quote
(file-name-directory (reftex-TeX-master-file))))))
- (set (make-local-variable 'reftex-docstruct-symbol) docstruct-symbol)
- (set (make-local-variable 'reftex-prefix)
- (cdr (assoc labels reftex-typekey-to-prefix-alist)))
+ (setq-local reftex-docstruct-symbol docstruct-symbol)
+ (setq-local reftex-prefix
+ (cdr (assoc labels reftex-typekey-to-prefix-alist)))
(if (equal reftex-prefix " ") (setq reftex-prefix nil))
;; Walk the docstruct and insert the appropriate stuff
@@ -459,7 +459,7 @@ During a selection process, these are the local bindings.
(reftex-find-start-point
(point-min) offset reftex-last-data reftex-last-line)
(beginning-of-line 1)
- (set (make-local-variable 'reftex-last-follow-point) (point))
+ (setq-local reftex-last-follow-point (point))
(unwind-protect
(progn
@@ -480,9 +480,9 @@ During a selection process, these are the local bindings.
(mapc (lambda (c) (delete-overlay (nth 1 c)))
reftex-select-marked)))))
- (set (make-local-variable 'reftex-last-line)
- (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))
- (set (make-local-variable 'reftex-last-data) reftex--last-data)
+ (setq-local reftex-last-line
+ (+ (count-lines (point-min) (point)) (if (bolp) 1 0)))
+ (setq-local reftex-last-data reftex--last-data)
(reftex-kill-buffer "*RefTeX Help*")
(setq reftex-callback-fwd (not reftex-callback-fwd)) ;; ;-)))
(message "")
diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el
index 1cc6e27e780..fe5a32f15f0 100644
--- a/lisp/textmodes/reftex-toc.el
+++ b/lisp/textmodes/reftex-toc.el
@@ -1,6 +1,6 @@
;;; reftex-toc.el --- RefTeX's table of contents mode -*- lexical-binding: t; -*-
-;; Copyright (C) 1997-2000, 2003-2024 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2024 Free Software Foundation, Inc.
;; Author: Carsten Dominik <dominik@science.uva.nl>
;; Maintainer: auctex-devel@gnu.org
@@ -125,13 +125,13 @@ Press `?' for a summary of important key bindings.
Here are all local bindings.
\\{reftex-toc-mode-map}"
- (set (make-local-variable 'transient-mark-mode) t)
- (set (make-local-variable 'revert-buffer-function) #'reftex-toc-revert)
- (set (make-local-variable 'reftex-toc-include-labels-indicator) "")
- (set (make-local-variable 'reftex-toc-max-level-indicator)
- (if (= reftex-toc-max-level 100)
- "ALL"
- (int-to-string reftex-toc-max-level)))
+ (setq-local transient-mark-mode t)
+ (setq-local revert-buffer-function #'reftex-toc-revert)
+ (setq-local reftex-toc-include-labels-indicator "")
+ (setq-local reftex-toc-max-level-indicator
+ (if (= reftex-toc-max-level 100)
+ "ALL"
+ (int-to-string reftex-toc-max-level)))
(setq mode-line-format
(list "---- " 'mode-line-buffer-identification
" " 'global-mode-string " (" mode-name ")"
@@ -241,7 +241,7 @@ When called with a raw \\[universal-argument] prefix, rescan the document first.
(switch-to-buffer "*toc*"))
(or (eq major-mode 'reftex-toc-mode) (reftex-toc-mode))
- (set (make-local-variable 'reftex-docstruct-symbol) docstruct-symbol)
+ (setq-local reftex-docstruct-symbol docstruct-symbol)
(setq reftex-toc-include-labels-indicator
(if (eq reftex-toc-include-labels t)
"ALL"
diff --git a/lisp/textmodes/reftex.el b/lisp/textmodes/reftex.el
index 6974a4be4a7..efe38337001 100644
--- a/lisp/textmodes/reftex.el
+++ b/lisp/textmodes/reftex.el
@@ -1,6 +1,6 @@
;;; reftex.el --- minor mode for doing \label, \ref, \cite, \index in LaTeX -*- lexical-binding: t; -*-
-;; Copyright (C) 1997-2000, 2003-2024 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2024 Free Software Foundation, Inc.
;; Author: Carsten Dominik <dominik@science.uva.nl>
;; Maintainer: auctex-devel@gnu.org
@@ -2036,8 +2036,8 @@ IGNORE-WORDS List of words which should be removed from the string."
;; of font-lock)
(rename-buffer newname t)
;; Good: we have the indirection functions
- (set (make-local-variable 'font-lock-fontify-region-function)
- #'reftex-select-font-lock-fontify-region)
+ (setq-local font-lock-fontify-region-function
+ #'reftex-select-font-lock-fontify-region)
(let ((major-mode 'latex-mode))
(font-lock-mode 1)))
(rename-buffer oldname))))
diff --git a/lisp/textmodes/rst.el b/lisp/textmodes/rst.el
index 5fbff4ba888..1e09d3a6eb6 100644
--- a/lisp/textmodes/rst.el
+++ b/lisp/textmodes/rst.el
@@ -102,7 +102,6 @@
;; FIXME: Embed complicated `defconst's in `eval-when-compile'.
-;; Common Lisp stuff
(require 'cl-lib)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index c5918efb800..57eff075e73 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -157,13 +157,22 @@ dragging.")
;; Should this variable be documented?
(defvar-local touch-screen-keyboard-function nil
"Function that decides whether to display the on screen keyboard.
-If set, this function is called with point set to the position of the
-tap involved when a command listed in `touch-screen-set-point-commands'
-is about to be invoked in response to a tap, the current buffer, or the
-text beneath point (in the case of an `inhibit-read-only' text
-property), is not read only, and `touch-screen-display-keyboard' is nil,
-and should return non-nil if it is appropriate to display the on-screen
-keyboard afterwards.")
+If set, this function is called with point set to the position
+of the tap involved when a command listed in
+`touch-screen-set-point-commands' is about to be invoked in
+response to a tap, the current buffer, or the text beneath
+point (in the case of an `inhibit-read-only' text property), is
+not read only, and `touch-screen-display-keyboard' is nil, and
+should return non-nil if it is appropriate to display the
+on-screen keyboard afterwards.")
+
+(defvar touch-screen-simple-mouse-conversion nil
+ "Whether to unconditionally enable simple mouse event translation.
+If non-nil, touch screen event conversion will always proceed as
+though a command was bound to `down-mouse-1' at the position of
+the initial tap. That is to say, taps, mouse motion, and
+touchpoint removals will be unconditionally converted into
+mouse-down, mouse motion, mouse drag, and mouse button events.")
@@ -1418,36 +1427,27 @@ is not read-only."
(new-point (posn-point posn))
(old-posn (nth 4 touch-screen-current-tool))
(old-window (posn-window posn))
- (old-point (posn-point posn)))
+ (old-point (posn-point posn))
+ (new-relative-xy (touch-screen-relative-xy
+ posn new-window))
+ (old-relative-xy (touch-screen-relative-xy
+ old-posn new-window)))
(throw 'input-event
- ;; If the position of the touch point hasn't
- ;; changed, or it doesn't start or end on a
- ;; window...
- (if (and (not old-point) (not new-point))
- ;; Should old-point and new-point both equal
- ;; nil, compare the posn areas and nominal
- ;; column position. If either are
- ;; different, generate a drag event.
- (let ((new-col-row (posn-col-row posn))
- (new-area (posn-area posn))
- (old-col-row (posn-col-row old-posn))
- (old-area (posn-area old-posn)))
- (if (and (equal new-col-row old-col-row)
- (eq new-area old-area))
- ;; ... generate a mouse-1 event...
- (list 'mouse-1 posn)
- ;; ... otherwise, generate a
- ;; drag-mouse-1 event.
- (list 'drag-mouse-1 old-posn posn)))
- (if (and (eq new-window old-window)
- (eq new-point old-point)
- (windowp new-window)
- (windowp old-window))
- ;; ... generate a mouse-1 event...
- (list 'mouse-1 posn)
- ;; ... otherwise, generate a drag-mouse-1
- ;; event.
- (list 'drag-mouse-1 old-posn posn)))))))
+ ;; If the position of the touch point has
+ ;; changed, or it has moved significantly, as
+ ;; measured by reference to double-click-fuzz...
+ (if (or (let ((xdiff (- (car new-relative-xy)
+ (car old-relative-xy)))
+ (ydiff (- (cdr new-relative-xy)
+ (cdr old-relative-xy))))
+ (and (>= (abs xdiff) double-click-fuzz)
+ (>= (abs ydiff) double-click-fuzz)))
+ (not (eq old-window new-window))
+ (not (eq old-point new-point)))
+ ;; ... generate a drag-mouse-1 event...
+ (list 'drag-mouse-1 old-posn posn)
+ ;; ... otherwise, generate a mouse-1 event.
+ (list 'mouse-1 posn))))))
((eq what 'mouse-1-menu)
;; Generate a `down-mouse-1' event at the position the tap
;; took place, unless the touch sequence was canceled.
@@ -1633,29 +1633,35 @@ functions undertaking event management themselves to call
;; Generate the `restart-drag' event.
(throw 'input-event (list 'touchscreen-restart-drag
position))))
- ;; Determine if there is a command bound to `down-mouse-1'
- ;; at the position of the tap and that command is not a
- ;; command whose functionality is replaced by the
- ;; long-press mechanism. If so, set the fourth element of
- ;; `touch-screen-current-tool' to `mouse-drag' and
- ;; generate an emulated `mouse-1' event.
+ ;; Determine whether there is a command bound to
+ ;; `down-mouse-1' at the position of the tap and that
+ ;; command is not a command whose functionality is replaced
+ ;; by the long-press mechanism. If so, set the fourth
+ ;; element of `touch-screen-current-tool' to `mouse-drag'
+ ;; and generate an emulated `mouse-1' event. Likewise if
+ ;; touch event translation is being invoked by a caller of
+ ;; `read-key' that expects unprocessed mouse input,
;;
- ;; If the command in question is a keymap, set that
- ;; element to `mouse-1-menu' instead of `mouse-drag', and
- ;; don't generate a `down-mouse-1' event immediately.
- ;; Instead, wait for the touch point to be released.
+ ;; If the command in question is a keymap, set that element
+ ;; to `mouse-1-menu' instead of `mouse-drag', and don't
+ ;; generate a `down-mouse-1' event immediately, but wait for
+ ;; the touch point to be released, so that the menu bar may
+ ;; not be displayed before the user has released the touch
+ ;; point and the window system is ready to display a menu.
(if (and tool-list
- (and (setq binding
- (key-binding (if prefix
- (vector prefix
- 'down-mouse-1)
- [down-mouse-1])
- t nil position))
- (not (and (symbolp binding)
- (get binding 'ignored-mouse-command)))))
- (if (or (keymapp binding)
- (and (symbolp binding)
- (get binding 'mouse-1-menu-command)))
+ (or (and (setq binding
+ (key-binding (if prefix
+ (vector prefix
+ 'down-mouse-1)
+ [down-mouse-1])
+ t nil position))
+ (not (and (symbolp binding)
+ (get binding 'ignored-mouse-command))))
+ touch-screen-simple-mouse-conversion))
+ (if (and (not touch-screen-simple-mouse-conversion)
+ (or (keymapp binding)
+ (and (symbolp binding)
+ (get binding 'mouse-1-menu-command))))
;; binding is a keymap, or a command that does
;; almost the same thing. If a `mouse-1' event is
;; generated after the keyboard command loop
diff --git a/lisp/version.el b/lisp/version.el
index a84f7f161f0..db2afd55694 100644
--- a/lisp/version.el
+++ b/lisp/version.el
@@ -28,26 +28,31 @@
+;; If either of the files examined by the following two functions does
+;; not exist, Emacs was configured `--disable-build-details'.
+
(defun android-read-build-system ()
"Obtain the host name of the system on which Emacs was built.
Use the data stored in the special file `/assets/build_info'.
Value is the string ``Unknown'' upon failure, else the hostname
of the build system."
- (with-temp-buffer
- (insert-file-contents "/assets/build_info")
- (let ((string (buffer-substring 1 (line-end-position))))
- (and (not (equal string "Unknown")) string))))
+ (when (file-exists-p "/assets/build_info")
+ (with-temp-buffer
+ (insert-file-contents "/assets/build_info")
+ (let ((string (buffer-substring 1 (line-end-position))))
+ (and (not (equal string "Unknown")) string)))))
(defun android-read-build-time ()
"Obtain the time at which Emacs was built.
Use the data stored in the special file `/assets/build_info'.
Value is nil upon failure, else the time in the same format as
returned by `current-time'."
- (with-temp-buffer
- (insert-file-contents "/assets/build_info")
- (end-of-line)
- (let ((number (read (current-buffer))))
- (time-convert number 'list))))
+ (when (file-exists-p "/assets/build_info")
+ (with-temp-buffer
+ (insert-file-contents "/assets/build_info")
+ (end-of-line)
+ (let ((number (read (current-buffer))))
+ (time-convert number 'list)))))
diff --git a/lisp/whitespace.el b/lisp/whitespace.el
index bc23a8794eb..28d131b054c 100644
--- a/lisp/whitespace.el
+++ b/lisp/whitespace.el
@@ -1465,6 +1465,11 @@ The problems cleaned up are:
If `whitespace-style' includes the value
`space-after-tab::space', replace TABs by SPACEs.
+5. missing newline at end of file.
+ If `whitespace-style' includes the value `missing-newline-at-eof',
+ and the cleanup region includes the end of file, add a final newline
+ if it is not there already.
+
See `whitespace-style', `indent-tabs-mode' and `tab-width' for
documentation."
(interactive "@r")
@@ -1545,7 +1550,16 @@ documentation."
((memq 'space-before-tab::space whitespace-style)
(whitespace-replace-action
'untabify rstart rend
- whitespace-space-before-tab-regexp 2))))
+ whitespace-space-before-tab-regexp 2)))
+ ;; PROBLEM 5: missing newline at end of file
+ (and (memq 'missing-newline-at-eof whitespace-style)
+ (> (point-max) (point-min))
+ (= (point-max) (without-restriction (point-max)))
+ (/= (char-before (point-max)) ?\n)
+ (not (and (eq selective-display t)
+ (= (char-before (point-max)) ?\r)))
+ (goto-char (point-max))
+ (ignore-errors (insert "\n"))))
(set-marker rend nil)))) ; point marker to nowhere
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index b63391a6ad7..ec7aac47089 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,5 +1,5 @@
# canonicalize.m4
-# serial 39
+# serial 40
dnl Copyright (C) 2003-2007, 2009-2024 Free Software Foundation, Inc.
@@ -113,7 +113,7 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
result |= 2;
free (name);
}
- /* This test fails on Cygwin 2.9. */
+ /* This test fails on macOS 14, Cygwin 2.9. */
#if HAVE_LSTAT
{
char *name = realpath ("conftest.l/../conftest.a", NULL);
@@ -122,7 +122,7 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
free (name);
}
#endif
- /* This test fails on Mac OS X 10.13, OpenBSD 6.0. */
+ /* This test fails on macOS 14, OpenBSD 6.0. */
{
char *name = realpath ("conftest.a/", NULL);
if (name != NULL)
@@ -163,6 +163,8 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
*-gnu* | gnu*) gl_cv_func_realpath_works="guessing yes" ;;
# Guess 'nearly' on musl systems.
*-musl*) gl_cv_func_realpath_works="guessing nearly" ;;
+ # Guess no on macOS.
+ darwin*) gl_cv_func_realpath_works="guessing no" ;;
# Guess no on Cygwin.
cygwin*) gl_cv_func_realpath_works="guessing no" ;;
# Guess no on native Windows.
diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4
index 9af4b3a9fc8..6c49edac932 100644
--- a/m4/gnulib-comp.m4
+++ b/m4/gnulib-comp.m4
@@ -1646,7 +1646,6 @@ AC_DEFUN([gl_FILE_LIST], [
m4/vararrays.m4
m4/warn-on-use.m4
m4/warnings.m4
- m4/wchar_t.m4
m4/wint_t.m4
m4/xattr.m4
m4/zzgnulib.m4
diff --git a/m4/largefile.m4 b/m4/largefile.m4
index 2f824089b0a..28813483594 100644
--- a/m4/largefile.m4
+++ b/m4/largefile.m4
@@ -1,5 +1,5 @@
# largefile.m4
-# serial 1
+# serial 2
dnl Copyright 1992-1996, 1998-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -88,7 +88,7 @@ m4_define([_AC_SYS_YEAR2038_OPTIONS], m4_normalize(
# If you change this macro you may also need to change
# _AC_SYS_YEAR2038_OPTIONS.
AC_DEFUN([_AC_SYS_YEAR2038_PROBE],
-[AC_CACHE_CHECK([for $CPPFLAGS option for timestamps after 2038],
+[AC_CACHE_CHECK([for $CC option to support timestamps after 2038],
[ac_cv_sys_year2038_opts],
[ac_save_CPPFLAGS="$CPPFLAGS"
ac_opt_found=no
@@ -234,7 +234,7 @@ m4_define([_AC_SYS_LARGEFILE_OPTIONS], m4_normalize(
# If you change this macro you may also need to change
# _AC_SYS_LARGEFILE_OPTIONS.
AC_DEFUN([_AC_SYS_LARGEFILE_PROBE],
-[AC_CACHE_CHECK([for $CPPFLAGS option for large files],
+[AC_CACHE_CHECK([for $CC option to support large files],
[ac_cv_sys_largefile_opts],
[ac_save_CPPFLAGS=$CPPFLAGS
ac_opt_found=no
diff --git a/m4/ndk-build.m4 b/m4/ndk-build.m4
index f86d4e4fc1e..a561c7c849d 100644
--- a/m4/ndk-build.m4
+++ b/m4/ndk-build.m4
@@ -143,22 +143,35 @@ ndk_resolve_import_module () {
ndk_module=[$]1
AC_MSG_CHECKING([for imported $ndk_module])
+ AC_CACHE_VAL([AS_TR_SH([ndk_cv_commands_$ndk_module])],
+ [for ndk_android_mk in $ndk_module_files; do
+ # Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in
+ # tree build system sets it to a meaningful value, but build files
+ # just use it to test whether or not the NDK is being used.
+ ndk_commands=`ndk_run_test`
+ eval "$ndk_commands"
+
+ if test -n "$module_name"; then
+ # Guarantee that evaluation of the cached value will also set
+ # `ndk_android_mk'.
+ ndk_commands="$ndk_commands ndk_android_mk=$ndk_android_mk"
+ break;
+ fi
+ done
+ AS_IF([test -z "$module_name"],
+ [AS_VAR_SET([AS_TR_SH([ndk_cv_commands_$ndk_module])],
+ [""])],
+ [AS_VAR_SET([AS_TR_SH([ndk_cv_commands_$ndk_module])],
+ [$ndk_commands])])])
+
+ # Copy the computed value into ndk_commands.
+ AS_VAR_COPY([ndk_commands], [AS_TR_SH([ndk_cv_commands_$ndk_module])])
+ eval "$ndk_commands"
- for ndk_android_mk in $ndk_module_files; do
- # Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in
- # tree build system sets it to a meaningful value, but build files
- # just use it to test whether or not the NDK is being used.
- ndk_commands=`ndk_run_test`
- eval "$ndk_commands"
-
- if test -n "$module_name"; then
- break;
- fi
- done
-
- AS_IF([test -z "$module_name"],
+ # Print the outcome of the test.
+ AS_IF([test -n "$module_name"], [AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])
- AC_MSG_ERROR([The module currently being built depends on [$]1, but \
+ AC_MSG_ERROR([The module currently being built has imported [$]1, but \
that could not be found in the list of directories specified in \
`--with-ndk-path'.])])
@@ -175,8 +188,6 @@ but none were found.])])
[AC_MSG_ERROR([The module [$]1 requires the C++ standard library,
but a working C++ compiler was not found.])])
- AC_MSG_RESULT([yes])
-
# Make sure the module is prepended.
ndk_MODULES="$ndk_MODULES $module_target"
ndk_MAKEFILES="$ndk_android_mk $ndk_MAKEFILES"
@@ -552,19 +563,28 @@ AC_DEFUN([ndk_SEARCH_MODULE],
module_name=
ndk_module=$1
ndk_replace_pkg_config_package
-AC_MSG_CHECKING([for Android.mk that builds $ndk_module])
-
-for ndk_android_mk in $ndk_module_files; do
- # Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in
- # tree build system sets it to a meaning value, but build files just
- # use it to test whether or not the NDK is being used.
- ndk_commands=`ndk_run_test`
-
- eval "$ndk_commands"
- if test -n "$module_name"; then
- break;
- fi
-done
+AC_MSG_CHECKING([for Android.mk providing $ndk_module])
+AC_CACHE_VAL([AS_TR_SH([ndk_cv_commands_$ndk_module])],
+ [for ndk_android_mk in $ndk_module_files; do
+ # Read this Android.mk file. Set NDK_ROOT to /tmp: the Android in
+ # tree build system sets it to a meaningful value, but build files
+ # just use it to test whether or not the NDK is being used.
+ ndk_commands=`ndk_run_test`
+ eval "$ndk_commands"
+
+ if test -n "$module_name"; then
+ # Guarantee that evaluation of the cached value will also set
+ # `ndk_android_mk'.
+ ndk_commands="$ndk_commands ndk_android_mk=$ndk_android_mk"
+ break;
+ fi
+ done
+ AS_IF([test -n "$module_name"],
+ [AS_VAR_SET([AS_TR_SH([ndk_cv_commands_$ndk_module])],
+ [$ndk_commands])],
+ [AS_VAR_SET([AS_TR_SH([ndk_cv_commands_$ndk_module])], [])])])
+AS_VAR_COPY([ndk_commands], [AS_TR_SH([ndk_cv_commands_$ndk_module])])
+eval "$ndk_commands"
if test -z "$module_name"; then
AC_MSG_RESULT([no])
diff --git a/m4/nstrftime.m4 b/m4/nstrftime.m4
index f73bca40ec1..534507d300b 100644
--- a/m4/nstrftime.m4
+++ b/m4/nstrftime.m4
@@ -1,5 +1,5 @@
# nstrftime.m4
-# serial 38
+# serial 40
dnl Copyright (C) 1996-1997, 1999-2007, 2009-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -11,8 +11,6 @@ AC_DEFUN([gl_FUNC_GNU_STRFTIME],
[
AC_REQUIRE([AC_C_RESTRICT])
- # This defines (or not) HAVE_TZNAME and HAVE_STRUCT_TM_TM_ZONE.
- AC_REQUIRE([AC_STRUCT_TIMEZONE])
-
AC_REQUIRE([gl_TM_GMTOFF])
+ AC_CHECK_FUNCS_ONCE([strftime_z])
])
diff --git a/m4/printf-posix-rpl.m4 b/m4/printf-posix-rpl.m4
deleted file mode 100644
index 0f741192499..00000000000
--- a/m4/printf-posix-rpl.m4
+++ /dev/null
@@ -1,26 +0,0 @@
-# printf-posix-rpl.m4 serial 4
-dnl Copyright (C) 2007-2024 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-AC_DEFUN([gl_FUNC_PRINTF_POSIX],
-[
- AC_REQUIRE([gl_FUNC_VFPRINTF_POSIX])
- if test $gl_cv_func_vfprintf_posix = no; then
- gl_REPLACE_PRINTF
- fi
-])
-
-AC_DEFUN([gl_REPLACE_PRINTF],
-[
- AC_REQUIRE([gl_STDIO_H_DEFAULTS])
- AC_REQUIRE([gl_ASM_SYMBOL_PREFIX])
- AC_LIBOBJ([printf])
- REPLACE_PRINTF=1
- AC_DEFINE([REPLACE_PRINTF_POSIX], [1],
- [Define if printf is overridden by a POSIX compliant gnulib implementation.])
- gl_PREREQ_PRINTF
-])
-
-AC_DEFUN([gl_PREREQ_PRINTF], [:])
diff --git a/m4/readlinkat.m4 b/m4/readlinkat.m4
index 1f091e8b636..4c4e3588e0a 100644
--- a/m4/readlinkat.m4
+++ b/m4/readlinkat.m4
@@ -1,5 +1,5 @@
# readlinkat.m4
-# serial 9
+# serial 10
dnl Copyright (C) 2009-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -34,7 +34,7 @@ AC_DEFUN([gl_FUNC_READLINKAT],
[gl_cv_decl_readlinkat_works=no])
])
# Assume readlinkat has the same bugs as readlink,
- # as is the case on OS X 10.10 with trailing slashes.
+ # as is the case on macOS 14 with trailing slashes.
case $gl_cv_decl_readlinkat_works,$gl_cv_func_readlink_trailing_slash,$gl_cv_func_readlink_truncate in
*yes,*yes,*yes)
;;
diff --git a/m4/stddef_h.m4 b/m4/stddef_h.m4
index 998fe12fa83..c7f75b37fa0 100644
--- a/m4/stddef_h.m4
+++ b/m4/stddef_h.m4
@@ -1,5 +1,5 @@
# stddef_h.m4
-# serial 16
+# serial 17
dnl Copyright (C) 2009-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -10,7 +10,6 @@ dnl A placeholder for <stddef.h>, for platforms that have issues.
AC_DEFUN_ONCE([gl_STDDEF_H],
[
AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
- AC_REQUIRE([gt_TYPE_WCHAR_T])
dnl Persuade OpenBSD <stddef.h> to declare max_align_t.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
@@ -52,11 +51,6 @@ AC_DEFUN_ONCE([gl_STDDEF_H],
GL_GENERATE_STDDEF_H=true
fi
- if test $gt_cv_c_wchar_t = no; then
- HAVE_WCHAR_T=0
- GL_GENERATE_STDDEF_H=true
- fi
-
AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
[gl_cv_decl_null_works],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>
@@ -148,5 +142,4 @@ AC_DEFUN([gl_STDDEF_H_DEFAULTS],
STDDEF_NOT_IDEMPOTENT=0; AC_SUBST([STDDEF_NOT_IDEMPOTENT])
REPLACE_NULL=0; AC_SUBST([REPLACE_NULL])
HAVE_MAX_ALIGN_T=1; AC_SUBST([HAVE_MAX_ALIGN_T])
- HAVE_WCHAR_T=1; AC_SUBST([HAVE_WCHAR_T])
])
diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4
index 8eb5816ad7e..10e1fbb8aa9 100644
--- a/m4/stdio_h.m4
+++ b/m4/stdio_h.m4
@@ -1,5 +1,5 @@
# stdio_h.m4
-# serial 63
+# serial 69
dnl Copyright (C) 2007-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -159,6 +159,7 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_GETLINE])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_PRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_OBSTACK_ZPRINTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PCLOSE])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_PERROR])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_POPEN])
@@ -177,6 +178,7 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_STDIO_H_SIGPIPE])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TMPFILE])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VASPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VAZSPRINTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VFSCANF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSCANF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VDPRINTF])
@@ -186,6 +188,10 @@ AC_DEFUN([gl_STDIO_H_REQUIRE_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VPRINTF_POSIX])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSNPRINTF])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VSPRINTF_POSIX])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VZSNPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_VZSPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ZSNPRINTF])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_ZSPRINTF])
dnl Support Microsoft deprecated alias function names by default.
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FCLOSEALL], [1])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_FDOPEN], [1])
diff --git a/m4/time_h.m4 b/m4/time_h.m4
index d2f3c9701cb..4ca7305792c 100644
--- a/m4/time_h.m4
+++ b/m4/time_h.m4
@@ -1,5 +1,5 @@
# time_h.m4
-# serial 25
+# serial 26
dnl Copyright (C) 2000-2001, 2003-2007, 2009-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -145,6 +145,7 @@ AC_DEFUN([gl_TIME_H_REQUIRE_DEFAULTS],
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIMESPEC_GETRES])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_R])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TIME_RZ])
+ gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZNAME])
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_TZSET])
dnl Support Microsoft deprecated alias function names by default.
gl_MODULE_INDICATOR_INIT_VARIABLE([GNULIB_MDA_TZSET], [1])
diff --git a/m4/time_rz.m4 b/m4/time_rz.m4
index 8f45f2b1d3d..9613597aca0 100644
--- a/m4/time_rz.m4
+++ b/m4/time_rz.m4
@@ -1,5 +1,5 @@
# time_rz.m4
-# serial 1
+# serial 2
dnl Copyright (C) 2015-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -13,7 +13,6 @@ AC_DEFUN([gl_TIME_RZ],
[
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_REQUIRE([gl_TIME_H_DEFAULTS])
- AC_REQUIRE([AC_STRUCT_TIMEZONE])
# On Mac OS X 10.6, localtime loops forever with some time_t values.
# See Bug#27706, Bug#27736, and
diff --git a/m4/tm_gmtoff.m4 b/m4/tm_gmtoff.m4
index 0c7dcb2a09a..3d97edb7a7f 100644
--- a/m4/tm_gmtoff.m4
+++ b/m4/tm_gmtoff.m4
@@ -1,15 +1,29 @@
# tm_gmtoff.m4
-# serial 3
+# serial 5
dnl Copyright (C) 2002, 2009-2024 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
+dnl Check for tm_gmtoff and tm_zone in struct tm, and #define
+dnl HAVE_STRUCT_TM_TM_GMTOFF and HAVE_STRUCT_TM_TM_ZONE accordingly.
+dnl Most code that needs one needs the other, so there seemed little
+dnl point to having two macros to check them individually.
+dnl Although all platforms that we know of have either both members or
+dnl neither member, check for the two members separately just in case.
+dnl
+dnl These days this macro is more useful than AC_STRUCT_TIMEZONE, which also
+dnl checks for the obsolescent tzname and does not check for tm_gmtoff.
AC_DEFUN([gl_TM_GMTOFF],
[
- AC_CHECK_MEMBER([struct tm.tm_gmtoff],
- [AC_DEFINE([HAVE_TM_GMTOFF], [1],
- [Define if struct tm has the tm_gmtoff member.])],
- ,
- [#include <time.h>])
+ AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.tm_zone], [], [],
+ [[#include <time.h>
+ ]])
+
+ dnl Backward compatibility with 2024-and-earlier versions of this macro.
+ AS_IF([test "$ac_cv_member_struct_tm_tm_gmtoff" = yes],
+ [AC_DEFINE([HAVE_TM_GMTOFF], [1],
+ [Define if struct tm has the tm_gmtoff member.
+ This macro is obsolete.
+ New code should use HAVE_STRUCT_TM_TM_GMTOFF.])])
])
diff --git a/m4/wchar_t.m4 b/m4/wchar_t.m4
deleted file mode 100644
index 968832cb296..00000000000
--- a/m4/wchar_t.m4
+++ /dev/null
@@ -1,25 +0,0 @@
-# wchar_t.m4
-# serial 4 (gettext-0.18.2)
-dnl Copyright (C) 2002-2003, 2008-2024 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-dnl Test whether <stddef.h> has the 'wchar_t' type.
-dnl Prerequisite: AC_PROG_CC
-
-AC_DEFUN([gt_TYPE_WCHAR_T],
-[
- AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t],
- [AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [[#include <stddef.h>
- wchar_t foo = (wchar_t)'\0';]],
- [[]])],
- [gt_cv_c_wchar_t=yes],
- [gt_cv_c_wchar_t=no])])
- if test $gt_cv_c_wchar_t = yes; then
- AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.])
- fi
-])
diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp
index 3c719e3f9ac..1285afeddf1 100644
--- a/msdos/sed2v2.inp
+++ b/msdos/sed2v2.inp
@@ -67,7 +67,7 @@
/^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/
/^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/
/^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/
-/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "30.0.60"/
+/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "31.0.50"/
/^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/
/^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/
/^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/
diff --git a/msdos/sedlibmk.inp b/msdos/sedlibmk.inp
index 5680126ad7a..624983798c4 100644
--- a/msdos/sedlibmk.inp
+++ b/msdos/sedlibmk.inp
@@ -269,7 +269,6 @@ s/@PACKAGE@/emacs/
/^HAVE_UNSIGNED_LONG_LONG_INT *=/s/@HAVE_UNSIGNED_LONG_LONG_INT@/1/
/^HAVE_USLEEP *=/s/@HAVE_USLEEP@/1/
/^HAVE_WCHAR_H *=/s/@HAVE_WCHAR_H@/1/
-/^HAVE_WCHAR_T *=/s/@HAVE_WCHAR_T@/1/
/^HAVE_LIBGMP *=/s/@HAVE_LIBGMP@/0/
/^HAVE__BOOL *=/s/@HAVE__BOOL@/1/
/^HAVE__EXIT *=/s/@HAVE__EXIT@/1/
diff --git a/nt/README.W32 b/nt/README.W32
index 33e252f7e01..5f33898c215 100644
--- a/nt/README.W32
+++ b/nt/README.W32
@@ -1,7 +1,7 @@
Copyright (C) 2001-2024 Free Software Foundation, Inc.
See the end of the file for license conditions.
- Emacs version 30.0.60 for MS-Windows
+ Emacs version 31.0.50 for MS-Windows
This README file describes how to set up and run a precompiled
distribution of the latest version of GNU Emacs for MS-Windows. You
diff --git a/src/emacs-module.h.in b/src/emacs-module.h.in
index 690254bd28c..21e4ca7cfa1 100644
--- a/src/emacs-module.h.in
+++ b/src/emacs-module.h.in
@@ -198,6 +198,23 @@ struct emacs_env_30
@module_env_snippet_30@
};
+struct emacs_env_31
+{
+@module_env_snippet_25@
+
+@module_env_snippet_26@
+
+@module_env_snippet_27@
+
+@module_env_snippet_28@
+
+@module_env_snippet_29@
+
+@module_env_snippet_30@
+
+@module_env_snippet_31@
+};
+
/* Every module should define a function as follows. */
extern int emacs_module_init (struct emacs_runtime *runtime)
EMACS_NOEXCEPT
diff --git a/src/emacs.c b/src/emacs.c
index 7b315310873..c85beede992 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <fcntl.h>
+#include <locale.h>
#include <stdlib.h>
#include <sys/file.h>
@@ -132,10 +133,6 @@ extern char etext;
# endif
#endif
-#ifdef HAVE_SETLOCALE
-#include <locale.h>
-#endif
-
#if HAVE_WCHAR_H
# include <wchar.h>
#endif
@@ -402,14 +399,6 @@ section of the Emacs manual or the file BUGS.\n"
/* True if handling a fatal error already. */
bool fatal_error_in_progress;
-#if !HAVE_SETLOCALE
-static char *
-setlocale (int cat, char const *locale)
-{
- return 0;
-}
-#endif
-
/* True if the current system locale uses UTF-8 encoding. */
static bool
using_utf8 (void)
@@ -3277,7 +3266,6 @@ You must run Emacs in batch mode in order to dump it. */)
#endif
-#if HAVE_SETLOCALE
/* Recover from setlocale (LC_ALL, ""). */
void
fixup_locale (void)
@@ -3297,7 +3285,7 @@ synchronize_locale (int category, Lisp_Object *plocale, Lisp_Object desired_loca
*plocale = desired_locale;
char const *locale_string
= STRINGP (desired_locale) ? SSDATA (desired_locale) : "";
-# ifdef WINDOWSNT
+#ifdef WINDOWSNT
/* Changing categories like LC_TIME usually requires specifying
an encoding suitable for the new locale, but MS-Windows's
'setlocale' will only switch the encoding when LC_ALL is
@@ -3306,9 +3294,9 @@ synchronize_locale (int category, Lisp_Object *plocale, Lisp_Object desired_loca
numbers is unaffected. */
setlocale (LC_ALL, locale_string);
fixup_locale ();
-# else /* !WINDOWSNT */
+#else
setlocale (category, locale_string);
-# endif /* !WINDOWSNT */
+#endif
}
}
@@ -3322,21 +3310,20 @@ synchronize_system_time_locale (void)
Vsystem_time_locale);
}
-# ifdef LC_MESSAGES
+#ifdef LC_MESSAGES
static Lisp_Object Vprevious_system_messages_locale;
-# endif
+#endif
/* Set system messages locale to match Vsystem_messages_locale, if
possible. */
void
synchronize_system_messages_locale (void)
{
-# ifdef LC_MESSAGES
+#ifdef LC_MESSAGES
synchronize_locale (LC_MESSAGES, &Vprevious_system_messages_locale,
Vsystem_messages_locale);
-# endif
+#endif
}
-#endif /* HAVE_SETLOCALE */
/* Return a diagnostic string for ERROR_NUMBER, in the wording
and encoding appropriate for the current locale. */
diff --git a/src/fns.c b/src/fns.c
index cb3e25811ea..6ccdfbcd070 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3012,6 +3012,25 @@ bool_vector_cmp (Lisp_Object a, Lisp_Object b)
return (d & aw) ? 1 : -1;
}
+/* Return -1 if a<b, 1 if a>b, 0 if a=b or if b is NaN (a must be a fixnum). */
+static inline int
+fixnum_float_cmp (EMACS_INT a, double b)
+{
+ double fa = (double)a;
+ if (fa == b)
+ {
+ /* This doesn't mean that a=b because the conversion may have rounded.
+ However, b must be an integer that fits in an EMACS_INT,
+ because |b| ≤ 2|a| and EMACS_INT has at least one bit more than
+ needed to represent any fixnum.
+ Thus we can compare in the integer domain instead. */
+ EMACS_INT ib = b; /* lossless conversion */
+ return a < ib ? -1 : a > ib;
+ }
+ else
+ return fa < b ? -1 : fa > b; /* return 0 if b is NaN */
+}
+
/* Return -1, 0 or 1 to indicate whether a<b, a=b or a>b in the sense of value<.
In particular 0 does not mean equality in the sense of Fequal, only
that the arguments cannot be ordered yet they can be compared (same
@@ -3035,7 +3054,7 @@ value_cmp (Lisp_Object a, Lisp_Object b, int maxdepth)
if (FIXNUMP (b))
return ia < XFIXNUM (b) ? -1 : 1; /* we know that a != b */
if (FLOATP (b))
- return ia < XFLOAT_DATA (b) ? -1 : ia > XFLOAT_DATA (b);
+ return fixnum_float_cmp (ia, XFLOAT_DATA (b));
if (BIGNUMP (b))
return -mpz_sgn (*xbignum_val (b));
}
@@ -3176,7 +3195,7 @@ value_cmp (Lisp_Object a, Lisp_Object b, int maxdepth)
if (FLOATP (b))
return fa < XFLOAT_DATA (b) ? -1 : fa > XFLOAT_DATA (b);
if (FIXNUMP (b))
- return fa < XFIXNUM (b) ? -1 : fa > XFIXNUM (b);
+ return -fixnum_float_cmp (XFIXNUM (b), fa);
if (BIGNUMP (b))
{
if (isnan (fa))
diff --git a/src/lisp.h b/src/lisp.h
index 59d8e497f13..68b77a88aa7 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -5190,15 +5190,9 @@ extern AVOID terminate_due_to_signal (int, int);
#ifdef WINDOWSNT
extern Lisp_Object Vlibrary_cache;
#endif
-#if HAVE_SETLOCALE
void fixup_locale (void);
void synchronize_system_messages_locale (void);
void synchronize_system_time_locale (void);
-#else
-INLINE void fixup_locale (void) {}
-INLINE void synchronize_system_messages_locale (void) {}
-INLINE void synchronize_system_time_locale (void) {}
-#endif
extern char *emacs_strerror (int) ATTRIBUTE_RETURNS_NONNULL;
extern void shut_down_emacs (int, Lisp_Object);
diff --git a/src/lread.c b/src/lread.c
index 3feb27eda46..c3b0e8a3ef5 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -28,6 +28,7 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <sys/stat.h>
#include <sys/file.h>
#include <errno.h>
+#include <locale.h>
#include <math.h>
#include <stat-time.h>
#include "lisp.h"
@@ -55,11 +56,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#endif
#include <unistd.h>
-
-#ifdef HAVE_SETLOCALE
-#include <locale.h>
-#endif /* HAVE_SETLOCALE */
-
#include <fcntl.h>
#if !defined HAVE_ANDROID || defined ANDROID_STUBIFY \
diff --git a/src/marker.c b/src/marker.c
index f016bf9c088..16fa3bcef3e 100644
--- a/src/marker.c
+++ b/src/marker.c
@@ -202,19 +202,15 @@ buf_charpos_to_bytepos (struct buffer *b, ptrdiff_t charpos)
if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
CONSIDER (cached_charpos, cached_bytepos);
- for (tail = BUF_MARKERS (b); tail; tail = tail->next)
- {
- CONSIDER (tail->charpos, tail->bytepos);
-
- /* If we are down to a range of 50 chars,
- don't bother checking any other markers;
- scan the intervening chars directly now. */
- if (best_above - charpos < distance
- || charpos - best_below < distance)
- break;
- else
- distance += BYTECHAR_DISTANCE_INCREMENT;
- }
+ for (tail = BUF_MARKERS (b);
+ /* If we are down to a range of DISTANCE chars,
+ don't bother checking any other markers;
+ scan the intervening chars directly now. */
+ tail && !(best_above - charpos < distance
+ || charpos - best_below < distance);
+ tail = tail->next,
+ distance += BYTECHAR_DISTANCE_INCREMENT)
+ CONSIDER (tail->charpos, tail->bytepos);
/* We get here if we did not exactly hit one of the known places.
We have one known above and one known below.
@@ -354,19 +350,15 @@ buf_bytepos_to_charpos (struct buffer *b, ptrdiff_t bytepos)
if (b == cached_buffer && BUF_MODIFF (b) == cached_modiff)
CONSIDER (cached_bytepos, cached_charpos);
- for (tail = BUF_MARKERS (b); tail; tail = tail->next)
- {
- CONSIDER (tail->bytepos, tail->charpos);
-
- /* If we are down to a range of 50 chars,
- don't bother checking any other markers;
- scan the intervening chars directly now. */
- if (best_above - bytepos < distance
- || bytepos - best_below < distance)
- break;
- else
- distance += BYTECHAR_DISTANCE_INCREMENT;
- }
+ for (tail = BUF_MARKERS (b);
+ /* If we are down to a range of DISTANCE bytes,
+ don't bother checking any other markers;
+ scan the intervening chars directly now. */
+ tail && !(best_above_byte - bytepos < distance
+ || bytepos - best_below_byte < distance);
+ tail = tail->next,
+ distance += BYTECHAR_DISTANCE_INCREMENT)
+ CONSIDER (tail->bytepos, tail->charpos);
/* We get here if we did not exactly hit one of the known places.
We have one known above and one known below.
diff --git a/src/module-env-30.h b/src/module-env-30.h
index e75210c7f8e..e69de29bb2d 100644
--- a/src/module-env-30.h
+++ b/src/module-env-30.h
@@ -1,3 +0,0 @@
- /* Add module environment functions newly added in Emacs 30 here.
- Before Emacs 30 is released, remove this comment and start
- module-env-31.h on the master branch. */
diff --git a/src/module-env-31.h b/src/module-env-31.h
new file mode 100644
index 00000000000..e9827b18382
--- /dev/null
+++ b/src/module-env-31.h
@@ -0,0 +1,3 @@
+ /* Add module environment functions newly added in Emacs 31 here.
+ Before Emacs 31 is released, remove this comment and start
+ module-env-32.h on the master branch. */
diff --git a/src/pdumper.c b/src/pdumper.c
index 8946c317bf9..bc5748c8c47 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -2125,8 +2125,7 @@ dump_marker (struct dump_context *ctx, const struct Lisp_Marker *marker)
}
static dump_off
-dump_interval_node (struct dump_context *ctx, struct itree_node *node,
- dump_off parent_offset)
+dump_interval_node (struct dump_context *ctx, struct itree_node *node)
{
#if CHECK_STRUCTS && !defined (HASH_itree_node_50DE304F13)
# error "itree_node changed. See CHECK_STRUCTS comment in config.h."
@@ -2153,17 +2152,17 @@ dump_interval_node (struct dump_context *ctx, struct itree_node *node,
dump_remember_fixup_ptr_raw
(ctx,
offset + dump_offsetof (struct itree_node, parent),
- dump_interval_node (ctx, node->parent, offset));
+ dump_interval_node (ctx, node->parent));
if (node->left)
dump_remember_fixup_ptr_raw
(ctx,
offset + dump_offsetof (struct itree_node, left),
- dump_interval_node (ctx, node->left, offset));
+ dump_interval_node (ctx, node->left));
if (node->right)
dump_remember_fixup_ptr_raw
(ctx,
offset + dump_offsetof (struct itree_node, right),
- dump_interval_node (ctx, node->right, offset));
+ dump_interval_node (ctx, node->right));
return offset;
}
@@ -2180,7 +2179,7 @@ dump_overlay (struct dump_context *ctx, const struct Lisp_Overlay *overlay)
dump_remember_fixup_ptr_raw
(ctx,
offset + dump_offsetof (struct Lisp_Overlay, interval),
- dump_interval_node (ctx, overlay->interval, offset));
+ dump_interval_node (ctx, overlay->interval));
return offset;
}
@@ -2209,9 +2208,9 @@ dump_finalizer (struct dump_context *ctx,
/* Do _not_ call dump_pseudovector_lisp_fields here: we dump the
only Lisp field, finalizer->function, manually, so we can give it
a low weight. */
- dump_field_lv (ctx, &out, finalizer, &finalizer->function, WEIGHT_NONE);
- dump_field_finalizer_ref (ctx, &out, finalizer, &finalizer->prev);
- dump_field_finalizer_ref (ctx, &out, finalizer, &finalizer->next);
+ dump_field_lv (ctx, out, finalizer, &finalizer->function, WEIGHT_NONE);
+ dump_field_finalizer_ref (ctx, out, finalizer, &finalizer->prev);
+ dump_field_finalizer_ref (ctx, out, finalizer, &finalizer->next);
return finish_dump_pvec (ctx, &out->header);
}
diff --git a/src/puresize.h b/src/puresize.h
index 2a716872832..d7d8f0b4eec 100644
--- a/src/puresize.h
+++ b/src/puresize.h
@@ -47,7 +47,7 @@ INLINE_HEADER_BEGIN
#endif
#ifndef BASE_PURESIZE
-#define BASE_PURESIZE (3000000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
+#define BASE_PURESIZE (3100000 + SYSTEM_PURESIZE_EXTRA + SITELOAD_PURESIZE_EXTRA)
#endif
/* Increase BASE_PURESIZE by a ratio depending on the machine's word size. */
diff --git a/src/sysdep.c b/src/sysdep.c
index 07237885cb9..d916a695155 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -4551,18 +4551,10 @@ does the same thing as `current-time'. */)
# include <wchar.h>
# include <wctype.h>
-# if defined HAVE_NEWLOCALE || defined HAVE_SETLOCALE
-# include <locale.h>
-# endif
-# ifndef LC_COLLATE
-# define LC_COLLATE 0
-# endif
+# include <locale.h>
# ifndef LC_COLLATE_MASK
# define LC_COLLATE_MASK 0
# endif
-# ifndef LC_CTYPE
-# define LC_CTYPE 0
-# endif
# ifndef LC_CTYPE_MASK
# define LC_CTYPE_MASK 0
# endif
@@ -4595,15 +4587,11 @@ freelocale (locale_t loc)
static char *
emacs_setlocale (int category, char const *locale)
{
-# ifdef HAVE_SETLOCALE
errno = 0;
char *loc = setlocale (category, locale);
if (loc || errno)
return loc;
errno = EINVAL;
-# else
- errno = ENOTSUP;
-# endif
return 0;
}
diff --git a/src/xdisp.c b/src/xdisp.c
index 7d31813a57e..8c7e8e5cb43 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -5549,6 +5549,7 @@ setup_for_ellipsis (struct it *it, int len)
static Lisp_Object
find_display_property (Lisp_Object disp, Lisp_Object prop)
{
+ Lisp_Object elem;
if (NILP (disp))
return Qnil;
/* We have a vector of display specs. */
@@ -5556,11 +5557,11 @@ find_display_property (Lisp_Object disp, Lisp_Object prop)
{
for (ptrdiff_t i = 0; i < ASIZE (disp); i++)
{
- Lisp_Object elem = AREF (disp, i);
+ elem = AREF (disp, i);
if (CONSP (elem)
&& CONSP (XCDR (elem))
&& EQ (XCAR (elem), prop))
- return XCAR (XCDR (elem));
+ goto found;
}
return Qnil;
}
@@ -5570,11 +5571,11 @@ find_display_property (Lisp_Object disp, Lisp_Object prop)
{
while (!NILP (disp))
{
- Lisp_Object elem = XCAR (disp);
+ elem = XCAR (disp);
if (CONSP (elem)
&& CONSP (XCDR (elem))
&& EQ (XCAR (elem), prop))
- return XCAR (XCDR (elem));
+ goto found;
/* Check that we have a proper list before going to the next
element. */
@@ -5589,9 +5590,20 @@ find_display_property (Lisp_Object disp, Lisp_Object prop)
else if (CONSP (disp)
&& CONSP (XCDR (disp))
&& EQ (XCAR (disp), prop))
- return XCAR (XCDR (disp));
+ {
+ elem = disp;
+ goto found;
+ }
+
+ return Qnil;
+
+ found:
+ /* If the property value is a list of one element, just return the
+ CAR. */
+ if (NILP (XCDR (XCDR (elem))))
+ return XCAR (XCDR (elem));
else
- return Qnil;
+ return XCDR (elem);
}
static Lisp_Object
@@ -28053,18 +28065,7 @@ store_mode_line_string (const char *string, Lisp_Object lisp_string,
if (string != NULL)
{
-#if defined HAVE_ANDROID && !defined ANDROID_STUBIFY \
- && __ANDROID_API__ < 22
- /* Circumvent a bug in memchr preventing strnlen from returning
- valid values when a large limit is specified.
-
- https://issuetracker.google.com/issues/37020957 */
- if (precision <= 0 || ((uintptr_t) string
- > (UINTPTR_MAX - precision)))
- len = strlen (string);
- else
-#endif /* HAVE_ANDROID && !ANDROID_STUBIFY && __ANDROID_API__ < 22 */
- len = strnlen (string, precision <= 0 ? SIZE_MAX : precision);
+ len = strnlen (string, precision <= 0 ? SIZE_MAX : precision);
lisp_string = make_string (string, len);
if (NILP (props))
props = mode_line_string_face_prop;
diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba
index de32906212b..088df86ad70 100644
--- a/test/infra/Dockerfile.emba
+++ b/test/infra/Dockerfile.emba
@@ -145,7 +145,6 @@ RUN src/emacs -Q --batch \
treesit-language-source-alist \
(quote ((bash "https://github.com/tree-sitter/tree-sitter-bash") \
(c "https://github.com/tree-sitter/tree-sitter-c") \
- (c-sharp "https://github.com/tree-sitter/tree-sitter-c-sharp") \
(cpp "https://github.com/tree-sitter/tree-sitter-cpp") \
(css "https://github.com/tree-sitter/tree-sitter-css") \
(elixir "https://github.com/elixir-lang/tree-sitter-elixir") \
diff --git a/test/infra/Makefile.in b/test/infra/Makefile.in
index 0144ad1cbd9..9c32fd6a192 100644
--- a/test/infra/Makefile.in
+++ b/test/infra/Makefile.in
@@ -117,25 +117,22 @@ endef
$(foreach subdir, $(SUBDIRS), $(eval $(call subdir_template,$(subdir))))
-# csharp-mode-tests.el, js-tests.el and python-tests.el don't follow
-# test file name convention.
+# js-tests.el and python-tests.el don't follow test file name convention.
TREE-SITTER-FILES ?= $(shell cd .. ; \
find lisp src \( -name "*-ts-mode-tests.el" -o -name "treesit-tests.el" \
- -o -name "csharp-mode-tests.el" -o -name "js-tests.el" \
- -o -name "python-tests.el" \) | \
+ -o -name "js-tests.el" -o -name "python-tests.el" \) | \
sort | sed s/\\.el/.log/)
all: generate-test-jobs
-.PHONY: generate-test-jobs $(FILE) $(SUBDIR_TARGETS) tree-sitter-files
+.PHONY: generate-test-jobs $(FILE) $(SUBDIR_TARGETS) tree-sitter-files-template
-generate-test-jobs: $(FILE) $(SUBDIR_TARGETS) tree-sitter-files
+generate-test-jobs: $(FILE) $(SUBDIR_TARGETS) tree-sitter-files-template
-tree-sitter-files:
+tree-sitter-files-template:
@echo >>$(FILE)
- @echo "# csharp-mode-tests.el, js-tests.el and python-tests.el don't follow" >>$(FILE)
- @echo "# test file name convention." >>$(FILE)
- @echo '.tree-sitter-files:' >>$(FILE)
+ @echo "# js-tests.el and python-tests.el don't follow test file name convention." >>$(FILE)
+ @echo '.tree-sitter-files-template:' >>$(FILE)
@echo ' variables:' >>$(FILE)
@echo ' tree_sitter_files: >-' >>$(FILE)
@for name in $(TREE-SITTER-FILES) ; do echo " $${name}" >>$(FILE) ; done
diff --git a/test/infra/gitlab-ci.yml b/test/infra/gitlab-ci.yml
index e5e48b76ec2..11ff0d1c738 100644
--- a/test/infra/gitlab-ci.yml
+++ b/test/infra/gitlab-ci.yml
@@ -294,7 +294,7 @@ build-image-tree-sitter:
test-tree-sitter:
stage: platforms
- extends: [.job-template, .test-template, .tree-sitter-template, .tree-sitter-files]
+ extends: [.job-template, .test-template, .tree-sitter-template, .tree-sitter-files-template]
needs:
- job: build-image-tree-sitter
optional: true
diff --git a/test/infra/test-jobs.yml b/test/infra/test-jobs.yml
index 13b184b1277..0d9cbb029e5 100644
--- a/test/infra/test-jobs.yml
+++ b/test/infra/test-jobs.yml
@@ -577,12 +577,10 @@ test-src-inotify:
target: emacs-inotify
make_params: -C test check-src
-# csharp-mode-tests.el, js-tests.el and python-tests.el don't follow
-# test file name convention.
-.tree-sitter-files:
+# js-tests.el and python-tests.el don't follow test file name convention.
+.tree-sitter-files-template:
variables:
tree_sitter_files: >-
- lisp/progmodes/csharp-mode-tests.log
lisp/progmodes/c-ts-mode-tests.log
lisp/progmodes/elixir-ts-mode-tests.log
lisp/progmodes/go-ts-mode-tests.log
diff --git a/test/lisp/completion-preview-tests.el b/test/lisp/completion-preview-tests.el
index 3f64fe02e18..b190ecb7020 100644
--- a/test/lisp/completion-preview-tests.el
+++ b/test/lisp/completion-preview-tests.el
@@ -291,7 +291,7 @@ instead."
(setq-local completion-at-point-functions
(list
(completion-preview-tests--capf
- '("foobar" "foobaz")
+ '("foobar-1 2" "foobarverylong")
:exit-function
(lambda (&rest args)
(setq exit-fn-called t
@@ -299,11 +299,150 @@ instead."
(insert "foo")
(let ((this-command 'self-insert-command))
(completion-preview--post-command))
- (completion-preview-tests--check-preview "bar" 'completion-preview-common)
+ (completion-preview-tests--check-preview "bar-1 2"
+ 'completion-preview-common)
(completion-preview-insert)
+ (should (string= (buffer-string) "foobar-1 2"))
+ (should-not completion-preview--overlay)
+ (should exit-fn-called)
+ (should (equal exit-fn-args '("foobar-1 2" finished))))))
+
+(ert-deftest completion-preview-insert-word ()
+ "Test that `completion-preview-insert-word' properly inserts just a word."
+ (let ((exit-fn-called nil) (exit-fn-args nil))
+ (with-temp-buffer
+ (setq-local completion-at-point-functions
+ (list
+ (completion-preview-tests--capf
+ '("foobar-1 2" "foobarverylong")
+ :exit-function
+ (lambda (&rest args)
+ (setq exit-fn-called t
+ exit-fn-args args)))))
+ (insert "foo")
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "bar-1 2"
+ 'completion-preview-common)
+ (completion-preview-insert-word)
(should (string= (buffer-string) "foobar"))
+ (completion-preview-tests--check-preview "-1 2" 'completion-preview)
+ (should-not exit-fn-called)
+ (should-not exit-fn-args))))
+
+(ert-deftest completion-preview-insert-nonsubword ()
+ "Test that `completion-preview-insert-word' with `subword-mode' off."
+ (let ((exit-fn-called nil) (exit-fn-args nil))
+ (with-temp-buffer
+ (setq-local completion-at-point-functions
+ (list
+ (completion-preview-tests--capf
+ '("foobarBar" "foobarverylong")
+ :exit-function
+ (lambda (&rest args)
+ (setq exit-fn-called t
+ exit-fn-args args)))))
+ (insert "foo")
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "barBar"
+ 'completion-preview-common)
+ (completion-preview-insert-word)
+ (should (string= (buffer-string) "foobarBar"))
(should-not completion-preview--overlay)
(should exit-fn-called)
- (should (equal exit-fn-args '("foobar" finished))))))
+ (should (equal exit-fn-args '("foobarBar" finished))))))
+
+(ert-deftest completion-preview-insert-subword ()
+ "Test that `completion-preview-insert-word' with `subword-mode' on."
+ (let ((exit-fn-called nil) (exit-fn-args nil))
+ (with-temp-buffer
+ (subword-mode)
+ (setq-local completion-at-point-functions
+ (list
+ (completion-preview-tests--capf
+ '("foobarBar" "foobarverylong")
+ :exit-function
+ (lambda (&rest args)
+ (setq exit-fn-called t
+ exit-fn-args args)))))
+ (insert "foo")
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "barBar"
+ 'completion-preview-common)
+ (completion-preview-insert-word)
+ (should (string= (buffer-string) "foobar"))
+ (completion-preview-tests--check-preview "Bar" 'completion-preview)
+ (should-not exit-fn-called)
+ (should-not exit-fn-args))))
+
+(ert-deftest completion-preview-insert-mid-symbol ()
+ "Test `completion-preview-insert-word' when point is in a mulit-word symbol."
+ (with-temp-buffer
+ (setq-local completion-at-point-functions
+ (list
+ (completion-preview-tests--capf
+ '("foo-bar-baz-spam"))))
+ (insert "foo-bar-baz-")
+ (goto-char 4)
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "spam"
+ 'completion-preview-exact
+ 'completion-preview-exact)
+ (completion-preview-insert-word 2)
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ ;; Moving two words forward should land at the end of baz, without
+ ;; inserting anything from the completion candidate.
+ (completion-preview-tests--check-preview "spam"
+ 'completion-preview-exact
+ 'completion-preview-exact)
+ (should (= (point) 12))
+ (completion-preview-insert-word -2)
+ ;; Moving backward shouldn't change anything, either.
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "spam"
+ 'completion-preview-exact
+ 'completion-preview-exact)
+ (should (= (point) 5))))
+
+(ert-deftest completion-preview-insert-sexp ()
+ "Test that `completion-preview-insert-sexp' properly inserts just a sexp."
+ (let ((exit-fn-called nil) (exit-fn-args nil))
+ (with-temp-buffer
+ (setq-local completion-at-point-functions
+ (list
+ (completion-preview-tests--capf
+ '("foobar-1 2" "foobarverylong")
+ :exit-function
+ (lambda (&rest args)
+ (setq exit-fn-called t
+ exit-fn-args args)))))
+ (insert "foo")
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "bar-1 2"
+ 'completion-preview-common)
+ (completion-preview-insert-sexp)
+ (should (string= (buffer-string) "foobar-1"))
+ (completion-preview-tests--check-preview " 2" 'completion-preview)
+ (should-not exit-fn-called)
+ (should-not exit-fn-args))))
+
+(ert-deftest completion-preview-insert-inherits-text-properties ()
+ "Test that `completion-preview-insert' inherits text properties."
+ (with-temp-buffer
+ (setq-local completion-at-point-functions
+ (list (completion-preview-tests--capf '("foobar" "foobaz"))))
+ (insert (propertize "foo" 'prop 'val))
+ (let ((this-command 'self-insert-command))
+ (completion-preview--post-command))
+ (completion-preview-tests--check-preview "bar" 'completion-preview-common)
+ (completion-preview-insert)
+ (should (string= (buffer-string) "foobar"))
+ (should (eq (get-text-property 6 'prop) 'val))))
;;; completion-preview-tests.el ends here
diff --git a/test/lisp/eshell/eshell-tests.el b/test/lisp/eshell/eshell-tests.el
index e58b5a14ed9..f16c28cd1ae 100644
--- a/test/lisp/eshell/eshell-tests.el
+++ b/test/lisp/eshell/eshell-tests.el
@@ -117,6 +117,27 @@ This test uses a pipeline for the command."
(forward-line)
(should (looking-at "hi\n"))))))
+(ert-deftest eshell-test/eshell-command/output-buffer/async-kill ()
+ "Test that the `eshell-command' function kills the old process when told to."
+ (skip-unless (executable-find "echo"))
+ (ert-with-temp-directory eshell-directory-name
+ (let ((orig-processes (process-list))
+ (eshell-history-file-name nil)
+ (eshell-command-async-buffer 'confirm-kill-process))
+ (eshell-command "sleep 5 | *echo hi &")
+ (cl-letf* ((result t)
+ ;; Say "yes" only once: for the `confirm-kill-process'
+ ;; prompt. If there are any other prompts (e.g. from
+ ;; `kill-buffer'), say "no" to make the test fail.
+ ((symbol-function 'yes-or-no-p)
+ (lambda (_prompt) (prog1 result (setq result nil)))))
+ (eshell-command "*echo bye &"))
+ (eshell-wait-for (lambda () (equal (process-list) orig-processes)))
+ (with-current-buffer "*Eshell Async Command Output*"
+ (goto-char (point-min))
+ (forward-line)
+ (should (looking-at "bye\n"))))))
+
(ert-deftest eshell-test/command-running-p ()
"Modeline should show no command running"
(with-temp-eshell
diff --git a/test/lisp/net/rfc2104-tests.el b/test/lisp/net/rfc2104-tests.el
index be5da619eaa..40e593ad56b 100644
--- a/test/lisp/net/rfc2104-tests.el
+++ b/test/lisp/net/rfc2104-tests.el
@@ -23,8 +23,6 @@
(require 'ert)
(require 'rfc2104)
-(require 'sha1)
-(require 'md5)
(ert-deftest dbus-test-sha1 ()
(should
diff --git a/test/lisp/net/shr-tests.el b/test/lisp/net/shr-tests.el
index 54d85ee95f9..f8559df5272 100644
--- a/test/lisp/net/shr-tests.el
+++ b/test/lisp/net/shr-tests.el
@@ -158,6 +158,7 @@ settings, then once more for each (OPTION . VALUE) pair.")
(shr-width 80)
(shr-use-fonts nil)
(shr-image-animate nil)
+ (shr-sliced-image-height nil)
(inhibit-message t)
(dom (libxml-parse-html-region (point-min) (point-max))))
;; Render the document.
@@ -170,19 +171,15 @@ settings, then once more for each (OPTION . VALUE) pair.")
(shr-zoom-image)
(shr-test-wait-for (lambda () (= put-image-calls 2))
"Timed out waiting to zoom image")
- ;; Check that we got a sliced image.
- (let ((slice-count 0))
+ ;; Check that we have a single image at original size.
+ (let (image-zooms)
(goto-char (point-min))
(while (< (point) (point-max))
- (when-let ((display (get-text-property (point) 'display)))
- ;; If this is nil, we found a non-sliced image, but we
- ;; should have replaced that!
- (should (assq 'slice display))
- (cl-incf slice-count))
+ (when (get-text-property (point) 'display)
+ (push (get-text-property (point) 'image-zoom) image-zooms))
(goto-char (or (next-single-property-change (point) 'display)
(point-max))))
- ;; Make sure we actually saw a slice.
- (should (> slice-count 1)))))))))
+ (should (equal image-zooms '(original))))))))))
(require 'shr)
diff --git a/test/lisp/whitespace-tests.el b/test/lisp/whitespace-tests.el
index 73c7e742ec5..bd35b3ac9f3 100644
--- a/test/lisp/whitespace-tests.el
+++ b/test/lisp/whitespace-tests.el
@@ -8,7 +8,6 @@
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
-
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -94,6 +93,20 @@ buffer's content."
(should (equal (whitespace-tests--cleanup-string "a \n\t \n\n")
"a \n"))))
+(ert-deftest whitespace-cleanup-missing-newline-at-eof ()
+ (let ((whitespace-style '(empty missing-newline-at-eof)))
+ (should (equal (whitespace-tests--cleanup-string "")
+ ""))
+ (should (equal (whitespace-tests--cleanup-string "a")
+ "a\n"))
+ (should (equal (whitespace-tests--cleanup-string "a\n\t")
+ "a\n"))
+ (should (equal (whitespace-tests--cleanup-string "a\n\t ")
+ "a\n"))
+ (should (equal (whitespace-tests--cleanup-string "a\n\t ")
+ "a\n"))
+ (should (equal (whitespace-tests--cleanup-string "\n\t")
+ ""))))
;; We cannot call whitespace-mode because it will do nothing in batch
;; mode. So we call its innards instead.
diff --git a/test/manual/indent/perl.perl b/test/manual/indent/perl.perl
index b44593da028..de76fffa262 100755
--- a/test/manual/indent/perl.perl
+++ b/test/manual/indent/perl.perl
@@ -5,6 +5,10 @@ sub add_funds($) {
return 0;
}
+find ({ wanted => sub {
+ return;
+ }, follow => 1 }, '/tmp');
+
# qw(...) is a quoted list of words, so we can and should indent its content!
my @tutu = qw[
tata
diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el
index ca5b10db705..decbdb6ac52 100644
--- a/test/src/fns-tests.el
+++ b/test/src/fns-tests.el
@@ -1606,6 +1606,13 @@
(1.5 . 1.6) (-1.3 . -1.2) (-13.0 . 12.0)
;; floats/fixnums
(1 . 1.1) (1.9 . 2) (-2.0 . 1) (-2 . 1.0)
+ ;; fixnums that can't be represented as floats
+ (72057594037927935 . 72057594037927936.0)
+ (72057594037927936.0 . 72057594037927937)
+ (-72057594037927936.0 . -72057594037927935)
+ (-72057594037927937 . -72057594037927936.0)
+ (2305843009213693951 . 2305843009213693952.0)
+
;; floats/bignums
(,big . ,(float (* 2 big))) (,(float big) . ,(* 2 big))
;; symbols
@@ -1665,7 +1672,11 @@
(should (value< x y))
(should-not (value< y x))
(should-not (value< x x))
- (should-not (value< y y))))
+ (should-not (value< y y))
+ (should (value< (vector x 2) (vector y 1)))
+ (should-not (value< (vector y 1) (vector x 2)))
+ (should (value< (vector x 1) (vector x 2)))
+ (should (value< (vector y 1) (vector y 2)))))
(delete-process proc2)
(delete-process proc1)
@@ -1683,6 +1694,9 @@
;; numbers
(0 . 0.0) (0 . -0.0) (0.0 . -0.0)
+ (72057594037927936 . 72057594037927936.0)
+ (1 . 0.0e+NaN)
+
;; symbols
(a . #:a)
@@ -1697,7 +1711,9 @@
(let ((x (car c))
(y (cdr c)))
(should-not (value< x y))
- (should-not (value< y x))))))
+ (should-not (value< y x))
+ (should (value< (cons x 1) (cons y 2)))
+ (should-not (value< (cons x 2) (cons y 1)))))))
(ert-deftest fns-value<-type-mismatch ()
;; values of disjoint (incomparable) types