Compare commits

..

1 commit

Author SHA1 Message Date
João Távora
a603aa48a5 Breadcrumb: first stab, very slow
* lisp/progmodes/breadcrumb.el: New file
2023-04-08 00:40:12 +01:00
314 changed files with 4194 additions and 129040 deletions

View file

@ -21,9 +21,6 @@
(electric-quote-comment . nil)
(electric-quote-string . nil)
(mode . bug-reference-prog)))
(c-ts-mode . ((c-ts-mode-indent-style . gnu)
(indent-tabs-mode . t)
(mode . bug-reference-prog)))
(log-edit-mode . ((log-edit-font-lock-gnu-style . t)
(log-edit-setup-add-author . t)
(vc-git-log-edit-summary-target-len . 50)))

View file

@ -321,7 +321,7 @@ them right the first time, so here are guidelines for formatting them:
** Committing your changes.
When you commit changes, Git invokes several scripts that test the
commit for validity, and may abort the commit if some of the tests
commit for validity, and may abort the commit of some of the tests
fail. These scripts live in the '.git/hooks/' subdirectory of the
top-level directory of the repository, and they perform the following
tests:

114348
ChangeLog.4

File diff suppressed because it is too large Load diff

View file

@ -417,9 +417,9 @@ advice-on-failure:
sanity-check:
@[ -f .no-advice-on-failure ] && exit 0; true
@v=`src/emacs${EXEEXT} --batch --eval \
@v=$$(src/emacs${EXEEXT} --batch --eval \
'(progn (defun f (n) (if (= 0 n) 1 (* n (f (- n 1))))) (princ (f 10)))' \
2> /dev/null`; \
2> /dev/null); \
[ "X$$v" = "X3628800" ] && exit 0; \
echo >&2 '***'; \
echo >&2 '*** '"\"make ${make-target}\" succeeded, but Emacs is not functional."; \
@ -1030,9 +1030,6 @@ $(foreach dir,$(distclean_dirs),$(eval $(call submake_template,$(dir),distclean)
distclean: $(distclean_dirs:=_distclean) clean-gsettings-schemas
${top_distclean}
ifeq ($(HAVE_NATIVE_COMP),yes)
rm -rf native-lisp
endif
### 'bootstrap-clean'
### Delete everything that can be reconstructed by 'make' and that
@ -1287,7 +1284,7 @@ PREFERRED_BRANCH = emacs-28
preferred-branch-is-current:
git branch | grep -q '^\* $(PREFERRED_BRANCH)$$'
unchanged-history-files:
x=`git diff-files --name-only $(CHANGELOG_N) $(emacslog)` && \
x=$$(git diff-files --name-only $(CHANGELOG_N) $(emacslog)) && \
test -z "$$x"
# Regular expression that matches the newest commit covered by a ChangeLog.

View file

@ -182,7 +182,7 @@ files.")
("Philip Kaludercic" "Philip K\\." "Philip K")
("Philipp Stephani" "Philipp .*phst@google")
("Piotr Zieliński" "Piotr Zielinski")
("Po Lu" "Po Lu Via" "Your Name") ; looks like a mistake
("Po Lu" "Po Lu Via") ; looks like a mistake
("Przemysław Wojnowski" "Przemyslaw Wojnowski")
("R. Bernstein" "rb@dustyfeet.com")
("Rainer Schöpf" "Rainer Schoepf")

View file

@ -181,7 +181,7 @@ ${charsetdir}/GB180304.map: ${charsetdir}/GB180302.map ${gb180304}
${AM_V_GEN}$(AWK) -f ${gb180304} < $< > $@
${charsetdir}/JISX0201.map: ${GLIBC_CHARMAPS}/JIS_X0201.gz ${mapconv} ${compact}
${AM_V_GEN}(${run_mapconv} $< '/^<.*[ ]\/x[0-9]/' GLIBC-1 ${compact} && \
${AM_V_GEN}(${mapconv} $< '/^<.*[ ]\/x[0-9]/' GLIBC-1 ${compact} && \
echo "# Generated by hand" && \
echo "0xA1-0xDF 0xFF61" ) > $@

View file

@ -38,8 +38,7 @@
## So that eg [A-F] as used by KANJI-DATABASE branch below works as expected.
## Otherwise with LANG=en_US.utf8, CNS-6.map was generated with a
## bogus entry. By experiment, LC_COLLATE=C was not enough.
LC_ALL=C
export LC_ALL
export LC_ALL=C
BASE=`expr "$1" : '.*/\(.*\)' '|' "$1"` # basename
FILE="admin/charsets/mapfiles/$BASE"

View file

@ -68,25 +68,16 @@ General steps (for each step, check for possible errors):
PREFERRED_BRANCH = emacs-NN
where NN is the version on the release branch from which you are
producing the tarball. If NN is incorrect (which it usually is
when starting a pretest of a new major release), update
Makefile.in and re-run 'configure' to update Makefile.
producing the tarball. If NN is incorrect, update Makefile.in and
re-run 'configure' to update Makefile.
For the first pretest of a new major release, consider starting a
new top-level ChangeLog.N file if the last versioned ChangeLog.N
file is too large. A good point to start a new ChangeLog.N file
is when the last one gets larger than 1.5 MiB. If so, start a new
one by bumping N, and also update the line in top-level
Makefile.in which says
If the versioned ChangeLog.N file is too large, start a new one
by bumping N, and also update the line in top-level Makefile.in
which says
CHANGELOG_HISTORY_INDEX_MAX = N
by incrementing the value of N by 1; then regenerate Makefile.
After bumping N, you need to actually create and commit
ChangeLog.N with the updated N, otherwise "M-x authors" below will
fail. The easiest way of creating the new ChangeLog.N is to
rename the file ChangeLog (without the .N suffix) left over from
the last major release (it is usually unversioned) and commit it.
Now:
@ -108,12 +99,11 @@ General steps (for each step, check for possible errors):
the relevant entry. If a file was deleted or renamed, consider
adding an appropriate entry to variables authors-ignored-files,
authors-valid-file-names, or authors-renamed-files-alist in
authors.el. If some authors are "ignored", consider adding
entries to the author-aliases variable.
authors.el.
If necessary, repeat 'C-u M-x authors' after making those changes.
Save the "*Authors*" buffer as etc/AUTHORS.
Check the diff looks reasonable. Maybe add more entries to
Check the diff looks reasonable. Maybe add entries to
authors-ambiguous-files or authors-aliases, and repeat.
Commit any fixes to authors.el.
@ -179,13 +169,7 @@ General steps (for each step, check for possible errors):
messages from TeX, but those seem to be harmless, as the result
looks just fine.)
5. Copy lisp/loaddefs.el to lisp/ldefs-boot.el. After copying, edit
ldefs-boot.el to add
;; no-byte-compile: t
to its file-local variables section, otherwise make-dist will
complain.
5. Copy lisp/loaddefs.el to lisp/ldefs-boot.el.
Commit ChangeLog.N, etc/AUTHORS, lisp/ldefs-boot.el, and the files
changed by M-x set-version. Note that the set-version changes

View file

@ -340,8 +340,7 @@ git_config diff.texinfo.xfuncname \
tailored_hooks=
sample_hooks=
for hook in commit-msg pre-commit prepare-commit-msg post-commit \
pre-push commit-msg-files.awk; do
for hook in commit-msg pre-commit prepare-commit-msg; do
cmp -- build-aux/git-hooks/$hook "$hooks/$hook" >/dev/null 2>&1 ||
tailored_hooks="$tailored_hooks $hook"
done

View file

@ -1,128 +0,0 @@
# Check the file list of GNU Emacs change log entries for each commit SHA.
# Copyright 2023 Free Software Foundation, Inc.
# This file is part of GNU Emacs.
# GNU Emacs is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# GNU Emacs is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
### Commentary:
# This script accepts a list of (unabbreviated) Git commit SHAs, and
# will then iterate over them to check that any files mentioned in the
# commit message are actually present in the commit's diff. If not,
# it will print out the incorrect file names and return 1.
# You can also pass "-v reason=pre-push", which will add more-verbose
# output, indicating the abbreviated commit SHA and first line of the
# commit message for any improper commits.
### Code:
function get_commit_changes(commit_sha, changes, cmd, i, j, len, \
bits, filename) {
# Collect all the files touched in the specified commit.
cmd = ("git show --name-status --first-parent --format= " commit_sha)
while ((cmd | getline) > 0) {
for (i = 2; i <= NF; i++) {
len = split($i, bits, "/")
for (j = 1; j <= len; j++) {
if (j == 1)
filename = bits[j]
else
filename = filename "/" bits[j]
changes[filename] = 1
}
}
}
close(cmd)
}
function check_commit_msg_files(commit_sha, verbose, changes, good, \
cmd, msg, filenames_str, filenames, i) {
get_commit_changes(commit_sha, changes)
good = 1
cmd = ("git log -1 --format=%B " commit_sha)
while ((cmd | getline) > 0) {
if (verbose && ! msg)
msg = $0
# Find file entries in the commit message. We look at any line
# starting with "*" (possibly prefixed by "; ") followed by a ":",
# possibly on a different line. If we encounter a blank line
# without seeing a ":", then we don't treat that as a file entry.
# Accumulate the contents of a (possible) file entry.
if (/^[ \t]*$/)
filenames_str = ""
else if (/^(; )?\*[ \t]+[[:alnum:]]/)
filenames_str = $0
else if (filenames_str)
filenames_str = (filenames_str $0)
# We have a file entry; analyze it.
if (filenames_str && /:/) {
# Delete the leading "*" and any trailing information.
sub(/^(; )?\*[ \t]+/, "", filenames_str)
sub(/[ \t]*[[(<:].*$/, "", filenames_str)
# There might be multiple files listed in this entry, separated
# by spaces (and possibly a comma). Iterate over each of them.
split(filenames_str, filenames, ",[ \t]+")
for (i in filenames) {
# Remove trailing slashes from any directory entries.
sub(/\/$/, "", filenames[i])
if (length(filenames[i]) && ! (filenames[i] in changes)) {
if (good) {
# Print a header describing the error.
if (verbose)
printf("In commit %s \"%s\"...\n", substr(commit_sha, 1, 10), msg)
printf("Files listed in commit message, but not in diff:\n")
}
printf(" %s\n", filenames[i])
good = 0
}
}
filenames_str = ""
}
}
close(cmd)
return good
}
BEGIN {
if (reason == "pre-push")
verbose = 1
}
/^[a-z0-9]{40}$/ {
if (! check_commit_msg_files($0, verbose)) {
status = 1
}
}
END {
if (status != 0) {
if (reason == "pre-push")
error_msg = "Push aborted"
else
error_msg = "Bad commit message"
printf("%s; please see the file 'CONTRIBUTE'\n", error_msg)
}
exit status
}

View file

@ -1,47 +0,0 @@
#!/bin/sh
# Check the file list of GNU Emacs change log entries after committing.
# Copyright 2023 Free Software Foundation, Inc.
# This file is part of GNU Emacs.
# GNU Emacs is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# GNU Emacs is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
### Commentary:
# This hook runs after a commit is finalized and checks that the files
# mentioned in the commit message match the diff. We perform this in
# the post-commit phase so that we can be sure we properly detect all
# the files in the diff (this is difficult during the commit-msg hook,
# since there's no cross-platform way to detect when a commit is being
# amended).
# However, since this is a post-commit hook, it's too late to error
# out and abort the commit: it's already done! As a result, this hook
# is purely advisory, and instead we error out when trying to push
# (see "pre-push" in this directory).
### Code:
HOOKS_DIR=`dirname "$0"`
# Prefer gawk if available, as it handles NUL bytes properly.
if type gawk >/dev/null 2>&1; then
awk="gawk"
else
awk="awk"
fi
git rev-parse HEAD | $awk -v reason=post-commit \
-f "$HOOKS_DIR"/commit-msg-files.awk

View file

@ -1,88 +0,0 @@
#!/bin/sh
# Check the file list of GNU Emacs change log entries before pushing.
# Copyright 2023 Free Software Foundation, Inc.
# This file is part of GNU Emacs.
# GNU Emacs is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# GNU Emacs is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
### Commentary:
# This hook runs before pushing a series of commits and checks that
# the files mentioned in each commit message match the diffs. This
# helps ensure that the resulting change logs are correct, which
# should prevent errors when generating etc/AUTHORS.
# These checks also happen in the "post-commit" hook (which see), but
# that hook can't abort a commit; it just advises the committer to fix
# the commit so that this hook runs without errors.
### Code:
HOOKS_DIR=`dirname "$0"`
# Prefer gawk if available, as it handles NUL bytes properly.
if type gawk >/dev/null 2>&1; then
awk="gawk"
else
awk="awk"
fi
# Standard input receives lines of the form:
# <local ref> SP <local sha> SP <remote ref> SP <remote sha> LF
$awk -v origin_name="$1" '
# If the local SHA is all zeroes, ignore it.
$2 ~ /^0{40}$/ {
next
}
# Check any lines with a valid local SHA and whose remote ref is
# master or an emacs-NN release branch. (We want to avoid checking
# feature or scratch branches here.)
$2 ~ /^[a-z0-9]{40}$/ && $3 ~ /^refs\/heads\/(master|emacs-[0-9]+)$/ {
newref = $2
# If the remote SHA is all zeroes, this is a new object to be
# pushed (likely a branch)...
if ($4 ~ /^0{40}$/) {
back = 0
# ... Go backwards until we find a SHA on an origin branch.
# Stop trying after 1000 commits, just in case...
for (back = 0; back < 1000; back++) {
cmd = ("git branch -r -l '\''" origin_name "/*'\''" \
" --contains " newref "~" back)
rv = (cmd | getline)
close(cmd)
if (rv > 0)
break;
}
cmd = ("git rev-parse " newref "~" back)
cmd | getline oldref
if (!(oldref ~ /^[a-z0-9]{40}$/)) {
# The SHA is misformatted! Skip this line.
next
}
close(cmd)
} else if ($4 ~ /^[a-z0-9]{40}$/) {
oldref = $4
} else {
# The SHA is misformatted! Skip this line.
next
}
# Print every SHA after oldref, up to (and including) newref.
system("git rev-list --first-parent --reverse " oldref ".." newref)
}
' | $awk -v reason=pre-push -f "$HOOKS_DIR"/commit-msg-files.awk

View file

@ -1001,7 +1001,7 @@ AC_ARG_ENABLE([gcc-warnings],
# however, if there is also a .tarball-version file it is probably
# just a release imported into Git for patch management.
gl_gcc_warnings=no
if test -d "$srcdir"/.git && test ! -f "$srcdir"/.tarball-version; then
if test -e "$srcdir"/.git && test ! -f "$srcdir"/.tarball-version; then
# Clang typically identifies itself as GCC 4.2 or something similar
# even if it is recent enough to accept the warnings we enable.
AS_IF([test "$emacs_cv_clang" = yes],
@ -1643,8 +1643,7 @@ case "$opsys" in
## Motif needs -lgen.
unixware) LIBS_SYSTEM="-lsocket -lnsl -lelf -lgen" ;;
# Haiku needs -lbsd for cfsetspeed.
haiku) LIBS_SYSTEM="-lnetwork -lbsd" ;;
haiku) LIBS_SYSTEM="-lnetwork" ;;
esac
AC_SUBST([LIBS_SYSTEM])
@ -2034,23 +2033,31 @@ if test "${with_ns}" != no; then
ns_appresdir=${ns_appdir}/Contents/Resources
ns_appsrc=Cocoa/Emacs.base
ns_fontfile=macfont.o
elif flags=`(gnustep-config --objc-flags) 2>/dev/null`; then
elif flags=$( (gnustep-config --objc-flags) 2>/dev/null); then
NS_IMPL_GNUSTEP=yes
NS_GNUSTEP_CONFIG=yes
GNU_OBJC_CFLAGS="$flags"
LIBS_GNUSTEP=`gnustep-config --gui-libs || exit`
LIBS_GNUSTEP=$(gnustep-config --gui-libs) || exit
elif test -f $GNUSTEP_CONFIG_FILE; then
NS_IMPL_GNUSTEP=yes
dnl FIXME sourcing this several times in subshells seems inefficient.
GNUSTEP_SYSTEM_HEADERS=`. $GNUSTEP_CONFIG_FILE \
&& AS_ECHO(["$GNUSTEP_SYSTEM_HEADERS"])`
GNUSTEP_SYSTEM_LIBRARIES=` . $GNUSTEP_CONFIG_FILE \
&& AS_ECHO(["$GNUSTEP_SYSTEM_LIBRARIES"])`
GNUSTEP_SYSTEM_HEADERS=$(
. $GNUSTEP_CONFIG_FILE
AS_ECHO(["$GNUSTEP_SYSTEM_HEADERS"])
)
GNUSTEP_SYSTEM_LIBRARIES=$(
. $GNUSTEP_CONFIG_FILE
AS_ECHO(["$GNUSTEP_SYSTEM_LIBRARIES"])
)
dnl I seemed to need these as well with GNUstep-startup 0.25.
GNUSTEP_LOCAL_HEADERS=`. $GNUSTEP_CONFIG_FILE \
&& AS_ECHO(["$GNUSTEP_LOCAL_HEADERS"])`
GNUSTEP_LOCAL_LIBRARIES=`. $GNUSTEP_CONFIG_FILE \
&& AS_ECHO(["$GNUSTEP_LOCAL_LIBRARIES"])`
GNUSTEP_LOCAL_HEADERS=$(
. $GNUSTEP_CONFIG_FILE
AS_ECHO(["$GNUSTEP_LOCAL_HEADERS"])
)
GNUSTEP_LOCAL_LIBRARIES=$(
. $GNUSTEP_CONFIG_FILE
AS_ECHO(["$GNUSTEP_LOCAL_LIBRARIES"])
)
test "x${GNUSTEP_LOCAL_HEADERS}" != "x" && \
GNUSTEP_LOCAL_HEADERS="-I${GNUSTEP_LOCAL_HEADERS}"
test "x${GNUSTEP_LOCAL_LIBRARIES}" != "x" && \
@ -3773,7 +3780,7 @@ if test "${HAVE_X11}" = "yes"; then
AC_DEFINE([HAVE_OTF_GET_VARIATION_GLYPHS], [1],
[Define to 1 if libotf has OTF_get_variation_glyphs.])
fi
if $PKG_CONFIG --atleast-version=0.9.16 libotf; then :; else
if ! $PKG_CONFIG --atleast-version=0.9.16 libotf; then
AC_DEFINE([HAVE_OTF_KANNADA_BUG], [1],
[Define to 1 if libotf is affected by https://debbugs.gnu.org/28110.])
fi
@ -3881,7 +3888,7 @@ if test "${HAVE_BE_APP}" = "yes"; then
AC_DEFINE([HAVE_OTF_GET_VARIATION_GLYPHS], [1],
[Define to 1 if libotf has OTF_get_variation_glyphs.])
fi
if $PKG_CONFIG --atleast-version=0.9.16 libotf; then :; else
if ! $PKG_CONFIG --atleast-version=0.9.16 libotf; then
AC_DEFINE([HAVE_OTF_KANNADA_BUG], [1],
[Define to 1 if libotf is affected by https://debbugs.gnu.org/28110.])
fi
@ -4199,7 +4206,7 @@ module_env_snippet_27="$srcdir/src/module-env-27.h"
module_env_snippet_28="$srcdir/src/module-env-28.h"
module_env_snippet_29="$srcdir/src/module-env-29.h"
module_env_snippet_30="$srcdir/src/module-env-30.h"
emacs_major_version=`AS_ECHO([$PACKAGE_VERSION]) | sed 's/[[.]].*//'`
emacs_major_version="${PACKAGE_VERSION%%.*}"
AC_SUBST([emacs_major_version])
### Emacs Lisp native compiler support
@ -4309,16 +4316,14 @@ if test "${with_native_compilation}" != "no"; then
# available. (We filter out the gcc4 packages, because they
# don't support jit, and they have names like "gcc49" that
# sort later than "gcc11".)
PORT_PACKAGE=`port installed active | grep '^ *gcc@<:@0-9@:>@* ' | \
PORT_PACKAGE=$(port installed active | grep '^ *gcc@<:@0-9@:>@* ' | \
awk '{ print $1; }' | grep -v 'gcc4@<:@0-9@:>@' | \
sort -V | tail -n 1`
sort -V | tail -n 1)
if test -n "$PORT_PACKAGE"; then
emacs_val=`port contents $PORT_PACKAGE | grep libgccjit.h`
emacs_val=`dirname $emacs_val`
MAC_CFLAGS="-I$emacs_val"
emacs_val=`port contents $PORT_PACKAGE | grep libgccjit.dylib`
emacs_val=`dirname $emacs_val`
MAC_LIBS="-L$emacs_val"
MAC_CFLAGS="-I$(dirname $(port contents $PORT_PACKAGE | \
grep libgccjit.h))"
MAC_LIBS="-L$(dirname $(port contents $PORT_PACKAGE | \
grep libgccjit.dylib))"
fi
fi

View file

@ -1245,7 +1245,6 @@ Manual}.
These four keywords are not really variables; setting them in any
other context has no special meaning.
@cindex fallback modes
If you're editing a file across Emacs versions, and a new mode has
been introduced to handle a file in a newer Emacs version, you can use
several @code{mode} entries to use the new mode (called

View file

@ -2289,15 +2289,10 @@ behavior by using the options @code{image-auto-resize} and
@code{image-auto-resize-on-window-resize}.
@findex image-transform-fit-to-window
@kindex s w (Image mode)
@findex image-transform-set-percent
@kindex s p (Image mode)
@findex image-transform-set-scale
@kindex s s (Image mode)
@findex image-transform-reset-to-initial
@kindex s 0 (Image mode)
@findex image-transform-reset-to-original
@kindex s o (Image mode)
To resize the image manually you can use the command
@code{image-transform-fit-to-window} bound to @kbd{s w} that fits the
image to both the window height and width. To scale the image to a
@ -2358,94 +2353,6 @@ frames at once. You can go to a specific frame with @kbd{F}
(@code{image-reverse-speed}) reverses it. The command @kbd{a 0}
(@code{image-reset-speed}) resets the speed to the original value.
In addition to the above key bindings, which are specific to Image
mode, images shown in any Emacs buffer have special key bindings when
point is at or inside the image:
@table @kbd
@cindex resize images
@cindex image resize
@findex image-increase-size
@kindex i + (Image mode)
@item i +
Increase the image size (@code{image-increase-size}) by 20%. Prefix
numeric argument controls the increment; the value of @var{n} means to
multiply the size by the factor of @w{@code{1 + @var{n} / 10}}, so
@w{@kbd{C-u 5 i +}} means to increase the size by 50%.
@findex image-decrease-size
@kindex i - (Image mode)
@item i -
Decrease the image size (@code{image-increase-size}) by 20%. Prefix
numeric argument controls the decrement; the value of @var{n} means to
multiply the size by the factor of @w{@code{1 - @var{n} / 10}}, so
@w{@kbd{C-u 3 i -}} means to decrease the size by 30%.
@cindex rotating images
@cindex image rotation
@findex image-rotate
@kindex i r (Image mode)
@item i r
Rotate the image by 90 degrees clockwise (@code{image-rotate}).
With the prefix argument, rotate by 90 degrees counter-clockwise instead.
Note that this command is not available for sliced images.
@findex image-flip-horizontally
@kindex i h (Image mode)
@item i h
Flip the image horizontally (@code{image-flip-horizontally}). This
presents the image as if reflected in a vertical mirror.
Note that this command is not available for sliced images.
@findex image-flip-vertically
@kindex i v (Image mode)
@item i v
Flip the image vertically (@code{image-flip-vertically}). This
presents the image as if reflected in a horizontal mirror.
Note that this command is not available for sliced images.
@findex image-save
@kindex i o (Image mode)
@item i o
Save the image to a file (@code{image-save}). This command prompts
you for the name of the file to save the image.
@cindex cropping images
@vindex image-crop-crop-command
@findex image-crop
@kindex i c (Image mode)
@item i c
Crop the image (@code{image-crop}). This command is available only if
your system has an external program installed that can be used for
cropping and cutting of images; the user option
@code{image-crop-crop-command} determines what program to use, and
defaults to the ImageMagick's @command{convert} program. The command
displays the image with a rectangular frame superimposed on it, and
lets you use the mouse to move and resize the frame. Type @kbd{m} to
cause mouse movements to move the frame instead of resizing it; type
@kbd{s} to move a square frame instead. When you are satisfied with
the position and size of the cropping frame, type @kbd{@key{RET}} to
actually crop the part under the frame; or type @kbd{q} to exit
without cropping. You can then save the cropped image using @w{@kbd{i
o}} or @w{@kbd{M-x image-save}}.
@findex image-cut
@kindex i x (Image mode)
@vindex image-cut-color
@vindex image-crop-cut-command
@item i x
Cut a rectangle from the image (@code{image-cut}). This works the
same as @code{image-crop} (and also requires an external program,
defined by the variable @code{image-crop-cut-command}, to perform the
image cut), but instead of cropping the image, it removes the part
inside the frame and fills that part with the color specified by
@code{image-cut-color}. With prefix argument, the command prompts for
the color to use.
@end table
The size and rotation commands are ``repeating'', which means that you
can continue adjusting the image without using the @kbd{i} prefix.
@cindex ImageMagick support
@vindex imagemagick-enabled-types
@vindex imagemagick-types-inhibit

View file

@ -313,27 +313,19 @@ may be defined in your Emacs session. For example, if a command
called @code{authorize-me} was defined, Emacs could only complete
as far as @samp{aut}.)
If you type @kbd{@key{TAB}} again immediately, it cannot determine
the next character; it could be @samp{-}, @samp{a}, or @samp{c}. So
it does not add any characters; instead, @key{TAB} displays a list of
all possible completions in another window.
If you type @key{TAB} again immediately, it cannot determine the
next character; it could be @samp{-}, @samp{a}, or @samp{c}. So it
does not add any characters; instead, @key{TAB} displays a list of all
possible completions in another window.
Next, type @kbd{-f}. The minibuffer now contains @samp{auto-f}, and
the only command name that starts with this is @code{auto-fill-mode}.
If you now type @kbd{@key{TAB}}, completion fills in the rest of the
If you now type @key{TAB}, completion fills in the rest of the
argument @samp{auto-fill-mode} into the minibuffer.
Hence, typing just @kbd{a u @key{TAB} - f @key{TAB}} allows you to
enter @samp{auto-fill-mode}.
@key{TAB} also works while point is not at the end of the
minibuffer. In that case, it will fill in text both at point and at
the end of the minibuffer. If you type @kbd{M-x autocm}, then press
@kbd{C-b} to move point before the @samp{m}, you can type
@kbd{@key{TAB}} to insert the text @samp{onf-} at point and @samp{ode}
at the end of the minibuffer, so that the minibuffer contains
@samp{autoconf-mode}.
@node Completion Commands
@subsection Completion Commands

View file

@ -329,15 +329,15 @@ version of the package, a newer version is also installed.
@section Package Installation
@findex package-install
@findex package-upgrade
@findex package-upgrade-all
@findex package-update
@findex package-update-all
Packages are most conveniently installed using the package menu
(@pxref{Package Menu}), but you can also use the command @kbd{M-x
package-install}. This prompts for the name of a package with the
@samp{available} status, then downloads and installs it. Similarly,
if you want to upgrade a package, you can use the @kbd{M-x
package-upgrade} command, and if you want to upgrade all the packages,
you can use the @kbd{M-x package-upgrade-all} command.
if you want to update a package, you can use the @kbd{M-x
package-update} command, and if you just want to update all the
packages, you can use the @kbd{M-x package-update-all} command.
@cindex package requirements
A package may @dfn{require} certain other packages to be installed,
@ -551,8 +551,8 @@ bugs.
source code for a package directly from source. The command will also
automatically ensure that all files are byte-compiled and auto-loaded,
just like with a regular package. Packages installed this way behave
just like any other package. You can upgrade them using
@code{package-upgrade} or @code{package-upgrade-all} and delete them
just like any other package. You can update them using
@code{package-update} or @code{package-update-all} and delete them
again using @code{package-delete}. They are even displayed in the
regular package listing. If you just wish to clone the source of a
package, without adding it to the package list, use
@ -578,80 +578,3 @@ from the package directory (@pxref{Package Files}) to your checkout
and initializes the code. Note that you might have to use
@code{package-vc-refresh} to repeat the initialization and update the
autoloads.
@subsection Specifying Package Sources
@cindex package specification
@cindex specification, for source packages
To install a package from source, Emacs must know where to get the
package's source code (such as a code repository) and basic
information about the structure of the code (such as the main file in
a multi-file package). A @dfn{package specification} describes these
properties.
When supported by a package archive (@pxref{Package
Archives,,,elisp, The Emacs Lisp Reference Manual}), Emacs can
automatically download a package's specification from said archive.
If the first argument passed to @code{package-vc-install} is a symbol
naming a package, then Emacs will use the specification provided by
the archive for that package.
@example
@group
;; Emacs will download BBDB's specification from GNU ELPA:
(package-vc-install 'bbdb)
@end group
@end example
The first argument to @code{package-vc-install} may also be a
package specification. This allows you to install source packages
from locations other than the known archives listed in the user option
@code{package-archives}. A package specification is a list of the
form @code{(@var{name} . @var{spec})}, in which @var{spec} should be a
property list using any of the keys in the table below.
For definitions of basic terms for working with code repositories and
version control systems, see @ref{VCS Concepts,,,emacs, The GNU Emacs
Manual}.
@table @code
@item :url
A string providing the URL that specifies the repository from which to
fetch the package's source code.
@item :branch
A string providing the revision of the code to install. Do not
confuse this with a package's version number.
@item :lisp-dir
A string providing the repository-relative name of the directory to
use for loading the Lisp sources, which defaults to the root directory
of the repository.
@item :main-file
A string providing the main file of the project, from which to gather
package metadata. If not given, the default is the package name with
".el" appended to it.
@item :doc
A string providing the repository-relative name of the documentation
file from which to build an Info file. This can be a Texinfo file or
an Org file.
@item :vc-backend
A symbol naming the VC backend to use for downloading a copy of the
package's repository (@pxref{Version Control Systems,,,emacs, The GNU
Emacs Manual}). If omitted, Emacs will attempt to make a guess based
on the provided URL, or, failing that, the process will fall back onto
the value of @code{package-vc-default-backend}.
@end table
@example
@group
;; Specifying information manually:
(package-vc-install
'(bbdb :url "https://git.savannah.nongnu.org/git/bbdb.git"
:lisp-dir "lisp"
:doc "doc/bbdb.texi"))
@end group
@end example

View file

@ -6604,11 +6604,10 @@ works. You will probably need to use @kbd{C-h f}
(@code{describe-function}). The newer version uses a conditional to
determine whether the buffer has been narrowed.
Also, the modern version of @code{what-line} uses
@code{line-number-at-pos}, which among other simple expressions, such
as @code{(goto-char (point-min))}, moves point to the beginning of the
current line with @code{(forward-line 0)} rather than
@code{beginning-of-line}.)
(Also, it uses @code{line-number-at-pos}, which among other simple
expressions, such as @code{(goto-char (point-min))}, moves point to
the beginning of the current line with @code{(forward-line 0)} rather
than @code{beginning-of-line}.)
The @code{what-line} function as shown here has a documentation line
and is interactive, as you would expect. The next two lines use the

View file

@ -959,9 +959,9 @@ infinite recursion.
@defun buffer-match-p condition buffer-or-name &optional arg
This function checks if a buffer designated by @code{buffer-or-name}
satisfies the specified @code{condition}. Optional third argument
@var{arg} is passed to the predicate function in @var{condition}. A
valid @var{condition} can be one of the following:
satisfies a @code{condition}. Optional third argument @var{arg} is
passed to the predicate function in @var{condition}. A condition can
be one of the following:
@itemize @bullet{}
@item
A string, interpreted as a regular expression. The buffer
@ -990,23 +990,21 @@ Satisfied if @emph{all} the conditions in @var{conds} satisfy
Satisfied if the buffer's major mode derives from @var{expr}.
@item major-mode
Satisfied if the buffer's major mode is equal to @var{expr}. Prefer
using @code{derived-mode} instead, when both can work.
using @code{derived-mode} instead when both can work.
@end table
@item t
Satisfied by any buffer. A convenient alternative to @code{""} (empty
string) or @code{(and)} (empty conjunction).
string), @code{(and)} (empty conjunction) or @code{always}.
@end itemize
@end defun
@defun match-buffers condition &optional buffer-list arg
This function returns a list of all buffers that satisfy the
@code{condition}. If no buffers match, the function returns
@code{nil}. The argument @var{condition} is as defined in
@code{buffer-match-p} above. By default, all the buffers are
considered, but this can be restricted via the optional argument
@code{buffer-list}, which should be a list of buffers to consider.
Optional third argument @var{arg} will be passed to @var{condition} in
the same way as @code{buffer-match-p} does.
This function returns a list of all buffers that satisfy a
@code{condition}, as defined for @code{buffer-match-p}. By default
all buffers are considered, but this can be restricted via the second
optional @code{buffer-list} argument. Optional third argument
@var{arg} will be used by @var{condition} in the same way as
@code{buffer-match-p} does.
@end defun
@node Creating Buffers

View file

@ -2395,17 +2395,6 @@ as @code{set-language-environment}), use the
;; Get the full localized name of the language
(w32-get-locale-info language-id t)
@end smallexample
@cindex @code{end-session} event
@item end-session
This event is generated on MS-Windows when the operating system
informs Emacs that the user terminated the interactive session, or
that the system is shutting down. The standard definition of this
event is to invoke the @code{kill-emacs} command (@pxref{Killing
Emacs}) so as to shut down Emacs in an orderly fashion; if there are
unsaved changes, this will produce auto-save files
(@pxref{Auto-Saving}) that the user can use after restarting the
session to restore the unsaved edits.
@end table
If one of these events arrives in the middle of a key sequence---that

View file

@ -1809,9 +1809,6 @@ wish the program to continue execution despite an error in a subroutine.
In these cases, you would use @code{condition-case} to establish
@dfn{error handlers} to recover control in case of error.
For reporting problems without terminating the execution of the
current command, consider issuing a warning instead. @xref{Warnings}.
Resist the temptation to use error handling to transfer control from
one part of the program to another; use @code{catch} and @code{throw}
instead. @xref{Catch and Throw}.

View file

@ -264,12 +264,11 @@ have any number of prefixes.
@end table
@cindex @code{custom-group} property
The variables, faces, and subgroups of a group are stored in the
The variables and subgroups of a group are stored in the
@code{custom-group} property of the group's symbol. @xref{Symbol
Plists}. The value of that property is a list of pairs whose
@code{car} is the symbol of the variable or the face or the subgroup,
and the @code{cdr} is one of the corresponding symbols
@code{custom-variable}, @code{custom-face}, or @code{custom-group}.
@code{car} is the variable or subgroup symbol and the @code{cdr} is
either @code{custom-variable} or @code{custom-group}.
@end defmac
@defopt custom-unlispify-remove-prefixes

View file

@ -752,8 +752,7 @@ echo area (which is really a special use of the minibuffer window;
@cindex warnings
@dfn{Warnings} are a facility for a program to inform the user of a
possible problem, but continue running (as opposed to signaling an
error, @pxref{Errors}).
possible problem, but continue running.
@menu
* Warning Basics:: Warnings concepts and functions to report them.
@ -766,74 +765,69 @@ error, @pxref{Errors}).
@subsection Warning Basics
@cindex severity level
Every warning is a textual message, which explains the problem for
the user, with the associated @dfn{severity level} which is a symbol.
Here are the supported severity levels, in order of decreasing
severity, and their meanings:
Every warning has a textual message, which explains the problem for
the user, and a @dfn{severity level} which is a symbol. Here are the
possible severity levels, in order of decreasing severity, and their
meanings:
@table @code
@item :emergency
A problem that will seriously impair Emacs operation soon
if the user does not attend to it promptly.
if you do not attend to it promptly.
@item :error
A report about data or circumstances that are inherently wrong.
A report of data or circumstances that are inherently wrong.
@item :warning
A report about data or circumstances that are not inherently wrong,
but raise suspicion of a possible problem.
A report of data or circumstances that are not inherently wrong, but
raise suspicion of a possible problem.
@item :debug
A report of information that may be useful if the user is currently
debugging the Lisp program which issues the warning.
A report of information that may be useful if you are debugging.
@end table
When your program encounters invalid input data, it can either
signal a Lisp error by calling @code{error} or @code{signal}
(@pxref{Signaling Errors}) or report a warning with severity
@code{:error}. Signaling a Lisp error is the easiest thing to do, but
it means the signaling program cannot continue execution. If you want
to take the trouble of implementing a way to continue processing
despite the invalid data, then reporting a warning of severity
@code{:error} is the right way of informing the user of the problem.
For instance, the Emacs Lisp byte compiler can report an error that
way and continue compiling other functions. (If the program signals a
Lisp error and then handles it with @code{condition-case}, the user
won't see the error message; reporting that as a warning instead
avoids that problem.)
signal a Lisp error by calling @code{error} or @code{signal} or report
a warning with severity @code{:error}. Signaling a Lisp error is the
easiest thing to do, but it means the program cannot continue
processing. If you want to take the trouble to implement a way to
continue processing despite the bad data, then reporting a warning of
severity @code{:error} is the right way to inform the user of the
problem. For instance, the Emacs Lisp byte compiler can report an
error that way and continue compiling other functions. (If the
program signals a Lisp error and then handles it with
@code{condition-case}, the user won't see the error message; it could
show the message to the user by reporting it as a warning.)
@c FIXME: Why use "(bytecomp)" instead of "'bytecomp" or simply
@c "bytecomp" here? The parens are part of warning-type-format but
@c not part of the warning type. --xfq
@cindex warning type
In addition to severity level, each warning has a @dfn{warning type}
to classify it. The warning type is either a symbol or a list of
symbols. If it is a symbol, it should be the custom group that you
use for the program's user options; if it is a list, the first element
of the list should be that custom group. For example, byte compiler
warnings use the warning type @code{(bytecomp)}. If the warning type
is a list, the elements of the list after the first one, which should
be arbitrary symbols, represent subcategories of the warning: they
will be displayed to the user to better explain the nature of the
warning.
Each warning has a @dfn{warning type} to classify it. The type is a
list of symbols. The first symbol should be the custom group that you
use for the program's user options. For example, byte compiler
warnings use the warning type @code{(bytecomp)}. You can also
subcategorize the warnings, if you wish, by using more symbols in the
list.
@defun display-warning type message &optional level buffer-name
This function reports a warning, using the string @var{message} as the
warning text and @var{type} as the warning type. @var{level} should
be the severity level, and defaults to @code{:warning} if omitted or
@code{nil}.
This function reports a warning, using @var{message} as the message
and @var{type} as the warning type. @var{level} should be the
severity level, with @code{:warning} being the default.
@var{buffer-name}, if non-@code{nil}, specifies the name of the buffer
for logging the warning message. By default, it is @file{*Warnings*}.
for logging the warning. By default, it is @file{*Warnings*}.
@end defun
@defun lwarn type level message &rest args
This function reports a warning using the value returned by
@w{@code{(format-message @var{message} @var{args}@dots{})}} as the
message text in the @file{*Warnings*} buffer. In other respects it is
equivalent to @code{display-warning}.
This function reports a warning using the value of @code{(format-message
@var{message} @var{args}...)} as the message in the @file{*Warnings*}
buffer. In other respects it is equivalent to @code{display-warning}.
@end defun
@defun warn message &rest args
This function reports a warning using the value returned by
@w{@code{(format-message @var{message} @var{args}@dots{})}} as the
message text, @code{emacs} as the warning type, and @code{:warning} as
the severity level. It exists for compatibility only; we recommend
not using it, because you should specify a specific warning type.
This function reports a warning using the value of @code{(format-message
@var{message} @var{args}...)} as the message, @code{(emacs)} as the
type, and @code{:warning} as the severity level. It exists for
compatibility only; we recommend not using it, because you should
specify a specific warning type.
@end defun
@node Warning Variables
@ -848,16 +842,15 @@ This list defines the meaning and severity order of the warning
severity levels. Each element defines one severity level,
and they are arranged in order of decreasing severity.
Each element has the form @w{@code{(@var{level} @var{string}
[@var{function}])}}, where @var{level} is the severity level it
defines. @var{string} specifies the textual description of this
level. @var{string} should use @samp{%s} to specify where to put the
warning type information, or it can omit the @samp{%s} so as not to
include that information.
Each element has the form @code{(@var{level} @var{string}
@var{function})}, where @var{level} is the severity level it defines.
@var{string} specifies the textual description of this level.
@var{string} should use @samp{%s} to specify where to put the warning
type information, or it can omit the @samp{%s} so as not to include
that information.
The optional @var{function}, if non-@code{nil}, is a function to call
with no arguments, to get the user's attention. A notable example is
@code{ding} (@pxref{Beeping}).
with no arguments, to get the user's attention.
Normally you should not change the value of this variable.
@end defvar
@ -866,19 +859,18 @@ Normally you should not change the value of this variable.
If non-@code{nil}, the value is a function to generate prefix text for
warnings. Programs can bind the variable to a suitable function.
@code{display-warning} calls this function with the warnings buffer
the current buffer, and the function can insert text into it. That
text becomes the beginning of the warning message.
current, and the function can insert text in it. That text becomes
the beginning of the warning message.
The function is called with two arguments, the severity level and its
entry in @code{warning-levels}. It should return a list to use
@emph{instead} of that entry (the value need not be an actual member
of @code{warning-levels}, but it must have the same structure). By
constructing this value, the function can change the severity of the
warning, or specify different handling for a given severity level.
entry in @code{warning-levels}. It should return a list to use as the
entry (this value need not be an actual member of
@code{warning-levels}). By constructing this value, the function can
change the severity of the warning, or specify different handling for
a given severity level.
If the variable's value is @code{nil}, there's no prefix text, before
the warning is displayed, starting with the @var{string} part of the
entry in @code{warning-levels} corresponding to the warning's level.
If the variable's value is @code{nil} then there is no function
to call.
@end defvar
@defvar warning-series
@ -886,18 +878,17 @@ Programs can bind this variable to @code{t} to say that the next
warning should begin a series. When several warnings form a series,
that means to leave point on the first warning of the series, rather
than keep moving it for each warning so that it appears on the last one.
The series ends when the local binding of this variable is unbound and
The series ends when the local binding is unbound and
@code{warning-series} becomes @code{nil} again.
The value can also be a symbol with a function definition. That is
equivalent to @code{t}, except that the next warning will also call
the function with no arguments with the warnings buffer the current
buffer. The function can, for example, insert text which will serve
as a header for the series of warnings.
the function with no arguments with the warnings buffer current. The
function can insert text which will serve as a header for the series
of warnings.
Once a series has begun, the value of this variable is a marker which
points to the buffer position in the warnings buffer of the start of
the series.
Once a series has begun, the value is a marker which points to the
buffer position in the warnings buffer of the start of the series.
The variable's normal value is @code{nil}, which means to handle
each warning separately.
@ -905,7 +896,7 @@ each warning separately.
@defvar warning-fill-prefix
When this variable is non-@code{nil}, it specifies a fill prefix to
use for filling the text of each warning.
use for filling each warning's text.
@end defvar
@defvar warning-fill-column
@ -914,11 +905,11 @@ The column at which to fill warnings.
@defvar warning-type-format
This variable specifies the format for displaying the warning type
in the warning text. The result of formatting the type this way
in the warning message. The result of formatting the type this way
gets included in the message under the control of the string in the
entry in @code{warning-levels}. The default value is @code{" (%s)"}.
If you bind it to the empty string @code{""} then the warning type
won't appear at all.
If you bind it to @code{""} then the warning type won't appear at
all.
@end defvar
@node Warning Options
@ -930,71 +921,38 @@ when a Lisp program reports a warning.
@defopt warning-minimum-level
This user option specifies the minimum severity level that should be
shown immediately to the user, by popping the warnings buffer in some
window. The default is @code{:warning}, which means to show the
warning buffer for any warning severity except @code{:debug}. The
warnings of lower severity levels will still be written into the
warnings buffer, but the buffer will not be forced onto display.
shown immediately to the user. The default is @code{:warning}, which
means to immediately display all warnings except @code{:debug}
warnings.
@end defopt
@defopt warning-minimum-log-level
This user option specifies the minimum severity level that should be
logged in the warnings buffer. Warnings of lower severity will be
completely ignored: not written to the warnings buffer and not
displayed. The default is @code{:warning}, which means to log
warnings of any severity except @code{:debug}.
logged in the warnings buffer. The default is @code{:warning}, which
means to log all warnings except @code{:debug} warnings.
@end defopt
@defopt warning-suppress-types
This list specifies which warning types should not be displayed
immediately when they occur. Each element of the list should be a
list of symbols. If an element of this list has the same elements as
the first elements in a warning type, then the warning of that type
will not be shown on display by popping the warnings buffer in some
window (the warning will still be logged in the warnings buffer).
For example, if the value of this variable is a list like this:
@lisp
((foo) (bar subtype))
@end lisp
@noindent
then warnings whose types are @code{foo} or @code{(foo)} or
@w{@code{(foo something)}} or @w{@code{(bar subtype other)}} will not
be shown to the user.
immediately for the user. Each element of the list should be a list
of symbols. If its elements match the first elements in a warning
type, then that warning is not displayed immediately.
@end defopt
@defopt warning-suppress-log-types
This list specifies which warning types should be ignored: not logged
in the warnings buffer and not shown to the user. The structure and
the matching of warning types are the same as for
@code{warning-suppress-types} above.
This list specifies which warning types should not be logged in the
warnings buffer. Each element of the list should be a list of
symbols. If it matches the first few elements in a warning type, then
that warning is not logged.
@end defopt
@cindex warnings, suppressing during startup
@cindex prevent warnings in init files
During startup, Emacs delays showing any warnings until after it
loads and processes the site-wide and user's init files
(@pxref{Startup Summary}). Let-binding (@pxref{Local Variables}) the
values of these options around some code in your init files which
might emit a warning will therefore not work, because it will not be
in effect by the time the warning is actually processed. Thus, if you
want to suppress some warnings during startup, change the values of
the above options in your init file early enough, or put those
let-binding forms in your @code{after-init-hook} or
@code{emacs-startup-hook} functions. @xref{Init File}.
@node Delayed Warnings
@subsection Delayed Warnings
@cindex delayed warnings
@cindex warnings, delayed
Sometimes, you may wish to avoid showing a warning while a command is
running, and only show it only after the end of the command. You can
use the function @code{delay-warning} for this. Emacs automatically
delays any warnings emitted during the early stages of startup, and
shows them only after the init files are processed.
use the function @code{delay-warning} for this.
@defun delay-warning type message &optional level buffer-name
This function is the delayed counterpart to @code{display-warning}
@ -1015,7 +973,7 @@ with the same form, and the same meanings, as the argument list of
@code{display-warning}. Immediately after running
@code{post-command-hook} (@pxref{Command Overview}), the Emacs
command loop displays all the warnings specified by this variable,
then resets the variable to @code{nil}.
then resets it to @code{nil}.
@end defvar
Programs which need to further customize the delayed warnings
@ -1024,9 +982,7 @@ mechanism can change the variable @code{delayed-warnings-hook}:
@defvar delayed-warnings-hook
This is a normal hook which is run by the Emacs command loop, after
@code{post-command-hook}, in order to process and display delayed
warnings. Emacs also runs this hook during startup, after loading the
site-start and user init files (@pxref{Startup Summary}), because
warnings emitted before that are automatically delayed.
warnings.
Its default value is a list of two functions:
@ -6920,7 +6876,7 @@ This function puts image @var{image} in front of @var{pos} in the
current buffer. The argument @var{pos} should be an integer or a
marker. It specifies the buffer position where the image should appear.
The argument @var{string} specifies the text that should hold the image
as an alternative to the default @samp{x}.
as an alternative to the default.
The argument @var{image} must be an image descriptor, perhaps returned
by @code{create-image} or stored by @code{defimage}.
@ -6933,7 +6889,7 @@ buffer's text.
Internally, this function creates an overlay, and gives it a
@code{before-string} property containing text that has a @code{display}
property whose value is the image. (Whew! that was a mouthful@dots{})
property whose value is the image. (Whew!)
@end defun
@defun remove-images start end &optional buffer
@ -6980,47 +6936,41 @@ This function returns @code{t} if point is on an image, and @code{nil}
otherwise.
@end defun
@cindex operations on images
Images inserted with the insertion functions above also get a local
keymap installed in the text properties (or overlays) that span the
displayed image. This keymap defines the following commands:
@table @kbd
@findex image-increase-size
@item i +
Increase the image size (@code{image-increase-size})
Increase the image size (@code{image-increase-size}). A prefix value
of @samp{4} means to increase the size by 40%. The default is 20%.
@findex image-decrease-size
@item i -
Decrease the image size (@code{image-decrease-size}).
Decrease the image size (@code{image-increase-size}). A prefix value
of @samp{4} means to decrease the size by 40%. The default is 20%.
@findex image-rotate
@item i r
Rotate the image (@code{image-rotate}).
Rotate the image by 90 degrees clockwise (@code{image-rotate}).
A prefix means to rotate by 90 degrees counter-clockwise instead.
@findex image-flip-horizontally
@item i h
Flip the image horizontally (@code{image-flip-horizontally}).
@findex image-flip-vertically
@item i v
Flip the image vertically (@code{image-flip-vertically}).
@findex image-save
@item i o
Save the image to a file (@code{image-save}).
@findex image-crop
@item i c
Interactively crop the image (@code{image-crop}).
Crop the image interactively (@code{image-crop}).
@findex image-cut
@item i x
Interactively cut a rectangle from the image (@code{image-cut}).
Cut a rectangle from the image interactively (@code{image-cut}).
@end table
@xref{Image Mode,,, emacs, The GNU Emacs Manual}, for more details
about these image-specific key bindings.
The size and rotation commands are ``repeating'', which means that you
can continue adjusting the image without using the @kbd{i} prefix.
@node Multi-Frame Images
@subsection Multi-Frame Images

View file

@ -3390,7 +3390,7 @@ first, before handlers for jobs such as remote file access.
@code{file-directory-p},
@code{file-equal-p},
@code{file-executable-p}, @code{file-exists-p},
@code{file-group-gid}, @code{file-in-directory-p},
@code{file-in-directory-p},
@code{file-local-copy}, @code{file-locked-p},
@code{file-modes}, @code{file-name-all-completions},
@code{file-name-as-directory},
@ -3452,7 +3452,7 @@ first, before handlers for jobs such as remote file access.
@code{file-direc@discretionary{}{}{}tory-p},
@code{file-equal-p},
@code{file-executable-p}, @code{file-exists-p},
@code{file-group-gid}, @code{file-in-directory-p},
@code{file-in-directory-p},
@code{file-local-copy}, @code{file-locked-p},
@code{file-modes}, @code{file-name-all-completions},
@code{file-name-as-directory},

View file

@ -4112,7 +4112,7 @@ has the same meaning as the @var{action} argument to
Emacs implements receiving text and URLs individually for each
window system, and does not by default support receiving other kinds
of data as drops. To support receiving other kinds of data, use the
X-specific interface described below.
X-specific interface described below:
@vindex x-dnd-test-function
@vindex x-dnd-known-types
@ -4141,71 +4141,29 @@ depending on the specific drag-and-drop protocol being used. For
example, the data type used for plain text may be either
@code{"STRING"} or @code{"text/plain"}.
@cindex XDS
@cindex direct save protocol
@vindex x-dnd-direct-save-function
When Emacs runs on X window system, it supports the X Direct Save
(@acronym{XDS}) protocol, which allows users to save a file by
dragging and dropping it onto an Emacs window, such as a Dired window.
To comply with the unique requirements of @acronym{XDS}, these
drag-and-drop requests are processed specially: instead of being
handled according to @code{x-dnd-types-alist}, they are handled by the
@dfn{direct-save function} that is the value of the variable
@code{x-dnd-direct-save-function}. The value should be a function of
two arguments, @var{need-name} and @var{filename}. The @acronym{XDS}
protocol uses a two-step procedure for dragging files:
@enumerate 1
@item
The application from which the file is dragged asks Emacs to provide
the full file name under which to save the file. For this purpose,
the direct-save function is called with its first argument
@var{need-name} non-@code{nil}, and the second argument @var{filename}
set to the basename of the file to be saved. It should return the
fully-expanded absolute file name under which to save the file. For
example, if a file is dragged to a Dired window, the natural directory
for the file is the directory of the file shown at location of the
drop. If saving the file is not possible for some reason, the
function should return @code{nil}, which will cancel the drag-and-drop
operation.
@item
The application from which the file is dragged saves the file under
the name returned by the first call to the direct-save function. If
it succeeds in saving the file, the direct-save function is called
again, this time with the first argument @var{need-name} set to
@code{nil} and the second argument @var{filename} set to the full
absolute name of the saved file. The function is then expected to do
whatever is needed given the fact that file was saved. For example,
Dired should update the directory on display by showing the new file
there.
@end enumerate
The default value of @code{x-dnd-direct-save-function} is
@code{x-dnd-save-direct}.
@defun x-dnd-save-direct need-name filename
When called with the @var{need-name} argument non-@code{nil}, this
function prompts the user for the absolute file name under which it
should be saved. If the specified file already exists, it
additionally asks the user whether to overwrite it, and returns the
absolute file name only if the user confirms the overwriting.
When called with the @var{need-name} argument @code{nil}, it reverts
the Dired listing if the current buffer is in Dired mode or one of its
descendants, and otherwise visits the file by calling @code{find-file}
(@pxref{Visiting Functions}).
@end defun
@defun x-dnd-save-direct-immediately need-name filename
This function works like @code{x-dnd-save-direct}, but when called
with its @var{need-name} argument non-@code{nil}, it doesn't prompt
the user for the full name of the file to be saved; instead, it
returns its argument @var{filename} expanded against the current
buffer's default directory (@pxref{File Name Expansion}). (It still
asks for confirmation if a file by that name already exists in the
default directory.)
@end defun
@c FIXME: This description is overly-complicated and confusing. In
@c particular, the two calls to the function basically sound
@c identical, so it is unclear how should the function distinguish
@c between the first and the second one. The description of who asks
@c whom to do what is also very hard to understand. Needs rewording,
@c and needs shorter sentences. Perhaps examples could help.
However, @code{x-dnd-types-alist} does not handle a special kind of
drop sent by a program that wants Emacs to tell it where to save a
file in a specific location determined by the user. These drops are
instead handled by a function that is the value of the variable
@code{x-dnd-direct-save-function}. This function should accept two arguments.
If the first argument is non-@code{nil}, then the second argument is a
file name to save (with leading directories) that the other
program recommends, and the
function should return the full file name under which it should be
saved. After the function completes, Emacs will ask the other program
to save the file under the name that was returned, and if the file was
successfully saved, call the function again with the first argument
set to a non-@code{nil} value and the second argument set to the file
name that was returned. The function should then perform whatever
action is appropriate (i.e., opening the file or refreshing a
directory listing.)
@cindex initiating drag-and-drop
On capable window systems, Emacs also supports dragging contents

View file

@ -2631,12 +2631,6 @@ so the byte compiler can ignore calls whose value is ignored. This is
the same as the @code{side-effect-free} property of the function's
symbol, @pxref{Standard Properties}.
@item (important-return-value @var{val})
If @var{val} is non-@code{nil}, the byte compiler will warn about
calls to this function that do not use the returned value. This is the
same as the @code{important-return-value} property of the function's
symbol, @pxref{Standard Properties}.
@item (speed @var{n})
Specify the value of @code{native-comp-speed} in effect for native
compilation of this function (@pxref{Native-Compilation Variables}).

View file

@ -1224,15 +1224,7 @@ x
@end example
However, the other arguments (all but the last) should be mutable
lists. They can be dotted lists, whose last @sc{cdr}s are then
replaced with the next argument:
@example
@group
(nconc (cons 1 2) (cons 3 (cons 4 5)) 'z)
@result{} (1 3 4 . z)
@end group
@end example
lists.
A common pitfall is to use a constant list as a non-last argument to
@code{nconc}. If you do this, the resulting behavior is undefined

View file

@ -1338,7 +1338,7 @@ specified @var{file} and perform the necessary initialization of the
module. This is the primitive which makes sure the module exports the
@code{plugin_is_GPL_compatible} symbol, calls the module's
@code{emacs_module_init} function, and signals an error if that
function returns an error indication, or if the user typed @kbd{C-g}
function returns an error indication, or if the use typed @kbd{C-g}
during the initialization. If the initialization succeeds,
@code{module-load} returns @code{t}. Note that @var{file} must
already have the proper file-name extension, as this function doesn't

View file

@ -4155,7 +4155,7 @@ Other keywords are optional:
@end multitable
Lisp programs mark patterns in @var{query} with capture names (names
that start with @code{@@}), and tree-sitter will return matched nodes
that starts with @code{@@}), and tree-sitter will return matched nodes
tagged with those same capture names. For the purpose of
fontification, capture names in @var{query} should be face names like
@code{font-lock-keyword-face}. The captured node will be fontified

View file

@ -219,25 +219,17 @@ creates huge integers.
@cindex @acronym{IEEE} floating point
Floating-point numbers are useful for representing numbers that are
not integral. The range of floating-point numbers is the same as the
range of the C data type @code{double} on the machine you are using.
On almost all computers supported by Emacs, this is @acronym{IEEE}
binary64 floating point format, which is standardized by
@url{https://standards.ieee.org/standard/754-2019.html,,IEEE Std
754-2019} and is discussed further in David Goldberg's paper
not integral. The range of floating-point numbers is
the same as the range of the C data type @code{double} on the machine
you are using. On all computers supported by Emacs, this is
@acronym{IEEE} binary64 floating point format, which is standardized by
@url{https://standards.ieee.org/standard/754-2019.html,,IEEE Std 754-2019}
and is discussed further in David Goldberg's paper
``@url{https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html,
What Every Computer Scientist Should Know About Floating-Point
Arithmetic}''. On modern platforms, floating-point operations follow
the IEEE-754 standard closely; however, results are not always rounded
correctly on some systems, notably 32-bit x86.
On some old computer systems, Emacs may not use IEEE floating-point.
We know of one such system on which Emacs runs correctly, but does not
follow IEEE-754: the VAX running NetBSD using GCC 10.4.0, where the
VAX @samp{D_Floating} format is used instead. IBM System/370-derived
mainframes and their XL/C compiler are also capable of utilizing a
hexadecimal floating point format, but Emacs has not yet been built in
such a configuration.
What Every Computer Scientist Should Know About Floating-Point Arithmetic}''.
On modern platforms, floating-point operations follow the IEEE-754
standard closely; however, results are not always rounded correctly on
some obsolescent platforms, notably 32-bit x86.
The read syntax for floating-point numbers requires either a decimal
point, an exponent, or both. Optional signs (@samp{+} or @samp{-})
@ -270,10 +262,6 @@ two NaNs as equal when their
signs and significands agree. Significands of NaNs are
machine-dependent, as are the digits in their string representation.
NaNs are not available on systems which do not use IEEE
floating-point arithmetic; if the read syntax for a NaN is used on a
VAX, for example, the reader signals an error.
When NaNs and signed zeros are involved, non-numeric functions like
@code{eql}, @code{equal}, @code{sxhash-eql}, @code{sxhash-equal} and
@code{gethash} determine whether values are indistinguishable, not
@ -754,10 +742,9 @@ by rounding the quotient towards zero after each division.
@cindex @code{arith-error} in division
If you divide an integer by the integer 0, Emacs signals an
@code{arith-error} error (@pxref{Errors}). On systems using IEEE-754
floating-point, floating-point division of a nonzero number by zero
yields either positive or negative infinity (@pxref{Float Basics});
otherwise, an @code{arith-error} is signaled as usual.
@code{arith-error} error (@pxref{Errors}). Floating-point division of
a nonzero number by zero yields either positive or negative infinity
(@pxref{Float Basics}).
@end defun
@defun % dividend divisor

View file

@ -182,9 +182,7 @@ is over, and, together with @code{before-init-time}, provides the
measurement of how long it took.
@item
It runs the normal hooks @code{after-init-hook} and
@code{delayed-warnings-hook}. The latter shows any warnings emitted
during previous stages of startup, which are automatically delayed.
It runs the normal hook @code{after-init-hook}.
@item
If the buffer @file{*scratch*} exists and is still in Fundamental mode
@ -1290,22 +1288,12 @@ the remote connection has no associated user, it will instead return
@end defun
@cindex GID
@defun group-real-gid
This function returns the real @acronym{GID} of the Emacs process.
@end defun
@defun group-gid
This function returns the effective @acronym{GID} of the Emacs process.
@end defun
@defun file-group-gid
This function returns the connection-local value for the user's
effective @acronym{GID}. Similar to @code{file-user-uid}, if
@code{default-directory} is local, this is equivalent to
@code{group-gid}, but for remote files (@pxref{Remote Files, , ,
emacs, The GNU Emacs Manual}), it will return the @acronym{GID} for
the user associated with that remote connection; if the remote
connection has no associated user, it will instead return -1.
@defun group-real-gid
This function returns the real @acronym{GID} of the Emacs process.
@end defun
@defun system-users

View file

@ -1755,9 +1755,7 @@ caught automatically, so that it doesn't stop the execution of whatever
program was running when the filter function was started. However, if
@code{debug-on-error} is non-@code{nil}, errors are not caught.
This makes it possible to use the Lisp debugger to debug filter
functions. @xref{Debugger}. If an error is caught, Emacs pauses for
@code{process-error-pause-time} seconds so that the user sees the
error. @xref{Asynchronous Processes}
functions. @xref{Debugger}.
Many filter functions sometimes (or always) insert the output in the
process's buffer, mimicking the actions of the default filter.
@ -2161,9 +2159,7 @@ automatically, so that it doesn't stop the execution of whatever
programs was running when the sentinel was started. However, if
@code{debug-on-error} is non-@code{nil}, errors are not caught.
This makes it possible to use the Lisp debugger to debug the
sentinel. @xref{Debugger}. If an error is caught, Emacs pauses for
@code{process-error-pause-time} seconds so that the user sees the
error. @xref{Asynchronous Processes}
sentinel. @xref{Debugger}.
While a sentinel is running, the process sentinel is temporarily
set to @code{nil} so that the sentinel won't run recursively.

View file

@ -376,43 +376,45 @@ is less than @var{c}, then @var{a} must be less than @var{c}. If you
use a comparison function which does not meet these requirements, the
result of @code{sort} is unpredictable.
The destructive aspect of @code{sort} for lists is that it reuses the
cons cells forming @var{sequence} by changing their contents, possibly
rearranging them in a different order. This means that the value of
the input list is undefined after sorting; only the list returned by
@code{sort} has a well-defined value. Example:
The destructive aspect of @code{sort} for lists is that it rearranges the
cons cells forming @var{sequence} by changing @sc{cdr}s. A nondestructive
sort function would create new cons cells to store the elements in their
sorted order. If you wish to make a sorted copy without destroying the
original, copy it first with @code{copy-sequence} and then sort.
Sorting does not change the @sc{car}s of the cons cells in @var{sequence};
the cons cell that originally contained the element @code{a} in
@var{sequence} still has @code{a} in its @sc{car} after sorting, but it now
appears in a different position in the list due to the change of
@sc{cdr}s. For example:
@example
@group
(setq nums (list 2 1 4 3 0))
(sort nums #'<)
@result{} (0 1 2 3 4)
; nums is unpredictable at this point
(setq nums (list 1 3 2 6 5 4 0))
@result{} (1 3 2 6 5 4 0)
@end group
@end example
Most often we store the result back into the variable that held the
original list:
@example
(setq nums (sort nums #'<))
@end example
If you wish to make a sorted copy without destroying the original,
copy it first and then sort:
@example
@group
(setq nums (list 2 1 4 3 0))
(sort (copy-sequence nums) #'<)
@result{} (0 1 2 3 4)
(sort nums #'<)
@result{} (0 1 2 3 4 5 6)
@end group
@group
nums
@result{} (2 1 4 3 0)
@result{} (1 2 3 4 5 6)
@end group
@end example
@noindent
@strong{Warning}: Note that the list in @code{nums} no longer contains
0; this is the same cons cell that it was before, but it is no longer
the first one in the list. Don't assume a variable that formerly held
the argument now holds the entire sorted list! Instead, save the result
of @code{sort} and use that. Most often we store the result back into
the variable that held the original list:
@example
(setq nums (sort nums #'<))
@end example
For the better understanding of what stable sort is, consider the following
vector example. After sorting, all items whose @code{car} is 8 are grouped
at the beginning of @code{vector}, but their relative order is preserved.

View file

@ -643,12 +643,6 @@ ignore a call whose value is unused. If the property's value is
calls. In addition to byte compiler optimizations, this property is
also used for determining function safety (@pxref{Function Safety}).
@item important-return-value
@cindex @code{important-return-value} property
A non-@code{nil} value makes the byte compiler warn about code that
calls the named function without using its returned value. This is
useful for functions where doing so is likely to be a mistake.
@item undo-inhibit-region
If non-@code{nil}, the named function prevents the @code{undo} operation
from being restricted to the active region, if @code{undo} is invoked

View file

@ -5510,7 +5510,7 @@ contents of an SQLite database.
@section Parsing HTML and XML
@cindex parsing html
Emacs can be compiled with built-in @file{libxml2} support.
Emacs can be compiled with built-in libxml2 support.
@defun libxml-available-p
This function returns non-@code{nil} if built-in libxml2 support is
@ -5529,10 +5529,8 @@ mistakes.
If @var{start} or @var{end} are @code{nil}, they default to the values
from @code{point-min} and @code{point-max}, respectively.
The optional argument @var{base-url}, if non-@code{nil}, should be
used for warnings and errors reported by the @file{libxml2} library,
but Emacs currently calls the library with errors and warnings
disabled, so this argument is not used.
The optional argument @var{base-url}, if non-@code{nil}, should be a
string specifying the base URL for relative URLs occurring in links.
If the optional argument @var{discard-comments} is non-@code{nil},
any top-level comment is discarded. (This argument is obsolete and

View file

@ -1183,16 +1183,13 @@ wants the current value of a variable, it looks first in the lexical
environment; if the variable is not specified in there, it looks in
the symbol's value cell, where the dynamic value is stored.
(Internally, the lexical environment is a list whose members are
usually cons cells that are symbol-value pairs, but some of its
members can be symbols rather than cons cells. A symbol in the list
means the lexical environment declared that symbol's variable as
locally considered to be dynamically bound. This list can be passed
as the second argument to the @code{eval} function, in order to
specify a lexical environment in which to evaluate a form.
@xref{Eval}. Most Emacs Lisp programs, however, should not interact
directly with lexical environments in this way; only specialized
programs like debuggers.)
(Internally, the lexical environment is an alist of symbol-value
pairs, with the final element in the alist being the symbol @code{t}
rather than a cons cell. Such an alist can be passed as the second
argument to the @code{eval} function, in order to specify a lexical
environment in which to evaluate a form. @xref{Eval}. Most Emacs
Lisp programs, however, should not interact directly with lexical
environments in this way; only specialized programs like debuggers.)
@cindex closures, example of using
Lexical bindings have indefinite extent. Even after a binding
@ -2561,9 +2558,6 @@ documentation as @var{base-variable} has, if any, unless
the documentation of the variable at the end of the chain of aliases.
This function returns @var{base-variable}.
If the resulting variable definition chain would be circular, then
Emacs will signal a @code{cyclic-variable-indirection} error.
@end defun
Variable aliases are convenient for replacing an old name for a
@ -2612,6 +2606,9 @@ look like:
This function returns the variable at the end of the chain of aliases
of @var{variable}. If @var{variable} is not a symbol, or if @var{variable} is
not defined as an alias, the function returns @var{variable}.
This function signals a @code{cyclic-variable-indirection} error if
there is a loop in the chain of symbols.
@end defun
@example

View file

@ -3216,7 +3216,7 @@ 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}).
@vindex preserve-size@r{, a buffer display action alist entry}
@item preserve-size

View file

@ -5394,7 +5394,7 @@ a variable containing a vector of rules.
1: [merge, secsqr] 1: [a/x + b/x := (a + b)/x, ... ]
. .
' [merge,secsqr] @key{RET} =
' [merge,sinsqr] @key{RET} =
@end group
@end smallexample

View file

@ -330,7 +330,6 @@ Syntactic Symbols
* Multiline Macro Symbols::
* Objective-C Method Symbols::
* Java Symbols::
* Constraint Symbols::
* Statement Block Symbols::
* K&R Symbols::
@ -4235,9 +4234,6 @@ The first line in a ``topmost'' definition. @ref{Function Symbols}.
Topmost definition continuation lines. This is only used in the parts
that aren't covered by other symbols such as @code{func-decl-cont} and
@code{knr-argdecl}. @ref{Function Symbols}.
@item constraint-cont
Continuation line of a topmost C++20 concept or requires clause.
@ref{Constraint Symbols}.
@item annotation-top-cont
Topmost definition continuation lines where all previous items are
annotations. @ref{Java Symbols}.
@ -4401,7 +4397,6 @@ Java. @ref{Java Symbols}.
* Multiline Macro Symbols::
* Objective-C Method Symbols::
* Java Symbols::
* Constraint Symbols::
* Statement Block Symbols::
* K&R Symbols::
@end menu
@ -5075,39 +5070,6 @@ the current line. Similarly, line 4 is assigned the @code{annotation-var-cont}
syntax due to it being a continuation of a variable declaration where preceding
the declaration is an annotation.
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@node Constraint Symbols
@subsection C++ Constraint Symbols
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
The C++20 standard introduced the notion of @dfn{concepts} and
@dfn{requirements}, a typical instance of which looks something like
this:
@example
1: template <typename T>
2: requires
3: requires (T t) @{
4: @{ ++t; @}
5: @}
6: && std::is_integral<T>
7: int foo();
@end example
@ssindex constraint-cont
Line 1 is assigned the familiar @code{topmost-intro}. Line 2 gets
@code{topmost-intro-cont}, being the keyword which introduces a
@dfn{requires clause}. Lines 3, 6, and 7 are assigned the syntax
@code{constraint-cont}, being continuations of the requires clause
started on line 2. Lines 4 and 5 get the syntaxes
@code{defun-block-intro} and @code{defun-close}, being analyzed as
though part of a function.
Note that the @code{requires} on Line 3 begins a @dfn{requires
expression}, not a a requires clause, hence its components are not
assigned @code{constraint-cont}. See
@url{https://en.cppreference.com/w/cpp/language/requires}.
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@node Statement Block Symbols
@subsection Statement Block Symbols

View file

@ -3133,23 +3133,13 @@ example, you can put the following in your init file:
To avoid the slightly distracting visual effect of Emacs starting with
its default frame size and then growing to fullscreen, you can add an
@samp{Emacs.Geometry} entry to the Windows Registry settings. @xref{X
Resources,,, emacs, The GNU Emacs Manual}. To compute the correct
values for width and height you use in the Registry settings, first
maximize the Emacs frame and then evaluate @code{(frame-height)} and
@samp{Emacs.Geometry} entry to the Windows registry settings.
@xref{X Resources,,, emacs, The GNU Emacs Manual}.
To compute the correct values for width and height, first maximize the
Emacs frame and then evaluate @code{(frame-height)} and
@code{(frame-width)} with @kbd{M-:}.
Alternatively, you can avoid the visual effect of Emacs changing its
frame size entirely in your init file (i.e., without using the
Registry), like this:
@lisp
(setq frame-resize-pixelwise t)
(set-frame-position nil 0 0)
(set-frame-size nil (display-pixel-width) (display-pixel-height) t)
@end lisp
@node Emacs in a Linux console
@section How can I alleviate the limitations of the Linux console?
@cindex Console, Linux console, TTY, fbterm

View file

@ -1265,7 +1265,7 @@ is serialized by Eglot to the following JSON text:
@chapter Troubleshooting Eglot
@cindex troubleshooting Eglot
This chapter documents commands and variables that can be used to
This section documents commands and variables that can be used to
troubleshoot Eglot problems. It also provides guidelines for
reporting Eglot bugs in a way that facilitates their resolution.
@ -1275,15 +1275,7 @@ pop up special buffers that can be used to inspect the communications
between the Eglot and language server. In many cases, this will
indicate the problems or at least provide a hint.
@menu
* Performance::
* Getting the latest version::
* Reporting bugs::
@end menu
@node Performance
@section Performance
@cindex performance problems, with Eglot
@cindex performance
A common and easy-to-fix cause of performance problems is the length
of the Eglot events buffer because it represent additional work that
Eglot must do. After verifying Eglot is operating correctly but
@ -1297,33 +1289,6 @@ techniques to improve their performance. Often, this can be tweaked
by changing the server configuration (@pxref{Advanced server
configuration}).
@node Getting the latest version
@section Getting the latest version
@cindex upgrading Eglot
To install the latest Eglot in an Emacs version that does not bundle
Eglot, use @kbd{M-x package-install}.
Often, a newer Eglot version exists that has fixed a longstanding bug,
has more LSP features, or just better supports a particular language
server. Recent Eglot versions can self-update via the command
@kbd{M-x eglot-upgrade-eglot}. This will replace any currently
installed version with the newest one available from the ELPA archives
configured in @code{package-archives}.
You can also update Eglot through other methods, such as
@code{use-package} (@pxref{Installing packages,,, use-package,
use-package User Manual}), @code{package-install},
@code{list-packages} or the newer @code{package-upgrade}
(@pxref{Packages,,, emacs, GNU Emacs Manual}). However, do read the
docstrings of the command you intend to use before you use it, as some
of them may not work in exactly the same way across Emacs versions,
meaning your configuration may be not portable.
@node Reporting bugs
@section Reporting bugs
@cindex bug reports
If you think you have found a bug, we want to hear about it. Before
reporting a bug, keep in mind that interaction with language servers
represents a large quantity of unknown variables. Therefore, it is
@ -1367,10 +1332,6 @@ public Git repository.
Include versions of the software used. The Emacs version can be
obtained with @kbd{M-x emacs-version}.
We welcome bug reports about all Eglot versions, but it is helpful to
first check if the problem isn't already fixed in the latest version
(@pxref{Getting the latest version}).
It's also essential to include the version of ELPA packages that are
explicitly or implicitly loaded. The optional but popular Company or
Markdown packages are distributed as GNU ELPA packages, not to mention

View file

@ -952,7 +952,7 @@ Here, ``password'' refers to your account password, which is usually
your @samp{NickServ} password. To make this work, customize
@code{erc-sasl-user} and @code{erc-sasl-password} or specify the
@code{:user} and @code{:password} keyword arguments when invoking
@code{erc-tls}.
@code{erc-tls}. Note that @code{:user} cannot be given interactively.
@item @code{external} (via Client TLS Certificate)
This works in conjunction with the @code{:client-certificate} keyword
@ -1477,30 +1477,10 @@ questions. You can also try the relatively quiet @samp{#erc}, on the
same network, for more involved questions.
@item
@anchor{Upgrading}
You can check GNU ELPA between Emacs releases to see if a newer
version is available that might contain a fix for your issue:
@uref{https://elpa.gnu.org/packages/erc.html}.
To upgrade, run @kbd{M-x list-packages @key{RET}}. In the
@file{*Packages*} (@code{package-menu-mode}) buffer, click the
@samp{erc} package link for the desired version. If unsure, or if the
version column is too narrow to tell, try the bottom-most candidate.
In the resulting @code{help-mode} buffer, confirm the version and
click @samp{Install}. Make sure to restart Emacs before reconnecting
to IRC, and don't forget that you can roll back to the previous
version by running @kbd{M-x package-delete @key{RET}}.
@xref{Packages,,,emacs, the Emacs manual} for more information.
In the rare instance you need an emergency fix or have volunteered to
test an edge feature between ERC releases, you can try adding
@samp{("devel" . "https://elpa.gnu.org/devel/")} to
@code{package-archives} prior to performing the steps above. For
this, you'll want to instead select a ``snapshot'' version from the
menu. Please be aware that when going this route, the latest changes
may not yet be available and you run the risk of incurring other bugs
and encountering unstable features.
@item
To report a bug in ERC, use @kbd{M-x erc-bug}.

View file

@ -602,8 +602,6 @@ disabled by default.
@cmindex egrep
@itemx fgrep
@cmindex fgrep
@itemx rgrep
@cmindex rgrep
@itemx glimpse
@cmindex glimpse
The @command{grep} commands are compatible with GNU @command{grep},

View file

@ -1,8 +1,8 @@
\input texinfo @c -*- mode: texinfo; coding: utf-8 -*-
@comment %**start of header
@setfilename ../../info/flymake.info
@set VERSION 1.3.4
@set UPDATED April 2023
@set VERSION 1.2.2
@set UPDATED November 2021
@settitle GNU Flymake @value{VERSION}
@include docstyle.texi
@syncodeindex pg cp
@ -142,12 +142,6 @@ highlighted regions to learn what the specific problem
is. Alternatively, place point on the highlighted regions and use the
commands @code{eldoc} or @code{display-local-help}.
Another easy way to get instant access to the diagnostic text is to
set @code{flymake-show-diagnostics-at-end-of-line} to a non-@code{nil}
value. This makes the diagnostic messages appear at the end of the
line where the regular annotation is located (@pxref{Customizable
variables})
@cindex next and previous diagnostic
If the diagnostics are outside the visible region of the buffer,
@code{flymake-goto-next-error} and @code{flymake-goto-prev-error} are
@ -320,22 +314,6 @@ Which fringe (if any) should show the warning/error bitmaps.
@item flymake-wrap-around
If non-@code{nil}, moving to errors with @code{flymake-goto-next-error} and
@code{flymake-goto-prev-error} wraps around buffer boundaries.
@item flymake-show-diagnostics-at-end-of-line
If non-@code{nil}, show summarized descriptions of diagnostics at the
end of the line. Depending on your preference, this can either be
distracting and easily confused with actual code, or a significant
early aid that relieves you from moving around or reaching for the
mouse to consult an error message.
@item flymake-error-eol
A custom face for summarizing diagnostic error messages.
@item flymake-warning-eol
A custom face for summarizing diagnostic warning messages.
@item flymake-note-eol
A custom face for summarizing diagnostic notes.
@end vtable
@node Extending Flymake
@ -416,7 +394,7 @@ its @code{flymake-overlay-control} property:
@item
@cindex severity of diagnostic
@code{severity} is a non-negative integer specifying the
@code{flymake-severity} is a non-negative integer specifying the
diagnostic's severity. The higher the value, the more serious is the
error. If the overlay property @code{priority} is not specified in
@code{flymake-overlay-control}, @code{flymake-severity} is used to set
@ -431,17 +409,6 @@ type, in case the name of the symbol associated with it is very long.
@vindex flymake-category
@code{flymake-category} is a symbol whose property list is considered
the default for missing values of any other properties.
@item
@cindex mode-line appearance of a diagnostic
@code{mode-line-face} is a face specifier controlling the appearance
of the indicator of this type of diagnostic in the mode line.
@item
@cindex summarized appearance of a diagnostic
@code{echo-face} is a face specifier controlling the appearance of the
summarized description of this diagnostic when reading diagnostic
messages (@pxref{Finding diagnostics}).
@end itemize
@cindex predefined diagnostic types

View file

@ -10528,9 +10528,9 @@ article (@code{gnus-summary-refer-references}).
@kindex A T @r{(Summary)}
Display the full thread where the current article appears
(@code{gnus-summary-refer-thread}). By default this command looks for
articles only in the current group. If the group belongs to a backend
that has an associated search engine, articles are found by searching.
In other cases each header in the current group must be fetched and
articles only in the current group. Some backends (currently only
@code{nnimap}) know how to find articles in the thread directly. In
other cases each header in the current group must be fetched and
examined, so it usually takes a while. If you do it often, you may
consider setting @code{gnus-fetch-old-headers} to @code{invisible}
(@pxref{Filling In Threads}). This won't have any visible effects
@ -10538,22 +10538,19 @@ normally, but it'll make this command work a whole lot faster. Of
course, it'll make group entry somewhat slow.
@vindex gnus-refer-thread-use-search
If @code{gnus-refer-thread-use-search} is @code{nil} (the default)
then thread-referral only looks for articles in the current group. If
this variable is @code{t} the server to which the current group
belongs is searched (provided that searching is available for the
server's backend). If this variable is a list of servers, each server
in the list is searched.
If @code{gnus-refer-thread-use-search} is non-@code{nil} then those backends
that know how to find threads directly will search not just in the
current group but all groups on the same server.
@vindex gnus-refer-thread-limit
The @code{gnus-refer-thread-limit} variable says how many old (i.e.,
articles before the first displayed in the current group) headers to
fetch when referring a thread. The default is 500. If @code{t}, all
the available headers will be fetched. This variable can be
overridden by giving the @kbd{A T} command a numerical prefix.
fetch when doing this command. The default is 200. If @code{t}, all
the available headers will be fetched. This variable can be overridden
by giving the @kbd{A T} command a numerical prefix.
@vindex gnus-refer-thread-limit-to-thread
@code{gnus-summary-refer-thread} tries to add any articles it finds to
In most cases @code{gnus-refer-thread} adds any articles it finds to
the current summary buffer. (When @code{gnus-refer-thread-use-search}
is true and the initial referral starts from a summary buffer for a
non-virtual group this may not be possible. In this case a new

View file

@ -1948,9 +1948,11 @@ requires the @acronym{POP}-before-@acronym{SMTP} authentication.
@cindex X-Message-SMTP-Method
If you have a complex @acronym{SMTP} setup, and want some messages to
go via one mail server, and other messages to go through another, you
can use the @samp{X-Message-SMTP-Method} header to override the
default by using the keyword @samp{smtp} followed by the server
information:
can use the @samp{X-Message-SMTP-Method} header. These are the
supported values:
@table @samp
@item smtpmail
@example
X-Message-SMTP-Method: smtp smtp.fsf.org 587
@ -1966,19 +1968,16 @@ 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.
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
example:
@item sendmail
@example
X-Message-SMTP-Method: sendmail
@end example
will send the message via the locally installed sendmail program. The
recognized values of @samp{mailer} are sendmail, qmail, mh, and
mailclient.
This will send the message via the locally installed sendmail/exim/etc
installation.
@end table
@item message-mh-deletable-headers
@vindex message-mh-deletable-headers

View file

@ -5958,9 +5958,8 @@ the agenda (see [[*Weekly/daily agenda]]). We distinguish:
#+findex: org-block
For more complex date specifications, Org mode supports using the
special expression diary entries implemented in the
[[info:emacs#Special Diary Entries][Emacs Calendar package]][fn:20].
For example, with optional time:
special expression diary entries implemented in the Emacs Calendar
package[fn:20]. For example, with optional time:
#+begin_example
,* 22:00-23:00 The nerd meeting on every 2nd Thursday of the month

View file

@ -938,16 +938,6 @@ be used.
This method does not support user names.
@item @option{flatpak}
@cindex method @option{flatpak}
@cindex @option{flatpak} method
Integration of Flatpak sandboxes. The host name may be either an
application ID, a sandbox instance ID, or a PID, as returned by
@samp{flatpak ps}.
This method does not support user names.
@end table
@ -4377,6 +4367,7 @@ Flushes the current buffer's remote connection objects, the same as in
Flushes all active remote connection objects, the same as in
@code{tramp-cleanup-connection}. This command removes also ad-hoc
proxy definitions (@pxref{Ad-hoc multi-hops}).
@end deffn
@deffn Command tramp-cleanup-all-buffers
@ -4385,20 +4376,6 @@ connections and ad-hoc proxy definition are cleaned up in addition to
killing all buffers related to remote connections.
@end deffn
@deffn Command tramp-cleanup-some-buffers
Similar to @code{tramp-cleanup-all-buffers}, where all remote
connections and ad-hoc proxy definition are cleaned up. However,
additional buffers are killed only if one of the functions in
@code{tramp-cleanup-some-buffers-hook} returns @code{t}.
@end deffn
@defopt tramp-cleanup-some-buffers-hook
The functions in this hook determine, whether a remote buffer is
killed when @code{tramp-cleanup-some-buffers} is called. Per default,
remote buffers which are linked to a remote file, remote @code{dired}
buffers, and buffers related to a remote process are cleaned up.
@end defopt
@node Renaming remote files
@section Renaming remote files

View file

@ -17,32 +17,6 @@ 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 in Eglot 1.15 (29/4/2023)
** Fix LSP "languageId" detection
Many servers today support multiple languages, meaning they can handle
more than one file type in the same connection. This relies on the
client supplying a ':languageId' string. Previously, Eglot calculated
this string based on an imperfect heuristic and was often wrong. See
github#1206.
** Fix problems with missing signature documentation (bug#62687)
** Reworked 'eglot-imenu'
Eglot's Imenu backend (used for M-x imenu among other extensions), has
been reworked. Most newer servers respond to
'textDocument/documentSymbol' with a vector of 'DocumentSymbol', not
'SymbolInformation'. It's not worth it trying to make the two formats
resemble each other. This also lays groundwork supporting a
forthcoming "breadcrumb" feature of bug#58431.
** New command 'eglot-update'
This allows users to easily update to the latest version of Eglot.
* Changes in Eglot 1.14 (3/4/2023)
@ -96,16 +70,6 @@ been added to 'eglot-stay-out-of'.
** ELPA installations on Emacs 26.3 are supported again.
* Changes in Eglot 1.12.29 (Eglot bundled with Emacs 29.1)
** Eglot can upgrade itself to the latest version.
The new command 'eglot-upgrade-eglot' works around behaviour in the
existing 'package-install' command and the new 'package-upgrade'
command which would prevent the user from easily grabbing the latest
version as usual.
* Changes in Eglot 1.12 (13/03/2023)
@ -129,7 +93,7 @@ The position-encoding scheme (UTF-8, UTF-16 or UTF-32) can now
be negotiated with the server.
** More of the user's Eldoc configuration is respected.
This change addresses the problems reported in many Eglot reports
This change addresses the problems reported in many Elglot reports
dating back to early 2021 at least.
(github#646, github#894, github#920, github#1031, github#1171).
@ -175,7 +139,7 @@ systems (bug#58790).
These modes are usually handled by the same server that handles the
"classical mode".
** New servers csharp-ls and texlab added to 'eglot-server-programs'.
** New servers chsharp-ls and texlab added to 'eglot-server-programs'.
** Assorted bugfixes.
(bug#59824, bug#59338)

View file

@ -11,210 +11,6 @@ This file is about changes in ERC, the powerful, modular, and
extensible IRC (Internet Relay Chat) client distributed with
GNU Emacs since Emacs version 22.1.
* Changes in ERC 5.6
** Module 'keep-place' now offers a visual indicator.
Remember your place in ERC buffers a bit more easily while retaining
the freedom to look around. Optionally sync the indicator to any
progress made when you haven't yet caught up to the live stream. See
options 'erc-keep-place-indicator-style' and friends and new module
'keep-place-indicator', which for now must be added manually to
'erc-modules'.
** Module 'fill' now offers a style based on 'visual-line-mode'.
This fill style mimics the "hanging indent" look of 'erc-fill-static'
and provides some movement and editing commands to optionally tame the
less familiar aspects of 'visual-line' behavior. An interactive
helper called 'erc-fill-wrap-nudge' allows for dynamic "refilling" of
buffers on the fly. Set 'erc-fill-function' to 'erc-fill-wrap' to get
started.
** A unified interactive entry point.
New users are often dismayed to discover that M-x ERC doesn't connect
to its default network, Libera.Chat, over TLS. Though perhaps a
decade overdue, this is no longer the case. Other UX improvements in
this area aim to make the process of connecting interactively slightly
more streamlined and less repetitive, even for veteran users.
** Revised buffer-display handling for interactive commands.
A point of friction for new users and one only just introduced with
ERC 5.5 has been the lack of visual feedback when first connecting via
M-x erc or when issuing a "/JOIN" command at the prompt. As explained
below, in the news for 5.5, the discovery of a security issue led to
most new ERC buffers being "buried" on creation. On further
reflection, this was judged to have been an overcorrection in the case
of interactive invocations, hence the borrowing of an old option,
'erc-query-display', and the bestowing of a new alias,
'erc-interactive-display', which better describes its expanded role as
a more general buffer-display knob for interactive commands ("/QUERY"
still among them).
Accompanying this addition are "display"-suffixed aliases for related
options 'erc-join-buffer' and 'erc-auto-query', which users have
reported as being difficult to discover and remember. When the latter
option (now known as 'erc-receive-query-display') is nil, ERC uses
'erc-join-buffer' in its place, much like it does for
'erc-interactive-display'. The old nil behavior can still be gotten
via the new compatibility flag 'erc-receive-query-display-defer'.
** Setting a module's mode variable via Customize earns a warning.
Trying and failing to activate a module via its minor mode's Custom
widget has been an age-old annoyance for new users. Previously
ineffective, this method now actually works, but it also admonishes
users to edit the 'erc-modules' widget instead.
** The option 'erc-timestamp-use-align-to' is more versatile.
While this option has always offered to right-align stamps via the
'display' text property, it's now more effective at doing so when set
to a number indicating an offset from the right edge. And when set to
the symbol 'margin', it displays stamps in the right margin, although,
at the moment, this is mostly intended for use by other modules, such
as 'fill-wrap', described above. For both these variants, users of
the 'log' module may want to customize 'erc-log-filter-function' to
'erc-stamp-prefix-log-filter' to avoid ragged right-hand stamps
appearing in their saved logs.
** Smarter reconnect handling for users on the move.
ERC now offers a new, experimental reconnect strategy in the function
'erc-server-delayed-check-reconnect', which tests for underlying
connectivity before attempting to reconnect in earnest. See options
'erc-server-reconnect-function' and 'erc-nickname-in-use-functions' to
get started.
** Easily constrain all ERC-related business to a dedicated frame.
The option 'erc-reuse-frames' can now be set to 'displayed', which
tells ERC to show new buffers in frames already occupied by buffers
from the same connection. This customization depends on the option
'erc-buffer-display' (formerly 'erc-join-buffer') being set to
'frame'. If you find the name 'displayed' unhelpful, please suggest
an alternative by writing to the mailing list.
** Some keybindings are now set by modules rather than their libraries.
To put it another way, simply loading a built-in module's library no
longer modifies 'erc-mode-map'. Instead, modifications occur during
module setup. This should not impact most user configs since ERC
doesn't bother with keys already taken and only removes bindings it's
previously created. Note that while all affected bindings still
reside in 'erc-mode-map', future built-in modules will use their own
minor-mode maps, and new third-party modules should do the same.
** The option 'erc-timestamp-format-right' has been deprecated.
Having to account for this option prevented other ERC modules from
easily determining what right-hand stamps would look like before
insertion, which is knowledge needed for certain UI decisions. The
way ERC has chosen to address this is imperfect and boils down to
asking users who've customized this option to switch to
'erc-timestamp-format' instead. If you're affected by this and feel
that some other solution, like automatic migration, is justified,
please make that known on the bug list.
** The 'nicknames' entry in 'erc-button-alist' is officially exceptional.
It's no secret that the 'buttons' module treats potential nicknames
specially. To simplify ERC's move to next-gen "rich UI" extensions,
this special treatment is being canonized. From now on, all values
other than the symbol 'erc-button-buttonize-nicks' appearing in the
"FORM" field (third element) of this entry are considered deprecated
and will incur a warning.
** Option 'erc-query-on-unjoined-chan-privmsg' restored and renamed.
This option was accidentally removed from the default client in ERC
5.5 and was thus prevented from influencing PRIVMSG routing. It's now
been restored with a slightly revised role contingent on a few
assumptions explained in its doc string. For clarity, it has been
renamed 'erc-ensure-target-buffer-on-privmsg'.
** Miscellaneous UX changes.
Some minor quality-of-life niceties have finally made their way to
ERC. For example, the function 'erc-echo-timestamp' is now
interactive and can be invoked on any message to view its timestamp in
the echo area. The command 'erc-button-previous' now moves to the
beginning instead of the end of buttons. And the 'irccontrols' module
now supports additional colors and special handling for "spoilers"
(hidden text).
** Changes in the library API.
*** Some top-level dependencies have been removed.
The library 'erc-goodies' is no longer loaded by ERC's main library.
This was done to further cement the move toward a unidirectional
dependency flow begun in 5.5. Additionally, a few barely used and
newly introduced dependencies are now lazily loaded, which may upset
some third-party code. The first of these is 'pp' because its
'pp-to-string' is autoloaded in all supported ERC versions. Also gone
are 'thingatpt', 'time-date', and 'iso8601'. All were used ultra
sparingly, and the latter two have only been around for one minor
release cycle, so their removal hopefully won't cause much churn.
*** Some ERC-applied text properties have changed.
Chiefly, 'rear-sticky' has been replaced by 'erc-command', which
records the IRC command (or numeric) associated with a message. Less
impactfully, the value of the 'field' property for ERC's prompt has
changed from 't' to the more useful 'erc-prompt', although the
property of the same name has been retained.
*** ERC now manages timestamp-related properties a bit differently.
For starters, the 'cursor-sensor-functions' property no longer
contains unique closures and thus no longer proves effective for
traversing messages. To compensate, a new property, 'erc-timestamp',
now spans message bodies but not the newlines delimiting them.
Somewhat relatedly, the function 'erc-insert-aligned' has been
deprecated and removed from the primary client code path.
*** The role of a module's Custom group is now more clearly defined.
Associating built-in modules with Custom groups and provided library
features has improved. More specifically, a module's group now enjoys
the singular purpose of determining where the module's minor mode
variable lives in the Customize interface. And although ERC is now
slightly more adept at linking these entities, third-parties are still
encouraged to keep a module's name aligned with its group's as well as
the provided feature of its containing library, if only for the usual
reasons of namespace hygiene and discoverability.
*** ERC now supports arbitrary CHANTYPES.
Specifically, channels can be prefixed with any predesignated
character, mainly to afford more flexibility to specialty services,
like bridges to other protocols.
*** 'erc-cmd-HELP' recognizes subcommands.
Some IRC "slash" commands are hierarchical and require users to
specify a subcommand to actually carry out anything of consequence.
Built-in modules can now provide more detailed help for a particular
subcommand by telling ERC to defer to a specialized handler.
*** Longtime quasi modules have been made proper.
The 'fill' module is now defined by 'define-erc-module'. The same
goes for ERC's imenu integration, which has 'imenu' now appearing in
the default value of 'erc-modules'.
*** Prompt input is split before 'erc-pre-send-functions' has a say.
Hook members are now treated to input whose lines have already been
adjusted to fall within the allowed length limit. For convenience,
third-party code can request that the final input be "re-filled" prior
to being sent. See doc string for details.
*** ERC's prompt survives the insertion of user input and messages.
Previously, ERC's prompt and its input marker disappeared while
running hooks during message insertion, and the position of its
"insert marker" (ERC's per-buffer process mark) was inconsistent
during these spells. To make insertion handling more predictable in
preparation for incorporating various protocol extensions, the prompt
and its bounding markers have become perennial fixtures. In rare
cases, these changes may mean third-party code needs tweaking, for
example, requiring the use of 'insert-before-markers' instead of
'insert'. As always, users feeling unduly inconvenienced by these
changes are encouraged to voice their concerns on the bug list.
*** Miscellaneous changes
Two helper macros from GNU ELPA's Compat library are now available to
third-party modules as 'erc-compat-call' and 'erc-compat-function'.
In the area of buttons, 'Info-goto-node' has been supplanted by plain
old 'info' in 'erc-button-alist', and the bracketed "<URL:...>"
pattern entry has been removed because it was more or less redundant.
And the "TAB" key is now bound to a new command, 'erc-tab', that only
calls 'completion-at-point' when point is in the input area and
module-specific commands, like 'erc-button-next', otherwise.
* Changes in ERC 5.5
@ -359,8 +155,8 @@ In an effort to help further tame ERC's complexity, the variable
'erc-default-recipients' is now expected to hold but a single target.
As a consequence, functions like 'erc-add-default-channel' that
imagine an alternate, aspirational model of buffer-target relations
have been deprecated. Grep for their names in ChangeLog.4 for
details.
have been deprecated. See Emacs change-log entries from around July
of 2022 for specifics.
A number of less consequential deprecations also debut in this
release. For example, the function 'erc-auto-query' was deemed too

View file

@ -89,9 +89,7 @@ Mathematics ∀ p ∈ world • hello p □
Meetei Mayek (ꯃꯤꯇꯩ ꯃꯌꯦꯛ) ꯈꯨꯔꯨꯝꯖꯔꯤ
Mende Kikakui (𞠀𞠁𞠂) 𞠛𞠉
Modi (𑘦𑘻𑘚𑘲) 𑘡𑘦𑘭𑘿𑘎𑘰𑘨
Mongolian Cyrillic (монгол хэл) Сайн байна уу?
Mongolian Traditional (ᠮᠣᠩᠭᠣᠯ ᠪᠢᠴᠢᠭ᠋) ᠰᠠᠶᠢᠨ ᠪᠠᠶᠢᠨ᠎ᠠ ᠤᠤ?
Mongolian (монгол хэл) Сайн байна уу?
Northern Thai (ᨣᩣᩴᨾᩮᩬᩥᨦ / ᨽᩣᩈᩣᩃ᩶ᩣ᩠ᨶᨶᩣ) ᩈ᩠ᩅᩢᩔ᩠ᨯᩦᨣᩕᩢ᩠ᨸ
Norwegian (norsk) Hei / God dag
Odia (ଓଡ଼ିଆ) ନମସ୍କାର

133
etc/NEWS
View file

@ -30,11 +30,6 @@ applies, and please also update docstrings as needed.
* Changes in Emacs 30.1
---
** New user option 'describe-bindings-outline-rules'.
This user option controls outline visibility in the output buffer of
'describe-bindings' when 'describe-bindings-outline' in non-nil.
** X selection requests are now handled much faster and asynchronously.
This means it should be less necessary to disable the likes of
'select-active-regions' when Emacs is running over a slow network
@ -71,11 +66,6 @@ This allows the user to customize the prompt that is appended by
This is used for displaying the time and date components of
'display-time-mode'.
---
** New icon images for general use.
Several symbolic icons are added to "etc/images/symbols", including
plus, minus, check-mark, start, etc.
* Editing Changes in Emacs 30.1
@ -110,7 +100,7 @@ If you want to get back the old behavior, set the user option to the value
(setopt gdb-locals-table-row-config
`((type . 0) (name . 0) (value . ,gdb-locals-value-limit)))
** Grep
** Compile
*** New user option 'grep-use-headings'.
When non-nil, the output of Grep is split into sections, one for each
@ -184,16 +174,11 @@ correctly unloads Eshell and all of its modules.
After manually editing 'eshell-aliases-file', you can use this command
to load the edited aliases.
+++
*** 'rgrep' is now a builtin command.
Running 'rgrep' in Eshell now uses the Emacs grep facility instead of
calling external rgrep.
** Shell Mode
+++
*** New user option 'shell-get-old-input-include-continuation-lines'.
When this user option is non-nil, 'shell-get-old-input' ('C-RET')
When this user option is non-nil, 'shell-get-old-input' (C-RET)
includes multiple shell "\" continuation lines from command output.
Default is nil.
@ -209,23 +194,16 @@ point is not in a comment or a string. It is by default bound to
** Tramp
+++
*** New connection methods "toolbox" and "flatpak".
They allow accessing system containers provided by Toolbox or
sandboxes provided by Flatpak.
*** New connection method "toolbox".
This allows accessing system containers provided by Toolbox.
+++
*** Rename 'tramp-use-ssh-controlmaster-options' to 'tramp-use-connection-share'.
The old name still exists as obsolete variable alias. This user
option controls now connection sharing for both ssh-based and
plink-based methods. It allows the values t, nil, and 'suppress'.
The latter suppresses also "ControlMaster" settings in the user's
"~/.ssh/config" file, or connection share configuration in PuTTY
sessions, respectively.
+++
*** New command 'tramp-cleanup-some-buffers'.
It allows to kill only selected remote buffers, controlled by user
option 'tramp-cleanup-some-buffers-hook'.
*** Rename 'tramp-use-ssh-controlmaster-options' to 'tramp-use-connection-share.
The old name still exists as defvaralias. This user option controls
now connection sharing for both ssh-based and plink-based methods. It
allows the values t, nil, and 'suppress'. The latter suppresses
also "ControlMaster" settings in the user's "~/.ssh/config" file,
or connection share configuration in PuTTY sessions, respectively.
** EWW
@ -236,17 +214,6 @@ the new argument NEW-BUFFER non-nil, it will use a new buffer instead.
Interactively, invoke 'eww-open-file' with a prefix argument to
activate this behavior.
---
*** 'eww' URL or keyword prompt now has tab completion.
The interactive minibuffer prompt when invoking 'eww' now has support
for tab completion.
+++
*** 'eww' URL and keyword prompt now completes suggested URIs and bookmarks.
The interactive minibuffer prompt when invoking 'eww' now provides
completions from 'eww-suggest-uris'. 'eww-suggest-uris' now includes
bookmark URIs.
** go-ts-mode
+++
@ -294,34 +261,6 @@ When non-nil, it will automatically register every package as a
project, that you can quickly select using 'project-switch-project'
('C-x p p').
** Flymake
+++
*** New user option 'flymake-show-diagnostics-at-end-of-line'.
When non-nil, Flymake shows summarized descriptions of diagnostics at
the end of the line. Depending on your preference, this can either be
distracting and easily confused with actual code, or a significant
early aid that relieves you from moving the buffer or reaching for the
mouse to consult an error message.
** Python Mode
---
*** New user option 'python-indent-block-paren-deeper'.
If non-nil, increase the indentation of the lines inside parens in a
header of a block when they are indented to the same level as the body
of the block:
if (some_expression
and another_expression):
do_something()
instead of:
if (some_expression
and another_expression):
do_something()
* New Modes and Packages in Emacs 30.1
@ -380,7 +319,7 @@ hooks named after the feature name, like 'esh-mode-unload-hook'.
* Lisp Changes in Emacs 30.1
** New variable 'inhibit-auto-fill' to temporarily prevent auto-fill.
** New var 'inhibit-auto-fill' to temporarily prevent auto-fill.
** Functions and variables to transpose sexps
@ -496,7 +435,7 @@ any unwind forms, as in
(unwind-protect (read buffer))
because the behavior is identical to that of the argument; there is
because the behaviour is identical to that of the argument; there is
no protection of any kind. Perhaps the intended unwind forms have
been misplaced or forgotten, or the use of 'unwind-protect' could be
simplified away.
@ -504,50 +443,26 @@ simplified away.
This warning can be suppressed using 'with-suppressed-warnings' with
the warning name 'suspicious'.
---
*** Warn about more ignored function return values.
The compiler now warns when the return value from certain functions is
implicitly ignored. Example:
(progn (nreverse my-list) my-list)
will elicit a warning because it is usually pointless to call
'nreverse' on a list without using the returned value.
To silence the warning, make use of the value in some way, such as
assigning it to a variable. You can also wrap the function call in
'(ignore ...)', or use 'with-suppressed-warnings' with the warning
name 'ignored-return-value'.
The warning will only be issued for calls to functions declared
'important-return-value' or 'side-effect-free' (but not 'error-free').
+++
** New function 'file-user-uid'.
This function is like 'user-uid', but is aware of file name handlers,
so it will return the remote UID for remote files (or -1 if the
connection has no associated user).
+++
** New function declaration and property 'important-return-value'.
The declaration '(important-return-value t)' sets the
'important-return-value' property which indicates that the function
return value should probably not be thrown away implicitly.
+++
** New functions 'file-user-uid' and 'file-group-gid'.
These functions are like 'user-uid' and 'group-gid', respectively, but
are aware of file name handlers, so they will return the remote UID or
GID for remote files (or -1 if the connection has no associated user).
+++
** 'fset', 'defalias' and 'defvaralias' now signal an error for cyclic aliases.
Previously, 'fset', 'defalias' and 'defvaralias' could be made to
build circular function and variable indirection chains as in
** 'fset' and 'defalias' now signal an error for circular alias chains.
Previously, 'fset' and 'defalias' could be made to build circular
function indirection chains as in
(defalias 'able 'baker)
(defalias 'baker 'able)
but trying to use them would sometimes make Emacs hang. Now, an attempt
but trying to call them would often make Emacs hang. Now, an attempt
to create such a loop results in an error.
Since circular alias chains now cannot occur, 'function-alias-p',
'indirect-function' and 'indirect-variable' will never signal an error.
Their 'noerror' arguments have no effect and are therefore obsolete.
Since circular alias chains now cannot occur, 'function-alias-p' and
'indirect-function' will never signal an error. Their second
'noerror' arguments have no effect and are therefore obsolete.
* Changes in Emacs 30.1 on Non-Free Operating Systems

View file

@ -218,13 +218,13 @@ of 'user-emacs-directory'.
+++
** The image commands have changed key bindings.
In previous Emacs versions, the '+', '-' and 'r' keys were bound when
point was over an image. In Emacs 29.1, additional commands have been
added, and this made it more likely that users would trigger the image
commands by mistake. To avoid this, all image commands have been
moved to the 'i' prefix keymap, so '+' is now 'i +', '-' is now 'i -',
and 'r' is now 'i r'. In addition, these commands are now repeating,
so you can rotate an image twice by saying 'i r r', for instance.
In previous Emacs versions, images have had the '+', '-' and 'r' keys
bound when point is over an image. In Emacs 29.1, additional commands
were added, and this made it more likely that users would trigger the
image commands by mistake. To avoid this, all image commands have
moved to the 'i' keymap, so '+' is now 'i +', '-' is now 'i -', and
'r' is now 'i r'. In addition, these commands are now repeating, so
you can rotate an image twice by saying 'i r r', for instance.
+++
** Emacs now picks the correct coding-system for X input methods.
@ -380,7 +380,7 @@ this user option to nil to revert back to the old behavior.
---
** Support for old EIEIO functions is not autoloaded any more.
You need an explicit '(require 'eieio-compat)' to use 'defmethod'
and 'defgeneric' (which were made obsolete in Emacs 25.1 by
and 'defgeneric' (which have been made obsolete in Emacs 25.1 with
'cl-defmethod' and 'cl-defgeneric').
Similarly you might need to '(require 'eieio-compat)' before loading
files that were compiled with an old EIEIO (Emacs<25).
@ -497,7 +497,7 @@ the 'nlinum' package from GNU ELPA instead. The former has better
performance, but the latter is closer to a drop-in replacement.
1. To use 'display-line-numbers-mode', add something like this to your
init file:
Init file:
(global-display-line-numbers-mode 1)
;; Alternatively, to use it only in programming modes:
@ -517,7 +517,7 @@ performance, but the latter is closer to a drop-in replacement.
---
** The thumbs.el library is now obsolete.
We recommend using the 'image-dired' command instead.
We recommend using command 'image-dired' instead.
---
** The autoarg.el library is now marked obsolete.
@ -577,7 +577,7 @@ encoding, only for decoding.
** New user option 'major-mode-remap-alist' to specify favorite major modes.
This user option lets you remap the default modes (e.g. 'perl-mode' or
'latex-mode') to your favorite ones (e.g. 'cperl-mode' or
'LaTeX-mode') instead of having to use 'defalias', which can have
'LaTeX-mode') without having to use 'defalias', which can have
undesirable side effects.
This applies to all modes specified via 'auto-mode-alist', file-local
variables, etc.
@ -587,8 +587,6 @@ variables, etc.
---
** New user option 'electric-quote-replace-consecutive'.
This allows you to disable the default behavior of consecutive single
quotes being replaced with a double quote.
---
** Emacs is now capable of editing files with very long lines.
@ -803,7 +801,7 @@ element: 'set-minibuffer-message', which displays echo-area messages
at the end of the minibuffer text when the minibuffer is active.
Other useful functions include 'inhibit-message', which allows
specifying, via 'inhibit-message-regexps', the list of messages whose
display should be inhibited; and 'set-multi-message' that accumulates
display shall be inhibited; and 'set-multi-message' that accumulates
recent messages and displays them stacked together.
---
@ -857,17 +855,17 @@ This value stands for the value of the corresponding attribute of the
inheriting from other faces.
+++
** New X resource "borderThickness".
** New X resource: "borderThickness".
This controls the thickness of the external borders of the menu bars
and pop-up menus.
+++
** New X resource "inputStyle".
** New X resource: "inputStyle".
This controls the style of the pre-edit and status areas of X input
methods.
+++
** New X resources "highlightForeground" and "highlightBackground".
** New X resources: "highlightForeground" and "highlightBackground".
Only in the Lucid build, this controls colors used for highlighted
menu item widgets.
@ -904,7 +902,7 @@ frame's contents will be hidden, leaving only the title bar on display.
---
** New user option 'x-gtk-use-native-input'.
This controls whether or not GTK input methods are used by Emacs,
instead of XIM input methods. Defaults to nil.
instead of XIM input methods.
+++
** New user option 'use-system-tooltips'.
@ -1001,17 +999,17 @@ combinations in a graphical menu system.
+++
*** New command 'emoji-search' (bound to 'C-x 8 e s').
This command lets you search for and insert an Emoji based on names.
This command lets you search for Emoji based on names.
+++
*** New command 'emoji-list' (bound to 'C-x 8 e l').
This command lists all Emoji (categorized by themes) in a special
buffer and lets you choose one of them to insert.
buffer and lets you choose one of them.
---
*** New command 'emoji-recent' (bound to 'C-x 8 e r').
This command lets you choose among the Emoji you have recently
inserted and insert it.
inserted.
+++
*** New command 'emoji-describe' (bound to 'C-x 8 e d').
@ -1045,7 +1043,7 @@ quotes removed.
---
*** 'M-x apropos-variable' output now includes values of variables.
Such an apropos buffer is more easily viewed with outlining after
Such apropos buffer is more easily viewed with outlining after
enabling 'outline-minor-mode' in 'apropos-mode'.
+++
@ -1077,7 +1075,7 @@ This has been changed to:
+++
*** The 'C-h .' command now accepts a prefix argument.
'C-u C-h .' would previously inhibit displaying a warning message if
there was no local help at point. This has been changed to call
there's no local help at point. This has been changed to call
'button-describe'/'widget-describe' and display button/widget help
instead.
@ -1130,7 +1128,7 @@ helpful commands for various tasks. You can toggle the display using
'C-h C-q'.
** Emacs now comes with Org v9.6.
See the file "etc/ORG-NEWS" for user-visible changes in Org.
See the file "ORG-NEWS" for user-visible changes in Org.
** Outline Mode
@ -1193,13 +1191,12 @@ the display of several buffers in a row more amenable.
+++
*** New buffer display action alist entry 'lru-frames'.
This allows specifying which frames 'display-buffer' should consider
when using a window that shows another buffer. It is interpreted as
per the ALL-FRAMES argument of 'get-lru-window'.
This allows to specify which frames 'display-buffer' should consider
when using a window that shows another buffer.
+++
*** New buffer display action alist entry 'lru-time'.
'display-buffer' will ignore windows with a use time higher than this
'display-buffer' will ignore windows with a use time higher than that
when using a window that shows another buffer.
+++
@ -1209,14 +1206,12 @@ making it a less likely candidate for displaying another buffer.
+++
*** New buffer display action alist entry 'window-min-width'.
This allows specifying a preferred minimum width of the window used to
display a buffer.
This allows to specify a minimum width of the window used to display a
buffer.
---
*** You can specify on which window 'scroll-other-window' operates.
This is controlled by the new 'other-window-scroll-default' variable,
which should be set to a function that returns a window. When this
variable is nil, 'next-window' is used.
*** You can customize on which window 'scroll-other-window' operates.
This is controlled by the new 'other-window-scroll-default' variable.
** Frames
@ -1279,19 +1274,17 @@ respond within N seconds. The default is to wait forever.
+++
*** 'server-stop-automatically' can be used to automatically stop the server.
The Emacs server will be automatically stopped when certain conditions
are met. The conditions are determined by the argument to
'server-stop-automatically', which can be 'empty', 'delete-frame' or
'kill-terminal'.
are met. The conditions are given by the argument, which can be
'empty', 'delete-frame' or 'kill-terminal'.
** Rcirc
+++
*** New command 'rcirc-when'.
This shows the reception time of the message at point (if available).
+++
*** New user option 'rcirc-cycle-completion-flag'.
Rcirc now uses the default 'completion-at-point' mechanism. The
Rcirc will use the default 'completion-at-point' mechanism. The
conventional IRC behavior of completing by cycling through the
available options can be restored by enabling this option.
@ -1546,10 +1539,6 @@ environments are:
Coptic script and language environment
Mongolian-traditional script and language environment
Mongolian-cyrillic language environment
---
*** The "Oriya" language environment was renamed to "Odia".
This is to follow the change in the official name of the script. The
@ -1563,10 +1552,7 @@ Type 'C-u C-h t' to select it in case your language setup does not do
so automatically.
---
*** New Ukrainian translation of the Emacs tutorial.
---
*** New Farsi/Persian translation of the Emacs tutorial.
*** New Ukrainian translation of the Emacs Tutorial.
---
*** New default phonetic input method for the Tamil language environment.
@ -1591,12 +1577,6 @@ This input method is based on the russian-computer input method, and
is intended for typing in the Chuvash language written in the Cyrillic
script.
---
*** New input method 'cyrillic-mongolian'.
This input method is for typing in the Mongolian language using the
Cyrillic script. It is the default input method for the new
Mongolian-cyrillic language environment, see above.
* Changes in Specialized Modes and Packages in Emacs 29.1
@ -1843,18 +1823,13 @@ this includes "binary" buffers like 'archive-mode' and 'image-mode'.
** Package
+++
*** New command 'package-upgrade'.
*** New command 'package-update'.
This command allows you to upgrade packages without using 'M-x
list-packages'. A package that comes with the Emacs distribution can
only be upgraded after you install, once, a newer version from ELPA
via the package-menu displayed by 'list-packages'.
list-packages'.
+++
*** New command 'package-upgrade-all'.
This command allows upgrading all packages without any queries.
A package that comes with the Emacs distribution will only be upgraded
by this command after you install, once, a newer version of that
package from ELPA via the package-menu displayed by 'list-packages'.
*** New command 'package-update-all'.
This command allows updating all packages without any queries.
+++
*** New commands 'package-recompile' and 'package-recompile-all'.
@ -1889,26 +1864,13 @@ packages checked out using 'package-vc-install'.
+++
*** New command 'package-report-bug'.
This command helps you compose an email for sending bug reports to
package maintainers, and is bound to 'b' in the "*Packages*" buffer.
package maintainers.
+++
*** New user option 'package-vc-selected-packages'.
By customizing this user option you can specify specific packages to
install.
---
*** New user option 'package-install-upgrade-built-in'.
When enabled, 'package-install' will include in the list of
upgradeable packages those built-in packages (like Eglot and
use-package, for example) for which a newer version is available in
package archives, and will allow installing those newer versions. By
default, this is disabled; however, if 'package-install' is invoked
with a prefix argument, it will act as if this new option were
enabled.
If you customize this option, we recommend you place its non-default
setting in your early-init file.
** Emacs Sessions (Desktop)
+++
@ -1966,8 +1928,8 @@ displayed in a window.
+++
*** New user option 'compilation-hidden-output'.
This regular expression can be used to make specific parts of
compilation output invisible.
This can be used to make specific parts of compilation output
invisible.
+++
*** The 'compilation-auto-jump-to-first-error' user option has been extended.
@ -2350,7 +2312,7 @@ EUDC inline expansion result formatting defaulted to
("%s %s <%s>" firstname name email)
Since email address specifications need to comply with RFC 5322 in
order to be useful in messages, there was a risk of producing syntax
order to be useful in messages, there was a risk to produce syntax
which was standard with RFC 822, but is marked as obsolete syntax by
its successor RFC 5322. Also, the first and last name part was never
enclosed in double quotes, potentially producing invalid address
@ -2384,8 +2346,8 @@ used to select the entry type in the ecomplete database.
+++
*** New back-end for mailabbrev.
A new back-end for mailabbrev allows information from that database to
be queried by EUDC, too. Only the attributes 'email', 'name', and
'firstname' are supported.
be queried by EUDC, too. The attributes 'email', 'name', and 'firstname'
are supported only.
** EWW/SHR
@ -2632,14 +2594,14 @@ as opposed to via the command-line.
+++
*** New command 'image-transform-fit-to-window'.
This command fits the image to the current window by scaling down or
up as necessary. Unlike 'image-transform-fit-both', this can scale
the image up as well as down. It is bound to 's w' in Image Mode by
default.
up as necessary. Unlike 'image-transform-fit-both', this does not
only scale the image down, but up as well. It is bound to 's w' in
Image Mode by default.
---
*** New command 'image-mode-wallpaper-set'.
This command sets the desktop background to the current image. It is
bound to 'W' in Image Mode by default.
bound to 'W' by default.
+++
*** 'image-transform-fit-to-{height,width}' are now obsolete.
@ -2657,14 +2619,19 @@ much (in percent). It is nil by default, which means no limit.
---
*** New user option 'image-text-based-formats'.
This controls whether or not to show a message, when opening certain
image formats, explaining how to edit it as text. The default is to
show this message for SVG and XPM.
This controls whether or not to show a message when opening certain
image formats saying how to edit it as text. The default is to show
this message for SVG and XPM.
+++
*** New commands: 'image-flip-horizontally' and 'image-flip-vertically'.
These commands horizontally and vertically flip the image under point,
and are bound to 'i h' and 'i v', respectively.
+++
*** New command 'image-transform-set-percent'.
It allows resizing the image to a percentage of its original size, and
is bound to 's p' in Image mode.
It allows setting the image size to a percentage of its original size,
and is bound to 's p' in Image mode.
+++
*** 'image-transform-original' renamed to 'image-transform-reset-to-original'.
@ -2676,19 +2643,6 @@ The old name was confusing, and is now an obsolete function alias.
** Images
+++
*** New commands 'image-crop' and 'image-cut'.
These commands allow interactively cropping/cutting the image at
point. The commands are bound to keys 'i c' and 'i x' (respectively)
in the local keymap over images. They rely on external programs, by
default "convert" from ImageMagick, to do the actual cropping/eliding
of the image file.
+++
*** New commands 'image-flip-horizontally' and 'image-flip-vertically'.
These commands horizontally and vertically flip the image under point,
and are bound to 'i h' and 'i v', respectively.
+++
*** Users can now add special image conversion functions.
This is done via 'image-converter-add-handler'.
@ -3277,10 +3231,6 @@ based on data provided by language servers using the Language Server
Protocol (LSP). See the new Info manual "(eglot) Top" for more. Also
see "etc/EGLOT-NEWS".
If you want to be able to use 'package-install' to upgrade Eglot to
newer versions released on GNU ELPA, customize the new option
'package-install-upgrade-built-in' to a non-nil value.
+++
** use-package: Declarative package configuration.
use-package is now shipped with Emacs. It provides the 'use-package'
@ -3288,9 +3238,13 @@ macro, which allows you to isolate package configuration in your init
file in a way that is declarative, tidy, and performance-oriented.
See the new Info manual "(use-package) Top" for more.
If you want to be able to use 'package-install' to upgrade use-package
to newer versions released on GNU ELPA, customize the new option
'package-install-upgrade-built-in' to a non-nil value.
+++
** New commands 'image-crop' and 'image-cut'.
These commands allow interactively cropping/cutting the image at
point. The commands are bound to keys 'i c' and 'i x' (respectively)
in the local keymap over images. They rely on external programs, by
default "convert" from ImageMagick, to do the actual cropping/eliding
of the image file.
---
** New package 'wallpaper'.
@ -3956,9 +3910,9 @@ connection-local profile.
+++
*** New macro 'with-connection-local-application-variables'.
This macro works like 'with-connection-local-variables', but it allows
using another application instead of 'tramp'. This is useful when
running code in a buffer where Tramp has already set some
connection-local variables.
to use another application but 'tramp'. This is useful when running
code in a buffer where Tramp has already set some connection-local
variables.
+++
*** New macro 'setq-connection-local'.
@ -4037,8 +3991,8 @@ This returns a list of sub-sequences of the specified sequence.
+++
*** New function 'seq-remove-at-position'.
This function returns a copy of the specified sequence with the
element at a given (zero-based) index removed.
This function returns a copy of the specified sequence where the
element at a given (zero-based) index got removed.
+++
*** New function 'seq-positions'.
@ -4106,7 +4060,7 @@ that quote character has to be escaped to avoid Emacs displaying it as
(setq foo '(1 2 3))
invalid. Emacs will now warn during byte compilation if it sees
invalid. Emacs will now warn during byte compilation if it seems
something like that, and also warn about when using RIGHT/LEFT SINGLE
QUOTATION MARK directly. In both these cases, if these characters
should really be present in the docstring, they should be quoted with
@ -4166,7 +4120,7 @@ example for benchmarking purposes.
** New function 'string-edit'.
This is meant to be used when the user has to edit a (potentially)
long string. It pops up a new buffer where you can edit the string,
and the provided callback is called when the user types 'C-c C-c'.
and a callback is called when the user types 'C-c C-c'.
+++
** New function 'read-string-from-buffer'.
@ -4312,7 +4266,7 @@ them towards or away from each other.
+++
** New hook 'x-pre-popup-menu-hook'.
This hook is run before 'x-popup-menu' is about to display a
This hook, run before 'x-popup-menu', is about to display a
deck-of-cards menu on screen.
---
@ -4413,8 +4367,8 @@ switch to these new functions.
+++
*** 'define-key' now takes an optional REMOVE argument.
If non-nil, remove the definition from the keymap. This is subtly
different from setting a definition to nil: when the keymap has a
parent such a definition will shadow the parent's definition.
different from setting a definition to nil (when the keymap has a
parent).
+++
*** 'read-multiple-choice' now takes an optional SHOW-HELP argument.

View file

@ -2708,15 +2708,6 @@ Emacs so that it isn't compiled with '-O5'.
We list bugs in current versions here. See also the section on legacy
systems.
*** On Solaris 10, running 'configure' with "/bin/sh" produces errors.
The "/bin/sh" shell on Solaris is an ancient and non-POSIX shell, so
we recommend not to use it. The Emacs 'configure' script should find
an appropriate shell and re-exec itself with that shell, unless you
force it to use "/bin/sh" by using "CONFIG_SHELL=/bin/sh" on the
'configure' command line. So either don't use CONFIG_SHELL, or, if
you'd rather pick the shell yourself, choose "/bin/bash" or "/bin/ksh"
or "/usr/xpg4/bin/sh" instead.
*** On Solaris 10 sparc, Emacs crashes during the build while saving state.
This was observed for Emacs 28.1 on Solaris 10 32-bit sparc, with
Oracle Developer Studio 12.6 (Sun C 5.15). The failure was intermittent,

View file

@ -1,5 +1,5 @@
% Reference Card for Org Mode
\def\orgversionnumber{9.6.5}
\def\orgversionnumber{9.6.3}
\def\versionyear{2023} % latest update
\input emacsver.tex

View file

@ -4,7 +4,7 @@ Emacs commands generally involve the CONTROL key (often labeled CTRL)
or the META key (usually labeled ALT). Rather than writing that
in full each time, we'll use the following abbreviations:
C-<chr> means hold the CONTROL key while typing the character <chr>.
C-<chr> means hold the CONTROL key while typing the character <chr>
Thus, C-f would be: hold the CONTROL key and type f.
M-<chr> means hold the META or ALT key down while typing <chr>.
If there is no META or ALT key, instead press and release the

View file

@ -15,10 +15,10 @@ META 键(有时候用 EDIT 或 ALT 来标示)。为了避免每次都要写
ESC 键。
重要提示:要退出 Emacs请用 C-x C-c两个连续的组合键
中断一个正在输入的命令,请用 C-g。
退出一个正在运行中的命令,请用 C-g。
下文中左边顶行的“>>”字样用来提示你尝试键盘命令。比如:
<<Blank lines inserted around following line by help-with-tutorial>>
【本页当中特意留出一些空白是出于教学目的,请继续往后阅读】
[本页当中特意留出一些空白是出于教学目的,请继续往后阅读]
>> 现在输入 C-v (查看下一屏文字)移动到下一屏。
(别紧张,在输入字符 v 的同时注意要按住 CONTROL 键)
从现在开始,每读完当前一屏你都需要这样做一次。
@ -26,17 +26,12 @@ META 键(有时候用 EDIT 或 ALT 来标示)。为了避免每次都要写
值得注意的是,当你从上一屏滚到下一屏时,中间会有两行的重复;这样做是为
了维持滚屏的连续性,方便你顺畅、连续地阅读。
这是 Emacs 教程文本的一个经过少量修改的副本。不久后我们会让你尝试不同
的命令来修改此文本。若你在我们提到这些命令前修改了文本,不要担心;这就
叫做“编辑”,而这就是 Emacs 存在的根本原因。
用编辑器,开门第一件事就是学会在文字中移动。你已经知道了 C-v 可以向下移
动一屏,要往上移,请用 M-v (也就是按住 META 键然后输入v如果你没有
META、EDIT 或 ALT 键那么就先按 <ESC> 再按 v
>> 试试 M-v然后再试试 C-v来回遛几次。
若你知道其他移动文本的方式,也可以在这里试试。
* 小结SUMMARY
-----------------
@ -106,7 +101,7 @@ P 代表 previous上一行N 代表 next下一行B 代表 backw
如果你嫌一个字符一个字符地挪光标太慢你还可以一个词一个词地跳。M-f
(META-f) 可以将光标往前移动一个词,而 M-b 则是往后移。【这里的“词”指
英文单词,对中文来说,则是指移动到下一个空格或标点符号。】
英文单词,对中文来说,则是指移动到下一个标点符号。】
>> 试试 M-f 和 M-b。
@ -137,8 +132,8 @@ P 代表 previous上一行N 代表 next下一行B 代表 backw
C-f 向右移动一个字符
C-b 向左移动一个字符
M-f 向右移动一个词【对中文是移动到下一个空格或标点符号】
M-b 向左移动一个词【对中文是移动到上一个空格或标点符号】
M-f 向右移动一个词【对中文是移动到下一个标点符号】
M-b 向左移动一个词【对中文是移动到上一个标点符号】
C-n 移动到下一行
C-p 移动到上一行
@ -165,25 +160,24 @@ M-commaMETA 逗号)。
然后再按几次 M-v 回到这里。
如果你的键盘上有方向键的话,也可以用它们来移动光标。不过我们有三个理由
推荐你学习 C-b 、C-f 、C-n 、和 C-p1它们在任何终端terminal
都能用。2当你熟练使用 Emacs 之后,你会发现用这些组合键比用方向键要
快得多,因为你的手不需要离开打字区。3一旦你习惯了使用这些组合键
你也可以很容易地适应其它更高级的光标移动命令。
推荐你学习 C-b 、C-f 、C-n 、和 C-p1它们在任何键盘上都能用。2
当你熟练使用 Emacs 之后,你会发现用这些组合键比用方向键要快得多,因为你
的手不需要离开打字区。3一旦你习惯了使用这些组合键你也可以很容易地
适应其它更高级的光标移动命令。
大部分的 Emacs 命令接受数字参数,并且对于多数命令而言,这些数字参数的
作用是指定命令的重复次数。为一个命令指定数字参数(也就是重复次数)的方
法是:先输入 C-u然后输入数字作为参数最后再输入命令。如果你有
META或EDIT 或 ALT那么还有另一种办法按住 META 键不放,然后输
入数字。不过我们还是建议你用 C-u因为它在任何终端上都能用。这种数字参
数也称为“前缀参数”prefix argument意思是说这个参数是先于使用它的
命令而输入的。
大部分的 Emacs 命令接受数字参数,并且对于多数命令而言,这些数字参数的作
用是指定命令的重复次数。为一个命令指定数字参数(也就是重复次数)的方法
是:先输入 C-u然后输入数字作为参数最后再输入命令。如果你有META (或
EDIT 或 ALT那么还有另一种办法按住 META 键不放,然后输入数字。不
过我们还是建议你用 C-u因为它在任何终端机上都能用。这种数字参数也称为
“前缀参数”,意思是说这个参数是先于使用它的命令而输入的。
举例来说, C-u 8 C-f 会向前移动 8 个字符。
>> 为 C-n 或者 C-p 指定一个数字参数,这样你可以只用一个命令就把光标移动
到本行的附近。
虽然大部分命令把数字参数解为其重复次数,但是也有些命令例外,它们将数
虽然大部分命令把数字参数解为其重复次数,但是也有些命令例外,它们将数
字参数另做它用。比如有些命令(我们目前还没学到)仅仅将前缀参数作为一个
标志――只要给出有一个前缀参数,不管其值为何,它都会改变命令的功能。
@ -195,7 +189,7 @@ META或EDIT 或 ALT那么还有另一种办法按住 META 键不
这个命令应该已经将文字向上滚动了 8 行。如果你想将它再次地向下滚动,你可
以给定一个参数然后执行 M-v。
如果你正在使用图形界面,比如 X 或者微软的 Windows那么在 Emacs
如果你正在使用图形界面,比如 X 或者微软的 Windows那么在 Emacs窗
口的一边应该有一个长方形的区域叫“滚动条”。你可以用鼠标操纵滚动条来滚动
文字。
@ -241,8 +235,8 @@ Emacs 可以有多个“窗格”,每个窗格显示不同的文字。后面
C-x 1 只保留一个窗格(也就是关掉其它所有窗格)。
也就是先按 CONTROL-x 然后再按数字 1。C-x 1 会保留光标所在的窗格,并将
其扩大到整个屏幕,同时关掉所有其它的窗格。
也就是先按 CONTROL-x 然后再按 1。C-x 1 会保留光标所在的窗格,并将其扩大
到整个屏幕,同时关掉所有其它的窗格。
>> 把光标移到本行然后输入 C-u 0 C-l。
@ -272,13 +266,12 @@ Emacs 可以有多个“窗格”,每个窗格显示不同的文字。后面
不用担心文件被修改,你做什么都没关系,这里就是专给你练习用的。
如果一行文字很长、超出了窗格的宽度,显示不下的部分会在紧邻的下一行继续
显示称为接续行continuation line。如果你使用的是图形界面文本区
域两边的狭窄区域(左右“边缘”)会出现小小的转弯箭头,表明这是某一行的接
续显示。如果你使用的是文本终端,接续显示由屏幕最右边一列的一个“\”来表
示。
显示。如果你使用的是图形界面,文本区域两边的狭窄区域(左右“边缘”)会出
现小小的转弯箭头,表明这是某一行的接续显示。如果你使用的是文本终端,接
续显示由屏幕最右边一列的一个反斜线(“\”)来表示。
>> 输入文字,一直到屏幕的右边界,然后继续。
你会看到一个接续行出现。
你会看到一个接续行出现。
>> 用 <DEL> 删掉一些文字,直到此行长度小于窗格宽度,接续行就消失了。
@ -293,9 +286,7 @@ Emacs 可以有多个“窗格”,每个窗格显示不同的文字。后面
<Return> 是一个特殊的键,因为按下这个键后,得到的可能不仅仅是一个换行
符。根据周围文本的不同Emacs 可能会在换行符之后插入一些空白字符,这样,
当你在新的一行开始打字时,文本会自动与前一行对齐。我们称这种行为(在按
这个按键时不只是插入其对应字符为“electric”可以理解为“通电的自动
的”。
当你在新的一行开始打字时,文本会自动与前一行对齐。
>> 这是一个自动缩进的例子。
在这一行的末尾输入 <Return>。
@ -347,8 +338,7 @@ Emacs 可以有多个“窗格”,每个窗格显示不同的文字。后面
了。】重新插入被移除的文字称为“召回yank”。一般而言那些可能消除很
多文字的命令会把消除掉的文字记录下来(它们被设定成了“可召回”),而那些
只消除一个字符或者只消除空白的命令就不会记录被消除的内容(自然你也就无
法召回了)。<DEL> 和 C-d 在无前缀参数的情况下进行“删除”,而有前缀参数
时则改用“移除”。
法召回了)。
>> 移动光标到一非空白行的行头,然后输入 C-k 移除那一行上的文字。
@ -360,11 +350,10 @@ Emacs 可以有多个“窗格”,每个窗格显示不同的文字。后面
C-k 会把两行以及它们的换行符移除;而如果只是输入 C-k 两次显然不是这个结
果。
【重新插入被移除的文字恢复的动作称为“召回yanking就好像把别人
从你身边移走的东西又猛力地拉回来。】你可以在你删除文字的地方召回,也
可以在别的地方召回,还可以多次召回同样的文字以得到它的多个拷贝。很多其
它的编辑器把移除和召回叫做“剪切”和“粘贴” (详情可见 Emacs 使用手册里的
术语表)。
重新插入被移除的文字恢复的动作称为“召回yanking”。就好像把别人从你身边
移走的东西又猛力地拉回来。)你可以在你删除文字的地方召回,也可以在别的
地方召回,还可以多次召回同样的文字以得到它的多个拷贝。很多其它的编辑器
把移除和召回叫做“剪切”和“粘贴” (详情可见 Emacs 使用手册里的术语表)。
召回的命令是 C-y。它会在光标所在处插入你最后移除的文字。
@ -383,8 +372,8 @@ C-y 就可以把它们都召回。
C-y 可以召回最近一次移除的内容,那如何召回前几次移除的内容呢?它们当然
没有丢,你可以用 M-y 来召回它们。在用 C-y 召回最近移除的文字之后,紧接
着再按 M-y 就可以召回再前一次被移除的内容,再按一次 M-y 又可以召回再上
一次的内容……连续使用 M-y 直到找到你想要召回的东西,然后什么也不用做,
继续编辑就行了。
一次的……连续使用 M-y 直到找到你想要召回的东西,然后什么也不用做,继续
编辑就行了。
如果连续按 M-y 很多次,你可能会回到起始点,也就是最近移除的文字。
【看得出这实际上是一个环。】
@ -412,16 +401,14 @@ C-/,你会把以前的命令也依次撤销。
>> 用 C-k 将这一行移除,然后输入 C-/ ,它会再次出现。
C-_ 也是撤销命令;它的作用跟 C-/ 一样,但是它比较容易多次输入。在某些
终端上,你可以不按 shift 键(即 C--)。在某些终端上,输入 C-/ 实际上向
Emacs 发送的是 C-_ 。另外, C-x u 和 C-/ 完全一样,但是按起来有些麻烦。
C-_ 也是撤销命令;它的作用跟 C-/ 一样,但是它比较容易多次输入。在
某些终端上,输入 C-/ 实际上向 Emacs 发送的是 C-_ 。
另外, C-x u 和 C-/ 完全一样,但是按起来有些麻烦。
数字参数对于 C-/ 、 C-_ 和 C-x u 的意义是执行撤销的重复次数。
你可以撤销文字的删除,就像你能撤销文字的移除一样。删除与移除的区别只在
于你是否能召回被影响的文字;对于撤销来说没有区别。
* 文件FILES
* 文件FILE
--------------
想保存工作成果就要记得存盘,否则一旦退出 Emacs 你编辑的文字就会丢失。要
@ -437,7 +424,7 @@ Emacs 发送的是 C-_ 。另外, C-x u 和 C-/ 完全一样,但是按起来
在屏幕的下方,你应该能够看到头部有短线“-”的一行,行首通常是一些诸如“
-:--- TUTORIAL.cn”的文字这些文字代表了你当前正在访问的文件。比如你现
在正在访问的文件是对 Emacs 快速指南的一份临时拷贝叫做“TUTORIAL.cn”。
每当 Emacs 寻找到一个文件,文件名就会出现在这个位置。
每当Emacs 寻找到一个文件,文件名就会出现在这个位置。
寻找文件的命令有一个特点,那就是你必须给出文件名。我们称这个命令“读入
了一个参数”(在这里,这个参数显然就是文件名)。在你输入这条命令之后:
@ -448,14 +435,14 @@ Emacs 会提示你输入文件名。你输入的文件名会出现在屏幕最
行被称为小缓冲minibuffer在小缓冲里你可以使用通常的 Emacs 编辑命令
来编辑文件名。
在小缓冲里输入文件名(其实输入其它东西也一样)时可以用 C-g 取消这个命令
在小缓冲里输入文件名(其实输入其它东西也一样)时可以用 C-g 取消。
>> 输入 C-x C-f然后输入 C-g
这会关掉小缓冲,同时也会取消使用小缓冲的 C-x C-f 命令。
当然了,你也没有找任何文件。
当然了,你也没有找任何文件。
当你写完要寻找的文件名时,用 <Return> 结束文件名的输入。之后,小缓冲会
消失C-x C-f 将会去寻找你指定的文件。
用 <Return> 结束文件名的输入。之后,小缓冲会消失C-x C-f 将会去寻找你
指定的文件。小缓冲在 C-x C-f 命令结束之后也会消失
文件被显示在了屏幕上,你可以开始编辑了。存盘用这条命令:
@ -466,21 +453,20 @@ Emacs 会提示你输入文件名。你输入的文件名会出现在屏幕最
【对许多人来说,这是一个烦人的特性,关掉文件备份可以用如下命令:
M-x customize-variable <Return> make-backup-files <Return>】
存盘结束后Emacs 会显示写入文件的文件名。【你最好养成经常存盘的习惯,
这可以减少系统崩溃和死机给你带来的损失(也可参见下面的“自动保存”一
节)。】
存盘结束后Emacs 会显示写入文件的文件名。你最好养成经常存盘的习惯,这
可以减少系统崩溃和死机给你带来的损失(也可参见下面的“自动保存”一节)。
>> 输入 C-x C-s TUTORIAL.cn <Return> 。
这将会把该指南保存为一个名为 TUTORIAL.cn 的文件,并且在屏幕的下方显
示一条消息“Wrote TUTORIAL.cn”。
示一条消息“Wrote ...TUTORIAL.cn”。
你不但可以寻找一个已有的文件来查看或编辑,还可以寻找一个不存在的文件。
实际上这正是 Emacs 创建新文件的方法:找到不存在的新文件,它一开始是空
的,然后你就可以开始插入文本。事实上,只有在存盘的时候Emacs 才会真正
创建这个文件。而在这之后的一切就跟编辑一个已有文件没有区别了。
实际上这正是 Emacs 创建新文件的方法:找到不存在的新文件。事实上,只有
在存盘的时候Emacs 才会真正创建这个文件。而在这之后的一切就跟编辑一个
已有文件没有区别了。
* 缓冲区BUFFERS
* 缓冲区BUFFER
------------------
你可以用 C-x C-f 找到并打开第二个文件,但第一个文件仍然在 Emacs 中。要
@ -509,7 +495,7 @@ C-x C-f 是一种办法。不过还有一个更简单的办法,那就是用 C-
然后输入 C-x b TUTORIAL.cn <Return> 回到这里。
大多数情况下,缓冲区与跟其对应的文件是同名的(不包括目录名),不过这也
不是绝对的。因此用 C-x C-b 得到的缓冲区列表总是显示缓冲区名与文件名
不是绝对的。用 C-x C-b 得到的缓冲区列表总是显示缓冲区名。
缓冲区未必有对应文件。显示缓冲区列表的缓冲区(叫做“*Buffer List*”)就
是这样。这个 TUTORIAL.cn 缓冲区起初没有对应的文件,但是现在有了,因为
@ -530,8 +516,8 @@ C-x C-f 是一种办法。不过还有一个更简单的办法,那就是用 C-
C-x s 保存多个缓冲区
C-x s 会找出所有访问文件的、且已被修改但尚未存盘的缓冲区,然后向你逐个
询问:是否需要存盘此文件
C-x s 会找出所有已被修改但尚未存盘的缓冲区,然后向你逐个询问:是否需要
存盘
>> 插入一行文字,然后输入 C-x s。
它应该会问你,是否要储存名为 TUTORIAL.cn 的缓冲区?
@ -568,9 +554,7 @@ C-x 的扩展命令有很多,下面列出的是你已经学过的:
C-x C-f 寻找文件。
C-x C-s 保存文件。
C-x s 保存多个缓冲区。
C-x C-b 列出缓冲区。
C-x b 切换缓冲区。
C-x C-c 离开 Emacs。
C-x 1 关掉其它所有窗格,只保留一个。
C-x u 撤销。
@ -624,10 +608,10 @@ replace-string字符串替换这个命令它会把一个字符串替换
状态栏显示了 Emacs 的状态和你正在编辑的文字的一些信息。
你应该知道文件名的意思吧就是你找到的那个文件嘛。NN% 显示的是光标在
全文中的位置。如果位于文件的开头,那么就显示 Top 而不是 0%;如
果位于文件的末尾,就显示 Bot。如果文件很小一屏就足以显示全部内容
那么状态栏会显示 All。
你应该知道文件名的意思吧?就是你找到的那个文件嘛。-NN%-- 显示的是光标在
全文中的位置。如果位于文件的开头,那么就显示 --Top-- 而不是 --00%--;如
果位于文件的末尾,就显示 --Bot--。如果文件很小,一屏就足以显示全部内容,
那么状态栏会显示 --All--
“L” 和其后的数字给出了光标所在行的行号。
@ -739,10 +723,7 @@ C-s 是向前搜索C-r 是向后搜索。不过手别这么快!别着急试
* 多窗格MULTIPLE WINDOWS
----------------------------
Emacs 的迷人之处很多,能够在屏幕上同时显示多个窗格就是其中之一。(请注
意在 Emacs 里的“窗口frame”与“窗格window”的定义可能与其他应用程
序不同详见Emacs 手册里的术语表。)【另见此教程末尾的翻译章节的术语译
词对照表。】
Emacs 的迷人之处很多,能够在屏幕上同时显示多个窗格就是其中之一。
>> 移动光标到这一行,然后输入 C-l C-l。
@ -801,13 +782,13 @@ Emacs 可以创建多个窗口。窗口由许多窗格以及菜单、滚动条
在图形界面下,多个窗口可以同时显示出来。在文本终端中,只能同时显示一个
窗口。
>> 输入 C-x 5 2
>> 输入 M-x make-frame <Return>
可以看到一个新的窗口出现在了你的屏幕上。
你可以在新的窗口里做最初的窗口里可以做的任何事情。第一个窗口没有什么特
别的。
>> 输入 C-x 5 0。
>> 输入 M-x delete-frame <Return>.
这个命令将会关闭选中的窗口。
你也可以通过图形系统来关闭某个窗口(通常是在窗口上面的某个角落里的一个
@ -872,9 +853,9 @@ Emacs 可以创建多个窗口。窗口由许多窗格以及菜单、滚动条
还有一些其它有用的 C-h 命令:
C-h x 解释一个命令。需要输入命令名。
C-h f 解释一个函数。需要输入函数名。
>> 试试看,输入 C-h x previous-line <Return>。
>> 试试看,输入 C-h f previous-line <Return>。
Emacs 会给出它所知道的所有有关“实现 C-p 命令功能的函数”的信息。
C-h v 用来显示 Emacs 变量的文档。Emacs 变量可以被用来“定制 Emacs 的行
@ -924,15 +905,15 @@ Dired 能够在一个缓冲区里列出一个目录下的所有文件(可以
Emacs 使用手册里还有许许多多的精彩功能等着你来了解。
* 安装软件INSTALLING PACKAGES
* 安装包INSTALLING PACKAGES
---------------------------
Emacs 社区著作了许多持有扩展性的软件packages其中包括对各种语言
支持、色彩鲜艳的主题、用于集成外部程序的软件包,等等。
Emacs 社区著作了许多持有扩展性的包packages其中包括对各种语言
支持、色彩鲜艳的主题、用于集成外部程序的包,等等。
使用 M-x list-packages 便可浏览所有可安装的软件包。这个命令显示的界面
中可以安装和卸载软件包以及查看软件包的简介。Emacs 使用手册中有对软件
包管理更详细的介绍。
使用 M-x list-packages 便可浏览存在的包裹。这个命令显示的界面中可以安
装和卸载包裹以及查看包裹的简介。Emacs 使用手册中有对包裹管理更详细的
介绍。
* 总结CONCLUSION
--------------------
@ -948,7 +929,6 @@ Emacs 社区著作了许多持有扩展性的软件包packages其中包
翻译:孙一江 <sunyijiang@gmail.com>
维护:薛富侨 <xfq.free@gmail.com>
余睿杰 <ruijie@netyu.xyz>
校对水木社区www.newsmth.netEmacs 板众多网友及众多 Emacs 中文用户
Emacs 快速指南Tutorial早有两个刘昭宏的中文译本繁简各一。其简体版本

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,6 @@ Maintainer: Ognyan Kulev <ogi@tower.3.bg>
* TUTORIAL.cn:
Author: Sun Yijiang <sunyijiang@gmail.com>
Maintainer: Xue Fuqiao <xfq.free@gmail.com>
Ruijie Yu <ruijie@netyu.xyz>
* TUTORIAL.cs:
Author: Milan Zamazal <pdm@zamazal.org>
@ -31,10 +30,6 @@ Maintainer: Rafael Sepúlveda <drs@gnulinux.org.mx>
Author: Protesilaos Stavrou <info@protesilaos.com>
Maintainer: Protesilaos Stavrou <info@protesilaos.com>
* TUTORIAL.fa:
Author: Mohsen BANAN <emacs@mohsen.1.banan.byname.net>
Maintainer: Mohsen BANAN <emacs@mohsen.1.banan.byname.net>
* TUTORIAL.fr:
Author: Éric Jacoboni <jaco@teaser.fr>
Maintainer: Éric Jacoboni <jaco@teaser.fr>

View file

@ -197,7 +197,7 @@
GAN 近緊跟根巾筋斤僅謹靳堇哏艮
GANG 梗更庚羹館耿粳哽
GAP 鴿蛤急
GAT <20><><EFBFBD>
GAT <20><><EFBFBD>
GAU 究舊九夠苟狗垢玖韭久灸廄救咎疚摳鼽
GEI 幾記機基既紀技箕肌飢譏姬己伎寄忌妓剞嘰杞畿麂
GENG 鏡頸
@ -231,7 +231,7 @@
GWAI 櫃季瑰圭硅歸龜閨軌鬼詭桂跪貴悸巋饋匭匱劌皈
GWAN 君軍均滾棍鈞郡袞筠
GWANG 轟
GWAT 癌备竇浑
GWAT 癌备竇浑
GWING 炯
GWOH 過果戈裹棵顆錁
GWOK 郭國廓

View file

@ -72,10 +72,9 @@ AUTOGENEL = ${loaddefs} ${srcdir}/cus-load.el ${srcdir}/finder-inf.el \
${srcdir}/subdirs.el ${srcdir}/eshell/esh-groups.el
# Set load-prefer-newer for the benefit of the non-bootstrappers.
# Set org--inhibit-version-check to avoid unnecessarily aborting the build.
BYTE_COMPILE_FLAGS = \
--eval "(setq load-prefer-newer t byte-compile-warnings 'all)" \
--eval "(setq org--inhibit-version-check t)" $(BYTE_COMPILE_EXTRA_FLAGS)
$(BYTE_COMPILE_EXTRA_FLAGS)
# ... but we must prefer .elc files for those in the early bootstrap.
compile-first: BYTE_COMPILE_FLAGS = $(BYTE_COMPILE_EXTRA_FLAGS)
@ -490,8 +489,8 @@ check-declare:
## This finds a lot of duplicates between foo.el and obsolete/foo.el.
check-defun-dups:
sed -n -e '/^(defun /s/\(.\)(.*/\1/p' \
`find . -name '*.el' ! -name '.*' -print | \
grep -Ev '(loaddefs|ldefs-boot)\.el|obsolete'` | sort | uniq -d
$$(find . -name '*.el' ! -name '.*' -print | \
grep -Ev '(loaddefs|ldefs-boot)\.el|obsolete') | sort | uniq -d
# Dependencies
@ -544,4 +543,12 @@ $(lisp)/progmodes/cc-styles.elc: $(lisp)/progmodes/cc-vars.elc \
$(lisp)/progmodes/js.elc: $(lisp)/progmodes/cc-defs.elc \
$(lisp)/progmodes/cc-engine.elc $(lisp)/progmodes/cc-mode.elc
# When org-version.el gets updated with a new version, all the Org
# files need to be recompiled, or else the build will fail due to
# version mismatch, prompting the naive users to bootstrap. So we
# make all the Org *.elc files dependent of org-version.el, to trigger
# their recompilation automatically.
$(lisp)/org/org.elc $(filter-out $(lisp)/org/org-version.elc,$(filter-out $(lisp)/org/org.elc,$(wildcard $(lisp)/org/*.elc))): \
$(lisp)/org/org-version.el
# Makefile ends here.

View file

@ -5390,7 +5390,7 @@ Defaults:
;; not specified -- default it:
(setq tobuf (concat "*" (buffer-name frombuf) " exposed*")))
(if (listp format)
(setq format (reverse format)))
(nreverse format))
(let* ((listified
(progn (set-buffer frombuf)

View file

@ -645,49 +645,6 @@ Does not signal an error if optional argument NOERROR is non-nil."
(if (not noerror)
(error "Line does not describe a member of the archive")))))
;; -------------------------------------------------------------------------
;;; Section: Helper functions for requiring filename extensions
(defun archive--act-files (command files)
(lambda (archive)
(apply #'call-process (car command)
nil nil nil (append (cdr command) (cons archive files)))))
(defun archive--need-rename-p (&optional archive)
(let ((archive
(file-name-nondirectory (or archive buffer-file-name))))
(cl-case archive-subtype
((zip) (not (seq-contains-p archive ?. #'eq))))))
(defun archive--ensure-extension (archive ensure-extension)
(if ensure-extension
(make-temp-name (expand-file-name (concat archive "_tmp.")))
archive))
(defun archive--maybe-rename (newname need-rename-p)
;; Operating with archive as current buffer, and protect
;; `default-directory' from being modified in `rename-visited-file'.
(when need-rename-p
(let ((default-directory default-directory))
(rename-visited-file newname))))
(defun archive--with-ensure-extension (archive proc-fn)
(let ((saved default-directory))
(with-current-buffer (find-buffer-visiting archive)
(let ((ensure-extension (archive--need-rename-p))
(default-directory saved))
(unwind-protect
;; Some archive programs (like zip) expect filenames to
;; have an extension, so if necessary, temporarily rename
;; an extensionless file for write accesses.
(let ((archive (archive--ensure-extension
archive ensure-extension)))
(archive--maybe-rename archive ensure-extension)
(let ((exitcode (funcall proc-fn archive)))
(or (zerop exitcode)
(error "Updating was unsuccessful (%S)" exitcode))))
(progn (archive--maybe-rename archive ensure-extension)
(revert-buffer nil t)))))))
;; -------------------------------------------------------------------------
;;; Section: the mode definition
;;;###autoload
@ -1421,9 +1378,16 @@ NEW-NAME."
(setq ename
(encode-coding-string ename archive-file-name-coding-system))
(let* ((coding-system-for-write 'no-conversion)
(default-directory (file-name-as-directory archive-tmpdir)))
(archive--with-ensure-extension
archive (archive--act-files command (list ename)))))
(default-directory (file-name-as-directory archive-tmpdir))
(exitcode (apply #'call-process
(car command)
nil
nil
nil
(append (cdr command)
(list archive ename)))))
(or (zerop exitcode)
(error "Updating was unsuccessful (%S)" exitcode))))
(archive-delete-local tmpfile))))
(defun archive-write-file (&optional file)
@ -1546,7 +1510,9 @@ as a relative change like \"g+rw\" as for chmod(2)."
(archive-resummarize))
(error "Setting group is not supported for this archive type"))))
(defun archive--expunge-maybe-force (force)
(defun archive-expunge ()
"Do the flagged deletions."
(interactive)
(let (files)
(save-excursion
(goto-char archive-file-list-start)
@ -1560,8 +1526,7 @@ as a relative change like \"g+rw\" as for chmod(2)."
(and files
(or (not archive-read-only)
(error "Archive is read-only"))
(or force
(yes-or-no-p (format "Really delete %d member%s? "
(or (yes-or-no-p (format "Really delete %d member%s? "
(length files)
(if (null (cdr files)) "" "s")))
(error "Operation aborted"))
@ -1575,14 +1540,13 @@ as a relative change like \"g+rw\" as for chmod(2)."
(archive-resummarize)
(revert-buffer))))))
(defun archive-expunge ()
"Do the flagged deletions."
(interactive)
(archive--expunge-maybe-force nil))
(defun archive-*-expunge (archive files command)
(archive--with-ensure-extension
archive (archive--act-files command files)))
(apply #'call-process
(car command)
nil
nil
nil
(append (cdr command) (cons archive files))))
(defun archive-rename-entry (newname)
"Change the name associated with this entry in the archive file."

View file

@ -195,6 +195,7 @@ Calc user interface as before (either \\`C-x * C' or \\`C-x * K'; initially \\`C
;;;###autoload
(defun calc-info-goto-node (node)
"Go to a node in the Calculator info documentation."
(interactive)
(select-window (get-largest-window))
(info (concat "(Calc)" node)))

View file

@ -936,6 +936,7 @@
(defun calc-edit-macro-finish-edit (cmdname key)
"Finish editing a Calc macro.
Redefine the corresponding command."
(interactive)
(let ((cmd (intern cmdname)))
(calc-edit-macro-pre-finish-edit)
(let* ((str (buffer-substring calc-edit-top (point-max)))

View file

@ -1349,9 +1349,8 @@ Optional string argument KEYS will force using it as the keys entered."
(calculator-update-display t))
(defun calculator-saved-move (n)
"Go N elements up the list of saved values.
Interactively, N is the prefix numeric argument and defaults to 1."
(interactive "p")
"Go N elements up the list of saved values."
(interactive)
(when (and calculator-saved-list
(or (null calculator-stack) calculator-display-fragile))
(setq calculator-saved-ptr

View file

@ -147,7 +147,7 @@ letters, digits, plus or minus signs or colons."
;;;###autoload(put 'parse-time-rules 'risky-local-variable t)
;;;###autoload
(defun parse-time-string (string &optional form)
(defun parse-time-string (string)
"Parse the time in STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ).
STRING should be an ISO 8601 time string, e.g., \"2020-01-15T16:12:21-08:00\",
or something resembling an RFC 822 (or later) date-time, e.g.,
@ -156,11 +156,9 @@ somewhat liberal in what format it accepts, and will attempt to
return a \"likely\" value even for somewhat malformed strings.
The values returned are identical to those of `decode-time', but
any unknown values other than DST are returned as nil, and an
unknown DST value is returned as -1.
See `decode-time' for the meaning of FORM."
unknown DST value is returned as -1."
(condition-case ()
(iso8601-parse string form)
(iso8601-parse string)
(wrong-type-argument
(let ((time (list nil nil nil nil nil nil nil -1 nil))
(temp (parse-time-tokenize (downcase string))))
@ -201,14 +199,12 @@ See `decode-time' for the meaning of FORM."
(setf (nth (pop slots) time) new-val))))))))
time))))
(defun parse-iso8601-time-string (date-string &optional form)
(defun parse-iso8601-time-string (date-string)
"Parse an ISO 8601 time string, such as \"2020-01-15T16:12:21-08:00\".
Fall back on parsing something resembling an RFC 822 (or later) date-time.
This function is like `parse-time-string' except that it returns
a Lisp timestamp when successful.
See `decode-time' for the meaning of FORM."
(when-let ((time (parse-time-string date-string form)))
a Lisp timestamp when successful."
(when-let ((time (parse-time-string date-string)))
(encode-time time)))
(provide 'parse-time)

View file

@ -927,9 +927,9 @@ marked file, return (t FILENAME) instead of (FILENAME)."
(lambda ()
(if ,show-progress (sit-for 0))
(setq results (cons ,body results))))
(when (< ,arg 0)
(setq results (nreverse results)))
results)
(if (< ,arg 0)
(nreverse results)
results))
;; non-nil, non-integer, non-marked ARG means use current file:
(list ,body))
(let ((regexp (dired-marker-regexp)) next-position)
@ -1647,16 +1647,13 @@ If HDR is non-nil, insert a header line with the directory name."
;; save the answer in `dired-use-ls-dired'.
(or (setq dired-use-ls-dired
(eq 0 (call-process insert-directory-program
nil nil nil "--dired" "-N")))
nil nil nil "--dired")))
(progn
(message "ls does not support --dired -N; \
(message "ls does not support --dired; \
see `dired-use-ls-dired' for more details.")
nil))
dired-use-ls-dired)))
;; Use -N with --dired, to countermand possible non-default
;; quoting style, in particular via the environment variable
;; QUOTING_STYLE.
(setq switches (concat "--dired -N " switches)))
(setq switches (concat "--dired " switches)))
;; Expand directory wildcards and fill file-list.
(let ((dir-wildcard (insert-directory-wildcard-in-dir-p dir)))
(cond (dir-wildcard
@ -1665,7 +1662,7 @@ see `dired-use-ls-dired' for more details.")
;; "--dired", so we cannot add it to the `process-file'
;; call for wildcards.
(when (file-remote-p dir)
(setq switches (string-replace "--dired -N" "" switches)))
(setq switches (string-replace "--dired" "" switches)))
(let* ((default-directory (car dir-wildcard))
(script (format "ls %s %s" switches (cdr dir-wildcard)))
(remotep (file-remote-p dir))

View file

@ -499,6 +499,7 @@ Reprint the frame with the new view plist."
(defun backtrace-expand-ellipsis (button)
"Expand display of the elided form at BUTTON."
(interactive)
(goto-char (button-start button))
(unless (get-text-property (point) 'cl-print-ellipsis)
(if (and (> (point) (point-min))

View file

@ -221,17 +221,21 @@ for speeding up processing.")
(defun byte-optimize--substitutable-p (expr)
"Whether EXPR is a constant that can be propagated."
;; Only consider numbers, symbols and strings to be values for substitution
;; purposes. Numbers and symbols are immutable, and mutating string
;; literals (or results from constant-evaluated string-returning functions)
;; can be considered undefined.
;; (What about other quoted values, like conses?)
(or (booleanp expr)
(numberp expr)
(arrayp expr)
(let ((head (car-safe expr)))
(cond ((eq head 'quote) t)
;; Don't substitute #'(lambda ...) since that would enable
;; uncontrolled inlining.
((eq head 'function) (symbolp (cadr expr)))
;; (internal-get-closed-var N) can be considered constant for
;; const-prop purposes.
((eq head 'internal-get-closed-var) (integerp (cadr expr)))))
(stringp expr)
(and (consp expr)
(or (and (memq (car expr) '(quote function))
(symbolp (cadr expr)))
;; (internal-get-closed-var N) can be considered constant for
;; const-prop purposes.
(and (eq (car expr) 'internal-get-closed-var)
(integerp (cadr expr)))))
(keywordp expr)))
(defmacro byte-optimize--pcase (exp &rest cases)
@ -465,6 +469,10 @@ for speeding up processing.")
form
(byte-optimize-form newform for-effect))))
;; FIXME: Strictly speaking, I think this is a bug: (closure...)
;; is a *value* and shouldn't appear in the car.
(`((closure . ,_) . ,_) form)
(`(setq ,var ,expr)
(let ((lexvar (assq var byte-optimize--lexvars))
(value (byte-optimize-form expr nil)))
@ -492,13 +500,19 @@ for speeding up processing.")
(cons fn (mapcar #'byte-optimize-form exps)))
(`(,(pred (not symbolp)) . ,_)
(byte-compile-warn-x form "`%s' is a malformed function" fn)
(byte-compile-warn-x fn "`%s' is a malformed function" fn)
form)
((guard (when for-effect
(if-let ((tmp (byte-opt--fget fn 'side-effect-free)))
(or byte-compile-delete-errors
(eq tmp 'error-free)))))
(eq tmp 'error-free)
(progn
(byte-compile-warn-x
form
"value returned from %s is unused"
form)
nil)))))
(byte-compile-log " %s called for effect; deleted" fn)
(byte-optimize-form (cons 'progn (cdr form)) t))
@ -1412,13 +1426,10 @@ See Info node `(elisp) Integer Basics'."
(defun byte-optimize-funcall (form)
;; (funcall #'(lambda ...) ...) -> ((lambda ...) ...)
;; (funcall #'SYM ...) -> (SYM ...)
;; (funcall 'SYM ...) -> (SYM ...)
(let* ((fn (nth 1 form))
(head (car-safe fn)))
(if (or (eq head 'function)
(and (eq head 'quote) (symbolp (nth 1 fn))))
;; (funcall (lambda ...) ...) ==> ((lambda ...) ...)
;; (funcall foo ...) ==> (foo ...)
(let ((fn (nth 1 form)))
(if (memq (car-safe fn) '(quote function))
(cons (nth 1 fn) (cdr (cdr form)))
form)))
@ -1515,44 +1526,6 @@ See Info node `(elisp) Integer Basics'."
;; (list) -> nil
(and (cdr form) form))
(put 'nconc 'byte-optimizer #'byte-optimize-nconc)
(defun byte-optimize-nconc (form)
(pcase (cdr form)
('nil nil) ; (nconc) -> nil
(`(,x) x) ; (nconc X) -> X
(_ (named-let loop ((args (cdr form)) (newargs nil))
(if args
(let ((arg (car args))
(prev (car newargs)))
(cond
;; Elide null args.
((and (null arg)
;; Don't elide a terminal nil unless preceded by
;; a nonempty proper list, since that will have
;; its last cdr forced to nil.
(or (cdr args)
;; FIXME: prove the 'nonempty proper list' property
;; for more forms than just `list', such as
;; `append', `mapcar' etc.
(eq 'list (car-safe (car newargs)))))
(loop (cdr args) newargs))
;; Merge consecutive `list' args.
((and (eq (car-safe arg) 'list)
(eq (car-safe prev) 'list))
(loop (cons (cons (car prev) (append (cdr prev) (cdr arg)))
(cdr args))
(cdr newargs)))
;; (nconc ... (list A) B ...) -> (nconc ... (cons A B) ...)
((and (eq (car-safe prev) 'list) (cdr prev) (null (cddr prev)))
(loop (cdr args)
(cons (list 'cons (cadr prev) arg)
(cdr newargs))))
(t (loop (cdr args) (cons arg newargs)))))
(let ((new-form (cons (car form) (nreverse newargs))))
(if (equal new-form form)
form
new-form)))))))
(put 'append 'byte-optimizer #'byte-optimize-append)
(defun byte-optimize-append (form)
;; There is (probably) too much code relying on `append' to return a
@ -1605,9 +1578,11 @@ See Info node `(elisp) Integer Basics'."
;; (append X) -> X
((null newargs) arg)
;; (append ... (list Xs...) nil) -> (append ... (list Xs...))
((and (null arg) (eq (car-safe prev) 'list))
(cons (car form) (nreverse newargs)))
;; (append (list Xs...) nil) -> (list Xs...)
((and (null arg)
newargs (null (cdr newargs))
(consp prev) (eq (car prev) 'list))
prev)
;; (append '(X) Y) -> (cons 'X Y)
;; (append (list X) Y) -> (cons X Y)
@ -1618,13 +1593,13 @@ See Info node `(elisp) Integer Basics'."
(= (length (cadr prev)) 1)))
((eq (car prev) 'list)
(= (length (cdr prev)) 1))))
`(cons ,(if (eq (car prev) 'quote)
(macroexp-quote (caadr prev))
(cadr prev))
,arg))
(list 'cons (if (eq (car prev) 'quote)
(macroexp-quote (caadr prev))
(cadr prev))
arg))
(t
(let ((new-form (cons (car form) (nreverse (cons arg newargs)))))
(let ((new-form (cons 'append (nreverse (cons arg newargs)))))
(if (equal new-form form)
form
new-form))))))))
@ -1667,231 +1642,98 @@ See Info node `(elisp) Integer Basics'."
;; I wonder if I missed any :-\)
(let ((side-effect-free-fns
'(
;; alloc.c
make-bool-vector make-byte-code make-list make-record make-string
make-symbol make-vector
;; buffer.c
buffer-base-buffer buffer-chars-modified-tick buffer-file-name
buffer-local-value buffer-local-variables buffer-modified-p
buffer-modified-tick buffer-name get-buffer next-overlay-change
overlay-buffer overlay-end overlay-get overlay-properties
overlay-start overlays-at overlays-in previous-overlay-change
;; callint.c
prefix-numeric-value
;; casefiddle.c
capitalize downcase upcase upcase-initials
;; category.c
category-docstring category-set-mnemonics char-category-set
copy-category-table get-unused-category make-category-set
;; character.c
char-width multibyte-char-to-unibyte string unibyte-char-to-multibyte
;; charset.c
decode-char encode-char
;; chartab.c
make-char-table
;; data.c
% * + - / /= 1+ 1- < <= = > >=
aref ash bare-symbol
'(% * + - / /= 1+ 1- < <= = > >= abs acos append aref ash asin atan
assq
base64-decode-string base64-encode-string base64url-encode-string
bool-vector-count-consecutive bool-vector-count-population
bool-vector-subsetp
boundp car cdr default-boundp default-value fboundp
get-variable-watchers indirect-variable
local-variable-if-set-p local-variable-p
logand logcount logior lognot logxor max min mod
number-to-string position-symbol string-to-number
subr-arity subr-name subr-native-lambda-list subr-type
symbol-function symbol-name symbol-plist symbol-value
symbol-with-pos-pos variable-binding-locus
;; doc.c
documentation
;; editfns.c
buffer-substring buffer-substring-no-properties
byte-to-position byte-to-string
char-after char-before char-equal char-to-string
compare-buffer-substrings
format format-message
group-name
line-beginning-position line-end-position ngettext pos-bol pos-eol
propertize region-beginning region-end string-to-char
user-full-name user-login-name
;; fileio.c
car-less-than-car directory-name-p file-directory-p file-exists-p
file-name-absolute-p file-name-concat file-newer-than-file-p
file-readable-p file-symlink-p file-writable-p
;; filelock.c
file-locked-p
;; floatfns.c
abs acos asin atan ceiling copysign cos exp expt fceiling ffloor
float floor fround ftruncate isnan ldexp log logb round sin sqrt tan
truncate
;; fns.c
append assq
base64-decode-string base64-encode-string base64url-encode-string
compare-strings concat copy-alist copy-hash-table copy-sequence elt
featurep get
gethash hash-table-count hash-table-rehash-size
hash-table-rehash-threshold hash-table-size hash-table-test
hash-table-weakness
length length< length= length>
line-number-at-pos locale-info make-hash-table
member memq memql nth nthcdr
object-intervals rassoc rassq reverse
string-as-multibyte string-as-unibyte string-bytes string-distance
string-equal string-lessp string-make-multibyte string-make-unibyte
string-search string-to-multibyte substring substring-no-properties
sxhash-eq sxhash-eql sxhash-equal sxhash-equal-including-properties
take vconcat
;; frame.c
frame-ancestor-p frame-bottom-divider-width frame-char-height
frame-char-width frame-child-frame-border-width frame-focus
frame-fringe-width frame-internal-border-width frame-native-height
frame-native-width frame-parameter frame-parameters frame-parent
frame-pointer-visible-p frame-position frame-right-divider-width
frame-scale-factor frame-scroll-bar-height frame-scroll-bar-width
frame-text-cols frame-text-height frame-text-lines frame-text-width
frame-total-cols frame-total-lines frame-visible-p
frame-window-state-change next-frame previous-frame
tool-bar-pixel-width window-system
;; fringe.c
fringe-bitmaps-at-pos
;; keyboard.c
posn-at-point posn-at-x-y
;; keymap.c
copy-keymap keymap-parent keymap-prompt make-keymap make-sparse-keymap
;; lread.c
intern-soft read-from-string
;; marker.c
copy-marker marker-buffer marker-insertion-type marker-position
;; minibuf.c
active-minibuffer-window assoc-string innermost-minibuffer-p
minibuffer-innermost-command-loop-p minibufferp
;; print.c
error-message-string prin1-to-string
;; process.c
format-network-address get-buffer-process get-process
process-buffer process-coding-system process-command process-filter
process-id process-inherit-coding-system-flag process-mark
process-name process-plist process-query-on-exit-flag
process-running-child-p process-sentinel process-thread
process-tty-name process-type
;; search.c
match-beginning match-end regexp-quote
;; sqlite.c
sqlite-columns sqlite-more-p sqlite-version
;; syntax.c
char-syntax copy-syntax-table matching-paren string-to-syntax
syntax-class-to-char
;; term.c
controlling-tty-p tty-display-color-cells tty-display-color-p
tty-top-frame tty-type
;; terminal.c
frame-terminal terminal-list terminal-live-p terminal-name
terminal-parameter terminal-parameters
;; textprop.c
get-char-property get-char-property-and-overlay get-text-property
next-char-property-change next-property-change
next-single-char-property-change next-single-property-change
previous-char-property-change previous-property-change
previous-single-char-property-change previous-single-property-change
text-properties-at text-property-any text-property-not-all
;; thread.c
all-threads condition-mutex condition-name mutex-name thread-live-p
thread-name
;; timefns.c
current-time-string current-time-zone decode-time encode-time
float-time format-time-string time-add time-convert time-equal-p
time-less-p time-subtract
;; window.c
coordinates-in-window-p frame-first-window frame-root-window
frame-selected-window get-buffer-window minibuffer-selected-window
minibuffer-window next-window previous-window window-at
window-body-height window-body-width window-buffer
window-combination-limit window-configuration-equal-p
window-dedicated-p window-display-table window-frame window-fringes
window-hscroll window-left-child window-left-column window-margins
window-minibuffer-p window-new-normal window-new-total
window-next-buffers window-next-sibling window-normal-size
window-parameter window-parameters window-parent window-point
window-prev-buffers window-prev-sibling window-scroll-bars
window-start window-text-height window-top-child window-top-line
window-total-height window-total-width window-use-time window-vscroll
;; xdisp.c
buffer-text-pixel-size current-bidi-paragraph-direction
get-display-property invisible-p line-pixel-height lookup-image-map
tab-bar-height tool-bar-height window-text-pixel-size
))
boundp buffer-file-name buffer-local-variables buffer-modified-p
buffer-substring byte-code-function-p
capitalize car-less-than-car car cdr ceiling char-after char-before
char-equal char-to-string char-width compare-strings
window-configuration-equal-p concat coordinates-in-window-p
copy-alist copy-sequence copy-marker copysign cos
current-time-string current-time-zone
decode-char
decode-time default-boundp default-value documentation downcase
elt encode-char exp expt encode-time error-message-string
fboundp fceiling featurep ffloor
file-directory-p file-exists-p file-locked-p file-name-absolute-p
file-name-concat
file-newer-than-file-p file-readable-p file-symlink-p file-writable-p
float float-time floor format format-message format-time-string
frame-first-window frame-root-window frame-selected-window
frame-visible-p fround ftruncate
get gethash get-buffer get-buffer-window get-file-buffer
hash-table-count
intern-soft isnan
keymap-parent
ldexp
length length< length> length=
line-beginning-position line-end-position pos-bol pos-eol
local-variable-if-set-p local-variable-p locale-info
log logand logb logcount logior lognot logxor
make-byte-code make-list make-string make-symbol marker-buffer max
match-beginning match-end
member memq memql min minibuffer-selected-window minibuffer-window
mod multibyte-char-to-unibyte next-window nth nthcdr number-to-string
prefix-numeric-value previous-window prin1-to-string propertize
rassq rassoc read-from-string
regexp-quote region-beginning region-end reverse round
sin sqrt string string-equal string-lessp
string-search string-to-char
string-to-number string-to-syntax substring substring-no-properties
sxhash-equal sxhash-eq sxhash-eql
symbol-function symbol-name symbol-plist symbol-value
string-make-unibyte
string-make-multibyte string-as-multibyte string-as-unibyte
string-to-multibyte
take tan time-convert truncate
unibyte-char-to-multibyte upcase user-full-name
user-login-name
vconcat
window-at window-body-height
window-body-width window-buffer window-dedicated-p window-display-table
window-combination-limit window-frame window-fringes
window-hscroll
window-left-child window-left-column window-margins window-minibuffer-p
window-next-buffers window-next-sibling window-new-normal
window-new-total window-normal-size window-parameter window-parameters
window-parent window-point window-prev-buffers
window-prev-sibling window-scroll-bars
window-start window-text-height window-top-child window-top-line
window-total-height window-total-width window-use-time window-vscroll
))
(side-effect-and-error-free-fns
'(
;; alloc.c
bool-vector cons list make-marker purecopy record vector
;; buffer.c
buffer-list buffer-live-p current-buffer overlay-lists overlayp
;; casetab.c
case-table-p current-case-table standard-case-table
;; category.c
category-table category-table-p make-category-table
standard-category-table
;; character.c
characterp max-char
;; charset.c
charsetp
;; data.c
arrayp atom bare-symbol-p bool-vector-p bufferp byte-code-function-p
byteorder car-safe cdr-safe char-or-string-p char-table-p
condition-variable-p consp eq floatp indirect-function
integer-or-marker-p integerp keywordp listp markerp
module-function-p multibyte-string-p mutexp natnump nlistp null
number-or-marker-p numberp recordp remove-pos-from-symbol
sequencep stringp subr-native-elisp-p subrp symbol-with-pos-p symbolp
threadp type-of user-ptrp vector-or-char-table-p vectorp wholenump
;; editfns.c
bobp bolp buffer-size buffer-string current-message emacs-pid
eobp eolp following-char gap-position gap-size group-gid
group-real-gid mark-marker point point-marker point-max point-min
position-bytes preceding-char system-name
user-real-login-name user-real-uid user-uid
;; emacs.c
invocation-directory invocation-name
;; eval.c
commandp functionp
;; fileio.c
default-file-modes
;; fns.c
eql equal hash-table-p identity proper-list-p safe-length
secure-hash-algorithms
;; frame.c
frame-list frame-live-p framep last-nonminibuffer-frame
old-selected-frame selected-frame visible-frame-list
;; image.c
imagep
;; indent.c
current-column current-indentation
;; keyboard.c
current-idle-time current-input-mode recent-keys recursion-depth
this-command-keys this-command-keys-vector this-single-command-keys
this-single-command-raw-keys
;; keymap.c
current-global-map current-local-map current-minor-mode-maps keymapp
;; minibuf.c
minibuffer-contents minibuffer-contents-no-properties minibuffer-depth
minibuffer-prompt minibuffer-prompt-end
;; process.c
process-list processp signal-names waiting-for-user-input-p
;; sqlite.c
sqlite-available-p sqlitep
;; syntax.c
standard-syntax-table syntax-table syntax-table-p
;; thread.c
current-thread
;; timefns.c
current-time
;; window.c
selected-window window-configuration-p window-live-p window-valid-p
windowp
;; xdisp.c
long-line-optimizations-p
)))
'(arrayp atom
bobp bolp bool-vector-p
buffer-list buffer-size buffer-string bufferp
car-safe case-table-p cdr-safe char-or-string-p characterp
charsetp commandp cons consp
current-buffer current-global-map current-indentation
current-local-map current-minor-mode-maps current-time
eobp eolp eq equal
floatp following-char framep
hash-table-p
identity indirect-function integerp integer-or-marker-p
invocation-directory invocation-name
keymapp keywordp
list listp
make-marker mark-marker markerp max-char
natnump nlistp null number-or-marker-p numberp
overlayp
point point-marker point-min point-max preceding-char
processp proper-list-p
recent-keys recursion-depth
safe-length selected-frame selected-window sequencep
standard-case-table standard-syntax-table stringp subrp symbolp
syntax-table syntax-table-p
this-command-keys this-command-keys-vector this-single-command-keys
this-single-command-raw-keys type-of
user-real-login-name user-real-uid user-uid
vector vectorp visible-frame-list
wholenump window-configuration-p window-live-p
window-valid-p windowp)))
(while side-effect-free-fns
(put (car side-effect-free-fns) 'side-effect-free t)
(setq side-effect-free-fns (cdr side-effect-free-fns)))
@ -1916,34 +1758,41 @@ See Info node `(elisp) Integer Basics'."
;; values if a marker is moved.
(let ((pure-fns
'(
;; character.c
characterp
;; data.c
% * + - / /= 1+ 1- < <= = > >= aref arrayp ash atom bare-symbol
bool-vector-count-consecutive bool-vector-count-population
bool-vector-p bool-vector-subsetp
bufferp car car-safe cdr cdr-safe char-or-string-p char-table-p
condition-variable-p consp eq floatp integer-or-marker-p integerp
keywordp listp logand logcount logior lognot logxor markerp max min
mod multibyte-string-p mutexp natnump nlistp null number-or-marker-p
numberp recordp remove-pos-from-symbol sequencep stringp symbol-name
symbolp threadp type-of vector-or-char-table-p vectorp
;; editfns.c
string-to-char
;; floatfns.c
abs ceiling copysign fceiling ffloor float floor fround ftruncate
isnan ldexp logb round sqrt truncate
;; fns.c
assq base64-decode-string base64-encode-string base64url-encode-string
concat elt eql equal hash-table-p identity length length< length=
length> member memq memql nth nthcdr proper-list-p rassoc rassq
safe-length string-bytes string-distance string-equal string-lessp
string-search take
;; search.c
regexp-quote
;; syntax.c
string-to-syntax
'(concat regexp-quote
string-to-char string-to-syntax symbol-name
eq eql
= /= < <= >= > min max
+ - * / % mod abs ash 1+ 1- sqrt
logand logior lognot logxor logcount
copysign isnan ldexp float logb
floor ceiling round truncate
ffloor fceiling fround ftruncate
string-equal string-lessp
string-search
consp atom listp nlistp proper-list-p
sequencep arrayp vectorp stringp bool-vector-p hash-table-p
null
numberp integerp floatp natnump characterp
integer-or-marker-p number-or-marker-p char-or-string-p
symbolp keywordp
type-of
identity
;; The following functions are pure up to mutation of their
;; arguments. This is pure enough for the purposes of
;; constant folding, but not necessarily for all kinds of
;; code motion.
car cdr car-safe cdr-safe nth nthcdr take
equal
length safe-length
memq memql member
;; `assoc' and `assoc-default' are excluded since they are
;; impure if the test function is (consider `string-match').
assq rassq rassoc
aref elt
base64-decode-string base64-encode-string base64url-encode-string
bool-vector-subsetp
bool-vector-count-population bool-vector-count-consecutive
)))
(while pure-fns
(put (car pure-fns) 'pure t)

View file

@ -145,11 +145,6 @@ So far, FUNCTION can only be a symbol, not a lambda expression."
(list 'function-put (list 'quote f)
''side-effect-free (list 'quote val))))
(defalias 'byte-run--set-important-return-value
#'(lambda (f _args val)
(list 'function-put (list 'quote f)
''important-return-value (list 'quote val))))
(put 'compiler-macro 'edebug-declaration-spec
'(&or symbolp ("lambda" &define lambda-list lambda-doc def-body)))
@ -231,8 +226,6 @@ This may shift errors from run-time to compile-time.")
(list 'side-effect-free #'byte-run--set-side-effect-free
"If non-nil, calls can be ignored if their value is unused.
If `error-free', drop calls even if `byte-compile-delete-errors' is nil.")
(list 'important-return-value #'byte-run--set-important-return-value
"If non-nil, warn about calls not using the returned value.")
(list 'compiler-macro #'byte-run--set-compiler-macro)
(list 'doc-string #'byte-run--set-doc-string)
(list 'indent #'byte-run--set-indent)
@ -657,8 +650,11 @@ in `byte-compile-warning-types'; see the variable
`byte-compile-warnings' for a fuller explanation of the warning
types. The types that can be suppressed with this macro are
`free-vars', `callargs', `redefine', `obsolete',
`interactive-only', `lexical', `ignored-return-value', `constants',
`suspicious' and `empty-body'."
`interactive-only', `lexical', `mapcar', `constants',
`suspicious' and `empty-body'.
For the `mapcar' case, only the `mapcar' function can be used in
the symbol list."
;; Note: during compilation, this definition is overridden by the one in
;; byte-compile-initial-macro-environment.
(declare (debug (sexp body)) (indent 1))

View file

@ -317,9 +317,7 @@ Elements of the list may be:
lexical-dynamic
lexically bound variable declared dynamic elsewhere
make-local calls to `make-variable-buffer-local' that may be incorrect.
ignored-return-value
function called without using the return value where this
is likely to be a mistake
mapcar mapcar called for effect.
not-unused warning about using variables with symbol names starting with _.
constants let-binding of, or assignment to, constants/nonvariables.
docstrings docstrings that are too wide (longer than
@ -332,7 +330,7 @@ Elements of the list may be:
empty-body body argument to a special form or macro is empty.
If the list begins with `not', then the remaining elements specify warnings to
suppress. For example, (not free-vars) will suppress the `free-vars' warning.
suppress. For example, (not mapcar) will suppress warnings about mapcar.
The t value means \"all non experimental warning types\", and
excludes the types in `byte-compile--emacs-build-warning-types'.
@ -3492,29 +3490,6 @@ lambda-expression."
(byte-compile-report-error
(format-message "`%s' defined after use in %S (missing `require' of a library file?)"
(car form) form)))
(when byte-compile--for-effect
(let ((sef (function-get (car form) 'side-effect-free)))
(cond
((and sef (or (eq sef 'error-free)
byte-compile-delete-errors))
;; This transform is normally done in the Lisp optimiser,
;; so maybe we don't need to bother about it here?
(setq form (cons 'progn (cdr form)))
(setq handler #'byte-compile-progn))
((and (or sef (function-get (car form) 'important-return-value))
;; Don't warn for arguments to `ignore'.
(not (eq byte-compile--for-effect 'for-effect-no-warn))
(byte-compile-warning-enabled-p
'ignored-return-value (car form)))
(byte-compile-warn-x
(car form)
"value from call to `%s' is unused%s"
(car form)
(cond ((eq (car form) 'mapcar)
"; use `mapc' or `dolist' instead")
(t "")))))))
(if (and handler
;; Make sure that function exists.
(and (functionp handler)
@ -3538,26 +3513,6 @@ lambda-expression."
(byte-compile-discard))
(pop byte-compile-form-stack)))
(let ((important-return-value-fns
'(
;; These functions are side-effect-free except for the
;; behaviour of functions passed as argument.
mapcar mapcan mapconcat
assoc plist-get plist-member
;; It's safe to ignore the value of `sort' and `nreverse'
;; when used on arrays, but most calls pass lists.
nreverse sort
;; Adding these functions causes many warnings;
;; evaluate how many of them are false first.
;;delq delete
;;nconc plist-put
)))
(dolist (fn important-return-value-fns)
(put fn 'important-return-value t)))
(defun byte-compile-normal-call (form)
(when (and (symbolp (car form))
(byte-compile-warning-enabled-p 'callargs (car form)))
@ -3568,7 +3523,11 @@ lambda-expression."
(byte-compile-callargs-warn form))
(if byte-compile-generate-call-tree
(byte-compile-annotate-call-tree form))
(when (and byte-compile--for-effect (eq (car form) 'mapcar)
(byte-compile-warning-enabled-p 'mapcar 'mapcar))
(byte-compile-warn-x
(car form)
"`mapcar' called for effect; use `mapc' or `dolist' instead"))
(byte-compile-push-constant (car form))
(mapc 'byte-compile-form (cdr form)) ; wasteful, but faster.
(byte-compile-out 'byte-call (length (cdr form))))
@ -4408,8 +4367,7 @@ This function is never called when `lexical-binding' is nil."
(defun byte-compile-ignore (form)
(dolist (arg (cdr form))
;; Compile each argument for-effect but suppress unused-value warnings.
(byte-compile-form arg 'for-effect-no-warn))
(byte-compile-form arg t))
(byte-compile-form nil))
;; Return the list of items in CONDITION-PARAM that match PRED-LIST.

View file

@ -408,7 +408,6 @@ Other non-digit chars are considered junk.
RADIX is an integer between 2 and 36, the default is 10. Signal
an error if the substring between START and END cannot be parsed
as an integer unless JUNK-ALLOWED is non-nil."
(declare (side-effect-free t))
(cl-check-type string string)
(let* ((start (or start 0))
(len (length string))
@ -567,7 +566,6 @@ too large if positive or too small if negative)."
;;;###autoload
(defun cl-revappend (x y)
"Equivalent to (append (reverse X) Y)."
(declare (side-effect-free t))
(nconc (reverse x) y))
;;;###autoload

View file

@ -459,7 +459,6 @@ Thus, `(cl-list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
(defun cl-copy-list (list)
"Return a copy of LIST, which may be a dotted list.
The elements of LIST are not copied, just the list structure itself."
(declare (side-effect-free error-free))
(if (consp list)
(let ((res nil))
(while (consp list) (push (pop list) res))

View file

@ -2891,14 +2891,45 @@ The function's arguments should be treated as immutable.
,(format "compiler-macro for inlining `%s'." name)
(cl--defsubst-expand
',argns '(cl-block ,name ,@(cdr (macroexp-parse-body body)))
;; We used to pass `simple' as
;; (not (or unsafe (cl-expr-access-order pbody argns)))
;; But this is much too simplistic since it
;; does not pay attention to the argvs (and
;; cl-expr-access-order itself is also too naive).
nil
,(and (memq '&key args) 'cl-whole) nil ,@argns)))
(cl-defun ,name ,args ,@body))))
(defun cl--defsubst-expand (argns body _simple whole _unsafe &rest argvs)
(if (and whole (not (cl--safe-expr-p (cons 'progn argvs))))
whole
`(let ,(cl-mapcar #'list argns argvs) ,body)))
(defun cl--defsubst-expand (argns body simple whole _unsafe &rest argvs)
(if (and whole (not (cl--safe-expr-p (cons 'progn argvs)))) whole
(if (cl--simple-exprs-p argvs) (setq simple t))
(let* ((substs ())
(lets (delq nil
(cl-mapcar (lambda (argn argv)
(if (or simple (macroexp-const-p argv))
(progn (push (cons argn argv) substs)
nil)
(list argn argv)))
argns argvs))))
;; FIXME: `sublis/subst' will happily substitute the symbol
;; `argn' in places where it's not used as a reference
;; to a variable.
;; FIXME: `sublis/subst' will happily copy `argv' to a different
;; scope, leading to name capture.
(setq body (cond ((null substs) body)
((null (cdr substs))
(cl-subst (cdar substs) (caar substs) body))
(t (cl--sublis substs body))))
(if lets `(let ,lets ,body) body))))
(defun cl--sublis (alist tree)
"Perform substitutions indicated by ALIST in TREE (non-destructively)."
(let ((x (assq tree alist)))
(cond
(x (cdr x))
((consp tree)
(cons (cl--sublis alist (car tree)) (cl--sublis alist (cdr tree))))
(t tree))))
;;; Structures.
@ -3213,8 +3244,19 @@ To see the documentation for a defined struct type, use
(let* ((anames (cl--arglist-args args))
(make (cl-mapcar (lambda (s d) (if (memq s anames) s d))
slots defaults))
(con-fun (or type #'record)))
(push `(,cldefsym ,cname
;; `cl-defsubst' is fundamentally broken: it substitutes
;; its arguments into the body's `sexp' much too naively
;; when inlinling, which results in various problems.
;; For example it generates broken code if your
;; argument's name happens to be the same as some
;; function used within the body.
;; E.g. (cl-defsubst sm-foo (list) (list list))
;; will expand `(sm-foo 1)' to `(1 1)' rather than to `(list t)'!
;; Try to catch this known case!
(con-fun (or type #'record))
(unsafe-cl-defsubst
(or (memq con-fun args) (assq con-fun args))))
(push `(,(if unsafe-cl-defsubst 'cl-defun cldefsym) ,cname
(&cl-defs (nil ,@descs) ,@args)
,(if (stringp doc) doc
(format "Constructor for objects of type `%s'." name))
@ -3648,53 +3690,14 @@ macro that returns its `&whole' argument."
;;; Things that are side-effect-free.
(mapc (lambda (x) (function-put x 'side-effect-free t))
'(cl-oddp cl-evenp cl-signum cl-ldiff cl-pairlis cl-gcd
'(cl-oddp cl-evenp cl-signum last butlast cl-ldiff cl-pairlis cl-gcd
cl-lcm cl-isqrt cl-floor cl-ceiling cl-truncate cl-round cl-mod cl-rem
cl-subseq cl-list-length cl-get cl-getf))
;;; Things that are side-effect-and-error-free.
(mapc (lambda (x) (function-put x 'side-effect-free 'error-free))
'(cl-list* cl-acons cl-equalp
cl-random-state-p copy-tree))
;;; Things whose return value should probably be used.
(mapc (lambda (x) (function-put x 'important-return-value t))
'(
;; Functions that are side-effect-free except for the
;; behaviour of functions passed as argument.
cl-mapcar cl-mapcan cl-maplist cl-map cl-mapcon
cl-reduce
cl-assoc cl-assoc-if cl-assoc-if-not
cl-rassoc cl-rassoc-if cl-rassoc-if-not
cl-member cl-member-if cl-member-if-not
cl-adjoin
cl-mismatch cl-search
cl-find cl-find-if cl-find-if-not
cl-position cl-position-if cl-position-if-not
cl-count cl-count-if cl-count-if-not
cl-remove cl-remove-if cl-remove-if-not
cl-remove-duplicates
cl-subst cl-subst-if cl-subst-if-not
cl-substitute cl-substitute-if cl-substitute-if-not
cl-sublis
cl-union cl-intersection cl-set-difference cl-set-exclusive-or
cl-subsetp
cl-every cl-some cl-notevery cl-notany
cl-tree-equal
;; Functions that mutate and return a list.
cl-delete cl-delete-if cl-delete-if-not
cl-delete-duplicates
cl-nsubst cl-nsubst-if cl-nsubst-if-not
cl-nsubstitute cl-nsubstitute-if cl-nsubstitute-if-not
cl-nunion cl-nintersection cl-nset-difference cl-nset-exclusive-or
cl-nreconc cl-nsublis
cl-merge
;; It's safe to ignore the value of `cl-sort' and `cl-stable-sort'
;; when used on arrays, but most calls pass lists.
cl-sort cl-stable-sort
))
'(eql cl-list* cl-subst cl-acons cl-equalp
cl-random-state-p copy-tree cl-sublis))
;;; Types and assertions.

View file

@ -176,7 +176,6 @@ supertypes from the most specific to least specific.")
(i 0)
(offset (if type 0 1)))
(dolist (slot slots)
(put (car slot) 'slot-name t)
(let* ((props (cl--plist-to-alist (cddr slot)))
(typep (assq :type props))
(type (if (null typep) t

View file

@ -681,35 +681,30 @@ This is the default value for `eldoc-documentation-strategy'."
(lambda (f)
(funcall f (eldoc--make-callback :eager f)))))
(defun eldoc-documentation-compose ()
"Show multiple documentation strings together after waiting for all of them.
This is meant to be used as a value for `eldoc-documentation-strategy'."
(let (fns-and-callbacks)
;; Make all the callbacks, setting up state inside
;; `eldoc--invoke-strategy' to know how many callbacks to wait for
;; before displaying the result (bug#62816).
(run-hook-wrapped 'eldoc-documentation-functions
(lambda (f)
(push (cons f (eldoc--make-callback :patient f))
fns-and-callbacks)
nil))
;; Now call them. The last one will trigger the display.
(cl-loop for (f . callback) in fns-and-callbacks
for str = (funcall f callback)
when (or (null str) (stringp str)) do (funcall callback str)))
t)
(defun eldoc-documentation-compose-eagerly ()
"Show multiple documentation strings one by one as soon as possible.
This is meant to be used as a value for `eldoc-documentation-strategy'."
(defun eldoc--documentation-compose-1 (eagerlyp)
"Helper function for composing multiple doc strings.
If EAGERLYP is non-nil show documentation as soon as possible,
else wait for all doc strings."
(run-hook-wrapped 'eldoc-documentation-functions
(lambda (f)
(let* ((callback (eldoc--make-callback :eager f))
(let* ((callback (eldoc--make-callback
(if eagerlyp :eager :patient)
f))
(str (funcall f callback)))
(if (or (null str) (stringp str)) (funcall callback str))
nil)))
t)
(defun eldoc-documentation-compose ()
"Show multiple documentation strings together after waiting for all of them.
This is meant to be used as a value for `eldoc-documentation-strategy'."
(eldoc--documentation-compose-1 nil))
(defun eldoc-documentation-compose-eagerly ()
"Show multiple documentation strings one by one as soon as possible.
This is meant to be used as a value for `eldoc-documentation-strategy'."
(eldoc--documentation-compose-1 t))
(defun eldoc-documentation-enthusiast ()
"Show most important documentation string produced so far.
This is meant to be used as a value for `eldoc-documentation-strategy'."

View file

@ -563,9 +563,9 @@ The same keyword arguments are supported as in
;; Emacs's Makefile sets $HOME to a nonexistent value. Needed
;; in batch mode only, therefore.
(when (and noninteractive (not (file-directory-p "~/")))
(setenv "HOME" (directory-file-name temporary-file-directory)))
(setenv "HOME" temporary-file-directory))
(format "/mock::%s" temporary-file-directory))))
"Temporary directory for remote file tests.")
"Temporary directory for remote file tests.")
(provide 'ert-x)

View file

@ -639,13 +639,6 @@ REF must have been previously obtained with `gv-ref'."
;;; Generalized variables.
;; You'd think noone would write `(setf (error ...) ..)' but it
;; appears naturally as the result of macroexpansion of things like
;; (setf (pcase-exhaustive ...)).
;; We could generalize this to `throw' and `signal', but it seems
;; preferable to wait until there's a concrete need.
(gv-define-expander error (lambda (_do &rest args) `(error . ,args)))
;; Some Emacs-related place types.
(gv-define-simple-setter buffer-file-name set-visited-file-name t)
(make-obsolete-generalized-variable

View file

@ -597,66 +597,73 @@ instead of just updating them with the new/changed autoloads."
defs))))))
(progress-reporter-done progress))
;; First group per output file.
(dolist (fdefs (seq-group-by (lambda (x) (expand-file-name (car x)))
defs))
(let ((loaddefs-file (car fdefs))
hash)
;; If we have no autoloads data, but we have EXTRA-DATA, then
;; generate the (almost) empty file anyway.
(if (and (not defs) extra-data)
(with-temp-buffer
(if (and updating (file-exists-p loaddefs-file))
(insert-file-contents loaddefs-file)
(insert (loaddefs-generate--rubric
loaddefs-file nil t include-package-version))
(search-backward "\f")
(when extra-data
(insert extra-data)
(ensure-empty-lines 1)))
(setq hash (buffer-hash))
;; Then group by source file (and sort alphabetically).
(dolist (section (sort (seq-group-by #'cadr (cdr fdefs))
(lambda (e1 e2)
(string<
(file-name-sans-extension
(file-name-nondirectory (car e1)))
(file-name-sans-extension
(file-name-nondirectory (car e2)))))))
(pop section)
(let* ((relfile (file-relative-name
(cadar section)
(file-name-directory loaddefs-file)))
(head (concat "\n\f\n;;; Generated autoloads from "
relfile "\n\n")))
(when (file-exists-p loaddefs-file)
;; If we're updating an old loaddefs file, then see if
;; there's a section here for this file already.
(goto-char (point-min))
(if (not (search-forward head nil t))
;; It's a new file; put the data at the end.
(progn
(goto-char (point-max))
(search-backward "\f\n" nil t))
;; Delete the old version of the section. Strictly
;; speaking this should search for "\n\f\n;;;", but
;; there are loaddefs files in the wild that only
;; have two ';;'. (Bug#63236)
(delete-region (match-beginning 0)
(and (search-forward "\n\f\n;;")
(match-beginning 0)))
(forward-line -2)))
(insert head)
(dolist (def (reverse section))
(setq def (caddr def))
(if (stringp def)
(princ def (current-buffer))
(loaddefs-generate--print-form def))
(unless (bolp)
(insert "\n")))))
;; Only write the file if we actually made a change.
(unless (equal (buffer-hash) hash)
(write-region (point-min) (point-max) loaddefs-file nil 'silent)
(byte-compile-info
(file-relative-name loaddefs-file (car (ensure-list dir)))
t "GEN")))))))
(insert (loaddefs-generate--rubric output-file nil t))
(search-backward "\f")
(insert extra-data)
(ensure-empty-lines 1)
(write-region (point-min) (point-max) output-file nil 'silent))
;; We have some data, so generate the loaddef files. First
;; group per output file.
(dolist (fdefs (seq-group-by (lambda (x) (expand-file-name (car x)))
defs))
(let ((loaddefs-file (car fdefs))
hash)
(with-temp-buffer
(if (and updating (file-exists-p loaddefs-file))
(insert-file-contents loaddefs-file)
(insert (loaddefs-generate--rubric
loaddefs-file nil t include-package-version))
(search-backward "\f")
(when extra-data
(insert extra-data)
(ensure-empty-lines 1)))
(setq hash (buffer-hash))
;; Then group by source file (and sort alphabetically).
(dolist (section (sort (seq-group-by #'cadr (cdr fdefs))
(lambda (e1 e2)
(string<
(file-name-sans-extension
(file-name-nondirectory (car e1)))
(file-name-sans-extension
(file-name-nondirectory (car e2)))))))
(pop section)
(let* ((relfile (file-relative-name
(cadar section)
(file-name-directory loaddefs-file)))
(head (concat "\n\f\n;;; Generated autoloads from "
relfile "\n\n")))
(when (file-exists-p loaddefs-file)
;; If we're updating an old loaddefs file, then see if
;; there's a section here for this file already.
(goto-char (point-min))
(if (not (search-forward head nil t))
;; It's a new file; put the data at the end.
(progn
(goto-char (point-max))
(search-backward "\f\n" nil t))
;; Delete the old version of the section.
(delete-region (match-beginning 0)
(and (search-forward "\n\f\n;;;")
(match-beginning 0)))
(forward-line -2)))
(insert head)
(dolist (def (reverse section))
(setq def (caddr def))
(if (stringp def)
(princ def (current-buffer))
(loaddefs-generate--print-form def))
(unless (bolp)
(insert "\n")))))
;; Only write the file if we actually made a change.
(unless (equal (buffer-hash) hash)
(write-region (point-min) (point-max) loaddefs-file nil 'silent)
(byte-compile-info
(file-relative-name loaddefs-file (car (ensure-list dir)))
t "GEN"))))))))
(defun loaddefs-generate--print-form (def)
"Print DEF in a format that makes sense for version control."

View file

@ -24,7 +24,7 @@
;; While packages managed by package.el use tarballs for distributing
;; the source code, this extension allows for packages to be fetched
;; and upgraded directly from a version control system.
;; and updated directly from a version control system.
;;
;; To install a package from source use `package-vc-install'. If you
;; aren't interested in activating a package, you can use
@ -147,9 +147,32 @@ is a symbol designating the package and SPEC is one of:
- nil, if any package version can be installed;
- a version string, if that specific revision is to be installed;
- a property list, describing a package specification. For more
details, please consult the subsection \"Specifying Package
Sources\" in the Info node `(emacs)Fetching Package Sources'.
- a property list, describing a package specification. Valid
key/value pairs are
`:url' (string)
The URL of the repository used to fetch the package source.
`:branch' (string)
If given, the name of the branch to checkout after cloning the directory.
`:lisp-dir' (string)
The repository-relative name of the directory to use for loading the Lisp
sources. If not given, the value defaults to the root directory
of the repository.
`:main-file' (string)
The main file of the project, relevant to gather package metadata.
If not given, the assumed default is the package name with \".el\"
appended to it.
`:vc-backend' (symbol)
A symbol of the VC backend to use for cloning the package. The
value ought to be a member of `vc-handled-backends'. If omitted,
`vc-clone' will fall back onto the archive default or on
`package-vc-default-backend'.
All other keys are ignored.
This user option will be automatically updated to store package
specifications for packages that are not specified in any
@ -163,11 +186,10 @@ archive."
(:branch string)
(:lisp-dir string)
(:main-file string)
(:doc string)
(:vc-backend symbol)))))
:version "29.1")
(defvar package-vc--archive-spec-alists nil
(defvar package-vc--archive-spec-alist nil
"List of package specifications for each archive.
The list maps each package name, as a string, to a plist as
specified in `package-vc-selected-packages'.")
@ -199,15 +221,15 @@ name for PKG-DESC."
(not (alist-get name package-vc-selected-packages
nil nil #'string=)))
(alist-get (intern (package-desc-archive pkg-desc))
package-vc--archive-spec-alists)
package-vc--archive-spec-alist)
;; Consult both our local list of package specifications, as well
;; as the lists provided by the archives.
(apply #'append (cons package-vc-selected-packages
(mapcar #'cdr package-vc--archive-spec-alists))))
(mapcar #'cdr package-vc--archive-spec-alist))))
'() nil #'string=))
(defun package-vc--read-archive-data (archive)
"Update `package-vc--archive-spec-alists' for ARCHIVE.
"Update `package-vc--archive-spec-alist' for ARCHIVE.
This function is meant to be used as a hook for `package-read-archive-hook'."
(let ((contents-file (expand-file-name
(format "archives/%s/elpa-packages.eld" archive)
@ -224,7 +246,7 @@ This function is meant to be used as a hook for `package-read-archive-hook'."
(let ((spec (read (current-buffer))))
(when (eq package-vc--elpa-packages-version
(plist-get (cdr spec) :version))
(setf (alist-get (intern archive) package-vc--archive-spec-alists)
(setf (alist-get (intern archive) package-vc--archive-spec-alist)
(car spec)))
(setf (alist-get (intern archive) package-vc--archive-data-alist)
(cdr spec))
@ -235,7 +257,7 @@ This function is meant to be used as a hook for `package-read-archive-hook'."
(defun package-vc--download-and-read-archives (&optional async)
"Download specifications of all `package-archives' and read them.
Populate `package-vc--archive-spec-alists' with the result.
Populate `package-vc--archive-spec-alist' with the result.
If optional argument ASYNC is non-nil, perform the downloads
asynchronously."
@ -583,7 +605,7 @@ Emacs Lisp files.")
(defun package-vc--unpack (pkg-desc pkg-spec &optional rev)
"Install the package described by PKG-DESC.
PKG-SPEC is a package specification, a property list describing
how to fetch and build the package. See `package-vc--archive-spec-alists'
how to fetch and build the package. See `package-vc--archive-spec-alist'
for details. The optional argument REV specifies a specific revision to
checkout. This overrides the `:branch' attribute in PKG-SPEC."
(unless (eq (package-desc-kind pkg-desc) 'vc)
@ -632,8 +654,7 @@ abort installation?" name))
(throw 'done (setq lisp-dir name)))))
;; Ensure we have a copy of the package specification
(unless (seq-some (lambda (alist) (equal (alist-get name (cdr alist)) pkg-spec))
package-vc--archive-spec-alists)
(unless (equal (alist-get name (mapcar #'cdr package-vc--archive-spec-alist)) pkg-spec)
(customize-save-variable
'package-vc-selected-packages
(cons (cons name pkg-spec)
@ -673,19 +694,19 @@ installed package."
#'string=)))
;;;###autoload
(defun package-vc-upgrade-all ()
"Attempt to upgrade all installed VC packages."
(defun package-vc-update-all ()
"Attempt to update all installed VC packages."
(interactive)
(dolist (package package-alist)
(dolist (pkg-desc (cdr package))
(when (package-vc-p pkg-desc)
(package-vc-upgrade pkg-desc))))
(message "Done upgrading packages."))
(package-vc-update pkg-desc))))
(message "Done updating packages."))
;;;###autoload
(defun package-vc-upgrade (pkg-desc)
"Attempt to upgrade the package PKG-DESC."
(interactive (list (package-vc--read-package-desc "Upgrade VC package: " t)))
(defun package-vc-update (pkg-desc)
"Attempt to update the package PKG-DESC."
(interactive (list (package-vc--read-package-desc "Update VC package: " t)))
;; HACK: To run `package-vc--unpack-1' after checking out the new
;; revision, we insert a hook into `vc-post-command-functions', and
;; remove it right after it ran. To avoid running the hook multiple
@ -883,7 +904,7 @@ Rebuilding an installation means scraping for new autoload
cookies, re-compiling Emacs Lisp files, building and installing
any documentation, downloading any missing dependencies. This
command does not fetch new revisions from a remote server. That
is the responsibility of `package-vc-upgrade'. Interactively,
is the responsibility of `package-vc-update'. Interactively,
prompt for the name of the package to rebuild."
(interactive (list (package-vc--read-package-desc "Rebuild package: " t)))
(package-vc--unpack-1 pkg-desc (package-desc-dir pkg-desc)))

View file

@ -795,21 +795,6 @@ specifying the minimum acceptable version."
(require 'finder-inf nil t) ; For `package--builtins'.
(assq package package--builtins))))))
(defun package--active-built-in-p (package)
"Return non-nil if the built-in version of PACKAGE is used.
If the built-in version of PACKAGE is used and PACKAGE is
also available for installation from an archive, it is an
indication that PACKAGE was never upgraded to any newer
version from the archive."
(and (not (assq (cond
((package-desc-p package)
(package-desc-name package))
((stringp package) (intern package))
((symbolp package) package)
((error "Unknown package format: %S" package)))
(package--alist)))
(package-built-in-p package)))
(defun package--autoloads-file-name (pkg-desc)
"Return the absolute name of the autoloads file, sans extension.
PKG-DESC is a `package-desc' object."
@ -1196,7 +1181,7 @@ boundaries."
;; the earliest in version 31.1. The idea is to phase out the
;; requirement for a "footer line" without unduly impacting users
;; on earlier Emacs versions. See Bug#26490 for more details.
(unless (search-forward (concat ";;; " file-name ".el ends here") nil t)
(unless (search-forward (concat ";;; " file-name ".el ends here"))
(lwarn '(package package-format) :warning
"Package lacks a terminating comment"))
;; Try to include a trailing newline.
@ -1224,8 +1209,8 @@ boundaries."
:url website
:keywords keywords
:maintainer
;; For backward compatibility, use a single cons-cell if
;; there's only one maintainer (the most common case).
;; For backward compatibility, use a single string if there's only
;; one maintainer (the most common case).
(let ((maints (lm-maintainers))) (if (cdr maints) maints (car maints)))
:authors (lm-authors)))))
@ -2193,18 +2178,12 @@ using `package-compute-transaction'."
(unless package-archive-contents
(package-refresh-contents)))
(defcustom package-install-upgrade-built-in nil
"Non-nil means that built-in packages can be upgraded via a package archive.
If disabled, then `package-install' will not suggest to replace a
built-in package with a (possibly newer) version from a package archive."
:type 'boolean
:version "29.1")
;;;###autoload
(defun package-install (pkg &optional dont-select)
"Install the package PKG.
PKG can be a `package-desc' or a symbol naming one of the
available packages in an archive in `package-archives'.
available packages in an archive in `package-archives'. When
called interactively, prompt for the package name.
Mark the installed package as selected by adding it to
`package-selected-packages'.
@ -2214,11 +2193,7 @@ non-nil, install the package but do not add it to
`package-selected-packages'.
If PKG is a `package-desc' and it is already installed, don't try
to install it but still mark it as selected.
If the command is invoked with a prefix argument, it will allow
upgrading of built-in packages, as if `package-install-upgrade-built-in'
had been enabled."
to install it but still mark it as selected."
(interactive
(progn
;; Initialize the package system to get the list of package
@ -2226,14 +2201,11 @@ had been enabled."
(package--archives-initialize)
(list (intern (completing-read
"Install package: "
(mapcan
(lambda (elt)
(and (or (and (or current-prefix-arg
package-install-upgrade-built-in)
(package--active-built-in-p (car elt)))
(not (package-installed-p (car elt))))
(list (symbol-name (car elt)))))
package-archive-contents)
(delq nil
(mapcar (lambda (elt)
(unless (package-installed-p (car elt))
(symbol-name (car elt))))
package-archive-contents))
nil t))
nil)))
(package--archives-initialize)
@ -2244,9 +2216,6 @@ had been enabled."
(unless (or dont-select (package--user-selected-p name))
(package--save-selected-packages
(cons name package-selected-packages)))
(when (and (or current-prefix-arg package-install-upgrade-built-in)
(package--active-built-in-p pkg))
(setq pkg (or (cadr (assq name package-archive-contents)) pkg)))
(if-let* ((transaction
(if (package-desc-p pkg)
(unless (package-installed-p pkg)
@ -2259,30 +2228,24 @@ had been enabled."
(message "Package `%s' installed." name))
(message "`%s' is already installed" name))))
(declare-function package-vc-upgrade "package-vc" (pkg))
(declare-function package-vc-update "package-vc" (pkg))
;;;###autoload
(defun package-upgrade (name)
"Upgrade package NAME if a newer version exists."
(defun package-update (name)
"Update package NAME if a newer version exists."
(interactive
(list (completing-read
"Upgrade package: " (package--upgradeable-packages t) nil t)))
"Update package: " (package--updateable-packages) nil t)))
(let* ((package (if (symbolp name)
name
(intern name)))
(pkg-desc (cadr (assq package package-alist)))
(package-install-upgrade-built-in (not pkg-desc)))
;; `pkg-desc' will be nil when the package is an "active built-in".
(if (and pkg-desc (package-vc-p pkg-desc))
(package-vc-upgrade pkg-desc)
(when pkg-desc
(package-delete pkg-desc 'force 'dont-unselect))
(package-install package
;; An active built-in has never been "selected"
;; before. Mark it as installed explicitly.
(and pkg-desc 'dont-select)))))
(pkg-desc (cadr (assq package package-alist))))
(if (package-vc-p pkg-desc)
(package-vc-update pkg-desc)
(package-delete pkg-desc 'force)
(package-install package 'dont-select))))
(defun package--upgradeable-packages (&optional include-builtins)
(defun package--updateable-packages ()
;; Initialize the package system to get the list of package
;; symbols for completion.
(package--archives-initialize)
@ -2293,46 +2256,30 @@ had been enabled."
(or (let ((available
(assq (car elt) package-archive-contents)))
(and available
(or (and
include-builtins
(not (package-desc-version (cadr elt))))
(version-list-<
(package-desc-version (cadr elt))
(package-desc-version (cadr available))))))
(package-vc-p (cadr elt))))
(if include-builtins
(append package-alist
(mapcan
(lambda (elt)
(when (not (assq (car elt) package-alist))
(list (list (car elt) (package--from-builtin elt)))))
package--builtins))
package-alist))))
(version-list-<
(package-desc-version (cadr elt))
(package-desc-version (cadr available)))))
(package-vc-p (cadr (assq (car elt) package-alist)))))
package-alist)))
;;;###autoload
(defun package-upgrade-all (&optional query)
(defun package-update-all (&optional query)
"Refresh package list and upgrade all packages.
If QUERY, ask the user before upgrading packages. When called
interactively, QUERY is always true.
Currently, packages which are part of the Emacs distribution are
not upgraded by this command. To enable upgrading such a package
using this command, first upgrade the package to a newer version
from ELPA by either using `\\[package-upgrade]' or
`\\<package-menu-mode-map>\\[package-menu-mark-install]' after `\\[list-packages]'."
If QUERY, ask the user before updating packages. When called
interactively, QUERY is always true."
(interactive (list (not noninteractive)))
(package-refresh-contents)
(let ((upgradeable (package--upgradeable-packages)))
(if (not upgradeable)
(message "No packages to upgrade")
(let ((updateable (package--updateable-packages)))
(if (not updateable)
(message "No packages to update")
(when (and query
(not (yes-or-no-p
(if (length= upgradeable 1)
"One package to upgrade. Do it? "
(format "%s packages to upgrade. Do it?"
(length upgradeable))))))
(user-error "Upgrade aborted"))
(mapc #'package-upgrade upgradeable))))
(if (length= updateable 1)
"One package to update. Do it? "
(format "%s packages to update. Do it?"
(length updateable))))))
(user-error "Updating aborted"))
(mapc #'package-update updateable))))
(defun package--dependencies (pkg)
"Return a list of all dependencies PKG has.
@ -2745,8 +2692,7 @@ Helper function for `describe-package'."
(status (if desc (package-desc-status desc) "orphan"))
(incompatible-reason (package--incompatible-p desc))
(signed (if desc (package-desc-signed desc)))
(maintainers (or (cdr (assoc :maintainers extras))
(cdr (assoc :maintainer extras))))
(maintainer (cdr (assoc :maintainer extras)))
(authors (cdr (assoc :authors extras)))
(news (and-let* (pkg-dir
((not built-in))
@ -2881,21 +2827,19 @@ Helper function for `describe-package'."
'action 'package-keyword-button-action)
(insert " "))
(insert "\n"))
(when maintainers
(unless (proper-list-p maintainers)
(setq maintainers (list maintainers)))
(package--print-help-section
(if (cdr maintainers) "Maintainers" "Maintainer"))
(dolist (maintainer maintainers)
(when (bolp)
(insert (make-string 13 ?\s)))
(package--print-email-button maintainer)))
(when maintainer
(package--print-help-section "Maintainer")
(package--print-email-button maintainer))
(when authors
(package--print-help-section (if (cdr authors) "Authors" "Author"))
(dolist (author authors)
(when (bolp)
(insert (make-string 13 ?\s)))
(package--print-email-button author)))
(package--print-help-section
(if (= (length authors) 1)
"Author"
"Authors"))
(package--print-email-button (pop authors))
;; If there's more than one author, indent the rest correctly.
(dolist (name authors)
(insert (make-string 13 ?\s))
(package--print-email-button name)))
(let* ((all-pkgs (append (cdr (assq name package-alist))
(cdr (assq name package-archive-contents))
(let ((bi (assq name package--builtins)))

View file

@ -294,8 +294,7 @@
"\\|"
"bash$\\|bash.exe$"
"\\)")
shell-file-name)
t))
shell-file-name)))
"Is the user using a unix-type shell under a non-OS?"
:type 'boolean)

View file

@ -47,8 +47,7 @@
(defun viper-window-display-p ()
(and window-system (not (memq window-system '(tty stream pc)))))
(defcustom viper-ms-style-os-p
(not (not (memq system-type '(ms-dos windows-nt))))
(defcustom viper-ms-style-os-p (memq system-type '(ms-dos windows-nt))
"Non-nil if Emacs is running under an MS-style OS: MS-DOS, or MS-Windows."
:type 'boolean
:tag "Is it Microsoft-made OS?"

View file

@ -102,12 +102,11 @@
(require 'erc-common)
(defvar erc--target)
(defvar erc--user-from-nick-function)
(defvar erc-auto-query)
(defvar erc-channel-list)
(defvar erc-channel-users)
(defvar erc-default-nicks)
(defvar erc-default-recipients)
(defvar erc-ensure-target-buffer-on-privmsg)
(defvar erc-format-nick-function)
(defvar erc-format-query-as-channel-p)
(defvar erc-hide-prompt)
@ -124,8 +123,6 @@
(defvar erc-nick-change-attempt-count)
(defvar erc-prompt-for-channel-key)
(defvar erc-prompt-hidden)
(defvar erc-receive-query-display)
(defvar erc-receive-query-display-defer)
(defvar erc-reuse-buffers)
(defvar erc-verbose-server-ping)
(defvar erc-whowas-on-nosuchnick)
@ -300,12 +297,6 @@ function `erc-server-process-alive' instead.")
(defvar-local erc-server-reconnect-count 0
"Number of times we have failed to reconnect to the current server.")
(defvar-local erc--server-reconnect-display-timer nil
"Timer that resets `erc--server-last-reconnect-count' to zero.
Becomes non-nil in all server buffers when an IRC connection is
first \"established\" and carries out its duties
`erc-reconnect-display-timeout' seconds later.")
(defvar-local erc--server-last-reconnect-count 0
"Snapshot of reconnect count when the connection was established.")
@ -424,12 +415,8 @@ This only has an effect if `erc-server-auto-reconnect' is non-nil."
(defcustom erc-server-reconnect-timeout 1
"Number of seconds to wait between successive reconnect attempts.
If this value is too low, servers may reject your initial nick
request upon reconnecting because they haven't yet noticed that
your previous connection is dead. If this happens, try setting
this value to 120 or greater and/or exploring the option
`erc-nickname-in-use-functions', which may provide a more
proactive means of handling this situation on some servers."
If a key is pressed while ERC is waiting, it will stop waiting."
:type 'number)
(defcustom erc-server-reconnect-function 'erc-server-delayed-reconnect
@ -440,7 +427,6 @@ dialing. Use `erc-schedule-reconnect' to instead try again later
and optionally alter the attempts tally."
:package-version '(ERC . "5.5")
:type '(choice (function-item erc-server-delayed-reconnect)
(function-item erc-server-delayed-check-reconnect)
function))
(defcustom erc-split-line-length 440
@ -573,47 +559,6 @@ If this is set to nil, never try to reconnect."
;;;; Helper functions
(defvar erc--reject-unbreakable-lines nil
"Signal an error when a line exceeds `erc-split-line-length'.
Sending such lines and hoping for the best is no longer supported
in ERC 5.6. This internal var exists as a possibly temporary
escape hatch for inhibiting their transmission.")
(defun erc--split-line (longline)
(let* ((coding (erc-coding-system-for-target nil))
(original-window-buf (window-buffer (selected-window)))
out)
(when (consp coding)
(setq coding (car coding)))
(setq coding (coding-system-change-eol-conversion coding 'unix))
(unwind-protect
(with-temp-buffer
(set-window-buffer (selected-window) (current-buffer))
(insert longline)
(goto-char (point-min))
(while (not (eobp))
(let ((upper (filepos-to-bufferpos erc-split-line-length
'exact coding)))
(goto-char (or upper (point-max)))
(unless (eobp)
(skip-chars-backward "^ \t"))
(when (bobp)
(when erc--reject-unbreakable-lines
(user-error
(substitute-command-keys
(concat "Unbreakable line encountered "
"(Recover input with \\[erc-previous-command])"))))
(goto-char upper))
(when-let ((cmp (find-composition (point) (1+ (point)))))
(if (= (car cmp) (point-min))
(goto-char (nth 1 cmp))
(goto-char (car cmp)))))
(cl-assert (/= (point-min) (point)))
(push (buffer-substring-no-properties (point-min) (point)) out)
(delete-region (point-min) (point)))
(or (nreverse out) (list "")))
(set-window-buffer (selected-window) original-window-buf))))
;; From Circe
(defun erc-split-line (longline)
"Return a list of lines which are not too long for IRC.
@ -713,30 +658,6 @@ The current buffer is given by BUFFER."
(run-hooks 'erc--server-post-connect-hook)
(erc-login))
(defvar erc--server-connect-function #'erc--server-propagate-failed-connection
"Function called one second after creating a server process.
Called with the newly created process just before the opening IRC
protocol exchange.")
(defun erc--server-propagate-failed-connection (process)
"Ensure the PROCESS sentinel runs at least once on early failure.
Act as a watchdog timer to force `erc-process-sentinel' and its
finalizers, like `erc-disconnected-hook', to run when PROCESS has
a status of `failed' after one second. But only do so when its
error data is something ERC recognizes. Print an explanation to
the server buffer in any case."
(when (eq (process-status process) 'failed)
(erc-display-message
nil 'error (process-buffer process)
(format "Process exit status: %S" (process-exit-status process)))
(pcase (process-exit-status process)
(111
(erc-process-sentinel process "failed with code 111\n"))
(`(file-error . ,_)
(erc-process-sentinel process "failed with code -523\n"))
((rx "tls" (+ nonl) "failed")
(erc-process-sentinel process "failed with code -525\n")))))
(defvar erc--server-connect-dumb-ipv6-regexp
;; Not for validation (gives false positives).
(rx bot "[" (group (+ (any xdigit digit ":.")) (? "%" (+ alnum))) "]" eot))
@ -789,9 +710,7 @@ TLS (see `erc-session-client-certificate' for more details)."
;; MOTD line)
(if (eq (process-status process) 'connect)
;; waiting for a non-blocking connect - keep the user informed
(progn
(erc-display-message nil nil buffer "Opening connection..\n")
(run-at-time 1 nil erc--server-connect-function process))
(erc-display-message nil nil buffer "Opening connection..\n")
(message "%s...done" msg)
(erc--register-connection))))
@ -825,78 +744,6 @@ Make sure you are in an ERC buffer when running this."
(with-current-buffer buffer
(erc-server-reconnect))))
(defvar-local erc--server-reconnect-timeout nil)
(defvar-local erc--server-reconnect-timeout-check 10)
(defvar-local erc--server-reconnect-timeout-scale-function
#'erc--server-reconnect-timeout-double)
(defun erc--server-reconnect-timeout-double (existing)
"Double EXISTING timeout, but cap it at 5 minutes."
(min 300 (* existing 2)))
;; This may appear to hang at various places. It's assumed that when
;; *Messages* contains "Waiting for socket ..." or similar, progress
;; will be made eventually.
(defun erc-server-delayed-check-reconnect (buffer)
"Wait for internet connectivity before trying to reconnect.
Expect BUFFER to be the server buffer for the current connection."
(when (buffer-live-p buffer)
(with-current-buffer buffer
(setq erc--server-reconnect-timeout
(funcall erc--server-reconnect-timeout-scale-function
(or erc--server-reconnect-timeout
erc-server-reconnect-timeout)))
(let* ((reschedule (lambda (proc)
(when (buffer-live-p buffer)
(with-current-buffer buffer
(let ((erc-server-reconnect-timeout
erc--server-reconnect-timeout))
(delete-process proc)
(erc-display-message nil 'error buffer
"Nobody home...")
(erc-schedule-reconnect buffer 0))))))
(conchk-exp (time-add erc--server-reconnect-timeout-check
(current-time)))
(conchk-timer nil)
(conchk (lambda (proc)
(let ((status (process-status proc))
(xprdp (time-less-p conchk-exp (current-time))))
(when (or (not (eq 'connect status)) xprdp)
(cancel-timer conchk-timer))
(when (buffer-live-p buffer)
(cond (xprdp (erc-display-message
nil 'error buffer
"Timed out while dialing...")
(delete-process proc)
(funcall reschedule proc))
((eq 'failed status)
(funcall reschedule proc)))))))
(sentinel (lambda (proc event)
(pcase event
("open\n"
(run-at-time nil nil #'send-string proc
(format "PING %d\r\n"
(time-convert nil 'integer))))
((or "connection broken by remote peer\n"
(rx bot "failed"))
(funcall reschedule proc)))))
(filter (lambda (proc _)
(delete-process proc)
(with-current-buffer buffer
(setq erc--server-reconnect-timeout nil))
(run-at-time nil nil #'erc-server-delayed-reconnect
buffer))))
(condition-case _
(let ((proc (funcall erc-session-connector
"*erc-connectivity-check*" nil
erc-session-server erc-session-port
:nowait t)))
(setq conchk-timer (run-at-time 1 1 conchk proc))
(set-process-filter proc filter)
(set-process-sentinel proc sentinel))
(file-error (funcall reschedule nil)))))))
(defun erc-server-filter-function (process string)
"The process filter for the ERC server."
(with-current-buffer (process-buffer process)
@ -951,22 +798,6 @@ EVENT is the message received from the closed connection process."
erc-server-reconnecting)
(erc--server-reconnect-p event)))
(defun erc--server-last-reconnect-on-disconnect (&rest _)
(remove-hook 'erc-disconnected-hook
#'erc--server-last-reconnect-on-disconnect t)
(erc--server-last-reconnect-display-reset (current-buffer)))
(defun erc--server-last-reconnect-display-reset (buffer)
"Deactivate `erc-reconnect-display'."
(when (buffer-live-p buffer)
(with-current-buffer buffer
(when erc--server-reconnect-display-timer
(cancel-timer erc--server-reconnect-display-timer)
(remove-hook 'erc-disconnected-hook
#'erc--server-last-reconnect-display-reset t)
(setq erc--server-reconnect-display-timer nil
erc--server-last-reconnect-count 0)))))
(defconst erc--mode-line-process-reconnecting
'(:eval (erc-with-server-buffer
(and erc--server-reconnect-timer
@ -992,16 +823,11 @@ When `erc-server-reconnect-attempts' is a number, increment
`erc-server-reconnect-count' by INCR unconditionally."
(let ((count (and (integerp erc-server-reconnect-attempts)
(- erc-server-reconnect-attempts
(cl-incf erc-server-reconnect-count (or incr 1)))))
(proc (buffer-local-value 'erc-server-process buffer)))
(erc-display-message nil 'error buffer 'reconnecting
(cl-incf erc-server-reconnect-count (or incr 1))))))
(erc-display-message nil 'error (current-buffer) 'reconnecting
?m erc-server-reconnect-timeout
?i (if count erc-server-reconnect-count "N")
?n (if count erc-server-reconnect-attempts "A"))
(set-process-sentinel proc #'ignore)
(set-process-filter proc nil)
(delete-process proc)
(erc-update-mode-line)
(setq erc-server-reconnecting nil
erc--server-reconnect-timer
(run-at-time erc-server-reconnect-timeout nil
@ -1501,6 +1327,8 @@ Finds hooks by looking in the `erc-server-responses' hash table."
(erc-with-server-buffer
(run-hook-with-args 'erc-timer-hook (erc-current-time)))))
(add-hook 'erc-default-server-functions #'erc-handle-unknown-server-response)
(defun erc-handle-unknown-server-response (proc parsed)
"Display unknown server response's message."
(let ((line (concat (erc-response.sender parsed)
@ -1895,16 +1723,11 @@ add things to `%s' instead."
(unless (or buffer noticep (string-empty-p tgt) (eq ?$ (aref tgt 0))
(erc-is-message-ctcp-and-not-action-p msg))
(if privp
(when-let ((erc-join-buffer
(or (and (not erc-receive-query-display-defer)
erc-receive-query-display)
(and erc-ensure-target-buffer-on-privmsg
(or erc-receive-query-display
erc-join-buffer)))))
(setq buffer (erc--open-target nick)))
;; A channel buffer has been killed but is still joined.
(when erc-ensure-target-buffer-on-privmsg
(setq buffer (erc--open-target tgt)))))
(when erc-auto-query
(let ((erc-join-buffer erc-auto-query))
(setq buffer (erc--open-target nick))))
;; A channel buffer has been killed but is still joined
(setq buffer (erc--open-target tgt))))
(when buffer
(with-current-buffer buffer
(when privp (erc--unhide-prompt))
@ -1913,8 +1736,7 @@ add things to `%s' instead."
;; at this point.
(erc-update-channel-member (if privp nick tgt) nick nick
privp nil nil nil nil nil host login nil nil t)
(let ((cdata (funcall erc--user-from-nick-function
(erc-downcase nick) sndr parsed)))
(let ((cdata (erc-get-channel-user nick)))
(setq fnick (funcall erc-format-nick-function
(car cdata) (cdr cdata))))))
(cond
@ -2054,7 +1876,7 @@ ambiguous and only useful for tokens supporting a single
primitive value."
(if-let* ((table (or erc--isupport-params
(erc-with-server-buffer erc--isupport-params)))
(value (with-memoization (gethash key table)
(value (erc-compat--with-memoization (gethash key table)
(when-let ((v (assoc (symbol-name key)
erc-server-parameters)))
(if (cdr v)
@ -2414,11 +2236,6 @@ See `erc-display-server-message'." nil
(erc-display-message parsed '(notice error) 'active
's401 ?n nick/channel)))
(define-erc-response-handler (402)
"No such server." nil
(erc-display-message parsed '(notice error) 'active
's402 ?c (cadr (erc-response.command-args parsed))))
(define-erc-response-handler (403)
"No such channel." nil
(erc-display-message parsed '(notice error) 'active
@ -2566,7 +2383,7 @@ See `erc-display-error-notice'." nil
;; (define-erc-response-handler (323 364 365 381 382 392 393 394 395
;; 200 201 202 203 204 205 206 208 209 211 212 213
;; 214 215 216 217 218 219 241 242 243 244 249 261
;; 262 302 342 351 407 409 411 413 414 415
;; 262 302 342 351 402 407 409 411 413 414 415
;; 423 424 436 441 443 444 467 471 472 473 KILL)
;; nil nil
;; (ignore proc parsed))

View file

@ -52,15 +52,14 @@
;;;###autoload(autoload 'erc-button-mode "erc-button" nil t)
(define-erc-module button nil
"This mode buttonizes all messages according to `erc-button-alist'."
((erc-button--check-nicknames-entry)
(add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append)
((add-hook 'erc-insert-modify-hook #'erc-button-add-buttons 'append)
(add-hook 'erc-send-modify-hook #'erc-button-add-buttons 'append)
(add-hook 'erc--tab-functions #'erc-button-next)
(erc--modify-local-map t "<backtab>" #'erc-button-previous))
(add-hook 'erc-complete-functions #'erc-button-next-function)
(add-hook 'erc-mode-hook #'erc-button-setup))
((remove-hook 'erc-insert-modify-hook #'erc-button-add-buttons)
(remove-hook 'erc-send-modify-hook #'erc-button-add-buttons)
(remove-hook 'erc--tab-functions #'erc-button-next)
(erc--modify-local-map nil "<backtab>" #'erc-button-previous)))
(remove-hook 'erc-complete-functions #'erc-button-next-function)
(remove-hook 'erc-mode-hook #'erc-button-setup)))
;;; Variables
@ -128,12 +127,13 @@ longer than `erc-fill-column'."
;; things hard to maintain.
'((nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0)
(erc-button-url-regexp 0 t browse-url-button-open-url 0)
("<URL: *\\([^<> ]+\\) *>" 0 t browse-url-button-open-url 1)
;;; ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3)
;; emacs internal
("[`]\\([a-zA-Z][-a-zA-Z_0-9!*<=>+]+\\)[']"
1 t erc-button-describe-symbol 1)
;; pseudo links
("\\(?:\\bInfo: ?\\|(info \\)[\"]\\(([^\"]+\\)[\"])?" 0 t info 1)
("\\bInfo:[\"]\\([^\"]+\\)[\"]" 0 t Info-goto-node 1)
("\\b\\(Ward\\|Wiki\\|WardsWiki\\|TheWiki\\):\\([A-Z][a-z]+\\([A-Z][a-z]+\\)+\\)"
0 t (lambda (page)
(browse-url (concat "http://c2.com/cgi-bin/wiki?" page)))
@ -165,14 +165,8 @@ REGEXP is the string matching text around the button or a symbol
BUTTON is the number of the regexp grouping actually matching the
button. This is ignored if REGEXP is `nicknames'.
FORM is either a boolean or a special variable whose value must
be non-nil for the button to be added. When REGEXP is the
special symbol `nicknames', FORM must be the symbol
`erc-button-buttonize-nicks'. Anything else is deprecated.
For all other entries, FORM can also be a function to call in
place of `erc-button-add-button' with the exact same arguments.
When FORM is also a special variable, ERC disregards the
variable and calls the function.
FORM is a Lisp expression which must eval to true for the button to
be added.
CALLBACK is the function to call when the user push this button.
CALLBACK can also be a symbol. Its variable value will be used
@ -182,7 +176,7 @@ PAR is a number of a regexp grouping whose text will be passed to
CALLBACK. There can be several PAR arguments. If REGEXP is
`nicknames', these are ignored, and CALLBACK will be called with
the nickname matched as the argument."
:package-version '(ERC . "5.6") ; FIXME sync on release
:package-version '(ERC . "5.5")
:type '(repeat
(list :tag "Button"
(choice :tag "Matches"
@ -239,8 +233,6 @@ constituents.")
"Internal variable used to keep track of whether we've added the
global-level ERC button keys yet.")
;; Maybe deprecate this function and `erc-button-keys-added' if they
;; continue to go unused for a another version (currently 5.6).
(defun erc-button-setup ()
"Add ERC mode-level button movement keys. This is only done once."
;; Add keys.
@ -283,186 +275,35 @@ specified by `erc-button-alist'."
(concat "\\<" (regexp-quote (car elem)) "\\>")
entry)))))))))))
(defun erc-button--maybe-warn-arbitrary-sexp (form)
(cl-assert (not (booleanp form))) ; covered by caller
;; If a special-variable is also a function, favor the function.
(cond ((functionp form) form)
((and (symbolp form) (special-variable-p form)) (symbol-value form))
(t (unless (get 'erc-button--maybe-warn-arbitrary-sexp
'warned-arbitrary-sexp)
(put 'erc-button--maybe-warn-arbitrary-sexp
'warned-arbitrary-sexp t)
(lwarn 'erc :warning (concat "Arbitrary sexps for the third FORM"
" slot of `erc-button-alist' entries"
" have been deprecated.")))
(eval form t))))
(defun erc-button--check-nicknames-entry ()
;; This helper exists because the module is defined after its options.
(when (eq major-mode 'erc-mode)
(unless (eq (nth 1 (alist-get 'nicknames erc-button-alist))
'erc-button-buttonize-nicks)
(erc-button--display-error-notice-with-keys-and-warn
"Values other than `erc-button-buttonize-nicks' in the third slot of "
"the `nicknames' entry of `erc-button-alist' are deprecated."))))
(cl-defstruct erc-button--nick
( bounds nil :type cons
;; Indicates the nick's position in the current message. BEG is
;; normally also point.
:documentation "A cons of (BEG . END).")
( data nil :type (or null cons)
;; When non-nil, the CAR must be a non-casemapped nickname. For
;; compatibility, the CDR should probably be nil, but this may
;; have to change eventually. If non-nil, the entire cons should
;; be mutated rather than replaced because it's used as a key in
;; hash tables and text-property searches.
:documentation "A unique cons whose car is a nickname.")
( downcased nil :type (or null string)
:documentation "The case-mapped nickname sans text properties.")
( user nil :type (or null erc-server-user)
;; Not necessarily present in `erc-server-users'.
:documentation "A possibly nil or spoofed `erc-server-user'.")
( cuser nil :type (or null erc-channel-user)
;; The CDR of a value from an `erc-channel-users' table.
:documentation "A possibly nil `erc-channel-user'.")
( erc-button-face erc-button-face :type symbol
:documentation "Temp `erc-button-face' while buttonizing.")
( erc-button-nickname-face erc-button-nickname-face :type symbol
:documentation "Temp `erc-button-nickname-face' while buttonizing.")
( erc-button-mouse-face erc-button-mouse-face :type symbol
:documentation "Temp `erc-button-mouse-face' while buttonizing."))
;; This variable is intended to serve as a "core" to be wrapped by
;; (built-in) modules during setup. It's unclear whether
;; `add-function's practice of removing existing advice before
;; re-adding it is desirable when integrating modules since we're
;; mostly concerned with ensuring one "piece" precedes or follows
;; another (specific piece), which may not yet (or ever) be present.
(defvar erc-button--modify-nick-function #'identity
"Function to possibly modify aspects of nick being buttonized.
Called with one argument, an `erc-button--nick' object, or nil.
The function should return the same (or similar) object when
buttonizing ought to proceed and nil otherwise. While running,
all faces defined in `erc-button' are bound temporarily and can
be updated at will.")
(defvar-local erc-button--phantom-users nil)
(defvar erc-button--fallback-user-function #'ignore
"Function to determine `erc-server-user' if not found in the usual places.
Called with DOWNCASED-NICK, NICK, and NICK-BOUNDS when
`erc-button-add-nickname-buttons' cannot find a user object for
DOWNCASED-NICK in `erc-channel-users' or `erc-server-users'.")
(defun erc-button--add-phantom-speaker (downcased nuh _parsed)
"Stash fictitious `erc-server-user' while processing \"PRIVMSG\".
Expect DOWNCASED to be the downcased nickname, NUH to be a triple
of (NICK LOGIN HOST), and parsed to be an `erc-response' object."
(pcase-let* ((`(,nick ,login ,host) nuh)
(user (or (gethash downcased erc-button--phantom-users)
(make-erc-server-user
:nickname nick
:host (and (not (string-empty-p host)) host)
:login (and (not (string-empty-p login)) login)))))
(list (puthash downcased user erc-button--phantom-users))))
(defun erc-button--get-phantom-user (down _word _bounds)
(gethash down erc-button--phantom-users))
;; In the future, we'll most likely create temporary
;; `erc-channel-users' tables during BATCH chathistory playback, thus
;; obviating the need for this mode entirely.
(define-minor-mode erc-button--phantom-users-mode
"Minor mode to recognize unknown speakers.
Expect to be used by module setup code for creating placeholder
users on the fly during history playback. Treat an unknown
\"PRIVMSG\" speaker, like \"<bob>\", as if they previously
appeared in a prior \"353\" message and are thus a known member
of the channel. However, don't bother creating an actual
`erc-channel-user' object because their status prefix is unknown.
Instead, just spoof an `erc-server-user' and stash it during
\"PRIVMSG\" handling via `erc--user-from-nick-function' and
retrieve it during buttonizing via
`erc-button--fallback-user-function'."
:interactive nil
(if erc-button--phantom-users-mode
(progn
(add-function :after-until (local 'erc--user-from-nick-function)
#'erc-button--add-phantom-speaker '((depth . -50)))
(add-function :after-until (local 'erc-button--fallback-user-function)
#'erc-button--get-phantom-user '((depth . 50)))
(setq erc-button--phantom-users (make-hash-table :test #'equal)))
(remove-function (local 'erc--user-from-nick-function)
#'erc-button--add-phantom-speaker)
(remove-function (local 'erc-button--fallback-user-function)
#'erc-button--get-phantom-user)
(kill-local-variable 'erc-nicks--phantom-users)))
(defun erc-button-add-nickname-buttons (entry)
"Search through the buffer for nicknames, and add buttons."
(let ((form (nth 2 entry))
(fun (nth 3 entry))
bounds word)
(when (eq form 'erc-button-buttonize-nicks)
(setq form (and (symbol-value form) erc-button--modify-nick-function)))
(when (or (functionp form)
(eq t form)
(and form (erc-button--maybe-warn-arbitrary-sexp form)))
(when (or (eq t form)
(eval form t))
(goto-char (point-min))
(while (erc-forward-word)
(when (setq bounds (erc-bounds-of-word-at-point))
(setq word (buffer-substring-no-properties
(car bounds) (cdr bounds)))
(let* ((erc-button-face erc-button-face)
(erc-button-mouse-face erc-button-mouse-face)
(erc-button-nickname-face erc-button-nickname-face)
(down (erc-downcase word))
(cuser (and erc-channel-users
(gethash down erc-channel-users)))
(user (or (and cuser (car cuser))
(and erc-server-users
(gethash down erc-server-users))
(funcall erc-button--fallback-user-function
down word bounds)))
(data (list word)))
(when (or (not (functionp form))
(and-let* ((user)
(obj (funcall form (make-erc-button--nick
:bounds bounds :data data
:downcased down :user user
:cuser (cdr cuser)))))
(setq bounds (erc-button--nick-bounds obj)
data (erc-button--nick-data obj)
erc-button-mouse-face
(erc-button--nick-erc-button-mouse-face obj)
erc-button-nickname-face
(erc-button--nick-erc-button-nickname-face obj)
erc-button-face
(erc-button--nick-erc-button-face obj))))
(erc-button-add-button (car bounds) (cdr bounds)
fun t data))))))))
(when (or (and (erc-server-buffer-p) (erc-get-server-user word))
(and erc-channel-users (erc-get-channel-user word)))
(erc-button-add-button (car bounds) (cdr bounds)
fun t (list word))))))))
(defun erc-button-add-buttons-1 (regexp entry)
"Search through the buffer for matches to ENTRY and add buttons."
(goto-char (point-min))
(let (buttonizer)
(while
(and (re-search-forward regexp nil t)
(or buttonizer
(setq buttonizer
(and-let*
((raw-form (nth 2 entry))
(res (or (eq t raw-form)
(erc-button--maybe-warn-arbitrary-sexp
raw-form))))
(if (functionp res) res #'erc-button-add-button)))))
(let ((start (match-beginning (nth 1 entry)))
(end (match-end (nth 1 entry)))
(fun (nth 3 entry))
(data (mapcar #'match-string-no-properties (nthcdr 4 entry))))
(funcall buttonizer start end fun nil data regexp)))))
(while (re-search-forward regexp nil t)
(let ((start (match-beginning (nth 1 entry)))
(end (match-end (nth 1 entry)))
(form (nth 2 entry))
(fun (nth 3 entry))
(data (mapcar #'match-string-no-properties (nthcdr 4 entry))))
(when (or (eq t form)
(eval form t))
(erc-button-add-button start end fun nil data regexp)))))
(defun erc-button-remove-old-buttons ()
"Remove all existing buttons.
@ -564,7 +405,6 @@ call it with the value of the `erc-data' text property."
(defun erc-button-next-function ()
"Pseudo completion function that actually jumps to the next button.
For use on `completion-at-point-functions'."
(declare (obsolete erc-nickserv-identify "30.1"))
;; FIXME: This is an abuse of completion-at-point-functions.
(when (< (point) (erc-beg-of-input-line))
(let ((start (point)))
@ -582,73 +422,27 @@ For use on `completion-at-point-functions'."
(error "No next button"))
t)))))
(defvar erc-button--prev-next-predicate-functions
'(erc-button--end-of-button-p)
"Abnormal hook whose members can return non-nil to continue searching.
Otherwise, if all members return nil, point will stay at the
current button. Called with a single arg, a buffer position
greater than `point-min' with a text property of `erc-callback'.")
(defun erc-button-next ()
"Go to the next button in this buffer."
(interactive)
(let ((f (erc-button-next-function)))
(if f (funcall f))))
(defun erc-button--end-of-button-p (point)
(get-text-property (1- point) 'erc-callback))
(defun erc--button-next (arg)
(let* ((nextp (prog1 (>= arg 1) (setq arg (max 1 (abs arg)))))
(search-fn (if nextp
#'next-single-char-property-change
#'previous-single-char-property-change))
(start (point))
(p start))
(while (progn
;; Break out of current search context.
(when-let ((low (max (point-min) (1- (pos-bol))))
(high (min (point-max) (1+ (pos-eol))))
(prop (get-text-property p 'erc-callback))
(q (if nextp
(text-property-not-all p high
'erc-callback prop)
(funcall search-fn p 'erc-callback nil low)))
((< low q high)))
(setq p q))
;; Assume that buttons occur frequently enough that
;; omitting LIMIT is acceptable.
(while
(and (setq p (funcall search-fn p 'erc-callback))
(if nextp (< p erc-insert-marker) (/= p (point-min)))
(run-hook-with-args-until-success
'erc-button--prev-next-predicate-functions p)))
(and arg
(< (point-min) p erc-insert-marker)
(goto-char p)
(not (zerop (cl-decf arg))))))
(when (= (point) start)
(user-error (if nextp "No next button" "No previous button")))
t))
(defun erc-button-next (&optional arg)
"Go to the ARGth next button."
(declare (advertised-calling-convention (arg) "30.1"))
(interactive "p")
(setq arg (pcase arg ((pred listp) (prefix-numeric-value arg)) (_ arg)))
(erc--button-next arg))
(defun erc-button-previous (&optional arg)
"Go to ARGth previous button."
(declare (advertised-calling-convention (arg) "30.1"))
(interactive "p")
(setq arg (pcase arg ((pred listp) (prefix-numeric-value arg)) (_ arg)))
(erc--button-next (- arg)))
(defun erc-button-previous-of-nick (arg)
"Go to ARGth previous button for nick at point."
(interactive "p")
(if-let* ((prop (get-text-property (point) 'erc-data))
(erc-button--prev-next-predicate-functions
(cons (lambda (p)
(not (equal (get-text-property p 'erc-data) prop)))
erc-button--prev-next-predicate-functions)))
(erc--button-next (- arg))
(user-error "No nick at point")))
(defun erc-button-previous ()
"Go to the previous button in this buffer."
(interactive)
(let ((here (point)))
(when (< here (erc-beg-of-input-line))
(while (and (get-text-property here 'erc-callback)
(not (= here (point-min))))
(setq here (1- here)))
(while (and (not (get-text-property here 'erc-callback))
(not (= here (point-min))))
(setq here (1- here)))
(if (> here (point-min))
(goto-char here)
(error "No previous button"))
t)))
(defun erc-browse-emacswiki (thing)
"Browse to THING in the emacs-wiki."
@ -717,70 +511,6 @@ and `apropos' for other symbols."
(message "@%s is %d:%02d local time"
beats hours minutes)))
(defun erc-button--display-error-with-buttons
(from to fun nick-p &optional data regexp)
"Replace command in region with keys and return new bounds"
(let* ((o (buffer-substring from to))
(s (substitute-command-keys o))
(erc-button-face (and (equal o s) erc-button-face)))
(delete-region from to)
(insert s)
(erc-button-add-button from (point) fun nick-p data regexp)))
;;;###autoload
(defun erc-button--display-error-notice-with-keys (&optional parsed buffer
&rest strings)
"Add help keys to STRINGS for configuration-related admonishments.
Return inserted result. Expect PARSED to be an `erc-response'
object, a string, or nil. Expect BUFFER to be a buffer, a string,
or nil. As a special case, allow PARSED to be a buffer as long
as BUFFER is a string or nil. If STRINGS contains any trailing
non-strings, concatenate leading string members before applying
`format'. Otherwise, just concatenate everything."
(when (stringp buffer)
(push buffer strings)
(setq buffer nil))
(when (stringp parsed)
(push parsed strings)
(setq parsed nil))
(when (bufferp parsed)
(cl-assert (null buffer))
(setq buffer parsed
parsed nil))
(let* ((op (if (seq-every-p #'stringp (cdr strings))
#'concat
(let ((head (pop strings)))
(while (stringp (car strings))
(setq head (concat head (pop strings))))
(push head strings))
#'format))
(string (apply op strings))
(erc-insert-post-hook
(cons (lambda ()
(setq string (buffer-substring (point-min)
(1- (point-max)))))
erc-insert-post-hook))
(erc-button-alist
`((,(rx "\\[" (group (+ (not "]"))) "]") 0
erc-button--display-error-with-buttons
erc-button-describe-symbol 1)
,@erc-button-alist)))
(erc-display-message parsed '(notice error) (or buffer 'active) string)
string))
;;;###autoload
(defun erc-button--display-error-notice-with-keys-and-warn (&rest args)
"Like `erc-button--display-error-notice-with-keys' but also warn."
(let ((string (apply #'erc-button--display-error-notice-with-keys args)))
(with-temp-buffer
(insert string)
(goto-char (point-min))
(with-syntax-table lisp-mode-syntax-table
(skip-syntax-forward "^-"))
(forward-char)
(display-warning
'erc (buffer-substring-no-properties (point) (point-max))))))
(provide 'erc-button)
;;; erc-button.el ends here

View file

@ -89,7 +89,6 @@ character not found in IRC nicknames to avoid confusion."
;;; Define module:
;;;###autoload(autoload 'erc-capab-identify-mode "erc-capab" nil t)
(put 'capab-identify 'erc-group 'erc-capab)
(define-erc-module capab-identify nil
"Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP."
;; append so that `erc-server-parameters' is already set by `erc-server-005'

View file

@ -30,35 +30,19 @@
(defvar erc--casemapping-rfc1459-strict)
(defvar erc-channel-users)
(defvar erc-dbuf)
(defvar erc-insert-this)
(defvar erc-log-p)
(defvar erc-modules)
(defvar erc-send-this)
(defvar erc-server-process)
(defvar erc-server-users)
(defvar erc-session-server)
(declare-function erc--get-isupport-entry "erc-backend" (key &optional single))
(declare-function erc-get-buffer "erc" (target &optional proc))
(declare-function erc-server-buffer "erc" nil)
(declare-function widget-apply-action "wid-edit" (widget &optional event))
(declare-function widget-at "wid-edit" (&optional pos))
(declare-function widget-create-child-and-convert "wid-edit"
(parent type &rest args))
(declare-function widget-default-format-handler "wid-edit" (widget escape))
(declare-function widget-get-sibling "wid-edit" (widget))
(declare-function widget-move "wid-edit" (arg &optional suppress-echo))
(declare-function widget-type "wid-edit" (widget))
(cl-defstruct erc-input
string insertp sendp refoldp)
string insertp sendp)
(cl-defstruct (erc--input-split (:include erc-input
(string :read-only)
(insertp erc-insert-this)
(sendp erc-send-this)))
(lines nil :type (list-of string))
(cmdp nil :type boolean))
(cl-defstruct (erc--input-split (:include erc-input))
lines cmdp)
(cl-defstruct (erc-server-user (:type vector) :named)
;; User data
@ -101,52 +85,45 @@
(contents "" :type string)
(tags '() :type list))
;; After dropping 28, we can use prefixed "erc-autoload" cookies.
;; TODO move goodies modules here after 29 is released.
(defconst erc--features-to-modules
'((erc-pcomplete completion pcomplete)
(erc-capab capab-identify)
(erc-join autojoin)
(erc-page page ctcp-page)
(erc-sound sound ctcp-sound)
(erc-stamp stamp timestamp)
(erc-services services nickserv))
"Migration alist mapping a library feature to module names.
Keys need not be unique: a library may define more than one
module. Sometimes a module's downcased alias will be its
canonical name.")
(defconst erc--modules-to-features
(let (pairs)
(pcase-dolist (`(,feature . ,names) erc--features-to-modules)
(dolist (name names)
(push (cons name feature) pairs)))
(nreverse pairs))
"Migration alist mapping a module's name to its home library feature.")
(defconst erc--module-name-migrations
(let (pairs)
(pcase-dolist (`(,_ ,canonical . ,rest) erc--features-to-modules)
(dolist (obsolete rest)
(push (cons obsolete canonical) pairs)))
pairs)
"Association list of obsolete module names to canonical names.")
(defun erc--normalize-module-symbol (symbol)
"Return preferred SYMBOL for `erc--modules'."
(while-let ((canonical (get symbol 'erc--module))
((not (eq canonical symbol))))
(setq symbol canonical))
symbol)
(defvar erc--inside-mode-toggle-p nil
"Non-nil when a module's mode toggle is updating module membership.
This serves as a flag to inhibit the mutual recursion that would
otherwise occur between an ERC-defined minor-mode function, such
as `erc-services-mode', and the custom-set function for
`erc-modules'. For historical reasons, the latter calls
`erc-update-modules', which, in turn, enables the minor-mode
functions for all member modules. Also non-nil when a mode's
widget runs its set function.")
(defun erc--favor-changed-reverted-modules-state (name op)
"Be more nuanced in displaying Custom state of `erc-modules'.
When `customized-value' differs from `saved-value', allow widget
to behave normally and show \"SET for current session\", as
though `customize-set-variable' or similar had been applied.
However, when `customized-value' and `standard-value' match but
differ from `saved-value', prefer showing \"CHANGED outside
Customize\" to prevent the widget from seeing a `standard'
instead of a `set' state, which precludes any actual saving."
;; Although the button "Apply and save" is fortunately grayed out,
;; `Custom-save' doesn't actually save (users must click the magic
;; state button instead). The default behavior described in the doc
;; string is intentional and was introduced by bug#12864 "Make state
;; button interaction less confusing". However, it is unfriendly to
;; rogue libraries (like ours) that insist on mutating user options
;; as a matter of course.
(custom-load-symbol 'erc-modules)
(funcall (get 'erc-modules 'custom-set) 'erc-modules
(funcall op (erc--normalize-module-symbol name) erc-modules))
(when (equal (pcase (get 'erc-modules 'saved-value)
(`((quote ,saved) saved)))
erc-modules)
(customize-mark-as-set 'erc-modules)))
"Return preferred SYMBOL for `erc-modules'."
(setq symbol (intern (downcase (symbol-name symbol))))
(or (cdr (assq symbol erc--module-name-migrations)) symbol))
(defun erc--assemble-toggle (localp name ablsym mode val body)
(let ((arg (make-symbol "arg")))
`(defun ,ablsym ,(if localp `(&optional ,arg) '())
,(erc--fill-module-docstring
,(concat
(if val "Enable" "Disable")
" ERC " (symbol-name name) " mode."
(when localp
@ -160,133 +137,14 @@ instead of a `set' state, which precludes any actual saving."
(,ablsym))
(setq ,mode ,val)
,@body)))
;; No need for `default-value', etc. because a buffer-local
;; `erc-modules' only influences the next session and
;; doesn't survive the major-mode reset that soon follows.
`((unless
(or erc--inside-mode-toggle-p
,@(let ((v `(memq ',(erc--normalize-module-symbol name)
erc-modules)))
`(,(if val v `(not ,v)))))
(let ((erc--inside-mode-toggle-p t))
(erc--favor-changed-reverted-modules-state
',name #',(if val 'cons 'delq))))
`(,(if val
`(cl-pushnew ',(erc--normalize-module-symbol name)
erc-modules)
`(setq erc-modules (delq ',(erc--normalize-module-symbol name)
erc-modules)))
(setq ,mode ,val)
,@body)))))
;; This is a migration helper that determines a module's `:group'
;; keyword argument from its name or alias. A (global) module's minor
;; mode variable appears under the group's Custom menu. Like
;; `erc--normalize-module-symbol', it must run when the module's
;; definition (rather than that of `define-erc-module') is expanded.
;; For corner cases in which this fails or the catch-all of `erc' is
;; more inappropriate, (global) modules can declare a top-level
;;
;; (put 'foo 'erc-group 'erc-bar)
;;
;; where `erc-bar' is the group and `foo' is the normalized module.
;; Do this *before* the module's definition. If `define-erc-module'
;; ever accepts arbitrary keywords, passing an explicit `:group' will
;; obviously be preferable.
(defun erc--find-group (&rest symbols)
(catch 'found
(dolist (s symbols)
(let* ((downed (downcase (symbol-name s)))
(known (intern-soft (concat "erc-" downed))))
(when (and known
(or (get known 'group-documentation)
(rassq known custom-current-group-alist)))
(throw 'found known))
(when (setq known (intern-soft (concat "erc-" downed "-mode")))
(when-let ((found (custom-group-of-mode known)))
(throw 'found found))))
(when-let ((found (get (erc--normalize-module-symbol s) 'erc-group)))
(throw 'found found)))
'erc))
;; This exists as a separate, top-level function to prevent the byte
;; compiler from warning about widget-related dependencies not being
;; loaded at runtime.
(defun erc--tick-module-checkbox (name &rest _) ; `name' must be normalized
(customize-variable-other-window 'erc-modules)
;; Move to `erc-modules' section.
(while (not (eq (widget-type (widget-at)) 'checkbox))
(widget-move 1 t))
;; This search for a checkbox can fail when `name' refers to a
;; third-party module that modifies `erc-modules' (improperly) on
;; load.
(let (w)
(while (and (eq (widget-type (widget-at)) 'checkbox)
(not (and (setq w (widget-get-sibling (widget-at)))
(eq (widget-value w) name))))
(setq w nil)
(widget-move 1 t)) ; the `suppress-echo' arg exists in 27.2
(unless w
(error "Failed to find %s in `erc-modules' checklist" name))
(widget-apply-action (widget-at))
(message "Hit %s to apply or %s to apply and save."
(substitute-command-keys "\\[Custom-set]")
(substitute-command-keys "\\[Custom-save]"))))
;; This stands apart to avoid needing forward declarations for
;; `wid-edit' functions in every file requiring `erc-common'.
(defun erc--make-show-me-widget (widget escape &rest plist)
(if (eq escape ?i)
(apply #'widget-create-child-and-convert widget 'push-button plist)
(widget-default-format-handler widget escape)))
(defun erc--prepare-custom-module-type (name)
`(let* ((name (erc--normalize-module-symbol ',name))
(fmtd (format " `%s' " name)))
`(boolean
:format "%{%t%}: %i %[Deprecated Toggle%] %v \n%h\n"
:format-handler
,(lambda (widget escape)
(erc--make-show-me-widget
widget escape
:button-face '(custom-variable-obsolete custom-button)
:tag "Show Me"
:action (apply-partially #'erc--tick-module-checkbox name)
:help-echo (lambda (_)
(let ((hasp (memq name erc-modules)))
(concat (if hasp "Remove" "Add") fmtd
(if hasp "from" "to")
" `erc-modules'.")))))
:action widget-toggle-action
:documentation-property
,(lambda (_)
(let ((hasp (memq name erc-modules)))
(concat
"Setting a module's minor-mode variable is "
(propertize "ineffective" 'face 'error)
".\nPlease " (if hasp "remove" "add") fmtd
(if hasp "from" "to") " `erc-modules' directly instead.\n"
"You can do so now by clicking "
(propertize "Show Me" 'face 'custom-variable-obsolete)
" above."))))))
(defun erc--fill-module-docstring (&rest strings)
(with-temp-buffer
(emacs-lisp-mode)
(insert "(defun foo ()\n"
(format "%S" (apply #'concat strings))
"\n(ignore))")
(goto-char (point-min))
(forward-line 2)
(let ((emacs-lisp-docstring-fill-column 65)
(sentence-end-double-space t))
(fill-paragraph))
(goto-char (point-min))
(nth 3 (read (current-buffer)))))
(defmacro erc--find-feature (name alias)
`(pcase (erc--find-group ',name ,(and alias (list 'quote alias)))
('erc (and-let* ((file (or (macroexp-file-name) buffer-file-name)))
(intern (file-name-base file))))
(v v)))
(defmacro define-erc-module (name alias doc enable-body disable-body
&optional local-p)
"Define a new minor mode using ERC conventions.
@ -321,20 +179,21 @@ Example:
(declare (doc-string 3) (indent defun))
(let* ((sn (symbol-name name))
(mode (intern (format "erc-%s-mode" (downcase sn))))
(group (intern (format "erc-%s" (downcase sn))))
(enable (intern (format "erc-%s-enable" (downcase sn))))
(disable (intern (format "erc-%s-disable" (downcase sn)))))
`(progn
(define-minor-mode
,mode
,(erc--fill-module-docstring (format "Toggle ERC %s mode.
,(format "Toggle ERC %S mode.
With a prefix argument ARG, enable %s if ARG is positive,
and disable it otherwise. If called from Lisp, enable the mode
if ARG is omitted or nil.
\n%s" name name doc))
:global ,(not local-p)
:group (erc--find-group ',name ,(and alias (list 'quote alias)))
,@(unless local-p `(:require ',(erc--find-feature name alias)))
,@(unless local-p `(:type ,(erc--prepare-custom-module-type name)))
%s" name name doc)
;; FIXME: We don't know if this group exists, so this `:group' may
;; actually just silence a valid warning about the fact that the var
;; is not associated with any group.
:global ,(not local-p) :group (quote ,group)
(if ,mode
(,enable)
(,disable)))
@ -390,17 +249,11 @@ See also `with-current-buffer'.
"Execute BODY in the current ERC server buffer.
If no server buffer exists, return nil."
(declare (indent 0) (debug (body)))
(let ((varp (and (symbolp (car body))
(not (cdr body))
(special-variable-p (car body))))
(buffer (make-symbol "buffer")))
`(when-let* (((processp erc-server-process))
(,buffer (process-buffer erc-server-process))
((buffer-live-p ,buffer)))
,(if varp
`(buffer-local-value ',(car body) ,buffer)
`(with-current-buffer ,buffer
,@body)))))
(let ((buffer (make-symbol "buffer")))
`(let ((,buffer (erc-server-buffer)))
(when (buffer-live-p ,buffer)
(with-current-buffer ,buffer
,@body)))))
(defmacro erc-with-all-buffers-of-server (process pred &rest forms)
"Execute FORMS in all buffers which have same process as this server.

View file

@ -32,50 +32,7 @@
;;; Code:
(require 'compat nil 'noerror)
(eval-when-compile (require 'cl-lib))
;; Except for the "erc-" namespacing, these two definitions should be
;; continuously updated to match the latest upstream ones verbatim.
;; Although they're pretty simple, it's likely not worth checking for
;; and possibly deferring to the non-prefixed versions.
;;
;; BEGIN Compat macros
;;;; Macros for extended compatibility function calls
(defmacro erc-compat-function (fun)
"Return compatibility function symbol for FUN.
If the Emacs version provides a sufficiently recent version of
FUN, the symbol FUN is returned itself. Otherwise the macro
returns the symbol of a compatibility function which supports the
behavior and calling convention of the current stable Emacs
version. For example Compat 29.1 will provide compatibility
functions which implement the behavior and calling convention of
Emacs 29.1.
See also `compat-call' to directly call compatibility functions."
(let ((compat (intern (format "compat--%s" fun))))
`#',(if (fboundp compat) compat fun)))
(defmacro erc-compat-call (fun &rest args)
"Call compatibility function or macro FUN with ARGS.
A good example function is `plist-get' which was extended with an
additional predicate argument in Emacs 29.1. The compatibility
function, which supports this additional argument, can be
obtained via (compat-function plist-get) and called
via (compat-call plist-get plist prop predicate). It is not
possible to directly call (plist-get plist prop predicate) on
Emacs older than 29.1, since the original `plist-get' function
does not yet support the predicate argument. Note that the
Compat library never overrides existing functions.
See also `compat-function' to lookup compatibility functions."
(let ((compat (intern (format "compat--%s" fun))))
`(,(if (fboundp compat) compat fun) ,@args)))
;; END Compat macros
(eval-when-compile (require 'cl-lib) (require 'url-parse))
;;;###autoload(autoload 'erc-define-minor-mode "erc-compat")
(define-obsolete-function-alias 'erc-define-minor-mode
@ -411,8 +368,16 @@ If START or END is negative, it counts from the end."
;;;; Misc 29.1
(defmacro erc-compat--with-memoization (table &rest forms)
(declare (indent defun))
(cond
((fboundp 'with-memoization)
`(with-memoization ,table ,@forms)) ; 29.1
((fboundp 'cl--generic-with-memoization)
`(cl--generic-with-memoization ,table ,@forms))
(t `(progn ,@forms))))
(defvar url-irc-function)
(declare-function url-type "url-parse" (cl-x))
(defun erc-compat--29-browse-url-irc (string &rest _)
(require 'url-irc)
@ -444,28 +409,6 @@ If START or END is negative, it counts from the end."
(cons '("\\`irc6?s?://" . erc-compat--29-browse-url-irc)
existing))))))
;;;; Misc 28.1
(defvar comint-file-name-quote-list)
(defvar shell-file-name-quote-list)
(declare-function shell--parse-pcomplete-arguments "shell" nil)
(defun erc-compat--28-split-string-shell-command (string)
(require 'comint)
(require 'shell)
(with-temp-buffer
(insert string)
(let ((comint-file-name-quote-list shell-file-name-quote-list))
(car (shell--parse-pcomplete-arguments)))))
(defmacro erc-compat--split-string-shell-command (string)
;; Autoloaded in Emacs 28.
(list (if (fboundp 'split-string-shell-command)
'split-string-shell-command
'erc-compat--28-split-string-shell-command)
string))
(provide 'erc-compat)
;;; erc-compat.el ends here

View file

@ -43,7 +43,7 @@
;; /dcc chat nick - Either accept pending chat offer from nick, or offer
;; DCC chat to nick
;; /dcc close type [nick] - Close DCC connection (SEND/GET/CHAT) with nick
;; /dcc get [-t][-s] nick [--] file - Accept DCC offer from nick
;; /dcc get [-t][-s] nick [file] - Accept DCC offer from nick
;; /dcc list - List all DCC offers/connections
;; /dcc send nick file - Offer DCC SEND to nick
@ -389,18 +389,12 @@ If this is nil, then the current value of `default-directory' is used."
:type '(choice (const :value nil :tag "Default directory") directory))
;;;###autoload
(defun erc-cmd-DCC (line &rest compat-args)
(defun erc-cmd-DCC (cmd &rest args)
"Parser for /dcc command.
This figures out the dcc subcommand and calls the appropriate routine to
handle it. The function dispatched should be named \"erc-dcc-do-FOO-command\",
where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
(let (cmd args)
;; Called as library function (i.e., not directly as /dcc)
(if compat-args
(setq cmd line
args compat-args)
(setq args (delete "" (erc-compat--split-string-shell-command line))
cmd (pop args)))
(when cmd
(let ((fn (intern-soft (concat "erc-dcc-do-" (upcase cmd) "-command"))))
(if fn
(apply fn erc-server-process args)
@ -410,16 +404,8 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
(apropos "erc-dcc-do-.*-command")
t))))
(put 'erc-cmd-DCC 'do-not-parse-args t)
(autoload 'pcomplete-erc-all-nicks "erc-pcomplete")
;;;###autoload(put 'erc-cmd-DCC 'erc--cmd-help 'erc-dcc--cmd-help)
(defun erc-dcc--cmd-help (&rest args)
(describe-function
(or (and args (intern-soft (concat "erc-dcc-do-"
(upcase (car args)) "-command")))
'erc-cmd-DCC)))
;;;###autoload
(defun pcomplete/erc-mode/DCC ()
"Provide completion for the /DCC command."
@ -444,20 +430,15 @@ where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
(eq (plist-get elt :type) 'GET))
erc-dcc-list)))
('send (pcomplete-erc-all-nicks))))
(when (equal "get" (downcase (pcomplete-arg 'first 1)))
(pcomplete-opt "-"))
(pcomplete-here
(pcase (intern (downcase (pcomplete-arg 'first 1)))
('get (mapcar (lambda (elt)
(combine-and-quote-strings (list (plist-get elt :file))))
('get (mapcar (lambda (elt) (plist-get elt :file))
(cl-remove-if-not
(lambda (elt)
(and (eq (plist-get elt :type) 'GET)
(erc-nick-equal-p (erc-extract-nick
(plist-get elt :nick))
(pcase (pcomplete-arg 1)
("--" (pcomplete-arg 2))
(v v)))))
(pcomplete-arg 1))))
erc-dcc-list)))
('close (mapcar #'erc-dcc-nick
(cl-remove-if-not
@ -523,33 +504,16 @@ At least one of TYPE and NICK must be provided."
?n (erc-extract-nick (plist-get ret :nick))))))
t))
(defun erc-dcc-do-GET-command (proc &rest args)
"Perform a DCC GET command.
Recognize input conforming to the following usage syntax:
/DCC GET [-t|-s] nick [--] filename
nick The person who is sending the file.
filename The filename to be downloaded. Can be split into multiple
arguments that are then joined by a space.
flags \"-t\" sets `:turbo' in `erc-dcc-list'
\"-s\" sets `:secure' in `erc-dcc-list'
\"--\" indicates end of options
All of which are optional.
Expect PROC to be the server process and ARGS to contain
everything after the subcommand \"GET\" in the usage description
above."
;; Despite the advertised syntax above, we currently respect flags
;; in these positions: [flag] nick [flag] filename [flag]
(let* ((trailing (and-let* ((trailing (member "--" args)))
(setq args (butlast args (length trailing)))
(cdr trailing)))
(args (seq-group-by (lambda (s) (eq ?- (aref s 0))) args))
(defun erc-dcc-do-GET-command (proc nick &rest file)
"Do a DCC GET command. NICK is the person who is sending the file.
FILE is the filename. If FILE is split into multiple arguments,
re-join the arguments, separated by a space.
PROC is the server process."
(let* ((args (seq-group-by (lambda (s) (eq ?- (aref s 0))) (cons nick file)))
(flags (prog1 (cdr (assq t args))
(setq args (nconc (cdr (assq nil args)) trailing))))
(nick (pop args))
(file (and args (mapconcat #'identity args " ")))
(setq args (cdr (assq nil args))
nick (pop args)
file (and args (mapconcat #'identity args " ")))))
(elt (erc-dcc-member :nick nick :type 'GET :file file))
(filename (or file (plist-get elt :file) "unknown")))
(if elt

View file

@ -28,9 +28,6 @@
;; `erc-fill-mode' to switch it on. Customize `erc-fill-function' to
;; change the style.
;; TODO: redo `erc-fill-wrap-nudge' using transient after ERC drops
;; support for Emacs 27.
;;; Code:
(require 'erc)
@ -41,18 +38,30 @@
:group 'erc)
;;;###autoload(autoload 'erc-fill-mode "erc-fill" nil t)
(define-erc-module fill nil
"Manage filling in ERC buffers.
(define-minor-mode erc-fill-mode
"Toggle ERC fill mode.
With a prefix argument ARG, enable ERC fill mode if ARG is
positive, and disable it otherwise. If called from Lisp, enable
the mode if ARG is omitted or nil.
ERC fill mode is a global minor mode. When enabled, messages in
the channel buffers are filled."
;; FIXME ensure a consistent ordering relative to hook members from
;; other modules. Ideally, this module's processing should happen
;; after "morphological" modifications to a message's text but
;; before superficial decorations.
((add-hook 'erc-insert-modify-hook #'erc-fill)
(add-hook 'erc-send-modify-hook #'erc-fill))
((remove-hook 'erc-insert-modify-hook #'erc-fill)
(remove-hook 'erc-send-modify-hook #'erc-fill)))
:global t
(if erc-fill-mode
(erc-fill-enable)
(erc-fill-disable)))
(defun erc-fill-enable ()
"Setup hooks for `erc-fill-mode'."
(interactive)
(add-hook 'erc-insert-modify-hook #'erc-fill)
(add-hook 'erc-send-modify-hook #'erc-fill))
(defun erc-fill-disable ()
"Cleanup hooks, disable `erc-fill-mode'."
(interactive)
(remove-hook 'erc-insert-modify-hook #'erc-fill)
(remove-hook 'erc-send-modify-hook #'erc-fill))
(defcustom erc-fill-prefix nil
"Values used as `fill-prefix' for `erc-fill-variable'.
@ -82,29 +91,16 @@ Static Filling with `erc-fill-static-center' of 27:
These two styles are implemented using `erc-fill-variable' and
`erc-fill-static'. You can, of course, define your own filling
function. Narrowing to the region in question is in effect while your
function is called.
A third style resembles static filling but \"wraps\" instead of
fills, thanks to `visual-line-mode' mode, which ERC automatically
enables when this option is `erc-fill-wrap' or when
`erc-fill-wrap-mode' is active. Set `erc-fill-static-center' to
your preferred initial \"prefix\" width. For adjusting the width
during a session, see the command `erc-fill-wrap-nudge'."
function is called."
:type '(choice (const :tag "Variable Filling" erc-fill-variable)
(const :tag "Static Filling" erc-fill-static)
(const :tag "Dynamic word-wrap" erc-fill-wrap)
function))
(defcustom erc-fill-static-center 27
"Number of columns to \"outdent\" the first line of a message.
During early message handing, ERC prepends a span of
non-whitespace characters to every message, such as a bracketed
\"<nickname>\" or an `erc-notice-prefix'. The
`erc-fill-function' variants `erc-fill-static' and
`erc-fill-wrap' look to this option to determine the amount of
padding to apply to that portion until the filled (or wrapped)
message content aligns with the indicated column. See also
https://en.wikipedia.org/wiki/Hanging_indent."
"Column around which all statically filled messages will be centered.
This column denotes the point where the ` ' character between
<nickname> and the entered text will be put, thus aligning nick
names right and text left."
:type 'integer)
(defcustom erc-fill-variable-maximum-indentation 17
@ -134,7 +130,7 @@ You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
(defun erc-fill-static ()
"Fills a text such that messages start at column `erc-fill-static-center'."
(save-restriction
(save-match-data
(goto-char (point-min))
(looking-at "^\\(\\S-+\\)")
(let ((nick (match-string 1)))
@ -171,343 +167,6 @@ You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
(erc-fill-regarding-timestamp))))
(erc-restore-text-properties)))
(defvar-local erc-fill--wrap-value nil)
(defvar-local erc-fill--wrap-visual-keys nil)
(defcustom erc-fill-wrap-use-pixels t
"Whether to calculate padding in pixels when possible.
A value of nil means ERC should use columns, which may happen
regardless, depending on the Emacs version. This option only
matters when `erc-fill-wrap-mode' is enabled."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type 'boolean)
(defcustom erc-fill-wrap-visual-keys 'non-input
"Whether to retain keys defined by `visual-line-mode'.
A value of t tells ERC to use movement commands defined by
`visual-line-mode' everywhere in an ERC buffer along with visual
editing commands in the input area. A value of nil means to
never do so. A value of `non-input' tells ERC to act like the
value is nil in the input area and t elsewhere. This option only
plays a role when `erc-fill-wrap-mode' is enabled."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type '(choice (const nil) (const t) (const non-input)))
(defcustom erc-fill-wrap-merge t
"Whether to consolidate messages from the same speaker.
This tells ERC to omit redundant speaker labels for subsequent
messages less than a day apart."
:package-version '(ERC . "5.6") ; FIXME sync on release
:type 'boolean)
(defun erc-fill--wrap-move (normal-cmd visual-cmd arg)
(funcall (pcase erc-fill--wrap-visual-keys
('non-input
(if (>= (point) erc-input-marker) normal-cmd visual-cmd))
('t visual-cmd)
(_ normal-cmd))
arg))
(defun erc-fill--wrap-kill-line (arg)
"Defer to `kill-line' or `kill-visual-line'."
(interactive "P")
;; ERC buffers are read-only outside of the input area, but we run
;; `kill-line' anyway so that users can see the error.
(erc-fill--wrap-move #'kill-line #'kill-visual-line arg))
(defun erc-fill--wrap-beginning-of-line (arg)
"Defer to `move-beginning-of-line' or `beginning-of-visual-line'."
(interactive "^p")
(let ((inhibit-field-text-motion t))
(erc-fill--wrap-move #'move-beginning-of-line
#'beginning-of-visual-line arg))
(if (get-text-property (point) 'erc-prompt)
(goto-char erc-input-marker)
;; Mimic what `move-beginning-of-line' does with invisible text.
(when-let ((erc-fill-wrap-merge)
(empty (get-text-property (point) 'display))
((string-empty-p empty)))
(goto-char (text-property-not-all (point) (pos-eol) 'display empty)))))
(defun erc-fill--wrap-end-of-line (arg)
"Defer to `move-end-of-line' or `end-of-visual-line'."
(interactive "^p")
(erc-fill--wrap-move #'move-end-of-line #'end-of-visual-line arg))
(defun erc-fill-wrap-cycle-visual-movement (arg)
"Cycle through `erc-fill-wrap-visual-keys' styles ARG times.
Go from nil to t to `non-input' and back around, but set internal
state instead of mutating `erc-fill-wrap-visual-keys'. When ARG
is 0, reset to value of `erc-fill-wrap-visual-keys'."
(interactive "^p")
(when (zerop arg)
(setq erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys))
(while (not (zerop arg))
(cl-incf arg (- (abs arg)))
(setq erc-fill--wrap-visual-keys (pcase erc-fill--wrap-visual-keys
('nil t)
('t 'non-input)
('non-input nil))))
(message "erc-fill-wrap movement: %S" erc-fill--wrap-visual-keys))
(defvar-keymap erc-fill-wrap-mode-map ; Compat 29
:doc "Keymap for ERC's `fill-wrap' module."
:parent visual-line-mode-map
"<remap> <kill-line>" #'erc-fill--wrap-kill-line
"<remap> <move-end-of-line>" #'erc-fill--wrap-end-of-line
"<remap> <move-beginning-of-line>" #'erc-fill--wrap-beginning-of-line
"C-c a" #'erc-fill-wrap-cycle-visual-movement
;; Not sure if this is problematic because `erc-bol' takes no args.
"<remap> <erc-bol>" #'erc-fill--wrap-beginning-of-line)
(defvar erc-match-mode)
(defvar erc-button-mode)
(defvar erc-match--hide-fools-offset-bounds)
(defun erc-fill--make-module-dependency-msg (module)
(concat "Enabling default global module `" module "' needed by local"
" module `fill-wrap'. This will impact \C-]all\C-] ERC"
" sessions. Add `" module "' to `erc-modules' to avoid this"
" warning. See Info:\"(erc) Modules\" for more."))
;;;###autoload(put 'fill-wrap 'erc--feature 'erc-fill)
(define-erc-module fill-wrap nil
"Fill style leveraging `visual-line-mode'.
This module displays nickname labels for speakers as overhanging
leftward (and thus right-aligned) to a common offset, as
determined by the option `erc-fill-static-center'. It depends on
the `fill' and `button' modules and assumes the option
`erc-insert-timestamp-function' is `erc-insert-timestamp-right'
or `erc-insert-timestamp-left-and-right' (recommended) so that it
can display right-hand stamps in the right margin. A value of
`erc-insert-timestamp-left' is unsupported. This local module
depends on the global `fill' module. To use it, either include
`fill-wrap' in `erc-modules' or set `erc-fill-function' to
`erc-fill-wrap' (recommended). You can also manually invoke one
of the minor-mode toggles as usual."
((let (msg)
(unless erc-fill-mode
(unless (memq 'fill erc-modules)
(setq msg
;; FIXME use `erc-button--display-error-notice-with-keys'
;; when bug#60933 is ready.
(erc-fill--make-module-dependency-msg "fill")))
(erc-fill-mode +1))
(when erc-fill-wrap-merge
(require 'erc-button)
(unless erc-button-mode
(unless (memq 'button erc-modules)
(setq msg (concat msg (and msg " ")
(erc-fill--make-module-dependency-msg "button"))))
(erc-with-server-buffer
(erc-button-mode +1)))
(add-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p nil t))
;; Set local value of user option (can we avoid this somehow?)
(unless (eq erc-fill-function #'erc-fill-wrap)
(setq-local erc-fill-function #'erc-fill-wrap))
(when-let* ((vars (or erc--server-reconnecting erc--target-priors))
((alist-get 'erc-fill-wrap-mode vars)))
(setq erc-fill--wrap-visual-keys (alist-get 'erc-fill--wrap-visual-keys
vars)
erc-fill--wrap-value (alist-get 'erc-fill--wrap-value vars)))
(add-function :filter-args (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date)
(when (or erc-stamp-mode (memq 'stamp erc-modules))
(erc-stamp--display-margin-mode +1))
(when (or (bound-and-true-p erc-match-mode) (memq 'match erc-modules))
(require 'erc-match)
(setq erc-match--hide-fools-offset-bounds t))
(setq erc-fill--wrap-value
(or erc-fill--wrap-value erc-fill-static-center))
(visual-line-mode +1)
(unless (local-variable-p 'erc-fill--wrap-visual-keys)
(setq erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys))
(when msg
(erc-display-error-notice nil msg))))
((when erc-stamp--display-margin-mode
(erc-stamp--display-margin-mode -1))
(kill-local-variable 'erc-fill--wrap-value)
(kill-local-variable 'erc-fill-function)
(kill-local-variable 'erc-fill--wrap-visual-keys)
(remove-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p t)
(remove-function (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date)
(visual-line-mode -1))
'local)
(defvar-local erc-fill--wrap-length-function nil
"Function to determine length of overhanging characters.
It should return an EXPR as defined by the Info node `(elisp)
Pixel Specification'. This value should represent the width of
the overhang with all faces applied, including any enclosing
brackets (which are not normally fontified) and a trailing space.
It can also return nil to tell ERC to fall back to the default
behavior of taking the length from the first \"word\". This
variable can be converted to a public one if needed by third
parties.")
(defvar-local erc-fill--wrap-last-msg nil)
(defvar-local erc-fill--wrap-max-lull (* 24 60 60))
(defun erc-fill--wrap-continued-message-p ()
(prog1 (and-let*
((m (or erc-fill--wrap-last-msg
(setq erc-fill--wrap-last-msg (point-min-marker))
nil))
((< (1+ (point-min)) (- (point) 2)))
(props (save-restriction
(widen)
(when (eq 'erc-timestamp (field-at-pos m))
(set-marker m (field-end m)))
(and (eq 'PRIVMSG (get-text-property m 'erc-command))
(not (eq (get-text-property m 'font-lock-face)
'erc-action-face))
(cons (get-text-property m 'erc-timestamp)
(get-text-property (1+ m) 'erc-data)))))
(ts (pop props))
((not (time-less-p (erc-stamp--current-time) ts)))
((time-less-p (time-subtract (erc-stamp--current-time) ts)
erc-fill--wrap-max-lull))
(nick (buffer-substring-no-properties
(1+ (point-min)) (- (point) 2)))
(props)
((erc-nick-equal-p (car props) nick))))
(set-marker erc-fill--wrap-last-msg (point-min))))
(defun erc-fill--wrap-stamp-insert-prefixed-date (args)
"Apply `line-prefix' property to args."
(let* ((ts-left (car args)))
(put-text-property 0 (length ts-left) 'line-prefix
`(space :width
(- erc-fill--wrap-value
,(length (string-trim-left ts-left))))
ts-left))
args)
(defun erc-fill-wrap ()
"Use text props to mimic the effect of `erc-fill-static'.
See `erc-fill-wrap-mode' for details."
(unless erc-fill-wrap-mode
(erc-fill-wrap-mode +1))
(save-excursion
(goto-char (point-min))
(let ((len (or (and erc-fill--wrap-length-function
(funcall erc-fill--wrap-length-function))
(progn
(skip-syntax-forward "^-")
(forward-char)
;; Using the `invisible' property might make more
;; sense, but that would require coordination
;; with other modules, like `erc-match'.
(cond ((and erc-fill-wrap-merge
(erc-fill--wrap-continued-message-p))
(put-text-property (point-min) (point)
'display "")
0)
((and erc-fill-wrap-use-pixels
(fboundp 'buffer-text-pixel-size))
(save-restriction
(narrow-to-region (point-min) (point))
(list (car (buffer-text-pixel-size)))))
(t (- (point) (point-min))))))))
;; Leaving out the final newline doesn't seem to affect anything.
(erc-put-text-properties (point-min) (point-max)
'(line-prefix wrap-prefix) nil
`((space :width (- erc-fill--wrap-value ,len))
(space :width erc-fill--wrap-value))))))
;; FIXME use own text property to avoid false positives.
(defun erc-fill--wrap-merged-button-p (point)
(equal "" (get-text-property point 'display)))
;; This is an experimental helper for third-party modules. You could,
;; for example, use this to automatically resize the prefix to a
;; fraction of the window's width on some event change. Another use
;; case would be to fix lines affected by toggling a display-oriented
;; mode, like `display-line-numbers-mode'.
(defun erc-fill--wrap-fix (&optional value)
"Re-wrap from `point-min' to `point-max'.
That is, recalculate the width of all accessible lines and reset
local prefix VALUE when non-nil."
(save-excursion
(when value
(setq erc-fill--wrap-value value))
(let ((inhibit-field-text-motion t)
(inhibit-read-only t))
(goto-char (point-min))
(while (and (zerop (forward-line))
(< (point) (min (point-max) erc-insert-marker)))
(save-restriction
(narrow-to-region (line-beginning-position) (line-end-position))
(erc-fill-wrap))))))
(defun erc-fill--wrap-nudge (arg)
(when (zerop arg)
(setq arg (- erc-fill-static-center erc-fill--wrap-value)))
(cl-incf erc-fill--wrap-value arg)
arg)
(defun erc-fill-wrap-nudge (arg)
"Adjust `erc-fill-wrap' by ARG columns.
Offer to repeat command in a manner similar to
`text-scale-adjust'.
\\`=' Increase indentation by one column
\\`-' Decrease indentation by one column
\\`0' Reset indentation to the default
\\`+' Shift right margin rightward (shrink) by one column
\\`_' Shift right margin leftward (grow) by one column
\\`)' Reset the right margin to the default
Note that misalignment may occur when messages contain
decorations applied by third-party modules. See
`erc-fill--wrap-fix' for a temporary workaround."
(interactive "p")
(unless erc-fill--wrap-value
(cl-assert (not erc-fill-wrap-mode))
(user-error "Minor mode `erc-fill-wrap-mode' disabled"))
(unless (get-buffer-window)
(user-error "Command called in an undisplayed buffer"))
(let* ((total (erc-fill--wrap-nudge arg))
(win-ratio (/ (float (- (window-point) (window-start)))
(- (window-end nil t) (window-start)))))
(when (zerop arg)
(setq arg 1))
(erc-compat-call
set-transient-map
(let ((map (make-sparse-keymap)))
(dolist (key '(?= ?- ?0))
(let ((a (pcase key
(?0 0)
(?- (- (abs arg)))
(_ (abs arg)))))
(define-key map (vector (list key))
(lambda ()
(interactive)
(cl-incf total (erc-fill--wrap-nudge a))
(recenter (round (* win-ratio (window-height))))))))
(dolist (key '(?\) ?_ ?+))
(let ((a (pcase key
(?\) 0)
(?_ (- (abs arg)))
(?+ (abs arg)))))
(define-key map (vector (list key))
(lambda ()
(interactive)
(erc-stamp--adjust-right-margin (- a))
(recenter (round (* win-ratio (window-height))))))))
map)
t
(lambda ()
(message "Fill prefix: %d (%+d col%s)"
erc-fill--wrap-value total (if (> (abs total) 1) "s" "")))
"Use %k for further adjustment"
1)
(recenter (round (* win-ratio (window-height))))))
(defun erc-fill-regarding-timestamp ()
"Fills a text such that messages start at column `erc-fill-static-center'."
(fill-region (point-min) (point-max) t t)

View file

@ -29,13 +29,30 @@
;;; Code:
;;; Imenu support
(eval-when-compile (require 'cl-lib))
(require 'erc)
(require 'erc-common)
(declare-function fringe-columns "fringe" (side &optional real))
(declare-function pulse-available-p "pulse" nil)
(declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face))
(defvar erc-controls-highlight-regexp)
(defvar erc-controls-remove-regexp)
(defvar erc-input-marker)
(defvar erc-insert-marker)
(defvar erc-server-process)
(defvar erc-modules)
(defvar erc-log-p)
(declare-function erc-buffer-list "erc" (&optional predicate proc))
(declare-function erc-error "erc" (&rest args))
(declare-function erc-extract-command-from-line "erc" (line))
(declare-function erc-beg-of-input-line "erc" nil)
(defun erc-imenu-setup ()
"Setup Imenu support in an ERC buffer."
(setq-local imenu-create-index-function #'erc-create-imenu-index))
(add-hook 'erc-mode-hook #'erc-imenu-setup)
(autoload 'erc-create-imenu-index "erc-imenu" "Imenu index creation function")
;;; Automatically scroll to bottom
(defcustom erc-input-line-position nil
@ -48,7 +65,6 @@ argument to `recenter'."
:group 'erc-display
:type '(choice integer (const nil)))
;;;###autoload(autoload 'erc-scrolltobottom-mode "erc-goodies" nil t)
(define-erc-module scrolltobottom nil
"This mode causes the prompt to stay at the end of the window."
((add-hook 'erc-mode-hook #'erc-add-scroll-to-bottom)
@ -100,7 +116,6 @@ variable `erc-input-line-position'."
(recenter (or erc-input-line-position -1)))))))
;;; Make read only
;;;###autoload(autoload 'erc-readonly-mode "erc-goodies" nil t)
(define-erc-module readonly nil
"This mode causes all inserted text to be read-only."
((add-hook 'erc-insert-post-hook #'erc-make-read-only)
@ -116,7 +131,6 @@ Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'."
(put-text-property (point-min) (point-max) 'rear-nonsticky t))
;;; Move to prompt when typing text
;;;###autoload(autoload 'erc-move-to-prompt-mode "erc-goodies" nil t)
(define-erc-module move-to-prompt nil
"This mode causes the point to be moved to the prompt when typing text."
((add-hook 'erc-mode-hook #'erc-move-to-prompt-setup)
@ -141,160 +155,11 @@ Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'."
(add-hook 'pre-command-hook #'erc-move-to-prompt nil t))
;;; Keep place in unvisited channels
;;;###autoload(autoload 'erc-keep-place-mode "erc-goodies" nil t)
(define-erc-module keep-place nil
"Leave point above un-viewed text in other channels."
((add-hook 'erc-insert-pre-hook #'erc-keep-place))
((remove-hook 'erc-insert-pre-hook #'erc-keep-place)))
(defcustom erc-keep-place-indicator-style t
"Flavor of visual indicator applied to kept place.
For use with the `keep-place-indicator' module. A value of `arrow'
displays an arrow in the left fringe or margin. When it's
`face', ERC adds the face `erc-keep-place-indicator-line' to the
appropriate line. A value of t does both."
:group 'erc
:package-version '(ERC . "5.6")
:type '(choice (const t) (const server) (const target)))
(defcustom erc-keep-place-indicator-buffer-type t
"ERC buffer type in which to display `keep-place-indicator'.
A value of t means \"all\" ERC buffers."
:group 'erc
:package-version '(ERC . "5.6")
:type '(choice (const t) (const server) (const target)))
(defcustom erc-keep-place-indicator-follow nil
"Whether to sync visual kept place to window's top when reading.
For use with `erc-keep-place-indicator-mode'."
:group 'erc
:package-version '(ERC . "5.6")
:type 'boolean)
(defface erc-keep-place-indicator-line
'((((class color) (min-colors 88) (background light)
(supports :underline (:style wave)))
(:underline (:color "PaleGreen3" :style wave)))
(((class color) (min-colors 88) (background dark)
(supports :underline (:style wave)))
(:underline (:color "PaleGreen1" :style wave)))
(t :underline t))
"Face for option `erc-keep-place-indicator-style'."
:group 'erc-faces)
(defface erc-keep-place-indicator-arrow
'((((class color) (min-colors 88) (background light))
(:foreground "PaleGreen3"))
(((class color) (min-colors 88) (background dark))
(:foreground "PaleGreen1"))
(t :inherit fringe))
"Face for arrow value of option `erc-keep-place-indicator-style'."
:group 'erc-faces)
(defvar-local erc--keep-place-indicator-overlay nil
"Overlay for `erc-keep-place-indicator-mode'.")
(defun erc--keep-place-indicator-on-window-configuration-change ()
"Maybe sync `erc--keep-place-indicator-overlay'.
Specifically, do so unless switching to or from another window in
the active frame."
(when erc-keep-place-indicator-follow
(unless (or (minibuffer-window-active-p (minibuffer-window))
(eq (window-old-buffer) (current-buffer)))
(when (< (overlay-end erc--keep-place-indicator-overlay)
(window-start)
erc-insert-marker)
(erc-keep-place-move (window-start))))))
(defun erc--keep-place-indicator-setup ()
"Initialize buffer for maintaining `erc--keep-place-indicator-overlay'."
(require 'fringe)
(setq erc--keep-place-indicator-overlay
(if-let* ((vars (or erc--server-reconnecting erc--target-priors))
((alist-get 'erc-keep-place-indicator-mode vars)))
(alist-get 'erc--keep-place-indicator-overlay vars)
(make-overlay 0 0)))
(add-hook 'window-configuration-change-hook
#'erc--keep-place-indicator-on-window-configuration-change nil t)
(when-let* (((memq erc-keep-place-indicator-style '(t arrow)))
(display (if (zerop (fringe-columns 'left))
`((margin left-margin) ,overlay-arrow-string)
'(left-fringe right-triangle
erc-keep-place-indicator-arrow)))
(bef (propertize " " 'display display)))
(overlay-put erc--keep-place-indicator-overlay 'before-string bef))
(when (memq erc-keep-place-indicator-style '(t face))
(overlay-put erc--keep-place-indicator-overlay 'face
'erc-keep-place-indicator-line)))
;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies)
(define-erc-module keep-place-indicator nil
"`keep-place' with a fringe arrow and/or highlighted face."
((unless erc-keep-place-mode
(unless (memq 'keep-place erc-modules)
;; FIXME use `erc-button--display-error-notice-with-keys'
;; to display this message when bug#60933 is ready.
(erc-display-error-notice
nil (concat
"Local module `keep-place-indicator' needs module `keep-place'."
" Enabling now. This will affect \C-]all\C-] ERC sessions."
" Add `keep-place' to `erc-modules' to silence this message.")))
(erc-keep-place-mode +1))
(if (pcase erc-keep-place-indicator-buffer-type
('target erc--target)
('server (not erc--target))
('t t))
(erc--keep-place-indicator-setup)
(setq erc-keep-place-indicator-mode nil)))
((when erc--keep-place-indicator-overlay
(delete-overlay erc--keep-place-indicator-overlay)
(remove-hook 'window-configuration-change-hook
#'erc--keep-place-indicator-on-window-configuration-change t)
(kill-local-variable 'erc--keep-place-indicator-overlay)))
'local)
(defun erc-keep-place-move (pos)
"Move keep-place indicator to current line or POS.
For use with `keep-place-indicator' module. When called
interactively, interpret POS as an offset. Specifically, when
POS is a raw prefix arg, like (4), move the indicator to the
window's last line. When it's the minus sign, put it on the
window's first line. Interpret an integer as an offset in lines."
(interactive
(progn
(unless erc-keep-place-indicator-mode
(user-error "`erc-keep-place-indicator-mode' not enabled"))
(list (pcase current-prefix-arg
((and (pred integerp) v)
(save-excursion
(let ((inhibit-field-text-motion t))
(forward-line v)
(point))))
(`(,_) (1- (min erc-insert-marker (window-end))))
('- (min (1- erc-insert-marker) (window-start)))))))
(save-excursion
(let ((inhibit-field-text-motion t))
(when pos
(goto-char pos))
(move-overlay erc--keep-place-indicator-overlay
(line-beginning-position)
(line-end-position)))))
(defun erc-keep-place-goto ()
"Jump to keep-place indicator.
For use with `keep-place-indicator' module."
(interactive
(prog1 nil
(unless erc-keep-place-indicator-mode
(user-error "`erc-keep-place-indicator-mode' not enabled"))
(deactivate-mark)
(push-mark)))
(goto-char (overlay-start erc--keep-place-indicator-overlay))
(recenter (truncate (* (window-height) 0.25)) t)
(require 'pulse)
(when (pulse-available-p)
(pulse-momentary-highlight-overlay erc--keep-place-indicator-overlay)))
(defun erc-keep-place (_ignored)
"Move point away from the last line in a non-selected ERC buffer."
(when (and (not (eq (window-buffer (selected-window))
@ -303,11 +168,6 @@ For use with `keep-place-indicator' module."
(deactivate-mark)
(goto-char (erc-beg-of-input-line))
(forward-line -1)
(when erc-keep-place-indicator-mode
(unless (or (minibuffer-window-active-p (selected-window))
(and (frame-visible-p (selected-frame))
(get-buffer-window (current-buffer) (selected-frame))))
(erc-keep-place-move nil)))
;; if `switch-to-buffer-preserve-window-point' is set,
;; we cannot rely on point being saved, and must commit
;; it to window-prev-buffers.
@ -333,14 +193,12 @@ For use with `keep-place-indicator' module."
If a command's function symbol is in this list, the typed command
does not appear in the ERC buffer after the user presses ENTER.")
;;;###autoload(autoload 'erc-noncommands-mode "erc-goodies" nil t)
(define-erc-module noncommands nil
"This mode distinguishes non-commands.
Commands listed in `erc-insert-this' know how to display
themselves."
((add-hook 'erc--input-review-functions #'erc-send-distinguish-noncommands))
((remove-hook 'erc--input-review-functions
#'erc-send-distinguish-noncommands)))
((add-hook 'erc-pre-send-functions #'erc-send-distinguish-noncommands))
((remove-hook 'erc-pre-send-functions #'erc-send-distinguish-noncommands)))
(defun erc-send-distinguish-noncommands (state)
"If STR is an ERC non-command, set `insertp' in STATE to nil."
@ -393,12 +251,6 @@ The value `erc-interpret-controls-p' must also be t for this to work."
"ERC inverse face."
:group 'erc-faces)
(defface erc-spoiler-face
'((((background light)) :foreground "DimGray" :background "DimGray")
(((background dark)) :foreground "LightGray" :background "LightGray"))
"ERC spoiler face."
:group 'erc-faces)
(defface erc-underline-face '((t :underline t))
"ERC underline face."
:group 'erc-faces)
@ -501,38 +353,19 @@ The value `erc-interpret-controls-p' must also be t for this to work."
"ERC face."
:group 'erc-faces)
;; https://lists.gnu.org/archive/html/emacs-erc/2021-07/msg00005.html
(defvar erc--controls-additional-colors
["#470000" "#472100" "#474700" "#324700" "#004700" "#00472c"
"#004747" "#002747" "#000047" "#2e0047" "#470047" "#47002a"
"#740000" "#743a00" "#747400" "#517400" "#007400" "#007449"
"#007474" "#004074" "#000074" "#4b0074" "#740074" "#740045"
"#b50000" "#b56300" "#b5b500" "#7db500" "#00b500" "#00b571"
"#00b5b5" "#0063b5" "#0000b5" "#7500b5" "#b500b5" "#b5006b"
"#ff0000" "#ff8c00" "#ffff00" "#b2ff00" "#00ff00" "#00ffa0"
"#00ffff" "#008cff" "#0000ff" "#a500ff" "#ff00ff" "#ff0098"
"#ff5959" "#ffb459" "#ffff71" "#cfff60" "#6fff6f" "#65ffc9"
"#6dffff" "#59b4ff" "#5959ff" "#c459ff" "#ff66ff" "#ff59bc"
"#ff9c9c" "#ffd39c" "#ffff9c" "#e2ff9c" "#9cff9c" "#9cffdb"
"#9cffff" "#9cd3ff" "#9c9cff" "#dc9cff" "#ff9cff" "#ff94d3"
"#000000" "#131313" "#282828" "#363636" "#4d4d4d" "#656565"
"#818181" "#9f9f9f" "#bcbcbc" "#e2e2e2" "#ffffff"])
(defun erc-get-bg-color-face (n)
"Fetches the right face for background color N (0-15)."
(if (stringp n) (setq n (string-to-number n)))
(if (not (numberp n))
(prog1 'default
(erc-error "erc-get-bg-color-face: n is NaN: %S" n))
(when (> n 99)
(when (> n 16)
(erc-log (format " Wrong color: %s" n))
(setq n (mod n 16)))
(cond
((and (>= n 0) (< n 16))
(intern (concat "bg:erc-color-face" (number-to-string n))))
((< 15 n 99)
(list :background (aref erc--controls-additional-colors (- n 16))))
(t (erc-log (format " Wrong color: %s" n)) '(default)))))
(t (erc-log (format " Wrong color: %s" n)) 'default))))
(defun erc-get-fg-color-face (n)
"Fetches the right face for foreground color N (0-15)."
@ -540,44 +373,20 @@ The value `erc-interpret-controls-p' must also be t for this to work."
(if (not (numberp n))
(prog1 'default
(erc-error "erc-get-fg-color-face: n is NaN: %S" n))
(when (> n 99)
(when (> n 16)
(erc-log (format " Wrong color: %s" n))
(setq n (mod n 16)))
(cond
((and (>= n 0) (< n 16))
(intern (concat "fg:erc-color-face" (number-to-string n))))
((< 15 n 99)
(list :foreground (aref erc--controls-additional-colors (- n 16))))
(t (erc-log (format " Wrong color: %s" n)) '(default)))))
(t (erc-log (format " Wrong color: %s" n)) 'default))))
;;;###autoload(autoload 'erc-irccontrols-mode "erc-goodies" nil t)
(define-erc-module irccontrols nil
"This mode enables the interpretation of IRC control chars."
((add-hook 'erc-insert-modify-hook #'erc-controls-highlight)
(add-hook 'erc-send-modify-hook #'erc-controls-highlight)
(erc--modify-local-map t "C-c C-c" #'erc-toggle-interpret-controls))
(add-hook 'erc-send-modify-hook #'erc-controls-highlight))
((remove-hook 'erc-insert-modify-hook #'erc-controls-highlight)
(remove-hook 'erc-send-modify-hook #'erc-controls-highlight)
(erc--modify-local-map nil "C-c C-c" #'erc-toggle-interpret-controls)))
;; These patterns were moved here to circumvent compiler warnings but
;; otherwise translated verbatim from their original string-literal
;; definitions (minus a small bug fix to satisfy newly added tests).
(defvar erc-controls-remove-regexp
(rx (or ?\C-b ?\C-\] ?\C-_ ?\C-v ?\C-g ?\C-o
(: ?\C-c (? (any "0-9")) (? (any "0-9"))
(? (group ?, (any "0-9") (? (any "0-9")))))))
"Regular expression matching control characters to remove.")
;; Before the change to `rx', group 3 used to be a sibling of group 2.
;; This was assumed to be a bug. A few minor simplifications were
;; also performed. If incorrect, please admonish.
(defvar erc-controls-highlight-regexp
(rx (group (or ?\C-b ?\C-\] ?\C-v ?\C-_ ?\C-g ?\C-o
(: ?\C-c (? (group (** 1 2 (any "0-9")))
(? (group ?, (group (** 1 2 (any "0-9")))))))))
(group (* (not (any ?\C-b ?\C-c ?\C-g ?\n ?\C-o ?\C-v ?\C-\] ?\C-_)))))
"Regular expression matching control chars to highlight.")
(remove-hook 'erc-send-modify-hook #'erc-controls-highlight)))
(defun erc-controls-interpret (str)
"Return a copy of STR after dealing with IRC control characters.
@ -631,7 +440,6 @@ See `erc-interpret-controls-p' and `erc-interpret-mirc-color' for options."
s))
(t s)))))
;;;###autoload
(defun erc-controls-strip (str)
"Return a copy of STR with all IRC control characters removed."
(when str
@ -640,6 +448,16 @@ See `erc-interpret-controls-p' and `erc-interpret-mirc-color' for options."
(setq s (replace-match "" nil nil s)))
s)))
(defvar erc-controls-remove-regexp
"\C-b\\|\C-]\\|\C-_\\|\C-v\\|\C-g\\|\C-o\\|\C-c[0-9]?[0-9]?\\(,[0-9][0-9]?\\)?"
"Regular expression which matches control characters to remove.")
(defvar erc-controls-highlight-regexp
(concat "\\(\C-b\\|\C-]\\|\C-v\\|\C-_\\|\C-g\\|\C-o\\|"
"\C-c\\([0-9][0-9]?\\)?\\(,\\([0-9][0-9]?\\)\\)?\\)"
"\\([^\C-b\C-]\C-v\C-_\C-c\C-g\C-o\n]*\\)")
"Regular expression which matches control chars and the text to highlight.")
(defun erc-controls-highlight ()
"Highlight IRC control chars in the buffer.
This is useful for `erc-insert-modify-hook' and `erc-send-modify-hook'.
@ -696,13 +514,6 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
(if (and fg bg (equal fg bg))
(progn
(setq fg 'erc-spoiler-face
bg nil)
(put-text-property from to 'mouse-face 'erc-inverse-face str))
(when fg (setq fg (erc-get-fg-color-face fg)))
(when bg (setq bg (erc-get-bg-color-face bg))))
(font-lock-prepend-text-property
from
to
@ -720,10 +531,10 @@ to a region in the current buffer."
'(erc-underline-face)
nil)
(if fg
(list fg)
(list (erc-get-fg-color-face fg))
nil)
(if bg
(list bg)
(list (erc-get-bg-color-face bg))
nil))
str)
str)
@ -742,7 +553,6 @@ Else interpretation is turned off."
(if erc-interpret-controls-p "ON" "OFF")))
;; Smiley
;;;###autoload(autoload 'erc-smiley-mode "erc-goodies" nil t)
(define-erc-module smiley nil
"This mode translates text-smileys such as :-) into pictures.
This requires the function `smiley-region', which is defined in
@ -759,7 +569,6 @@ This function should be used with `erc-insert-modify-hook'."
(smiley-region (point-min) (point-max))))
;; Unmorse
;;;###autoload(autoload 'erc-unmorse-mode "erc-goodies" nil t)
(define-erc-module unmorse nil
"This mode causes morse code in the current channel to be unmorsed."
((add-hook 'erc-insert-modify-hook #'erc-unmorse))
@ -802,7 +611,3 @@ servers. If called from a program, PROC specifies the server process."
(provide 'erc-goodies)
;;; erc-goodies.el ends here
;; Local Variables:
;; generated-autoload-file: "erc-loaddefs.el"
;; End:

View file

@ -32,7 +32,6 @@
(require 'ibuffer)
(require 'ibuf-ext)
(require 'erc)
(require 'erc-goodies) ; `erc-controls-interpret'
(defgroup erc-ibuffer nil
"The Ibuffer group for ERC."

View file

@ -52,8 +52,7 @@ Don't rely on this function, read it first!"
(forward-line 1)
(looking-at " "))
(forward-line 1))
(end-of-line) (point))))
(inhibit-read-only t))
(end-of-line) (point)))))
(with-temp-buffer
(insert str)
(goto-char (point-min))
@ -125,26 +124,6 @@ Don't rely on this function, read it first!"
index-alist))
index-alist))
(defvar-local erc-imenu--create-index-function nil
"Previous local value of `imenu-create-index-function', if any.")
(defun erc-imenu-setup ()
"Wire up support for Imenu in an ERC buffer."
(when (and (local-variable-p 'imenu-create-index-function)
imenu-create-index-function)
(setq erc-imenu--create-index-function imenu-create-index-function))
(setq imenu-create-index-function #'erc-create-imenu-index))
;;;###autoload(autoload 'erc-imenu-mode "erc-imenu" nil t)
(define-erc-module imenu nil
"Simple Imenu integration for ERC."
((add-hook 'erc-mode-hook #'erc-imenu-setup))
((remove-hook 'erc-mode-hook #'erc-imenu-setup)
(erc-with-all-buffers-of-server erc-server-process nil
(when erc-imenu--create-index-function
(setq imenu-create-index-function erc-imenu--create-index-function)
(kill-local-variable 'erc-imenu--create-index-function)))))
(provide 'erc-imenu)
;;; erc-imenu.el ends here

View file

@ -198,7 +198,6 @@ This should ideally, be a \"catch-all\" coding system, like
The function should take one argument, which is the text to filter."
:type '(choice (function "Function")
(function-item erc-stamp-prefix-log-filter)
(const :tag "No filtering" nil)))
@ -231,8 +230,7 @@ also be a predicate function. To only log when you are not set away, use:
;; append, so that 'erc-initialize-log-marker runs first
(add-hook 'erc-connect-pre-hook #'erc-log-setup-logging 'append)
(dolist (buffer (erc-buffer-list))
(erc-log-setup-logging buffer))
(erc--modify-local-map t "C-c C-l" #'erc-save-buffer-in-logs))
(erc-log-setup-logging buffer)))
;; disable
((remove-hook 'erc-insert-post-hook #'erc-save-buffer-in-logs)
(remove-hook 'erc-send-post-hook #'erc-save-buffer-in-logs)
@ -243,8 +241,9 @@ also be a predicate function. To only log when you are not set away, use:
(remove-hook 'erc-part-hook #'erc-conditional-save-buffer)
(remove-hook 'erc-connect-pre-hook #'erc-log-setup-logging)
(dolist (buffer (erc-buffer-list))
(erc-log-disable-logging buffer))
(erc--modify-local-map nil "C-c C-l" #'erc-save-buffer-in-logs)))
(erc-log-disable-logging buffer))))
(define-key erc-mode-map "\C-c\C-l" #'erc-save-buffer-in-logs)
;;; functionality referenced from erc.el
(defun erc-log-setup-logging (buffer)

View file

@ -52,13 +52,8 @@ they are hidden or highlighted. This is controlled via the variables
`erc-current-nick-highlight-type'. For all these highlighting types,
you can decide whether the entire message or only the sending nick is
highlighted."
((add-hook 'erc-insert-modify-hook #'erc-match-message 'append)
(add-hook 'erc-mode-hook #'erc-match--modify-invisibility-spec)
(erc--modify-local-map t "C-c C-k" #'erc-go-to-log-matches-buffer))
((remove-hook 'erc-insert-modify-hook #'erc-match-message)
(remove-hook 'erc-mode-hook #'erc-match--modify-invisibility-spec)
(erc-match--modify-invisibility-spec)
(erc--modify-local-map nil "C-c C-k" #'erc-go-to-log-matches-buffer)))
((add-hook 'erc-insert-modify-hook #'erc-match-message 'append))
((remove-hook 'erc-insert-modify-hook #'erc-match-message)))
;; Remaining customizations
@ -652,24 +647,15 @@ See `erc-log-match-format'."
(get-buffer (car buffer-cons))))))
(switch-to-buffer buffer-name)))
(defvar-local erc-match--hide-fools-offset-bounds nil)
(define-key erc-mode-map "\C-c\C-k" #'erc-go-to-log-matches-buffer)
;; FIXME this should merge with instead of overwrite existing
;; `invisible' values.
(defun erc-hide-fools (match-type _nickuserhost _message)
"Hide foolish comments.
This function should be called from `erc-text-matched-hook'."
(when (eq match-type 'fool)
(if erc-match--hide-fools-offset-bounds
(let ((beg (point-min))
(end (point-max)))
(save-restriction
(widen)
(put-text-property (1- beg) (1- end) 'invisible 'erc-match)))
;; The docs say `intangible' is deprecated, but this has been
;; like this for ages. Should verify unneeded and remove if so.
(erc-put-text-properties (point-min) (point-max)
'(invisible intangible)))))
(when (eq match-type 'fool)
(erc-put-text-properties (point-min) (point-max)
'(invisible intangible)
(current-buffer))))
(defun erc-beep-on-match (match-type _nickuserhost _message)
"Beep when text matches.
@ -677,13 +663,6 @@ This function is meant to be called from `erc-text-matched-hook'."
(when (member match-type erc-beep-match-types)
(beep)))
(defun erc-match--modify-invisibility-spec ()
"Add an ellipsis property to the local spec."
(if erc-match-mode
(add-to-invisibility-spec 'erc-match)
(erc-with-all-buffers-of-server nil nil
(remove-from-invisibility-spec 'erc-match))))
(provide 'erc-match)
;;; erc-match.el ends here

View file

@ -67,9 +67,6 @@
(declare-function erc-server-process-alive "erc-backend" (&optional buffer))
(declare-function erc-set-active-buffer "erc" (buffer))
(declare-function erc-button--display-error-notice-with-keys
(parsed &rest strings))
;; Variables
(defgroup erc-networks nil
@ -1295,6 +1292,7 @@ shutting down the connection."
erc-server-announced-name "\" in `erc-networks-alist'"
" or consider calling `erc-tls' with the keyword `:id'."
" See Info:\"(erc) Network Identifier\" for more.")))
(require 'info)
(erc-display-error-notice parsed m)
(if erc-networks--allow-unknown-network
(progn
@ -1313,11 +1311,12 @@ shutting down the connection."
Copy source (prefix) from MOTD-ish message as a last resort."
;; The 004 handler never ran; see 2004-03-10 Diane Murray in change log
(unless erc-server-announced-name
(require 'erc-button)
(erc-button--display-error-notice-with-keys
parsed "Failed to determine server name. Using \""
(setq erc-server-announced-name (erc-response.sender parsed)) "\" instead"
". If this was unexpected, consider reporting it via \\[erc-bug]" "."))
(setq erc-server-announced-name (erc-response.sender parsed))
(erc-display-error-notice
parsed (concat "Failed to determine server name. Using \""
erc-server-announced-name "\" instead."
" If this was unexpected, consider reporting it via "
(substitute-command-keys "\\[erc-bug]") ".")))
nil)
(defun erc-unset-network-name (_nick _ip _reason)
@ -1495,9 +1494,9 @@ to be a false alarm. If `erc-reuse-buffers' is nil, let
(memq (erc--target-symbol erc--target)
erc-networks--bouncer-targets)))
proc)
(require 'erc-button)
(erc-button--display-error-notice-with-keys
parsed "Unexpected state detected. Please report via \\[erc-bug].")))
(let ((m (concat "Unexpected state detected. Please report via "
(substitute-command-keys "\\[erc-bug]") ".")))
(erc-display-error-notice parsed m))))
;; For now, retain compatibility with erc-server-NNN-functions.
(or (erc-networks--ensure-announced proc parsed)
@ -1515,6 +1514,7 @@ to be a false alarm. If `erc-reuse-buffers' is nil, let
"Emit warning when the `networks' module hasn't been loaded.
Ideally, do so upon opening the network process."
(unless (or erc--target erc-networks-mode)
(require 'info nil t)
(let ((m (concat "Required module `networks' not loaded. If this "
" was unexpected, please add it to `erc-modules'.")))
;; Assume the server buffer has been marked as active.

View file

@ -30,13 +30,10 @@
(require 'erc)
(declare-function erc-controls-interpret "erc-goodies" (str))
(defgroup erc-page nil
"React to CTCP PAGE messages."
:group 'erc)
;;;###autoload(put 'ctcp-page 'erc--module 'page)
;;;###autoload(autoload 'erc-page-mode "erc-page")
(define-erc-module page ctcp-page
"Process CTCP PAGE requests from IRC."
@ -72,7 +69,6 @@ SENDER and MSG, so that might be easier to use."
This will call `erc-page-function', if defined, or it will just print
a message and `beep'. In addition to that, the page message is also
inserted into the server buffer."
(require 'erc-goodies) ; for `erc-controls-interpret'
(when (and erc-page-mode
(string-match "PAGE\\(\\s-+.*\\)?$" msg))
(let* ((m (match-string 1 msg))

View file

@ -56,8 +56,6 @@ add this string to nicks completed."
"If t, order nickname completions with the most recent speakers first."
:type 'boolean)
;;;###autoload(put 'Completion 'erc--module 'completion)
;;;###autoload(put 'pcomplete 'erc--module 'completion)
;;;###autoload(autoload 'erc-completion-mode "erc-pcomplete" nil t)
(define-erc-module pcomplete Completion
"In ERC Completion mode, the TAB key does completion whenever possible."

View file

@ -46,10 +46,10 @@
(define-erc-module ring nil
"Stores input in a ring so that previous commands and messages can
be recalled using M-p and M-n."
((add-hook 'erc--input-review-functions #'erc-add-to-input-ring 90)
((add-hook 'erc-pre-send-functions #'erc-add-to-input-ring)
(define-key erc-mode-map "\M-p" #'erc-previous-command)
(define-key erc-mode-map "\M-n" #'erc-next-command))
((remove-hook 'erc--input-review-functions #'erc-add-to-input-ring)
((remove-hook 'erc-pre-send-functions #'erc-add-to-input-ring)
(define-key erc-mode-map "\M-p" #'undefined)
(define-key erc-mode-map "\M-n" #'undefined)))

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