Merge branch 'master' into feature/igc3

This commit is contained in:
Helmut Eller 2026-05-17 21:00:58 +02:00
commit e0d8600cff
408 changed files with 95528 additions and 16378 deletions

View file

@ -3149,7 +3149,7 @@
Remove mention of removed `gnus-treat-play-sounds' variable from manual
* info/gnus.info: Remove `gnus-treat-play-sounds' from
* doc/misc/gnus.texi: Remove `gnus-treat-play-sounds' from
manual. According to lisp/gnus/ChangeLog.3 this variable was
removed in 2010 (bug#53192).
@ -46460,7 +46460,7 @@
* lisp/subr.el (ctl-x-map): Initialize inside the declaration.
* src/command.h (control_x_map):
* src/commands.h (control_x_map):
* src/keymap.c (control_x_map): Delete variable.
(syms_of_keymap):
* src/keyboard.c (keys_of_keyboard):

View file

@ -22242,7 +22242,7 @@
2024-03-10 Andreas Schwab <schwab@linux-m68k.org>
Avoid dependency on nonexisting target in lispref makefile
Avoid dependency on nonexistent target in lispref makefile
* doc/lispref/Makefile.in (auxfiles): Change target into a
variable.
@ -83524,7 +83524,7 @@
2023-12-04 Philipp Stephani <p.stephani2@gmail.com>
Don't claim to signal an error when deleting a nonexisting file.
Don't claim to signal an error when deleting a nonexistent file.
The behavior has changed in commit
1a65afb7ecc2a52127d6164bad19313440237f9d to no longer signal an error
@ -150001,7 +150001,7 @@
2022-04-27 Lars Ingebrigtsen <larsi@gnus.org>
Give better error message in dired-toggle-read-only on nonexisting dirs
Give better error message in dired-toggle-read-only on nonexistent dirs
* lisp/dired.el (dired-toggle-read-only): Refuse to edit
non-existent directories (bug#23276).

62982
ChangeLog.5

File diff suppressed because it is too large Load diff

View file

@ -1314,7 +1314,7 @@ ChangeLog:
./$(emacslog) -o $(CHANGELOG) -n $(CHANGELOG_HISTORY_INDEX_MAX)
# Check that we are in a good state for changing history.
PREFERRED_BRANCH = emacs-30
PREFERRED_BRANCH = emacs-31
preferred-branch-is-current:
git branch | grep -q '^\* $(PREFERRED_BRANCH)$$'
unchanged-history-files:

2
README
View file

@ -2,7 +2,7 @@ Copyright (C) 2001-2026 Free Software Foundation, Inc.
See the end of the file for license conditions.
This directory tree holds version 31.0.50 of GNU Emacs, the extensible,
This directory tree holds version 32.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

View file

@ -235,6 +235,7 @@ Philip Kaludercic
lisp/emacs-lisp/package.el
lisp/emacs-lisp/package-vc.el
lisp/emacs-lisp/compat.el
lisp/textmodes/sgml-mode.el
Yuan Fu
src/treesit.c

View file

@ -192,7 +192,7 @@ Documentation changes might not have been completed!"))))
"mv" newsfile oldnewsfile)
(when (y-or-n-p "Commit move of NEWS file?")
(call-process admin-git-command nil nil nil
"commit" "-m" (format "; Move etc/%s to etc/%s"
"commit" "-m" (format "; Move etc/%s to etc/%s."
(file-name-nondirectory newsfile)
(file-name-nondirectory oldnewsfile))))
(find-file oldnewsfile) ; to prompt you to commit it

View file

@ -43,14 +43,17 @@ files.")
(nil "A\\. N\\. Other") ; unknown author 2014-12-03, later removed
(nil "Anticrisis")
(nil "akater")
("Aaron L. Zeng" "Aaron Zeng")
("Aaron S. Hawley" "Aaron Hawley")
("Alan Third" "Alan J Third")
("Alexander Gramiak" "Alex Gramiak")
("Alexandru Harsanyi" "Alex Harsanyi")
("Álvar Jesús Ibeas Martín" "Álvar Ibeas")
("Álvaro Ramírez" "Alvaro Ramirez" "xenodium")
(nil "ambihelical")
("Andrea Corallo" "AndreaCorallo")
("Andrii Kolomoiets" "andreyk\\.mad@gmail\\.com")
("André A. Gomes" "Andre A. Gomes")
("Andrew Csillag" "Drew Csillag")
("Andrew G Cohen" "Andrew Cohen")
("Anna M. Bigatti" "Anna Bigatti")
@ -103,6 +106,7 @@ files.")
("Eric M. Ludlam" "Eric Ludlam")
("Eric S. Raymond" "Eric Raymond")
("Etienne PrudHomme" "Etienne Prud'Homme")
("Ewan Townshend" "ewan@etown\\.dev")
("Fabián Ezequiel Gallina" "Fabian Ezequiel Gallina" "Fabi.n E\\. Gallina")
(nil "felix.*EmacsWiki")
(nil "felix\\.dick@web\\.de")
@ -224,6 +228,7 @@ files.")
(nil "pillule")
(nil "psyberbits@gmail\\.com")
("Paul Eggert" "Paul R\\. Eggert")
("Paul Nelson" "Paul D. Nelson")
("Pavel Janík" "Pavel Janík Ml\\." "Pavel Janik Ml\\." "Pavel Janik")
("Pavel Kobiakov" "Pavel Kobyakov")
("Per Abrahamsen" "Per Abhiddenware")
@ -698,7 +703,11 @@ Changes to files matching one of the regexps in this list are not listed.")
"lisp/org/ob-picolisp.el"
"lisp/obsolete/levents.el"
"lisp/obsolete/lucid.el"
"lisp/obsolete/old-whitespace.el")
"lisp/obsolete/old-whitespace.el"
"doc/misc/modus-themes.texi"
"doc/misc/elisp-semantic-highlighting.org"
"lisp/emacs-lisp/scope.el"
"etc/yow.lines")
"List of files and directories to ignore.
Changes to files in this list are not listed.")
@ -924,7 +933,8 @@ Changes to files in this list are not listed.")
("Dale R. Worley" :changed "mail-extr.el")
("Jamie Zawinski" :changed "bytecode.c" :wrote "tar-mode.el"
:cowrote "disass.el")
("Andrea Corallo" :wrote "comp.c"))
("Andrea Corallo" :wrote "comp.c" "[native compilation of Emacs Lisp]")
("Ewan Townshend" :wrote "[24-bit color support for MS-Windows console]"))
"Manual fixes to the list of actions taken.
These are mostly taken from the original, manually (un)maintained
AUTHORS file. There are also some more recent manual additions.")
@ -1161,7 +1171,42 @@ AUTHORS file. There are also some more recent manual additions.")
"admin/notes/tree-sitter/build-module/batch.sh"
"doc/misc/gnus-coding.texi"
"gnus-coding.texi"
"doc/misc/org.texi")
"doc/misc/org.texi"
;; Unexec & pure space removal.
"src/puresize.h"
"src/sheap.c"
"src/sheap.h"
"src/unexec.h"
"src/unexaix.c"
"src/unexcoff.c"
"src/unexcw.c"
"src/unexelf.c"
"src/unexhp9k800.c"
"src/unexmacosx.c"
"src/unexsol.c"
"src/unexw32.c"
"src/firstfile.c"
"src/lastfile.c"
;; Removed.
"nt/configure.bat"
"lisp/obsolete/cc-compat.el"
"lisp/obsolete/info-edit.el"
"lisp/obsolete/otodo-mode.el"
"lisp/obsolete/rcompile.el"
"lisp/terminal.el"
"lisp/obsolete/vi.el"
"lisp/obsolete/vip.el"
"doc/misc/vip.texi"
"lisp/obsolete/ws-mode.el"
"lisp/obsolete/yow.el"
"test/lisp/erc/resources/base/reconnect/ping-pong.eld"
"test/lisp/erc/resources/base/reconnect/proxy-solo.eld"
"test/lisp/erc/resources/erc-d/resources/proxy-solo.eld"
"admin/coccinelle/process.cocci"
"admin/coccinelle/window.cocci"
"admin/coccinelle/frame.cocci"
;; Merged into various files in cl-lib.
"lisp/emacs-lisp/cl-types.el" "test/lisp/emacs-lisp/cl-types-tests.el")
"File names which are valid, but no longer exist (or cannot be found)
in the repository.")
@ -1413,7 +1458,7 @@ in the repository.")
("lisp/new/eww.el" . "eww.el") ; an actual typo in ChangeLog.3
("gssapi.el" . "gssapi.el")
("lisp/gnus/gssapi.el" . "gssapi.el")
("imap.el" . "net/imap.el")
("imap.el" . "imap.el")
("mailcap.el" . "mailcap.el")
("gnus/mailcap.el" . "mailcap.el")
("lisp/gnus/mailcap.el" . "mailcap.el")
@ -1723,7 +1768,17 @@ in the repository.")
("lisp/vt100-led.el" . "lisp/obsolete/vt100-led.el")
("lisp/mail/metamail.el" . "lisp/obsolete/metamail.el")
("lisp/sb-image.el" . "lisp/obsolete/sb-image.el")
("lisp/cedet/semantic/grammar-wy.el" . "lisp/cedet/semantic/grm-wy-boot.el"))
("lisp/cedet/semantic/grammar-wy.el" . "lisp/cedet/semantic/grm-wy-boot.el")
("lisp/vc/vc-dav.el" . "vc-dav.el")
("test/lisp/vc/vc-tests.el" . "vc-tests.el")
("admin/notes/elpa" . "elpa.md")
("etc/NEWS.unknown" . "symbol-releases.eld")
("test/lisp/eshell/eshell-tests-helpers.el" . "eshell-tests-helpers.el")
("test/lisp/package-vc-tests.el" . "package-vc-tests.el")
("test/lisp/vc/vc-misc-tests.el" . "vc-test-misc.el")
("admin/treesit-admin.el" . "treesit-admin.el")
("java/incrementing-version-code" . "AndroidManifest.xml.in")
("etc/ctags.1" "ctags.1"))
"Alist of files which have been renamed during their lifetime.
Elements are (OLDNAME . NEWNAME).")

View file

@ -108,7 +108,7 @@ General steps (for each step, check for possible errors):
Now:
M-: (require 'authors) RET
M-x load-file RET admin/authors.el RET
M-x authors RET
If this says "Problem updating ChangeLog", find the reason for the

View file

@ -106,7 +106,7 @@ For instance, this
anywhere in sight is too confusing.
may not need mentioning, because --daemon will give an error message
saying it's not implemented, and other cases aren't affected.
saying it is not implemented, and other cases aren't affected.
The kind of change for which the user really needs help from Antinews
is where a feature works _differently_ in the previous version.
@ -164,3 +164,5 @@ like subr.el, which are not quoted.
Call 'emacs-news-view-mode'. Lisp symbols and Info manual links shall
be decorated, and clicking on them shall lead to the respective Help
buffer or Info node.
*** Do not use "it's", "you're" and alike.

View file

@ -76,6 +76,10 @@ Every pipeline generates a JUnit test report for the respective test
jobs, which can be inspected on the pipeline web page. This test
report counts completed ERT tests, aborted tests are not counted.
Twice a day, a pipeline for branch 'master', and another pipeline for
branch 'emacs-31' are started automatically, running all stages for
normal and expensive tests.
* Emba configuration
The emba configuration files are hosted on

View file

@ -16,14 +16,14 @@ Initial setup
Then we want to clone the repository. We normally want to have both
the current master and (if there is one) the active release branch
(eg emacs-30).
(eg emacs-31).
mkdir ~/emacs
cd ~/emacs
git clone <membername>@git.sv.gnu.org:/srv/git/emacs.git master
cd master
git config push.default current
git worktree add ../emacs-30 emacs-30
git worktree add ../emacs-31 emacs-31
You now have both branches conveniently accessible, and you can do
"git pull" in them once in a while to keep updated.
@ -67,7 +67,7 @@ which will look like
commit 958b768a6534ae6e77a8547a56fc31b46b63710b
cd ~/emacs/emacs-30
cd ~/emacs/emacs-31
git cherry-pick -xe 958b768a6534ae6e77a8547a56fc31b46b63710b
and add "Backport:" to the commit string. Then
@ -109,7 +109,7 @@ up-to-date by doing a pull. Then start Emacs with
emacs -l admin/gitmerge.el -f gitmerge
You'll be asked for the branch to merge, which will default to
(eg) 'origin/emacs-30', which you should accept. Merging a local tracking
(eg) 'origin/emacs-31', which you should accept. Merging a local tracking
branch is discouraged, since it might not be up-to-date, or worse,
contain commits from you which are not yet pushed upstream.

View file

@ -54,6 +54,7 @@ GNU - GNU is not Unix
HTH - hope this helps
IANAL - I am not a lawyer
ICYMI - in case you missed it
IDK - I don't know
IIRC - if I recall correctly
IIUC - if I understand correctly
IMHO - in my humble opinion
@ -62,6 +63,7 @@ IMO - in my opinion
IOW - in other words
LGTM - looks good to me
LMK - let me know
MRE - minimal reproducible example
OOO - out of office
OOTB - out of the box
OTOH - on the other hand

View file

@ -25,12 +25,12 @@
from subprocess import check_output
## Constants
EMACS_MAJOR_VERSION= os.getenv('EMACS_MAJOR_VERSION') or "30"
EMACS_MAJOR_VERSION= os.getenv('EMACS_MAJOR_VERSION') or "31"
# Base URI for the package sources mapped in PKG_REQ
SRC_REPO="https://repo.msys2.org/mingw/sources"
# Map items in `dynamic-library-alist' to source packages
# Map items in `dynamic-library-alist' to source pakages
PKG_REQ='''mingw-w64-x86_64-giflib
mingw-w64-x86_64-gnutls
mingw-w64-x86_64-harfbuzz
@ -47,29 +47,15 @@
mingw-w64-x86_64-tree-sitter
mingw-w64-x86_64-sqlite3'''.split()
# Emacs style path to dependency DLLs on build system
DLL_SRC="c:/msys64/mingw64/bin"
# Emacs style path to dependancy DLLs on build system
DLL_SRC="mingw64"
OUT_TAG=""
# libraries we never include
DLL_SKIP=["libgccjit-0.dll"]
# Report first existing file for entries in dynamic-library-alist
# ELISP_PROG="""
# (message "%s" (mapconcat 'identity (remove nil
# (mapcar (lambda(lib)
# (seq-find
# (lambda(file)
# (file-exists-p
# (file-name-concat "{}"
# file)))
# (cdr lib)))
# dynamic-library-alist)
# ) "\\n"))
# """.format(DLL_SRC)
## Options
DRY_RUN=False
# NEW_EMACS="bin/emacs.exe"
def check_output_maybe(*args,**kwargs):
if(DRY_RUN):
@ -82,7 +68,6 @@ def check_output_maybe(*args,**kwargs):
# entry point
def gather_deps():
os.mkdir("x86_64")
os.chdir("x86_64")
@ -95,12 +80,12 @@ def gather_deps():
if dep not in DLL_SKIP:
if args.l != True:
print("Adding dep", dep)
check_output_maybe(["cp /mingw64/bin/{} .".format(dep)], shell=True)
check_output_maybe(["cp /{}/bin/{} .".format(DLL_SRC,dep)], shell=True)
else:
if args.l != True:
print("Skipping dep", dep)
zipfile="../emacs-{}-{}deps.zip".format(EMACS_MAJOR_VERSION, DATE)
zipfile="../emacs-{}{}-{}deps.zip".format(EMACS_MAJOR_VERSION, OUT_TAG, DATE)
tmpfile="{}.tmp".format(zipfile)
print("Zipping deps in", os.getcwd(), "as", tmpfile)
check_output_maybe("zip -9vr {} *.dll".format(tmpfile), shell=True)
@ -110,7 +95,7 @@ def gather_deps():
print("Deps updated in", os.getcwd(), "as", zipfile)
os.chdir("../")
# Return dependencies listed in Emacs
# Return dependancies listed in Emacs
def init_deps():
return '''libXpm-nox4.dll
libpng16-16.dll
@ -125,23 +110,17 @@ def init_deps():
libgio-2.0-0.dll
libgobject-2.0-0.dll
libgnutls-30.dll
libxml2-2.dll
libxml2-16.dll
zlib1.dll
liblcms2-2.dll
libgccjit-0.dll
libtree-sitter.dll'''.split()
# job_args=[NEW_EMACS, "--batch", "--eval", ELISP_PROG]
# #print("args: ", job_args)
# return subprocess.check_output(job_args, stderr=subprocess.STDOUT
# ).decode('utf-8').splitlines()
libtree-sitter-0.26.dll'''.split()
# Return all second order dependencies
def full_dll_dependency(dlls):
deps = [dll_dependency(dep) for dep in dlls]
return set(sum(deps, []) + dlls)
#xs = filter(lambda x: x.attribute == value, xs)
# Dependencies for a given DLL
def dll_dependency(dll):
output = check_output(["/mingw64/bin/ntldd", "--recursive",
@ -171,80 +150,29 @@ def ntldd_munge(out):
## Packages to fiddle with
## Source for gcc-libs is part of gcc
SKIP_SRC_PKGS=["mingw-w64-gcc-libs"]
SKIP_DEP_PKGS=["mingw-w64-glib2", "mingw-w64-ca-certificates-20211016-3"]
SKIP_DEP_PKGS=["mingw-w64-glib2", "mingw-w64-x86_64-cc-libs", "mingw-w64-ca-certificates-20211016-3"]
## A few source packages don't follow typical naming conventions.
## Handle transformation from formulaic name to actual name
MUNGE_SRC_PKGS={
"mingw-w64-libwinpthread-git":"mingw-w64-winpthreads-git",
"mingw-w64-libwinpthread":"mingw-w64-winpthreads",
"mingw-w64-gettext-runtime":"mingw-w64-gettext"
}
## As above, but for source packages of second order deps
## Empty as of 30.0.50 (May, 2026), last used for Emacs 30.2
MUNGE_DEP_PKGS={
"mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git",
"mingw-w64-x86_64-libtre": "mingw-w64-x86_64-libtre-git",
}
SRC_EXT={
"mingw-w64-freetype": ".src.tar.zst",
"mingw-w64-fribidi": ".src.tar.zst",
"mingw-w64-glib2": ".src.tar.zst",
"mingw-w64-harfbuzz": ".src.tar.zst",
"mingw-w64-libunistring": ".src.tar.zst",
"mingw-w64-winpthreads-git": ".src.tar.zst",
"mingw-w64-ca-certificates": ".src.tar.zst",
"mingw-w64-libxml2": ".src.tar.zst",
"mingw-w64-ncurses": ".src.tar.zst",
"mingw-w64-openssl": ".src.tar.zst",
"mingw-w64-pango": ".src.tar.zst",
"mingw-w64-python": ".src.tar.zst",
"mingw-w64-sqlite3": ".src.tar.zst",
"mingw-w64-xpm-nox": ".src.tar.zst",
"mingw-w64-xz": ".src.tar.zst",
"mingw-w64-bzip2": ".src.tar.zst",
"mingw-w64-cairo": ".src.tar.zst",
"mingw-w64-expat": ".src.tar.zst",
"mingw-w64-fontconfig": ".src.tar.zst",
"mingw-w64-gdk-pixbuf2": ".src.tar.zst",
"mingw-w64-giflib": ".src.tar.zst",
"mingw-w64-gmp": ".src.tar.zst",
"mingw-w64-gnutls": ".src.tar.zst",
"mingw-w64-graphite2": ".src.tar.zst",
"mingw-w64-jbigkit": ".src.tar.zst",
"mingw-w64-lcms2": ".src.tar.zst",
"mingw-w64-lerc": ".src.tar.zst",
"mingw-w64-libdatrie": ".src.tar.zst",
"mingw-w64-libffi": ".src.tar.zst",
"mingw-w64-libiconv": ".src.tar.zst",
"mingw-w64-libiconv": ".src.tar.zst",
"mingw-w64-libpng": ".src.tar.zst",
"mingw-w64-librsvg": ".src.tar.zst",
"mingw-w64-libsystre": ".src.tar.zst",
"mingw-w64-libtasn": ".src.tar.zst",
"mingw-w64-libthai": ".src.tar.zst",
"mingw-w64-libtiff": ".src.tar.zst",
"mingw-w64-libtre-git": ".src.tar.zst",
"mingw-w64-libwebp": ".src.tar.zst",
"mingw-w64-mpdecimal": ".src.tar.zst",
"mingw-w64-nettle": ".src.tar.zst",
"mingw-w64-p11-kit": ".src.tar.zst",
"mingw-w64-pcre": ".src.tar.zst",
"mingw-w64-pixman": ".src.tar.zst",
"mingw-w64-python-packaging": ".src.tar.zst",
"mingw-w64-readline": ".src.tar.zst",
"mingw-w64-tcl": ".src.tar.zst",
"mingw-w64-termcap": ".src.tar.zst",
"mingw-w64-tk": ".src.tar.zst",
"mingw-w64-tree-sitter": ".src.tar.zst",
"mingw-w64-tzdata": ".src.tar.zst",
"mingw-w64-wineditline": ".src.tar.zst",
"mingw-w64-zlib": ".src.tar.zst",
"mingw-w64-zstd": ".src.tar.zst",
"mingw-w64-brotli": ".src.tar.zst",
"mingw-w64-gettext": ".src.tar.zst",
"mingw-w64-libdeflate": ".src.tar.zst",
"mingw-w64-libidn2": ".src.tar.zst",
"mingw-w64-libjpeg-turbo": ".src.tar.zst",
"mingw-w64-libtasn1": ".src.tar.zst",
"mingw-w64-pcre2": ".src.tar.zst",
#"mingw-w64-x86_64-libwinpthread":"mingw-w64-x86_64-libwinpthread-git",
#"mingw-w64-x86_64-libtre": "mingw-w64-x86_64-libtre-git",
}
## Currently no packages seem to require this!
# usual source ext is now tar.zst; this overrides that..
SRC_EXT={
# "mingw-w64-brotli": ".src.tar.gz",
}
## Pick up packages only when building for a given architecture
## Currently no packages seem to require this! Unused since Emacs 26
ARCH_PKGS=[]
def immediate_deps(pkg):
@ -296,7 +224,7 @@ def download_source(tarball):
)
print("Downloading {}... done".format(tarball))
print("Copying {} from local".format(tarball))
#print("Copying {} from local".format(tarball))
shutil.copyfile("../emacs-src-cache/{}".format(tarball),
"{}".format(tarball))
@ -311,6 +239,7 @@ def gather_source(deps):
os.chdir("emacs-src")
for pkg in deps:
#print("Parsing pkg name and version from {}".format(pkg))
pkg_name_and_version= \
check_output(["pacman","-Q", pkg]).decode("utf-8").strip()
@ -321,7 +250,7 @@ def gather_source(deps):
pkg_version=pkg_name_components[1]
## source pkgs don't have an architecture in them
pkg_name = re.sub(r"x86_64-","",pkg_name)
pkg_name = re.sub(r"(ucrt-)?x86_64-","",pkg_name)
if(pkg_name in SKIP_SRC_PKGS):
continue
@ -329,17 +258,18 @@ def gather_source(deps):
## Switch names if necessary
pkg_name = MUNGE_SRC_PKGS.get(pkg_name,pkg_name)
## src archive is usually a .tar.gz
## src archive is usually a .tar.zst
if pkg_name in SRC_EXT.keys():
src_ext = SRC_EXT[pkg_name]
else:
src_ext = ".src.tar.gz"
src_ext = ".src.tar.zst"
tarball = "{}-{}{}".format(pkg_name,pkg_version,src_ext)
download_source(tarball)
srczip="../emacs-{}-{}deps-mingw-w64-src.zip".format(EMACS_MAJOR_VERSION,DATE)
srczip="../emacs-{}{}-{}deps-mingw-w64-src.zip".format(
EMACS_MAJOR_VERSION,OUT_TAG, DATE)
tmpzip="{}.tmp".format(srczip)
print("Zipping Dsrc in", os.getcwd(), "as", tmpzip)
check_output_maybe("zip -9 {} *".format(tmpzip), shell=True)
@ -367,6 +297,9 @@ def clean():
#parser.add_argument("emacs", help="emacs executable")
parser.add_argument("-u", help="UCRT64 build",
action="store_true")
parser.add_argument("-s", help="snapshot build",
action="store_true")
@ -382,16 +315,21 @@ def clean():
parser.add_argument("-l", help="list dependencies",
action="store_true")
parser.add_argument("-e", help="extract direct dependencies",
parser.add_argument("-e", help="extract direct dependancies",
action="store_true")
args = parser.parse_args()
do_all=not (args.c or args.r)
#NEW_EMACS=args.emacs
DRY_RUN=args.d
if( args.u ):
DLL_SRC="ucrt64"
OUT_TAG="-ucrt"
if( args.e ):
print("\n".join(init_deps()))

View file

@ -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], [31.0.50], [bug-gnu-emacs@gnu.org], [],
AC_INIT([GNU Emacs], [32.0.50], [bug-gnu-emacs@gnu.org], [],
[https://www.gnu.org/software/emacs/])
if test "$XCONFIGURE" = "android"; then
@ -1810,7 +1810,9 @@ AS_IF([test $gl_gcc_warnings = no],
;;
esac
AS_IF([test $gl_gcc_warnings = yes],
[WERROR_CFLAGS=-Werror],
[WERROR_CFLAGS=-Werror
# Work around GCC bug 125116.
gl_WARN_ADD([-Wno-analyzer-allocation-size])],
[# Use -fanalyzer and related options only if --enable-gcc-warnings,
# as they slow GCC considerably.
nw="$nw -fanalyzer -Wno-analyzer-double-free -Wno-analyzer-malloc-leak"
@ -3099,14 +3101,13 @@ if test "${HAVE_W32}" = "yes"; then
# the rc file), not a linker script.
W32_RES_LINK="-Wl,emacs.res"
else
W32_OBJ="$W32_OBJ w32.o w32console.o w32heap.o w32inevt.o w32proc.o"
W32_OBJ="$W32_OBJ w32.o w32console.o w32heap.o w32image.o w32inevt.o w32proc.o"
dnl FIXME: This should probably be supported for Cygwin/w32 as
dnl well, but the Cygwin build needs to link against -lgdiplus
if test "${with_native_image_api}" = yes; then
AC_DEFINE([HAVE_NATIVE_IMAGE_API], [1],
[Define to use native OS APIs for images.])
NATIVE_IMAGE_API="yes (w32)"
W32_OBJ="$W32_OBJ w32image.o"
fi
W32_LIBS="$W32_LIBS -lwinmm -lgdi32 -lcomdlg32"
W32_LIBS="$W32_LIBS -lmpr -lwinspool -lole32 -lcomctl32"
@ -4476,11 +4477,10 @@ XWIDGETS_OBJ=
if test "$with_xwidgets" != "no"; then
if test "$USE_GTK_TOOLKIT" = "GTK3" && test "$window_system" != "none"; then
WEBKIT_REQUIRED=2.12
WEBKIT_BROKEN=2.41.92
WEBKIT_MODULES="webkit2gtk-4.1 >= $WEBKIT_REQUIRED webkit2gtk-4.1 < $WEBKIT_BROKEN"
WEBKIT_MODULES="webkit2gtk-4.1 >= $WEBKIT_REQUIRED"
EMACS_CHECK_MODULES([WEBKIT], [$WEBKIT_MODULES])
if test "$HAVE_WEBKIT" = "no"; then
WEBKIT_MODULES="webkit2gtk-4.0 >= $WEBKIT_REQUIRED webkit2gtk-4.0 < $WEBKIT_BROKEN"
WEBKIT_MODULES="webkit2gtk-4.0 >= $WEBKIT_REQUIRED"
EMACS_CHECK_MODULES([WEBKIT], [$WEBKIT_MODULES])
fi
HAVE_XWIDGETS=$HAVE_WEBKIT
@ -5120,6 +5120,7 @@ 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])
AC_SUBST_FILE([module_env_snippet_32])
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"
@ -5127,6 +5128,7 @@ 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"
module_env_snippet_32="$srcdir/src/module-env-32.h"
emacs_major_version=`AS_ECHO([$PACKAGE_VERSION]) | sed 's/[[.]].*//'`
AC_SUBST([emacs_major_version])

View file

@ -22,7 +22,8 @@ the distribution.
@c and anyone who has made major enhancements in Emacs
@c that many users would notice and consider important.
@c Note this file is only used ifnottex; otherwise a shorter version in
@c emacs.texi is used.
@c emacs.texi is used. Adding a name to this list should entail adding
@c it to the list in emacs.texi too.
@itemize @bullet
@item

View file

@ -188,6 +188,22 @@ appears in the @file{*compilation*} buffer. (This variable can also
have the values @code{if-location-known} and @code{first-known}, which
modify the conditions for automatically visiting the error locus.)
@vindex compilation-search-path
@vindex compilation-search-extra-path
The actual locus of an error message is determined by
@code{compilation-search-path}, a list of directory names. By default,
Emacs visits the file indicated in the error message under the directory
where the compilation happens, represented by the special directory name
@code{nil} in the default value for @code{compilation-search-path}
(i.e. @code{(nil)}). To make Emacs try to find the file under a
different directory (e.g. when compiling a nested project), customize
@code{compilation-search-path} to include that directory. For
directory-local customization (@pxref{Directory Variables}), prefer
setting @code{compilation-search-extra-path} instead, which Emacs
considers in addition to @code{compilation-search-path}. Entries in
@code{compilation-search-extra-path} take precedence over entries in
@code{compilation-search-path}.
Compilation mode provides the following additional commands. These
commands can also be used in @file{*grep*} buffers, where the
hyperlinks are search matches rather than error messages (@pxref{Grep
@ -1875,6 +1891,16 @@ Emacs Lisp expressions. Type @kbd{M-x ielm} to create an
@file{*ielm*} buffer which uses this mode. For more information, see
that command's documentation.
@cindex persistent *scratch* buffer
By default, the @file{*scratch*} buffer is not associated with any
file. Therefore, any text in the buffer is lost when you quit Emacs.
If you prefer, you can use Remember mode's notes buffer feature to make
Emacs save and reload the contents of @file{*scratch*}. Customize the
variable @code{initial-buffer-choice} to the symbol
@code{remember-notes} and the variable @code{remember-notes-buffer-name}
to the string @code{"*scratch*"} to achieve this. See also @xref{Quick
Start,,, remember, the Remember mode manual}.
@node External Lisp
@section Running an External Lisp
@cindex Lisp mode

View file

@ -260,9 +260,14 @@ on. To invoke a Lisp program, use the @samp{-batch} option in
conjunction with one or more of @samp{-l}, @samp{-f} or @samp{--eval}
(@pxref{Action Arguments}). @xref{Command Example}, for an example.
@vindex kill-emacs-on-sigint
In batch mode, Emacs does not display the text being edited, and the
standard terminal interrupt characters such as @kbd{C-z} and @kbd{C-c}
have their usual effect. Emacs functions that normally print a
have their usual effect: for @kbd{C-c} that effect is either to
exit Emacs or to signal @code{quit}, depending on the variable
@code{kill-emacs-on-sigint}.
Emacs functions that normally print a
message in the echo area will print to either the standard output
stream (@code{stdout}) or the standard error stream (@code{stderr})
instead. (To be precise, functions like @code{prin1}, @code{princ}
@ -1024,19 +1029,26 @@ colored display.
@itemx ansi8
Turn on the color support unconditionally, and use color commands
specified by the ANSI escape sequences for the 8 standard colors.
@item 8bit
Turn on support for 8-bit (256 color) display if available.
Currently this option is effective on MS-Windows (10+) only.
On other systems, maximal color support is enabled automatically.
@item 24bit
Turn on support for 24-bit (true color) display if available.
Currently this option is effective on MS-Windows (10+) only.
On other systems, 24-bit color is enabled automatically if supported.
@item @var{num}
Use color mode for @var{num} colors. If @var{num} is @minus{}1, turn off
color support (equivalent to @samp{never}); if it is 0, use the
default color support for this terminal (equivalent to @samp{auto});
otherwise use an appropriate standard mode for @var{num} colors.
Depending on your terminal's capabilities, Emacs might be able to turn
on a color mode for 8, 16, 88, or 256 as the value of @var{num}. If
there is no mode that supports @var{num} colors, Emacs acts as if
@var{num} were 0, i.e., it uses the terminal's default color support
mode.
on a color mode for 8, 16, 88, 256, or 16777216 as the value of @var{num}.
If there is no mode that supports @var{num} colors, Emacs acts as if
@var{num} were 0, i.e., it uses the terminal's default color support mode.
@end table
This option has no effect on MS-Windows and MS-DOS.
This option has no effect on MS-DOS, nor MS-Windows prior to Windows 10.
@cindex colors on character terminal, changing during session
@cindex character terminal, change color mode

View file

@ -761,7 +761,7 @@ that operates on the marked files finishes.
@cindex operating on files in Dired
This section describes the basic Dired commands to operate on one file
or several files. All of these commands are capital letters; all of
or several files. Many of these commands are capital letters; all of
them use the minibuffer, either to read an argument or to ask for
confirmation, before they act. All of them let you specify the
files to manipulate in these ways:
@ -1022,6 +1022,21 @@ single archive anywhere on the file system. The default archive is
controlled by the @code{dired-compress-directory-default-suffix} user
option. Also see @code{dired-compress-files-alist}.
@cindex Dired and version control
@findex dired-vc-next-action
@kindex C-x v v @r{(Dired)}
@item C-x v v
@itemx C-x v = @r{(Dired)}
@itemx C-x v l @r{(Dired)}
If the directory you are visiting is under version control
(@pxref{Version Control}), then the normal VC commands will operate on
the selected files. For example, @kbd{C-x v v} invokes
@code{dired-vc-next-action}, which does the same as
@code{vc-next-action} in a buffer visiting a file under version control
(@pxref{Basic VC Editing}). Similarly, @kbd{C-x v =} shows the diffs
between the marked files and their committed versions, and @code{C-x v l}
shows the VC change history for the marked files.
@findex epa-dired-do-decrypt
@kindex :d @r{(Dired)}
@cindex decrypting files (in Dired)
@ -1947,11 +1962,6 @@ file/directory listings. To change this, customize the options
@code{dired-hide-details-hide-symlink-targets} and
@code{dired-hide-details-hide-information-lines}, respectively.
@cindex Dired and version control
If the directory you are visiting is under version control
(@pxref{Version Control}), then the normal VC diff and log commands
will operate on the selected files.
@findex dired-compare-directories
The command @kbd{M-x dired-compare-directories} is used to compare
the current Dired buffer with another directory. It marks all the files

View file

@ -811,6 +811,22 @@ Similar to @code{mode-line} for a window's tab line, which appears
at the top of a window with tabs representing window buffers.
@xref{Tab Line}.
The @code{tab-line-active} and @code{tab-line-inactive} faces (which
are the ones actually used on the tab lines) inherit from this face.
@cindex faces for tab lines
@item tab-line-active
Like @code{tab-line}, but used for the tab line of the currently
selected window. This face inherits from @code{tab-line}, so changes
in that face affect tab lines in all windows.
@cindex @code{tab-line-inactive} face
@item tab-line-inactive
Like @code{tab-line}, but used for tab lines of the windows other
than the selected one (if those windows have a tab line). This face
inherits from @code{tab-line}, so changes in that face affect tab
lines in all windows.
@cindex @code{vertical-border} face
@item vertical-border
This face is used for the vertical divider between windows on text

View file

@ -872,7 +872,7 @@ Miscellaneous Commands and Features of VC
* VC Delete/Rename:: Deleting and renaming version-controlled files.
* Revision Tags:: Symbolic names for revisions.
* Merge Bases:: The most recent revision existing on both branches.
* Outstanding Changes:: Diffs including all outstanding changes on a branch.
* Unintegrated Changes:: Diffs including all unintegrated changes on a branch.
* Other Working Trees:: Multiple sets of workfiles.
* Version Headers:: Inserting version control headers into working files.
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
@ -1463,108 +1463,119 @@ USA
@node Acknowledgments
@unnumberedsec Acknowledgments
@c Nowadays we add names to this list only while simultaneously adding
@c them to ack.texi. There remain lots of names here that aren't in
@c ack.texi for historical reasons.
@c It's hard to update this fairly.
@c I wonder if it would be better to drop it in favor of AUTHORS?
Contributors to GNU Emacs include Jari Aalto, Eric Abrahamsen, Per Abrahamsen, Tomas
Abrahamsson, Jay K. Adams, Alon Albert, Michael Albinus, Nagy
Andras, Benjamin Andresen, Ralf Angeli, Dmitry Antipov, Joe Arceneaux, Emil @AA{}str@"om,
Miles Bader, David Bakhash, Juanma Barranquero, Eli Barzilay, Thomas
Baumann, Steven L. Baur, Jay Belanger, Alexander L. Belikoff,
Thomas Bellman, Scott Bender, Boaz Ben-Zvi, Sergey Berezin, Stephen Berman, Jonas Bernoulli, Karl
Berry, Anna M. Bigatti, Ray Blaak, Martin Blais, Jim Blandy, Johan
Bockg@aa{}rd, Jan B@"ocker, Joel Boehland, Lennart Borgman, Per Bothner,
Terrence Brannon, Frank Bresz, Peter Breton, Emmanuel Briot, Kevin
Broadey, Vincent Broman, Michael Brouwer, David M. Brown, Ken Brown, Stefan Bruda,
Damien Cassou, Daniel Colascione,
Georges Brun-Cottan, Joe Buehler, Scott Byer, W@l{}odek Bzyl, Tino Calancha,
Bill Carpenter, Per Cederqvist, Hans Chalupsky, Chris Chase, Bob
Chassell, Andrew Choi, Chong Yidong, Sacha Chua, Stewart Clamen, James
Clark, Mike Clarkson, Glynn Clements, Andrea Corallo, Andrew Cohen, Daniel Colascione,
Christoph Conrad, Ludovic Court@`es, Andrew Csillag,
Toby Cubitt, Baoqiu Cui, Doug Cutting, Mathias Dahl, Yue Daian, Julien Danjou, Satyaki
Das, Vivek Dasmohapatra, Dan Davison, Michael DeCorte, Gary Delp, Nachum
Dershowitz, Dave Detlefs, Matthieu Devin, Christophe de Dinechin, Eri
Ding, Jan Dj@"arv, Lawrence R. Dodd, Carsten Dominik, Scott Draves,
Benjamin Drieu, Viktor Dukhovni, Jacques Duthen, Dmitry Dzhus, John
Eaton, Rolf Ebert, Carl Edman, David Edmondson, Paul Eggert, Stephen
Eglen, Christian Egli, Torbj@"orn Einarsson, Helmut Eller, Tsugutomo
Enami, David Engster, Hans Henrik Eriksen, Michael Ernst, Ata Etemadi, Frederick
Farnbach, Oscar Figueiredo, Jared Finder, Fred Fish, Steve Fisk, Thomas Fitzsimmons,
Karl Fogel, Gary Foster, Eric S. Fraga, Romain Francoise, Noah Friedman, Andreas
Fuchs, Shigeru Fukaya, Xue Fuqiao, Hallvard Furuseth, Keith Gabryelski, Peter S.
Galbraith, Kevin Gallagher, Fabi@'an E. Gallina, Kevin Gallo, Juan Le@'en Lahoz Garc@'ia,
Contributors to GNU Emacs include Jari Aalto, Eric Abrahamsen, Per
Abrahamsen, Tomas Abrahamsson, Jay K. Adams, Alon Albert, Michael
Albinus, Nagy Andras, Benjamin Andresen, Ralf Angeli, Dmitry Antipov,
Aur@'elien Aptel, Joe Arceneaux, Emil @AA{}str@"om, Miles Bader, David
Bakhash, Juanma Barranquero, Eli Barzilay, Thomas Baumann, Steven
L. Baur, Jay Belanger, Alexander L. Belikoff, Thomas Bellman, Scott
Bender, Boaz Ben-Zvi, Sergey Berezin, Stephen Berman, Jonas Bernoulli,
Karl Berry, Anna M. Bigatti, Ray Blaak, David Blacka, Martin Blais, Jim
Blandy, Johan Bockg@aa{}rd, Jan B@"ocker, Joel Boehland, Lennart
Borgman, Per Bothner, Terrence Brannon, Frank Bresz, Peter Breton,
Emmanuel Briot, Kevin Broadey, Vincent Broman, Michael Brouwer, David
M. Brown, Ken Brown, Stefan Bruda, Georges Brun-Cottan, Joe Buehler,
Scott Byer, W@l{}odek Bzyl, Tino Calancha, Bill Carpenter, Damien
Cassou, Per Cederqvist, Hans Chalupsky, Chris Chase, Bob Chassell,
Jihyun Cho, Andrew Choi, Chong Yidong, Sacha Chua, Stewart Clamen, James
Clark, Mike Clarkson, Glynn Clements, Andrea Corallo, Andrew Cohen,
Daniel Colascione, Christoph Conrad, Ludovic Court@`es, Andrew Csillag,
Toby Cubitt, Baoqiu Cui, Doug Cutting, Mathias Dahl, Yue Daian, Julien
Danjou, Satyaki Das, Vivek Dasmohapatra, Dan Davison, Michael DeCorte,
Gary Delp, Nachum Dershowitz, Dave Detlefs, Matthieu Devin, Christophe
de Dinechin, Eric Ding, Jan Dj@"arv, Lawrence R. Dodd, Carsten Dominik,
Scott Draves, Benjamin Drieu, Viktor Dukhovni, Jacques Duthen, Dmitry
Dzhus, John Eaton, Rolf Ebert, Carl Edman, David Edmondson, Paul Eggert,
Stephen Eglen, Christian Egli, Torbj@"orn Einarsson, Helmut Eller,
Tsugutomo Enami, David Engster, Hans Henrik Eriksen, Michael Ernst, Ata
Etemadi, Frederick Farnbach, Oscar Figueiredo, Jared Finder, Fred Fish,
Steve Fisk, Thomas Fitzsimmons, Karl Fogel, Gary Foster, Eric S. Fraga,
Romain Francoise, Noah Friedman, Andreas Fuchs, Shigeru Fukaya, Xue
Fuqiao, Hallvard Furuseth, Keith Gabryelski, Peter S. Galbraith, Kevin
Gallagher, Fabi@'an E. Gallina, Kevin Gallo, Juan Le@'en Lahoz Garc@'ia,
Howard Gayle, Daniel German, Stephen Gildea, Julien Gilles, David
Gillespie, Bob Glickstein, Nicolas Goaziou, Deepak Goel, David De La Harpe Golden, Boris
Goldowsky, David Goodger, Chris Gray, Kevin Greiner, Michelangelo Grigni, Odd
Gripenstam, Kai Gro@ss{}johann, Michael Gschwind, Bastien Guerry, Henry
Guillaume, Dmitry Gutov, Doug Gwyn, Bruno Haible, Ken'ichi Handa, Lars Hansen, Chris
Hanson, Jesper Harder, Alexandru Harsanyi, K. Shane Hartman, John
Heidemann, Jon K. Hellan, Magnus Henoch, Markus Heritsch, Dirk
Herrmann, Karl Heuer, Manabu Higashida, Konrad Hinsen, Torsten Hilbrich, Anders Holst,
Jeffrey C. Honig, J@"urgen H@"otzel, Tassilo Horn, Kurt Hornik, Khaled Hosny, Tom Houlder, Joakim
Hove, Denis Howe, Lars Ingebrigtsen, Andrew Innes, Seiichiro Inoue,
Philip Jackson, Martyn Jago, Pavel Janik, Paul Jarc, Ulf Jasper,
Thorsten Jolitz, Michael K. Johnson, Kyle Jones, Terry Jones, Simon
Josefsson, Alexandre Julliard, Arne J@o{}rgensen, Tomoji Kagatani,
Brewster Kahle, Tokuya Kameshima, Lute Kamstra, Stefan Kangas, Ivan Kanis, David
Gillespie, Bob Glickstein, Nicolas Goaziou, Deepak Goel, David De La
Harpe Golden, Boris Goldowsky, David Goodger, Jacob Gore, Chris Gray,
Kevin Greiner, Michelangelo Grigni, Odd Gripenstam, Kai Gro@ss{}johann,
Michael Gschwind, Bastien Guerry, Henry Guillaume, Dmitry Gutov, Doug
Gwyn, Bruno Haible, Ken'ichi Handa, Lars Hansen, Chris Hanson, Jesper
Harder, Alexandru Harsanyi, K. Shane Hartman, John Heidemann, Jon
K. Hellan, Magnus Henoch, Markus Heritsch, Dirk Herrmann, Karl Heuer,
Manabu Higashida, Joe Hildebrand, Konrad Hinsen, Torsten Hilbrich,
Anders Holst, Jeffrey C. Honig, J@"urgen H@"otzel, Tassilo Horn, Kurt
Hornik, Khaled Hosny, Tom Houlder, Joakim Hove, Denis Howe, Lars
Ingebrigtsen, Andrew Innes, Seiichiro Inoue, Philip Jackson, Martyn
Jago, Pavel Janik, Paul Jarc, Ulf Jasper, Thorsten Jolitz, Michael
K. Johnson, Kyle Jones, Terry Jones, Simon Josefsson, Alexandre
Julliard, Arne J@o{}rgensen, Jambunathan K, Tomoji Kagatani, Brewster
Kahle, Tokuya Kameshima, Lute Kamstra, Stefan Kangas, Ivan Kanis, David
Kastrup, David Kaufman, Henry Kautz, Taichi Kawabata, Taro Kawagishi,
Howard Kaye, Michael Kifer, Richard King, Wilhelm Kirschbaum, Peter Kleiweg,
Karel Kl@'i@v{c}, Shuhei Kobayashi, Pavel Kobyakov, Larry K. Kolodney, David
Howard Kaye, Michael Kifer, Richard King, Peter Kleiweg,
M. Koppelman, Koseki Yoshinori, Robert Krawitz, Sebastian Kremer,
Ryszard Kubiak, Tak Kunihiro, Igor Kuzmin, David K@aa{}gedal, Daniel LaLiberte, Karl
Landstrom, Mario Lang, Aaron Larson, James R. Larus, Gemini Lasswell, Vinicius Jose
Latorre, Werner Lemberg, Frederic Lepied, Peter Liljenberg, Christian
Limpach, Lars Lindberg, Chris Lindblad, Anders Lindgren, Thomas Link,
Juri Linkov, Francis Litterio, Sergey Litvinov, Leo Liu, Emilio C. Lopes,
Martin Lorentzson, Dave Love, Eric Ludlam, K@'aroly L@H{o}rentey, Sascha
L@"udecke, Greg McGary, Roland McGrath, Michael McNamara, Alan Mackenzie,
Christopher J. Madsen, Neil M. Mager, Arni Magnusson, Artur Malabarba, Ken Manheimer, Bill Mann,
Brian Marick, Simon Marshall, Bengt Martensson, Charlie Martin,
Yukihiro Matsumoto, Tomohiro Matsuyama, David Maus, Thomas May, Will Mengarini, David
Megginson, Jimmy Aguilar Mena, Stefan Merten, Ben A. Mesander, Wayne Mesard, Brad
Miller, Lawrence Mitchell, Richard Mlynarik, Gerd M@"ollmann, Dani Moncayo, Stefan
Monnier, Keith Moore, Jan Moringen, Morioka Tomohiko, Glenn Morris,
Don Morrison, John Muhl, Diane Murray, Riccardo Murri, Sen Nagata, Erik Naggum,
Gergely Nagy, Nobuyoshi Nakada, Thomas Neumann, Mike Newton, Thien-Thi Nguyen,
Jurgen Nickelsen, Dan Nicolaescu, Hrvoje Nik@v{s}i@'c, Jeff Norden,
Andrew Norman, Theresa O'Connor, Kentaro Ohkouchi, Christian Ohler,
Kenichi Okada, Alexandre Oliva, Bob Olson, Michael Olson, Takaaki Ota,
Mark Oteiza, Pieter E. J. Pareit, Ross Patterson, David Pearson, Juan Pechiar,
Jeff Peck, Damon Anton Permezel, Tom Perrine, William M. Perry, Per
Persson, Jens Petersen, Nicolas Petton, Daniel Pfeiffer, Justus Piater, Richard L.
Pieri, Fred Pierresteguy, Fran@,{c}ois Pinard, Daniel Pittman, Christian
Plaunt, Alexander Pohoyda, David Ponce, Noam Postavsky, Francesco A. Potort@`i,
Michael D. Prange, Mukesh Prasad, Steve Purcell, Vincenzo Pupillo, Ken Raeburn,
Marko Rahamaa, Ashwin Ram, Eric S. Raymond, Paul Reilly, Edward M. Reingold, David
Reitter, Alex Rezinsky, Rob Riepel, Lara Rios, Adrian Robert, Nick
Roberts, Roland B. Roberts, John Robinson, Denis B. Roegel, Danny
Roozendaal, Sebastian Rose, William Rosenblatt, Markus Rost, Guillermo
J. Rozas, Martin Rudalics, Ivar Rummelhoff, Jason Rumney, Wolfgang
Rupprecht, Benjamin Rutt, Kevin Ryde, Phil Sainty, James B. Salem, Masahiko Sato,
Timo Savola, Jorgen Sch@"afer, Holger Schauer, William Schelter, Ralph
Schleicher, Gregor Schmid, Michael Schmidt, Ronald S. Schnell,
Philippe Schnoebelen, Jan Schormann, Alex Schroeder, Stefan Schoef,
Rainer Sch@"opf, Raymond Scholz, Eric Schulte, Andreas Schwab, Randal
Schwartz, Oliver Seidel, Daniel Semyonov, Manuel Serrano, Paul Sexton,
Hovav Shacham, Stanislav Shalunov, Marc Shapiro, Richard Sharman, Olin
Shivers, Tibor @v{S}imko, Espen Skoglund, Rick Sladkey, Lynn Slater, Chris Smith,
David Smith, JD Smith, Paul D. Smith, Wilson Snyder, William Sommerfeld, Simon
South, Andre Spiegel, Michael Staats, Thomas Steffen, Ulf Stegemann,
Reiner Steib, Sam Steingold, Ake Stenhoff, Philipp Stephani, Peter Stephenson, Ken
Stevens, Andy Stewart, Jonathan Stigelman, Martin Stjernholm, Kim F.
Howard Kaye, Michael Kifer, Richard King, Wilhelm Kirschbaum, Peter
Kleiweg, Karel Kl@'i@v{c}, Shuhei Kobayashi, Pavel Kobyakov, Larry
K. Kolodney, David Howard Kaye, Michael Kifer, Richard King, Peter
Kleiweg, M. Koppelman, Koseki Yoshinori, Robert Krawitz, Sebastian
Kremer, Ryszard Kubiak, Tak Kunihiro, Igor Kuzmin, David K@aa{}gedal,
Daniel LaLiberte, Karl Landstrom, Mario Lang, Aaron Larson, James
R. Larus, Gemini Lasswell, Vinicius Jose Latorre, Werner Lemberg,
Frederic Lepied, Peter Liljenberg, Christian Limpach, Lars Lindberg,
Chris Lindblad, Anders Lindgren, Thomas Link, Juri Linkov, Francis
Litterio, Sergey Litvinov, Leo Liu, Emilio C. Lopes, Martin Lorentzson,
Dave Love, Eric Ludlam, K@'aroly L@H{o}rentey, Sascha L@"udecke, Greg
McGary, Roland McGrath, Michael McNamara, Alan Mackenzie, Christopher
J. Madsen, Neil M. Mager, Arni Magnusson, Artur Malabarba, Ken
Manheimer, Bill Mann, Brian Marick, Simon Marshall, Bengt Martensson,
Charlie Martin, Yukihiro Matsumoto, Tomohiro Matsuyama, David Maus,
Thomas May, Will Mengarini, David Megginson, Jimmy Aguilar Mena, Stefan
Merten, Ben A. Mesander, Wayne Mesard, Brad Miller, Lawrence Mitchell,
Richard Mlynarik, Gerd M@"ollmann, Dani Moncayo, Stefan Monnier, David
Moore, Keith Moore, Jan Moringen, Morioka Tomohiko, Glenn Morris, Don
Morrison, John Muhl, Diane Murray, Riccardo Murri, Sen Nagata, Erik
Naggum, Gergely Nagy, Nobuyoshi Nakada, Thomas Neumann, Mike Newton,
Thien-Thi Nguyen, Jurgen Nickelsen, Dan Nicolaescu, Hrvoje Nik@v{s}i@'c,
Jeff Norden, Andrew Norman, Theresa O'Connor, Kentaro Ohkouchi,
Christian Ohler, Kenichi Okada, Alexandre Oliva, Bob Olson, Michael
Olson, Takaaki Ota, Mark Oteiza, Pieter E. J. Pareit, Ross Patterson,
David Pearson, Juan Pechiar, Jeff Peck, Damon Anton Permezel, Tom
Perrine, William M. Perry, Per Persson, Jens Petersen, Nicolas Petton,
Daniel Pfeiffer, Justus Piater, Richard L. Pieri, Fred Pierresteguy,
Fran@,{c}ois Pinard, Daniel Pittman, Christian Plaunt, Alexander
Pohoyda, David Ponce, Noam Postavsky, Francesco A. Potort@`i, Michael
D. Prange, Mukesh Prasad, Steve Purcell, Vincenzo Pupillo, Jim Radford,
Ken Raeburn, Marko Rahamaa, Ashwin Ram, Eric S. Raymond, Paul Reilly,
Edward M. Reingold, David Reitter, Alex Rezinsky, Rob Riepel, Lara Rios,
Adrian Robert, Nick Roberts, Roland B. Roberts, John Robinson, Denis
B. Roegel, Danny Roozendaal, Sebastian Rose, William Rosenblatt, Markus
Rost, Guillermo J. Rozas, Martin Rudalics, Ivar Rummelhoff, Jason
Rumney, Wolfgang Rupprecht, Benjamin Rutt, Kevin Ryde, Phil Sainty,
James B. Salem, Masahiko Sato, Timo Savola, Jorgen Sch@"afer, Holger
Schauer, William Schelter, Ralph Schleicher, Gregor Schmid, Michael
Schmidt, Ronald S. Schnell, Philippe Schnoebelen, Jan Schormann, Alex
Schroeder, Stefan Schoef, Rainer Sch@"opf, Raymond Scholz, Eric Schulte,
Andreas Schwab, Randal Schwartz, Oliver Seidel, Daniel Semyonov, Manuel
Serrano, Paul Sexton, Hovav Shacham, Stanislav Shalunov, Marc Shapiro,
Richard Sharman, Olin Shivers, Tibor @v{S}imko, Espen Skoglund, Rick
Sladkey, Lynn Slater, Chris Smith, David Smith, JD Smith, Paul D. Smith,
Wilson Snyder, William Sommerfeld, Simon South, Andre Spiegel, Michael
Staats, Richard M. Stallman, Thomas Steffen, Ulf Stegemann, Reiner
Steib, Sam Steingold, Ake Stenhoff, Philipp Stephani, Peter Stephenson,
Ken Stevens, Andy Stewart, Jonathan Stigelman, Martin Stjernholm, Kim F.
Storm, Steve Strassmann, Christopher Suckling, Olaf Sylvester, Naoto
Takahashi, Steven Tamm, Jan Tatarik, Jo@~ao T@'avora, Luc Teirlinck,
Jean-Philippe Theberge, Jens T.@: Berger Thielemann, Spencer Thomas,
Jim Thompson, Theodor Thornhill, Toru Tomabechi, David O'Toole, Markus Triska,
Tom Tromey, Eli Tziperman, Daiki Ueno, Masanobu Umeda, Rajesh Vaidheeswarran, Neil
W. Van Dyke, Didier Verna, Joakim Verona, Ulrik Vieth, Geoffrey
Voelker, Johan Vromans, Inge Wallin, John Paul Wallington, Colin
Walters, Barry Warsaw, Christoph Wedler, Ilja Weis, Zhang Weize,
Morten Welinder, Joseph Brian Wells, Rodney Whitby, John Wiegley,
Sascha Wilde, Ed Wilkinson, Mike Williams, Roland Winkler, Bill
Wohler, Steven A. Wood, Dale R. Worley, Francis J. Wright, Felix
S. T. Wu, Tom Wurgler, Yamamoto Mitsuharu, Po Lu, Katsumi Yamaoka,
Jean-Philippe Theberge, Jens T.@: Berger Thielemann, Spencer Thomas, Jim
Thompson, Theodor Thornhill, Toru Tomabechi, Andy Oram, David O'Toole,
Markus Triska, Tom Tromey, Eli Tziperman, Daiki Ueno, Masanobu Umeda,
Rajesh Vaidheeswarran, Neil W. Van Dyke, Didier Verna, Joakim Verona,
Ulrik Vieth, Geoffrey Voelker, Johan Vromans, Inge Wallin, John Paul
Wallington, Colin Walters, Barry Warsaw, Christoph Wedler, Ilja Weis,
Zhang Weize, Morten Welinder, Joseph Brian Wells, Rodney Whitby, Sean
Whitton, John Wiegley, Sascha Wilde, Ed Wilkinson, Mike Williams, Roland
Winkler, Bill Wohler, Steven A. Wood, Dale R. Worley, Francis J. Wright,
Felix S. T. Wu, Tom Wurgler, Yamamoto Mitsuharu, Po Lu, Katsumi Yamaoka,
Masatake Yamato, Jonathan Yavner, Ryan Yeske, Ilya Zakharevich, Milan
Zamazal, Victor Zandy, Eli Zaretskii, Jamie Zawinski, Andrew Zhilin,
Shenghuo Zhu, Piotr Zieli@'nski, Ian T. Zimmermann, Reto Zimmermann,

View file

@ -123,7 +123,7 @@ expansion, type @samp{$$}. This pair is converted to a single
@samp{$} at the same time that variable substitution is performed for
a single @samp{$}. Alternatively, quote the whole file name with
@samp{/:} (@pxref{Quoted File Names}). File names which begin with a
literal @samp{~} should also be quoted with @samp{/:}.
literal @samp{~} should be quoted with @samp{/:./}.
You can include non-@acronym{ASCII} characters in file names.
@xref{File Name Coding}.
@ -2408,6 +2408,8 @@ remote file name, you can quote just the local part.
@samp{/:} can also prevent @samp{~} from being treated as a special
character for a user's home directory. For example, @file{/:/tmp/~hack}
refers to a file whose name is @file{~hack} in directory @file{/tmp}.
If @samp{~} is at the beginning of the file name, it must be quoted with
@samp{/:./}, like in @samp{/:./~foo/bar}.
Quoting with @samp{/:} is also a way to enter in the minibuffer a
file name that contains @samp{$}. In order for this to work, the

View file

@ -142,6 +142,7 @@ undo data, then it is probably a bug and you should report it.
@node Transpose
@section Transposing Text
@cindex transposing text
@table @kbd
@item C-t
@ -160,6 +161,14 @@ Transpose two paragraphs (@code{transpose-paragraphs}).
Transpose two regions.
@end table
One of the common editing mistakes is to type characters or words or
sentences in the wrong order. To fix that, you could delete the
incorrectly-typed text and re-type it anew, or you could kill
(@pxref{Erasing}) the text that's in the wrong place and then yank it
(@pxref{Yanking}) in its correct place. But that is inefficient. Emacs
has convenient commands, described in this section, to transpose
characters, words, sentences, etc.
@kindex C-t
@findex transpose-chars
The common error of transposing two characters can be fixed, when they
@ -215,7 +224,10 @@ across four words. @kbd{C-u - C-M-t} would cancel the effect of plain
A numeric argument of zero is assigned a special meaning (because
otherwise a command with a repeat count of zero would do nothing): to
transpose the character (or word or expression or line) ending after
point with the one ending after the mark.
point with the one ending after the mark. So to convert, say, @samp{Bob
and Mary} into @samp{Mary and Bob}, set the mark on @samp{Bob}
(@pxref{Setting Mark}), then move point to @samp{Mary}, and then type
@kbd{C-u 0 M-t}.
@findex transpose-regions
@kbd{M-x transpose-regions} transposes the text between point and

View file

@ -862,7 +862,7 @@ v} to check-out the file and start editing it.
Compare the work files in the current VC fileset with the versions you
started from (@code{vc-diff}). With a prefix argument, prompt for two
revisions of the current VC fileset and compare them. You can also
call this command from a Dired buffer (@pxref{Dired}).
call this command from a Dired buffer (@pxref{Operating on Files}).
@ifnottex
@item M-x vc-ediff
@ -1109,6 +1109,15 @@ but limited to the current fileset.
If you customize @code{vc-use-incoming-outgoing-prefixes} to
non-@code{nil}, this command becomes available on @kbd{C-x v O =}.
@item C-x v E D
Display a combined diff of all changes that will be sent by the next
push operation plus any uncommitted changes.
@item C-x v E =
Display a combined diff of all changes that will be sent by the next
push operation plus any uncommitted changes, but limited to the current
fileset.
@item C-x v h
Display the history of changes made in the region of file visited by
the current buffer (@code{vc-region-history}).
@ -1128,9 +1137,9 @@ Buffer}). If invoked from a buffer visiting a file, the current
fileset consists of that single file, and point in the displayed
@file{*vc-change-log*} buffer is centered at the revision of that
file. If invoked from a VC Directory buffer (@pxref{VC Directory
Mode}) or from a Dired buffer (@pxref{Dired}), the fileset consists of
all the marked files, defaulting to the file shown on the current line
in the directory buffer if no file is marked.
Mode}) or from a Dired buffer (@pxref{Operating on Files}), the fileset
consists of all the marked files, defaulting to the file shown on the
current line in the directory buffer if no file is marked.
If the fileset includes one or more directories, the resulting
@file{*vc-change-log*} buffer shows a short log of changes (one line
@ -1223,6 +1232,17 @@ The difference is that the diffs reported are limited to the current
fileset. Don't forget that actual pull and push operations always
affect the whole working tree, not just the current fileset.
@kindex C-x v E =
@kindex C-x v E D
@findex vc-diff-outgoing-and-edited
@findex vc-root-diff-outgoing-and-edited
Finally, there is also @kbd{C-x v E D}
(@code{vc-root-diff-outgoing-and-edited}) which shows a combined diff of
all changes that would be pushed plus any uncommitted changes. It is
useful to show all work that's present only locally. There is also
@kbd{C-x v E =} (@code{vc-diff-outgoing-and-edited}) which is the same
but limited to the current fileset.
@cindex VC log buffer, commands in
@cindex vc-log buffer
In the @file{*vc-change-log*} buffer, you can use the following keys
@ -1719,7 +1739,7 @@ Do an incremental regular expression search on the fileset
Apart from acting on multiple files, these commands behave much like
their single-buffer counterparts (@pxref{Search}).
@c Outstanding changes commands under 'T' are not mentioned because
@c Unintegrated changes commands under 'T' are not mentioned because
@c these are an advanced feature documented only in vc1-xtra.texi.
The VC Directory buffer additionally defines some branch-related

View file

@ -1200,6 +1200,33 @@ you should set its value in your init file (@pxref{Init File}), either
directly or via @kbd{M-x customize-variable}, which lets you save the
customized value, see @ref{Saving Customizations}.
@findex w32-use-virtual-terminal
@cindex Windows Terminal, Windows Console, MS-Windows
The implementation of display functionality for Windows Console
differs from the implementation for other terminal emulators,
because historically, Windows required use of an idiosyncractic API.
That API limited Windows Console display of Emacs to 16 basic colors.
With the introduction of Windows Terminal, Microsoft implemented
support for ANSI control sequences, modelled on the VT100 and Xterm,
as well as 24-bit RBG color display.
The functions @code{w32-use-virtual-terminal} and
@code{w32-use-virtual-terminal-p} can be used to set and inspect
(respectively) an internal variable which determines whether this newer
mechanism is used for display, or the older one. The internal variable is
automatically set based on your terminal's capabilities on startup.
By default, 24-bit RGB color will be used, but other (8, 16, 256) color
spaces may be used, by passing the @code{--color} command line argument,
or setting the value of the @code{tty-color-mode} frame parameter.
@code{(w32-use-virtual-terminal-p)} evaluates to @code{t} if and only if
the internal variable has a non-zero numerical value, and otherwise to
@code{nil}. If it evaluates to @code{t}, ANSI escape sequences are used
for color, otherwise, the older mechanism is used. The internal variable
can be set by evaluating @code{(w32-use-virtual-terminal x)}, where @code{x} is
@code{t} or @code{nil}: if @code{x} is @code{t} and the feature is supported by
your terminal, it will be enabled. Otherwise, the feature will be disabled.
@ifnottex
@include msdos-xtra.texi
@end ifnottex

View file

@ -11,17 +11,17 @@
This section explains the less-frequently-used features of VC.
@menu
* Change Logs and VC:: Generating a change log file from log entries.
* VC Delete/Rename:: Deleting and renaming version-controlled files.
* Revision Tags:: Symbolic names for revisions.
* Merge Bases:: The most recent revision existing on both branches.
* Outstanding Changes:: Diffs including all outstanding changes on a branch.
* Other Working Trees:: Multiple sets of workfiles.
* Version Headers:: Inserting version control headers into working files.
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
* Preparing Patches:: Preparing and composing patches from within VC.
* VC Auto-Reverting:: Updating buffer contents after VCS operations.
* Rewinding Branches:: Commands to delete revisions from ends of branches.
* Change Logs and VC:: Generating a change log file from log entries.
* VC Delete/Rename:: Deleting and renaming version-controlled files.
* Revision Tags:: Symbolic names for revisions.
* Merge Bases:: The most recent revision existing on both branches.
* Unintegrated Changes:: Diffs including all unintegrated changes on a branch.
* Other Working Trees:: Multiple sets of workfiles.
* Version Headers:: Inserting version control headers into working files.
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
* Preparing Patches:: Preparing and composing patches from within VC.
* VC Auto-Reverting:: Updating buffer contents after VCS operations.
* Rewinding Branches:: Commands to delete revisions from ends of branches.
@end menu
@node Change Logs and VC
@ -293,27 +293,48 @@ on the target branch if you were to merge the source branch into it, and
@kbd{C-x v M L} shows you a log of the changes on the source branch not
yet merged into the target branch.
@node Outstanding Changes
@subsubsection Commands to see all outstanding changes
@cindex outstanding changes
@node Unintegrated Changes
@subsubsection Commands to see all unintegrated changes
@cindex unintegrated changes
@cindex remote unintegrated changes
@table @kbd
@item C-x v T =
Display diffs of changes to the VC fileset since the merge base of this
branch and its upstream counterpart (@code{vc-diff-outstanding}).
branch and its upstream counterpart (@code{vc-diff-unintegrated}).
@item C-x v T D
Display a diff of all changes since the merge base of this branch and
its upstream counterpart (@code{vc-root-diff-outstanding}).
its upstream counterpart (@code{vc-root-diff-unintegrated}).
@item C-x v T l
Display log messages for changes to the VC fileset since the merge base
of this branch and its upstream counterpart
(@code{vc-log-outstanding}).
(@code{vc-log-unintegrated}).
@item C-x v T L
Display log messages for all changes since the merge base of this branch
and its upstream counterpart (@code{vc-root-log-outstanding}).
and its upstream counterpart (@code{vc-root-log-unintegrated}).
@item C-x v T R =
Display diffs of remote changes to the VC fileset since the merge base
of this topic branch and its upstream counterpart
(@code{vc-diff-remote-unintegrated}).
@item C-x v T R D
Display a diff of all remote changes since the merge base of this topic
branch and its upstream counterpart
(@code{vc-root-diff-remote-unintegrated}).
@item C-x v T R l
Display log messages for remote changes to the VC fileset since the
merge base of this topic branch and its upstream counterpart
(@code{vc-log-remote-unintegrated}).
@item C-x v T R L
Display log messages for all remote changes since the merge base of this
topic branch and its upstream counterpart
(@code{vc-root-log-remote-unintegrated}).
@end table
For decentralized version control systems (@pxref{VCS Repositories}),
@ -324,21 +345,21 @@ both when working on a single branch and when developing features on a
separate branch (@pxref{Branches}). These two cases are conceptually
distinct, and so we will introduce them separately.
First, consider working on a single branch. @dfn{Outstanding changes}
First, consider working on a single branch. @dfn{Unintegrated changes}
are those which you haven't yet pushed upstream. This includes both
unpushed commits and uncommitted changes in your working tree. In many
cases the reason these changes are not pushed yet is that they are not
finished: the changes committed so far don't make sense in isolation.
@kindex C-x v T =
@findex vc-diff-outstanding
@findex vc-diff-unintegrated
@kindex C-x v T D
@findex vc-root-diff-outstanding
Type @kbd{C-x v T D} (@code{vc-root-diff-outstanding}) to display a
@findex vc-root-diff-unintegrated
Type @kbd{C-x v T D} (@code{vc-root-diff-unintegrated}) to display a
summary of all these changes, committed and uncommitted. This summary
is in the form of a diff of what committing and pushing (@pxref{Pulling
/ Pushing}) all these changes would do to the upstream repository. You
can use @kbd{C-x v T =} (@code{vc-diff-outstanding}) instead to limit
can use @kbd{C-x v T =} (@code{vc-diff-unintegrated}) instead to limit
the display of changes to the current VC fileset. (The difference
between @w{@kbd{C-x v T D}} and @w{@kbd{C-x v T =}} is like the
difference between @kbd{C-x v D} and @kbd{C-x v =} (@pxref{Old
@ -350,13 +371,13 @@ commands, you can use a prefix argument to specify a particular upstream
location.}
@kindex C-x v T l
@findex vc-log-outstanding
@findex vc-log-unintegrated
@kindex C-x v T L
@findex vc-root-log-outstanding
Type @kbd{C-x v T L} (@code{vc-root-log-outstanding}) to display a
@findex vc-root-log-unintegrated
Type @kbd{C-x v T L} (@code{vc-root-log-unintegrated}) to display a
summary of the same changes in the form of a revision log; this does not
include uncommitted changes. You can use @kbd{C-x v T l}
(@code{vc-log-outstanding}) instead to limit the display of changes to
(@code{vc-log-unintegrated}) instead to limit the display of changes to
the current VC fileset.
Second, consider developing a feature on a separate branch. Call this
@ -369,11 +390,11 @@ or other branches are repeatedly merged into.} and call the branch from
which the topic branch was originally created the @dfn{trunk} or
@dfn{development trunk}.
In this case, outstanding changes is a more specific notion than just
In this case, unintegrated changes is a more specific notion than just
unpushed and uncommitted changes on the topic branch. You're not
finished sharing changes with your collaborators until they have been
merged into the trunk, and pushed. Therefore, in this example,
outstanding changes are those which haven't yet been integrated into the
unintegrated changes are those which haven't yet been included in the
upstream repository's development trunk. That means committed changes
on the topic branch that haven't yet been merged into the trunk, plus
uncommitted changes.
@ -388,7 +409,24 @@ changes to the current VC fileset. @kbd{C-x v T L} and @kbd{C-x v T l}
show the corresponding revision logs, excluding uncommitted changes as
above.
This functionality relies on Emacs correctly detecting whether the
@findex vc-diff-remote-unintegrated
@findex vc-root-diff-remote-unintegrated
@findex vc-log-remote-unintegrated
@findex vc-root-log-remote-unintegrated
On topic branches, it is sometimes also useful to see the same
information but for the remote repository's version of the topic branch.
This is the outstanding work on the topic branch that has been pushed,
but not yet merged. It is visible to your collaborators but is
otherwise still unintegrated. We call such work @dfn{remote
unintegrated changes}. There is a command corresponding to each of the
four commands discussed so far but which operates on the remote
repository's version of the current topic branch: @w{@kbd{C-x v R T =}}
(@code{vc-diff-remote-unintegrated}), @w{@kbd{C-x v R T D}}
(@code{vc-root-diff-remote-unintegrated}), @w{@kbd{C-x v R T l}}
(@code{vc-log-remote-unintegrated}), and @w{@kbd{C-x v R T L}}
(@code{vc-root-log-remote-unintegrated}).
All this functionality relies on Emacs correctly detecting whether the
current branch is a trunk or a topic branch, and in the latter case,
correctly determining the branch to which the topic branch will
eventually be merged. If the autodetection doesn't produce the right

View file

@ -1366,8 +1366,11 @@ following in it:
---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error: (void-function this)
(this is an unquoted list)
eval((this is an unquoted list) nil)
(progn (this is an unquoted list))
eval((progn (this is an unquoted list)) t)
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
@ -1807,6 +1810,8 @@ Debugger entered--Lisp error: (void-function fill-column)
(fill-column)
eval((fill-column) nil)
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
@ -1843,8 +1848,10 @@ says:
@group
---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error: (void-variable +)
eval(+)
eval(+ nil)
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
@ -2099,15 +2106,16 @@ You will create and enter a @file{*Backtrace*} buffer that says:
@smallexample
@group
---------- Buffer: *Backtrace* ----------
Debugger entered--Lisp error:
(wrong-type-argument number-or-marker-p hello)
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p hello)
+(2 hello)
eval((+ 2 'hello) nil)
elisp--eval-last-sexp(t)
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-print-last-sexp nil)
call-interactively(eval-print-last-sexp nil nil)
command-execute(eval-print-last-sexp)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
@end group
@end smallexample
@ -15348,7 +15356,7 @@ Here is the function:
@c (files-in-below-directory "/usr/local/src/emacs/lisp/")
@c (files-in-below-directory "/usr/local/share/emacs/22.1.1/lisp/")
The @code{files-in-below-directory} @code{directory-files} function
The @code{files-in-below-directory} function
takes one argument, the name of a directory.
@need 1250
@ -16570,18 +16578,16 @@ M-x customize
@end smallexample
@noindent
and find that the group for editing files of text is called ``Text''.
Enter that group. Text Mode Hook is the first member. You can click
on its various options, such as @code{turn-on-auto-fill}, to set the
values. After you click on the button to
@smallexample
Save for Future Sessions
@end smallexample
@noindent
Emacs will write an expression into your @file{.emacs} file.
It will look like this:
and find that the group for editing files of text is called @samp{Text}.
Enter that group by clicking or typing @key{RET} on it. Text Mode Hook
is one of the group's members; click on the triangular button (or on the
@samp{Show Value} button which replaces that on text-only terminals) to
its left to show its various options. Then you can click (or type
@key{RET} if you are on a text-only terminal) on its options, such as
@code{turn-on-auto-fill}, to set or reset the values. After you click
(or type @key{RET}) on the @samp{State} button and select @samp{Save for
Future Sessions}, Emacs will write an expression into your @file{.emacs}
file. It will look like this:
@smallexample
@group
@ -16981,11 +16987,10 @@ The command invoked by the keys is @code{compare-windows}. Note that
@code{compare-windows} is preceded by a single-quote; otherwise, Emacs
would first try to evaluate the symbol to determine its value.
These three things, the double quotation marks, the backslash before
the @samp{C}, and the single-quote are necessary parts of
key binding that I tend to forget. Fortunately, I have come to
remember that I should look at my existing @file{.emacs} file, and
adapt what is there.
These two things, the double quotation marks and the single-quote, are
necessary parts of key binding that I tend to forget. Fortunately, I
have come to remember that I should look at my existing @file{.emacs}
file, and adapt what is there.
As for the key binding itself: @kbd{C-c w}. This combines the prefix
key, @kbd{C-c}, with a single character, in this case, @kbd{w}. This
@ -17941,13 +17946,16 @@ Debugger entered--Lisp error: (void-function 1=)
(let ((total 0)) (while (> number 0) (setq total ...)
(setq number ...)) total)
triangle-bugged(4)
eval((triangle-bugged 4) nil)
@end group
@group
eval((triangle-bugged 4) nil)
eval-expression((triangle-bugged 4) nil nil 127)
funcall-interactively(eval-expression (triangle-bugged 4) nil nil 127)
call-interactively(eval-expression nil nil)
command-execute(eval-expression)
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
@end group
@end smallexample
@ -18045,10 +18053,13 @@ Debugger entered--entering a function:
eval((triangle-bugged 5) nil)
@end group
@group
eval-expression((triangle-bugged 5) nil nil 127)
funcall-interactively(eval-expression (triangle-bugged 5) nil nil 127)
call-interactively(eval-expression nil nil)
command-execute(eval-expression)
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
@end group
@end smallexample
@ -18097,12 +18108,15 @@ Debugger entered--beginning evaluation of function call form:
(setq number ...)) total)
* triangle-bugged(5)
eval((triangle-bugged 5) nil)
@group
@end group
eval-expression((triangle-bugged 5) nil nil 127)
funcall-interactively(eval-expression (triangle-bugged 5) nil nil 127)
call-interactively(eval-expression nil nil)
command-execute(eval-expression)
@group
elisp--eval-last-sexp(nil)
#f(compiled-function () #<bytecode ...>)()
handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug)
eval-last-sexp(nil)
funcall-interactively(eval-last-sexp nil)
call-interactively(eval-last-sexp nil nil)
command-execute(eval-last-sexp)
---------- Buffer: *Backtrace* ----------
@end group
@end smallexample

View file

@ -3817,6 +3817,11 @@ Basic faces used for the corresponding decorations of GUI frames.
@item cursor
The basic face used for the text cursor.
@item margin
The basic face used for window margins, both on the left and on the
right. It is commonly used to customize the background of the empty
areas of the margins. It inherits from the @code{default} face.
@item mouse
The basic face used for displaying mouse-sensitive text when the mouse
pointer is on that text.
@ -5909,12 +5914,14 @@ that text, put on that text an overlay with a @code{before-string}
property, and put the margin display specification on the contents of
the before-string.
Note that if the string to be displayed in the margin doesn't
specify a face, its face is determined using the same rules and
priorities as it is for strings displayed in the text area
(@pxref{Displaying Faces}). If this results in undesirable
``leaking'' of faces into the margin, make sure the string has an
explicit face specified for it.
Note that if the string to be displayed in the margin doesn't fully
specify its face, the nonspecified attributes are inherited from the
@code{margin} face (@pxref{Basic Faces}). The face merging mechanism
ensures that the margin background remains consistent when margin
annotations specify only a foreground color. If you want a margin
string to have a specific appearance independent of the @code{margin}
face, make sure the string has a face specifying all required
attributes.
Before the display margins can display anything, you must give
them a nonzero width. The usual way to do that is to set these

View file

@ -2100,6 +2100,7 @@ Call the function @var{f} for every piece of advice that was added to
and its properties.
@end defun
@anchor{advice-eval-interactive-spec}
@defun advice-eval-interactive-spec spec
Evaluate the interactive @var{spec} just like an interactive call to a function
with such a spec would, and then return the corresponding list of arguments
@ -2112,7 +2113,7 @@ For instance, if you want to make the @kbd{C-x m}
could say something like this:
@example
(defun my-compose-mail-advice (orig &rest args)
(defun my-compose-mail-advice (&rest _)
"Read From: address interactively."
(interactive
(lambda (spec)
@ -2126,9 +2127,10 @@ could say something like this:
;; Put the From header into the OTHER-HEADERS argument.
(push (cons 'From from) (nth 2 spec))
spec)))
(apply orig args))
;; This body is not used.
nil)
(advice-add 'compose-mail :around #'my-compose-mail-advice)
(advice-add 'compose-mail :interactive-only #'my-compose-mail-advice)
@end example
@end defun
@ -2148,8 +2150,8 @@ instead. This separate set of functions to manipulate pieces of advice applied
to named functions, offers the following extra features compared to
@code{add-function}: they know how to deal with macros and autoloaded
functions, they let @code{describe-function} preserve the original docstring as
well as document the added advice, and they let you add and remove advice
before a function is even defined.
well as document the added advice, and they let you add and remove
pieces of advice before a function is even defined.
@code{advice-add} can be useful for altering the behavior of existing calls
to an existing function without having to redefine the whole function.
@ -2338,8 +2340,18 @@ More specifically, the composition of the two functions behaves like:
@example
(lambda (&rest r) (funcall @var{function} (apply @var{oldfun} r)))
@end example
@end table
@item :interactive-only
While the @var{where} option controls how the body of the two functions
are composed, it does not actually affect the way interactive forms are
composed. So, in a sense, this does the opposite of @code{:override}:
call only the old function as if no advice was applied. But it still
affects the interactive form like any other @var{where} value would: The
interactive form of @var{function}, if any, overrides that of
@var{oldfun} and if it is a lambda expression, it receives
@var{function}'s interactive form as argument.
See @pxref{advice-eval-interactive-spec} for an example.
@end table
@node Porting Old Advice
@subsection Adapting code using the old defadvice

View file

@ -4447,6 +4447,14 @@ arguments as optional arguments for future extensibility.
If a capture name is both a face and a function, the face takes
priority. If a capture name is neither a face nor a function, it is
ignored.
@findex treesit-query-with-optional
@findex treesit-query-with-fallback
Sometimes, to support different versions of the same grammar, it's
useful to conditionally include some optional @var{query}, or choose the
first valid query from a list of queries. Functions like
@code{treesit-query-with-optional} and
@code{treesit-query-with-fallback} can come in handy.
@end defun
@c FIXME: Cross-ref treesit-font-lock-level to user manual.

View file

@ -411,8 +411,8 @@ that the early init file is loaded much earlier during the startup
process, so you can use it to customize some things that are
initialized before loading the regular init file. For example, you
can customize the process of initializing the package system, by
setting variables such as @var{package-load-list} or
@var{package-enable-at-startup}. @xref{Package Installation,,,
setting variables such as @code{package-load-list} or
@code{package-enable-at-startup}. @xref{Package Installation,,,
emacs,The GNU Emacs Manual}.
@cindex default init file
@ -2382,6 +2382,7 @@ calling a timer function in a row, when many previously scheduled
calls were unavoidably delayed.
@end defopt
@cindex running code with timeout
@defmac with-timeout (seconds timeout-forms@dots{}) body@dots{}
Execute @var{body}, but give up after @var{seconds} seconds. If
@var{body} finishes before the time is up, @code{with-timeout} returns
@ -2400,6 +2401,8 @@ primitive that can wait, @code{with-timeout} cannot stop executing
@var{body} while it is in the midst of a computation---only when it
calls one of those primitives. So use @code{with-timeout} only with a
@var{body} that waits for input, not one that does a long computation.
Primitives that wait for input include @code{sit-for}, @code{sleep-for},
@code{accept-process-output}, and some others.
@end defmac
The function @code{y-or-n-p-with-timeout} provides a simple way to use

View file

@ -133,15 +133,6 @@ init file, and any code that should run after it in the primary init
file (@pxref{Init File,,, emacs, The GNU Emacs Manual}).
@end defun
@deffn Command package-initialize &optional no-activate
This function initializes Emacs's internal record of which packages are
installed, and then calls @code{package-activate-all}.
The optional argument @var{no-activate}, if non-@code{nil}, causes
Emacs to update its record of installed packages without actually
making them available.
@end deffn
@node Simple Packages
@section Simple Packages
@cindex single file package

View file

@ -1383,7 +1383,11 @@ Here are the kinds of elements an undo list can have:
This kind of element records a previous value of point; undoing this
element moves point to @var{position}. Ordinary cursor motion does not
make any sort of undo record, but deletion operations use these entries
to record where point was before the command.
to record where point was before the command if re-inserting the deleted
text by undoing the deletion will not already place point at the right
position. Lisp programs that need to ensure correct restoration of
point by undoing a command can explicitly push @code{(point)} to
@code{buffer-undo-list} to record the position to restore.
@item (@var{beg} . @var{end})
This kind of element indicates how to delete text that was inserted.
@ -5434,7 +5438,9 @@ database object. The database object returned by the
@defun sqlite-close db
Close the database @var{db}. It's usually not necessary to call this
function explicitly---the database will automatically be closed if
Emacs shuts down or the database object is garbage collected.
Emacs shuts down or the database object is garbage collected. If the
connection identified by @var{db} is already closed, this function does
nothing.
@end defun
@defun sqlite-execute db statement &optional values

View file

@ -282,7 +282,7 @@ previous example is equivalent to using nested @code{let} bindings:
@end defspec
@defspec letrec (bindings@dots{}) forms@dots{}
@defmac letrec (bindings@dots{}) forms@dots{}
This special form is like @code{let*}, but all the variables are bound
before any of the local values are computed. The values are then
assigned to the locally bound variables. This is useful only when
@ -299,11 +299,11 @@ being run once:
(remove-hook 'post-command-hook hookfun))))
(add-hook 'post-command-hook hookfun))
@end lisp
@end defspec
@end defmac
@cindex dynamic binding, temporarily
@cindex dynamic let-binding
@defspec dlet (bindings@dots{}) forms@dots{}
@defmac dlet (bindings@dots{}) forms@dots{}
This special form is like @code{let}, but it binds all variables
dynamically. This is rarely useful---you usually want to bind normal
variables lexically, and special variables (i.e., variables that are
@ -315,9 +315,9 @@ that certain variables are dynamically bound (@pxref{Dynamic
Binding}), but it's impractical to @code{defvar} these variables.
@code{dlet} will temporarily make the bound variables special, execute
the forms, and then make the variables non-special again.
@end defspec
@end defmac
@defspec named-let name bindings &rest body
@defmac named-let name bindings &rest body
This special form is a looping construct inspired from the
Scheme language. It is similar to @code{let}: It binds the variables in
@var{bindings}, and then evaluates @var{body}. However,
@ -353,7 +353,7 @@ itself, as is the case in the recursive call to @code{sum} above.
@code{named-let} can be used only when lexical-binding is enabled.
@xref{Lexical Binding}.
@end defspec
@end defmac
Here is a complete list of the other facilities that create local
bindings:

View file

@ -3892,12 +3892,16 @@ specified right below this list.
@vindex dedicated@r{, a buffer display action alist entry}
@item dedicated
If non-@code{nil}, such an entry tells @code{display-buffer} to mark
any window it creates as dedicated to its buffer (@pxref{Dedicated
If non-@code{nil}, such an entry tells @code{display-buffer} to mark any
window it creates as dedicated to its buffer (@pxref{Dedicated
Windows}). It does that by calling @code{set-window-dedicated-p} with
the chosen window as first argument and the entry's value as second.
Side windows are by default dedicated with the value @code{side}
(@pxref{Side Window Options and Functions}).
(@pxref{Side Window Options and Functions}). Windows that are reused
are not marked as dedicated regardless of whether they already showed
the buffer before or not. If a window dedicated to its buffer gets
reused for showing the same buffer again, its dedicated flag is left
alone.
@vindex preserve-size@r{, a buffer display action alist entry}
@item preserve-size
@ -4922,10 +4926,10 @@ window and defaults to the selected one.
Each list element has the form @code{(@var{buffer} @var{window-start}
@var{window-pos})}, where @var{buffer} is a buffer previously shown in
the window, @var{window-start} is the window start position
(@pxref{Window Start and End}) when that buffer was last shown, and
@var{window-pos} is the window point position (@pxref{Window Point})
when that buffer was last shown in @var{window}.
the window, @var{window-start} is a marker that gives the window start
position (@pxref{Window Start and End}) when that buffer was last shown,
and @var{window-pos} is a marker that gives the window point position
(@pxref{Window Point}) when that buffer was last shown in @var{window}.
The list is ordered so that earlier elements correspond to more
recently-shown buffers, and the first element usually corresponds to the

View file

@ -168,10 +168,12 @@ longer Info tutorial.)
@menu
* Getting Started:: General description and overview.
@ifinfo
* Interactive Tutorial::
* Interactive Tutorial:: Tutorial, and brief instructions on using
the Emacs Info system for reading this manual.
@end ifinfo
@ifnotinfo
* Tutorial:: A step-by-step introduction for beginners.
@end ifnotinfo
* Introduction:: Introduction to the Calc reference manual.
* Data Types:: Types of objects manipulated by Calc.
* Stack and Trail:: Manipulating the stack and trail buffers.
@ -1244,8 +1246,8 @@ finished in two weeks.
@ifinfo
@c This node is accessed by the 'C-x * t' command.
@node Interactive Tutorial, Tutorial, Getting Started, Top
@chapter Tutorial
@node Interactive Tutorial, Introduction, Getting Started, Top
@chapter Interactive Tutorial
@noindent
Some brief instructions on using the Emacs Info system for this tutorial:
@ -9572,7 +9574,12 @@ the last rule.
@c [reference]
@node Introduction
@ifinfo
@node Introduction, Data Types, Interactive Tutorial, Top
@end ifinfo
@ifnotinfo
@node Introduction, Data Types, Tutorial, Top
@end ifnotinfo
@chapter Introduction
@noindent

View file

@ -66,6 +66,7 @@ another. An overview of D-Bus can be found at
* Errors and Events:: Errors and events.
* Monitoring Messages:: Monitoring messages.
* File Descriptors:: Handle file descriptors.
* Flatpak integration:: Integration with flatpak
* Index:: Index including concepts, functions, variables.
* GNU Free Documentation License:: The license for this documentation.
@ -2302,6 +2303,38 @@ instance have acquired a file descriptor as well. Example:
@end defun
@node Flatpak integration
@chapter Integration with flatpak
@c https://docs.flatpak.org/en/latest/sandbox-permissions.html
@c TODO: This needs more input.
If you run the Emacs flatpak program, there are restrictions. By
default, there is limited access to the session D-Bus, and no access to
the system D-Bus. You must enable access to services living outside the
sandbox like
@example
# flatpak override --talk-name=org.freedesktop.secrets org.gnu.emacs
@end example
@samp{org.gnu.emacs} is the Emacs flatpak application, and
@samp{org.freedesktop.secrets} is a service you want to talk to, for
example.
Access to the entire bus with @samp{--socket=system-bus} or
@samp{--socket=session-bus} stops the filtering and using them is a
security risk. So they must be avoided.
@c Bug#80977.
Service names might be mapped when arriving Emacs. For example, you
will see the @samp{org.freedesktop.DBus.NameOwnerChanged} signal for
service @samp{org.freedesktop.portal.Flatpak}, even if you have
registered the signal for another namespace.
@c TODO: What about portals?
@node Index
@unnumbered Index

View file

@ -1914,14 +1914,40 @@ exhibits all the colors Emacs knows about on the current display.
Syntax highlighting is also on by default on text-only terminals.
@cindex direct color in terminals
Emacs 26.1 and later support direct color mode in terminals. If Emacs
finds Terminfo capabilities @samp{setb24} and @samp{setf24}, 24-bit
direct color mode is used. The capability strings are expected to
take one 24-bit pixel value as argument and transform the pixel to a
string that can be used to send 24-bit colors to the terminal.
Emacs 26.1 and later support direct color mode in terminals.
Standard terminal definitions don't support these capabilities and
therefore custom definition is needed.
If Emacs finds Terminfo capabilities @samp{setrgbb} and @samp{setrgbf},
@samp{setb24} and @samp{setf24}, or @samp{Tc}, 24-bit direct color mode
is used. Standard terminal definitions don't support any of these
capabilities, and therefore custom definition is needed.
The capability strings @samp{setrgbb} and @samp{setrgbf} are expected to
take three 8-bit values as arguments. They are supported by Emacs 31.1
and newer (and some other applications).
@example
$ cat terminfo-custom.src
xterm-truecolor|xterm with 24-bit true color,
use=xterm-256color,
Tc,
setrgbb=\E[48\:2\:\:%p1%d\:%p2%d\:%p3%dm,
setrgbf=\E[38\:2\:\:%p1%d\:%p2%d\:%p3%dm,
$ tic -x -o ~/.terminfo terminfo-custom.src
$ TERM=xterm-truecolor emacs -nw
@end example
Some terminal emulators bundle their own custom definition that include
the @samp{setrgbb}, @samp{setrgbf} and @samp{Tc} capabilities.
The capability strings @samp{setb24} and @samp{setf24} are expected to
take one 24-bit pixel value as argument and transform the pixel to a
string that can be used to send 24-bit colors to the terminal. They are
only know to be supported by Emacs. They are made obsolete by
@samp{setrgbb} and @samp{setrgbf}, and may be removed in a future
version of Emacs.
@example
$ cat terminfo-custom.src
@ -1973,12 +1999,13 @@ If Terminfo database is not available, but 24-bit direct color mode is
supported, it can still be enabled by defining the environment
variable @env{COLORTERM} to @samp{truecolor}.
Terminals with @samp{RGB} capability treat pixels #000001 - #000007 as
Terminals with @samp{RGB} capability treat pixels #000000 - #000007 as
indexed colors to maintain backward compatibility with applications
that are unaware of direct color mode. Therefore the seven darkest
blue shades may not be available. If this is a problem, you can
always use custom terminal definition with @samp{setb24} and
@samp{setf24}.
always use custom terminal definition with @samp{setrgbb} and
@samp{setrgbf}, @samp{setb24} and @samp{setf24}, @samp{Tc} without
@samp{RGB}, or @env{COLORTERM}=@samp{truecolor} without @samp{RGB}.
@node Debugging a customization file
@section How do I debug an init file?

View file

@ -474,11 +474,11 @@ Code reformatting via the @code{eglot-format} and related commands
supported and is activated automatically as you type.
@item
If a completion package such as the Company package (a popular
third-party completion package providing @code{company-mode}), is
installed, Eglot enhances it by providing completion candidates based on
the language server's analysis of the source code. (Company can be
installed from GNU ELPA.)
Eglot enhances symbol completion front-ends by providing completion
candidates based on the language server's understanding of the source
code (@pxref{Symbol Completion,,, emacs, GNU Emacs Manual}). The
Company package, installable from GNU ELPA, is a popular package known
to work well with Eglot.
@item
If YASnippet, a popular third-party package for automatic insertion of
@ -488,12 +488,11 @@ completion package to instantiate these snippets using YASnippet.
(YASnippet can be installed from GNU ELPA.)
@item
If the popular third-party package @code{markdown-mode} is installed,
and the server provides at-point documentation formatted as Markdown in
When the server provides at-point documentation formatted as Markdown in
addition to plain text, Eglot arranges for the ElDoc package to enrich
this text with fontifications and other nice formatting before
displaying it to the user. This makes the documentation shown by ElDoc
look nicer on display.
this text with fontifications, hyperlinks and other nice formatting
before displaying it to the user. This makes the documentation shown by
ElDoc look nicer on display.
@item
In addition to enabling and enhancing other features and packages, Eglot
@ -713,6 +712,20 @@ Emacs session. As with @code{eglot-shutdown}, invoking this command
with a prefix argument avoids killing the buffers used for
communications with the language servers.
@item M-x eglot-describe-connection
This command pops up a detailed description buffer for the current
connection, outlining aspects such as the LSP server name and version,
the project name and root path, among others.
@item M-x eglot-list-connections
This command pops up a buffer listing all active Eglot connections,
showing aspects such as the server name, project, number of managed
buffers, major modes, and the server invocation. In this buffer,
@kbd{k} shuts down the server on the current line, @kbd{r} reconnects
to it, @kbd{e} visits its events buffer, @kbd{w} shows its workspace
configuration, and @kbd{RET} describes the connection with
@code{eglot-describe-connection}.
@item M-x eglot-rename
This command renames the program symbol (a.k.a.@: @dfn{identifier}) at
point to another name. It prompts for the new name of the symbol, and
@ -1955,7 +1968,7 @@ directory is a way to tell the maintainers about ELPA package versions.
@item
Include a recipe to replicate the problem with @emph{a clean Emacs run}.
The invocation @code{emacs -Q -f package-initialize} starts Emacs with
The invocation @code{emacs -Q -f package-activate-all} starts Emacs with
no configuration and initializes the ELPA packages. A very minimal
@file{.emacs} initialization file (10 lines or less) is also acceptable
and good means to describe changes to variables.

View file

@ -3,7 +3,7 @@
@setfilename ../../info/erc.info
@settitle ERC Manual
@documentlanguage en
@set ERCVER 5.6.2
@set ERCVER 5.7
@set ERCDIST as distributed with Emacs @value{EMACSVER}
@include docstyle.texi
@syncodeindex fn cp

View file

@ -323,6 +323,23 @@ for more information about backtraces.
Show the list of @code{should} forms executed in the test
(@code{ert-results-pop-to-should-forms-for-test-at-point}).
@kindex e@r{, in ert results buffer}
@findex ert-results-pop-to-erts-file-tests-for-test-at-point
@item e
Display a buffer with the list of tests from erts files executed by the
test at point
(@code{ert-results-pop-to-erts-file-tests-for-test-at-point}). For
tests that call @code{ert-test-erts-file}, the list contains the tests
defined in the referenced erts files that have been executed. Tests
that were skipped are omitted. If a test fails, the list ends with the
failing test.
Each entry consists of the name of the test followed by the code that
performs the transform being tested. The buffer also contains buttons
that allow jumping to the test definitions.
@xref{erts files} for more information.
@item m
@kindex m@r{, in ert results buffer}
@findex ert-results-pop-to-messages-for-test-at-point
@ -1123,7 +1140,7 @@ result of @var{NAME-FORM}. Example:
This uses the test buffer @file{*Test buffer
(backtrace-tests--variables): variables*}.
If @var{select-form} is non-nil, select the buffer after creating it.
If @var{select-form} is non-@code{nil}, select the buffer after creating it.
This has the same effect as combining @code{ert-with-test-buffer} with
@code{ert-with-buffer-selected}. Example:
@ -1132,6 +1149,12 @@ This has the same effect as combining @code{ert-with-test-buffer} with
(ert-with-test-buffer (:name "global" :selected t)
@dots{}))
@end lisp
@findex ert-play-keys
The @var{select-form} shall be set non-@code{nil} when @var{body} contains some
call to @code{ert-play-keys} to generate programmatically user input
events inserting text into the test buffer, or starting commands acting
on the test buffer.
@end defmac
@defmac ert-with-buffer-selected (buffer &body body)
@ -1154,6 +1177,13 @@ value is the last form in @var{body}. Example:
@end lisp
This displays a temporary buffer like @file{ *temp*-739785*}.
@c @findex ert-play-keys
One of the use of @code{ert-with-buffer-selected} is to set the buffer
to which user input events generated programmatically by one or more
calls to @code{ert-play-keys} are targetted, which is needed when those
events are supposed to insert text into this buffer, or start commands
acting on it.
@end defmac
@subsection Protecting buffers
@ -1257,21 +1287,21 @@ The following keyword arguments are supported:
@table @code
@vindex ert-temp-file-prefix
@item :prefix @var{string}
If non-nil, pass @var{string} to @code{make-temp-file} as
If non-@code{nil}, pass @var{string} to @code{make-temp-file} as
the @var{prefix} argument. Otherwise, use the value of
@code{ert-temp-file-prefix}.
@vindex ert-temp-file-suffix
@item :suffix @var{string}
If non-nil, pass @var{string} to @code{make-temp-file} as the
If non-@code{nil}, pass @var{string} to @code{make-temp-file} as the
@var{suffix} argument. Otherwise, use the value of
@code{ert-temp-file-suffix}; if the value of that variable is nil,
generate a suffix based on the name of the file that
@code{ert-with-temp-file} is called from.
@item :text @var{string}
If non-nil, pass @var{string} to @code{make-temp-file} as the @var{text}
argument.
If non-@code{nil}, pass @var{string} to @code{make-temp-file} as the
@var{text} argument.
@item :buffer @var{symbol}
Open the temporary file using @code{find-file-noselect} and bind
@ -1279,7 +1309,7 @@ Open the temporary file using @code{find-file-noselect} and bind
normally or non-locally.
@item :coding @var{coding}
If non-nil, bind @code{coding-system-for-write} to @var{coding} when
If non-@code{nil}, bind @code{coding-system-for-write} to @var{coding} when
executing @var{body}. This is handy when @var{string} includes
non-ASCII characters or the temporary file must have a specific encoding
or end-of-line format.
@ -1348,7 +1378,14 @@ symbol and the rest are arguments to the command. Example:
@strong{Note}: Since the command is not called by
@code{call-interactively}, a test for @code{(called-interactively-p
'interactive)} in the command will fail.
@var{kind})} in the command will fail for whatever @var{kind}.@*
Function @code{ert-play-keys} may be used instead to start a command if
you need the predicate @code{(called-interactively-p @var{kind})} tested
within the command body to return @code{t} for @var{kind} @code{any},
note however that it will still be @code{nil} too for @var{kind}
@code{interactive} since @code{ert-play-keys} uses keyboard macros under
the hood, and that @code{ert-play-keys} needs selecting the buffer of
interest.
@end defun
@defmac ert-simulate-keys (keys &rest body)
@ -1362,8 +1399,76 @@ vector. Examples:
(ert-simulate-keys (kbd "#fake C-m C-a C-k C-m") @dots{})
(ert-simulate-keys [?b ?2 return] @dots{})
@end lisp
@c @findex ert-play-keys
To generate input event for inserting some text into a buffer, or
calling some interactive command, see rather function
@code{ert-play-keys}.
@end defmac
@defun ert-play-keys (keys)
Generate programmatically user input events.
@c @findex ert-simulate-keys
Contrary to @code{ert-simulate-keys}, these events are not intended to be
consumed by functions reading input, like @code{read-from-minibuffer},
but are consumed by the command loop which typically will process them
to start interactive commands or insert text into the selected buffer.
So, before calling @code{ert-play-keys} you generally need to select the
buffer to which input events are intended to insert text or call a
command. Do this by passing a non-@code{nil} @code{:selected} flag to
@code{ert-with-test-buffer} if the buffer was created this way, or use
the @code{ert-with-buffer-selected} macro.
@c @findex ert-simulate-command
Contrary to @code{ert-simulate-command}, when @code{ert-play-keys}
generates events starting a command you cannot get the command return
value. On the other hand, @code{(called-interactively-p 'any)} tested in
the command body will be @code{t}, but not @code{(called-interactively-p
'interactive)} as @code{ert-play-keys} does not a true interactive call,
but uses a keyboard macro under the hood. Another difference is that,
contrary to @code{ert-simulate-command}, @code{ert-play-keys} needs to
select the buffer on which the command acts for the input events to
reach it.
In this example a test buffer is created and selected, then
@code{ert-play-keys} sets the mark, inserts text @samp{n'importe quoi}
and kills it, then the test checks that the killed text is in the kill
ring and the test buffer is empty, then a second @code{ert-play-keys}
call yanks again the killed text, and finally the test checks the test
buffer contains @samp{n'importe quoi}:
@lisp
(ert-deftest ert-example-kill&yank ()
"Test kill and yank."
(ert-with-test-buffer (:selected t)
(ert-play-keys "C-SPC n'importe SPC quoi C-w")
(should (string= "n'importe quoi" (car kill-ring)))
(should (string= "" (buffer-substring (point-min) (point-max))))
(ert-play-keys "C-y")
(should (string= "n'importe quoi"
(buffer-substring (point-min) (point-max))))))
@end lisp
@noindent
Write input events as above with a string in the input format used by
@code{key-parse}, or directly in the internal Emacs representation like
here which is otherwise the same test as above:
@lisp
(ert-deftest ert-example-kill&yank ()
"Test kill and yank."
(ert-with-test-buffer (:selected t)
(ert-play-keys (vconcat [ ?\C- ] "n'importe quoi" [ ?\C-w]))
(should (string= "n'importe quoi" (car kill-ring)))
(should (string= "" (buffer-substring (point-min) (point-max))))
(ert-play-keys [ ?\C-y ])
(should (string= "n'importe quoi"
(buffer-substring (point-min) (point-max))))))
@end lisp
@end defun
@defun ert-filter-string (s &rest regexps)
This function returns a copy of string @var{s} with all matches of
@var{regexps} removed. Elements of @var{regexps} may also be

View file

@ -849,7 +849,7 @@ Various
* Spam Package:: A package for filtering and processing spam.
* The Gnus Registry:: A package for tracking messages by Message-ID.
* The Gnus Cloud:: A package for synchronizing Gnus marks.
* D-Bus Integration:: Closing Gnus servers on system sleep.
* System Sleep Integration:: Closing Gnus servers on system sleep.
* Other modes:: Interaction with other modes.
* Various Various:: Things that are really various.
@ -22712,7 +22712,7 @@ For instance, @code{nnir-notmuch-program} is now
* Spam Package:: A package for filtering and processing spam.
* The Gnus Registry:: A package for tracking messages by Message-ID.
* The Gnus Cloud:: A package for synchronizing Gnus marks.
* D-Bus Integration:: Closing Gnus servers on system sleep.
* System Sleep Integration:: Closing Gnus servers on system sleep.
* Other modes:: Interaction with other modes.
* Various Various:: Things that are really various.
@end menu
@ -26680,11 +26680,11 @@ CloudSynchronizationDataPack(TM)s. It's easiest to set this from the
Server buffer (@pxref{Gnus Cloud Setup}).
@end defvar
@node D-Bus Integration
@section D-Bus Integration
@cindex dbus
@cindex D-Bus
@cindex gnus-dbus
@c Section name changed from this in Emacs 31. @c
@c This anchor allows old links to continue working. @c
@anchor{D-Bus Integration}
@node System Sleep Integration
@section System Sleep Integration
@cindex system sleep
@cindex closing servers automatically
@cindex hung connections
@ -26692,13 +26692,10 @@ Server buffer (@pxref{Gnus Cloud Setup}).
When using laptops or other systems that have a sleep or hibernate
functionality, it's possible for long-running server connections to
become ``hung'', requiring the user to manually close and re-open the
connections after the system resumes. On systems compiled with D-Bus
support (check the value of @code{(featurep 'dbusbind)}), Gnus can
register a D-Bus signal to automatically close all server connections
before the system goes to sleep. To enable this, set
@code{gnus-dbus-close-on-sleep} to a non-@code{nil} value.
For more information about D-Bus and Emacs, @pxref{Top,,, dbus, D-Bus integration in Emacs}.
connections after the system resumes. Using the system sleep library,
Gnus can automatically close all server connections before the system
goes to sleep. To enable this, set @code{gnus-close-on-sleep} to a
non-@code{nil} value.
@node Other modes
@section Interaction with other modes

View file

@ -464,7 +464,10 @@ Now type @kbd{]}, to learn about the @kbd{]} and @kbd{[} commands.
@end menu
@node Help-], , , Help-Inv
@subsection The @kbd{]} and @kbd{[} commands
@c @subheading and not @section to avoid warnings from makeinfo due to
@c the fact that all the 3 items in the above menu point to the same
@c node. The downside is that the section name has no number.
@subheading The @kbd{]} and @kbd{[} commands
If you type @kbd{n} now, you get an error message saying that this
node has no next node. Similarly, if you type @kbd{p}, the error
@ -709,7 +712,10 @@ there's no next node.
@end format
@node Help-FOO, , , Help-M
@subsection The @kbd{u} command
@c @subheading and not @subsection to avoid warnings from makeinfo due to
@c the fact that all the 3 items in the above menu point to the same
@c node. The downside is that the subsection name has no number.
@subheading The @kbd{u} command
Congratulations! This is the node @samp{Help-FOO}. It has an @samp{Up}
pointer @samp{Help-M}, the node you just came from via the @kbd{m}

View file

@ -1972,6 +1972,15 @@ This is the same as the above, but uses @samp{other-user} as the user
name when authenticating. This is handy if you have several
@acronym{SMTP} accounts on the same server.
Normally, the connection to the SMTP server follows the value of
@code{smtpmail-stream-type} except if port is 465, in which case a TLS
connection is required. To enforce a specific stream type, mention one
of the possible values of that variable, like so:
@example
X-Message-SMTP-Method: smtp smtp.fsf.org 587 other-user starttls
@end example
This header may also be used to specify an alternative MTA by using a
@samp{mailer} keyword, where @samp{mailer} is the name of an MTA with
a corresponding @code{message-send-mail-with-'mailer'} function. For

View file

@ -29,9 +29,9 @@
# Contact Info
#+texinfo_header: @set MAINTAINERSITE @uref{https://orgmode.org,maintainers webpage}
#+texinfo_header: @set MAINTAINER Bastien Guerry
#+texinfo_header: @set MAINTAINEREMAIL @email{bzg@gnu.org}
#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:bzg@gnu.org,contact the maintainer}
#+texinfo_header: @set MAINTAINER Ihor Radchenko
#+texinfo_header: @set MAINTAINEREMAIL @email{yantar92@posteo.net}
#+texinfo_header: @set MAINTAINERCONTACT @uref{mailto:yantar92@posteo.net,contact the maintainer}
#+options: H:4 num:t toc:t author:t \n:nil ::t |:t ^:nil -:t f:t *:t <:t e:t ':t
#+options: d:nil todo:nil pri:nil tags:not-in-toc stat:nil broken-links:mark

File diff suppressed because it is too large Load diff

View file

@ -2042,6 +2042,12 @@ Access of a hadoop/hdfs file system. A file is accessed via
the user that you want to use, and @samp{node} is the name of the
hadoop server.
@c @cindex method @option{rpc}
@c @cindex @option{rpc} method
@c @item tramp-rpc
@c This is a @value{tramp} backend of its own. It uses a remote server
@c process to serve the requests, which gains better performance.
@cindex method @option{vagrant}
@cindex @option{vagrant} method
@item vagrant-tramp
@ -4221,6 +4227,14 @@ called is local or remote, since @value{tramp} would add just the
@env{HGPLAIN} setting and local processes would take whole value of
@code{process-environment} along with the new value of @env{HGPLAIN}.
@vindex tramp-propagate-emacsclient-tramp
@vindex EMACSCLIENT_TRAMP@r{, environment variable}
If you set the user option @code{tramp-propagate-emacsclient-tramp} to
a non-@code{nil} value, the environment variable
@env{EMACSCLIENT_TRAMP} will be set to a value which allows to call
@command{emacsclient} from a process running on the remote
host. @xref{emacsclient Options, , , emacs}.
For integrating other Emacs packages so @value{tramp} can execute
remotely, please file a bug report. @xref{Bug Reports}.
@ -5556,6 +5570,8 @@ operations. For example, the GNU ELPA package @file{tramp-hlo}
implements specialized versions of @code{dir-locals--all-files},
@code{locate-dominating-file} and @code{dir-locals-find-file} for
@value{tramp}'s @code{tramp-sh} backend (@pxref{New operations}).
@c The NonGNU ELPA package @file{tramp-rpc} implements an own
@c @value{tramp} backend (@pxref{New operations}).
@end itemize
@ -6743,7 +6759,7 @@ The following parameters expand format specifiers for the
The example above could use
@lisp
(tramp-login-program "%1")
(tramp-login-program "%b")
@end lisp
And you could set @code{tramp-extra-expand-args} as connection-local value:
@ -6759,7 +6775,7 @@ And you could set @code{tramp-extra-expand-args} as connection-local value:
(connection-local-set-profile-variables
'foo-tramp-connection-local-default-profile
'((tramp-extra-expand-args
?1 (foo-tramp-get-login-program (car tramp-current-connection)))))
?b (foo-tramp-get-login-program (car tramp-current-connection)))))
(connection-local-set-profiles
'(:application tramp :protocol "foo")
@ -6867,15 +6883,12 @@ For example, it could implement this by using an own shell script
which collects the information on the remote host for this very
special purpose with one round-trip per-call.
@defun tramp-add-external-operation operation function backend
@defun tramp-add-external-operation operation function backend &optional arg-type
This adds an implementation of @var{operation} to @value{tramp}'s
backend @var{backend}. @var{function} is the new implementation.
Both @var{operation} and @var{function} shall be function symbols.
They must have the same argument list. The first argument is used to
determine, whether @value{tramp} is invoked (check for remote file
name syntax). It must be a string or nil, in the latter case
@code{default-directory} is used for the check.
They must have the same argument list.
@var{backend}, also a symbol, is the feature name of a @value{tramp}
backend (except @code{tramp-ftp}). The new implementation will be
@ -6883,18 +6896,18 @@ applied only for this backend. Example:
@lisp
@group
(defun test-operation (file)
(defun my-test-operation (file)
(message "Original implementation for %s" file))
@end group
@group
(defun handle-test-operation (file)
(defun my-handle-test-operation (file)
(message "Handler implementation for %s" file))
@end group
@group
(tramp-add-external-operation
#'test-operation #'handle-test-operation 'tramp-sh)
#'my-test-operation #'my-handle-test-operation 'tramp-sh)
@end group
@end lisp
@ -6903,23 +6916,24 @@ Then we have the different use cases:
@lisp
@group
;; Local file name.
(test-operation "/a/b")
(my-test-operation "/a/b")
@result{} "Original implementation for /a/b"
@end group
@group
;; Remote file name, handled by `tramp-sh'.
(test-operation "/ssh::/a/b")
(my-test-operation "/ssh::/a/b")
@result{} "Handler implementation for /ssh::/a/b"
@end group
@group
;; Remote file name, handled by `tramp-gvfs'.
(test-operation "/sftp::/a/b")
(my-test-operation "/sftp::/a/b")
@result{} "Original implementation for /sftp::/a/b"
@end group
@end lisp
@findex with-parsed-tramp-file-name
@var{function} is implemented like an ordinary @value{tramp} backend
handler, see the examples in @code{tramp-<backend>-handle-*} and
@code{tramp-handle-*}. It can expect, that the first argument (or
@ -6927,9 +6941,71 @@ handler, see the examples in @code{tramp-<backend>-handle-*} and
syntax. It shall use @value{tramp} internal macros and functions like
@code{with-parsed-tramp-file-name} and the different cache functions.
@findex tramp-run-real-handler
If @var{function} must call the original function, this can be done
via @code{tramp-run-real-handler}. The implementation of the example
could look like:
@lisp
@group
(defun my-handle-test-operation (file)
(message "Entry handler implementation for %s" file)
(tramp-run-real-handler #'my-test-operation (list file))
(message "Exit handler implementation for %s" file))
@end group
@group
(my-test-operation "/ssh::/a/b")
@result{} "Entry handler implementation for /ssh::/a/b
Original implementation for /ssh::/a/b
Exit handler implementation for /ssh::/a/b"
@end group
@end lisp
If the same @var{function} shall be used for different @value{tramp}
backends, @code{tramp-add-external-operation} must be called for every
backend, respectively.
The optional argument @var{arg-type} specisfies, which argument of
@var{operation} shall be used in order to determine, whether the
handler @var{function} should be called. It can be
@itemize @minus
@item @code{file}@*
The first argument of @var{operation} is the remote file name to be
checked. This is the default, if @var{arg-type} is @code{nil}.
@item @code{default-directory}@*
@code{default-directory} is the remote file name to be checked.
@item @code{process}@*
@code{default-directory} of the process buffer of the first argument
of @var{operation}, a process, is the remote file name to be checked.
@end itemize
If the first argument of @var{operation} is nil,
@code{default-directory} is the remote file name to be checked in case
of @var{arg-type} being @code{file} or @code{process}.
@findex tramp-file-name-for-operation
If @var{arg-type} is a function symbol, it will be called with the
same arguments as @code{tramp-file-name-for-operation}. It must
return a string, which is the remote file name to be checked.
The example above could be changed like this:
@lisp
@group
(defun my-file-name-for-test-operation (operation &rest args)
(if (stringp (car args)) (car args) default-directory))
@end group
@group
(tramp-add-external-operation
#'my-test-operation #'my-handle-test-operation 'tramp-sh
#'my-file-name-for-test-operation)
@end group
@end lisp
@end defun
@defun tramp-remove-external-operation operation backend
@ -6941,7 +7017,7 @@ they are kept. Example:
@lisp
@group
(tramp-remove-external-operation
#'test-operation 'tramp-sh)
#'my-test-operation 'tramp-sh)
@end group
@end lisp
@end defun
@ -6957,6 +7033,10 @@ An example implementing this mechanism is the GNU ELPA package
@code{dir-locals-find-file} for @value{tramp}'s @code{tramp-sh}
backend.
@c Another example is the NonGNU ELPA package @file{tramp-rpc}. It
@c provides an own @value{tramp} backend, using a server process on the
@c remote host.
@node Traces and Profiles
@chapter How to Customize Traces

View file

@ -25,13 +25,13 @@ General Public License for more details.
@dircategory Emacs misc features
@direntry
* Transient: (transient). Transient Commands.
* Transient: (transient). Transient Commands.
@end direntry
@finalout
@titlepage
@title Transient User and Developer Manual
@subtitle for version 0.12.0
@subtitle for version 0.13.3
@author Jonas Bernoulli
@page
@vskip 0pt plus 1filll
@ -53,7 +53,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial,
available at @uref{https://github.com/positron-solutions/transient-showcase}.
@noindent
This manual is for Transient version 0.12.0.
This manual is for Transient version 0.13.3.
@insertcopying
@end ifnottex
@ -385,7 +385,7 @@ than outlined above and even customizable.}
If the user does not save the value and just exits using a regular
suffix command, then the value is merely saved to the transient's
history. That value won't be used when the transient is next invoked,
but it is easily accessible (@pxref{Using History}).
but it is easily accessible (see @ref{Using History}).
Option @code{transient-common-command-prefix} controls the prefix key used
in the following bindings. For simplicity's sake the default, @kbd{C-x},
@ -454,8 +454,8 @@ previously used values. Usually the same keys as those mentioned
above are bound to those commands.
Authors of transients should arrange for different infix commands that
read the same kind of value to also use the same history key
(@pxref{Suffix Slots}).
read the same kind of value to also use the same history key (see
@ref{Suffix Slots}).
Both kinds of history are saved to a file when Emacs is exited.
@ -680,7 +680,7 @@ More options are described in @ref{Common Suffix Commands}, in @ref{Saving Value
Two more essential options are documented in @ref{Common Suffix Commands}.
@defopt transient-show-popup
@defopt transient-show-menu
This option controls whether and when transient's menu buffer is
shown.
@ -747,16 +747,23 @@ from the user. If @code{nil}, there is no initial input and the first
element has to be accessed the same way as the older elements.
@end defopt
@defopt transient-enable-popup-navigation
@defopt transient-enable-menu-navigation
This option controls whether navigation commands are enabled in
transient's menu buffer. If the value is @code{verbose} (the default),
brief documentation about the command under point is additionally
show in the echo area.
transient menu buffer, and whether additional documentation is shown
in the echo area while doing so.
While a transient is active the menu buffer is not the current
buffer, making it necessary to use dedicated commands to act on that
buffer itself. If this option is non-@code{nil}, then the following
features are available:
If the value is @code{verbose} (the default), additional documentation
about the command at point is shown in the echo area. If this would
result in the same documentation, which is being displayed inside
the menu buffer, to be duplicated in the echo area, then @code{verbose}
forgoes doing so. Use @code{force-verbose} to echo even such documentation.
Use @code{t} to enable menu navigation without showing documentation in the
echo area.
While a transient is active, the menu buffer is (by default) not the
current buffer, making it necessary to use dedicated commands to act
on that buffer itself. If this option is non-nil, then the
following bindings are available:
@itemize
@item
@ -766,15 +773,18 @@ features are available:
@item
@kbd{M-@key{RET}} invokes the suffix the cursor is on.
@item
@kbd{mouse-1} invokes the clicked on suffix.
@kbd{mouse-1} and @kbd{mouse-2} invokes the clicked on suffix.
@item
@kbd{C-s} and @kbd{C-r} start isearch in the menu buffer.
@end itemize
By default @kbd{M-@key{RET}} is bound to @code{transient-push-button}, instead of
@kbd{@key{RET}}, because if a transient allows the invocation of non-suffixes,
then it is likely, that you would want @kbd{@key{RET}} to do what it would do
if no transient were active."
@kbd{mouse-1} and @kbd{mouse-2} are bound in @code{transient-button-map}.
All other bindings are in @code{transient-popup-navigation-map}.
Instead of @kbd{@key{RET}}, @kbd{M-@key{RET}} is used to invoke the suffix command at point by
default, because if a transient allows the invocation of non-suffixes,
then it is likely that the user would want the former do what it would
do if no transient were active.
@end defopt
@defopt transient-display-buffer-action
@ -785,7 +795,7 @@ menu buffer. The menu buffer is displayed in a window using
The value of this option has the form @code{(@var{FUNCTION} . @var{ALIST})},
where @var{FUNCTION} is a function or a list of functions. Each such
function should accept two arguments: a buffer to display and an
alist of the same form as @var{ALIST}. @xref{Choosing Window,,,elisp,},
alist of the same form as @var{ALIST}. See @ref{Choosing Window,,,elisp,},
for details.
The default is:
@ -798,8 +808,8 @@ The default is:
@end lisp
This displays the window at the bottom of the selected frame.
For alternatives @xref{Buffer Display Action Functions,,,elisp,},
and @xref{Buffer Display Action Alists,,,elisp,}.
For alternatives see @ref{Buffer Display Action Functions,,,elisp,},
and @ref{Buffer Display Action Alists,,,elisp,}.
When you switch to a different ACTION, you should keep the ALIST
entries for @code{dedicated} and @code{inhibit-same-window} in most cases.
@ -828,11 +838,147 @@ when creating a new prefix with @code{transient-define-prefix}.
@anchor{Accessibility Options}
@subheading Accessibility Options
For visually impaired users I recommend the following configuration.
If you need more guidance or would like to share your experience,
please don't hesitate to contact me.
@lisp
(setopt transient-enable-menu-navigation 'force-verbose)
(setopt transient-navigate-to-group-descriptions t)
(setopt transient-describe-menu t)
(setopt transient-select-menu-window t)
(setopt transient-force-single-column t)
(setopt transient-prefer-reading-value t)
(setopt transient-use-accessible-values t)
(setopt transient-use-accessible-formats t)
@end lisp
Additionally you have allow the command, which you use to read the
text at point, to be run when a transient menu is active, for example:
@lisp
(define-key transient-predicate-map
[my-read-text-at-point] #'transient--do-stay)
@end lisp
@defopt transient-enable-menu-navigation
This option is documented in the previous node (@ref{Essential Options}). You might want to change the value from @code{verbose} to
@code{force-verbose}, which causes information to be shown in the echo
area, even if it is identical to information already displayed in
the menu buffer. Whether that is useful to you depends on whether
your setup makes it easy to read the last message displayed in the
echo area.
@end defopt
@defopt transient-navigate-to-group-descriptions
This option controls whether menu navigation commands stop at group
descriptions. If your output method works by reading the text at
point, you most likely want to enable this.
If @code{transient-enable-menu-navigation} is non-@code{nil}, which it is by
default, @kbd{@key{UP}} and @kbd{@key{DOWN}} move from suffix to suffix. When this option
is non-@code{nil} as well, then they additionally stop at group descriptions.
This is useful because it allows braille and audio devices to output
the group title at point.
@end defopt
@defopt transient-describe-menu
This option controls whether a short description about the menu
itself is inserted at the beginning of the menu buffer.
When this is non-@code{nil}, then the menu buffer begins with a short
description. Ideally this is a string written exactly for that
purpose, but because this is a new feature, most menu commands do
not provide that yet. In that case the first line of the prefix
command's docstring is used as fallback. If the value is @code{docstring},
then the docstring is used even if a description is available.
@end defopt
@defopt transient-select-menu-window
This option controls whether the window displaying the transient menu
is automatically selected as soon as it is displayed.
Enabling this is discouraged, except for users of braille and audio
output devises. Note that enabling this, or alternatively selecting
the menu window on demand, are both unnecessary, to be able to move
the cursor in the menu. See @code{transient-enable-menu-navigation}.
@end defopt
@defopt transient-force-single-column
This option controls whether the use of a single column to display
suffixes is enforced. This might be useful for users with low
vision who use large text and might otherwise have to scroll in two
dimensions.
dimensions. This is also useful for blind users, because it causes
suffixes to be navigated in a more natural order, because often
related commands are displayed in the same column but navigation
first moves horizontally to the next item on the same row.
@end defopt
@defopt transient-prefer-reading-value
This option controls whether reading a new value is preferred over
other value selection methods.
If this is @code{nil} (the default), then certain arguments are directly
disabled when they are invoked, while they have a non-@code{nil} value. I.e.,
to switch from one non-@code{nil} value to another non-@code{nil} value, such commands
have to be invoked twice. For other arguments, which happen to have a
small set of possible values, all values are displayed at all times,
using solely coloring to indicate which of the values is active. When
such an infix command is invoked it cycles to the next value.
This default does not work for visually impaired user. If this option
is non-@code{nil}, then more arguments immediately read the new value, instead
of being toggled off on first invocation, or instead of cycling through
values.
@end defopt
@defopt transient-use-accessible-values
This option controls whether values are shown in a way that does not
rely on coloring.
If this is @code{nil} (the default), then colors are used to communicate the
state of arguments. For certain argument types the state is solely
communicated that way. For example, an enabled command-line switch is
shown using some bright color, and disabling that argument, changes the
color to gray, without otherwise changing the displayed text.
This default does not work for visually impaired user. If this option
is non-@code{nil}, then the state is additionally communicated through other
means. A switch, for example, is either followed by "is enabled" or
"is disabled". How exactly the state is communicated depends on the
type of the infix command.
Note that packages, which use Transient, can define their own infix
command types, which may or may not involve overriding Transient's
code, which honors this new option. I.e., it will take some time until
everything respects this setting.
@end defopt
@defopt transient-use-accessible-formats
This option controls whether more accessible format strings are used
for menu elements.
If this is non-@code{nil}, then menu elements are displayed in a way, that I
hope, is more suitable for visually impaired users than the default.
Please provide feedback, so that we can together work on improving this.
By default the format specified by an element's @code{format} slot is used.
When this is non-@code{nil}, then the @code{accessible-format} slot is used instead.
One change implemented in the latter is that for an element representing
a command-line argument, the argument and its value are moved before the
description, giving quicker access to the current state, while still
allowing users to read the description, in case they don't know yet what
the argument in question does.
Enabling this also causes the string "inapt" to be added at the very
beginning of the text describing a command that currently cannot be
used. When using the default format, the only visual clue that a
command is inapt, is that the complete text representing it is grayed
out. (As an example of such an inapt command, consider the case of a
commands that can only act on the file at point, when there currently
isn't a file at point.) Placing the string "inapt" at the very
beginning gives users the opportunity to immediately skip over unusable
commands, while still giving them the opportunity to read on.
@end defopt
@anchor{Auxiliary Options}
@ -861,7 +1007,7 @@ used to draw the line.
This user option may be overridden if @code{:mode-line-format} is passed
when creating a new prefix with @code{transient-define-prefix}.
Otherwise this can be any mode-line format. @xref{Mode Line Format,,,elisp,}, for details.
Otherwise this can be any mode-line format. See @ref{Mode Line Format,,,elisp,}, for details.
@end defopt
@defopt transient-semantic-coloring
@ -1002,8 +1148,8 @@ That buffer is current and empty when this hook is runs.
@cindex modifying existing transients
To an extent, transients can be customized interactively,
@xref{Enabling and Disabling Suffixes}. This section explains how existing
To an extent, transients can be customized interactively, see
@ref{Enabling and Disabling Suffixes}. This section explains how existing
transients can be further modified non-interactively. Let's begin
with an example:
@ -1029,10 +1175,10 @@ which can be included in multiple prefixes. See TODO@.
as expected by @code{transient-define-prefix}. Note that an infix is a
special kind of suffix. Depending on context ``suffixes'' means
``suffixes (including infixes)'' or ``non-infix suffixes''. Here it
means the former. @xref{Suffix Specifications}.
means the former. See @ref{Suffix Specifications}.
@var{SUFFIX} may also be a group in the same form as expected by
@code{transient-define-prefix}. @xref{Group Specifications}.
@code{transient-define-prefix}. See @ref{Group Specifications}.
@item
@var{LOC} is a key description (a string as returned by @code{key-description}
@ -1072,7 +1218,7 @@ or after @var{LOC}.
Conceptually adding a binding to a transient prefix is similar to
adding a binding to a keymap, but this is complicated by the fact
that multiple suffix commands can be bound to the same key, provided
they are never active at the same time, @xref{Predicate Slots}.
they are never active at the same time, see @ref{Predicate Slots}.
Unfortunately both false-positives and false-negatives are possible.
To deal with the former, use non-@code{nil} @var{KEEP-OTHER@.} The symbol @code{always}
@ -1205,14 +1351,14 @@ enabled. One benefit of the Transient interface is that it remembers
history not only on a global level (``this command was invoked using
these arguments, and previously it was invoked using those other
arguments''), but also remembers the values of individual arguments
independently. @xref{Using History}.
independently. See @ref{Using History}.
After a transient prefix command is invoked, @kbd{C-h @var{KEY}} can be used to
show the documentation for the infix or suffix command that @kbd{@var{KEY}} is
bound to (@pxref{Getting Help for Suffix Commands}), and infixes and
bound to (see @ref{Getting Help for Suffix Commands}), and infixes and
suffixes can be removed from the transient using @kbd{C-x l @var{KEY}}. Infixes
and suffixes that are disabled by default can be enabled the same way.
@xref{Enabling and Disabling Suffixes}.
See @ref{Enabling and Disabling Suffixes}.
Transient ships with support for a few different types of specialized
infix commands. A command that sets a command line option, for example,
@ -1263,7 +1409,7 @@ explicitly.
@var{GROUP}s add key bindings for infix and suffix commands and specify
how these bindings are presented in the menu buffer. At least one
@var{GROUP} has to be specified. @xref{Binding Suffix and Infix Commands}.
@var{GROUP} has to be specified. See @ref{Binding Suffix and Infix Commands}.
The @var{BODY} is optional. If it is omitted, then @var{ARGLIST} is ignored and
the function definition becomes:
@ -1314,13 +1460,11 @@ GROUPs have the same form as for @code{transient-define-prefix}.
@section Binding Suffix and Infix Commands
The macro @code{transient-define-prefix} is used to define a transient.
This defines the actual transient prefix command (@pxref{Defining
Transients}) and adds the transient's infix and suffix bindings, as
This defines the actual transient prefix command (see @ref{Defining Transients}) and adds the transient's infix and suffix bindings, as
described below.
Users and third-party packages can add additional bindings using
functions such as @code{transient-insert-suffix} (@pxref{Modifying Existing Transients}).
These functions take a ``suffix specification'' as one of
functions such as @code{transient-insert-suffix} (see @ref{Modifying Existing Transients}). These functions take a ``suffix specification'' as one of
their arguments, which has the same form as the specifications used in
@code{transient-define-prefix}.
@ -1336,7 +1480,7 @@ for a set of suffixes.
Several group classes exist, some of which organize suffixes in
subgroups. In most cases the class does not have to be specified
explicitly, but @xref{Group Classes}.
explicitly, but see @ref{Group Classes}.
Groups are specified in the call to @code{transient-define-prefix}, using
vectors. Because groups are represented using vectors, we cannot use
@ -1346,13 +1490,10 @@ brackets to do the latter.
Group specifications then have this form:
@lisp
[@{@var{LEVEL}@} @{@var{DESCRIPTION}@}
@{@var{KEYWORD} @var{VALUE}@}...
@var{ELEMENT}...]
[@{LEVEL@} @{DESCRIPTION@} @{KEYWORD VALUE@}... ELEMENT...]
@end lisp
The @var{LEVEL} is optional and defaults to 4. @xref{Enabling and
Disabling Suffixes}.
The @var{LEVEL} is optional and defaults to 4. See @ref{Enabling and Disabling Suffixes}.
The @var{DESCRIPTION} is optional. If present, it is used as the heading of
the group.
@ -1383,7 +1524,7 @@ useful while rebase is already in progress; and another that uses
initiate a rebase.
These predicates can also be used on individual suffixes and are
only documented once, @xref{Predicate Slots}.
only documented once, see @ref{Predicate Slots}.
@item
The value of @code{:hide}, if non-@code{nil}, is a predicate that controls
@ -1488,13 +1629,13 @@ The form of suffix specifications is documented in the next node.
@cindex suffix specifications
A transient's suffix and infix commands are bound when the transient
prefix command is defined using @code{transient-define-prefix},
@xref{Defining Transients}. The commands are organized into groups,
@xref{Group Specifications}. Here we describe the form used to bind an
prefix command is defined using @code{transient-define-prefix}, see
@ref{Defining Transients}. The commands are organized into groups, see
@ref{Group Specifications}. Here we describe the form used to bind an
individual suffix command.
The same form is also used when later binding additional commands
using functions such as @code{transient-insert-suffix}, @xref{Modifying Existing Transients}.
using functions such as @code{transient-insert-suffix}, see @ref{Modifying Existing Transients}.
Note that an infix is a special kind of suffix. Depending on context
``suffixes'' means ``suffixes (including infixes)'' or ``non-infix
@ -1503,9 +1644,7 @@ suffixes''. Here it means the former.
Suffix specifications have this form:
@lisp
([@var{LEVEL}]
[@var{KEY} [@var{DESCRIPTION}]]
@var{COMMAND}|@var{ARGUMENT} [@var{KEYWORD} @var{VALUE}]...)
([LEVEL] [KEY [DESCRIPTION]] COMMAND|ARGUMENT [KEYWORD VALUE]...)
@end lisp
@var{LEVEL}, @var{KEY} and @var{DESCRIPTION} can also be specified using the @var{KEYWORD}s
@ -1516,8 +1655,8 @@ the object's values just for the binding inside this transient.
@itemize
@item
@var{LEVEL} is the suffix level, an integer between 1 and 7.
@xref{Enabling and Disabling Suffixes}.
@var{LEVEL} is the suffix level, an integer between 1 and 7. See
@ref{Enabling and Disabling Suffixes}.
@item
KEY is the key binding, a string in the format returned by
@ -1591,7 +1730,7 @@ guessed based on the long argument. If the argument ends with @samp{=}
Finally, details can be specified using optional @var{KEYWORD}-@var{VALUE} pairs.
Each keyword has to be a keyword symbol, either @code{:class} or a keyword
argument supported by the constructor of that class. @xref{Suffix Slots}.
argument supported by the constructor of that class. See @ref{Suffix Slots}.
If a keyword argument accepts a function as value, you an use a @code{lambda}
expression. As a special case, the @code{##} macro (which returns a @code{lambda}
@ -1941,8 +2080,8 @@ means that all outer prefixes are exited at once.
@item
The behavior for non-suffixes can be set for a particular prefix,
by the prefix's @code{transient-non-suffix} slot to a boolean, a suitable
pre-command function, or a shorthand for such a function.
@xref{Pre-commands for Non-Suffixes}.
pre-command function, or a shorthand for such a function. See
@ref{Pre-commands for Non-Suffixes}.
@item
The common behavior for the suffixes of a particular prefix can be
@ -2267,7 +2406,7 @@ Transient itself provides a single class for prefix commands,
@code{transient-prefix}, but package authors may wish to define specialized
classes. Doing so makes it possible to change the behavior of the set
of prefix commands that use that class, by implementing specialized
methods for certain generic functions (@pxref{Prefix Methods}).
methods for certain generic functions (see @ref{Prefix Methods}).
A transient prefix command's object is stored in the @code{transient--prefix}
property of the command symbol. While a transient is active, a clone
@ -2282,7 +2421,7 @@ object should not affect later invocations.
@item
All suffix and infix classes derive from @code{transient-suffix}, which in
turn derives from @code{transient-child}, from which @code{transient-group} also
derives (@pxref{Group Classes}).
derives (see @ref{Group Classes}).
@item
All infix classes derive from the abstract @code{transient-infix} class,
@ -2290,13 +2429,13 @@ which in turn derives from the @code{transient-suffix} class.
Infixes are a special type of suffixes. The primary difference is
that infixes always use the @code{transient--do-stay} pre-command, while
non-infix suffixes use a variety of pre-commands (@pxref{Transient State}). Doing that is most easily achieved by using this class,
non-infix suffixes use a variety of pre-commands (see @ref{Transient State}). Doing that is most easily achieved by using this class,
though theoretically it would be possible to define an infix class
that does not do so. If you do that then you get to implement many
methods.
Also, infixes and non-infix suffixes are usually defined using
different macros (@pxref{Defining Suffix and Infix Commands}).
different macros (see @ref{Defining Suffix and Infix Commands}).
@item
Classes used for infix commands that represent arguments should
@ -2607,7 +2746,7 @@ returns a brief summary about the command at point or hovered with
the mouse.
This function is called when the mouse is moved over a command and
(if the value of @code{transient-enable-popup-navigation} is @code{verbose}) when
(if the value of @code{transient-enable-menu-navigation} is @code{verbose}) when
the user navigates to a command using the keyboard.
If OBJ's @code{summary} slot is a string, that is used. If @code{summary} is a
@ -2706,7 +2845,7 @@ secondary value, called a ``scope''. See @code{transient-define-prefix}.
@code{transient-suffix}, @code{transient-non-suffix} and @code{transient-switch-frame}
play a part when determining whether the currently active transient
prefix command remains active/transient when a suffix or arbitrary
non-suffix command is invoked. @xref{Transient State}.
non-suffix command is invoked. See @ref{Transient State}.
@item
@code{refresh-suffixes} Normally suffix objects and keymaps are only setup
@ -2766,6 +2905,12 @@ fallback descriptions for suffixes that lack a description. This
is intended to be temporarily used when implementing of a new prefix
command, at which time @code{transient-command-summary-or-name} is a useful
value.
@item
@code{description} a short string describing the prefix, which users can
opt-in to be displayed at the top of the menu buffer. This should
be more concise than the first line of the docstring, which is used
as a fallback if no description is provided.
@end itemize
@anchor{Internal}
@ -2788,7 +2933,7 @@ of the same symbol.
@item
@code{level} The level of the prefix commands. The suffix commands whose
layer is equal or lower are displayed. @pxref{Enabling and Disabling Suffixes}.
layer is equal or lower are displayed. See @ref{Enabling and Disabling Suffixes}.
@item
@code{value} The likely outdated value of the prefix. Instead of accessing
@ -2812,19 +2957,46 @@ Here we document most of the slots that are only available for suffix
objects. Some slots are shared by suffix and group objects, they are
documented in @ref{Predicate Slots}.
Also @xref{Suffix Classes}.
Also see @ref{Suffix Classes}.
@anchor{Slots of @code{transient-child}}
@subheading Slots of @code{transient-child}
This is the abstract superclass of @code{transient-suffix} and @code{transient-group}.
This is where the shared @code{if*} and @code{inapt-if*} slots (@pxref{Predicate Slots}),
the @code{level} slot (@pxref{Enabling and Disabling Suffixes}), and the @code{advice}
and @code{advice*} slots (@pxref{Slots of @code{transient-suffix}}) are defined.
This is the abstract superclass of @code{transient-suffix} and
@code{transient-group}. In addition to the slots listed below, this class
is also where the @code{if*} and @code{inapt-if*} slots (see @ref{Predicate Slots}) and
the @code{level} slot (see @ref{Enabling and Disabling Suffixes}) are defined.
@itemize
@item
@code{parent} The object for the parent group.
@code{parent} The object for the parent group, if any.
@item
@code{inactive} If an @code{:if*} predicate of a suffix or group returns @code{nil},
then it is not displayed in the menu, but it has to remain in the
internal object tree, in case that predicate later returns @code{t}, and
the @code{object} therefore has to appear in the menu again. Likewise a
group or suffix may be (potentially only temporarily) inactive due
to its @code{level}. The @code{inactive} slot is set accordingly. Never set it
yourself.
@end itemize
The following two slots are experimental. If they are set for a
group, then they apply to all suffixes in that group, except for
suffixes that themselves set the same slot to a non-@code{nil} value.
@itemize
@item
@code{advice} A function used to advise the command. The advise is called
using @code{(apply advice command args)}, i.e., it behaves like an "around"
advice.
@item
@code{advice*} A function used to advise the command. Unlike @code{advice}, this
advises not only the command body but also its @code{interactive} spec. If
both slots are non-@code{nil}, @code{advice} is used for the body and @code{advice*} is
used for the @code{interactive} form. When advising the @code{interactive} spec,
called using @code{(funcall advice #'advice-eval-interactive-spec spec)}.
@end itemize
@anchor{Slots of @code{transient-suffix}}
@ -2846,7 +3018,7 @@ which is useful for alignment purposes.
@code{command} The command, a symbol.
@item
@code{transient} Whether to stay transient. @xref{Transient State}.
@code{transient} Whether to stay transient. See @ref{Transient State}.
@item
@code{format} The format used to display the suffix in the menu buffer.
@ -2877,34 +3049,23 @@ unspecified, the prefix controls how help is displayed for its
suffixes. See also function @code{transient-show-help}.
@item
@code{summary} The summary displayed in the echo area, or as a tooltip.
If this is @code{nil}, which it usually should be, the first line of the
documentation string is used instead. See @code{transient-show-summary}
for details.
@code{summary} A short description to be displayed in addition to the text
displayed in the menu itself. If this is @code{nil}, the first line of the
documentation string is used instead. If non-@code{nil}, this must be a
string or a function that returns a string or @code{nil}.
This description is displayed as a tooltip, when hovering an element
in the menu. If @code{transient-enable-menu-navigation} is @code{verbose}, it is
also shown in the echo area, when navigating the menu.
The generic function @code{transient-get-summary} is used to determine and
format this description.
@item
@code{definition} A command, which is used if the body is omitted when
defining a command using @code{transient-define-suffix}.
@end itemize
The following two slots are experimental. They can also be set for a
group, in which case they apply to all suffixes in that group, except
for suffixes that set the same slot to a non-@code{nil} value.
@itemize
@item
@code{advice} A function used to advise the command. The advise is called
using @code{(apply advice command args)}, i.e., it behaves like an "around"
advice.
@item
@code{advice*} A function used to advise the command. Unlike @code{advice}, this
advises not only the command body but also its @code{interactive} spec. If
both slots are non-@code{nil}, @code{advice} is used for the body and @code{advice*} is
used for the @code{interactive} form. When advising the @code{interactive} spec,
called using @code{(funcall advice #'advice-eval-interactive-spec spec)}.
@end itemize
@anchor{Slots of @code{transient-infix}}
@subheading Slots of @code{transient-infix}
@ -3070,14 +3231,14 @@ currently cannot be invoked.
By default these predicates run when the prefix command is invoked,
but this can be changes, using the @code{refresh-suffixes} prefix slot.
@xref{Prefix Slots}.
See @ref{Prefix Slots}.
One more slot is shared between group and suffix classes, @code{level}. Like
the slots documented above, it is a predicate, but it is used for a
different purpose. The value has to be an integer between 1
and 7. @code{level} controls whether a suffix or a group should be
available depending on user preference.
@xref{Enabling and Disabling Suffixes}.
See @ref{Enabling and Disabling Suffixes}.
@node FAQ
@appendix FAQ
@ -3092,20 +3253,17 @@ by passing @code{:display-action} to @code{transient-define-prefix}.
@anchor{How can I copy text from the menu buffer?}
@appendixsec How can I copy text from the menu buffer?
To be able to mark text in Transient's menu buffer using the mouse,
you have to add the below binding. Note that for technical reasons,
the region won't be visualized, while doing so. After you have quit
the transient menu, you will be able to yank it in another buffer.
You can select text in the menu buffer using the mouse, like in most
other buffers, by clicking @code{mouse-1} and keeping it pressed while
dragging.
@lisp
(keymap-set transient-predicate-map
"<mouse-set-region>"
#'transient--do-stay)
@end lisp
(Before v0.13.0, the above required additional configuration and the
region was not visualized while dragging. This isn't the case anymore,
but explains why the following was once deemed necessary.)
Copying the region while not seeing the region is a bit fiddly, so a
dedicated command, @code{transient-copy-menu-text}, was added. You have to
add a binding for this command in @code{transient-map}.
Alternatively the command @code{transient-copy-menu-text} can be used to copy
the complete content of the menu buffer. You have to add a binding
for this command in @code{transient-map}.
@lisp
(keymap-set transient-map "C-c C-w" #'transient-copy-menu-text)
@ -3115,9 +3273,9 @@ add a binding for this command in @code{transient-map}.
@appendixsec How can I autoload prefix and suffix commands?
If your package only supports Emacs 30, just prefix the definition
with @code{;;;###autoload}. If your package supports released versions of
Emacs, you unfortunately have to use a long form autoload comment
as described in @ref{Autoload,,,elisp,}.
with @code{;;;###autoload}. If your package supports older Emacs releases,
you unfortunately have to use a long-form autoload comment as
described in @ref{Autoload,,,elisp,}.
@lisp
;;;###autoload (autoload 'magit-dispatch "magit" nil t)

View file

@ -332,6 +332,29 @@ This means that the request was redirected to the URL
@item (:error (@var{error-symbol} . @var{data}))
This means that an error occurred. If so desired, the error can be
signaled with @code{(signal @var{error-symbol} @var{data})}.
@cindex status of GnuTLS connection, as provided by @code{url-retrieve}
@findex gnutls-peer-status-warning-describe
@findex gnutls-peer-status
@item (:peer @var{gnutls-information})
This means that GnuTLS was used for a TLS connection to the peer. The
@var{gnutls-information} has the following form:
@lisp
((:warnings @var{warning}@dots{})
(:certificates @var{certificate}@dots{} @var{peer-data}))
@end lisp
@noindent
where the @var{warning}s are warnings, if any, emitted by GnuTLS for the
connection, and @var{certificate}s is the list of certificates used for
the TLS connection followed by the properties of the connection in
@var{peer-data}. Both @var{warning}s and @var{peer-data} are in the
form of a key-value pairs (i.e., they are plists). The value of each
key in the @code{:warnings} list is a symbol whose description can be
obtained by using @code{gnutls-peer-status-warning-describe}, and the
various keys of the @var{peer-data} list and their values are documented
in the doc string of @code{gnutls-peer-status}.
@end table
When the callback function is called, the current buffer is the one

View file

@ -58,7 +58,7 @@ modify this GNU manual.''
@top @acronym{SES}: Simple Emacs Spreadsheet
@display
@acronym{SES} est mode majeur de GNU Emacs pour éditer des fichiers
@acronym{SES} est un mode majeur de GNU Emacs pour éditer des fichiers
tableur, c.-à-d.@: des fichiers contenant une grille rectangulaire de
cellules. Les valeurs des cellules sont spécifiées par des formules
pouvant se référer aux valeurs dautres cellules.
@ -70,7 +70,7 @@ Pour les rapports danomalie, utiliser @kbd{M-x report-emacs-bug}.
@insertcopying
@menu
* Boniment: Sales Pitch. Pourquoi utiliser @acronym{SES}?
* Boniment: Sales Pitch. Pourquoi utiliser @acronym{SES} ?
* Tuto: Quick Tutorial. Une introduction sommaire
* Les bases: The Basics. Les commandes de base du tableur
* Fonctions avancées: Advanced Features. Vous voulez en savoir plus ?
@ -335,12 +335,12 @@ Mettre en vedette toutes les cellules (@code{mark-whole-buffer}).
@node Formulas
@section Formules de cellule
@cindex formules
@cindex formules, saisire
@cindex formules, saisir
@cindex valeurs
@cindex valeurs de cellule
@cindex éditer des cellules
@findex ses-read-cell
@findex ses-read-symbole
@findex ses-read-symbol
@findex ses-edit-cell
@findex ses-recalculate-cell
@findex ses-recalculate-all

File diff suppressed because it is too large Load diff

View file

@ -17,6 +17,27 @@ This refers to https://github.com/joaotavora/eglot/issues/. That is,
to look up issue github#1234, go to
https://github.com/joaotavora/eglot/issues/1234.
* Changes to upcoming Eglot
** New command 'M-x eglot-describe-connection'
Pops up a detailed description buffer for the current connection,
outlining aspects such as the LSP server name and version, the project
name and root path, among others.
** Improvements to 'M-x eglot-list-connections'
New key bindings: 'k' shuts down, 'r' reconnects, 'e' visits the events
buffer, 'w' shows workspace configuration, and 'RET' invokes
'eglot-describe-connection'.
** Eglot uses new built-in 'markdown-ts-mode' of Emacs 31 (bug#80127)
This means that on newer versions of Emacs the external
'markdown-mode.el' package does not need to be installed to render
Markdown content.
* Changes in Eglot 1.23 (2/4/2026)

View file

@ -12,10 +12,47 @@ extensible IRC (Internet Relay Chat) client distributed with
GNU Emacs since Emacs version 22.1.
* Changes in ERC 5.6.2
* Changes in ERC 5.7
** Changes in the library API.
*** Module setup runs in query buffers on reconnect.
A module's setup would always run in channel buffers on reconnect, due
to channels being rejoined, but query buffers lacked a similar
opportunity to reinitialize their state for the new session. This is no
longer the case.
*** Local modules activate in preferred order instead of in reverse.
In recent versions, ERC has enabled local modules in the reverse order
of that produced by the "set" function used by 'setopt' and the Custom
UI for the option 'erc-modules'. Specifically, Built-in locals were
activated in reverse lexicographic order after third-party ones, which
were simply reversed as given. Now, just like with global modules, ERC
preserves the preferred order when activating local modules for new
sessions.
* Changes in ERC 5.6.2
** Option 'erc-log-insert-log-on-open' can be a function.
Rather than insert redundant logs into all buffers when reconnecting,
which is what happens when this option is set to t, ERC 5.6.2 allows
users to exercise more control by specifying a predicate. The provided
'erc-log-new-target-buffer-p' tells ERC to only insert logs when
creating a new target buffer, such as when issuing a "/JOIN" or a
"/QUERY" or when connecting for the first time with autojoin configured.
** Changes in the library API.
*** Function 'erc-log-setup-logging' deprecated.
In order to ensure proper buffer-local setup, the 'log' module has
always run this function somewhat indiscriminately and overly often.
This might be fine were it not for the function's interest in the option
'erc-log-insert-log-on-open' and its consequent altering of buffer text
in a manner only conducive to buffer creation. The module now conducts
such business in a tidier and more internal fashion that no longer has
any use for the function nor its presence in 'erc-connect-pre-hook'.
*** Accessors like 'erc-channel-user-voice' may ignore assignments.
ERC now silently ignores attempts to enable certain status flags on
'erc-channel-user' objects if the connection's "PREFIX" parameter omits

View file

@ -12,7 +12,7 @@ Non-ASCII examples:
Europe: <x-charset><param>latin-iso8859-1</param>¡Hola!, Grüß Gott, Hyvää päivää,</x-charset> Tere õhtust,<x-charset><param>latin-iso8859-3</param> Bonġu
Cześć!,</x-charset><x-charset><param>latin-iso8859-2</param> Dobrý den,</x-charset><x-charset><param>cyrillic-iso8859-5</param> Здравствуйте!,</x-charset><x-charset><param>greek-iso8859-7</param> Γειά σας,</x-charset> გამარჯობა
Africa: <x-charset><param>ethiopic</param>ሠላም</x-charset>
Middle/Near East:<x-charset><param>hebrew-iso8859-8</param> שָׁלוֹם,</x-charset> السّلام عليكم
Middle/Near East:<x-charset><param>hebrew-iso8859-8</param> שָׁלוֹם,</x-charset> السّلام عليكم, ܣܠܡܐ
South Asia: નમસ્તે, नमस्ते, ನಮಸ್ಕಾರ, നമസ്കാരം, ନମସ୍କାର,
ආයුබෝවන්, வணக்கம், నమస్కారం,<x-charset><param>tibetan</param> བཀྲ་ཤིས་བདེ་ལེགས༎</x-charset>
South East Asia: ជំរាបសួរ,<x-charset><param>lao</param> ສະບາຍດີ,</x-charset> မင်္ဂလာပါ,<x-charset><param>thai-tis620</param> สวัสดีครับ,</x-charset><x-charset><param>vietnamese-viscii-lower</param> </x-charset><x-charset><param>vietnamese-viscii-upper</param>C</x-charset><x-charset><param>vietnamese-viscii-lower</param>hào bạn</x-charset>
@ -107,6 +107,7 @@ Spanish (español) ¡Hola!
Sundanese (ᮃᮊ᮪ᮟᮛᮞᮥᮔ᮪ᮓ) ᮞᮙ᮪ᮕᮥᮛᮞᮥᮔ᮪
Swedish (svenska) Hej / Goddag / Hallå
Syloti Nagri (ꠍꠤꠟꠐꠤ ꠘꠣꠉꠞꠤ) ꠀꠌ꠆ꠍꠣꠟꠣꠝꠥ ꠀꠟꠣꠁꠇꠥꠝ / ꠘꠝꠡ꠆ꠇꠣꠞ
Syriac (ܣܘܪܝܝܐ) ܫܠܡܐ
Tamil (தமிழ்) வணக்கம்
Telugu (తెలుగు) నమస్కారం
Tagalog (ᜊᜌ᜔ᜊᜌᜒᜈ᜔) ᜃᜓᜋᜓᜐ᜔ᜆ

View file

@ -3,6 +3,19 @@
Copyright (C) 2001-2026 Free Software Foundation, Inc.
See the end of the file for license conditions.
* Changes in Emacs 31.1
** Bug Fixes in Emacs 31.1
*** 'mh-thread-refile' now remembers the destination folder.
For consistency with 'mh-refile-msg', 'mh-thread-refile' now updates
'mh-last-destination' and 'mh-last-destination-folder' unless the
optional argument 'dont-update-last-destination-flag' is non-nil (closes
SF #473).
* Changes in MH-E 8.6
Version 8.6 fixes composition errors in nmh 1.6.

4589
etc/NEWS

File diff suppressed because it is too large Load diff

4794
etc/NEWS.31 Normal file

File diff suppressed because it is too large Load diff

View file

@ -4,13 +4,930 @@ ORG NEWS -- history of user-visible changes. -*- mode: org; coding: utf-8 -*-
#+LINK: doc https://orgmode.org/worg/doc.html#%s
#+LINK: msg https://list.orgmode.org/%s/
#+LINK: git https://git.savannah.gnu.org/cgit/emacs/org-mode.git/commit/?id=%s
#+LINK: git https://git.savannah.nongnu.org/cgit/org-mode.git/commit/?id=%s
#+macro: kbd (eval (org-texinfo-kbd-macro $1))
Copyright (C) 2012-2026 Free Software Foundation, Inc.
See the end of the file for license conditions.
Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
* Version 9.8
** Important announcements and breaking changes
# Here, we list the *most important* changes and changes that _likely_
# require user action for most Org mode users.
# Sorted from most important to least important.
*** You may need to update =org-protocol= bookmarklets for browsers
In Firefox 133 and Firefox 128.5 ESR, the previously suggested
JavaScript bookmarklets replace the current page with the bookmarklet URL
text. We have updated the manual with new bookmarklets that do not
have this problem.
The new bookmarklets have ~void(0);~ appended at the end, so that they
do not return anything.
Example:
#+begin_example
javascript:location.href='org-protocol://store-link?url='+
encodeURIComponent(location.href);void(0);
#+end_example
*** =C-c C-x C-v= command toggling inline image display has been reworked
Previously, =C-c C-x C-v= always toggled image display in the whole
buffer (or narrowed part of the buffer). With prefix argument, it
also forced displaying image links with description.
Now, =C-c C-x C-v= is bound to a new command ~org-link-preview~, which
uses different defaults:
1. When the region is active, images in the region are previewed
2. Otherwise, if there is an image at point, it is toggled. If there
is no image at point, images in the current entry are previewed
3. With the =C-u= argument, image previews in the active region or at
point are cleared instead
4. The =C-u C-u= argument unconditionally shows all images in the
accessible portion of the buffer
5. The =C-u C-u C-u= argument unconditionally clears all images in the
accessible portion of the buffer
6. Displaying images over links with description can be forced using
numeric argument:
- ~C-u 1~ for toggling all images at point/current entry
- ~C-u 11~ for toggling all images in buffer
(The first five of these prefix argument behaviors are the same as that of
the ~org-latex-preview~ command.)
In addition to images, ~org-link-preview~ can also be used to preview
Org links of all types for which preview behavior is defined, see
[[#link-preview][previews for arbitrary link types]].
The old ~org-toggle-inline-images~ command is obsolete but still
available. You can bind it back to =C-c C-x C-v= by adding the
following to your config:
#+begin_src emacs-lisp
(eval-after-load 'org-keys
(org-defkey org-mode-map (kbd "C-c C-x C-v") #'org-toggle-inline-images))
#+end_src
*** Org mode no longer treats =:results drawer= as verbatim output
Previously, =:results drawer= left the code block results verbatim in
some scenarios. This is no longer the case, in line with the manual
and the intended purpose of this option. However, the fix may have
brought subtle changes in the code block output for users who made use
of the previous erroneous behavior. If you use =:results drawer= in your
Org documents, please watch out for potential changes in the code evaluation.
*** Diary-style timestamps are exported together with active timestamps
~org-export-with-timestamps~ and ~org-icalendar-with-timestamps~ now
treat diary-style timestamps as a type of active timestamp for
purposes of export.
This mainly affects iCalendar export, where diary timestamps will now
be included when only active timestamps are exported (the default).
This should have minimal impact on non-iCalendar exporters, since
~org-export-with-timestamps~ was already ~t~ by default. However,
users who manually set ~org-export-with-timestamps~ to ~active~ will
now have diary timestamps included as well.
To use the old behavior and export active timestamps only without
diary timestamps, users can set ~org-export-with-timestamps~ and
~org-icalendar-with-timestamps~ to ~active-exclude-diary~.
*** ~org-element-drawer-parser~ assigns ~:pre-blank~ property
Previously, the whole contents of drawer, including blank lines at the beginning were
parsed as paragraph. Now, the blank lines at the beginning are stored in ~:pre-blank~
property, just as in other greater elements.
*** ~org-element-org-data-parser~ now returns syntax node with ~:pre-blank~ property
Previously, parsing ~org-data~ syntax node did not record information
about blank lines at the beginning of the document. Now, the number
of blank lines is recorded in ~:pre-blank~ property.
~org-element-org-data-interpreter~ takes into account this information.
*** Emacs 26 and Emacs 27 support has been dropped
We maintain compatibility with the latest Emacs release, and two
versions prior the latest. The latest is Emacs 30, so we drop
everything before Emacs 28.
** New features
# We list the most important features, and the features that may
# require user action to be used.
*** Some navigation commands can now be repeated
When ~repeat-mode~ is turned on, the following navigation commands can
be repeated:
| Command | Key binding | Repeat key |
|-----------------------------------+------------------------+--------------|
| ~org-next-visible-heading~ | {{{kbd(C-c C-n)}}} | {{{kbd(n)}}} |
| ~org-previous-visible-heading~ | {{{kbd(C-c C-p)}}} | {{{kbd(p)}}} |
| ~org-forward-heading-same-level~ | {{{kbd(C-c C-f)}}} | {{{kbd(f)}}} |
| ~org-backward-heading-same-level~ | {{{kbd(C-c C-b)}}} | {{{kbd(b)}}} |
| ~org-up-heading~ | {{{kbd(C-c C-u)}}} | {{{kbd(u)}}} |
| ~org-next-block~ | {{{kbd(C-c M-f)}}} | {{{kbd(f)}}} |
| ~org-previous-block~ | {{{kbd(C-c M-b)}}} | {{{kbd(b)}}} |
| ~org-next-link~ | {{{kbd(C-c C-x C-n)}}} | {{{kbd(n)}}} |
| ~org-previous-link~ | {{{kbd(C-c C-x C-p)}}} | {{{kbd(p)}}} |
The keybindings in the repeat-maps can be changed by customizing
~org-navigation-repeat-map~, ~org-link-navigation-repeat-map~, and
~org-block-navigation-repeat-map~.
See the new [[info:org#Repeating commands]["Repeating commands"]] section in Org mode manual.
*** New babel backend for C# code blocks
Org now officially enables C# code block evaluation based on the .NET SDK.
The old backend that does not use .NET SDK remains in org-contrib
and will be removed in a future release. The built-in =ob-csharp.el= should be
considered the official successor.
*** All Org link types can be previewed
:PROPERTIES:
:CUSTOM_ID: link-preview
:END:
Org links support a new parameter =:preview= that can be used to
preview arbitrary link types. The value of this parameter should be a
function that is called to preview links of the corresponding type
(see ~org-link-parameters~).
The new preview system does not bring any brand-new link previews, but
open the possibility for third-party packages to implement custom previews
without having to use non-ideal hacks.
On the user side, the existing image link previews should now run
smoother, especially in Org buffers that have a lot of image links to
preview. The new previews are less blocking, previewing link in
batches, without fully blocking Emacs. See the new
~org-link-preview-batch-size~ and ~org-link-preview-delay~ options.
*** New =%\*N= placeholder in ~org-capture-templates~
The new placeholder is like =%\N=, but gives access not only to the
=%^{prompt}= values, but also to =%^{prompt}X= values.
*** Alignment of image previews can be customized
This feature was added in Org 9.7 but was not documented in the release notes. See [[https://orgmode.org/worg/org-release-notes.html#preview-align][retrospectively added news entry]].
*** ~org-open-at-point-global~ now accepts prefix argument
The argument is passed through to ~org-link-open~, allowing alternative
way to open links, if link ~:follow~ function supports it.
*** ox-latex: Table of contents generation has been fixed and augmented
The LaTeX exporter differs from other exporters in that it does not
include unnumbered sections in the table of contents by default. To
include an unnumbered section, set the property =:UNNUMBERED: toc= on
the section.
Alternatively, you can set the new custom variable
~org-latex-toc-include-unnumbered~ to include unnumbered sections by
default, aligning with other exporters' behavior. In that case, to
exclude a section from the table of contents, mark it as =:UNNUMBERED:
notoc= in its properties.
*** Tables copied from LibreOffice Calc documents can be pasted as Org tables
Tables copied into the clipboard from LibreOffice Calc documents can
now be pasted as an Org table using ~yank-media~.
*** Ditaa code blocks can use ditaa executable, and can produce SVG output
In order to use a ditaa executable instead of a JAR file, you can set
~org-ditaa-default-exec-mode~ to ~'ditaa~. The location of the
executable can be configured via ~org-ditaa-exec~.
SVG output can now be generated; note, however, that this requires a
ditaa version of at least 0.11.0.
*** New datetree capture ~:tree-type~ options
:PROPERTIES:
:CUSTOM_ID: 9.8-datetree-treetype
:END:
For datetree capture, ~:tree-type~ can now be any subset of ~(year
quarter month week day)~ to construct a datetree with the specified
levels. For back-compatibility, the default value of ~nil~ is an
alias for ~(year month day)~, ~month~ is an alias for ~(year month)~,
and ~week~ is an alias for ~(year week day)~.
If ~:tree-type~ is a superset of ~(month week)~, then weeks are
assigned to the month containing Thursday, to be consistent with the
ISO-8601 year-week rule. If ~:tree-type~ contains ~(quarter week)~
but does not contain ~month~, then quarters are defined as 13-week
periods (the final quarter of a 53-week year has 14-weeks).
Otherwise, quarters are defined as 3-month periods.
Additionally, ~:tree-type~ can be a function, in which case it should
take the date as an argument, and generate a list of pairs for
~org-datetree-find-create-hierarchy~. This allows for creating new
types of datetrees (e.g. for lunar calendars, academic calendars,
retail 4-4-5 calendars, etc).
*** New =shortdoc= link type
You can now create links to =shortdoc= documentation groups for Emacs
Lisp functions (see =M-x shortdoc-display-group=). Requires Emacs 28
or newer.
*** Beamer export supports setting frame subtitles
If a headline is exported as a frame, and has its =BEAMER_SUBTITLE=
property set, the value is used as the subtitle.
*** =:wrap= header argument can now be explicitly disabled
Previously, presence of =:wrap= argument (inherited or not) in code
block headers always made the block results wrapped. There was no way
to disable wrapping if =:wrap= was specified in the inherited header
arguments. Now, =:wrap no= or =:wrap nil= will explicitly disable
wrapping.
*** =ob-sqlite=: Added ability to open a database in readonly mode
Added option ~:readonly~ to =ob-sqlite=.
With ~:readonly yes~, the database is opened in readonly mode. For
example:
#+begin_example
,#+begin_src sqlite :db /tmp/rip.db :readonly yes :exports both
create table rip(a,b);
,#+end_src
#+end_example
This results in an error such as:
#+begin_example
Runtime error near line 2: attempt to write a readonly database (8)
[ Babel evaluation exited with code 1 ]
#+end_example
** New and changed options
# Changes dealing with changing default values of customizations,
# adding new customizations, or changing the interpretation of the
# existing customizations.
*** New option ~org-edit-keep-region~
Since Org 9.7, structure editing commands do not deactivate region
after editing. Now, this is configurable via the new option.
*** =xelatex= can be used for LaTeX previews
A new process =xelatex= is added to ~org-preview-process-alist~ to
allow generating LaTeX fragment preview through =xdv= file produced by
XeLaTeX, which has better support for Unicode.
You can now set ~org-preview-latex-default-process~ to ~'xelatex~.
*** New link preview system
**** New option ~org-link-preview-batch-size~
Org link previews are generated asynchronously and a few at a time, in
batches. This option controls the number of links that are previewed
in each batch.
**** New option ~org-link-preview-delay~
Org link previews are generated asynchronously. This option controls
the minimum idle time in seconds between previews of batches of links.
*** New and changed export options
**** ~org-html-style-default~ now highlights =#+begin_src c= (lowercase) blocks
The default value has been changed, adding ~pre.src-c:before {
content: 'C'; }~ (lowercase =c=) that parallels ~pre.src-C:before {
content: 'C'; }~ (uppercase =C=).
**** ~org-odt-with-latex~ accepts any method from ~org-preview-latex-process-alist~
Previously, only a few conversion methods (~dvipng~, ~imagemagick~,
~dvisvgm~) could be used to render LaTeX fragments as images when
exporting to ODT. Now any method in ~org-preview-latex-process-alist~
can be used.
**** New environment =onlyenv= in ~org-beamer-environments-default~
The =onlyenv= environment limits showing parts of an animated Beamer
slide to specific animation steps.
#+begin_example
,***** Comment
:PROPERTIES:
:BEAMER_env: onlyenv
:BEAMER_act: <2->
:END:
This text will be displayed on animation step 2 and later.
#+end_example
**** =ox-html=: Headline self links can be enabled from an Org mode file
Previously HTML export could add, to each headline, a link to itself.
To enable it, you had to use the variable
~org-html-self-link-headlines~.
Now, it's also possible to enable it per Org mode file by adding:
: #+OPTIONS: html-self-link-headlines:t
**** Allow disabling macro replacement during export
New custom option ~org-export-replace-macros~ controls whether Org
mode replaces macros in the buffer before export. Set it to nil to
disable macro replacement.
This variable has no effect on the ={{{results...}}}= macros for inline
code block results.
**** New option ~org-cite-bibtex-bibliography-style~
This option adds a fallback bibliography style for BibTeX when none is
provided in the =#+CITE_EXPORT= options. The default style is
"plain".
**** New option ~org-cite-csl-bibtex-titles-to-sentence-case~
When this option is non-nil then title fields in BibTeX bibliography
entries are converted to sentence-case before being formatted
according to a CSL style, except for entries with a =langid= field
specifying a non-English language. When nil, this conversion is
limited to entries having a =langid= field specifying a variant of
English. The default value is ~t~ as the CSL standard assumes that
English titles are specified in sentence-case but the BibTeX
bibliography format requires them to be written in title-case.
**** New option ~org-latex-mathml-directory~
This option specifies the path where MathML files generated from LaTeX
fragments are stored.
**** New option ~org-latex-use-sans~
This option specifies the PDF should be typeset using the Sans font
specified in the document class (or the user) instead of the default
font (i.e. the Roman font).
**** New option ~#+LATEX_CLASS_PRE~
This option prepends LaTeX code before the LaTeX preamble.
**** New option ~org-odt-with-forbidden-chars~
The new export option controls how to deal with characters that are forbidden
inside ODT documents during export.
The ODT documents must follow XML1.0 specification and cannot contain
certain Unicode characters. For example, form feed characters like ^L
are disallowed.
By default, =ox-odt= will strip such characters and display warning.
You may return to the previous behavior by setting
~org-odt-with-forbidden-chars~ to t.
Note that Emacs warnings can always be suppressed by clicking on ⛔
symbol or by customizing ~warning-suppress-types~.
**** New option ~org-md-link-org-files-as-md~
This option makes it possible to disable mapping of linked org files
to markdown during export to Markdown. This is analogous to how
~org-html-link-org-files-as-html~ works in export to HTML.
*** New context available to save in archived headings
~org-archive-save-context-info~ can now contain ~olid~ symbol to save
parent heading ID in the archived heading.
*** New hook ~org-archive-finalize-hook~
Hook run after successfully archiving a subtree in final location.
Unlike ~org-archive-hook~, which runs in the source Org buffer, the
new hook is called with point on the subtree in the destination file.
*** Headline/olp target in ~org-capture-templates~ can be a function/variable
The variable ~org-capture-templates~ accepts a target specification as
function or symbol for headline (~file+headline~) and olp (~file+olp~
and ~file+olp+datetree~).
*** The default value of ~org-babel-latex-process-alist~ is no longer taken from ~org-preview-latex-process-alist~
The default value used to be pulled from =dvipng= process type from
~org-preview-latex-process-alist~. Now, it defaults to using
=latexmk= (when available), or running =latex= multiple times, so that
all the references are resolved in the generated PNG.
*** ~org-tags-sort-function~ can now be a list of functions
~org-tags-sort-function~ can now be set to a list of functions.
Subsequent sorting functions will be used if two tags are found to be
equivalent. See docstring for more information.
*** New tags sorting function ~org-tags-sort-hierarchy~
By setting ~org-tags-sort-function~ to ~org-tags-sort-hierarchy~, tags
are sorted taking their hierarchy into account. See
[[info:org#Tag Hierarchy][Tag Hierarchy]] for how to set up a tag
hierarchy.
*** New option ~org-cite-basic-complete-key-crm-separator~
This option makes ~org-cite~'s ~basic~ insert processor use
~completing-read-multiple~ instead of the default consecutive prompts.
It can also be set to dynamically compute ~crm-separator~ so that the
separator does not appear in completion candidates.
*** ~org-yank-image-save-method~ can be a function producing directory name
In previous versions, ~org-yank-image-save-method~ could be either a
symbol ~attach~ or a string -- directory name. Now it can also be a
function, which will be called with no arguments and its return value
will be used as a directory to save the image to.
*** ~org-refile-targets~ can now match all headlines in the target file(s)
Candidate refile targets may now be specified with the symbol ~t~ to
indicate that all headlines within the specified file are to be
considered. For example, setting ~org-refile-targets~ to ~((nil . t))~
will allow one to refile to any heading within the current buffer.
*** In =ob-ditaa=, the output type is now controlled consistently with other babel backends
Output file type is determined as specified in Babel documentation:
the suffix of =:file= is the primary determinant, and =:file-ext=
secondary. Header arguments =:pdf= and =:eps= are supported for
backwards compatibility. Default output type is still PNG.
** New functions and changes in function arguments
# This also includes changes in function behavior from Elisp perspective.
*** The deprecated =show= parameter to =org-priority= has been removed
The =show= parameter for the =org-priority= function was deprecated in
Org 9.2 (released in 2017). Sufficient time has passed, and it is being
removed as part of refactoring for numeric priorities.
*** ~org-attach-attach~ now returns a link to file stored
Previously, ~org-attach-attach~ did not have any specified default value.
Now, it returns a list =(LINK DESCRIPTION)= to the file stored.
The link obeys non-nil ~org-attach-store-link-p~ setting.
When ~org-attach-store-link-p~ is nil, an =attachment:= link is returned.
*** New functions exposing link formatting done by ~org-insert-link~
New function ~org-link-get-description~ exposes handling ~:insert-description~
link parameter and ~org-link-make-description-function~.
New function ~org-link-make-string-for-buffer~ exposes link and description
cleanups performed by ~org-insert-link~, including cleaning up =<...>= brackets,
stripping current buffer file path from the link, and adjusting =file:= links
according to ~org-link-file-path-type~.
*** ob-comint: New optional arguments controlling prompt handling
The new argument ~prompt-handling~ in ~org-babel-comint-with-output~
and ~org-babel-comint-async-register~ allows Babel languages to
specify how prompts should be handled in comint output. If equal to
~filter-prompts~, prompts are removed from output before it is passed
on to language-specific processing. If equal to
~disable-prompt-filtering~, then the prompt filtering is skipped. If
unset, then the default behavior is the same as ~filter-prompts~ for
backwards compatibility.
Prompt filtering is needed for some Babel languages, such as ob-shell,
which leave extra prompts in the output as a side effect of
evaluation. However, other Babel languages, like ob-python, don't
leave extra prompts after evaluation, and skipping the prompt
filtering can be more robust for such languages (as this avoids
removing false positive prompts).
*** Elisp functions for new datetree tree-types
Accompanying the [[#9.8-datetree-treetype][new datetree capture ~:tree-type~ options]], on the
elisp level ~org-datetree-find-create-entry~ and
~org-datetree-find-create-hierarchy~ generalize
~org-datetree-find-date-create~, ~org-datetree-find-month-create~, and
~org-datetree-find-iso-week-create~ to new datetree types.
*** New function ~org-src-get-lang-mode-if-bound~
The new function is like ~org-src-get-lang-mode~, except that it
ensures the returned major mode for the given language is bound, and
so available to the user. If the mode is not bound, the function can
optionally return a fallback mode and display a message when doing so.
The function was added so that Org can fall back to Fundamental mode
for source blocks where the appropriate major mode is unavailable.
*** New function ~org-gnus-no-new-news-other-frame~ (to be used in ~org-link-frame-setup~)
The new function is like ~org-gnus-no-new-news~, but always opens the
link in other frame.
*** New function ~org-string-width-invisibility-spec~
The new function constructs an invisibility spec without folds and
ellipses, suitable for ~org-string-width~. This can be helpful for
performance if ~org-string-width~ is called multiple times.
*** New command ~org-link-preview~ to preview Org links
This command replaces ~org-toggle-inline-images~, which is now
obsolete.
*** New command ~org-link-preview-region~ to preview Org links in a region or the buffer
This command replaces ~org-display-inline-images~, which is now
obsolete.
*** New command ~org-link-preview-clear~ to clear Org link previews in a region or the buffer
This command replaces ~org-remove-inline-images~, which is now
obsolete.
*** New command ~org-link-preview-refresh~ to refresh Org link previews in the buffer
This command replaces ~org-redisplay-inline-images~, which is now
obsolete.
*** ~org-html-head~ and ~org-html-head-extra~ can now be specified as functions
Previously, ~org-html-head~ and ~org-html-head-extra~ could only be
specified directly as strings. Now, they can be set to functions that
accept the INFO channel and return a string. This makes it possible
to dynamically generate the content of the resulting ~<head>~ tag in
the resulting HTML document.
*** ~org-element-create~ now ignores ~nil~s in CHILDREN argument
When CHILDREN contains ~nil~ elements, they are skipped. This way,
#+begin_src emacs-lisp
(let ((children nil))
(org-element-create 'section nil children)) ; => (section nil)
#+end_src
will yield expected results rather than assigning literal ~nil~ as a child.
*** ~org-clock-get-clock-string~ now takes an optional ~max-length~ argument
When a ~max-length~ is passed to ~org-clock-get-clock-string~, it will first
attempt to truncate the headline and add an ellipsis in order to make the entire
clock string fit under the length limit. If the length limit is too small to
accommodate even a single character of the headline, after accounting for spaces
and the surrounding parentheses, it will omit the headline entirely and just
show as much of the clock as fits under the limit.
*** ~org-string-width~ now takes an optional ~invisibility-spec~ argument
For performance, if the invisibility spec has been constructed, it can
be passed in as ~invisibility-spec~ instead of having it be
constructed again.
** Removed or renamed functions and variables
*** Obsolete functions and variables removed from ~org-datetree~
Due to the refactoring of ~org-datetree~ to support the [[#9.8-datetree-treetype][new datetree
capture ~:tree-type~ options]], the internal variable
~org-datetree-base-level~ has been removed, as well as the
undocumented helper function ~org-datetree-insert-line~.
*** Obsolete functions ~org-let~ and ~org-let2~ are removed
If any code is still using these ancient functions, it should move to ~cl-progv~.
*** ~org-show-empty-lines-in-parent~ is now obsolete
This function is unused in Org code and does not appear to be used in third-party code.
To be removed in future releases.
*** ~org-edit-src-content-indentation~ is renamed to ~org-src-content-indentation~
The new name highlights that the customization affects more than
editing. ~org-src-content-indentation~ also affects detangling,
printing Org syntax tree (for example, during export to Org), and
indentation of src and example blocks in Org buffers.
*** ~org-cycle-display-inline-images~ is renamed to ~org-cycle-display-link-previews~
Inline image previews in Org mode are now provided by the more general
link previews feature. The behavior with regard to image links is
unchanged.
*** ~org-cycle-inline-images-display~ is renamed to ~org-cycle-link-previews-display~
The behavior is unchanged, except in that the new variable now affects
previews of supported link types besides image links.
*** ~org-startup-with-inline-images~ is renamed to ~org-startup-with-link-previews~
The behavior is unchanged, except in that the new variable now affects
previews of supported link types besides image links.
*** =ob-ditaa=: =org-babel-ditaa-java-cmd= renamed and =org-ditaa-jar-option= made obsolete
To align with other customizable variable names, which do not contain
the word =babel=, variable =org-babel-ditaa-java-cmd= has been renamed
to =org-ditaa-java-exec=. The old variable =org-babel-ditaa-java-cmd=
is still available as an obsolete alias.
Variable =org-ditaa-jar-option= did not serve any sensible purpose and
has been made obsolete. Its value is still used in place of default
parameter -jar if the variable is defined.
** Miscellaneous
*** =ob-calc.el=: Vector and matrix are now inserted as Org tables by default
~ob-calc~ now formats vector and matrix results as Org tables. This
conversion can be overridden using the ~:results verbatim~ keyword on
a per source block basis.
To get back the old behavior, add
#+begin_example
(with-eval-after-load 'ob-calc
(setq org-babel-header-args:calc
(append '(:results . "verbatim") org-babel-header-args:calc)))
#+end_example
to your configuration.
The new behavior follows general babel backend rules (auto-detecting
result type), but may affect the existing usage.
*** ~orgtbl-to-generic~ retains special rows when exporting to Org
Previously, special table rows were unconditionally removed when
export to Org. Now, the defaults follow what ox-org does - to retain
special rows by default. See [[https://orgmode.org/worg/org-release-notes.html#ox-org-special-table-rows][previous change]].
To retain the old behavior, add ~:with-special-rows nil~ to PARAMS argument:
: (orgtbl-to-generic table '(:with-special-rows nil)
*** ~org-babel-lob-ingest~ no longer performs noweb expansion when ingesting blocks
Previously, ~org-babel-lob-ingest~ would expand noweb references when
adding source blocks to the Library of Babel. Now, blocks are stored
with unexpanded noweb references.
Noweb expansion is handled appropriately when blocks are actually used
via ~org-babel-execute-src-block~ or ~org-babel-exp-do-export~, with
the correct context (~:tangle~, ~:export~, or ~:eval~).
This change is unlikely to affect most users, but code that directly
accesses ~org-babel-library-of-babel~ may observe the difference.
*** Trailing =-= is now allowed in plain links
Previously, plain links like
: https://domain/test-
did not include the trailing =-= punctuation.
Now, the =-= is allowed at the end, and is considered a part of the plain link.
#+begin_quote
These types of links will likely be encountered for sites where anchor
targets are automatically generated from documentation headings which
are questions.
https://list.orgmode.org/orgmode/87sexh9ddv.fsf@ice9.digital/
#+end_quote
*** Update of statistics cookies now respects narrowing
Calling ~org-update-statistics-cookies~ with a prefix argument will
now only update cookies in the accessible portion of the buffer.
*** ox-man: Support specifying =#+DATE:= and ~org-export-with-date~
Previously, ox-man ignored =#+DATE:= keyword even when
~org-export-with-date~ is set to non-nil. Now, the date is exported
and specified in the =footer-middle= argument of =.TH= macro (see ~man
7 man~).
*** ox-man: Support specifying =:release= and =:header= in =#+MAN_CLASS_OPTIONS:= in addition to =:section-id=
The newly added =:release= and =:header= options of =#+MAN_CLASS_OPTIONS=
are respectively mapped to the =footer-inside= and =header-middle=
arguments of the =.TH= macro (see ~man 7 groff_man~).
*** ~org-capture~ target pointing to headline is now handled uniformly for =plain= entry type
Previously, when using ~file+regexp~, ~file+function~ or ~function~, =plain= entries
were inserted right at the point according to regexp/function, even when point is
on an existing headline.
Now, when target points to an existing headline, =plain= entries are
inserted inside its body, honoring ~:prepend~ property. This is more
consistent with how ~item~, ~checkitem~, and ~table-line~ templates
are handled.
*** ~org-lint~ now checks priorities
Warnings are raised on headlines containing out-of-bounds, invalid
(e.g., =[#-1]=, =[#AA]=), or malformed (e.g., =[#1=, =[#A=)
priorities.
*** In Dot code blocks, ~graphviz-dot-mode~ is used if available
Previously, when editing Dot code blocks with =M-x org-edit-special=,
Dot code would open in Fundamental mode, even when specialized mode is
installed. The new behavior is more DWIM.
*** Source blocks fall back to Fundamental mode
Org now falls back to Fundamental mode for source blocks when the
appropriate major mode is unavailable.
*** Priority speed commands adapt to user options
Previously, =1=, =2=, and =3= would insert priorities =A=, =B=, and
=C=, which causes errors when using numeric priorities. These now
insert ~org-priority-highest~, ~org-priority-default~, and
~org-priority-lowest~, respectively.
*** ~org-store-link~ no longer asks to select store function when called noninteractively
Previously, when multiple store functions are available to store link
at point, ~org-store-link~ would always ask user which store function
to use.
Now, when ~org-store-link~ is called noninteractively (~interactive?~
argument is nil), the first matching store function is used.
Interactively, the previous behavior is retained.
*** Org mode may throw an error when attempting to include remote unsafe resource noninteractively
Previously, when ~org-resource-download-policy~ is ~ask~ (default),
and Emacs is running in batch mode, Org mode simply skipped unsafe
remote resources in the =#+include:='s. Now, an error is thrown to
avoid seemingly ignored =#+include= statements when publishing via
batch scripts.
*** HTML export wraps ~<code>~ around all the exported src blocks
HTML export always uses ~<pre>~ tag around exported src blocks.
In addition, previously, HTML export used ~<code>~ tag around src
blocks when ~org-html-klipsify-src~ is non-nil.
Now, both ~<pre>~ and ~<code>~ tags are *always* wrapped around the
export src blocks.
*** ~yank-media~ and DND handlers now honor the user option ~org-file-link-type~
When inserting file: links, ~yank-media~ and DND handlers now respect
the user option ~org-file-link-type~.
*** ~org-timer-done-hook~ is now run before the timer is stopped
Previously, ~org-timer-countdown-timer~ and ~org-timer-start-time~
were unset when the hook is run. Now, they still hold the timer info.
*** ox-latex: LaTeX images are now stored alongside the exported =.html= file
Previously, LaTeX images (when HTML export does use images for LaTeX)
were stored alongside the original =.org= file. Now, they are stored
alongside the =.html= file.
This change will make links to LaTeX images point to the folder
containing =.html= file, not the =.org= file.
*** Org mode no longer prevents =flyspell= from spell-checking inside =LOGBOOK= drawers
Previously, spell-checking via =flyspell= was disabled inside
=LOGBOOK= (or ~org-log-into-drawer~) drawers. Now, it is no longer
the case. It can be useful to see spelling mistakes inside notes
added via ~org-add-note~ command.
*** ~ob-R~ and ~ob-julia~ no longer use ESS settings for working directory
Previously, without =:dir= parameter, R and Julia code blocks could
query for working directory during evaluation. This was because
~ess-ask-for-ess-directory~ setting was obeyed.
Now, ~ess-ask-for-ess-directory~, ~ess-directory-function~, and
~ess-directory~ are all ignored during code block evaluation (except
when session is already running). In other words, R and Julia code
blocks now conform to the "16.4 Environment of a Code Block" section
of Org mode manual that prescribes Org buffer directory or ~:dir~
value to be used as working dir to run the code blocks.
*** ~org-cancel-repeater~ now cancels all the repeaters inside entry
Previously, ~org-cancel-repeater~ only canceled repeater in the first
active timestamp inside heading. Now, all the repeaters are
canceled.
The function is renamed to ~org-cancel-repeaters~ accordingly (the old
name is still kept as an alias).
*** ~org-refile~ now saves current position to Org mark ring when jumping to heading
When ~org-refile~ is called with =C-u= or =C-u C-u= prefix argument
(to jump to heading or to jump to the last refiled heading), it saves
point to Org mark ring before jumping. Then, the user can return back
via ~org-mark-ring-goto~.
*** =org-attach= now considers symlinked files when searching pre-existing attach dirs
When Org buffer is opened from a symlink, Org mode looks into the
original file directory when searching if an attachment directory already exists.
This way, attachments will remain accessible when opening symlinked Org file.
When no attach dir exists, Org mode will still prefer creating it in
the "default" directory - where the symlink is located.
*** Texinfo exporter now supports links in headings
The Texinfo exporter no longer removes links from headings. This
applies to all headings, below and above the =H= and =toc= export
=#+OPTIONS:=.
*** Texinfo exporter now considers numeric =toc= values in =#+OPTIONS:=
For example, given =H:3= and =toc:2= in =#+OPTIONS:=, all headings at
the 1st and 2nd level appear in the table of contents and those at the
3rd level do not.
*** =ob-tangle= now tangles source blocks that do not specify a =language= if an inherited property sets a tangle filename
Previously, all source blocks that did not specify a =language= where
ignored by ~org-babel-tangle-collect-blocks~. Now, if it inherits a
:tangle header argument with a value other than =no= or =yes= (that is, a
filename), a source block without =language= will get tangled to that
file.
*** BibTeX is tangled with the standard =.bib= file extension
Previously, =bibtex= source blocks located in a file named =NAME.org=
were tangled into a file named =NAME.bibtex=. Now, they are tangled
into a file named =FILE.bib=, using the standard extension =.bib=,
matching the rest of the ecosystem, including BibTeX and LaTeX.
*** LaTeX export now respects ~org-latex-with...~ options in the PDF metadata
Previously, the LaTeX exporter handled the PDF metadata =pdfcreator=,
=pdfauthor= and =pdftitle= as defined in
~org-latex-hyperref-template~. This has changed, and these three fields
will be defined as empty and not produce any metadata if their
corresponding ~org-latex-with-author~, ~org-latex-with-title~, or
~org-latex-with-creator~ option is set to ~nil~.
*** Fancy HTML5 export uses ~<time>~ element for timestamps
Previously, timestamps would always be rendered inside a ~<span
class="timestamp">~. Now, if both ~org-html-doctype~ is ~html5~ and
~org-html-html5-fancy~ is enabled, org will use the semantic
~<time>~ element. This will also have the ~timestamp~ class, but
additionally set the ~datetime~ attribute with a machine-readable
variant of the timestamp. The format used for the attribute can be
customized using ~org-html-datetime-formats~.
*** Export dispatcher supports arrow keys and mouse wheel
Previously, the arrow keys and the mouse wheel were ignored in the
export dispatcher, ~org-export-dispatch~ bound to =C-c C-e=. Now,
they scroll the text in the export dispatcher window.
*** Add completion for ID links
Completion is enabled for ID links inserted with ~org-insert-link~.
Completion candidates, by default, will be sourced from all files
known to contain headlines with IDs. You can use new option
~org-id-completion-targets~ to change where the candidates are
searched.
*** Pre-populate the description for BBDB links
When inserting BBDB links, use the full name as the default link
description, instead of nothing.
* Version 9.7
** Important announcements and breaking changes
@ -285,6 +1202,9 @@ Images dropped also respect the value of ~org-yank-image-save-method~
when ~org-yank-dnd-method~ is =attach=.
*** Alignment of image previews can be customized
:PROPERTIES:
:CUSTOM_ID: preview-align
:END:
Previously, all the image previews were always left-aligned.
@ -1634,6 +2554,9 @@ Previously, all the header arguments where stripped from src blocks
during export. Now, header arguments are preserved.
*** =ox-org= now exports special table rows by default
:PROPERTIES:
:CUSTOM_ID: ox-org-special-table-rows
:END:
Previously, when exporting to Org, special table rows (for example,
width cookies) were not exported. Now, they are exported by default.
@ -4205,10 +5128,13 @@ wget -c "https://ben.akrin.com/crackzor/crackzor_1.0.c.gz"
#+end_example
*** Add ~:session~ support of ob-js for js-comint
#+begin_src js :session "*Javascript REPL*"
console.log("stardiviner")
#+end_src
# SIC, JavaScript miscapitalized in `js-comint.el'.
*** Add ~:session~ support of ob-js for Indium
#+begin_src js :session "*JS REPL*"
console.log("stardiviner")

View file

@ -3262,6 +3262,30 @@ To turn the Windows Magnifier off, click "Start->All Programs", or
"Accessibility" and click "Magnifier". In the Magnifier Settings
dialog that opens, click "Exit".
** Cursor is invisible, or appears at times and then disappears
This is known to happen if 'w32-use-visible-system-caret' is non-nil.
That variable is nil by default, but if your system has the "Speech
Recognition" feature enabled, Emacs automatically sets this variable
non-nil at startup to allow the screen reader to read the relevant part
of the Emacs display and dictate it.
To turn this off on modern Windows systems, go to "Settings ->
Accessibility -> Speech", and turn off "Voice access". If you need to
leave this accessibility feature turned on, you can alternatively set
'w32-use-visible-system-caret' to the nil value in your init file:
(setq w32-use-visible-system-caret nil)
If you do need to see the system caret in Emacs windows, you can instead
work around this problem by disabling double-buffering in your init
file:
(set-frame-parameter nil 'inhibit-double-buffering nil)
Note that inhibiting double-buffering might cause the Emacs display to
flicker in some cases.
** Problems with mouse-tracking and focus management
There are problems with display if mouse-tracking is enabled and the

View file

@ -331,6 +331,7 @@ boost/container/detail/flat_tree.hpp:589:25: [ skipping 5 instantiation contex
|
|board.h:60:21:
| 60 | #define I(b, C) ((C).y * (b)->width + (C).x)
src/add.cpp:8:31: error: invalid operands of types const double and const double* to binary operator+
* Guile backtrace, 2.0.11

View file

@ -404,9 +404,6 @@
<style:style style:name="OrgTags" style:family="text"/>
<style:style style:name="OrgPriority" style:family="text"/>
<style:style style:name="OrgPriority-A" style:family="text" style:parent-style-name="OrgPriority"/>
<style:style style:name="OrgPriority-B" style:family="text" style:parent-style-name="OrgPriority"/>
<style:style style:name="OrgPriority-C" style:family="text" style:parent-style-name="OrgPriority"/>
<style:style style:name="OrgTimestamp" style:display-name="OrgTimestamp" style:family="text">
<style:text-properties style:font-name="Courier New" fo:background-color="transparent" style:font-name-asian="NSimSun" style:font-name-complex="Courier New"/>

View file

@ -1,6 +1,6 @@
% Reference Card for Org Mode
\def\orgversionnumber{9.7.11}
\def\versionyear{2024} % latest update
\def\orgversionnumber{9.8.3}
\def\versionyear{2026} % latest update
\input emacsver.tex
%**start of header
@ -401,7 +401,7 @@ \section{Tables}
formula, \kbd{:=} a field formula.
\key{Example: Add Col1 and Col2}{|=\$1+\$2 |}
\key{... with printf format specification}{|=\$1+\$2;\%.2f|}
\key{... with printf-style format specification}{|=\$1+\$2;\%.2f|}
\key{... with constants from constants.el}{|=\$1/\$c/\$cm |}
\metax{sum from 2nd to 3rd hline}{|:=vsum(@II..@III)|}
\key{apply current column formula}{| = |}

View file

@ -40,7 +40,7 @@
\newlength{\ColThreeWidth}
\setlength{\ColThreeWidth}{25mm}
\newcommand{\versionemacs}[0]{31} % version of Emacs this is for
\newcommand{\versionemacs}[0]{32} % version of Emacs this is for
\newcommand{\cyear}[0]{2026} % copyright year
\newcommand\shortcopyrightnotice[0]{\vskip 1ex plus 2 fill

View file

@ -4564,7 +4564,7 @@ FG and BG are the main colors."
;; :underline (:style wave :color unspecified)
;;
;; I checked all the relevant faces and feel that users will not be
;; benefitting form such a style anyway. What would be the point of a
;; benefiting form such a style anyway. What would be the point of a
;; spell checker that cannot highlight its errors, for example?
;; Granted, we could have another kind of highlight, but I am here
;; focusing on the use of this:

View file

@ -19,7 +19,7 @@
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary
;;; Commentary:
;; This theme configures user options that we can reasonably expect the
;; average, new user to want to enable, but would otherwise be unlikely
@ -163,6 +163,8 @@ This minor mode will enable and disable the theme on startup."
;;;; Frame- and window-related options
'(frame-inhibit-implied-resize t)
'(tab-bar-history-mode t)
;; FIXME: If you toggle off the theme, without having run any
;; tab-related commands, the tab bar remains visible.
'(tab-bar-show 0)
;;;; Programming-related options

View file

@ -868,7 +868,7 @@ désactive : on dit que la commande « fait basculer le mode ».
Vous devez mettre des espaces entre eux car le mode Auto Fill ne
coupe les lignes que sur les espaces.
La marge est habituellement fixée à 70 caractères, mais pouvez
La marge est habituellement fixée à 70 caractères, mais vous pouvez
modifier cette valeur avec la commande C-x f. Vous devez fournir la
nouvelle valeur de la marge sous la forme d'un paramètre numérique.
@ -1133,9 +1133,9 @@ Voici d'autres options utiles de C-h :
>> Faites C-h a file<Entrée>.
Cela affiche dans une autre fenêtre une liste de toutes les commandes
M-x ayant « file » dans leurs noms. Vous verrez listée des commandes
caractères à côté des noms de commandes qui leur correspondent (comme
C-x C-f à côté de find-file).
M-x ayant « file » dans leurs noms. À côté des noms de commandes, vous
verrez les combinaisons de touches qui correspondent (comme C-x C-f à
côté de find-file).
>> Faites C-M-v pour faire défiler la fenêtre d'aide. Faites-le
plusieurs fois.

View file

@ -22,7 +22,7 @@ dnl You should have received a copy of the GNU General Public License
dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
AC_PREREQ([2.65])
AC_INIT([libexec], [31.0.50], [bug-gnu-emacs@gnu.org], [],
AC_INIT([libexec], [32.0.50], [bug-gnu-emacs@gnu.org], [],
[https://www.gnu.org/software/emacs/])
AH_TOP([/* Copyright (C) 2026 Free Software Foundation, Inc.

View file

@ -350,6 +350,6 @@ repositories require an incrementing numeric version code to detect
upgrades, which is provided here and is altered by admin/admin.el.
Refer to e.g. https://forum.f-droid.org/t/emacs-packaging/30424/25.
Version-code: 310050000
Version-code: 320050000
-->

View file

@ -811,22 +811,22 @@ sock_err_message (const char *function_name)
}
/* Send to S the data in *DATA when either
/* Send to S the DATA, of size DLEN, when either
- the data's last byte is '\n', or
- the buffer is full (but this shouldn't happen)
- the buffer is full.
Otherwise, just accumulate the data. */
static void
send_to_emacs (HSOCKET s, const char *data)
send_to_emacs_len (HSOCKET s, const char *data, ptrdiff_t dlen)
{
enum { SEND_BUFFER_SIZE = 4096 };
/* Buffer to accumulate data to send in TCP connections. */
static char send_buffer[SEND_BUFFER_SIZE + 1];
static char send_buffer[SEND_BUFFER_SIZE];
/* Fill pointer for the send buffer. */
static int sblen;
for (ptrdiff_t dlen = strlen (data); dlen != 0; )
while (dlen != 0)
{
int part = min (dlen, SEND_BUFFER_SIZE - sblen);
memcpy (&send_buffer[sblen], data, part);
@ -858,20 +858,27 @@ send_to_emacs (HSOCKET s, const char *data)
}
}
/* In STR, insert a & before each &, each space, each newline, and
any initial -. Change spaces to underscores, too, so that the
return value never contains a space.
Does not change the string. Outputs the result to S. */
/* Send to S the data in the string DATA. */
static void
quote_argument (HSOCKET s, const char *str)
send_to_emacs (HSOCKET s, const char *data)
{
char *copy = xmalloc (strlen (str) * 2 + 1);
send_to_emacs_len (s, data, strlen (data));
}
/* Output to S a quoted copy of the array of bytes STR with length LEN.
Insert a & before each &, each space, each newline, and
any initial -. Change spaces to underscores, too, so that the
output never contains a space. */
static void
quote_argument_len (HSOCKET s, const char *str, ptrdiff_t len)
{
char const *lim = str + len;
char *copy = xmalloc (len * 2);
char *q = copy;
if (*str == '-')
*q++ = '&', *q++ = *str++;
for (; *str; str++)
if (str < lim && *str == '-')
*q++ = '&';
for (; str < lim; str++)
{
char c = *str;
if (c == ' ')
@ -882,13 +889,21 @@ quote_argument (HSOCKET s, const char *str)
*q++ = '&';
*q++ = c;
}
*q = 0;
send_to_emacs (s, copy);
send_to_emacs_len (s, copy, q - copy);
free (copy);
}
/* Output to S a quoted copy of the string STR.
Insert a & before each &, each space, each newline, and
any initial -. Change spaces to underscores, too, so that the
output never contains a space. */
static void
quote_argument (HSOCKET s, const char *str)
{
return quote_argument_len (s, str, strlen (str));
}
/* The inverse of quote_argument. Remove quoting in string STR by
modifying the addressed string in place. Return STR. */
@ -990,8 +1005,6 @@ static bool
get_server_config (const char *config_file, struct sockaddr_in *server,
char *authentication)
{
char dotted[32];
char *port;
FILE *config;
if (IS_ABSOLUTE_FILE_NAME (config_file))
@ -1009,8 +1022,11 @@ get_server_config (const char *config_file, struct sockaddr_in *server,
if (! config)
return false;
if (fgets (dotted, sizeof dotted, config)
&& (port = strchr (dotted, ':')))
char *dotted = NULL;
size_t dottedsize;
ssize_t dottedlen = getline (&dotted, &dottedsize, config);
char *port = dottedlen < 0 ? NULL : strchr (dotted, ':');
if (port)
*port++ = '\0';
else
{
@ -1022,6 +1038,7 @@ get_server_config (const char *config_file, struct sockaddr_in *server,
server->sin_family = AF_INET;
server->sin_addr.s_addr = inet_addr (dotted);
server->sin_port = htons (atoi (port));
free (dotted);
if (! fread (authentication, AUTH_KEY_LENGTH, 1, config))
{
@ -1060,9 +1077,9 @@ set_tcp_socket (const char *local_server_file)
struct sockaddr sa;
} server;
struct linger l_arg = { .l_onoff = 1, .l_linger = 1 };
char auth_string[AUTH_KEY_LENGTH + 1];
char auth_buf[AUTH_KEY_LENGTH];
if (! get_server_config (local_server_file, &server.in, auth_string))
if (! get_server_config (local_server_file, &server.in, auth_buf))
return INVALID_SOCKET;
if (server.in.sin_addr.s_addr != inet_addr ("127.0.0.1") && !quiet)
@ -1096,10 +1113,8 @@ set_tcp_socket (const char *local_server_file)
sock_err_message ("setsockopt");
/* Send the authentication. */
auth_string[AUTH_KEY_LENGTH] = '\0';
send_to_emacs (s, "-auth ");
send_to_emacs (s, auth_string);
send_to_emacs_len (s, auth_buf, sizeof auth_buf);
send_to_emacs (s, " ");
return s;
@ -1960,7 +1975,7 @@ set_socket_timeout (HSOCKET socket, int seconds)
}
static bool
check_socket_timeout (int rl)
check_socket_timeout (ssize_t rl)
{
#ifndef WINDOWSNT
return (rl == -1)
@ -1979,9 +1994,11 @@ main (int argc, char **argv)
main_argv = argv;
progname = argv[0] ? argv[0] : "emacsclient";
int rl = 0;
ssize_t rl = 0;
bool skiplf = true;
char string[BUFSIZ + 1];
char *recv_buf = NULL;
ptrdiff_t recv_bufsize = 0;
int exit_status = EXIT_SUCCESS;
#ifdef HAVE_NTGUI
@ -2170,11 +2187,14 @@ main (int argc, char **argv)
else if (eval)
{
/* Read expressions interactively. */
while (fgets (string, BUFSIZ, stdin))
char *line = NULL;
size_t linesize;
for (ssize_t len; 0 <= (len = getline (&line, &linesize, stdin)); )
{
send_to_emacs (emacs_socket, "-eval ");
quote_argument (emacs_socket, string);
quote_argument_len (emacs_socket, line, len);
}
free (line);
send_to_emacs (emacs_socket, " ");
}
@ -2190,6 +2210,8 @@ main (int argc, char **argv)
set_socket_timeout (emacs_socket, timeout > 0 ? timeout : DEFAULT_TIMEOUT);
bool saw_response = false;
ptrdiff_t nrecv = 0;
/* Now, wait for an answer and print any messages. */
while (exit_status == EXIT_SUCCESS)
{
@ -2198,7 +2220,14 @@ main (int argc, char **argv)
do
{
act_on_signals (emacs_socket);
rl = recv (emacs_socket, string, BUFSIZ, 0);
if (nrecv == recv_bufsize)
{
enum { DEFAULT_RECV_BUFSIZE = 4096 };
recv_bufsize = (recv_bufsize + (recv_bufsize >> 1)
+ DEFAULT_RECV_BUFSIZE);
recv_buf = xrealloc (recv_buf, recv_bufsize);
}
rl = recv (emacs_socket, recv_buf + nrecv, recv_bufsize - nrecv, 0);
retry = check_socket_timeout (rl);
if (retry && !saw_response)
{
@ -2221,16 +2250,22 @@ main (int argc, char **argv)
if (rl <= 0)
break;
nrecv += rl;
saw_response = true;
string[rl] = '\0';
/* Loop over all NL-terminated messages. */
char *p = string;
for (char *end_p = p; end_p && *end_p != '\0'; p = end_p)
char *p = recv_buf;
for (char *end_p = p; end_p < recv_buf + nrecv; p = end_p)
{
end_p = strchr (p, '\n');
if (end_p != NULL)
*end_p++ = '\0';
/* An unquoted newline ends a server command. Keep reading,
possibly growing the buffer, until a buffer with a newline
is received. This handles commands with arbitrary-long
arguments (actually needed in 'print' and 'error' commands,
which are followed by strings). */
end_p = memchr (p, '\n', recv_buf + nrecv - p);
if (!end_p)
break;
*end_p++ = '\0';
if (strprefix ("-emacs-pid ", p))
{
@ -2253,11 +2288,13 @@ main (int argc, char **argv)
tty = true;
}
/* This discards any remaining data in recv_buf. */
goto retry;
}
else if (strprefix ("-print ", p))
{
/* -print STRING: Print STRING on the terminal. */
/* -print STRING: Print STRING, preceeded by a newline, on
the terminal. */
if (!suppress_output)
{
char *str = unquote_argument (p + strlen ("-print "));
@ -2268,8 +2305,10 @@ main (int argc, char **argv)
}
else if (strprefix ("-print-nonl ", p))
{
/* -print-nonl STRING: Print STRING on the terminal.
Used to continue a preceding -print command. */
/* -print-nonl STRING: Print STRING on the terminal
without a preceding newlin. Used to continue a
preceding -print command. Nowadays used only for
servers in Emacs versions before 31. */
if (!suppress_output)
{
char *str = unquote_argument (p + strlen ("-print-nonl "));
@ -2306,6 +2345,9 @@ main (int argc, char **argv)
skiplf = true;
}
}
nrecv -= p - recv_buf;
memmove (recv_buf, p, nrecv);
}
if (!skiplf && 0 <= process_grouping ())

View file

@ -2602,14 +2602,14 @@ point is moved into the passwords (see `authinfo-hide-elements').
(defvar read-passwd--mode-line-icon nil
"Propertized mode line icon for showing/hiding passwords.")
(defvar read-passwd--hide-password t
"Toggle whether password should be hidden in minibuffer.")
(defvar read-passwd--password-hidden nil
"Flag indicating whether password in minibuffer is hidden.")
(defun read-passwd--hide-password ()
"Make password in minibuffer hidden or visible."
(let ((beg (minibuffer-prompt-end)))
(dotimes (i (1+ (- (buffer-size) beg)))
(if read-passwd--hide-password
(if read-passwd--password-hidden
(put-text-property
(+ i beg) (+ 1 i beg) 'display (string (or read-hide-char ?*)))
(remove-list-of-text-properties (+ i beg) (+ 1 i beg) '(display)))
@ -2617,9 +2617,10 @@ point is moved into the passwords (see `authinfo-hide-elements').
(+ i beg) (+ 1 i beg)
'help-echo "C-u: Clear password\nTAB: Toggle password visibility"))))
(defun read-passwd-toggle-visibility ()
(defun read-passwd-toggle-visibility (&optional force)
"Toggle minibuffer contents visibility.
Adapt also mode line."
Adapt also mode line. If optional FORCE is non-nil, hide the minibuffer
contents."
(interactive)
(let ((win (active-minibuffer-window)))
(unless win (error "No active minibuffer"))
@ -2627,12 +2628,13 @@ Adapt also mode line."
;; mini-buffer.
(with-current-buffer (window-buffer win)
(when (memq 'read-passwd-mode local-minor-modes)
(setq read-passwd--hide-password (not read-passwd--hide-password))
(setq read-passwd--password-hidden
(or force (not read-passwd--password-hidden)))
(setq read-passwd--mode-line-icon
`(:propertize
,(if icon-preference
(icon-string
(if read-passwd--hide-password
(if read-passwd--password-hidden
'read-passwd--show-password-icon
'read-passwd--hide-password-icon))
"")
@ -2652,6 +2654,9 @@ Adapt also mode line."
"C-u" #'delete-minibuffer-contents ;bug#12570
"TAB" #'read-passwd-toggle-visibility)
(defvar read-passwd--mini-buffers nil
"List of minibuffers where `read-passwd' is active.")
(define-minor-mode read-passwd-mode
"Toggle visibility of password in minibuffer."
:group 'mode-line
@ -2659,21 +2664,25 @@ Adapt also mode line."
:keymap read-passwd-map
:version "30.1"
(setq read-passwd--hide-password nil)
(or global-mode-string (setq global-mode-string '("")))
(let ((mode-string '(:eval read-passwd--mode-line-icon)))
(if read-passwd-mode
;; Add `read-passwd--mode-line-icon'.
(or (member mode-string global-mode-string)
(setq global-mode-string
(append global-mode-string (list mode-string))))
;; Remove `read-passwd--mode-line-icon'.
(setq global-mode-string
(delete mode-string global-mode-string))))
(unless read-passwd-mode
(setq read-passwd--mini-buffers
(delq (current-buffer) read-passwd--mini-buffers)))
(unless read-passwd--mini-buffers
(let ((mode-string '(:eval read-passwd--mode-line-icon)))
(if read-passwd-mode
;; Add `read-passwd--mode-line-icon'.
(or (member mode-string global-mode-string)
(setq global-mode-string
(append global-mode-string (list mode-string))))
;; Remove `read-passwd--mode-line-icon'.
(setq global-mode-string
(delete mode-string global-mode-string)))))
(when read-passwd-mode
(read-passwd-toggle-visibility)))
(push (current-buffer) read-passwd--mini-buffers))
;; Always hide the current password.
(when read-passwd--mini-buffers
(with-current-buffer (car read-passwd--mini-buffers)
(read-passwd-toggle-visibility t))))
(defvar overriding-text-conversion-style)

View file

@ -314,31 +314,41 @@ function symbol (unquoted)."
(while (and cont args)
(if (cond ((and (eq :map (car args))
(not prefix-map))
(setq map (cadr args)))
(setq map (cadr args))
t)
((eq :prefix-docstring (car args))
(setq prefix-doc (cadr args)))
(setq prefix-doc (cadr args))
t)
((and (eq :prefix-map (car args))
(not (memq map '(global-map
override-global-map))))
(setq prefix-map (cadr args)))
(setq prefix-map (cadr args))
t)
((eq :repeat-docstring (car args))
(setq repeat-doc (cadr args)))
(setq repeat-doc (cadr args))
t)
((and (eq :repeat-map (car args))
(not (memq map '(global-map
override-global-map))))
(setq repeat-map (cadr args))
(setq map repeat-map))
(setq map repeat-map)
t)
((memq (car args) '(:continue :continue-only :exit))
(setq repeat-type (car args)
arg-change-func 'cdr))
arg-change-func 'cdr)
t)
((eq :prefix (car args))
(setq prefix (cadr args)))
(setq prefix (cadr args))
t)
((eq :filter (car args))
(setq filter (cadr args)) t)
(setq filter (cadr args))
t)
((eq :menu-name (car args))
(setq menu-name (cadr args)))
(setq menu-name (cadr args))
t)
((eq :package (car args))
(setq pkg (cadr args))))
(setq pkg (cadr args))
t))
(setq args (funcall arg-change-func args))
(setq cont nil))))

View file

@ -24,8 +24,12 @@
;;; Commentary:
;; This file is a replacement for icalendar.el that uses a new parser
;; and offers more features.
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file is a replacement for the diary import/export features
;; previously provided by icalendar.el. It uses a new parser and offers
;; more flexibility and features than the old implementation. It is
;; documented in the Emacs manual.
;;; Code:
@ -1120,7 +1124,7 @@ attendee's address matches the regexp in
(dlet ((attendee-address (ical:strip-mailto value))
(attendee-cn (when cn (string-trim cn)))
(attendee-cutype cutype)
(attende-role role)
(attendee-role role)
(attendee-partstat partstat)
(attendee-rsvp rsvp))
(with-temp-buffer

View file

@ -24,6 +24,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file defines the abstract syntax tree representation for
;; iCalendar data. The AST is based on `org-element-ast' (which see;
;; that feature will eventually be renamed and moved out of the Org tree
@ -64,7 +66,7 @@
;; Constructing nodes with these macros automatically validates them
;; with the function `icalendar-ast-node-valid-p', which signals an
;; `icalendar-validation-error' if the node is not valid acccording to
;; `icalendar-validation-error' if the node is not valid according to
;; RFC5545.
@ -293,8 +295,11 @@ PROPS should be a plist with any of the following keywords:
(defun ical:ast-node-children-of (type node)
"Return a list of all the children of NODE of type TYPE."
(seq-filter (lambda (c) (eq type (ical:ast-node-type c)))
(ical:ast-node-children node)))
(let (tchildren)
(dolist (c (ical:ast-node-children node))
(when (eq type (ical:ast-node-type c))
(push c tchildren)))
(nreverse tchildren)))
;; A high-level API for constructing iCalendar syntax nodes in Lisp code:
@ -634,7 +639,7 @@ the following forms:
or any other expression that evaluates to a parameter node.
\(COMPONENT-TYPE CHILD [CHILD ...]) - constructs a component node of
COMPONENT-TYPE with CHILDs as child nodes. Each CHILD should either be
COMPONENT-TYPE with given child nodes. Each CHILD should either be
a template for a property (as above), a template for a
sub-component (of the same form), or any other expression that
evaluates to an iCalendar syntax node.

View file

@ -24,10 +24,19 @@
;;; Commentary:
;; This file defines the macros `ical:define-type', `ical:define-param',
;; `ical:define-property' and `ical:define-component', used in
;; icalendar-parser.el to define the particular value types, parameters,
;; properties and components in the standard as type symbols.
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file defines the macros `icalendar-define-type',
;; `icalendar-define-param', `icalendar-define-property' and
;; `icalendar-define-component', used in icalendar-parser.el to define
;; the particular value types, parameters, properties and components in
;; the standard as type symbols. It also defines the following macros
;; for binding values in iCalendar syntax nodes:
;; `icalendar-with-component'
;; `icalendar-with-property'
;; `icalendar-with-property-of'
;; `icalendar-with-param'
;; `icalendar-with-param-of'
;; TODOs:
;; - in the define* macros, :default needs rethinking.

View file

@ -24,6 +24,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file defines regular expressions, constants and functions that
;; implement the iCalendar grammar according to RFC5545.
;;
@ -110,7 +112,7 @@ errors instead of silently accepting such data."
;; `ical:unfold-region'. `ical:fold-region' will fold content lines
;; using line breaks appropriate to the buffer's coding system.
;;
;; All the parsing-related code belows assumes that lines have
;; All the parsing-related code below assumes that lines have
;; already been unfolded if necessary.
(defcustom ical:pre-unfolding-hook nil
"Hook run before unfolding iCalendar data.
@ -4350,7 +4352,7 @@ during printing will be logged in the buffer returned by
;;; High-level parsing and printing functions.
(defun ical:parse (&optional buffer)
"Parse an `icalendar-vcalendar' object in BUFFER (default: current buffer).
"Parse an iCalendar VCALENDAR object in BUFFER (default: current buffer).
An unfolded copy of BUFFER (see `icalendar-unfolded-buffer-from-buffer')
will first be obtained if necessary. Parsing will begin at the first
@ -4359,9 +4361,9 @@ occurrence of \"BEGIN:VCALENDAR\" in the unfolded buffer.
The buffer may be tidied up by user functions before parsing begins; see
`icalendar-pre-unfolding-hook' and `icalendar-pre-parsing-hook'.
If parsing is successful, the VCALENDAR object is returned. Otherwise,
nil is returned, a warning is issued, and errors are logged in the
buffer returned by `icalendar-error-buffer'."
If parsing is successful, an `icalendar-vcalendar' object is returned.
Otherwise, nil is returned, a warning is issued, and errors are logged
in the buffer returned by `icalendar-error-buffer'."
(let* ((buf (or buffer (current-buffer)))
(unfolded (cond ((ical:unfolded-p buf) buf)
((buffer-file-name buf)

View file

@ -23,6 +23,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This is a sub-library for working with recurrence rules and time
;; zones, as defined by RFC5545 (see especially Secs. 3.3.10 and
;; 3.8.5.3, which are required reading before you make any changes to
@ -131,24 +133,38 @@
;; also in this case, recurrences are generated for one interval at a
;; time, because a BYSETPOS clause might apply.
;;
;; An interval is represented as a list (LOW HIGH NEXT-LOW) of decoded
;; times. The length of time between LOW and HIGH corresponds to the
;; FREQ rule part: they are one year apart for a 'YEARLY rule, a month
;; apart for a 'MONTHLY rule, etc. NEXT-LOW is the upper bound of the
;; interval: it is equal to LOW in the subsequent interval. When the
;; INTERVAL rule part is equal to 1 (the default), HIGH and NEXT-LOW are
;; the same, but if it is > 1, NEXT-LOW is equal to LOW + INTERVAL *
;; FREQ. For example, in a 'MONTHLY rule where INTERVAL=3, which means
;; "every three months", LOW and HIGH bound the first month, while HIGH
;; and NEXT-LOW bound the following two months.
;; An interval is represented as a vector like [LOW HIGH NEXT-LOW] of
;; decoded times. The length of time between LOW and HIGH corresponds
;; to the FREQ rule part: they are one year apart for a 'YEARLY rule, a
;; month apart for a 'MONTHLY rule, etc. NEXT-LOW is the upper bound of
;; the interval: it is equal to LOW in the subsequent interval. When
;; the INTERVAL rule part is equal to 1 (the default), HIGH and NEXT-LOW
;; are the same, but if it is > 1, NEXT-LOW is equal to LOW + INTERVAL *
;; FREQ. (For performance reasons, NEXT-LOW is therefore left out of
;; the vector when it is redundant.) For example, in a 'MONTHLY rule
;; where INTERVAL=3, which means "every three months", LOW and HIGH
;; bound the first month, while HIGH and NEXT-LOW bound the following
;; two months.
;;
;; The times between LOW and HIGH are candidates for recurrences. LOW
;; is an inclusive lower bound, and HIGH is an exclusive upper bound:
;; LOW <= R < HIGH for each recurrence R in the interval. The times
;; between HIGH and NEXT-LOW are not candidates for recurrences.
;;
(defun icr:make-interval (low high &optional next-low)
(if next-low
(vector low high next-low)
(vector low high)))
(defsubst icr:interval-low (interval)
(aref interval 0))
(defsubst icr:interval-high (interval)
(aref interval 1))
(defsubst icr:interval-next (interval)
(aref interval (1- (length interval)))) ; = NEXT-LOW if present, HIGH otherwise
;; The following functions deal with constructing intervals, given a
;; target, a start date/time, and intervalsize, and optionally a time
;; target, a start date/time, an intervalsize, and optionally a time
;; zone. The main entry point is `icalendar-recur-find-interval'.
;; Look, dragons already:
@ -252,7 +268,8 @@ returned interval looks like (LOW LOW+FREQS LOW+INTERVALSIZE). See
(let ((offset (decoded-time-zone target-w/zone)))
(setq low (icr:tz-decode-time low-abs offset)
high (icr:tz-decode-time (+ low-abs freqs) offset)
next-low (icr:tz-decode-time (+ low-abs intervalsize) offset))))
next-low (when (< 1 intervalsize)
(icr:tz-decode-time (+ low-abs intervalsize) offset)))))
(unless (and given-start-zone given-target-zone)
;; but if we started with floating times, we should return floating times:
@ -260,10 +277,11 @@ returned interval looks like (LOW LOW+FREQS LOW+INTERVALSIZE). See
(setf (decoded-time-dst low) -1)
(setf (decoded-time-zone high) nil)
(setf (decoded-time-dst high) -1)
(setf (decoded-time-zone next-low) nil)
(setf (decoded-time-dst next-low) -1))
(when next-low
(setf (decoded-time-zone next-low) nil)
(setf (decoded-time-dst next-low) -1)))
(list low high next-low)))
(icr:make-interval low high next-low)))
(defun icr:find-secondly-interval (target dtstart intervalsize &optional vtimezone)
"Find a SECONDLY recurrence interval.
@ -317,16 +335,18 @@ See `icalendar-recur-find-interval' for arguments' meanings."
(calendar-gregorian-from-absolute low-absdate)))
(high-dt (ical:date-to-date-time
(calendar-gregorian-from-absolute high-absdate)))
(next-low-dt (ical:date-to-date-time
(calendar-gregorian-from-absolute next-low-absdate))))
(next-low-dt (unless (= high-absdate next-low-absdate)
(ical:date-to-date-time
(calendar-gregorian-from-absolute next-low-absdate)))))
(when vtimezone
(icr:tz-set-zone low-dt vtimezone)
(icr:tz-set-zone high-dt vtimezone)
(icr:tz-set-zone next-low-dt vtimezone))
(when next-low-dt
(icr:tz-set-zone next-low-dt vtimezone)))
;; Return the bounds:
(list low-dt high-dt next-low-dt))))
(icr:make-interval low-dt high-dt next-low-dt))))
(defun icr:find-weekly-interval (target dtstart intervalsize
&optional weekstart vtimezone)
@ -358,16 +378,19 @@ See `icalendar-recur-find-interval' for arguments' meanings."
(calendar-gregorian-from-absolute low-abs)))
(high (ical:date-to-date-time
(calendar-gregorian-from-absolute (+ 7 low-abs))))
(next-low (ical:date-to-date-time
(calendar-gregorian-from-absolute (+ intsize-days low-abs)))))
(next-low
(when (< 1 intervalsize)
(ical:date-to-date-time
(calendar-gregorian-from-absolute (+ intsize-days low-abs))))))
(when vtimezone
(icr:tz-set-zone low vtimezone)
(icr:tz-set-zone high vtimezone)
(icr:tz-set-zone next-low vtimezone))
(when next-low
(icr:tz-set-zone next-low vtimezone)))
;; Return the bounds:
(list low high next-low)))
(icr:make-interval low high next-low)))
(defun icr:find-monthly-interval (target dtstart intervalsize &optional vtimezone)
"Find a MONTHLY recurrence interval.
@ -399,10 +422,12 @@ See `icalendar-recur-find-interval' for arguments' meanings."
(low (ical:make-date-time :year low-year :month low-month :day 1
:hour 0 :minute 0 :second 0 :tz vtimezone))
(high (ical:date/time-add low :month 1 vtimezone))
(next-low (ical:date/time-add low :month intervalsize vtimezone)))
(next-low
(when (< 1 intervalsize)
(ical:date/time-add low :month intervalsize vtimezone))))
;; Return the bounds:
(list low high next-low)))
(icr:make-interval low high next-low)))
(defun icr:find-yearly-interval (target dtstart intervalsize &optional vtimezone)
"Find a YEARLY recurrence interval.
@ -417,12 +442,14 @@ See `icalendar-recur-find-interval' for arguments' meanings."
:hour 0 :minute 0 :second 0 :tz vtimezone))
(high (ical:make-date-time :year (1+ low-year) :month 1 :day 1
:hour 0 :minute 0 :second 0 :tz vtimezone))
(next-low (ical:make-date-time :year (+ low-year intervalsize)
:month 1 :day 1 :hour 0 :minute 0 :second 0
:tz vtimezone)))
(next-low
(when (< 1 intervalsize)
(ical:make-date-time :year (+ low-year intervalsize)
:month 1 :day 1 :hour 0 :minute 0 :second 0
:tz vtimezone))))
;; Return the bounds:
(list low high next-low)))
(icr:make-interval low high next-low)))
(defun icr:find-interval (target dtstart recur-value &optional vtimezone)
"Return the recurrence interval around TARGET.
@ -430,7 +457,7 @@ See `icalendar-recur-find-interval' for arguments' meanings."
TARGET and DTSTART should be `icalendar-date' or `icalendar-date-time'
values. RECUR-VALUE should be an `icalendar-recur'.
The returned value is a list (LOW HIGH NEXT-LOW) which
The returned value is an interval [LOW HIGH NEXT-LOW] which
represents the lower and upper bounds of a recurrence interval around
TARGET. For some N, LOW is equal to START + N*INTERVALSIZE units, HIGH
is equal to START + (N+1)*INTERVALSIZE units, and LOW <= TARGET < HIGH.
@ -460,7 +487,7 @@ information and represent floating local times."
(defun icr:nth-interval (n dtstart recur-value &optional vtimezone)
"Return the Nth recurrence interval after DTSTART.
The returned value is a list (LOW HIGH NEXT-LOW) which represent the Nth
The returned value is an interval [LOW HIGH NEXT-LOW] which is the Nth
recurrence interval after DTSTART. LOW is equal to START +
N*INTERVALSIZE units, HIGH is equal to START + (N+1)*INTERVALSIZE units,
and LOW <= TARGET < HIGH. START here is a time derived from DTSTART
@ -498,10 +525,10 @@ information and represent floating local times."
(defun icr:next-interval (interval recur-value &optional vtimezone)
"Return the next recurrence interval after INTERVAL.
Given a recurrence interval (LOW HIGH NEXT), returns the next interval
\(NEXT HIGHER HIGHER-NEXT), where HIGHER and HIGHER-NEXT are determined
Given a recurrence interval [LOW HIGH NEXT], returns the next interval
[NEXT HIGHER HIGHER-NEXT], where HIGHER and HIGHER-NEXT are determined
by the frequency and interval sizes of RECUR-VALUE."
(let* ((new-low (caddr interval))
(let* ((new-low (icr:interval-next interval))
(freq (ical:recur-freq recur-value))
(unit (cl-case freq
(YEARLY :year)
@ -513,7 +540,9 @@ by the frequency and interval sizes of RECUR-VALUE."
(SECONDLY :second)))
(intervalsize (ical:recur-interval-size recur-value))
(new-high (ical:date/time-add new-low unit 1 vtimezone))
(new-next (ical:date/time-add new-low unit intervalsize vtimezone)))
(new-next
(when (< 1 intervalsize)
(ical:date/time-add new-low unit intervalsize vtimezone))))
(when vtimezone
(icr:tz-set-zone new-low vtimezone)
@ -521,18 +550,18 @@ by the frequency and interval sizes of RECUR-VALUE."
;; (icr:tz-set-zone new-next vtimezone)
)
(list new-low new-high new-next)))
(icr:make-interval new-low new-high new-next)))
(defun icr:previous-interval (interval recur-value dtstart &optional vtimezone)
"Given a recurrence INTERVAL, return the previous interval.
For an interval (LOW HIGH NEXT-LOW), the previous interval is
\(PREV-LOW PREV-HIGH LOW), where PREV-LOW and PREV-HIGH are determined by
For an interval [LOW HIGH NEXT-LOW], the previous interval is
[PREV-LOW PREV-HIGH LOW], where PREV-LOW and PREV-HIGH are determined by
the frequency and interval sizes of RECUR-VALUE (see
`icalendar-recur-find-interval'). If the resulting period of time
between PREV-LOW and PREV-HIGH occurs entirely before DTSTART, then the
interval does not exist; in this case nil is returned."
(let* ((upper (car interval))
(let* ((upper (icr:interval-low interval))
(freq (ical:recur-freq recur-value))
(unit (cl-case freq
(YEARLY :year)
@ -544,7 +573,13 @@ interval does not exist; in this case nil is returned."
(SECONDLY :second)))
(intervalsize (ical:recur-interval-size recur-value))
(new-low (ical:date/time-add upper unit (* -1 intervalsize) vtimezone))
(new-high (ical:date/time-add new-low unit 1 vtimezone)))
(new-high
(if (< 1 intervalsize)
(ical:date/time-add new-low unit 1 vtimezone)
upper))
(new-upper
(when (< 1 intervalsize)
upper)))
(when vtimezone
;; (icr:tz-set-zone new-low vtimezone)
@ -552,7 +587,7 @@ interval does not exist; in this case nil is returned."
(icr:tz-set-zone upper vtimezone))
(unless (ical:date-time< new-high dtstart)
(list new-low new-high upper))))
(icr:make-interval new-low new-high new-upper))))
@ -617,21 +652,18 @@ interval does not exist; in this case nil is returned."
YEARDAYS should be a list of values from a recurrence rule's
BYYEARDAY=... clause; see `icalendar-recur' for the possible values."
(let* ((sorted-ydays (sort yeardays
:lessp (lambda (a b)
(let ((pos-a (if (< 0 a) a (+ 366 a)))
(pos-b (if (< 0 b) b (+ 366 b))))
(< pos-a pos-b)))))
(interval-start (car interval))
(start-year (decoded-time-year interval-start))
(interval-end (cadr interval))
:key (lambda (a) (if (< 0 a) a (+ 366 a)))))
(interval-start (icr:interval-low interval))
(curr-year (decoded-time-year interval-start))
(interval-end (icr:interval-high interval))
(end-year (decoded-time-year interval-end))
(subintervals nil))
(while (<= start-year end-year)
(while curr-year
;; For each year in the interval...
(dolist (n sorted-ydays)
;; ...the subinterval is one day long on the nth yearday
(let* ((nthday (calendar-date-from-day-of-year start-year n))
(low (ical:make-date-time :year start-year
(let* ((nthday (calendar-date-from-day-of-year curr-year n))
(low (ical:make-date-time :year curr-year
:month (calendar-extract-month nthday)
:day (calendar-extract-day nthday)
:hour 0 :minute 0 :second 0
@ -648,9 +680,11 @@ BYYEARDAY=... clause; see `icalendar-recur' for the possible values."
(when (and (ical:date-time<= interval-start low)
(ical:date-time< low high)
(ical:date-time<= high interval-end))
(push (list low high) subintervals))))
(setq start-year (1+ start-year)))
(push (icr:make-interval low high) subintervals))))
(setq curr-year (1+ curr-year))
(when (<= end-year curr-year)
;; we're done:
(setq curr-year nil)))
(nreverse subintervals)))
(defun icr:refine-byweekno (interval weeknos &optional weekstart vtimezone)
@ -660,20 +694,17 @@ WEEKNOS should be a list of values from a recurrence rule's
BYWEEKNO=... clause, and WEEKSTART should be the value of its
WKST=... clause (if any). See `icalendar-recur' for the possible values."
(let* ((sorted-weeknos (sort weeknos
:lessp (lambda (a b)
(let ((pos-a (if (< 0 a) a (+ 53 a)))
(pos-b (if (< 0 b) b (+ 53 b))))
(< pos-a pos-b)))))
(interval-start (car interval))
(start-year (decoded-time-year interval-start))
(interval-end (cadr interval))
:key (lambda (a) (if (< 0 a) a (+ 53 a)))))
(interval-start (icr:interval-low interval))
(curr-year (decoded-time-year interval-start))
(interval-end (icr:interval-high interval))
(end-year (decoded-time-year interval-end))
(subintervals nil))
(while (<= start-year end-year)
(while curr-year
;; For each year in the interval...
(dolist (wn sorted-weeknos)
;; ...the subinterval is one week long in the wn-th week
(let* ((nth-wstart (ical:start-of-weekno wn start-year weekstart))
(let* ((nth-wstart (ical:start-of-weekno wn curr-year weekstart))
(low (ical:make-date-time :year (calendar-extract-year nth-wstart)
:month (calendar-extract-month nth-wstart)
:day (calendar-extract-day nth-wstart)
@ -690,8 +721,11 @@ WKST=... clause (if any). See `icalendar-recur' for the possible values."
(when (and (ical:date-time<= interval-start low)
(ical:date-time< low high)
(ical:date-time<= high interval-end))
(push (list low high) subintervals))))
(setq start-year (1+ start-year)))
(push (icr:make-interval low high) subintervals))))
(setq curr-year (1+ curr-year))
(when (<= end-year curr-year)
;; we're done:
(setq curr-year nil)))
(nreverse subintervals)))
(defun icr:refine-bymonth (interval months &optional vtimezone)
@ -700,17 +734,17 @@ WKST=... clause (if any). See `icalendar-recur' for the possible values."
MONTHS should be a list of values from a recurrence rule's
BYMONTH=... clause; see `icalendar-recur' for the possible values."
(let* ((sorted-months (sort months))
(interval-start (car interval))
(start-year (decoded-time-year interval-start))
(interval-end (cadr interval))
(interval-start (icr:interval-low interval))
(curr-year (decoded-time-year interval-start))
(interval-end (icr:interval-high interval))
(end-year (decoded-time-year interval-end))
(subintervals nil))
(while (<= start-year end-year)
(while curr-year
;; For each year in the interval...
(dolist (m sorted-months)
;; ...the subinterval is from the first day of the given month
;; to the first day of the next
(let* ((low (ical:make-date-time :year start-year :month m :day 1
(let* ((low (ical:make-date-time :year curr-year :month m :day 1
:hour 0 :minute 0 :second 0
:tz vtimezone))
(high (ical:date/time-add low :month 1 vtimezone)))
@ -723,9 +757,11 @@ BYMONTH=... clause; see `icalendar-recur' for the possible values."
(when (and (ical:date/time<= interval-start low)
(ical:date/time< low high)
(ical:date/time<= high interval-end))
(push (list low high) subintervals))))
(setq start-year (1+ start-year)))
(push (icr:make-interval low high) subintervals))))
(setq curr-year (1+ curr-year))
(when (<= end-year curr-year)
; we're done:
(setq curr-year nil)))
(nreverse subintervals)))
(defun icr:refine-bymonthday (interval monthdays &optional vtimezone)
@ -734,22 +770,20 @@ BYMONTH=... clause; see `icalendar-recur' for the possible values."
MONTHDAYS should be a list of values from a recurrence rule's
BYMONTHDAY=... clause; see `icalendar-recur' for the possible values."
(let* ((sorted-mdays (sort monthdays
:lessp (lambda (a b)
(let ((pos-a (if (< 0 a) a (+ 31 a)))
(pos-b (if (< 0 b) b (+ 31 b))))
(< pos-a pos-b)))))
(interval-start (car interval))
(interval-end (cadr interval))
:key (lambda (a) (if (< 0 a) a (+ 31 a)))))
(interval-start (icr:interval-low interval))
(curr-dt interval-start)
(interval-end (icr:interval-high interval))
(subintervals nil))
(while (ical:date-time<= interval-start interval-end)
(while curr-dt
;; For each month in the interval...
(dolist (m sorted-mdays)
;; ...the subinterval is one day long on the given monthday
(let* ((month (ical:date/time-month interval-start))
(year (ical:date/time-year interval-start))
(let* ((month (ical:date/time-month curr-dt))
(year (ical:date/time-year curr-dt))
(monthday (if (< 0 m) m
(+ m 1 (calendar-last-day-of-month month year))))
(low (ical:date-time-variant interval-start :day monthday
(low (ical:date-time-variant curr-dt :day monthday
:hour 0 :minute 0 :second 0
:tz vtimezone))
(high (ical:date/time-add low :day 1 vtimezone)))
@ -763,9 +797,11 @@ BYMONTHDAY=... clause; see `icalendar-recur' for the possible values."
(when (and (ical:date/time<= interval-start low)
(ical:date/time< low high)
(ical:date/time<= high interval-end))
(push (list low high) subintervals)))))
(setq interval-start
(ical:date/time-add interval-start :month 1 vtimezone)))
(push (icr:make-interval low high) subintervals)))))
(setq curr-dt (ical:date/time-add curr-dt :month 1 vtimezone))
(when (ical:date-time<= interval-end curr-dt)
;; we're done:
(setq curr-dt nil)))
(nreverse subintervals)))
(defun icr:refine-byday (interval weekdays &optional in-month vtimezone)
@ -779,11 +815,11 @@ whether OFFSET is relative to the month of the start of the interval. If
it is nil, OFFSET will be relative to the year, rather than the month."
(let* ((sorted-weekdays (sort (seq-filter #'natnump weekdays)))
(with-offsets (sort (seq-filter #'consp weekdays)
:lessp (lambda (w1 w2) (and (< (car w1) (car w2))))))
(interval-start (car interval))
(start-abs (calendar-absolute-from-gregorian
(ical:date-time-to-date interval-start)))
(interval-end (cadr interval))
:key #'car))
(interval-start (icr:interval-low interval))
(curr-abs (calendar-absolute-from-gregorian
(ical:date-time-to-date interval-start)))
(interval-end (icr:interval-high interval))
(end-abs (calendar-absolute-from-gregorian
(ical:date-time-to-date interval-end)))
(subintervals nil))
@ -810,15 +846,15 @@ it is nil, OFFSET will be relative to the year, rather than the month."
(when (and (ical:date/time<= interval-start low)
(ical:date/time<= high interval-end)
(ical:date/time< low high))
(push (list low high) subintervals))))
(push (icr:make-interval low high) subintervals))))
;; When no offset was given, for each day in the interval...
(while (and (<= start-abs end-abs)
sorted-weekdays)
(while (and curr-abs sorted-weekdays)
;; ...the subinterval is one day long on matching weekdays.
(let* ((gdate (calendar-gregorian-from-absolute start-abs)))
(when (memq (calendar-day-of-week gdate) sorted-weekdays)
(let* ((low (ical:date-to-date-time gdate))
(when (memq (mod curr-abs 7) ; = weekday of absolute date;
sorted-weekdays) ; see `calendar-day-of-week'
(let* ((gdate (calendar-gregorian-from-absolute curr-abs))
(low (ical:date-to-date-time gdate))
(high (ical:date/time-add low :day 1 vtimezone)))
(when (ical:date/time< low interval-start)
(setq low interval-start))
@ -830,13 +866,16 @@ it is nil, OFFSET will be relative to the year, rather than the month."
(when (and (ical:date/time<= interval-start low)
(ical:date/time<= high interval-end)
(ical:date/time< low high))
(push (list low high) subintervals)))))
(setq start-abs (1+ start-abs)))
(push (icr:make-interval low high) subintervals))))
(setq curr-abs (1+ curr-abs))
(when (<= end-abs curr-abs)
;; we're done:
(setq curr-abs nil)))
;; Finally, sort and return all subintervals:
(sort subintervals
:lessp (lambda (int1 int2)
(ical:date-time< (car int1) (car int2)))
:key #'icr:interval-low
:lessp #'ical:date-time<
:in-place t)))
(defun icr:refine-byhour (interval hours &optional vtimezone)
@ -845,27 +884,31 @@ it is nil, OFFSET will be relative to the year, rather than the month."
HOURS should be a list of values from a recurrence rule's
BYHOUR=... clause; see `icalendar-recur' for the possible values."
(let* ((sorted-hours (sort hours))
(interval-start (car interval))
(interval-end (cadr interval))
(interval-start (icr:interval-low interval))
(interval-end (icr:interval-high interval))
(curr-dt interval-start)
(subintervals nil))
(while (ical:date-time<= interval-start interval-end)
(while curr-dt
;; For each day in the interval...
(dolist (h sorted-hours)
;; ...the subinterval is one hour long in the given hour
(let* ((low (ical:date-time-variant interval-start
(let* ((low (ical:date-time-variant curr-dt
:hour h :minute 0 :second 0
:tz vtimezone))
(high (ical:date/time-add low :hour 1 vtimezone)))
(ignore-errors ; do not generate subintervals for nonexisting times
(when (ical:date/time< low interval-start)
(setq low interval-start))
(ignore-errors ; do not generate subintervals for nonexistent times
(when (ical:date/time< low curr-dt)
(setq low curr-dt))
(when (ical:date/time< interval-end high)
(setq high interval-end))
(when (and (ical:date/time<= interval-start low)
(ical:date/time< low high)
(ical:date/time<= high interval-end))
(push (list low high) subintervals)))))
(setq interval-start (ical:date/time-add interval-start :day 1 vtimezone)))
(push (icr:make-interval low high) subintervals)))))
(setq curr-dt (ical:date/time-add curr-dt :day 1 vtimezone))
(when (ical:date-time<= interval-end curr-dt)
;; we're done:
(setq curr-dt nil)))
(nreverse subintervals)))
(defun icr:refine-byminute (interval minutes &optional vtimezone)
@ -874,33 +917,37 @@ BYHOUR=... clause; see `icalendar-recur' for the possible values."
MINUTES should be a list of values from a recurrence rule's
BYMINUTE=... clause; see `icalendar-recur' for the possible values."
(let* ((sorted-minutes (sort minutes))
(interval-start (car interval))
(interval-end (cadr interval))
(interval-start (icr:interval-low interval))
(interval-end (icr:interval-high interval))
;; we use absolute times (in seconds) for the loop variables in
;; case the interval crosses the boundary between two observances:
(low-ts (time-convert (encode-time interval-start) 'integer))
(curr-dt interval-start)
(curr-ts (time-convert (encode-time curr-dt) 'integer))
(end-ts (time-convert (encode-time interval-end) 'integer))
(subintervals nil))
(while (<= low-ts end-ts)
(while curr-ts
;; For each hour in the interval...
(dolist (m sorted-minutes)
;; ...the subinterval is one minute long in the given minute
(let* ((low (ical:date-time-variant interval-start :minute m :second 0
(let* ((low (ical:date-time-variant curr-dt :minute m :second 0
:tz vtimezone))
(high (ical:date/time-add low :minute 1 vtimezone)))
(ignore-errors ; do not generate subintervals for nonexisting times
(ignore-errors ; do not generate subintervals for nonexistent times
;; Clip the subinterval, as above
(when (ical:date/time< low interval-start)
(setq low interval-start))
(setq low curr-dt))
(when (ical:date/time< interval-end high)
(setq high interval-end))
(when (and (ical:date/time<= interval-start low)
(ical:date/time< low high)
(ical:date/time<= high interval-end))
(push (list low high) subintervals)))))
(setq low-ts (+ low-ts (* 60 60))
interval-start (if vtimezone (icr:tz-decode-time low-ts vtimezone)
(ical:date/time-add interval-start :hour 1))))
(push (icr:make-interval low high) subintervals)))))
(setq curr-ts (+ curr-ts (* 60 60))
curr-dt (if vtimezone (icr:tz-decode-time curr-ts vtimezone)
(ical:date/time-add curr-dt :hour 1)))
(when (<= end-ts curr-ts)
;; we're done:
(setq curr-ts nil)))
(nreverse subintervals)))
(defun icr:refine-bysecond (interval seconds &optional vtimezone)
@ -909,32 +956,36 @@ BYMINUTE=... clause; see `icalendar-recur' for the possible values."
SECONDS should be a list of values from a recurrence rule's
BYSECOND=... clause; see `icalendar-recur' for the possible values."
(let* ((sorted-seconds (sort seconds))
(interval-start (car interval))
(interval-end (cadr interval))
(interval-start (icr:interval-low interval))
(interval-end (icr:interval-high interval))
;; we use absolute times (in seconds) for the loop variables in
;; case the interval crosses the boundary between two observances:
(low-ts (time-convert (encode-time interval-start) 'integer))
(curr-dt interval-start)
(curr-ts (time-convert (encode-time curr-dt) 'integer))
(end-ts (time-convert (encode-time interval-end) 'integer))
(subintervals nil))
(while (<= low-ts end-ts)
(while curr-ts
;; For each minute in the interval...
(dolist (s sorted-seconds)
;; ...the subinterval is one second long: the given second
(let* ((low (ical:date-time-variant interval-start :second s
(let* ((low (ical:date-time-variant curr-dt :second s
:tz vtimezone))
(high (ical:date/time-add low :second 1 vtimezone)))
(when (ical:date/time< low interval-start)
(setq low interval-start))
(setq low curr-dt))
(when (ical:date/time< interval-end high)
(setq high interval-end))
(when (and (ical:date/time<= interval-start low)
(ical:date/time< low high)
(ical:date/time<= high interval-end))
(push (list low high) subintervals))))
(setq low-ts (+ low-ts 60)
interval-start (if vtimezone
(icr:tz-decode-time low-ts vtimezone)
(ical:date/time-add interval-start :minute 1))))
(push (icr:make-interval low high) subintervals))))
(setq curr-ts (+ curr-ts 60)
curr-dt (if vtimezone
(icr:tz-decode-time curr-ts vtimezone)
(ical:date/time-add curr-dt :minute 1)))
(when (<= end-ts curr-ts)
;; we're done:
(setq curr-ts nil)))
(nreverse subintervals)))
;; TODO: should this just become a generic function, with the above
@ -952,8 +1003,8 @@ BYSECOND=... clause; see `icalendar-recur' for the possible values."
(BYMINUTE (icr:refine-byminute interval values vtimezone))
(BYSECOND (icr:refine-bysecond interval values vtimezone))))
(defun icr:make-bysetpos-filter (setpos)
"Return a filter on values for the indices in SETPOS.
(defun icr:bysetpos-filter (setpos recurrences)
"Filter RECURRENCES on values for the indices in SETPOS.
SETPOS should be a list of positive or negative integers between -366
and 366, indicating a fixed index in a set of recurrences for *one
@ -962,23 +1013,24 @@ an `icalendar-recur'. For example, in a YEARLY recurrence rule with an
INTERVAL of 1, the SETPOS represent indices in the recurrence instances
generated for a single year.
The returned value is a closure which can be called on the list of
recurrences for one interval to filter it by index."
(lambda (dts)
(let* ((len (length dts))
(keep-indices (mapcar
(lambda (pos)
;; sequence indices are 0-based, POS's are 1-based:
(if (< pos 0)
(+ pos len)
(1- pos)))
setpos)))
(delq nil
(seq-map-indexed
(lambda (dt index)
(when (memq index keep-indices)
dt))
dts)))))
The returned value is RECURRENCES filtered by index."
(let* ((len (length recurrences))
(keep-indices (mapcar
(lambda (pos)
;; sequence indices are 0-based, POS's are 1-based:
(if (< pos 0)
(+ pos len)
(1- pos)))
setpos))
(r nil)
(i 0)
(dts recurrences))
(while dts
(when (memq i keep-indices)
(push (car dts) r))
(incf i)
(pop dts))
(nreverse r)))
(defun icr:refine-from-clauses (interval recur-value dtstart
&optional vtimezone)
@ -1099,13 +1151,13 @@ The returned list of recurrences contains one date-time value for each
second of each subinterval."
(let (recurrences)
(dolist (int subintervals)
(let* ((start (car int))
(let* ((start (icr:interval-low int))
(dt start)
;; Use absolute times for the loop in case the subinterval
;; crosses the boundary between two observances.
;; N.B. floating times will be correctly treated as local
;; times by encode-time.
(end (time-convert (encode-time (cadr int)) 'integer))
(end (time-convert (encode-time (icr:interval-high int)) 'integer))
(tick (time-convert (encode-time start) 'integer)))
(while (time-less-p tick end)
(push dt recurrences)
@ -1121,10 +1173,10 @@ The returned list of recurrences contains one date value for each
day of each subinterval."
(let (recurrences)
(dolist (int subintervals)
(let* ((start (car int))
(let* ((start (icr:interval-low int))
(start-abs (calendar-absolute-from-gregorian
(ical:date-time-to-date start)))
(end (cadr int))
(end (icr:interval-high int))
(end-abs (calendar-absolute-from-gregorian
(ical:date-time-to-date end)))
;; end is an exclusive upper bound, but number-sequence
@ -1136,9 +1188,9 @@ day of each subinterval."
(1- end-abs)
end-abs)))
(setq recurrences
(append recurrences
(mapcar #'calendar-gregorian-from-absolute
(number-sequence start-abs bound))))))
(nconc recurrences
(mapcar #'calendar-gregorian-from-absolute
(number-sequence start-abs bound))))))
recurrences))
(defun icr:subintervals-to-recurrences (subintervals dtstart &optional vtimezone)
@ -1162,7 +1214,7 @@ subinterval of the same type as DTSTART."
(defun icr:recurrences-in-interval (interval component &optional vtimezone nmax)
"Return a list of the recurrences of COMPONENT in INTERVAL.
INTERVAL should be a list (LOW HIGH NEXT) of date-times which bound a
INTERVAL should be an interval [LOW HIGH NEXT] of date-times which bound a
single recurrence interval, as returned e.g. by
`icalendar-recur-find-interval'. (To find the recurrences in an
arbitrary window of time, rather than between interval boundaries, see
@ -1209,11 +1261,7 @@ retrieved on subsequent calls with the same arguments."
:zone offset-from
:dst (not (ical:daylight-component-p
component)))))
(cl-labels ((get-interval
(apply-partially #'icr:-set-get-interval component))
(put-interval
(apply-partially #'icr:-set-put-interval component)))
(let ((cached (get-interval interval)))
(let ((cached (icr:-set-get-interval component interval)))
(cond ((eq cached :none) nil)
(cached cached)
(t
@ -1227,8 +1275,7 @@ retrieved on subsequent calls with the same arguments."
(keep-indices (ical:recur-by* 'BYSETPOS recur-value))
(pos-recs
(if keep-indices
(funcall (icr:make-bysetpos-filter keep-indices)
sub-recs)
(icr:bysetpos-filter keep-indices sub-recs)
sub-recs))
;; Remove any recurrences before DTSTART or after UNTIL
;; (both of which are inclusive bounds):
@ -1241,8 +1288,8 @@ retrieved on subsequent calls with the same arguments."
pos-recs))
;; Include any values in the interval from the
;; RDATE property:
(low (car interval))
(high (cadr interval))
(low (icr:interval-low interval))
(high (icr:interval-high interval))
(rdates
(mapcar #'ical:ast-node-value
(apply #'append
@ -1276,11 +1323,12 @@ retrieved on subsequent calls with the same arguments."
;; store more recurrences in the final interval than the
;; COUNT clause allows:
(nmax-recs
(if nmax (seq-take all-recs nmax)
(if nmax (take nmax all-recs)
all-recs)))
;; Store and return the computed recurrences:
(put-interval interval (or nmax-recs :none))
nmax-recs))))))))
(icr:-set-put-interval component interval
(or nmax-recs :none))
nmax-recs)))))))
(defun icr:recurrences-in-window (lower upper component &optional vtimezone)
"Return the recurrences of COMPONENT in the window between LOWER and UPPER.
@ -1320,12 +1368,12 @@ UTC offsets local to that time zone."
vtimezone))
(high-interval (icr:find-interval high-end dtstart recur-value
vtimezone))
(high-intbound (cadr high-interval))
(high-intbound (icr:interval-high high-interval))
(recurrences nil))
(while (ical:date-time< (car curr-interval) high-intbound)
(while (ical:date-time< (icr:interval-low curr-interval) high-intbound)
(setq recurrences
(append
(nconc
(icr:recurrences-in-interval curr-interval component vtimezone)
recurrences))
(setq curr-interval (icr:next-interval curr-interval recur-value
@ -1341,7 +1389,7 @@ UTC offsets local to that time zone."
(defun icr:recurrences-in-window-w/end-times
(lower upper component &optional vtimezone)
"Like `icalendar-recurrences-in-window', but returns end times.
"Like `icalendar-recur-recurrences-in-window', but returns end times.
The return value is a list of (START END) pairs representing the start
and end time of each recurrence of COMPONENT in the window defined by
@ -1370,18 +1418,18 @@ the period."
(mapcar #'ical:ast-node-value rdate-nodes)))))
(when (or starts periods)
(seq-uniq
(append (mapcar
(lambda (dt) (list dt (ical:date/time-add-duration
dt duration vtimezone)))
starts)
(mapcar
(lambda (p)
(let ((start (ical:period-start p)))
(list start
(or (ical:period-end p)
(ical:date/time-add-duration
start (ical:period-dur-value p) vtimezone)))))
periods)))))))
(nconc (mapcar
(lambda (dt) (list dt (ical:date/time-add-duration
dt duration vtimezone)))
starts)
(mapcar
(lambda (p)
(let ((start (ical:period-start p)))
(list start
(or (ical:period-end p)
(ical:date/time-add-duration
start (ical:period-dur-value p) vtimezone)))))
periods)))))))
(defun icr:recurrences-to-count (component &optional vtimezone)
"Return all the recurrences in COMPONENT up to COUNT in its recurrence rule.
@ -1418,8 +1466,8 @@ UTC offsets local to that time zone."
recs)
(while (length< recs count)
(setq recs
(append recs (icr:recurrences-in-interval int component vtimezone
(- count (length recs)))))
(nconc recs (icr:recurrences-in-interval int component vtimezone
(- count (length recs)))))
(setq int (icr:next-interval int recur-value vtimezone)))
recs)))
@ -1455,7 +1503,7 @@ UTC offsets local to that time zone."
(make-hash-table :test #'equal))
(defsubst icr:-key-from-interval (interval)
(take 6 (car interval))) ; (secs mins hours day month year)
(take 6 (icr:interval-low interval))) ; (secs mins hours day month year)
(defun icr:-set-get-interval (component interval)
(let ((set (ical:ast-node-meta-get :recurrence-set component))
@ -1636,8 +1684,26 @@ should be a time zone identifier, as found e.g. in an
(when (equal tzidval tzid)
(throw 'found tz))))))
(defun icr:-w/in-locally-p (dt start &optional end)
"Check whether DT falls after START (and before END, if any).
All three values must be `icalendar-date-time's. The check is performed with
`icalendar-date-time-locally<='."
(and
(ical:date-time-locally<= start dt)
(or (not end)
(ical:date-time-locally<= dt end))))
(defun icr:-w/in-abs-p (dt start &optional end)
"Check whether DT falls after START (and before END, if any).
DT must be a Lisp time stamp and START and END must be `icalendar-date-time's.
The check is performed with `icalendar-time<='."
(and
(ical:time<= (encode-time start) dt)
(or (not end)
(ical:time<= dt (encode-time end)))))
;; DRAGONS DRAGONS DRAGONS
(defun icr:tz-observance-on (dt vtimezone &optional update nonexisting)
(defun icr:tz-observance-on (dt vtimezone &optional update nonexistent)
"Return the time zone observance in effect on DT in VTIMEZONE.
If there is such an observance, the returned value is a list (OBSERVANCE
@ -1661,7 +1727,7 @@ If UPDATE is non-nil, the observance found will be used to update the
offset value in DT (as a side effect) before returning the observance
and onset.
If UPDATE is non-nil, NONEXISTING specifies how to handle clock times
If UPDATE is non-nil, NONEXISTENT specifies how to handle clock times
that do not exist in the observance (see
`icalendar-recur-tz-nonexistent-date-time-p'). The keyword `:error'
means to signal an \\='icalendar-tz-nonexistent-time error, without
@ -1669,13 +1735,13 @@ modifying any of the fields in DT. Otherwise, the default is to
interpret DT using the offset from UTC before the onset of the found
observance, and then reset the clock time in DT to the corresponding
existing time after the onset of the observance. For example, the
nonexisting time 2:30AM in Standard time on the day of the switch to
nonexistent time 2:30AM in Standard time on the day of the switch to
Daylight time in the US Eastern time zone will be reset to 3:30AM
Eastern Daylight time.
If DT is a Lisp timestamp, it represents an absolute time and
comparisons with the onsets in VTIMEZONE are performed with absolute
times. UPDATE and NONEXISTING have no meaning in this case and are
times. UPDATE and NONEXISTENT have no meaning in this case and are
ignored."
(ical:with-component vtimezone
((ical:standard :all stds)
@ -1715,10 +1781,27 @@ ignored."
(effective-start
(ical:date-time-variant start :zone offset-from
:dst (not is-daylight)))
(until (ical:recur-until recur-value))
(bound
;; Optimization: compute a rough upper bound for when
;; an observance might apply, thus allowing us to skip
;; computing recurrences for irrelevant observances.
;; The UNTIL date, if any, is the last *recurrence* of
;; the observance. The observance is therefore in
;; effect for some time after this recurrence, so we
;; can't just use UNTIL as an upper bound, but it's
;; guaranteed to end within N years after UNTIL, where
;; N is the interval size. This is not the tightest
;; possible bound but it is the cheapest to compute here.
(when until
(ical:date-time-variant until
:year (+ (decoded-time-year until)
(ical:recur-interval-size
recur-value)))))
(observance-might-apply
(if given-clock-time
(ical:date-time-locally<= effective-start given-clock-time)
(ical:time<= (encode-time effective-start) given-abs-time))))
(icr:-w/in-locally-p given-clock-time effective-start bound)
(icr:-w/in-abs-p given-abs-time effective-start bound))))
(when observance-might-apply
;; Initialize our return values on the first iteration
@ -1781,31 +1864,37 @@ ignored."
(decode-time given-abs-time offset-from)))
(int (icr:find-interval
target effective-start recur-value offset-from))
(int-recs (icr:recurrences-in-interval
int obs offset-from))
;; The closest observance onset before `dt' might
;; actually be in the previous interval, e.g.
;; if `dt' is in January after an annual change to
;; Standard Time in November. So check that as well.
(prev-int (icr:previous-interval int recur-value
effective-start
offset-from))
(prev-recs (when prev-int
(icr:recurrences-in-interval
prev-int obs offset-from)))
(recs (append prev-recs int-recs))
(keep-recs<=given
(<=given
(if given-clock-time
(lambda (rec)
(ical:date-time-locally<= rec given-clock-time))
(lambda (rec)
(ical:time<= (encode-time rec) given-abs-time))))
(srecs (sort (seq-filter ; (1)
keep-recs<=given
recs)
(int-recs (sort
(seq-filter <=given ; (1)
(icr:recurrences-in-interval
int obs offset-from))
:lessp #'ical:date-time<
:in-place t :reverse t))
(latest-rec (car srecs)))
latest-rec)
(unless int-recs
;; The closest observance onset before `dt' might
;; actually be in the previous interval, e.g.
;; if `dt' is in January after an annual change to
;; Standard Time in November. So check that as well.
(setq int (icr:previous-interval int recur-value
effective-start
offset-from))
(setq int-recs
(when int
(sort
(seq-filter <=given ; (1)
(icr:recurrences-in-interval
int obs offset-from))
:lessp #'ical:date-time<
:in-place t :reverse t))))
(setq latest-rec (car int-recs))
(when (and latest-rec
(ical:date-time< nearest-onset latest-rec)) ; (2)
@ -1827,7 +1916,7 @@ ignored."
(when (and update given-clock-time nearest-observance updated)
;; signal an error when `dt' does not exist if requested, so the
;; nonexistence can be handled further up the stack:
(when (and (eq :error nonexisting)
(when (and (eq :error nonexistent)
(not (ical:date-time-locally-simultaneous-p dt updated)))
(signal 'ical:tz-nonexistent-time
(list
@ -1895,7 +1984,7 @@ decoded directly into this UTC offset, and its dst slot is set to -1."
:dst (if observance (ical:daylight-component-p observance)
-1))))
(defun icr:tz-set-zone (dt vtimezone &optional nonexisting)
(defun icr:tz-set-zone (dt vtimezone &optional nonexistent)
"Set the time zone offset and dst flag in DT based on VTIMEZONE.
DT should be an `icalendar-date-time' and VTIMEZONE should be an
@ -1910,7 +1999,7 @@ where a different time zone observance may be in effect in the original
date-time. It cannot be used to re-decode a fixed point in time into a
different time zone; for that, see `icalendar-recur-tz-decode-time'.
If given, NONEXISTING is a keyword that specifies what to do if DT
If given, NONEXISTENT is a keyword that specifies what to do if DT
represents a clock time that does not exist according to the relevant
observance in VTIMEZONE. The value :error means to signal an
\\='icalendar-tz-nonexistent-time error, and nil means to reset the
@ -1941,7 +2030,7 @@ clock time in DT to an existing one; see
;; This updates the relevant slots in dt as a side effect:
;; TODO: if no observance is found, is it ever sensible to signal an error,
;; instead of just leaving the zone slot unset?
(icr:tz-observance-on dt vtimezone t nonexisting)))
(icr:tz-observance-on dt vtimezone t nonexistent)))
dt)
(defun icr:tz-set-zones-in (vtimezones node)
@ -1974,8 +2063,8 @@ called recursively on NODE's children."
:duration (ical:period-dur-value value)))))
(ical:ast-node-set-value value-node updated)))))
((ical:component-node-p node) ; includes VCALENDAR nodes
(mapc (apply-partially #'icr:tz-set-zones-in vtimezones)
(ical:ast-node-children node)))
(dolist (nd (ical:ast-node-children node))
(icr:tz-set-zones-in vtimezones nd)))
(t nil)))
(defun icr:tzname-on (dt vtimezone)
@ -2024,7 +2113,7 @@ observance."
(null dst-ends-time))))))
(defun icr:current-tz-to-vtimezone (&optional tz tzid start-year)
"Convert TZ to an `icalendar-vtimezone'.
"Convert TZ (default: current time zone) to an `icalendar-vtimezone'.
TZ defaults to the output of `calendar-current-time-zone'; if specified,
it should be a list of the same form as that function returns.

View file

@ -0,0 +1,273 @@
;;; icalendar-shortdoc.el --- Short documentation for iCalendar -*- lexical-binding: t; -*-
;; Copyright (C) 2026 Free Software Foundation, Inc.
;; Author: Richard Lawrence <rwl@recursewithless.net>
;; Created: April 2026
;; Keywords: calendar, help
;; Human-Keywords: calendar, iCalendar
;; This file is part of GNU Emacs.
;; This file 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.
;; This file 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 this file. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This file defines a short documentation group for the main functions
;; of the iCalendar API. It does not aim to cover every function in the
;; library; it is a guide to the high-level functions for Lisp
;; programmers who want to interpret or produce iCalendar data.
;; To read this documentation, do:
;; M-x load-libraray RET icalendar-shortdoc RET
;; M-x shortdoc RET icalendar RET
;;; Code:
(require 'shortdoc)
(require 'icalendar-macs)
(require 'icalendar-parser)
(require 'icalendar-utils)
(require 'icalendar-ast)
(require 'icalendar-recur)
(define-short-documentation-group icalendar
"Parsing and printing VCALENDAR objects"
(icalendar-parse
:no-manual t
:no-eval* (icalendar-parse)
:result-string "(icalendar-vcalendar ...)")
(icalendar-parse-and-index
:no-manual t
:no-eval* (icalendar-parse-and-index)
:result (vcalendar index))
(icalendar-index-get
:args (index &rest kwargs)
:no-manual t
:no-eval (icalendar-index-get index :uid "some-event-UID")
:eg-result-string "(icalendar-vevent ...)"
:no-eval (icalendar-index-get index :date '(5 28 2026))
:eg-result-string "((icalendar-vevent ...) ...)"
:no-eval (icalendar-index-get index :tzid "Europe/Vienna")
:eg-result-string "(icalendar-vtimezone ...)")
(icalendar-parse-from-string
:no-eval
(icalendar-parse-from-string 'icalendar-rrule "RRULE:FREQ=WEEKLY\n")
:result-string "(icalendar-rrule ...)")
(icalendar-print-calendar-node
:no-manual t
:no-eval (icalendar-print-calendar-node vcalendar)
:result "BEGIN:VCALENDAR...")
"Constructing syntax nodes"
(icalendar-make-vcalendar
:no-manual t
:no-eval
"(icalendar-make-vcalendar
some-vtimezone
(@ list-of-vevents)
...)"
:result-string "(icalendar-vcalendar ...)")
(icalendar-make-vevent
:no-manual t
:no-eval
"(icalendar-make-vevent
(icalendar-summary \"Party\")
(icalendar-location \"Robot House\")
(icalendar-organizer \"mailto:bender@mars.edu\"
(icalendar-cnparam \"Bender B. Rodriguez\"))
(icalendar-attendee \"mailto:philip.j.fry@mars.edu\"
(icalendar-partstatparam \"ACCEPTED\"))
(icalendar-dtstart '(3 13 3003))
(icalendar-rrule '((FREQ MONTHLY))))"
:result-string "(icalendar-vevent ...)")
(icalendar-make-vtodo
:no-manual t
:no-eval
"(icalendar-make-vtodo
(icalendar-summary \"Sell another doomsday device\")
(icalendar-description \"Need funds for electronium hat experiment.\")
(icalendar-due '(6 6 3002)))"
:result-string "(icalendar-vtodo ...)")
(icalendar-make-vjournal
:no-manual t
:no-eval
"(icalendar-make-vjournal
(icalendar-summary \"Results: Electronium Hat Experiment\")
(icalendar-description \"How do you like them bananas?\")
(icalendar-dtstart '(8 6 3002)))"
:result-string "(icalendar-vjournal ...)")
"Binding values in syntax nodes"
(icalendar-with-component
:args (node bindings &rest body)
:no-manual t
:no-eval
"(icalendar-with-component vevent
((icalendar-summary :value summary)
(icalendar-location :value location))
(format \"%s @ %s\" summary location))"
:eg-result "Party @ Robot House")
(icalendar-with-property
:args (node bindings &rest body)
:no-manual t
:no-eval "(icalendar-with-property location-node nil
(downcase value))"
:eg-result "robot house")
(icalendar-with-property-of
:args (component property-type bindings &rest body)
:no-manual t
:no-eval
"(icalendar-with-property-of vevent 'icalendar-location nil
(downcase value))"
:eg-result "robot house")
(icalendar-with-param
:args (parameter &rest body)
:no-manual t
:no-eval "(icalendar-with-param cnparam-node
(upcase value))"
:eg-result "BENDER B. RODRIGUEZ")
(icalendar-with-param-of
:args (property param-type &rest body)
:no-manual t
:no-eval "(icalendar-with-param-of organizer-node 'icalendar-cnparam
(upcase value))"
:eg-result "BENDER B. RODRIGUEZ")
"Time zones"
(icalendar-recur-current-tz-to-vtimezone
:no-manual t
:no-eval (icalendar-recur-current-tz-to-vtimezone)
:result-string "(icalendar-vtimezone ...)")
(icalendar-recur-tz-decode-time
:no-manual t
:no-eval (icalendar-recur-tz-decode-time timestamp vtimezone)
:eg-result (0 0 11 11 11 2024 1 nil 3600))
(icalendar-recur-tz-set-zone
:no-eval (icalendar-recur-tz-set-zone '(0 0 11 11 11 2024 1 -1 nil) vtimezone)
:eg-result (0 0 11 11 11 2024 1 nil 3600))
"Dates and date-times"
(icalendar-make-date-time
:no-manual t
:args (&rest kwargs)
:no-eval
"(icalendar-make-date-time :year 2024 :month 12 :day 11
:hour 10 :minute 0 :second 0
:tz vtimezone)"
:eg-result (0 0 10 11 12 2024 3 -1 3600))
(icalendar-date/time<=
:eval (icalendar-date/time<= '(12 15 2024) '(12 11 2024))
:eval "(icalendar-date/time<= '(0 0 8 11 11 2024 1 nil 3600)
'(0 0 10 11 11 2024 3 nil 3600))"
:no-manual t)
(icalendar-date/time<
:no-manual t
:eval (icalendar-date/time< '(12 15 2024) '(12 15 2024)))
(icalendar-date/time-min
:no-manual t
:eval (icalendar-date/time-min '(12 15 2024) '(11 15 2024) '(12 1 2024))
:eval
"(icalendar-date/time-min '(0 0 8 11 12 2024 3 nil 3600)
'(0 0 9 11 12 2024 3 nil 3600)
'(0 0 10 11 12 2024 3 nil 3600))")
(icalendar-date/time-max
:no-manual t
:eval (icalendar-date/time-max '(12 15 2024) '(11 15 2024) '(12 1 2024))
:eval
"(icalendar-date/time-max '(0 0 8 11 12 2024 3 nil 3600)
'(0 0 9 11 12 2024 3 nil 3600)
'(0 0 10 11 12 2024 3 nil 3600))")
(icalendar-date/time-add
:no-manual t
:eval (icalendar-date/time-add '(11 11 2024) :month 2)
:eval (icalendar-date/time-add '(0 0 10 11 11 2024 1 -1 nil) :hour -3))
(icalendar-date/time-add-duration
:no-manual t
:eval "(icalendar-date/time-add-duration '(12 11 2024)
(make-decoded-time :day 4))"
:eval "(icalendar-date/time-add-duration '(0 0 10 11 12 2024 3 -1 nil)
(make-decoded-time :hour 2 :minute 30))")
(icalendar-date/time-year
:no-manual t
:eval (icalendar-date/time-year '(12 11 2024))
:eval (icalendar-date/time-year '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-month
:no-manual t
:eval (icalendar-date/time-month '(12 11 2024))
:eval (icalendar-date/time-month '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-monthday
:no-manual t
:eval (icalendar-date/time-monthday '(12 11 2024))
:eval (icalendar-date/time-monthday '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-weekday
:no-manual t
:eval (icalendar-date/time-weekday '(12 11 2024))
:eval (icalendar-date/time-weekday '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-weekno
:no-manual t
:eval (icalendar-date/time-weekno '(12 11 2024))
:eval (icalendar-date/time-weekno '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-hour
:no-manual t
:eval (icalendar-date/time-hour '(12 11 2024))
:eval (icalendar-date/time-hour '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-minute
:no-manual t
:eval (icalendar-date/time-minute '(12 11 2024))
:eval (icalendar-date/time-minute '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-second
:no-manual t
:eval (icalendar-date/time-second '(12 11 2024))
:eval (icalendar-date/time-second '(0 0 10 11 12 2024 3 nil 3600)))
(icalendar-date/time-zone
:no-manual t
:eval (icalendar-date/time-zone '(12 11 2024))
:eval (icalendar-date/time-zone '(0 0 10 11 12 2024 3 nil 3600)))
"Recurrence rules and recurrences"
(icalendar-recur-recurrences-in-window
:no-manual t
:no-eval
"(icalendar-recur-recurrences-in-window '(1 1 2026) '(12 31 2026)
vevent)"
:eg-result-string "((1 10 2026) (2 10 2026) ...)")
(icalendar-recur-recurrences-in-window-w/end-times
:no-manual t
:no-eval
"(icalendar-recur-recurrences-in-window-w/end-times
'(0 0 0 1 1 2026 4 -1 nil) '(0 0 0 1 2 2026 1 -1 nil)
vevent)"
:eg-result-string
"(((0 0 10 10 1 2026 4 -1 nil) (0 0 11 10 1 2026 4 -1 nil)) ...)")
(icalendar-recur-recurrences-to-count
:no-manual t
:no-eval
"(icalendar-recur-recurrences-to-count '(1 1 2026) '(12 31 2026)
vevent)"
:eg-result-string "((1 10 2026) (2 10 2026) (3 10 2026))")
(icalendar-recur-freq
:eval
(icalendar-recur-freq '((FREQ MONTHLY) (INTERVAL 3) (BYDAY ((5 . -1))))))
(icalendar-recur-interval-size
:eval (icalendar-recur-interval-size '((FREQ MONTHLY) (BYDAY ((5 . -1)))))
:eval (icalendar-recur-interval-size '((FREQ MONTHLY) (INTERVAL 3))))
(icalendar-recur-count
:eval (icalendar-recur-count '((FREQ MONTHLY) (INTERVAL 2) (COUNT 6))))
(icalendar-recur-until
:eval (icalendar-recur-until '((FREQ WEEKLY) (UNTIL (12 31 2026)))))
(icalendar-recur-by*
:eval (icalendar-recur-by* 'BYDAY '((FREQ MONTHLY) (BYDAY ((5 . -1))))))
(icalendar-recur-weekstart
:eval
(icalendar-recur-weekstart '((FREQ WEEKLY) (UNTIL (12 31 2026)) (WKST 0)))
:eval
(icalendar-recur-weekstart '((FREQ WEEKLY) (UNTIL (12 31 2026))))))
(provide 'icalendar-shortdoc)

View file

@ -23,6 +23,8 @@
;;; Commentary:
;; For an overview of the iCalendar library, see icalendar-shortdoc.el.
;; This file contains a variety of utility functions to work with
;; iCalendar data which are used throughout the rest of the iCalendar
;; library. Most of the functions here deal with calendar and clock
@ -561,6 +563,7 @@ interpreted into Emacs local time, so that the dates returned are valid
for the local time zone."
(require 'icalendar-recur) ; avoid circular requires
(declare-function icalendar-recur-subintervals-to-dates "icalendar-recur")
(declare-function icalendar-recur-make-interval "icalendar-recur")
(when locally
(when (cl-typep start 'ical:date-time)
@ -572,18 +575,23 @@ for the local time zone."
(cl-typecase end
(ical:date
(icalendar-recur-subintervals-to-dates
(list (list (ical:date-to-date-time start)
(ical:date-to-date-time end)))))
(list
(icalendar-recur-make-interval
(ical:date-to-date-time start)
(ical:date-to-date-time end)))))
(ical:date-time
(icalendar-recur-subintervals-to-dates
(list (list (ical:date-to-date-time start) end))))))
(list
(icalendar-recur-make-interval (ical:date-to-date-time start) end))))))
(ical:date-time
(cl-typecase end
(ical:date
(icalendar-recur-subintervals-to-dates
(list (list start (ical:date-to-date-time end)))))
(list
(icalendar-recur-make-interval start (ical:date-to-date-time end)))))
(ical:date-time
(icalendar-recur-subintervals-to-dates (list (list start end))))))))
(icalendar-recur-subintervals-to-dates
(list (icalendar-recur-make-interval start end))))))))
(cl-defun ical:make-date-time (&key second minute hour day month year

View file

@ -27,21 +27,13 @@
;;; Commentary:
;; Most of the code in this file is now obsolete and has been marked as such.
;; For an overview of the new iCalendar library, see icalendar-shortdoc.el.
;; For the new implementation of diary import/export, see diary-icalendar.el.
;; Error handling code, global variables, and user options relevant for the
;; entire iCalendar library remain in this file.
;; This package is documented in the Emacs Manual.
;; The diary-icalendar feature is documented in the Emacs Manual.
;; Please note:
;; - Diary entries which have a start time but no end time are assumed to
;; last for one hour when they are exported.
;; - Weekly diary entries are assumed to occur the first time in the first
;; week of the year 2000 when they are exported.
;; - Yearly diary entries are assumed to occur the first time in the year
;; 1900 when they are exported.
;; - Float diary entries are assumed to occur the first time on the
;; day when they are exported.
;;; History:

View file

@ -4157,14 +4157,21 @@ setting."
(when (memq #'syntax-ppss-flush-cache before-change-functions)
(apply #'syntax-ppss-flush-cache beg rest)))))
(defun comint--fontify-input-fontify-region (fun beg end verbose)
"Fontify process output and user input in the current comint buffer.
First, fontify the region between BEG and END using FUN. Then
fontify only the input text in the region with the help of an
indirect buffer. VERBOSE is passed to the fontify-region
functions. Skip fontification of input regions with non-nil
`comint--fontify-input-inhibit-fontification' text property."
(pcase (funcall fun beg end verbose)
(defun comint--dummy-fontify-syntax (end)
;; Tell `syntax-propertize' that there's nothing
;; to propertize here.
;; BEWARE: don't use `ignore' because `syntax-propertize'
;; treats it specially.
(let ((syntax-propertize-function (lambda (&rest _) nil)))
(syntax-propertize end)))
(defun comint--fontify-input-fontify-region (orig-fun beg end &rest args)
"Fontify user input in the current comint buffer.
Fontify the input text in the region with the help of an indirect buffer.
Skip fontification of input regions with non-nil
`comint--fontify-input-inhibit-fontification' text property.
Designed as an advice for use in `font-lock-fontify-region-function'."
(pcase (apply orig-fun beg end args)
(`(jit-lock-bounds ,beg1 . ,end1)
(setq beg beg1 end end1)))
(pcase
@ -4173,10 +4180,12 @@ functions. Skip fontification of input regions with non-nil
(with-current-buffer (comint-indirect-buffer)
(narrow-to-region min max)
(comint--intersect-regions
nil (lambda (beg end)
(unless (get-text-property
beg 'comint--fontify-input-inhibit-fontification)
(font-lock-fontify-region beg end verbose)))
(lambda (_beg end) (comint--dummy-fontify-syntax end))
(lambda (beg end)
(if (get-text-property
beg 'comint--fontify-input-inhibit-fontification)
(comint--dummy-fontify-syntax end)
(apply #'font-lock-fontify-region beg end args)))
beg end)))
(`((jit-lock-bounds ,beg1 . ,_) . (jit-lock-bounds ,_ . ,end1))
(setq beg (min beg beg1))

View file

@ -499,7 +499,12 @@ candidates or if there are multiple matching completions and
(sort-fn (or (completion-metadata-get md 'cycle-sort-function)
(completion-metadata-get md 'display-sort-function)
completion-preview-sort-function))
(all (let ((completion-lazy-hilit t)
(all (let (;; This is somewhat redundant since we also specify
;; non-nil `lazy-highlight' in
;; `completion-frontend-properties', but we keep it
;; for compatibility with backends that do not know
;; about `completion-frontend-properties' yet.
(completion-lazy-hilit t)
;; FIXME: This does not override styles prescribed
;; by the completion category via
;; e.g. `completion-category-defaults'.
@ -525,7 +530,9 @@ candidates or if there are multiple matching completions and
(defun completion-preview--capf-wrapper (capf)
"Translate return value of CAPF to properties for completion preview overlay."
(let ((res (ignore-errors (funcall capf))))
(let* ((completion-frontend-properties '((no-annotations . t)
(lazy-highlight . t)))
(res (ignore-errors (funcall capf))))
(and (consp res)
(not (functionp res))
(seq-let (beg end table &rest plist) res

View file

@ -1344,7 +1344,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 "30.1"
(defvar customize-changed-options-previous-release "31.1"
"Version for `customize-changed' to refer back to by default.")
;; Packages will update this variable, so make it available.

View file

@ -2362,7 +2362,7 @@ unless OK-IF-ALREADY-EXISTS is non-nil."
(ignore-errors (vc-responsible-backend file))
(vc-backend file))
(ignore-errors (vc-responsible-backend newname)))
(vc-rename-file file newname)
(vc-rename-file file newname ok-if-already-exists)
;; error is caught in -create-files
(rename-file file newname ok-if-already-exists))
;; Silently rename the visited file of any buffer visiting this file.

View file

@ -553,7 +553,8 @@ displayed instead."
(defcustom dired-auto-toggle-b-switch nil
"Whether to automatically add or remove the `b' switch.
If non-nil, the function `dired--toggle-b-switch' (which see) is added
to `post-command-hook' in Dired mode."
to `post-command-hook' in Dired mode, unless the `ls' used by Dired does
not accept the `b' switch."
:type 'boolean
:group 'dired
:initialize #'custom-initialize-default
@ -649,6 +650,9 @@ The match starts at the beginning of the line and ends after the end
of the line.
Subexpression 2 must end right before the \\n.")
(defvar dired--ls-error-file nil
"When non-nil, name of temporary file an `ls' error is written to.")
(defvar dired--ls-error-buffer nil
"Non-nil if the current dired invocation yields an `ls' error.
The non-nil value is the buffer containing the error message.")
@ -1237,8 +1241,9 @@ If DIRNAME is already in a Dired buffer, that buffer is used without refresh."
(prog1 (pop-to-buffer-same-window (dired-noselect dirname switches))
(dired--display-ls-error)))
;; This is needed to let clicks on the menu bar invoke Dired even if
;; some feature remaps the Dired command to another command.
;; This lets clicks on the menu bar invoke Dired even if some feature
;; remaps the Dired command to another command that does not handle this
;; situation correctly (e.g. earlier versions of `dired-at-point-prompter').
;;;###autoload
(defun dired-from-menubar (dirname &optional switches)
"Edit an existing directory."
@ -1455,16 +1460,12 @@ The return value is the target column for the file names."
(let ((failed t))
(unwind-protect
(progn (dired-readin)
;; Check for file entries (they are listed below the
;; directory name and (if present) wildcard lines).
(while (and (skip-syntax-forward "\s")
(looking-at "\\(.+:$\\|wildcard\\)"))
(forward-line))
(unless (eobp)
(unless (and dired--ls-error-buffer
(get-buffer "*ls error*"))
(setq failed nil)))
;; No file entries indicates an `ls' error, and `dired-readin'
;; can fail if parent directories are inaccessible. In either
;; case don't leave the Dired buffer around.
;; If either `dired-readin' failed (e.g. if parent directories
;; are inaccessible) or `ls' errored, don't leave the Dired
;; buffer around.
(when failed
(kill-buffer buffer)
(setq buffer nil))))
@ -1472,15 +1473,16 @@ The return value is the target column for the file names."
(dired-initial-position dirname))
(when (consp dired-directory)
(dired--align-all-files))
;; Pop up a warning if the Dired listing displays a literal newline.
;; We do this here in order to get the warning not only when
;; interactively invoking `dired' on a directory, but also e.g. when
;; passing the directory name as a command line argument when
;; starting Emacs from the shell.
;; Pop up a warning if the Dired listing displays a literal newline
;; and `ls' can take the `b' switch. We do this here in order to
;; get the warning not only when interactively invoking `dired' on a
;; directory, but also e.g. when passing the directory name as a
;; command line argument when starting Emacs from the shell.
(unless (or dired-auto-toggle-b-switch
(dired-switches-escape-p dired-listing-switches)
(dired-switches-escape-p dired-actual-switches))
(when (dired--filename-with-newline-p)
(when (and (dired--filename-with-newline-p)
(dired--ls-accept-b-switch-p))
(dired--display-filename-with-newline-warning buffer)))
(set-buffer old-buf)
buffer))
@ -1618,7 +1620,27 @@ wildcards, erases the buffer, and builds the subdir-alist anew
;; Else treat it as a wildcard spec
;; unless we have an explicit list of files.
(dired-insert-directory dir dired-actual-switches
file-list (not file-list) t)))))
file-list (not file-list) t)))
;; Every time `temporary-file-directory' is (re)displayed in Dired a
;; new `ls' error file is created and the Dired buffer has an entry
;; for it. The file itself is deleted in `insert-directory' but its
;; Dired entry remains, so we remove it here. This is not relevant
;; if ls-lisp emulation is used.
(when (files--use-insert-directory-program-p)
(let ((tmpbuf (dired-find-buffer-nocreate temporary-file-directory)))
(when tmpbuf
(with-current-buffer tmpbuf
(save-excursion
(without-restriction
(goto-char (point-min))
(when (search-forward
(file-name-base dired--ls-error-file) nil t)
;; The call chain of `dired-remove-entry' requires
;; non-nil `dired-subdir-alist', but here it is nil,
;; so we set it.
(let ((dired-subdir-alist `((,temporary-file-directory
. ,(point-min-marker)))))
(dired-remove-entry dired--ls-error-file)))))))))))
(defun dired-align-file (beg end)
"Align the fields of a file to the ones of surrounding lines.
@ -4034,6 +4056,10 @@ newline character (regardless of whether Dired displays the character as
a literal newline or as \"\\n\")."
(directory-files default-directory nil "\n"))
(defun dired--ls-accept-b-switch-p ()
"Return non-nil if the `ls' used by Dired accepts the `b' switch."
(eq 0 (call-process insert-directory-program nil nil nil "-b")))
(defun dired--remove-b-switch ()
"Remove all variants of the `b' switch from `dired-actual-switches'.
This removes not only all occurrences of the short form `-b' but also
@ -4051,8 +4077,9 @@ the long forms `--escape' and `--quoting-style=escape'."
"Add or remove `b' switch and redisplay Dired buffer.
When the current Dired buffer has a file name containing a newline, add
the `b' switch to the actual switches if it isn't already among them;
otherwise remove the `b' switch unless it is in `dired-listing-switches'.
Then redisplay the Dired buffer. This function is called from
otherwise remove the `b' switch unless it is in
`dired-listing-switches'. Then redisplay the Dired buffer. When
`dired-auto-toggle-b-switch' is non-nil, this function is called from
`post-command-hook' in Dired mode buffers."
(when (eq major-mode 'dired-mode)
(if (and (dired--filename-with-newline-p) dired-auto-toggle-b-switch)
@ -4067,12 +4094,13 @@ Then redisplay the Dired buffer. This function is called from
(defun dired--set-auto-toggle-b-switch (symbol value)
"The :set function for user option `dired-auto-toggle-b-switch'."
(custom-set-default symbol value)
(if value
(add-hook 'post-command-hook #'dired--toggle-b-switch nil t)
(remove-hook 'post-command-hook #'dired--toggle-b-switch t))
(dolist (b (buffer-list))
(with-current-buffer b
(dired--toggle-b-switch))))
(when (dired--ls-accept-b-switch-p)
(if value
(add-hook 'post-command-hook #'dired--toggle-b-switch nil t)
(remove-hook 'post-command-hook #'dired--toggle-b-switch t))
(dolist (b (buffer-list))
(with-current-buffer b
(dired--toggle-b-switch)))))
(defun dired--display-filename-with-newline-warning (dir)
"Display a warning if buffer DIR has a file name with a newline."
@ -4111,8 +4139,8 @@ See `%s' for other alternatives and more information."))
(search-backward "Warning (dired)")))))
(defun dired--display-ls-error ()
"Pop up a buffer displaying the current `ls' error, if any."
(when dired--ls-error-buffer
"Pop up the buffer displaying the current `ls' error, if any."
(when (buffer-live-p dired--ls-error-buffer)
(let* ((errwin (display-buffer dired--ls-error-buffer)))
(fit-window-to-buffer errwin))
(setq dired--ls-error-buffer nil)))

View file

@ -2271,6 +2271,7 @@ See also `emacs-lisp-byte-compile-and-load'."
filename buffer-file-name))
;; Don't inherit lexical-binding from caller (bug#12938).
(unless (or (local-variable-p 'lexical-binding)
no-byte-compile
bytecomp--inhibit-lexical-cookie-warning)
(let ((byte-compile-current-buffer (current-buffer)))
(displaying-byte-compile-warnings

View file

@ -197,7 +197,7 @@ The name is made by appending a number to PREFIX, default \"T\"."
'(([&rest cl-lambda-arg]
[&optional ["&optional" cl-&optional-arg &rest cl-&optional-arg]]
[&optional ["&rest" cl-lambda-arg]]
[&optional ["&key" [cl-&key-arg &rest cl-&key-arg]
[&optional ["&key" [&optional cl-&key-arg &rest cl-&key-arg]
&optional "&allow-other-keys"]]
[&optional ["&aux" &rest
&or (cl-lambda-arg &optional def-form) arg]]
@ -217,8 +217,8 @@ The name is made by appending a number to PREFIX, default \"T\"."
[&rest cl-lambda-arg]
[&optional ["&optional" cl-&optional-arg &rest cl-&optional-arg]]
[&optional ["&rest" cl-lambda-arg]]
[&optional ["&key" cl-&key-arg &rest cl-&key-arg
&optional "&allow-other-keys"]]
[&optional ["&key" [&optional cl-&key-arg &rest cl-&key-arg]
&optional "&allow-other-keys"]]
[&optional ["&aux" &rest
&or (cl-lambda-arg &optional def-form) arg]]
. [&or arg nil])))
@ -3868,19 +3868,12 @@ If PARENTS is non-nil, ARGLIST must be nil."
;; both at compile-time and at runtime, so we need to double-check.
(static-if (not (fboundp 'cl--define-derived-type)) nil
(when (fboundp 'cl--define-derived-type)
(cl-deftype natnum () (declare (parents integer)) '(satisfies natnump))
(cl-deftype character () (declare (parents fixnum natnum))
'(and fixnum natnum))
(cl-deftype base-char () (declare (parents character))
'(satisfies characterp))
(cl-deftype extended-char () (declare (parents character))
'(and character (not base-char)))
(cl-deftype keyword () (declare (parents symbol)) '(satisfies keywordp))
(cl-deftype command ()
;; FIXME: Can't use `function' as parent because of arrays as
;; keyboard macros, which are redundant since `kmacro.el'!!
;;(declare (parents function))
'(satisfies commandp))
(eval-when-compile
(defmacro cl--defnumtype (type base)

View file

@ -37,7 +37,7 @@
;;; Code:
(eval-when-compile (require 'cl-lib))
(eval-when-compile (require 'cl-macs)) ;For cl--struct-class.
(eval-when-compile (require 'cl-macs)) ;For cl--find-class.
;; The `assert' macro from the cl package signals
;; `cl-assertion-failed' at runtime so always define it.
@ -528,6 +528,14 @@ PARENTS is a list of types NAME is a subtype of, or nil."
(when predicate
(define-symbol-prop name 'cl-deftype-satisfies predicate))))
(cl-deftype natnum () (declare (parents integer)) '(satisfies natnump))
(cl-deftype keyword () (declare (parents symbol)) '(satisfies keywordp))
(cl-deftype command ()
;; FIXME: Can't use `function' as parent because of arrays as
;; keyboard macros, which are redundant since `kmacro.el'!!
;;(declare (parents function))
'(satisfies commandp))
;; Make sure functions defined with cl-defsubst can be inlined even in
;; packages which do not require CL. We don't put an autoload cookie
;; directly on that function, since those cookies only go to cl-loaddefs.

View file

@ -192,14 +192,15 @@ Like `minibuffer-complete-word' but for `completing-read-multiple'."
(crm--completion-command beg end
(completion-in-region--single-word beg end)))
(defun crm-complete-and-exit ()
"If all of the minibuffer elements are valid completions then exit.
All elements in the minibuffer must match. If there is a mismatch, move point
to the location of mismatch and do not exit.
This function is modeled after `minibuffer-complete-and-exit'."
(interactive)
(let ((doexit t))
(defun crm-complete-and-exit (&optional no-exit)
"Exit if all of the minibuffer elements are valid completions.
Otherwise, try to complete the minibuffer contents.
This behaves like `minibuffer-complete-and-exit' (which see),
adjusted for the presence of multiple elements."
(interactive "P")
(when (completion--selected-candidate)
(minibuffer-choose-completion t t))
(let ((doexit (not no-exit)))
(goto-char (minibuffer-prompt-end))
(while
(and doexit

View file

@ -530,6 +530,7 @@ If INTERACTIVE, display it. Else, return said buffer."
(things-reported-on))
(special-mode)
(erase-buffer)
(visual-line-mode)
(setq-local nobreak-char-display nil)
(cl-loop for (docs . rest) on docs
for (this-doc . plist) = docs

View file

@ -2821,10 +2821,50 @@ It is passed to `elisp-scope-1', which see."
Call CALLBACK for each analyzed symbol SYM with arguments ROLE, POS,
SYM, ID and DEF, where ROLE is a symbol that specifies the semantics of
SYM; POS is the position of SYM in STREAM; ID is an object that uniquely
identifies (co-)occurrences of SYM in the current defun; and DEF is the
position in which SYM is locally defined, or nil. If SYM is itself a
binding occurrence, then POS and DEF are equal. If SYM is not lexically
bound, then DEF is nil.
identifies the local reference of SYM in the current defun, so different
occurrences of SYM get the same ID (up to `equal') if and only if they
refer to the same object; and lastly, DEF is the position in which SYM
is locally defined, or nil. For the occurrence of SYM at the position
where it is locally defined (a.k.a. \"bound\"), the values of POS and
DEF are equal. If SYM is not lexically bound, then DEF is nil and so
is ID.
CALLBACK should use ID by checking if it is nil or `equal' to other ID
values produced in the same call to this function. The specific value
of a given ID is otherwise meaningless.
As an example, when this function analyzes the following form
(lambda (mode) (let ((mode (or mode major-mode))) (symbol-name mode)))
the CALLBACK function is invoked four times with SYM `mode':
- Once for the `mode' in the `lambda' arguments list, with ROLE
`binding-variable', some non-nil ID value MODE-ID1, and with POS and
DEF both being the same position POS1 where this `mode' occurs.
- Another time for the binder in the let form, with ROLE
`binding-variable' some non-nil ID value MODE-ID2 that is not `equal'
to MODE-ID1, and with POS and DEF both being the same position POS2.
- Another for the first argument of `or', with ROLE `bound-variable' and
ID of MODE-ID1, since this occurrence of `mode' is bound by the
`lambda' argument `mode'. Similarly, DEF is POS1, and POS is now a
different position, POS3.
- Finally, CALLBACK is also invoked for the `mode' that appears in the
body of `let' as the argument of `symbol-name', with ROLE set to
`bound-variable', ID set to MODE-ID2, and DEF set to POS3.
In the above example, CALLBACK is also invoked for `lambda', `let',
`or', `major-mode' and `symbol-name'. Since those symbols do not have
local references (they refer to global functions/macros/variables),
CALLBACK gets nil ID and nil DEF.
Note that if SYM is locally-bound, but has no specific binding position,
then DEF is nil while ID is non-nil. This is the case when SYM is bound
by a binder that is only introduced during macro expansion and does not
appear literally in the analyzed code.
If STREAM is nil, it defaults to the current buffer. When reading from
the current buffer, this function leaves point at the end of the form.

View file

@ -416,6 +416,19 @@ The same keyword arguments are supported as in
(format "/mock::%s" temporary-file-directory))))
"Temporary directory for remote file tests.")
(defun ert-play-keys (keys)
"Play the key sequence KEYS as if it was user input.
KEYS shall have the same format as in a call to function `kmacro'.
This macro should be expanded within the body of
`ert-with-buffer-selected' to select a buffer when keys KEYS start
commands acting on this buffer, or within the body of
`ert-with-test-buffer' used with `:selected' flag set."
(funcall
(kmacro keys)))
;;;; Obsolete

View file

@ -681,6 +681,15 @@ A and B are the time values to compare."
,(format-time-string "%s.%N" (time-subtract a b) t))))
(function-put #'time-equal-p 'ert-explainer #'ert--explain-time-equal-p)
;;; Facilities for recording the execution of tests from erts files.
(defvar ert--erts-file-test-execution-observer nil)
(defun ert--signal-erts-file-test-execution (test-description)
"Tell the current erts-file test observer (if any) about TEST-DESCRIPTION."
(when ert--erts-file-test-execution-observer
(funcall ert--erts-file-test-execution-observer test-description)))
;;; Implementation of `ert-info'.
;; TODO(ohler): The name `info' clashes with
@ -716,8 +725,8 @@ in front of the value of MESSAGE-FORM."
(cl-defstruct ert-test-result
(messages nil)
(should-forms nil)
(duration 0)
)
(erts-file-tests nil)
(duration 0))
(cl-defstruct (ert-test-passed (:include ert-test-result)))
(cl-defstruct (ert-test-result-with-condition (:include ert-test-result))
(condition (cl-assert nil))
@ -867,11 +876,15 @@ Returns the result and stores it in ERT-TEST's `most-recent-result' slot."
(make-ert-test-aborted-with-non-local-exit)
:exit-continuation (lambda ()
(cl-return-from error nil))))
(should-form-accu (list)))
(should-form-accu (list))
(erts-file-test-accu (list)))
(unwind-protect
(let ((ert--should-execution-observer
(lambda (form-description)
(push form-description should-form-accu)))
(ert--erts-file-test-execution-observer
(lambda (test-description)
(push test-description erts-file-test-accu)))
(message-log-max t)
(ert--running-tests (cons ert-test ert--running-tests)))
(ert--run-test-internal info))
@ -882,9 +895,10 @@ Returns the result and stores it in ERT-TEST's `most-recent-result' slot."
(or (marker-position begin-marker) (point-min))
(point-max))))
(ert--force-message-log-buffer-truncation)
(setq should-form-accu (nreverse should-form-accu))
(setf (ert-test-result-should-forms result)
should-form-accu)
(setq should-form-accu (nreverse should-form-accu)
erts-file-test-accu (nreverse erts-file-test-accu))
(setf (ert-test-result-should-forms result) should-form-accu
(ert-test-result-erts-file-tests result) erts-file-test-accu)
(setf (ert-test-most-recent-result ert-test) result))))
(set-marker begin-marker nil))))
(ert-test-most-recent-result ert-test))
@ -2363,6 +2377,7 @@ SELECTOR; the default t means run all the defined tests."
("b" ert-results-pop-to-backtrace-for-test-at-point)
("m" ert-results-pop-to-messages-for-test-at-point)
("l" ert-results-pop-to-should-forms-for-test-at-point)
("e" ert-results-pop-to-erts-file-tests-for-test-at-point)
("h" ert-results-describe-test-at-point)
("D" ert-delete-test)
("T" ert-results-pop-to-timings)
@ -2390,6 +2405,8 @@ SELECTOR; the default t means run all the defined tests."
:active (ert--results-test-at-point-no-redefinition)]
["Show `should' forms" ert-results-pop-to-should-forms-for-test-at-point
:active (ert--results-test-at-point-no-redefinition)]
["Show tests from erts files" ert-results-pop-to-erts-file-tests-for-test-at-point
:active (ert--results-test-at-point-no-redefinition)]
["Describe test" ert-results-describe-test-at-point
:active (ert--results-test-at-point-no-redefinition)]
"--"
@ -2410,6 +2427,10 @@ SELECTOR; the default t means run all the defined tests."
'action #'ert--results-expand-collapse-button-action
'help-echo "mouse-2, RET: Expand/collapse test result")
(define-button-type 'ert--erts-file-test-name-button
'action #'ert--erts-file-test-name-button-action
'help-echo "mouse-2, RET: Find test definition in erts file")
(defun ert--results-test-node-or-null-at-point ()
"If point is on a valid ewoc node, return it; return nil otherwise.
@ -2493,6 +2514,14 @@ To be used in the ERT results buffer."
(car (button-get button 'help-args)))))
(ert-find-test-other-window name)))
(defun ert--erts-file-test-name-button-action (button)
"Find the definition in an erts file of the test BUTTON belongs to.
It creates a new window or reuses an existing one."
(let ((file (button-get button 'file))
(position (button-get button 'position)))
(find-file-other-window file)
(goto-char position)))
(defun ert--ewoc-position (ewoc node)
;; checkdoc-order: nil
"Return the position of NODE in EWOC, or nil if NODE is not in EWOC."
@ -2774,6 +2803,55 @@ To be used in the ERT results buffer."
"have been modified destructively.)\n"))
(forward-line 1)))))
(defun ert-results-pop-to-erts-file-tests-for-test-at-point ()
"Display a buffer with the tests from erts files executed by the test at point.
For tests that call `ert-test-erts-file', the list contains the tests
defined in the referenced erts files that have been executed. Tests
that were skipped are omitted. If a test fails, the list ends with the
failing test.
Each entry consists of the name of the test followed by the code that
performs the transform being tested. The buffer also contains buttons
that allow jumping to the test definitions.
To be used in the ERT results buffer. See Info node `(ert) Running
Tests Interactively' for more information about how to use this feature."
(interactive nil ert-results-mode)
(let* ((test (ert--results-test-at-point-no-redefinition t))
(stats ert--results-stats)
(pos (ert--stats-test-pos stats test))
(result (aref (ert--stats-test-results stats) pos)))
(let ((buffer (get-buffer-create "*ERT list of tests from erts files*")))
(pop-to-buffer buffer)
(let ((inhibit-read-only t))
(buffer-disable-undo)
(erase-buffer)
(ert-simple-view-mode)
(if (null (ert-test-result-erts-file-tests result))
(insert "\n(No tests from erts files executed during this test.)\n")
(cl-loop for test-description
in (ert-test-result-erts-file-tests result)
for i from 1 do
(insert (format "\n%d: " i))
(insert-text-button (cdr (assq 'name test-description))
:type 'ert--erts-file-test-name-button
'file (cdr (assq 'file test-description))
'position (cdr (assq 'position test-description)))
(insert "\n\t")
(let* ((begin (point))
(desc-code (cdr (assq 'code test-description)))
(code (if (interpreted-function-p desc-code)
(macroexp-progn (aref desc-code 1))
desc-code)))
(ert--pp-with-indentation-and-newline code)
(ert--make-xrefs-region begin (point)))))
(goto-char (point-min))
(insert (substitute-command-keys
"tests from erts files executed during test `"))
(ert-insert-test-name-button (ert-test-name test))
(insert (substitute-command-keys "':\n"))
(forward-line 1)))))
(defun ert-results-toggle-printer-limits-for-test-at-point ()
"Toggle how much of the condition to print for the test at point.
@ -2980,6 +3058,11 @@ write erts files."
(let ((code (cdr (assq 'code gen-specs))))
(unless code
(error "No code to run the transform"))
;; Record execution of test from erts file.
(ert--signal-erts-file-test-execution `((name . ,name)
(code . ,code)
(file . ,file)
(position . ,start-before)))
(funcall code))
(unless (equal (buffer-string) after)
(ert-fail (list (format "Mismatch in test \"%s\", file %s"
@ -3125,14 +3208,13 @@ The return value is the last form in BODY."
If BUFFER-OR-NAME is nil, the current buffer is used.
The buffer is made the current buffer, and the temporary window
becomes the `selected-window', before BODY is evaluated. The
modification hooks `before-change-functions' and
`after-change-functions' are not inhibited during the evaluation
of BODY, which makes it easier to use `execute-kbd-macro' to
simulate user interaction. The window configuration is restored
before returning, even if BODY exits nonlocally. The return
value is the last form in BODY."
The buffer is made the current buffer, and the temporary window becomes
the `selected-window', before BODY is evaluated. The modification hooks
`before-change-functions' and `after-change-functions' are not inhibited
during the evaluation of BODY, which makes it easier to use
`ert-play-keys' to simulate user sending input events. The window
configuration is restored before returning, even if BODY exits
nonlocally. The return value is the last form in BODY."
(declare (debug (form body)) (indent 1))
`(save-window-excursion
(with-current-buffer (or ,buffer-or-name (current-buffer))

View file

@ -302,18 +302,19 @@ TYPE should be nil to find a function, or `defvar' to find a variable."
(indirect-function
(find-function-advised-original fun-or-var)))))
(with-current-buffer (find-file-noselect file)
(goto-char (point-min))
(unless (re-search-forward
(if type
(concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\""
(regexp-quote (symbol-name fun-or-var))
"\"")
(concat "DEFUN[ \t\n]*([ \t\n]*\""
(regexp-quote (subr-name (advice--cd*r fun-or-var)))
"\""))
nil t)
(error "Can't find source for %s" fun-or-var))
(cons (current-buffer) (match-beginning 0))))
(without-restriction
(goto-char (point-min))
(unless (re-search-forward
(if type
(concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\""
(regexp-quote (symbol-name fun-or-var))
"\"")
(concat "DEFUN[ \t\n]*([ \t\n]*\""
(regexp-quote (subr-name (advice--cd*r fun-or-var)))
"\""))
nil t)
(error "Can't find source for %s" fun-or-var))
(cons (current-buffer) (match-beginning 0)))))
;;;###autoload
(defun find-library (library)

View file

@ -121,7 +121,7 @@ symbol, and each cdr is the same symbol without the `.'."
Dotted symbol is any symbol starting with a `.'. This macro creates
let-bindings for dotted symbols that appear literally in BODY (whether
or not they are actually used). It does not create bindings for dotted
symbols that are introdcued by macro-expansion in BODY.
symbols that are introduced by macro-expansion in BODY.
A symbol of the form `.foo.N' where N is a natural number refers to the
Nth element of the value that ALIST associates to key `foo'.

View file

@ -462,11 +462,10 @@ is wrapped around any parts requiring it."
The return value is a list of elements of the form (PACKAGE VERSION)
where PACKAGE is the package name (a symbol) and VERSION is the
package version (a string)."
(require 'package)
(lm-with-file file
(and-let* ((require-lines (lm-header-multiline "package-requires")))
(when-let* ((require-lines (lm-header-multiline "package-requires")))
(lm--prepare-package-dependencies
(package-read-from-string (mapconcat #'identity require-lines " "))))))
(car (read-from-string (mapconcat #'identity require-lines " ")))))))
(defun lm-package-version (&optional file)
"Return \"Package-Version\" or \"Version\" header.

View file

@ -432,10 +432,11 @@ This will generate compile-time constants from BINDINGS."
"\\(([ \t']*\\)?" ;; An opening paren.
"\\(\\(setf\\)[ \t]+" (rx lisp-mode-symbol)
"\\|" (rx lisp-mode-symbol) "\\)?")
(1 font-lock-keyword-face)
(3 (let ((type (get (intern-soft (match-string 1)) 'lisp-define-type)))
(cond ((eq type 'var) font-lock-variable-name-face)
((eq type 'type) font-lock-type-face)
(1 'font-lock-keyword-face)
(3 (let ((type (get (intern-soft (match-string 1))
'lisp-define-type)))
(cond ((eq type 'var) 'font-lock-variable-name-face)
((eq type 'type) 'font-lock-type-face)
;; If match-string 2 is non-nil, we encountered a
;; form like (defalias (intern (concat s "-p"))),
;; unless match-string 4 is also there. Then its a
@ -443,12 +444,12 @@ This will generate compile-time constants from BINDINGS."
((or (not (match-string 2)) ;; Normal defun.
(and (match-string 2) ;; Setf method.
(match-string 4)))
font-lock-function-name-face)))
'font-lock-function-name-face)))
nil t))
;; Emacs Lisp autoload cookies. Supports the slightly different
;; forms used by mh-e, calendar, etc.
(,lisp-mode-autoload-regexp (3 font-lock-warning-face prepend)
(2 font-lock-function-name-face prepend t)))
(,lisp-mode-autoload-regexp (3 'font-lock-warning-face prepend)
(2 'font-lock-function-name-face prepend t)))
"Subdued level highlighting for Emacs Lisp mode.")
(defconst lisp-cl-font-lock-keywords-1
@ -459,14 +460,15 @@ This will generate compile-time constants from BINDINGS."
"\\(([ \t']*\\)?" ;; An opening paren.
"\\(\\(setf\\)[ \t]+" (rx lisp-mode-symbol)
"\\|" (rx lisp-mode-symbol) "\\)?")
(1 font-lock-keyword-face)
(3 (let ((type (get (intern-soft (match-string 1)) 'lisp-define-type)))
(cond ((eq type 'var) font-lock-variable-name-face)
((eq type 'type) font-lock-type-face)
(1 'font-lock-keyword-face)
(3 (let ((type (get (intern-soft (match-string 1))
'lisp-define-type)))
(cond ((eq type 'var) 'font-lock-variable-name-face)
((eq type 'type) 'font-lock-type-face)
((or (not (match-string 2)) ;; Normal defun.
(and (match-string 2) ;; Setf function.
(match-string 4)))
font-lock-function-name-face)))
'font-lock-function-name-face)))
nil t)))
"Subdued level highlighting for Lisp modes.")
@ -476,17 +478,17 @@ This will generate compile-time constants from BINDINGS."
(append
lisp-el-font-lock-keywords-1
`( ;; Regexp negated char group.
("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)
("\\[\\(\\^\\)" 1 'font-lock-negation-char-face prepend)
;; Erroneous structures.
(,(concat "(" el-errs-re "\\_>")
(1 font-lock-warning-face))
(1 'font-lock-warning-face))
;; Control structures. Common Lisp forms.
(lisp--el-match-keyword . 1)
;; Exit/Feature symbols as constants.
(,(concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\_>"
"[ \t']*\\(" (rx lisp-mode-symbol) "\\)?")
(1 font-lock-keyword-face)
(2 font-lock-constant-face nil t))
(1 'font-lock-keyword-face)
(2 'font-lock-constant-face nil t))
;; Words inside \\[], \\<>, \\{} or \\`' tend to be for
;; `substitute-command-keys'.
(,(rx "\\\\" (or (seq "["
@ -495,27 +497,27 @@ This will generate compile-time constants from BINDINGS."
;; allow multiple words, e.g. "C-x a"
lisp-mode-symbol (* " " lisp-mode-symbol))
"'")))
(1 font-lock-constant-face prepend))
(1 'font-lock-constant-face prepend))
(,(rx "\\\\" (or (seq "<"
(group-n 1 (seq lisp-mode-symbol (not "\\"))) ">")
(seq "{"
(group-n 1 (seq lisp-mode-symbol (not "\\"))) "}")))
(1 font-lock-variable-name-face prepend))
(1 'font-lock-variable-name-face prepend))
;; Ineffective backslashes (typically in need of doubling).
("\\(\\\\\\)\\([^\"\\]\\)"
(1 (elisp--font-lock-backslash) prepend))
;; Words inside , '' and `' tend to be symbol names.
(,(concat "[`']\\(" (rx lisp-mode-symbol) "\\)[']")
(1 font-lock-constant-face prepend))
(1 'font-lock-constant-face prepend))
;; \\= tends to be an escape in doc strings.
(,(rx "\\\\=")
(0 font-lock-builtin-face prepend))
(0 'font-lock-builtin-face prepend))
;; Constant values.
(,(lambda (bound) (lisp-mode--search-key ":" bound))
(0 font-lock-builtin-face))
(0 'font-lock-builtin-face))
;; Elisp and Common Lisp `&' keywords as types.
(,(lambda (bound) (lisp-mode--search-key "&" bound))
(0 font-lock-type-face))
(0 'font-lock-type-face))
;; Elisp regexp grouping constructs
(,(lambda (bound)
(catch 'found
@ -546,31 +548,31 @@ This will generate compile-time constants from BINDINGS."
(append
lisp-cl-font-lock-keywords-1
`( ;; Regexp negated char group.
("\\[\\(\\^\\)" 1 font-lock-negation-char-face prepend)
("\\[\\(\\^\\)" 1 'font-lock-negation-char-face prepend)
;; Control structures. Common Lisp forms.
(,(concat "(" cl-kws-re "\\_>") . 1)
;; Exit/Feature symbols as constants.
(,(concat "(\\(catch\\|throw\\|provide\\|require\\)\\_>"
"[ \t']*\\(" (rx lisp-mode-symbol) "\\)?")
(1 font-lock-keyword-face)
(2 font-lock-constant-face nil t))
(1 'font-lock-keyword-face)
(2 'font-lock-constant-face nil t))
;; Erroneous structures.
(,(concat "(" cl-errs-re "\\_>")
(1 font-lock-warning-face))
(1 'font-lock-warning-face))
;; Words inside and `' tend to be symbol names.
(,(concat "[`]\\("
(rx (* lisp-mode-symbol (+ space)) lisp-mode-symbol)
"\\)[']")
(1 font-lock-constant-face prepend))
(1 'font-lock-constant-face prepend))
;; Uninterned symbols, e.g., (defpackage #:my-package ...)
;; must come before keywords below to have effect
(,(concat "#:" (rx lisp-mode-symbol) "") 0 font-lock-builtin-face)
(,(concat "#:" (rx lisp-mode-symbol) "") 0 'font-lock-builtin-face)
;; Constant values.
(,(lambda (bound) (lisp-mode--search-key ":" bound))
(0 font-lock-builtin-face))
(0 'font-lock-builtin-face))
;; Elisp and Common Lisp `&' keywords as types.
(,(lambda (bound) (lisp-mode--search-key "&" bound))
(0 font-lock-type-face))
(0 'font-lock-type-face))
;; Elisp regexp grouping constructs
;; This is too general -- rms.
;; A user complained that he has functions whose names start with `do'
@ -578,7 +580,7 @@ This will generate compile-time constants from BINDINGS."
;; That user has violated the https://www.cliki.net/Naming+conventions:
;; CL (but not EL!) `with-' (context) and `do-' (iteration)
(,(concat "(\\(\\(do-\\|with-\\)" (rx lisp-mode-symbol) "\\)")
(1 font-lock-keyword-face))
(1 'font-lock-keyword-face))
(lisp--match-hidden-arg
(0 '(face font-lock-warning-face
help-echo "Easy to misread; consider moving the element to the next line")

View file

@ -143,23 +143,6 @@ scanning for autoloads and will be in the `load-path'."
3)
form))
;; The following macros are known to define functions, and are treated
;; specially when encountered during autoload generation, translating
;; calls to them directly into appropriate (autoload function ...)
;; forms.
;;
;; An alternative to appearing on this list is for a macro to declare
;; (autoload-macro expand), so calls to it get expanded into more basic
;; forms during generation. Macros may be removed from this list once
;; they request such expansion and produce suitable output (e.g. by
;; employing :autoload-end to omit unneeded forms).
(defconst loaddefs--defining-macros
'( transient-define-prefix transient-define-suffix transient-define-infix
transient-define-argument
;; FIXME: How can this one make sense? It doesn't put anything
;; into `symbol-function'!
transient-define-group))
(defvar loaddefs--load-error-files nil)
(defun loaddefs-generate--make-autoload (form file &optional expansion)
"Turn FORM into an autoload or defvar for source file FILE.
@ -175,6 +158,7 @@ expand)' among their `declare' forms."
((and expansion (eq car 'defalias))
(pcase-let*
((`(,_ ,_ ,arg . ,rest) form)
(arg (macroexpand arg))
;; `type' is non-nil if it defines a macro.
;; `fun' is the function part of `arg' (defaults to `arg').
((or (and (or `(cons 'macro ,fun) `'(macro . ,fun)) (let type t))
@ -225,7 +209,6 @@ expand)' among their `declare' forms."
;; give packages a chance to define their macros.
(unless (or (not (symbolp car)) (fboundp car)
;; Special cases handled below
(memq car loaddefs--defining-macros)
(memq car '(defclass defcustom deftheme defgroup nil))
(assoc file load-history)
(member file loaddefs--load-error-files))
@ -238,7 +221,7 @@ expand)' among their `declare' forms."
(load file))
(error
(push file loaddefs--load-error-files) ; do not attempt again
(warn "loaddefs-gen: load error\n\t%s" e)))))
(warn "loaddefs-gen: load error\n\t%S" e)))))
(and (macrop car)
(eq 'expand (function-get car 'autoload-macro 'macro))
(setq expand (let ((load-true-file-name file)
@ -248,21 +231,6 @@ expand)' among their `declare' forms."
;; Recurse on the expansion.
(loaddefs-generate--make-autoload expand file 'expansion))
;; For known special macros which define functions, use `autoload'
;; directly.
((memq car loaddefs--defining-macros)
(let* ((name (nth 1 form))
(args (nth 2 form))
(body (nthcdr (or (function-get car 'doc-string-elt) 3) form))
(doc (if (stringp (car body)) (pop body))))
;; Add the usage form at the end where describe-function-1
;; can recover it.
(when (listp args) (setq doc (help-add-fundoc-usage doc args)))
;; `define-generic-mode' quotes the name, so take care of that
(loaddefs-generate--shorten-autoload
`(autoload ,(if (listp name) name (list 'quote name))
,file ,doc t))))
;; For defclass forms, use `eieio-defclass-autoload'.
((eq car 'defclass)
(let ((name (nth 1 form))

View file

@ -175,15 +175,26 @@ or array."
,v)))))))))))
(cl-defmethod map-elt ((map list) key &optional default testfn)
"Implementation of `map-elt' for maps that are alists or plists.
In a map that is a plist, property names are the keys, and the
corresponding property values are the values of those keys.
In a map that is an alist, the `car' of each cons cell is the key
and the `cdr' is the value."
(if (map--plist-p map)
(let ((res (map--plist-member map key testfn)))
(if res (cadr res) default))
(alist-get key map default nil (or testfn #'equal))))
(cl-defmethod map-elt ((map hash-table) key &optional default _testfn)
"Implementation of `map-elt' for maps that are hash-tables.
In a map that is a hash-table, the keys in the table serve as the map
keys and the associated values are the key values."
(gethash key map default))
(cl-defmethod map-elt ((map array) key &optional default _testfn)
"Implementation of `map-elt' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values."
(if (map-contains-key map key)
(aref map key)
default))
@ -234,6 +245,13 @@ say
for this to work reliably.")
(cl-defmethod map-delete ((map list) key)
"Implementation of `map-delete' for maps that are plists or alists.
In a map that is a plist, property names are the keys, and the
corresponding property values are the values of those keys; this
function removes the pair whose property-name matches KEY.
In a map that is an alist, the `car' of each cons cell is the key
and the `cdr' is the value; this function removes the cons cell
whose `car' equals KEY."
;; FIXME: Signal map-not-inplace i.s.o returning a different list?
(if (map--plist-p map)
(map--plist-delete map key)
@ -241,11 +259,18 @@ for this to work reliably.")
map))
(cl-defmethod map-delete ((map hash-table) key)
"Implementation of `map-delete' for maps that are hash-tables.
In a map that is a hash-table, the keys in the table serve as the map
keys and the associated values are the key values.
Calls `remhash' to remove KEY."
(remhash key map)
map)
(cl-defmethod map-delete ((map array) key)
"Store nil at index KEY."
"Implementation of `map-delete' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
Since array slots cannot be removed, this stores nil at index KEY."
(when (map-contains-key map key)
(aset map key nil))
map)
@ -273,7 +298,10 @@ The default implementation delegates to `map-apply'."
(map-apply (lambda (_ value) value) map))
(cl-defmethod map-values ((map array))
"Convert MAP into a list."
"Implementation of `map-values' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
This creates a list from MAP's slot values."
(append map ()))
(cl-defgeneric map-pairs (map)
@ -291,29 +319,45 @@ The default implementation delegates to `map-do'."
size))
(cl-defmethod map-length ((map hash-table))
"Implementation of `map-length' for maps that are hash-tables.
Value is the number of elements in MAP."
(hash-table-count map))
(cl-defmethod map-length ((map list))
"Implementation of `map-length' for maps that are plists or alists.
Value is the number of property-value pairs for plists and the number
of association cons cells in an alist."
(if (map--plist-p map)
(/ (length map) 2)
(length map)))
(cl-defmethod map-length ((map array))
"Implementation of `map-length' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
Value is the number of slots in MAP."
(length map))
(cl-defgeneric map-copy (map)
"Return a copy of MAP.")
(cl-defmethod map-copy ((map list))
"Use `copy-alist' on alists and `copy-sequence' on plists."
"Implementation of `map-copy' for maps that are plists or alists.
Uses `copy-alist' on alists and `copy-sequence' on plists."
(if (map--plist-p map)
(copy-sequence map)
(copy-alist map)))
(cl-defmethod map-copy ((map hash-table))
"Implementation of `map-copy' for maps that are hash-tables.
Returns a copy of MAP produced by `copy-hash-table'."
(copy-hash-table map))
(cl-defmethod map-copy ((map array))
"Implementation of `map-copy' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
Uses `copy-sequence'."
(copy-sequence map))
(cl-defgeneric map-apply (function map)
@ -326,10 +370,15 @@ The default implementation delegates to `map-do'."
(cl-defgeneric map-do (function map)
"Apply FUNCTION to each element of MAP and return nil.
FUNCTION is called with two arguments, the key and the value.")
FUNCTION is called with two arguments, the key and the value
of each MAP's element.")
;; FIXME: I wish there was a way to avoid this η-redex!
(cl-defmethod map-do (function (map hash-table)) (maphash function map))
(cl-defmethod map-do (function (map hash-table))
"Implementation of `map-do' for maps that are hash-tables.
Calls `maphash', which will call FUNCTION with key and value
of each element of MAP."
(maphash function map))
(cl-defgeneric map-keys-apply (function map)
"Return the result of applying FUNCTION to each key in MAP.
@ -346,6 +395,10 @@ The default implementation delegates to `map-apply'."
map))
(cl-defmethod map-values-apply (function (map array))
"Implementation of `map-values-apply' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
Calls `mapcar', which will call FUNCTION with each element of MAP."
(mapcar function map))
(cl-defgeneric map-filter (pred map)
@ -376,6 +429,8 @@ The default implementation delegates to `map-length'."
(zerop (map-length map)))
(cl-defmethod map-empty-p ((map list))
"Implementation of `map-empty-p' for maps that are plists or alists.
MAP is empty if `null' returns non-nil for it."
(null map))
(cl-defgeneric map-contains-key (map key &optional testfn)
@ -391,20 +446,30 @@ The default implementation delegates to `map-some'."
(map-some (lambda (k _v) (funcall testfn key k)) map))
(cl-defmethod map-contains-key ((map list) key &optional testfn)
"Return non-nil if MAP contains KEY.
"Implementation of `map-contains-key' for maps that are plists or alists.
If MAP is an alist, TESTFN defaults to `equal'.
If MAP is a plist, TESTFN defaults to `eq'."
If MAP is a plist, TESTFN defaults to `eq'.
In a map that is a plist, property names are the keys, and the
corresponding property values are the values of those keys.
In a map that is an alist, the `car' of each cons cell is the key
and the `cdr' is the value."
(if (map--plist-p map)
(map--plist-member map key testfn)
(let ((v '(nil)))
(not (eq v (alist-get key map v nil (or testfn #'equal)))))))
(cl-defmethod map-contains-key ((map array) key &optional _testfn)
"Return non-nil if KEY is an index of MAP, ignoring TESTFN."
"Implementation of `map-contains-key' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
Returns non-nil if KEY is a valid index in MAP, ignoring TESTFN."
(and (natnump key) (< key (length map))))
(cl-defmethod map-contains-key ((map hash-table) key &optional _testfn)
"Return non-nil if MAP contains KEY, ignoring TESTFN."
"Implementation of `map-contains-key' for maps that are hash-tables.
Returns non-nil if MAP contains KEY, ignoring TESTFN.
In a map that is a hash-table, the keys in the table serve as the map
keys and the associated values are the key values."
;; FIXME: use `hash-table-contains-p' from Compat when available.
(if (fboundp 'hash-table-contains-p)
(hash-table-contains-p key map)
@ -494,15 +559,21 @@ This does not modify any of the MAPS."
;; FIXME: I wish there was a way to avoid this η-redex!
(cl-defmethod map-into (map (_type (eql list)))
"Convert MAP into an alist."
"Implementation of `map-into' for TYPE that is list.
Convert MAP into an alist."
(map-pairs map))
(cl-defmethod map-into (map (_type (eql alist)))
"Convert MAP into an alist."
"Implementation of `map-into' for TYPE that is alist.
Convert MAP into an alist, with the `car' of each
association cons cell serving as keys and the `cdr' as
values."
(map-pairs map))
(cl-defmethod map-into (map (_type (eql plist)))
"Convert MAP into a plist."
"Implementation of `map-into' for TYPE that is plist.
Convert MAP into a plist, with property names serving as keys
and property values as values."
(let (plist)
(map-do (lambda (k v) (setq plist `(,v ,k ,@plist))) map)
(nreverse plist)))
@ -518,6 +589,11 @@ To insert an element without modifying MAP, use `map-insert'."
(declare (advertised-calling-convention (map key value) "27.1")))
(cl-defmethod map-put! ((map list) key value &optional testfn)
"Implementation of `map-put!' for maps that are plists or alists.
In a map that is a plist, property names are the keys, and the
corresponding property values are the values of those keys.
In a map that is an alist, the `car' of each cons cell is the key
and the `cdr' is the value."
(if (map--plist-p map)
(map--plist-put map key value testfn)
(let ((oldmap map))
@ -528,9 +604,16 @@ To insert an element without modifying MAP, use `map-insert'."
value)
(cl-defmethod map-put! ((map hash-table) key value &optional _testfn)
"Implementation of `map-put!' for maps that are hash-tables.
In a map that is a hash-table, the keys in the table serve as the map
keys and the associated values are the key values."
(puthash key value map))
(cl-defmethod map-put! ((map array) key value &optional _testfn)
"Implementation of `map-put!' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
Calls `aset'."
;; FIXME: If `key' is too large, should we signal `map-not-inplace'
;; and let `map-insert' grow the array?
(aset map key value))
@ -550,12 +633,22 @@ The default implementation defaults to `map-copy' and `map-put!'."
copy))
(cl-defmethod map-insert ((map list) key value)
"Cons KEY and VALUE to the front of MAP."
"Implementation of `map-insert' for maps that are plists or alists.
Cons KEY and VALUE to the front of MAP. If MAP is a plist, KEY and VALUE
will be the property name and its value, If MAP is an alist, KEY and
VALUE will be the `car' and `cdr' of the association cons cell."
(if (map--plist-p map)
(cons key (cons value map))
(cons (cons key value) map)))
(cl-defmethod map-apply (function (map list))
"Implementation of `map-apply' for maps that are plists or alists.
In a map that is a plist, property names are the keys, and the
corresponding property values are the values of those keys.
In a map that is an alist, the `car' of each cons cell is the key
and the `cdr' is the value.
Calls `mapcar', which will call FUNCTION for each element in MAP,
passing the element's key and its value as arguments of FUNCTION."
(if (map--plist-p map)
(cl-call-next-method)
(mapcar (lambda (pair)
@ -563,6 +656,9 @@ The default implementation defaults to `map-copy' and `map-put!'."
map)))
(cl-defmethod map-apply (function (map hash-table))
"Implementation of `map-apply' for maps that are hash-tables.
Calls `maphash', which will call FUNCTION for each element in MAP,
passing the element's key and its value as arguments of FUNCTION."
(let (result)
(maphash (lambda (key value)
(push (funcall function key value) result))
@ -570,11 +666,23 @@ The default implementation defaults to `map-copy' and `map-put!'."
(nreverse result)))
(cl-defmethod map-apply (function (map array))
"Implementation of `map-apply' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
FUNCTION will be called for each element of MAP with the
index of the element and the element itself as arguments."
(seq-map-indexed (lambda (elt index)
(funcall function index elt))
map))
(cl-defmethod map-do (function (map list))
"Implementation of `map-do' for maps that are plists or alists.
In a map that is a plist, property names are the keys, and the
corresponding property values are the values of those keys.
In a map that is an alist, the `car' of each cons cell is the key
and the `cdr' is the value.
FUNCTION's arguments are property name and property value for plist
elements, `car' and `cdr' of association cons cell for alists."
(if (map--plist-p map)
(while map
(funcall function (pop map) (pop map)))
@ -584,6 +692,11 @@ The default implementation defaults to `map-copy' and `map-put!'."
nil))
(cl-defmethod map-do (function (map array))
"Implementation of `map-do' for maps that are arrays.
In a map that is an array, the keys are the slot indices,
and slot contents are the values.
FUNCTION's arguments are the index of the element and the
element itself."
(seq-do-indexed (lambda (elt index)
(funcall function index elt))
map))
@ -598,11 +711,13 @@ KEYWORD-ARGS are forwarded to `make-hash-table'."
ht))
(cl-defmethod map-into (map (_type (eql hash-table)))
"Convert MAP into a hash-table with keys compared with `equal'."
"Implementation of `map-into' for TYPE that is hash-table.
Convert MAP into a hash-table with keys compared with `equal'."
(map--into-hash map (list :size (map-length map) :test #'equal)))
(cl-defmethod map-into (map (type (head hash-table)))
"Convert MAP into a hash-table.
"Implementation of `map-into' for TYPE that is hash-table with keywords.
Convert MAP into a hash-table.
TYPE is a list whose car is `hash-table' and cdr a list of
keyword-args forwarded to `make-hash-table'.

View file

@ -74,7 +74,8 @@
(:before-until (or (apply car r) (apply cdr r)))
(:before-while (and (apply car r) (apply cdr r)))
(:filter-args (apply cdr (funcall car r)))
(:filter-return (funcall car (apply cdr r))))
(:filter-return (funcall car (apply cdr r)))
(:interactive-only (apply cdr r)))
"List of descriptions of how to add a function.
Each element has the form (HOW OCL DOC) where HOW is a keyword,
OCL is a \"prototype\" function of type `advice', and

View file

@ -431,7 +431,6 @@ Newer versions are always activated, regardless of FORCE."
"Non-nil if `package-activate-all' has been run.")
;;;###autoload
(progn ;; Make the function usable without loading `package.el'.
(defun package-activate-all ()
"Activate all installed packages.
The variable `package-load-list' controls which packages to load."
@ -452,15 +451,13 @@ The variable `package-load-list' controls which packages to load."
(setq package-activated-list nil))
(load qs nil 'nomessage)
t)))
(progn
(require 'package)
;; Silence the "unknown function" warning when this is compiled
;; inside `loaddefs.el'.
;; FIXME: We use `with-no-warnings' because the effect of
;; `declare-function' is currently not scoped, so if we use
;; it here, we end up with a redefinition warning instead :-)
(with-no-warnings
(package--activate-all)))))))
;; Silence the "unknown function" warning when this is compiled
;; inside `loaddefs.el'.
;; FIXME: We use `with-no-warnings' because the effect of
;; `declare-function' is currently not scoped, so if we use
;; it here, we end up with a redefinition warning instead :-)
(with-no-warnings
(package--activate-all)))))
(defun package--activate-all ()
(dolist (elt (package--alist))

Some files were not shown because too many files have changed in this diff Show more