1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-05 22:20:24 -08:00

Merge branch 'master' into feature/igc

This commit is contained in:
Helmut Eller 2025-11-25 20:19:43 +01:00
commit 937aa5afe0
148 changed files with 4958 additions and 3065 deletions

View file

@ -142,7 +142,8 @@ the convention of leaving 2 spaces between sentences.
For more specific tips on Emacs's doc style, see
https://www.gnu.org/software/emacs/manual/html_node/elisp/Documentation-Tips.html
Use 'checkdoc' to check for documentation errors before submitting a patch.
and see the file admin/notes/documentation. Use 'checkdoc' to check for
documentation errors before submitting a patch.
** Testing your changes

View file

@ -124,6 +124,7 @@ files.")
("Hallvard B. Furuseth" "Hallvard B Furuseth" "Hallvard Furuseth")
(nil "hokomo@airmail\\.cc" "hokomo")
("Hrvoje Nikšić" "Hrvoje Niksic")
("Huang Jing" "rne\\.kou@icloud\\.com" "RadioNoiseE")
("Ian Dunn" "^Ian D\\>")
;; lisp/org/ChangeLog.1 2010-11-11.
("Ignacio Casso" "ignacio\\.decasso@imdea\\.org" "ignaciocasso@hotmail\\.com")
@ -305,6 +306,7 @@ files.")
("Yilkal Argaw" "yilkalargaw" "yilkalargawworkneh@gmail\\.com")
("Yoni Rabkin" "Yoni Rabkin Katzenell")
("Yoshinori Koseki" "KOSEKI Yoshinori" "小関 吉則")
("Yuhei Kikuchi" "8\\.slashes@gmail\\.com")
("Yuzhana Ego" "YugaEgo" "yet@ego\\.team")
("Yutaka NIIBE" "NIIBE Yutaka")
(nil "stardiviner")

View file

@ -46,7 +46,7 @@ GNULIB_MODULES='
nanosleep nproc nstrftime-limited
pathmax pipe2 pselect pthread_sigmask
qcopy-acl readlink readlinkat realloc-posix regex
sig2str sigdescr_np socklen stat-time std-gnu11
sig2str sigdescr_np socklen stat-time std-gnu23
stdc_bit_width stdc_count_ones stdc_trailing_zeros
stdckdint-h stddef-h stdio-h stdio-windows
stpcpy stringeq strnlen strtoimax symlink sys_stat-h sys_time-h
@ -61,7 +61,7 @@ AVOIDED_MODULES='
localcharset locale-h localename-unsafe-limited lock
mbrtowc mbsinit memchr mkdir msvc-inval msvc-nothrow nl_langinfo
openat-die opendir pthread-h raise
save-cwd select setenv sigprocmask stat stdarg-h
save-cwd select setenv sigprocmask stat std-gnu11 stdarg-h
threadlib tzset unsetenv utime utime-h
wchar-h wcrtomb wctype wctype-h
'

View file

@ -113,5 +113,54 @@ is where a feature works _differently_ in the previous version.
In those cases, the user might have trouble figuring out how to use
the old version without some sort of help.
** To indicate possession, write Emacs's rather than Emacs'.
https://lists.gnu.org/r/emacs-devel/2012-02/msg00649.html
** etc/NEWS style rules
Any change that matters to end-users should have an entry in etc/NEWS.
This is not intended as reference of design decisions or interfaces.
*** Each NEWS entry starts with a heading that summarizes the entry.
It takes just one line, and will finish with a period. Section
headings, which are one level up from entry headings, are not full
sentences. First-level headings are broad categories, and the other
section headings are the names of Emacs features. Don't use Lisp
symbols for section headings. E.g. "Random mode" not "'random-mode'".
*** All new, changed or obsoleted user options and commands are documented.
Document the default value or the argument list, respectively.
If a user option or command is obsoleted or changes the default value /
argument list, document how to keep the previous behavior.
Document further new, changed or obsoleted variables and functions, if
they are relevant for package authors.
*** Lisp symbols, Lisp forms and and key sequences are quoted 'like-this'.
This results in clickable Lisp symbols when the NEWS file is visited via
'view-emacs-news' ('C-h n'). Also single key names or keywords must
follow this rule, like 'TAB' or ':type'. Exception: the symbols t and
nil are not quoted.
Arguments of a function are written in capital letters LIKE-THIS, and they
are not quoted.
If Lisp forms are written in a line of its own, they are not quoted.
Separate these lines from the previous and following text by an empty
line. Indent them with a width of 4 spaces.
*** File names, buffer names, process names are strings.
Quote them with quotation marks "like this". Exception: Lisp file names
like subr.el, which are not quoted.
*** External program names are quoted with quotation marks like "this".
*** Manuals (Info pages) are referenced like "(elisp) Documentation Tips".
*** Prior pushing your changes, check the result.
Call 'emacs-news-view-mode'. Lisp symbols and Info manual links shall
be decorated, and clicking on them shall lead to the respective Help
buffer or Info node.

View file

@ -21,3 +21,6 @@ Re "behavior" vs "behaviour", etc.
In docstrings and the Texinfo manuals, say just "Lisp" whenever the
context renders it unambiguous that you mean "Emacs Lisp".
If you must abbreviate "Emacs Lisp", capitalize it thus: "Elisp".
- To indicate possession, write Emacs's rather than Emacs'.
https://lists.gnu.org/r/emacs-devel/2012-02/msg00649.html

View file

@ -67,7 +67,7 @@ END {
# The following codepoints are not emoji, but they are part of
# emoji sequences. We have code in font.c:font_range that will
# try to display them with the emoji font anyway.
# try to display those sequences with the emoji font anyway.
trigger_codepoints[1] = "261D"
trigger_codepoints[2] = "26F9"
@ -82,6 +82,7 @@ END {
trigger_codepoints[11] = "1F574"
trigger_codepoints[12] = "1F575"
trigger_codepoints[13] = "1F590"
trigger_codepoints[14] = "20E3"
print "(setq auto-composition-emoji-eligible-codepoints"
print "'("

View file

@ -49,6 +49,10 @@ if test "$XCONFIGURE" = "android"; then
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=32"
enable_largefile=no
enable_year2038=no])
# C23 cannot be enabled for Android builds on account of
# incompatibilities in many external dependencies (glib, librsvg,
# etc.) and system headers.
ac_cv_prog_cc_c23=no
fi
dnl Set emacs_config_options to the options of 'configure', quoted for the shell,

View file

@ -1234,18 +1234,23 @@ occur, such as Lisp and Prolog. In such languages, syntactic analysis
alone misses a lot of important information that coders need to reason
about their programs.
@vindex elisp-fontify-semantically
Emacs implements semantic highlighting for Emacs Lisp as an optional
feature of @code{emacs-lisp-mode} (@pxref{Executing Lisp}). To enable
it, customize the option @code{elisp-fontify-semantically} to a
non-@code{nil} value.
Some language servers provide semantic highlighting information, which
Emacs can leverage via its LSP client, Eglot. @xref{Eglot Features,,,
eglot, Eglot: The Emacs LSP Client}.
When this option is enabled, @code{emacs-lisp-mode} analyzes your code
and highlights symbols according to their semantic roles, as part of the
mode's usual Font Lock highlighting (@pxref{Font Lock}). It doesn't
affect the highlighting of strings, comments and other syntactic
elements such as brackets; @code{elisp-fontify-semantically} only
affects highlighting of symbols.
@vindex elisp-fontify-semantically
Additionally, Emacs implements semantic highlighting for Emacs Lisp as
an optional feature of @code{emacs-lisp-mode} (@pxref{Executing Lisp}).
To enable it, customize the option @code{elisp-fontify-semantically} to
a non-@code{nil} value. The rest of this subsection describes the use
of this Emacs Lisp-specific semantic highlighting support.
When @code{elisp-fontify-semantically} is enabled,
@code{emacs-lisp-mode} analyzes your code and highlights symbols
according to their semantic roles, as part of the mode's usual Font Lock
highlighting (@pxref{Font Lock}). It doesn't affect the highlighting of
strings, comments and other syntactic elements such as brackets;
@code{elisp-fontify-semantically} only affects highlighting of symbols.
@cindex symbol role, in semantic analysis
The semantic analysis assigns to each symbol a @dfn{symbol role}, such

View file

@ -877,6 +877,7 @@ Miscellaneous Commands and Features of VC
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
* Preparing Patches:: Preparing and composing patches from within VC.
* VC Auto-Reverting:: Updating buffer contents after VCS operations.
* Rewinding Branches:: Commands to delete revisions from ends of branches.
Customizing VC

View file

@ -1824,8 +1824,15 @@ reverse of the hunk, which changes the ``new'' version into the ``old''
version. If @code{diff-jump-to-old-file} is non-@code{nil}, apply the
hunk to the ``old'' version of the file instead.
@code{diff-apply-hunk} prompts you to confirm deleting files and
applying hunks to backup files, and it offers to reverse-apply hunks
that are already applied. If the region is active, however, it applies
all hunks that the region overlaps without doing any prompting. In this
mode, it simply fails if any hunks do not apply cleanly, and does not
confirm deletions or applying hunks to backup files.
@findex diff-revert-and-kill-hunk
@item C-c M-r
@item C-c M-u
Revert this hunk, and then remove the hunk from the diffs
(@code{diff-revert-and-kill-hunk}). Save the buffer visiting the target
file.

View file

@ -1268,11 +1268,20 @@ Unmark all marked entries (@code{log-view-unmark-all-entries}).
@item C
Copy changes to a currently checked out branch; either the changes from
the revision at point, or the changes from all marked revisions
(@code{log-view-revision-cherry-pick}).
(@code{log-view-cherry-pick}).
@item R
Undo the effects of old revisions; either the revision at point, or all
marked revisions (@code{log-view-revision-revert}).
marked revisions (@code{log-view-revert-or-delete-revisions}).
@item x
Delete revisions newer than the revision at point from the current
branch without touching the working tree
(@code{log-view-uncommit-revisions-from-end}).
@item X
Delete revisions newer than the revision at point from the current
branch (@code{log-view-delete-revisions-from-end}).
@end table
@vindex vc-log-show-limit
@ -1317,8 +1326,14 @@ also prompt for a specific VCS shell command to run for this purpose.
Revert the work file(s) in the current VC fileset to the last revision
(@code{vc-revert}).
@item M-x vc-revision-revert
@item M-x vc-revert-or-delete-revision
Undo the effects of an older commit.
@item M-x vc-revert-revision
Make a new commit which undoes the changes made by an older one.
@item M-x vc-delete-revision
Delete an unpushed commit from the revision history.
@end table
@kindex C-x v u
@ -1342,20 +1357,37 @@ unlocked; you must lock again to resume editing. You can also use
@kbd{C-x v u} to unlock a file if you lock it and then decide not to
change it.
@findex vc-revision-revert
@findex vc-revert-or-delete-revision
@cindex reverting commits
To discard changes that have already been committed, by yourself or
someone else, you can use @w{@kbd{M-x vc-revision-revert}}. This is
called @dfn{reverting} a commit. The command prompts for a revision to
revert, and then the VC backend reverts it. Most backends implement
this by making a new commit which undoes the changes made by the
revision.
someone else, you can use @w{@kbd{M-x vc-revert-or-delete-revision}}.
This is called @dfn{reverting} a commit. The command prompts for a
revision to revert, and then the VC backend reverts it.
An alternative way to access this functionality is to the
@code{log-view-revision-revert} command, bound to @kbd{R} in Log View
mode buffers (@pxref{VC Change Log}). Compared to using @w{@kbd{M-x
vc-revision revert}} directly, this can make it easier to be sure you
are reverting the revision you intend.
Most backends implement this by making a new commit which undoes the
changes made by the revision. For a distributed VCS, if the commit is
one that you made and have not yet pushed, Emacs will offer to delete it
entirely, instead. With a prefix argument, this command will only try
to entirely delete the revision, failing if it has already been pushed.
An alternative way to access this functionality is the
@code{log-view-revert-or-delete-revisions} command, bound to @kbd{R} in
Log View mode buffers (@pxref{VC Change Log}). Compared to using
@w{@kbd{M-x vc-revision revert}} directly, this can make it easier to be
sure you are reverting the revision you intend.
@findex vc-revert-revision
@findex vc-delete-revision
More specific, specialized commands are @w{@kbd{M-x
vc-revert-revision}} and @w{@kbd{M-x vc-delete-revision}}. The first of
these prompts for a revision and then always makes a new commit which
undoes the changes made by that revision, regardless of the VCS in use
and whether or not the revision is pushed. The second command prompts
for a revision and then always deletes it, though it will stop if the
commit has been pushed. Usually @code{vc-revert-or-delete-revision} is
sufficient, but @code{vc-revert-revision} and @code{vc-delete-revision}
can sometimes be useful for constructing particular version control
histories.
@node VC Ignore
@subsection Ignore Version Control Files
@ -1889,7 +1921,7 @@ different revision with @kbd{C-u C-x v v}.
@subsubsection Copying Changes Made By Revisions Between Branches
@table @kbd
@item M-x vc-revision-cherry-pick
@item M-x vc-cherry-pick
Copy a single revision to branch checked out in this working tree.
@end table
@ -1910,25 +1942,25 @@ can then cherry-pick that revision onto the feature-frozen branch in
order to fix the bug there, too. This is called @dfn{backporting} the
revision, or backporting the fix.
@findex vc-revision-cherry-pick
You can use the command @kbd{M-x vc-revision-cherry-pick} to
cherry-pick revisions. It prompts for a revision to cherry-pick. It
then pops up a buffer for you to edit the log message for the new
revision. Normally the VC backend generates a log message including a
reference to the revision you want to copy, so that the copy can be
traced. If you wish, you can delete this reference before typing
@kbd{C-c C-c} to conclude the cherry-pick.
@findex vc-cherry-pick
You can use the command @kbd{M-x vc-cherry-pick} to cherry-pick
revisions. It prompts for a revision to cherry-pick. It then pops up a
buffer for you to edit the log message for the new revision. Normally
the VC backend generates a log message including a reference to the
revision you want to copy, so that the copy can be traced. If you wish,
you can delete this reference before typing @kbd{C-c C-c} to conclude
the cherry-pick.
Alternatively you can invoke the command with a prefix argument,
i.e. @w{@kbd{C-u M-x vc-revision-cherry-pick}}. In this case the log
message from the source revision is used unmodified, and the cherry-pick
happens immediately, without popping up a buffer for log message edits.
i.e. @w{@kbd{C-u M-x vc-cherry-pick}}. In this case the log message
from the source revision is used unmodified, and the cherry-pick happens
immediately, without popping up a buffer for log message edits.
An alternative way to access this functionality is the
@code{log-view-revision-cherry-pick} command, bound to @kbd{C} in Log
View mode buffers (@pxref{VC Change Log}). Compared to using
@w{@kbd{M-x vc-revision-cherry-pick}} directly, this can make it easier
to be sure you are cherry-picking the revision you intend.
@code{log-view-cherry-pick} command, bound to @kbd{C} in Log View mode
buffers (@pxref{VC Change Log}). Compared to using @w{@kbd{M-x
vc-cherry-pick}} directly, this can make it easier to be sure you are
cherry-picking the revision you intend.
@ifnottex
@include vc1-xtra.texi

View file

@ -358,6 +358,10 @@ 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.
Note that @code{package-install} will not suggest to install packages
that are already installed. Similarly, @code{package-upgrade} will only
suggest to upgrade packages for which a newer version is available.
@vindex package-install-upgrade-built-in
By default, @code{package-install} doesn't consider built-in
packages for which new versions are available from the archives. (A

View file

@ -1699,7 +1699,6 @@ count as blocks.
@findex hs-show-region
@findex hs-hide-level
@findex hs-toggle-hiding
@findex hs-toggle-hiding
@kindex C-c @@ C-h
@kindex C-c @@ C-s
@kindex C-c @@ C-c
@ -1736,6 +1735,7 @@ Hide all blocks @var{n} levels below this block
@vindex hs-indicator-maximum-buffer-size
@vindex hs-isearch-open
@vindex hs-hide-block-behavior
@vindex hs-cycle-filter
These variables can be used to customize Hideshow mode:
@table @code
@ -1773,6 +1773,14 @@ performance.) By default, buffers larger than 2MB have the indicators
disabled; the value of @code{nil} will activate the indicators
regardless of the buffer size.
@item hs-cycle-filter
This variable controls where on the line with hideable blocks typing the
@kbd{@key{TAB}} key will cycle the visibility of the blocks. Depending
on its non-@code{nil} value, @key{TAB} can be active on different parts
of such lines. Anywhere else on the line @key{TAB} has its default key
binding. The value @code{nil} means @key{TAB} cannot cycle the
visibility of the blocks anywhere on the heading line.
@item hs-isearch-open
This variable specifies the conditions under which incremental search
should unhide a hidden block when matching text occurs within the

View file

@ -1908,6 +1908,10 @@ made.
to undo all the replacements and go back to where the first
replacement was made.
@item d
to show the diff buffer that changes all occurrences to their
replacements.
@item C-r
to enter a recursive editing level, in case the occurrence needs to be
edited rather than just replaced with @var{newstring}. When you are

View file

@ -21,6 +21,7 @@
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
* Preparing Patches:: Preparing and composing patches from within VC.
* VC Auto-Reverting:: Updating buffer contents after VCS operations.
* Rewinding Branches:: Commands to delete revisions from ends of branches.
@end menu
@node Change Logs and VC
@ -678,6 +679,60 @@ contents, regardless of whether Emacs initiated those operations.
@xref{VC Mode Line}, for details regarding Auto Revert mode in buffers
visiting tracked files (which is what @code{vc-auto-revert-mode} enables).
@node Rewinding Branches
@subsubsection Rewinding Branches
@cindex rewinding a branch (VC)
@table @kbd
@item M-x vc-delete-revisions-from-end
Delete revisions from the end of the current branch.
@item M-x vc-uncommit-revisions-from-end
Delete revisions from the end of the current branch without touching the
working tree.
@end table
@findex vc-delete-revisions-from-end
For decentralized version control systems (@pxref{VCS Repositories}),
these commands provide ways to move the current branch back to an
earlier revision. @code{vc-delete-revisions-from-end} prompts for a
revision, then removes all revisions from the end of the branch up to
but not including the specified revision. We say that the branch is
@dfn{rewound} back to the specified revision.
This command removes the changes made by the revisions from the
working tree. Therefore, if there are any uncommitted changes, they
must be reverted, first (@pxref{VC Undo}). This command will prompt you
to do that if necessary. If you supply a prefix argument, Emacs will
delete uncommitted changes without prompting.
@cindex uncommitting revisions
@findex vc-uncommit-revisions-from-end
To ``uncommit'' a revision means to remove it from the revision
history without removing its changes from the working tree. It is as
though you had made the changes but had not yet checked them in. The
command @code{vc-uncommit-revisions-from-end} prompts for a revision,
and then uncommits all revisions from the end of the branch up to but
not including the specified revision. The branch is rewound back to the
specified revision but the changes are left behind in the working tree.
When rewinding the current branch, if all the revisions deleted from
the revision history are among those you have pulled or pushed, then
these operations do not permanently delete anything: a simple
@w{@kbd{C-x v +}} (@pxref{Pulling / Pushing}) will bring the revisions
back. On the other hand, if there are new revisions on the end of the
branch that have not yet been pushed, then these commands will delete
them permanently. Emacs tries to detect this situation and ask you if
you are sure you want to delete them.
Alternative ways to access this functionality are the
@code{log-view-uncommit-revisions-from-end} and
@code{log-view-delete-revisions-from-end} commands, bound to @kbd{x} and
@kbd{X}, respectively, in Log View mode buffers (@pxref{VC Change Log}).
Compared to using the commands described here directly, the Log View
mode commands can make it easier to be sure you are rewinding back to
the revision you intend.
@node Customizing VC
@subsection Customizing VC

View file

@ -2611,7 +2611,9 @@ Sets the background transparency of the frame. Unlike the @code{alpha}
frame parameter, this only controls the transparency of the background
while keeping foreground elements such as text fully opaque. It
should be an integer between 0 and 100, where 0 means
completely transparent and 100 means completely opaque (default).
completely transparent and 100 means completely opaque (default). The
value can also be a float between 0 and 1.0, where 1.0 means completely
opaque.
@vindex borders-respect-alpha-background@r{, a frame parameter}
@item borders-respect-alpha-background

View file

@ -1331,11 +1331,12 @@ lexical binding is enabled if the @var{lexical} argument to
@findex eval-expression@r{, and }lexical-binding
Lexical binding is also enabled in Lisp Interaction and IELM mode,
used in the @file{*scratch*} and @file{*ielm*} buffers, and also when
evaluating expressions via @kbd{M-:} (@code{eval-expression}) and when
processing the @option{--eval} command-line options of Emacs
(@pxref{Action Arguments,,, emacs, The GNU Emacs Manual}) and
@command{emacsclient} (@pxref{emacsclient Options,,, emacs, The GNU
Emacs Manual}).
evaluating expressions via @kbd{M-:} (@code{eval-expression}), when
processing the @option{--eval}, @option{-x}, and @option{--script}
command-line options of Emacs (@pxref{Action Arguments,,, emacs, The GNU
Emacs Manual}), and when processing the @option{--eval} command-line
option of @command{emacsclient} (@pxref{emacsclient Options,,, emacs,
The GNU Emacs Manual}).
@node Converting to Lexical Binding
@subsection Converting to Lexical Binding

View file

@ -7068,9 +7068,10 @@ not use markers for sampling positions like @code{window-point} or
@code{window-start}. This argument should be non-@code{nil} when the
state will be written to disk and read back in another session.
Together, the argument @var{writable} and the variable
Together, @var{writable} and the variable
@code{window-persistent-parameters} specify which window parameters are
saved by this function. @xref{Window Parameters}.
saved by this function. The default is to save the @code{clone-of}
parameter if @var{writable} is @code{nil}. @xref{Window Parameters}.
@vindex window-state-normalize-buffer-name
Bind @code{window-state-normalize-buffer-name} to non-@code{nil} to
@ -7085,14 +7086,19 @@ and read back in another session. In either case, use the following
function to restore the state of the window.
@defun window-state-put state &optional window ignore
This function puts the window state @var{state} into @var{window}.
The argument @var{state} should be the state of a window returned by
an earlier invocation of @code{window-state-get}, see above. The
optional argument @var{window} can be either a live window or an
internal window (@pxref{Windows and Frames}). If @var{window} is not
a live window, it is replaced by a new live window created on the same
frame before putting @var{state} into it. If @var{window} is @code{nil},
it puts the window state into a new window.
This function puts the window state @var{state} into @var{window}. The
argument @var{state} should be the state of a window returned by an
earlier invocation of @code{window-state-get}, see above. The optional
argument @var{window} can be either a live window or an internal window
(@pxref{Windows and Frames}). If @var{window} is not a live window, it
is replaced by a new live window created on the same frame before
putting @var{state} into it. If @var{window} is @code{nil}, it puts the
window state into a new window.
This function assigns all window parameters that have been stored in
@var{state}. By default, this is the @code{clone-of} parameter provided
@var{state} was obtained from an invocation of @code{window-state-get}
with the argument @var{writable} @code{nil}. @xref{Window Parameters}.
This function consults the variable
@code{window-restore-killed-buffer-windows} (see below) when it tries to
@ -7330,9 +7336,10 @@ specific window.
@item clone-of
@vindex clone-of@r{, a window parameter}
This parameter specifies the window that this one has been cloned
from. It is installed by @code{window-state-get} (@pxref{Window
Configurations}).
This parameter specifies the window that this one has been cloned from.
It is persistent by default and as such gets saved by
@code{window-state-get} and installed by @code{window-state-put}
(@pxref{Window Configurations}).
@item window-preserved-size
@vindex window-preserved-size@r{, a window parameter}

View file

@ -422,21 +422,21 @@ enhances diagnostics with interactive server-suggested fixes (so-called
@item
Finding definitions and uses of identifiers, via Xref (@pxref{Xref,,,
emacs, GNU Emacs Manual}). Eglot provides a backend for the Xref
capabilities which uses the language-server understanding of the program
source. In particular, it eliminates the need to generate tags tables
(@pxref{Tags tables,,, emacs, GNU Emacs Manual}) for languages which are
only supported by the @code{etags} backend.
capabilities which uses the language server's understanding of the
program source. In particular, it eliminates the need to generate tags
tables (@pxref{Tags tables,,, emacs, GNU Emacs Manual}) for languages
which are only supported by the @code{etags} backend.
@item
Buffer navigation by name of function, class, method, etc., via Imenu
(@pxref{Imenu,,, emacs, GNU Emacs Manual}). Eglot provides its own
variant of @code{imenu-create-index-function}, which generates the index
for the buffer based on language-server program source analysis.
for the buffer based on the language server's program source analysis.
@item
Enhanced completion of symbol at point by the @code{completion-at-point}
command (@pxref{Symbol Completion,,, emacs, GNU Emacs Manual}). This
uses the language-server's parser data for the completion candidates.
uses the language server's parser data for the completion candidates.
@item
Server-suggested code refactorings. The ElDoc package is also leveraged
@ -452,6 +452,13 @@ be it the type of a variable, or the name of a formal parameter in a
function call. @xref{Eglot Commands}, and the
@code{eglot-inlay-hints-mode} minor mode.
@item
Enhanced source code fontification via LSP @dfn{semantic tokens}. Eglot
can leverage the language server's understanding of the role and meaning
of identifiers in the code to provide more accurate syntax highlighting.
@xref{Eglot Commands}, and the @code{eglot-semantic-tokens-mode} minor
mode.
@item
Display of function call and type hierarchies via the
@code{eglot-show-call-hierarchy} and @code{eglot-show-type-hierarchy}
@ -466,7 +473,7 @@ supported and is activated automatically as you type.
If a completion package such as the Company package (a popular
third-party completion package providing @code{company-mode}), is
installed, Eglot enhances it by providing completion candidates based on
the language-server analysis of the source code. (Company can be
the language server's analysis of the source code. (Company can be
installed from GNU ELPA.)
@item
@ -501,7 +508,8 @@ capabilities to Emacs users. However, @xref{Extending Eglot}.
Finally, it's worth noting that, by default, Eglot generally turns on
all features that it @emph{can} turn on. It's possible to opt out of
some features via user options (@pxref{Customizing Eglot}) and a hook
features via the @code{eglot-ignored-server-capabilities} user option
(@pxref{Customizing Eglot}) and the @code{eglot-managed-mode-hook} hook
that runs after Eglot starts managing a buffer (@pxref{Eglot and
Buffers}).
@ -515,14 +523,14 @@ One of the main strong points of using a language server is that a
language server has a broad view of the program: it considers more than
just the single source file you are editing. Ideally, the language
server should know about all the source files of your program which are
written in the language supported by the server. In the language-server
parlance, the set of the source files of a program is known as a
@dfn{workspace}. The Emacs equivalent of a workspace is a @dfn{project}
(@pxref{Projects,,, emacs, GNU Emacs Manual}). Eglot fully supports
Emacs projects, and considers the file in whose buffer Eglot is turned
on as belonging to a project. In the simplest case, that file is the
entire project, i.e.@: your project consists of a single file. But
there are other more complex projects:
written in the language supported by the server. In LSP parlance, the
set of the source files of a program is known as a @dfn{workspace}. The
Emacs equivalent of a workspace is a @dfn{project} (@pxref{Projects,,,
emacs, GNU Emacs Manual}). Eglot fully supports Emacs projects, and
considers the file in whose buffer Eglot is turned on as belonging to a
project. In the simplest case, that file is the entire project, i.e.@:
your project consists of a single file. But there are other more
complex projects:
@itemize @bullet
@item
@ -572,7 +580,7 @@ specially in several ways:
@vindex eglot-menu
@item
All of the project's file-visiting buffers under the same major-mode are
served by a single language-server connection. (If the project uses
served by a single language server connection. (If the project uses
several programming languages, there will usually be a separate server
connection for each group of files written in the same language and
using the same Emacs major-mode.) Eglot adds the
@ -631,6 +639,17 @@ minor mode is turned on and when it's turned off; use the function
or not.
@end itemize
For example, to turn off @dfn{inlay hints} and @dfn{semantic tokens} by
default but still retain the ability to turn them on again
interactively use this:
@lisp
(add-hook 'eglot-managed-mode-hook
(lambda ()
(eglot-inlay-hints-mode -1)
(eglot-semantic-tokens-mode -1)))
@end lisp
@node Eglot Commands
@section Eglot Commands
@cindex commands, Eglot
@ -655,7 +674,7 @@ major mode to use and for the server program to start. If invoked with
If the language server is successfully started and contacted, this
command arranges for any other buffers belonging to the same project and
using the same major mode to use the same language-server session. That
using the same major mode to use the same language server session. That
includes any buffers created by visiting files after this command
succeeds to connect to a language server.
@ -698,7 +717,7 @@ language server of the current buffer to implement the renaming.
@item M-x eglot-format
This command reformats the active region according to the
language-server rules. If no region is active, it reformats the entire
language server rules. If no region is active, it reformats the entire
current buffer.
@item M-x eglot-format-buffer
@ -744,6 +763,29 @@ serve hints about positional parameter names in function calls and a
variable's automatically deduced type. Inlay hints help the user not
have to remember these things by heart.
@cindex semantic tokens
@item M-x eglot-semantic-tokens-mode
This command toggles LSP @dfn{semantic tokens} fontification on and off
for the current buffer. Semantic tokens provide enhanced syntax
highlighting based on the language server's semantic analysis of the
code, going beyond traditional regular-expression-based fontification.
For example, the server can distinguish between different kinds of
variables (parameters, local variables, fields) or indicate whether a
function is being declared or called.
@vindex eglot-semantic-token-types
@vindex eglot-semantic-token-modifiers
The @code{eglot-semantic-faces} customization group contains the user
options @code{eglot-semantic-token-types} and
@code{eglot-semantic-token-modifiers}, which control which semantic
token types and modifiers reported by the language server Eglot should
consider when fontifying. For performance reasons, the server
connection has to be restarted before changes take effect.
@cindex semantic token faces
The @code{eglot-semantic-faces} customization group also contains the
face definitions for controlling the appearance of each token.
@cindex type hierarchy
@item M-x eglot-show-type-hierarchy
Pop up a special buffer showing a interactive tree which represents a

View file

@ -25,13 +25,13 @@ General Public License for more details.
@dircategory Emacs misc features
@direntry
* Transient: (transient). Transient Commands.
* Transient: (transient). Transient Commands.
@end direntry
@finalout
@titlepage
@title Transient User and Developer Manual
@subtitle for version 0.10.1
@subtitle for version 0.11.0
@author Jonas Bernoulli
@page
@vskip 0pt plus 1filll
@ -53,7 +53,7 @@ resource to get over that hurdle is Psionic K's interactive tutorial,
available at @uref{https://github.com/positron-solutions/transient-showcase}.
@noindent
This manual is for Transient version 0.10.1.
This manual is for Transient version 0.11.0.
@insertcopying
@end ifnottex
@ -385,7 +385,7 @@ than outlined above and even customizable.}
If the user does not save the value and just exits using a regular
suffix command, then the value is merely saved to the transient's
history. That value won't be used when the transient is next invoked,
but it is easily accessible (@pxref{Using History}).
but it is easily accessible (see @ref{Using History}).
Option @code{transient-common-command-prefix} controls the prefix key used
in the following bindings. For simplicity's sake the default, @kbd{C-x},
@ -454,8 +454,8 @@ previously used values. Usually the same keys as those mentioned
above are bound to those commands.
Authors of transients should arrange for different infix commands that
read the same kind of value to also use the same history key
(@pxref{Suffix Slots}).
read the same kind of value to also use the same history key (see
@ref{Suffix Slots}).
Both kinds of history are saved to a file when Emacs is exited.
@ -785,7 +785,7 @@ menu buffer. The menu buffer is displayed in a window using
The value of this option has the form @code{(@var{FUNCTION} . @var{ALIST})},
where @var{FUNCTION} is a function or a list of functions. Each such
function should accept two arguments: a buffer to display and an
alist of the same form as @var{ALIST}. @xref{Choosing Window,,,elisp,},
alist of the same form as @var{ALIST}. See @ref{Choosing Window,,,elisp,},
for details.
The default is:
@ -799,7 +799,7 @@ The default is:
This displays the window at the bottom of the selected frame.
For alternatives see @ref{Buffer Display Action Functions,,,elisp,},
and @xref{Buffer Display Action Alists,,,elisp,}.
and @ref{Buffer Display Action Alists,,,elisp,}.
When you switch to a different ACTION, you should keep the ALIST
entries for @code{dedicated} and @code{inhibit-same-window} in most cases.
@ -861,7 +861,7 @@ used to draw the line.
This user option may be overridden if @code{:mode-line-format} is passed
when creating a new prefix with @code{transient-define-prefix}.
Otherwise this can be any mode-line format. @xref{Mode Line Format,,,elisp,}, for details.
Otherwise this can be any mode-line format. See @ref{Mode Line Format,,,elisp,}, for details.
@end defopt
@defopt transient-semantic-coloring
@ -879,6 +879,9 @@ This option controls whether key bindings of infix commands that do
not match the respective command-line argument should be highlighted.
For other infix commands this option has no effect.
This is mostly indended for autors of transient menus and disabled
by default.
When this option is non-@code{nil}, the key binding for an infix argument
is highlighted when only a long argument (e.g., @code{--verbose}) is
specified but no shorthand (e.g., @code{-v}). In the rare case that a
@ -1026,10 +1029,10 @@ which can be included in multiple prefixes. See TODO@.
as expected by @code{transient-define-prefix}. Note that an infix is a
special kind of suffix. Depending on context ``suffixes'' means
``suffixes (including infixes)'' or ``non-infix suffixes''. Here it
means the former. @xref{Suffix Specifications}.
means the former. See @ref{Suffix Specifications}.
@var{SUFFIX} may also be a group in the same form as expected by
@code{transient-define-prefix}. @xref{Group Specifications}.
@code{transient-define-prefix}. See @ref{Group Specifications}.
@item
@var{LOC} is a key description (a string as returned by @code{key-description}
@ -1053,11 +1056,11 @@ the function @code{transient--get-layout}.
These functions operate on the information stored in the
@code{transient--layout} property of the @var{PREFIX} symbol. Elements in that
tree are not objects but have the form @code{(@var{CLASS} @var{PLIST}) for suffixes} and
[CLASS PLIST CHILDREN] for groups. At the root of the tree is an
element [N nil CHILDREN], where N is the version of the layout format,
@code{[CLASS PLIST CHILDREN]} for groups. At the root of the tree is an
element @code{[N Nil CHILDREN]}, where @code{N} is the version of the layout format,
currently and hopefully for a long time 2. While that element looks
like a group vector, that element does not count when identifying a
group using a coordinate vector, i.e., [0] is its first child, not the
group using a coordinate vector, i.e., @code{[0]} is its first child, not the
root element itself.
@defun transient-insert-suffix prefix loc suffix &optional keep-other
@ -1202,14 +1205,14 @@ enabled. One benefit of the Transient interface is that it remembers
history not only on a global level (``this command was invoked using
these arguments, and previously it was invoked using those other
arguments''), but also remembers the values of individual arguments
independently. @xref{Using History}.
independently. See @ref{Using History}.
After a transient prefix command is invoked, @kbd{C-h @var{KEY}} can be used to
show the documentation for the infix or suffix command that @kbd{@var{KEY}} is
bound to (see @ref{Getting Help for Suffix Commands}), and infixes and
suffixes can be removed from the transient using @kbd{C-x l @var{KEY}}. Infixes
and suffixes that are disabled by default can be enabled the same way.
@xref{Enabling and Disabling Suffixes}.
See @ref{Enabling and Disabling Suffixes}.
Transient ships with support for a few different types of specialized
infix commands. A command that sets a command line option, for example,
@ -1260,7 +1263,7 @@ explicitly.
@var{GROUP}s add key bindings for infix and suffix commands and specify
how these bindings are presented in the menu buffer. At least one
@var{GROUP} has to be specified. @xref{Binding Suffix and Infix Commands}.
@var{GROUP} has to be specified. See @ref{Binding Suffix and Infix Commands}.
The @var{BODY} is optional. If it is omitted, then @var{ARGLIST} is ignored and
the function definition becomes:
@ -1311,13 +1314,11 @@ GROUPs have the same form as for @code{transient-define-prefix}.
@section Binding Suffix and Infix Commands
The macro @code{transient-define-prefix} is used to define a transient.
This defines the actual transient prefix command (@pxref{Defining
Transients}) and adds the transient's infix and suffix bindings, as
This defines the actual transient prefix command (see @ref{Defining Transients}) and adds the transient's infix and suffix bindings, as
described below.
Users and third-party packages can add additional bindings using
functions such as @code{transient-insert-suffix} (@pxref{Modifying Existing Transients}).
These functions take a ``suffix specification'' as one of
functions such as @code{transient-insert-suffix} (see @ref{Modifying Existing Transients}). These functions take a ``suffix specification'' as one of
their arguments, which has the same form as the specifications used in
@code{transient-define-prefix}.
@ -1343,13 +1344,10 @@ brackets to do the latter.
Group specifications then have this form:
@lisp
[@{@var{LEVEL}@} @{@var{DESCRIPTION}@}
@{@var{KEYWORD} @var{VALUE}@}...
@var{ELEMENT}...]
[@{LEVEL@} @{DESCRIPTION@} @{KEYWORD VALUE@}... ELEMENT...]
@end lisp
The @var{LEVEL} is optional and defaults to 4. @xref{Enabling and
Disabling Suffixes}.
The @var{LEVEL} is optional and defaults to 4. See @ref{Enabling and Disabling Suffixes}.
The @var{DESCRIPTION} is optional. If present, it is used as the heading of
the group.
@ -1500,9 +1498,7 @@ suffixes''. Here it means the former.
Suffix specifications have this form:
@lisp
([@var{LEVEL}]
[@var{KEY} [@var{DESCRIPTION}]]
@var{COMMAND}|@var{ARGUMENT} [@var{KEYWORD} @var{VALUE}]...)
([LEVEL] [KEY [DESCRIPTION]] COMMAND|ARGUMENT [KEYWORD VALUE]...)
@end lisp
@var{LEVEL}, @var{KEY} and @var{DESCRIPTION} can also be specified using the @var{KEYWORD}s
@ -1513,8 +1509,8 @@ the object's values just for the binding inside this transient.
@itemize
@item
@var{LEVEL} is the suffix level, an integer between 1 and 7.
@xref{Enabling and Disabling Suffixes}.
@var{LEVEL} is the suffix level, an integer between 1 and 7. See
@ref{Enabling and Disabling Suffixes}.
@item
KEY is the key binding, a string in the format returned by
@ -1588,7 +1584,7 @@ guessed based on the long argument. If the argument ends with @samp{=}
Finally, details can be specified using optional @var{KEYWORD}-@var{VALUE} pairs.
Each keyword has to be a keyword symbol, either @code{:class} or a keyword
argument supported by the constructor of that class. @xref{Suffix Slots}.
argument supported by the constructor of that class. See @ref{Suffix Slots}.
If a keyword argument accepts a function as value, you an use a @code{lambda}
expression. As a special case, the @code{##} macro (which returns a @code{lambda}
@ -1742,16 +1738,16 @@ its value can be accessed using @code{transient-args}.
This function returns the scope of the active or current transient
prefix command.
If optional PREFIXES and CLASSES are both nil, return the scope of
If optional PREFIXES and CLASSES are both @code{nil}, return the scope of
the prefix currently being setup, making this variation useful, e.g.,
in @code{:if*} predicates. If no prefix is being setup, but the current
command was invoked from some prefix, then return the scope of that.
If PREFIXES is non-nil, it must be a prefix command or a list of such
commands. If CLASSES is non-nil, it must be a prefix class or a list
If PREFIXES is non-@code{nil}, it must be a prefix command or a list of such
commands. If CLASSES is non-@code{nil}, it must be a prefix class or a list
of such classes. When this function is called from the body or the
@code{interactive} form of a suffix command, PREFIXES and/or CLASSES should
be non-nil. If either is non-nil, try the following in order:
be non-@code{nil}. If either is non-@code{nil}, try the following in order:
@itemize
@item
@ -1777,7 +1773,7 @@ PREFIXES@. This only works if that slot is set in the respective
class definition or using its `transient-init-scope' method.
@end itemize
If no prefix matches, return nil.
If no prefix matches, return @code{nil}.
@end defun
@node Current Suffix Command
@ -1938,8 +1934,8 @@ means that all outer prefixes are exited at once.
@item
The behavior for non-suffixes can be set for a particular prefix,
by the prefix's @code{transient-non-suffix} slot to a boolean, a suitable
pre-command function, or a shorthand for such a function.
@xref{Pre-commands for Non-Suffixes}.
pre-command function, or a shorthand for such a function. See
@ref{Pre-commands for Non-Suffixes}.
@item
The common behavior for the suffixes of a particular prefix can be
@ -2279,7 +2275,7 @@ object should not affect later invocations.
@item
All suffix and infix classes derive from @code{transient-suffix}, which in
turn derives from @code{transient-child}, from which @code{transient-group} also
derives (@pxref{Group Classes}).
derives (see @ref{Group Classes}).
@item
All infix classes derive from the abstract @code{transient-infix} class,
@ -2293,7 +2289,7 @@ that does not do so. If you do that then you get to implement many
methods.
Also, infixes and non-infix suffixes are usually defined using
different macros (@pxref{Defining Suffix and Infix Commands}).
different macros (see @ref{Defining Suffix and Infix Commands}).
@item
Classes used for infix commands that represent arguments should
@ -2703,7 +2699,7 @@ secondary value, called a ``scope''. See @code{transient-define-prefix}.
@code{transient-suffix}, @code{transient-non-suffix} and @code{transient-switch-frame}
play a part when determining whether the currently active transient
prefix command remains active/transient when a suffix or arbitrary
non-suffix command is invoked. @xref{Transient State}.
non-suffix command is invoked. See @ref{Transient State}.
@item
@code{refresh-suffixes} Normally suffix objects and keymaps are only setup
@ -2785,7 +2781,7 @@ of the same symbol.
@item
@code{level} The level of the prefix commands. The suffix commands whose
layer is equal or lower are displayed. @pxref{Enabling and Disabling Suffixes}.
layer is equal or lower are displayed. See @ref{Enabling and Disabling Suffixes}.
@item
@code{value} The likely outdated value of the prefix. Instead of accessing
@ -2843,7 +2839,7 @@ which is useful for alignment purposes.
@code{command} The command, a symbol.
@item
@code{transient} Whether to stay transient. @xref{Transient State}.
@code{transient} Whether to stay transient. See @ref{Transient State}.
@item
@code{format} The format used to display the suffix in the menu buffer.
@ -2886,7 +2882,7 @@ defining a command using @code{transient-define-suffix}.
The following two slots are experimental. They can also be set for a
group, in which case they apply to all suffixes in that group, except
for suffixes that set the same slot to a non-nil value.
for suffixes that set the same slot to a non-@code{nil} value.
@itemize
@item
@ -2897,7 +2893,7 @@ advice.
@item
@code{advice*} A function used to advise the command. Unlike @code{advice}, this
advises not only the command body but also its @code{interactive} spec. If
both slots are non-nil, @code{advice} is used for the body and @code{advice*} is
both slots are non-@code{nil}, @code{advice} is used for the body and @code{advice*} is
used for the @code{interactive} form. When advising the @code{interactive} spec,
called using @code{(funcall advice #'advice-eval-interactive-spec spec)}.
@end itemize
@ -3067,14 +3063,14 @@ currently cannot be invoked.
By default these predicates run when the prefix command is invoked,
but this can be changes, using the @code{refresh-suffixes} prefix slot.
@xref{Prefix Slots}.
See @ref{Prefix Slots}.
One more slot is shared between group and suffix classes, @code{level}. Like
the slots documented above, it is a predicate, but it is used for a
different purpose. The value has to be an integer between 1
and 7. @code{level} controls whether a suffix or a group should be
available depending on user preference.
@xref{Enabling and Disabling Suffixes}.
See @ref{Enabling and Disabling Suffixes}.
@node FAQ
@appendix FAQ

View file

@ -17,6 +17,19 @@ This refers to https://github.com/joaotavora/eglot/issues/. That is,
to look up issue github#1234, go to
https://github.com/joaotavora/eglot/issues/1234.
* Changes to upcoming Eglot
** Support for semantic tokens (bug#79374)
The new minor mode 'eglot-semantic-tokens-mode' provides enhanced syntax
highlighting based on the language server's analysis, going beyond
traditional regular-expression-based fontification. The
'eglot-semantic-faces' customization group contains options for
controlling which token types and modifiers to consider, as well as
faces for customizing their appearance. The minor mode is on by
default: consult the manual on how to turn it off.
* Changes in Eglot 1.19 (23/10/2025)

220
etc/NEWS
View file

@ -392,10 +392,10 @@ for which you can use '(category . tex-shell)'.
+++
*** New user option 'split-window-preferred-direction'.
Users can now choose in which direction Emacs tries to split first:
vertical or horizontal. With this new setting, when the frame is in
landscape shape for instance, Emacs could split horizontally before
splitting vertically. The default setting preserves Emacs historical
behavior to try to split vertically first.
vertically or horizontally. The new default is to prefer to split
horizontally if the frame is landscape and vertically if it is portrait.
You can customize this option to 'vertical' to restore Emacs's old
behavior of always preferring vertical splits.
+++
*** New argument INDIRECT for 'get-buffer-window-list'.
@ -445,7 +445,7 @@ useful on tiling window managers where the initial frame size should be
specified by external means.
+++
*** New option 'alter-fullscreen-frames'.
*** New user option 'alter-fullscreen-frames'.
This option is useful to maintain a consistent state when attempting to
resize fullscreen frames. It defaults to 'inhibit' on NS builds which
means that a fullscreen frame would not change size. It defaults to nil
@ -455,8 +455,8 @@ keep the frame size unchanged. The value t means to first reset the
fullscreen status and then resize the frame.
---
*** Frames can now be renamed to F<number> on text terminals.
Unlike with other frame names, an attempt to rename to F<number> throws
*** Frames can now be renamed to "F<number>" on text terminals.
Unlike with other frame names, an attempt to rename to "F<number>" throws
an error when a frame of that name already exists.
** Mode Line
@ -857,6 +857,13 @@ you could already use 'C-u C-x C-n' to clear the goal column.
* Changes in Specialized Modes and Packages in Emacs 31.1
** Editorconfig
---
*** 'editorconfig-apply' is declared obsolete.
You can now use 'editorconfig-display-current-properties' without having
to call 'editorconfig-apply'.
** Auth Source
+++
@ -1062,16 +1069,16 @@ rather than a language, and it is now possible to select a local parser
at point to explore.
+++
*** Tree-sitter query predicate :equal, :match, and :pred are deprecated
Use :eq?, :match?, :pred? instead. The change is because newer
tree-sitter library mandates query predicates to end with question mark.
Emacs will transparently converts :equal, :match and :pred to :eq?,
:match? and :pred?, respectively, so existing queries still work fine
with latest tree-sitter library. Predicate :equal is changed to :eq? to
better follow tree-sitters convention. Also, the :match? predicates
can now take the regexp as either the first or second argument, so it
works with both tree-sitter convention (regexp arg second) and Emacs
convention (regexp arg first).
*** Tree-sitter query predicates ':equal', ':match', and ':pred' are deprecated.
Use ':eq?', ':match?', and ':pred?' instead. The change is because
newer tree-sitter libraries mandate query predicates to end with a
question mark. Emacs will transparently convert ':equal', ':match', and
':pred' to ':eq?', ':match?', and ':pred?', respectively, so existing
queries still work fine with the latest tree-sitter library. The
predicate ':equal' is changed to ':eq?' to better follow tree-sitters
convention. Also, the ':match?' predicate can now take the regexp as
either the first or second argument, so it works with both tree-sitter
convention (regexp arg second) and Emacs convention (regexp arg first).
** Hideshow
@ -1112,6 +1119,11 @@ should hide a block. If set to 'after-bol', hide the innermost block to
which the current line belongs. If set to 'after-cursor', hide the block
after cursor position. By default this is set to 'after-bol'.
+++
*** New user option 'hs-cycle-filter' for visibility-cycling with 'TAB'.
This user option controls the positions on the headline of hideable blocks
where the 'TAB' key cycles the blocks' visibility.
+++
*** The variable 'hs-special-modes-alist' is now obsolete.
Instead of customizing Hideshow for a mode by setting the elements of
@ -1294,6 +1306,13 @@ The prompts 'opstring' and 'active-opstring' can now either be strings
or functions. This is useful when your prompts can benefit from dynamic
content.
---
*** New Ibuffer-dedicated faces.
New faces 'ibuffer-marked', 'ibuffer-deletion', 'ibuffer-title', and
'ibuffer-filter-group-name'. By default they inherit from the
general-purpose faces Ibuffer previously used, to preserve previous
behavior.
** ElDoc
---
@ -1989,11 +2008,15 @@ This can be used by external ELPA packages for performance optimizations
in special cases. For more information, see "(tramp) New operations" in
the Tramp manual.
** Isearch and Replace
*** Typing 'd' during 'query-replace' shows the diff buffer with replacements.
** Diff
---
*** 'diff-mode' now refrains from automatically refining big hunks.
What is big is defined by the new 'diff-refine-threshold' variable.
What is big is defined by the new 'diff-refine-threshold' user option.
---
*** New command 'diff-kill-ring-save'.
@ -2003,7 +2026,7 @@ to the original text. If the selected range extends a hunk, the
command attempts to look up and copy the text in between the hunks.
+++
*** New command 'diff-revert-and-kill-hunk' bound to 'C-c M-r'.
*** New command 'diff-revert-and-kill-hunk' bound to 'u' and 'C-c M-u'.
This command reverts the hunk at point (i.e., applies the reverse of the
hunk), and then removes the hunk from the diffs.
This is useful to undo or revert changes, committed and uncommitted, when
@ -2022,19 +2045,22 @@ useful to prepare a "*vc-diff*" buffer for committing a single hunk.
When the region is active, it deletes all hunks that the region does not
overlap.
*** 'diff-apply-hunk' now supports creating and deleting files.
---
*** 'vc-version-diff' and 'vc-root-version-diff' changed default for REV1.
They suggest the previous revision as the default for REV1, not the last
one as before. This makes them different from 'vc-diff' and
'vc-root-diff' when those are called without a prefix argument.
*** 'diff-apply-hunk' now supports creating and deleting files.
+++
*** 'diff-apply-buffer' now considers the region and can reverse-apply.
If the region is active, this command now applies all hunks that the
region overlaps; otherwise, it applies all hunks.
With a prefix argument, it now reverse-applies the hunks.
*** 'diff-apply-hunk' and 'diff-apply-buffer' now consider the region.
If the region is active, these commands now apply all hunks that the
region overlaps. Otherwise, they have their existing behavior.
+++
*** 'diff-apply-buffer' can reverse-apply.
With a prefix argument, it now reverse-applies hunks.
This matches the existing prefix argument to 'diff-apply-hunk'.
** Ediff
@ -2261,6 +2287,11 @@ string instead of preprending it and 'tmm-mid-prompt' to said entry.
** Foldout
*** Improved behavior of 'foldout-exit-fold' with negative prefix argument.
When 'foldout-exit-fold' is called with a negative argument (so that the
exited fold remains visible), the position of point and window view are
preserved.
---
*** New command 'foldout-widen-to-current-fold'.
This command widens the view to the current fold level when in a fold,
@ -2358,11 +2389,19 @@ the contents of those files.
+++
*** New commands to cherry-pick and revert revisions.
The commands 'vc-revision-cherry-pick' and 'vc-revision-revert' let you
copy revisions between branches, and revert revisions.
The commands 'vc-cherry-pick', 'vc-revert-or-delete-revision',
'vc-revert-revision' and 'vc-delete-revision' let you copy revisions
between branches, revert and delete revisions.
From Log View buffers, you can use 'C' to cherry-pick the revision at
point or all marked revisions, and 'R' to revert the revision at point
or all marked revisions.
point or all marked revisions, and 'R' to undo the revision at point or
all marked revisions.
+++
*** New commands to rewind branches.
In Log View mode, 'x' deletes revisions newer than the revision at point
from the history of the current branch, though without undoing the
changes made by those revisions to the working tree. 'X' is similar
except that it does remove the changes from the working tree.
*** New command 'log-edit-done-strip-cvs-lines'.
This command strips all lines beginning with "CVS:" from the buffer.
@ -2537,6 +2576,9 @@ View mode, copies to the kill ring the ID of the revision at point in
the log entry. If there are marked revisions, it copies the IDs of
those, instead.
---
*** New command alias 'vc-restore' for 'vc-revert'.
** Package
+++
@ -2732,7 +2774,7 @@ New faces have been added to 'icomplete-vertical-mode':
Useful to delay initialization to the end of the file, so it can use
functions defined later than the variable, as is common for minor modes.
'define-globalized-minor-mode' now automatically uses it if the
init-value is non-nil.
':init-value' is non-nil.
---
*** New major mode 'Customize-dirlocals-mode'.
@ -2748,6 +2790,16 @@ determined by the new user option 'pulse-face-duration'.
** Miscellaneous
---
*** The first client frame now shows warnings from daemon startup.
When there are warnings emitted during Emacs startup, usually due to
problems in your initialization file, these are shown in a "*Warnings*"
buffer. Until now such warnings were not made visible in the case that
Emacs was started as a daemon. Now the first frame after daemon startup
will show the "*Warnings*" buffer. So for example, starting Emacs with
a command like 'emacsclient -a"" -c' will now show "*Warnings*" just
like a plain invocation of 'emacs' would.
---
*** 'tooltip-mode' now shows tooltips after delay on TTY frames.
Display of tooltips on text-only terminals now happens after
@ -2883,8 +2935,8 @@ The tabulated listings produced by 'flymake-show-buffer-diagnostics' and
widths based on content, optimizing display space and readability.
*** New value 'auto' of user option 'flymake-indicator-type'.
This value set by default tries to use fringes if possible,
otherwise falls back to margins.
This value (set by default) tries to use fringes if possible, otherwise
falls back to margins.
*** New user option 'elisp-flymake-byte-compile-executable'.
This allows customizing the Emacs executable used for Flymake byte
@ -3008,90 +3060,45 @@ recognizes the new functions "all" and "any".
See https://perldoc.perl.org/5.42.0/perldelta for details.
** Zone
Zone can scramble multiple windows across multiple frames; it may also
reorganize frames to be a single window. As before, when a key or mouse
event occurs, all of the frames and windows are restored to their
original state. This is controlled by three new customization flags
which control the use of frames and windows beyond the currently active
ones. It is identifies suitable buffers for zoning out so that
potentially important buffer contents are not exposed.
original state. This is controlled by three new user options which
control the use of frames and windows beyond the currently active ones.
It identifies suitable buffers for zoning out so that potentially
important buffer contents are not exposed.
When a zone program encounters an error, it will apologize for a minute
and then start a new round of zoning. Previously, it just kept
apologizing. Finally, zone does not pollute the *Messages* buffer with
extraneous messages.
**** New function 'zone-add-program'
This function accepts a symbol, whose name starts with "zone-pgm-", that
runs a zone program when 'zone' is invoked. It adds the program to the
'zone-programs' vector if it is not already present.''
**** New functipon 'zone-remove-program'
This function removes a program from the 'zone-programs' vector. If the
parameter is a symbol, and the symbol is present in the vector, it is
removed. If the parameter is a string, it is a regular expression that
will remove any programs whose name matches the parameter pattern.
*** Multi-window and -frame customization options
Prior to this update, zone would only (safely) scramble the contents of
the current window on the current frame. Now, with the use of these
three options, it is possible to scramble to contents of all windows
across all frames. It is also possible to make frames single window
displays while zoning. But when zoning is interrupted by a key- or
mouse-press, the original window layout across all frames is restored.
**** New user option 'zone-delete-other-windows'
*** New user option 'zone-delete-other-windows'.
When non-nil, the frame is made into a single full frame window to hold
the zoned buffer. If all frames were to be used (`zone-all-frames' set
the zoned buffer. If all frames were to be used ('zone-all-frames' set
to non-nil), then all frames are converted to single window frames.
**** New user option 'zone-all-frames'
When non-nil, zone will appear on all visible frames. While the buffer
*** New user option 'zone-all-frames'.
When non-nil, Zone will appear on all visible frames. While the buffer
scrambling will appear on each frame, it will be the same buffer so they
will all behave the same way.
**** New user option 'zone-all-windows-in-frame'
*** New user option 'zone-all-windows-in-frame'.
When non-nil, the zoned buffer will be mapped to all of the windows
present on the frame. If the option is nil, then only the selected
window will show the zoned buffer. Note, however, that each window
holding the zoned buffer is showing the same zoned buffer.
*** Selecting source buffers suitable for zoning
When the idle timer, or the user, invokes `zone', the current buffer may
not be appropriate as the source of the zone buffer. For example,
encrypted buffers, empty buffers, or specialized buffers like
`*Messages*' probably shouldn't have their content splashed across zoned
windows. So the selection of a suitable buffer for zoning can be controlled with a variable that identifies buffers with concerns.
**** New variable 'zone-ignored-buffers'
The variable is a list of criteria for excluding a buffer from
*** New variable 'zone-ignored-buffers'.
This variable is a list of criteria for excluding a buffer from
consideration as the source of zoning. The list has entries that are
tested against each buffer until a suitable one is found. The criteria
can be a symbol that ends in `-mode' which excludes buffers that are in
can be a symbol that ends in '-mode' which excludes buffers that are in
a mode derived from the specified mode. It may also be a function-bound
symbol or lambda expression that is called with a buffer that returns a
non-nil value if it should not be the zone source. Finally, an entry
can also be a regular expression string that must not match the buffer's
name.
non-nil value if it should not be the Zone source. Finally, an entry
can also be a regular expression that must not match the buffer's name.
Initially, the list excludes buffers in a special-mode, in an
image-mode, contains an encrypted file, is an empty buffer, is a hidden
buffer, or is the `*scratch*' buffer. If it cannot locate any
acceptable buffers, it will begrudgingly use the scratch buffer.
*** Zone hooks
Hooks have been added to notify programs of the start and end of zone activity. For example, you may want to credit time spent zoning as a Pomodoro break.
**** New hook 'zone-start-hook'
This hook contains functions that are invoked when zoning is about to begin.
**** New hook 'zone-finish-hook'
This hook contains functions that are invoked when zoning has finished.
**** New variable 'zone-time-elapsed-while-zoning'
This is the elapsed time between the start and finish hooks. So this
represents how long Emacs was zoning. Zone calculates this so that the
finish hook can communicate this to other modes if necessary.
Initially, the list excludes buffers in 'special-mode', in 'image-mode',
contains an encrypted file, is an empty buffer, is a hidden buffer, or
is the "*scratch*" buffer. If it cannot locate any acceptable buffers,
it will begrudgingly use the scratch buffer.
* New Modes and Packages in Emacs 31.1
@ -3130,6 +3137,16 @@ and blocks Emacs, or does not provide ways to limit how often it runs.
* Incompatible Lisp Changes in Emacs 31.1
** Files loaded from '-x' and '--script' now use lexical binding.
If you don't have time to adapt your script's code to the lexical
binding dialect (see "(elisp) Converting to Lexical Binding"), you can
wrap your code in:
#!/usr/bin/env -S emacs --batch --script
(eval
'(progn
YOUR CODE HERE))
+++
** String mutation has been restricted further.
'aset' on unibyte strings now requires the new character to be a single
@ -3549,12 +3566,21 @@ This is an abbreviation for using the name of the keymap as the prefix
command name. E.g., '(defvar-keymap foo-map :prefix t)' is equivalent
to '(defvar-keymap foo-map :prefix 'foo-map)'.
** Toolkit
---
** Emacs PGTK toolkit respects dark and light modes.
*** The Emacs PGTK toolkit respects dark and light modes.
Emacs when built with the pure GTK toolkit now respects desktop
dark and light modes for drawing a GTK toolbar and widgets,
automatically toggling between them.
---
*** 'toolkit-theme-set-functions' called when the toolkit theme is set for Emacs.
When the theme is set on PGTK, Android, or MS-Windows systems,
'toolkit-theme-set-functions' is called. The result is stored in the
variable 'toolkit-theme' as either symbol 'dark' or 'light', but may be
extended to encompass other toolkit-specific symbols in the future.
* Changes in Emacs 31.1 on Non-Free Operating Systems

View file

@ -3472,8 +3472,10 @@ symbolic form found in Lisp source that "abbreviates" a symbol's print
name. Among other applications, this feature can be used to avoid
name clashes and namespace pollution by renaming an entire file's
worth of symbols with proper and longer prefixes, without actually
touching the Lisp source. For details, see the Info node "(elisp)
Shorthands".
touching the Lisp source. Instead you need to set the
'read-symbol-shorthands' variable in the file-local section of the file
to list the shorthand prefixes in use.
For details, see the Info node "(elisp) Shorthands".
** New function 'string-search'.
This function takes two string parameters and returns the position of

View file

@ -61,6 +61,9 @@ public final class EmacsNative
scaledDensity is the DPI value used to translate point sizes to
pixel sizes when loading fonts.
uiMode holds the bits of the system's UI mode specification
defining the active system theme.
classPath must be the classpath of this app_process process, or
NULL.
@ -74,6 +77,7 @@ public final class EmacsNative
float pixelDensityX,
float pixelDensityY,
float scaledDensity,
int uiMode,
String classPath,
EmacsService emacsService,
int apiLevel);
@ -197,8 +201,9 @@ public final class EmacsNative
public static native void sendNotificationAction (String tag, String action);
/* Send an ANDROID_CONFIGURATION_CHANGED event. */
public static native void sendConfigurationChanged (float dpiX, float dpiY,
float dpiScaled);
public static native void sendConfigurationChanged (int detail, float dpiX,
float dpiY, float dpiScaled,
int ui_mode);
/* Return the file name associated with the specified file
descriptor, or NULL if there is none. */

View file

@ -67,7 +67,7 @@ public final class EmacsNoninteractive
cacheDir = context.getCacheDir ().getCanonicalPath ();
EmacsNative.setEmacsParams (assets, filesDir,
libDir, cacheDir, 0.0f,
0.0f, 0.0f, null, null,
0.0f, 0.0f, 0x0, null, null,
Build.VERSION.SDK_INT);
/* Now find the dump file that Emacs should use, if it has already

View file

@ -150,6 +150,10 @@ public final class EmacsService extends Service
consulted for font scaling. */
private double dpiX, dpiY, dpiScaled;
/* The display's previously observed UI mode as it relates to the
system theme. */
private int uiMode;
static
{
servicingQuery = new AtomicInteger ();
@ -240,6 +244,7 @@ public final class EmacsService extends Service
float tempScaledDensity;
Resources resources;
DisplayMetrics metrics;
Configuration configuration;
super.onCreate ();
@ -254,6 +259,8 @@ public final class EmacsService extends Service
tempScaledDensity = ((getScaledDensity (metrics)
/ metrics.density)
* pixelDensityX);
configuration = resources.getConfiguration ();
uiMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK;
resolver = getContentResolver ();
mainThread = Thread.currentThread ();
@ -311,7 +318,8 @@ public final class EmacsService extends Service
EmacsNative.setEmacsParams (manager, filesDir, libDir,
cacheDir, pixelDensityX,
pixelDensityY, scaledDensity,
classPath, EmacsService.this,
uiMode, classPath,
EmacsService.this,
Build.VERSION.SDK_INT);
}
}, extraStartupArguments);
@ -375,8 +383,14 @@ public final class EmacsService extends Service
dpiX = pixelDensityX;
dpiY = pixelDensityY;
dpiScaled = scaledDensity;
EmacsNative.sendConfigurationChanged (pixelDensityX, pixelDensityY,
scaledDensity);
EmacsNative.sendConfigurationChanged (0, pixelDensityX, pixelDensityY,
scaledDensity, 0);
}
if ((newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) != uiMode)
{
uiMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK;
EmacsNative.sendConfigurationChanged (1, 0.0f, 0.0f, 0.0f, uiMode);
}
super.onConfigurationChanged (newConfig);

View file

@ -577,7 +577,13 @@ struct global
};
/* Bit values for FLAGS field from the above. Applied for DEFUNs only. */
enum { DEFUN_noreturn = 1, DEFUN_const = 2, DEFUN_noinline = 4 };
enum
{
DEFUN_noreturn = 1,
DEFUN_const = 2,
DEFUN_noinline = 4,
DEFUN_pure = 8,
};
/* All the variable names we saw while scanning C sources in `-g'
mode. */
@ -752,6 +758,8 @@ write_globals (void)
fputs (" ATTRIBUTE_COLD", stdout);
if (globals[i].flags & DEFUN_const)
fputs (" ATTRIBUTE_CONST", stdout);
if (globals[i].flags & DEFUN_pure)
fputs (" ATTRIBUTE_PURE", stdout);
puts (";");
}
@ -1062,7 +1070,7 @@ scan_c_stream (FILE *infile)
attributes: attribute1 attribute2 ...)
(Lisp_Object arg...)
Now only `const', `noinline' and `noreturn' attributes
Now only 'const', 'noinline', 'noreturn', and 'pure' attributes
are used. */
/* Advance to the end of docstring. */
@ -1110,6 +1118,8 @@ scan_c_stream (FILE *infile)
g->flags |= DEFUN_noreturn;
if (strstr (input_buffer, "const"))
g->flags |= DEFUN_const;
if (strstr (input_buffer, "pure"))
g->flags |= DEFUN_pure;
/* Although the noinline attribute is no longer used,
leave its support in, in case it's needed later. */

View file

@ -161,9 +161,7 @@ acl_default_nontrivial (acl_t acl)
int
acl_nontrivial (int count, aclent_t *entries)
{
int i;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
aclent_t *ace = &entries[i];
@ -192,8 +190,6 @@ acl_nontrivial (int count, aclent_t *entries)
int
acl_ace_nontrivial (int count, ace_t *entries)
{
int i;
/* The flags in the ace_t structure changed in a binary incompatible way
when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15.
How to distinguish the two conventions at runtime?
@ -202,7 +198,7 @@ acl_ace_nontrivial (int count, ace_t *entries)
convention, these values are not used. */
int old_convention = 0;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER))
{
old_convention = 1;
@ -211,7 +207,7 @@ acl_ace_nontrivial (int count, ace_t *entries)
if (old_convention)
/* Running on Solaris 10. */
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
ace_t *ace = &entries[i];
@ -238,7 +234,7 @@ acl_ace_nontrivial (int count, ace_t *entries)
0 /* everyone@ allow */
};
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
ace_t *ace = &entries[i];
unsigned int index1;
@ -374,12 +370,10 @@ acl_ace_nontrivial (int count, ace_t *entries)
int
acl_nontrivial (int count, struct acl_entry *entries)
{
int i;
if (count > 3)
return 1;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
struct acl_entry *ace = &entries[i];
@ -396,9 +390,7 @@ acl_nontrivial (int count, struct acl_entry *entries)
int
aclv_nontrivial (int count, struct acl *entries)
{
int i;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
struct acl *ace = &entries[i];
@ -424,10 +416,8 @@ int
acl_nontrivial (struct acl *a)
{
/* The normal way to iterate through an ACL is like this:
struct acl_entry *ace;
for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
for (struct acl_entry *ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
{
struct ace_id *aei;
switch (ace->ace_type)
{
case ACC_PERMIT:
@ -435,7 +425,7 @@ acl_nontrivial (struct acl *a)
case ACC_SPECIFY:
...;
}
for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
for (struct ace_id *aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
...
}
*/
@ -453,9 +443,8 @@ acl_nfs4_nontrivial (nfs4_acl_int_t *a)
return (a->aclEntryN > 0 ? 1 : 0);
# else
int count = a->aclEntryN;
int i;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
nfs4_ace_int_t *ace = &a->aclEntry[i];
@ -484,9 +473,7 @@ acl_nfs4_nontrivial (nfs4_acl_int_t *a)
int
acl_nontrivial (int count, struct acl *entries)
{
int i;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
{
struct acl *ace = &entries[i];

View file

@ -286,160 +286,156 @@ diag (OFFSET xoff, OFFSET xlim, OFFSET yoff, OFFSET ylim, bool find_minimal,
}
}
if (find_minimal)
continue;
if (!find_minimal)
{
#ifdef USE_HEURISTIC
bool heuristic = ctxt->heuristic;
bool heuristic = ctxt->heuristic;
#else
bool heuristic = false;
bool heuristic = false;
#endif
/* Heuristic: check occasionally for a diagonal that has made lots
of progress compared with the edit distance. If we have any
such, find the one that has made the most progress and return it
as if it had succeeded.
/* Heuristic: check occasionally for a diagonal that has made lots
of progress compared with the edit distance. If we have any
such, find the one that has made the most progress and return it
as if it had succeeded.
With this heuristic, for vectors with a constant small density
of changes, the algorithm is linear in the vector size. */
With this heuristic, for vectors with a constant small density
of changes, the algorithm is linear in the vector size. */
if (200 < c && big_snake && heuristic)
{
{
OFFSET best = 0;
for (d = fmax; d >= fmin; d -= 2)
if (200 < c && big_snake && heuristic)
{
{
OFFSET dd = d - fmid;
OFFSET x = fd[d];
OFFSET y = x - d;
OFFSET v = (x - xoff) * 2 - dd;
OFFSET best = 0;
if (v > 12 * (c + (dd < 0 ? -dd : dd)))
for (d = fmax; d >= fmin; d -= 2)
{
if (v > best
&& xoff + SNAKE_LIMIT <= x && x < xlim
&& yoff + SNAKE_LIMIT <= y && y < ylim)
{
/* We have a good enough best diagonal; now insist
that it end with a significant snake. */
int k;
OFFSET dd = d - fmid;
OFFSET x = fd[d];
OFFSET y = x - d;
OFFSET v = (x - xoff) * 2 - dd;
for (k = 1; XREF_YREF_EQUAL (x - k, y - k); k++)
if (k == SNAKE_LIMIT)
{
best = v;
part->xmid = x;
part->ymid = y;
break;
}
if (v > 12 * (c + (dd < 0 ? -dd : dd)))
{
if (v > best
&& xoff + SNAKE_LIMIT <= x && x < xlim
&& yoff + SNAKE_LIMIT <= y && y < ylim)
{
/* We have a good enough best diagonal; now insist
that it end with a significant snake. */
for (int k = 1; XREF_YREF_EQUAL (x - k, y - k); k++)
if (k == SNAKE_LIMIT)
{
best = v;
part->xmid = x;
part->ymid = y;
break;
}
}
}
}
}
if (best > 0)
{
part->lo_minimal = true;
part->hi_minimal = false;
return;
}
}
{
OFFSET best = 0;
for (d = bmax; d >= bmin; d -= 2)
{
OFFSET dd = d - bmid;
OFFSET x = bd[d];
OFFSET y = x - d;
OFFSET v = (xlim - x) * 2 + dd;
if (v > 12 * (c + (dd < 0 ? -dd : dd)))
if (best > 0)
{
if (v > best
&& xoff < x && x <= xlim - SNAKE_LIMIT
&& yoff < y && y <= ylim - SNAKE_LIMIT)
{
/* We have a good enough best diagonal; now insist
that it end with a significant snake. */
int k;
for (k = 0; XREF_YREF_EQUAL (x + k, y + k); k++)
if (k == SNAKE_LIMIT - 1)
{
best = v;
part->xmid = x;
part->ymid = y;
break;
}
}
part->lo_minimal = true;
part->hi_minimal = false;
return;
}
}
if (best > 0)
{
part->lo_minimal = false;
part->hi_minimal = true;
return;
OFFSET best = 0;
for (d = bmax; d >= bmin; d -= 2)
{
OFFSET dd = d - bmid;
OFFSET x = bd[d];
OFFSET y = x - d;
OFFSET v = (xlim - x) * 2 + dd;
if (v > 12 * (c + (dd < 0 ? -dd : dd)))
{
if (v > best
&& xoff < x && x <= xlim - SNAKE_LIMIT
&& yoff < y && y <= ylim - SNAKE_LIMIT)
{
/* We have a good enough best diagonal; now insist
that it end with a significant snake. */
for (int k = 0; XREF_YREF_EQUAL (x + k, y + k); k++)
if (k == SNAKE_LIMIT - 1)
{
best = v;
part->xmid = x;
part->ymid = y;
break;
}
}
}
}
if (best > 0)
{
part->lo_minimal = false;
part->hi_minimal = true;
return;
}
}
}
}
/* Heuristic: if we've gone well beyond the call of duty, give up
and report halfway between our best results so far. */
if (c >= ctxt->too_expensive)
{
/* Find forward diagonal that maximizes X + Y. */
OFFSET fxybest = -1, fxbest;
for (d = fmax; d >= fmin; d -= 2)
{
OFFSET x = MIN (fd[d], xlim);
OFFSET y = x - d;
if (ylim < y)
{
x = ylim + d;
y = ylim;
}
if (fxybest < x + y)
{
fxybest = x + y;
fxbest = x;
}
}
/* Find backward diagonal that minimizes X + Y. */
OFFSET bxybest = OFFSET_MAX, bxbest;
for (d = bmax; d >= bmin; d -= 2)
/* Heuristic: if we've gone well beyond the call of duty, give up
and report halfway between our best results so far. */
if (c >= ctxt->too_expensive)
{
OFFSET x = MAX (xoff, bd[d]);
OFFSET y = x - d;
if (y < yoff)
/* Find forward diagonal that maximizes X + Y. */
OFFSET fxybest = -1, fxbest;
for (d = fmax; d >= fmin; d -= 2)
{
x = yoff + d;
y = yoff;
OFFSET x = MIN (fd[d], xlim);
OFFSET y = x - d;
if (ylim < y)
{
x = ylim + d;
y = ylim;
}
if (fxybest < x + y)
{
fxybest = x + y;
fxbest = x;
}
}
if (x + y < bxybest)
{
bxybest = x + y;
bxbest = x;
}
}
/* Use the better of the two diagonals. */
if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff))
{
part->xmid = fxbest;
part->ymid = fxybest - fxbest;
part->lo_minimal = true;
part->hi_minimal = false;
/* Find backward diagonal that minimizes X + Y. */
OFFSET bxybest = OFFSET_MAX, bxbest;
for (d = bmax; d >= bmin; d -= 2)
{
OFFSET x = MAX (xoff, bd[d]);
OFFSET y = x - d;
if (y < yoff)
{
x = yoff + d;
y = yoff;
}
if (x + y < bxybest)
{
bxybest = x + y;
bxbest = x;
}
}
/* Use the better of the two diagonals. */
if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff))
{
part->xmid = fxbest;
part->ymid = fxybest - fxbest;
part->lo_minimal = true;
part->hi_minimal = false;
}
else
{
part->xmid = bxbest;
part->ymid = bxybest - bxbest;
part->lo_minimal = false;
part->hi_minimal = true;
}
return;
}
else
{
part->xmid = bxbest;
part->ymid = bxybest - bxbest;
part->lo_minimal = false;
part->hi_minimal = true;
}
return;
}
}
#undef XREF_YREF_EQUAL

View file

@ -146,9 +146,8 @@ dupfd (int oldfd, int newfd, int flags)
/* Close the previous fds that turned out to be too small. */
{
int saved_errno = errno;
unsigned int duplicated_fd;
for (duplicated_fd = 0;
for (unsigned int duplicated_fd = 0;
duplicated_fd < fds_to_close_bound * CHAR_BIT;
duplicated_fd++)
if ((fds_to_close[duplicated_fd / CHAR_BIT]

View file

@ -495,6 +495,15 @@ _GL_WARN_ON_USE (openat2, "openat2 is not portable - "
# define AT_NO_AUTOMOUNT 0
#endif
/* errno when openat+O_NOFOLLOW fails because the file is a symlink. */
#if defined __FreeBSD__ || defined __FreeBSD_kernel__ || defined __DragonFly__
# define _GL_OPENAT_ESYMLINK EMLINK
#elif defined __NetBSD__
# define _GL_OPENAT_ESYMLINK EFTYPE
#else
# define _GL_OPENAT_ESYMLINK ELOOP
#endif
#endif /* _@GUARD_PREFIX@_FCNTL_H */
#endif /* _@GUARD_PREFIX@_FCNTL_H */
#endif

View file

@ -660,9 +660,9 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd,
(aclent_t *) malloc (alloc * sizeof (aclent_t));
if (entries == NULL)
return -1;
continue;
}
break;
else
break;
}
if (count < 0)
{
@ -732,9 +732,9 @@ fdfile_has_aclinfo (MAYBE_UNUSED int fd,
entries = malloced = (ace_t *) malloc (alloc * sizeof (ace_t));
if (entries == NULL)
return -1;
continue;
}
break;
else
break;
}
if (count < 0)
{

View file

@ -124,7 +124,6 @@ FTOASTR (char *buf, size_t bufsize, int flags, int width, FLOAT x)
PROMOTED_FLOAT promoted_x = x;
char format[sizeof "%-+ 0*.*Lg"];
FLOAT abs_x = x < 0 ? -x : x;
int prec;
char *p = format;
*p++ = '%';
@ -142,7 +141,7 @@ FTOASTR (char *buf, size_t bufsize, int flags, int width, FLOAT x)
*p++ = flags & FTOASTR_UPPER_E ? 'G' : 'g';
*p = '\0';
for (prec = abs_x < FLOAT_MIN ? 1 : FLOAT_DIG; ; prec++)
for (int prec = abs_x < FLOAT_MIN ? 1 : FLOAT_DIG; ; prec++)
{
int n = snprintf (buf, bufsize, format, width, prec, promoted_x);
if (n < 0

View file

@ -61,13 +61,10 @@ getdtablesize (void)
{
/* We are looking for the number N such that the valid file descriptors
are 0..N-1. It can be obtained through a loop as follows:
{
int fd;
for (fd = 3; fd < 65536; fd++)
if (dup2 (0, fd) == -1)
break;
return fd;
}
for (int fd = 3; fd < 65536; fd++)
if (dup2 (0, fd) == -1)
break;
return fd;
On Windows XP, the result is 2048.
The drawback of this loop is that it allocates memory for a libc
internal array that is never freed.

View file

@ -623,11 +623,11 @@ getloadavg (double loadavg[], int nelem)
struct proc_summary proc_sum_data;
struct stat_descr proc_info;
double load;
register unsigned int i, j;
register unsigned int j;
if (cpus == 0)
{
register unsigned int c, i;
register unsigned int c;
struct cpu_config conf;
struct stat_descr desc;
@ -641,7 +641,7 @@ getloadavg (double loadavg[], int nelem)
return -1;
c = 0;
for (i = 0; i < conf.config_maxclass; ++i)
for (unsigned int i = 0; i < conf.config_maxclass; ++i)
{
struct class_stats stats;
memset (&stats, 0, sizeof stats);
@ -672,7 +672,7 @@ getloadavg (double loadavg[], int nelem)
load = proc_sum_data.ps_nrunnable;
j = 0;
for (i = samples - 1; i > 0; --i)
for (unsigned int i = samples - 1; i > 0; --i)
{
load += proc_sum_data.ps_nrun[j];
if (j++ == PS_NRUNSIZE)

View file

@ -69,6 +69,7 @@
# --avoid=setenv \
# --avoid=sigprocmask \
# --avoid=stat \
# --avoid=std-gnu11 \
# --avoid=stdarg-h \
# --avoid=threadlib \
# --avoid=tzset \
@ -159,7 +160,7 @@
# sigdescr_np \
# socklen \
# stat-time \
# std-gnu11 \
# std-gnu23 \
# stdc_bit_width \
# stdc_count_ones \
# stdc_trailing_zeros \

View file

@ -73,14 +73,13 @@ get_group_info (struct group_info *gi)
int
group_member (gid_t gid)
{
int i;
int found;
struct group_info gi;
int n_groups = get_group_info (&gi);
/* Search through the list looking for GID. */
found = 0;
for (i = 0; i < n_groups; i++)
for (int i = 0; i < n_groups; i++)
{
if (gid == gi.group[i])
{
@ -99,9 +98,7 @@ group_member (gid_t gid)
int
main (int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++)
for (int i = 1; i < argc; i++)
{
gid_t gid;

View file

@ -116,8 +116,8 @@
#endif
/* True if __builtin_mul_overflow (A, B, P) works when P is non-null. */
#if defined __clang_major__ && __clang_major__ < 14
/* Work around Clang bug <https://bugs.llvm.org/show_bug.cgi?id=16404>. */
#if defined __clang_major__ && __clang_major__ < 21
/* Work around Clang bug <https://github.com/llvm/llvm-project/issues/16778>. */
# define _GL_HAS_BUILTIN_MUL_OVERFLOW 0
#else
# define _GL_HAS_BUILTIN_MUL_OVERFLOW _GL_HAS_BUILTIN_ADD_OVERFLOW
@ -179,9 +179,9 @@
_GL_INT_OP_WRAPV (a, b, r, *, _GL_INT_MULTIPLY_RANGE_OVERFLOW)
#endif
/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See:
/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25764. See:
https://gcc.gnu.org/PR68193
https://llvm.org/bugs/show_bug.cgi?id=25390
https://github.com/llvm/llvm-project/issues/25764
For now, assume GCC < 14 and all Clang versions generate bogus
warnings for _Generic. This matters only for compilers that
lack relevant builtins. */

View file

@ -84,15 +84,11 @@ __memrchr (void const *s, int c_in, size_t n)
repeated_one |= repeated_one << 31 << 1;
repeated_c |= repeated_c << 31 << 1;
if (8 < sizeof (longword))
{
size_t i;
for (i = 64; i < sizeof (longword) * 8; i *= 2)
{
repeated_one |= repeated_one << i;
repeated_c |= repeated_c << i;
}
}
for (size_t i = 64; i < sizeof (longword) * 8; i *= 2)
{
repeated_one |= repeated_one << i;
repeated_c |= repeated_c << i;
}
}
/* Instead of the traditional loop which tests each byte, we will test a

View file

@ -468,11 +468,9 @@ __mktime_internal (struct tm *tp, bool local, mktime_offset_t *offset)
int year_seconds_bound = 366 * 24 * 60 * 60 + 1;
int delta_bound = year_seconds_bound + stride;
int delta, direction;
/* Search in both directions, closest first. */
for (delta = stride; delta < delta_bound; delta += stride)
for (direction = -1; direction <= 1; direction += 2)
for (int delta = stride; delta < delta_bound; delta += stride)
for (int direction = -1; direction <= 1; direction += 2)
{
long_int ot;
if (! ckd_add (&ot, t, delta * direction))

View file

@ -89,10 +89,8 @@ num_processors_via_affinity_mask (void)
/* glibc >= 2.6 has the CPU_COUNT macro. */
count = CPU_COUNT (&set);
# else
size_t i;
count = 0;
for (i = 0; i < CPU_SETSIZE; i++)
for (size_t i = 0; i < CPU_SETSIZE; i++)
if (CPU_ISSET (i, &set))
count++;
# endif
@ -112,9 +110,7 @@ num_processors_via_affinity_mask (void)
if (pthread_getaffinity_np (pthread_self (), cpuset_size (set), set)
== 0)
{
cpuid_t i;
for (i = 0;; i++)
for (cpuid_t i = 0;; i++)
{
int ret = cpuset_isset (i, set);
if (ret < 0)
@ -180,10 +176,8 @@ num_processors_via_affinity_mask (void)
/* glibc >= 2.6 has the CPU_COUNT macro. */
count = CPU_COUNT (&set);
# else
size_t i;
count = 0;
for (i = 0; i < CPU_SETSIZE; i++)
for (size_t i = 0; i < CPU_SETSIZE; i++)
if (CPU_ISSET (i, &set))
count++;
# endif
@ -202,9 +196,7 @@ num_processors_via_affinity_mask (void)
if (sched_getaffinity_np (getpid (), cpuset_size (set), set) == 0)
{
cpuid_t i;
for (i = 0;; i++)
for (cpuid_t i = 0;; i++)
{
int ret = cpuset_isset (i, set);
if (ret < 0)

View file

@ -95,15 +95,13 @@ rpl_pselect (int nfds, fd_set *restrict rfds,
struct timespec const *restrict timeout,
sigset_t const *restrict sigmask)
{
int i;
/* FreeBSD 8.2 has a bug: it does not always detect invalid fds. */
if (nfds < 0 || nfds > FD_SETSIZE)
{
errno = EINVAL;
return -1;
}
for (i = 0; i < nfds; i++)
for (int i = 0; i < nfds; i++)
{
if (((rfds && FD_ISSET (i, rfds))
|| (wfds && FD_ISSET (i, wfds))

View file

@ -99,19 +99,17 @@ set_acls_from_mode (const char *name, int desc, mode_t mode, bool *must_chmod)
errno = ENOMEM;
return -1;
}
continue;
}
break;
else
break;
}
if (count <= 0)
convention = -1;
else
{
int i;
convention = 0;
for (i = 0; i < count; i++)
for (int i = 0; i < count; i++)
if (entries[i].a_flags & (OLD_ACE_OWNER | OLD_ACE_GROUP | OLD_ACE_OTHER))
{
convention = 1;

View file

@ -254,8 +254,7 @@ sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx)
while (words < endp)
{
uint32_t tm;
int t;
for (t = 0; t < 16; t++)
for (int t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;

View file

@ -96,10 +96,9 @@ set_uint32 (char *cp, uint32_t v)
void *
sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
{
int i;
char *r = resbuf;
for (i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
@ -108,10 +107,9 @@ sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
void *
sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
{
int i;
char *r = resbuf;
for (i = 0; i < 7; i++)
for (int i = 0; i < 7; i++)
set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
@ -338,9 +336,8 @@ sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
{
uint32_t tm;
uint32_t t0, t1;
int t;
/* FIXME: see sha1.c for a better implementation. */
for (t = 0; t < 16; t++)
for (int t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;

View file

@ -96,10 +96,9 @@ set_uint64 (char *cp, u64 v)
void *
sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf)
{
int i;
char *r = resbuf;
for (i = 0; i < 8; i++)
for (int i = 0; i < 8; i++)
set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
@ -108,10 +107,9 @@ sha512_read_ctx (const struct sha512_ctx *ctx, void *resbuf)
void *
sha384_read_ctx (const struct sha512_ctx *ctx, void *resbuf)
{
int i;
char *r = resbuf;
for (i = 0; i < 6; i++)
for (int i = 0; i < 6; i++)
set_uint64 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
return resbuf;
@ -367,9 +365,8 @@ sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
while (words < endp)
{
int t;
/* FIXME: see sha1.c for a better implementation. */
for (t = 0; t < 16; t++)
for (int t = 0; t < 16; t++)
{
x[t] = SWAP (*words);
words++;

View file

@ -286,8 +286,7 @@ str2signum (char const *signame)
}
else
{
unsigned int i;
for (i = 0; i < NUMNAME_ENTRIES; i++)
for (unsigned int i = 0; i < NUMNAME_ENTRIES; i++)
if (streq (numname_table[i].name, signame))
return numname_table[i].num;
@ -331,8 +330,7 @@ str2sig (char const *signame, int *signum)
int
sig2str (int signum, char *signame)
{
unsigned int i;
for (i = 0; i < NUMNAME_ENTRIES; i++)
for (unsigned int i = 0; i < NUMNAME_ENTRIES; i++)
if (numname_table[i].num == signum)
{
strcpy (signame, numname_table[i].name);

View file

@ -232,8 +232,7 @@ stat_time_normalize (int result, _GL_UNUSED struct stat *st)
short int const ts_off[] = { STAT_TIMESPEC_OFFSETOF (st_atim),
STAT_TIMESPEC_OFFSETOF (st_mtim),
STAT_TIMESPEC_OFFSETOF (st_ctim) };
int i;
for (i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
for (int i = 0; i < sizeof ts_off / sizeof *ts_off; i++)
{
struct timespec *ts = (struct timespec *) ((char *) st + ts_off[i]);
long int q = ts->tv_nsec / timespec_hz;

View file

@ -329,7 +329,6 @@ static RETURN_TYPE _GL_ATTRIBUTE_PURE
two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
const unsigned char *needle, size_t needle_len)
{
size_t i; /* Index into current byte of NEEDLE. */
size_t j; /* Index into current window of HAYSTACK. */
size_t period; /* The period of the right half of needle. */
size_t suffix; /* The index of the right half of needle. */
@ -344,9 +343,9 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
shift_table[c] is the distance from the last occurrence of c to
the end of NEEDLE, or NEEDLE_LEN if c is absent from the NEEDLE.
shift_table[NEEDLE[NEEDLE_LEN - 1]] contains the only 0. */
for (i = 0; i < 1U << CHAR_BIT; i++)
for (size_t i = 0; i < 1U << CHAR_BIT; i++)
shift_table[i] = needle_len;
for (i = 0; i < needle_len; i++)
for (size_t i = 0; i < needle_len; i++)
shift_table[CANON_ELEMENT (needle[i])] = needle_len - i - 1;
/* Perform the search. Each iteration compares the right half
@ -379,7 +378,7 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
}
/* Scan for matches in right half. The last byte has
already been matched, by virtue of the shift table. */
i = MAX (suffix, memory);
size_t i = MAX (suffix, memory);
while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
++i;
@ -423,7 +422,7 @@ two_way_long_needle (const unsigned char *haystack, size_t haystack_len,
}
/* Scan for matches in right half. The last byte has
already been matched, by virtue of the shift table. */
i = suffix;
size_t i = suffix;
while (i < needle_len - 1 && (CANON_ELEMENT (needle[i])
== CANON_ELEMENT (haystack[i + j])))
++i;

View file

@ -181,7 +181,9 @@ enum pad_style
#if SUPPORT_NON_GREG_CALENDARS_IN_STRFTIME
/* Support for non-Gregorian calendars. */
# include "localcharset.h"
# include "localename.h"
# if !(defined __APPLE__ && defined __MACH__)
# include "localename.h"
# endif
# include "calendars.h"
# define CAL_ARGS(x,y) x, y,
#else
@ -1020,8 +1022,7 @@ underlying_strftime (timezone_t tz, char *ubuf, size_t ubufsize,
{
/* The last word has length >= 3. */
bool found_letter = false;
const char *p;
for (p = space + 1; *p != '\0'; p++)
for (const char *p = space + 1; *p != '\0'; p++)
if ((*p >= 'A' && *p <= 'Z')
|| (*p >= 'a' && *p <= 'z'))
{
@ -1138,9 +1139,9 @@ my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
#if SUPPORT_NON_GREG_CALENDARS_IN_STRFTIME
/* Recognize whether to use a non-Gregorian calendar. */
const struct calendar *cal = NULL;
struct calendar_date caldate;
if (strcmp (locale_charset (), "UTF-8") == 0)
{
# if !(defined __APPLE__ && defined __MACH__)
const char *loc = gl_locale_name_unsafe (LC_TIME, "LC_TIME");
if (strlen (loc) >= 5 && !(loc[5] >= 'A' && loc[5] <= 'Z'))
{
@ -1150,15 +1151,45 @@ my_strftime (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
cal = &persian_calendar;
else if (memcmp (loc, "am_ET", 5) == 0)
cal = &ethiopian_calendar;
if (cal != NULL)
{
if (cal->from_gregorian (&caldate,
tp->tm_year + 1900,
tp->tm_mon,
tp->tm_mday) < 0)
cal = NULL;
}
}
# else /* defined __APPLE__ && defined __MACH__ */
/* Nearly equivalent code for macOS, that avoids the need to link with
CoreFoundation.
It's not entirely equivalent, because it tests only for the language
(Thai, Farsi, Amharic) instead of also for the territory (Thailand,
Iran, Ethiopia). */
/* Get the translation of "Monday" in the LC_TIME locale, by calling
the underlying strftime function. */
struct tm some_monday; /* 2024-01-01 12:00:00 */
memset (&some_monday, '\0', sizeof (struct tm));
some_monday.tm_year = 2024 - 1900;
some_monday.tm_mon = 1 - 1;
some_monday.tm_mday = 1;
some_monday.tm_wday = 1; /* Monday */
some_monday.tm_hour = 12;
some_monday.tm_min = 0;
some_monday.tm_sec = 0;
char weekday_buf[32];
if (strftime (weekday_buf, sizeof (weekday_buf), "%A", &some_monday) > 0)
{
/* Test for the Thai / Farsi / Amharic translation of "Monday". */
if (streq (weekday_buf, "จันทร์") || streq (weekday_buf, "วันจันทร์"))
cal = &thai_calendar;
else if (streq (weekday_buf, "ﺩﻮﺸﻨﺒﻫ") || streq (weekday_buf, "دوشنبه"))
cal = &persian_calendar;
else if (streq (weekday_buf, "ሰኞ"))
cal = &ethiopian_calendar;
}
# endif
}
struct calendar_date caldate;
if (cal != NULL)
{
if (cal->from_gregorian (&caldate,
tp->tm_year + 1900,
tp->tm_mon,
tp->tm_mday) < 0)
cal = NULL;
}
#endif
bool tzset_called = false;
@ -1248,7 +1279,6 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
#endif
retval_t i = 0;
STREAM_OR_CHAR_T *p = s;
const CHAR_T *f;
#if DO_MULTIBYTE && !defined COMPILE_WIDE
const char *format_end = NULL;
#endif
@ -1260,7 +1290,7 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
if (hour12 == 0)
hour12 = 12;
for (f = format; *f != '\0'; width = -1, f++)
for (const CHAR_T *f = format; *f != '\0'; width = -1, f++)
{
enum pad_style pad = ZERO_PAD;
int modifier; /* Field modifier ('E', 'O', or 0). */
@ -1659,10 +1689,9 @@ __strftime_internal (STREAM_OR_CHAR_T *s, STRFTIME_ARG (size_t maxsize)
{
/* The last word has length >= 3. */
bool found_letter = false;
const char *p;
for (p = space + 1; *p != '\0'; p++)
if ((*p >= 'A' && *p <= 'Z')
|| (*p >= 'a' && *p <= 'z'))
for (const char *wp = space + 1; *wp != '\0'; wp++)
if ((*wp >= 'A' && *wp <= 'Z')
|| (*wp >= 'a' && *wp <= 'z'))
{
found_letter = true;
break;

View file

@ -25,10 +25,10 @@
size_t
strnlen (const char *s, size_t maxlen)
{
size_t i = 0;
/* Do not use memchr, because on some platforms memchr has
undefined behavior if MAXLEN exceeds the number of bytes in S. */
size_t i;
for (i = 0; i < maxlen && s[i]; i++)
for (; i < maxlen && s[i]; i++)
continue;
return i;
}

View file

@ -217,7 +217,6 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr,
register unsigned int cutlim;
register unsigned LONG int i;
register const STRING_TYPE *s;
register UCHAR_TYPE c;
const STRING_TYPE *save, *end;
int overflow;
@ -307,7 +306,7 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr,
{
/* Find the end of the digit string and check its grouping. */
end = s;
for (c = *end; c != L_('\0'); c = *++end)
for (UCHAR_TYPE c = *end; c != L_('\0'); c = *++end)
if ((wchar_t) c != thousands
&& ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
&& (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
@ -326,7 +325,7 @@ INTERNAL (strtol) (const STRING_TYPE *nptr, STRING_TYPE **endptr,
overflow = 0;
i = 0;
for (c = *s; c != L_('\0'); c = *++s)
for (UCHAR_TYPE c = *s; c != L_('\0'); c = *++s)
{
if (s == end)
break;

View file

@ -152,11 +152,10 @@ typedef int suseconds_t;
static int
rpl_fd_isset (SOCKET fd, const fd_set * set)
{
u_int i;
if (set == NULL)
return 0;
for (i = 0; i < set->fd_count; i++)
for (u_int i = 0; i < set->fd_count; i++)
if (set->fd_array[i] == fd)
return 1;

View file

@ -191,7 +191,6 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
{
size_t len;
char *XXXXXX;
unsigned int count;
int fd = -1;
int saved_errno = errno;
@ -236,7 +235,7 @@ try_tempname_len (char *tmpl, int suffixlen, void *args,
/* This is where the Xs start. */
XXXXXX = &tmpl[len - x_suffix_len - suffixlen];
for (count = 0; count < attempts; ++count)
for (unsigned int count = 0; count < attempts; ++count)
{
for (size_t i = 0; i < x_suffix_len; i++)
{

View file

@ -548,12 +548,15 @@ OVERARGS is a list of arguments passed to the override and
`NAME-default' function, in place of those deduced from ARGS."
(declare (doc-string 3)
(indent defun)
(debug (&define name lambda-list stringp def-body)))
`(eval-and-compile
(debug (&define name lambda-list stringp def-body))
(autoload-macro expand))
`(progn
(defun ,name ,args
,docstring
,@(mode-local--overload-body name args body))
(put ',name 'mode-local-overload t)))
:autoload-end
(eval-and-compile
(put ',name 'mode-local-overload t))))
(put :override-with-args 'lisp-indent-function 1)
(define-obsolete-function-alias 'define-overload

View file

@ -166,10 +166,7 @@ If CONF is not found return nil."
;; nil when pattern not appeared yet, "" when pattern is empty ("[]")
(pattern nil)
;; Alist of properties for current PATTERN
(props ())
;; Current line num
(current-line-number 1))
(props ()))
(while (not (eobp))
(skip-chars-forward " \t\f")
(cond
@ -177,7 +174,7 @@ If CONF is not found return nil."
nil)
;; Start of section
((looking-at "\\[\\(.*\\)\\][ \t]*$")
((looking-at "\\[\\(.*\\)\\][ \t]*\\(?:[#;].*\\)?$")
(let ((newpattern (match-string 1)))
(when pattern
(push (make-editorconfig-core-handle-section
@ -187,25 +184,20 @@ If CONF is not found return nil."
(setq props nil)
(setq pattern newpattern)))
((looking-at "\\([^=: \t]+\\)[ \t]*[=:][ \t]*\\(.*?\\)[ \t]*$")
(let ((key (downcase (match-string 1)))
((looking-at "\\([^=: \n\t][^=:\n]*\\)[ \t]*[=:][ \t]*\\(.*?\\)[ \t]*$")
(let ((key (downcase (string-trim (match-string 1))))
(value (match-string 2)))
(when (and (< (length key) 51)
(< (length value) 256))
(if pattern
(when (< (length pattern) 4097) ;;FIXME: 4097?
(push `(,key . ,value)
props))
(if pattern
(push `(,key . ,value)
top-props)))))
props)
(push `(,key . ,value)
top-props))))
(t (error "Error while reading config file: %s:%d:\n %s\n"
conf current-line-number
conf (line-number-at-pos)
(buffer-substring-no-properties (line-beginning-position)
(line-end-position)))))
(setq current-line-number (1+ current-line-number))
(goto-char (point-min))
(forward-line (1- current-line-number)))
(forward-line 1))
(when pattern
(push (make-editorconfig-core-handle-section
:name pattern

View file

@ -160,132 +160,116 @@ translation is found for PATTERN."
(setq current-char (aref pattern index)
index (1+ index))
(cl-case current-char
(?*
(setq pos index)
(if (and (< pos length)
(= (aref pattern pos) ?*))
(push ".*" result)
(push "[^/]*" result)))
(push
(cl-case current-char
(?*
(setq pos index)
(if (and (< pos length)
(= (aref pattern pos) ?*))
".*"
"[^/]*"))
(??
(push "[^/]" result))
(?? "[^/]")
(?\[
(if in-brackets
(push "\\[" result)
(if (= (aref pattern index) ?/)
;; Slash after an half-open bracket
(progn
(push "\\[/" result)
(setq index (+ index 1)))
(setq pos index
has-slash nil)
(while (and (< pos length)
(not (= (aref pattern pos) ?\]))
(not has-slash))
(if (and (= (aref pattern pos) ?/)
(not (= (aref pattern (- pos 1)) ?\\)))
(setq has-slash t)
(setq pos (1+ pos))))
(if has-slash
(progn
(push (concat "\\["
(substring pattern
index
(1+ pos))
"\\]")
result)
(setq index (+ pos 2)))
(if (and (< index length)
(memq (aref pattern index)
'(?! ?^)))
(progn
(setq index (1+ index))
(push "[^" result))
(push "[" result))
(setq in-brackets t)))))
(?\[
(if in-brackets
"\\["
(if (= (aref pattern index) ?/)
;; Slash after an half-open bracket
(progn
(setq index (+ index 1))
"\\[/")
(setq pos index
has-slash nil)
(while (and (< pos length)
(not (= (aref pattern pos) ?\]))
(not has-slash))
(if (and (= (aref pattern pos) ?/)
(not (= (aref pattern (- pos 1)) ?\\)))
(setq has-slash t)
(setq pos (1+ pos))))
(if has-slash
(let ((content (substring pattern index (1+ pos))))
(setq index (+ pos 2))
(concat "\\[" content "\\]"))
(setq in-brackets t)
(if (and (< index length)
(memq (aref pattern index)
'(?! ?^)))
(progn
(setq index (1+ index))
"[^")
"[")))))
(?-
(if in-brackets
(push "-" result)
(push "\\-" result)))
(?- (if in-brackets "-" "\\-"))
(?\]
(push "]" result)
(setq in-brackets nil))
(?\] (setq in-brackets nil) "]")
(?{
(setq pos index
has-comma nil)
(while (and (or (and (< pos length)
(not (= (aref pattern pos) ?})))
is-escaped)
(not has-comma))
(if (and (eq (aref pattern pos) ?,)
(not is-escaped))
(setq has-comma t)
(setq is-escaped (and (eq (aref pattern pos)
?\\)
(not is-escaped))
pos (1+ pos))))
(if (and (not has-comma)
(< pos length))
(let ((pattern-sub (substring pattern index pos)))
(setq num-range (string-match editorconfig-fnmatch--numeric-range-regexp
pattern-sub))
(if num-range
(let ((number-start (string-to-number (match-string 1
pattern-sub)))
(number-end (string-to-number (match-string 2
pattern-sub))))
(push (concat "\\(?:"
(mapconcat #'number-to-string
(cl-loop for i from number-start to number-end
collect i)
"\\|")
"\\)")
result))
(let ((inner (editorconfig-fnmatch--do-translate pattern-sub t)))
(push (format "{%s}" inner) result)))
(setq index (1+ pos)))
(if matching-braces
(progn
(push "\\(?:" result)
(setq brace-level (1+ brace-level)))
(push "{" result))))
(?\{
(setq pos index
has-comma nil)
(while (and (or (and (< pos length)
(not (= (aref pattern pos) ?})))
is-escaped)
(not has-comma))
(if (and (eq (aref pattern pos) ?,)
(not is-escaped))
(setq has-comma t)
(setq is-escaped (and (eq (aref pattern pos)
?\\)
(not is-escaped))
pos (1+ pos))))
(if (and (not has-comma)
(< pos length))
(let ((pattern-sub (substring pattern index pos)))
(setq num-range (string-match
editorconfig-fnmatch--numeric-range-regexp
pattern-sub))
(setq index (1+ pos))
(if num-range
(let ((number-start (string-to-number
(match-string 1 pattern-sub)))
(number-end (string-to-number
(match-string 2 pattern-sub))))
(regexp-opt
(mapcar #'number-to-string
(cl-loop for i from number-start to number-end
collect i))))
(let ((inner (editorconfig-fnmatch--do-translate
pattern-sub t)))
(format "{%s}" inner))))
(if matching-braces
(progn
(setq brace-level (1+ brace-level))
"\\(?:")
"{")))
(?,
(if (and (> brace-level 0)
(not is-escaped))
(push "\\|" result)
(push "\\," result)))
(?,
(if (and (> brace-level 0)
(not is-escaped))
"\\|" "\\,"))
(?}
(if (and (> brace-level 0)
(not is-escaped))
(progn
(push "\\)" result)
(setq brace-level (- brace-level 1)))
(push "}" result)))
(?\}
(if (and (> brace-level 0)
(not is-escaped))
(progn
(setq brace-level (- brace-level 1))
"\\)")
"}"))
(?/
(if (and (<= (+ index 3) (length pattern))
(string= (substring pattern index (+ index 3)) "**/"))
(progn
(push "\\(?:/\\|/.*/\\)" result)
(setq index (+ index 3)))
(push "/" result)))
(?/
(if (and (<= (+ index 3) (length pattern))
(string= (substring pattern index (+ index 3)) "**/"))
(progn
(setq index (+ index 3))
"\\(?:/\\|/.*/\\)")
"/"))
(t
(unless (= current-char ?\\)
(push (regexp-quote (char-to-string current-char)) result))))
(?\\ (when is-escaped "\\\\"))
(t (regexp-quote (char-to-string current-char))))
result)
(if (= current-char ?\\)
(progn (when is-escaped
(push "\\\\" result))
(setq is-escaped (not is-escaped)))
(setq is-escaped nil))))
(setq is-escaped (and (= current-char ?\\) (not is-escaped)))))
(unless nested
(setq result `("\\'" ,@result "\\`")))
(apply #'concat (reverse result))))

View file

@ -41,11 +41,8 @@
;;;###autoload
(defun editorconfig-apply ()
"Get and apply EditorConfig properties to current buffer.
This function does not respect the values of `editorconfig-exclude-modes' and
`editorconfig-exclude-regexps' and always applies available properties.
Use `editorconfig-mode-apply' instead to make use of these variables."
"Get and apply EditorConfig properties to current buffer."
(declare (obsolete hack-local-variables "31.1"))
(interactive)
(when buffer-file-name
(condition-case err
@ -76,14 +73,12 @@ Use `editorconfig-mode-apply' instead to make use of these variables."
:error)))))
(defun editorconfig-mode-apply ()
"Get and apply EditorConfig properties to current buffer.
This function does nothing when the major mode is listed in
`editorconfig-exclude-modes', or variable `buffer-file-name' matches
any of regexps in `editorconfig-exclude-regexps'."
"Get and apply EditorConfig properties to current buffer."
(declare (obsolete editorconfig-apply "31.1"))
(interactive)
(when (and major-mode buffer-file-name)
(editorconfig-apply)))
(with-suppressed-warnings ((obsolete editorconfig-apply))
(editorconfig-apply))))
;;;###autoload

View file

@ -251,9 +251,7 @@ Otherwise, use `delete-trailing-whitespace'."
:type 'function)
(defvar-local editorconfig-properties-hash nil
"Hash object of EditorConfig properties that was enabled for current buffer.
Set by `editorconfig-apply' and nil if that is not invoked in
current buffer yet.")
"Hash object of EditorConfig properties that was enabled for current buffer.")
(put 'editorconfig-properties-hash 'permanent-local t)
(defvar editorconfig-lisp-use-default-indent nil
@ -527,9 +525,7 @@ This function will revert buffer when the coding-system has been changed."
(defun editorconfig-call-get-properties-function (filename)
"Call `editorconfig-core-get-properties-hash' with FILENAME and return result.
This function also removes `unset' properties and calls
`editorconfig-hack-properties-functions'."
This function also removes `unset' properties."
(if (stringp filename)
(setq filename (expand-file-name filename))
(editorconfig-error "Invalid argument: %S" filename))
@ -541,6 +537,12 @@ This function also removes `unset' properties and calls
err)))
(cl-loop for k being the hash-keys of props using (hash-values v)
when (equal v "unset") do (remhash k props))
;; E.g. for `editorconfig-display-current-properties'.
;; FIXME: Use it for memoization as well to avoid the duplicate
;; calls to `editorconfig-core-get-properties-hash' (one for
;; `editorconfig--get-coding-system' and one for
;; `editorconfig--get-dir-local-variables')?
(setq editorconfig-properties-hash props)
props))
(defvar editorconfig-get-local-variables-functions
@ -656,17 +658,21 @@ F is that function, and FILENAME and ARGS are arguments passed to F."
"Return the coding system to use according to EditorConfig.
Meant to be used on `auto-coding-functions'."
(defvar auto-coding-file-name) ;; Emacs≥30
(when (and (stringp auto-coding-file-name)
(file-name-absolute-p auto-coding-file-name)
;; Don't recurse infinitely.
(not (member auto-coding-file-name
editorconfig--getting-coding-system)))
(let* ((editorconfig--getting-coding-system
(cons auto-coding-file-name editorconfig--getting-coding-system))
(props (editorconfig-call-get-properties-function
auto-coding-file-name)))
(editorconfig-merge-coding-systems (gethash 'end_of_line props)
(gethash 'charset props)))))
;; Not only we don't want that an error in the `.editorconfig' file
;; prevents opening a file but we don't want an error to be dropped on
;; the floor by some `ignore-errors' higher up.
(with-demoted-errors "EditorConfig: %S"
(when (and (stringp auto-coding-file-name)
(file-name-absolute-p auto-coding-file-name)
;; Don't recurse infinitely.
(not (member auto-coding-file-name
editorconfig--getting-coding-system)))
(let* ((editorconfig--getting-coding-system
(cons auto-coding-file-name editorconfig--getting-coding-system))
(props (editorconfig-call-get-properties-function
auto-coding-file-name)))
(editorconfig-merge-coding-systems (gethash 'end_of_line props)
(gethash 'charset props))))))
(defun editorconfig--get-dir-local-variables ()
"Return the directory local variables specified via EditorConfig.

View file

@ -246,6 +246,12 @@ declaration" f2 f))
(list 'function-put (list 'quote f)
''function-type (list 'quote val))))
(defalias 'byte-run--dont-autoload
#'(lambda (fn)
#'(lambda (&rest args)
(let ((code (apply fn args)))
(list 'progn ':autoload-end code)))))
;; Add any new entries to info node `(elisp)Declare Form'.
(defvar defun-declarations-alist
(list
@ -368,16 +374,18 @@ This is used by `declare'.")
(cons actions cl-decls))))
(defvar macro-declarations-alist
(cons
(list 'debug #'byte-run--set-debug)
(cons
(nconc
(list
(list 'debug #'byte-run--set-debug)
;; macros can declare (autoload-macro expand) to request expansion
;; during autoload generation of forms calling them. See
;; `loaddefs-generate--make-autoload'.
(list 'autoload-macro #'byte-run--set-autoload-macro)
(cons
(list 'no-font-lock-keyword #'byte-run--set-no-font-lock-keyword)
defun-declarations-alist)))
;; Override the entry from `defun-declarations-alist', because we
;; prefer to autoload the macro when trying to indent it (bug#68818).
(list 'indent (byte-run--dont-autoload #'byte-run--set-indent))
(list 'no-font-lock-keyword #'byte-run--set-no-font-lock-keyword))
defun-declarations-alist)
"List associating properties of macros to their macro expansion.
Each element of the list takes the form (PROP FUN) where FUN is a function.
For each (PROP . VALUES) in a macro's declaration, the FUN corresponding

View file

@ -2618,7 +2618,7 @@ Call from the source buffer."
;; for `byte-compile-dynamic-docstrings'. Most other things can be output
;; as byte-code.
(put 'autoload 'byte-hunk-handler 'byte-compile-file-form-autoload)
(put 'autoload 'byte-hunk-handler #'byte-compile-file-form-autoload)
(defun byte-compile-file-form-autoload (form)
(and (let ((form form))
(while (if (setq form (cdr form)) (macroexp-const-p (car form))))
@ -2655,8 +2655,8 @@ Call from the source buffer."
(byte-compile-keep-pending (byte-compile--list-with-n form 3 newdoc)
#'byte-compile-normal-call)))
(put 'defvar 'byte-hunk-handler 'byte-compile-file-form-defvar)
(put 'defconst 'byte-hunk-handler 'byte-compile-file-form-defvar)
(put 'defvar 'byte-hunk-handler #'byte-compile-file-form-defvar)
(put 'defconst 'byte-hunk-handler #'byte-compile-file-form-defvar)
(defun byte-compile--check-prefixed-var (sym)
(when (and (symbolp sym)
@ -2680,8 +2680,8 @@ Call from the source buffer."
(byte-compile-defvar form 'toplevel))
(put 'define-abbrev-table 'byte-hunk-handler
'byte-compile-file-form-defvar-function)
(put 'defvaralias 'byte-hunk-handler 'byte-compile-file-form-defvar-function)
#'byte-compile-file-form-defvar-function)
(put 'defvaralias 'byte-hunk-handler #'byte-compile-file-form-defvar-function)
(defun byte-compile-file-form-defvar-function (form)
(pcase-let (((or `',name (let name nil)) (nth 1 form)))
@ -2705,7 +2705,7 @@ Call from the source buffer."
(byte-compile-keep-pending form)))
(put 'custom-declare-variable 'byte-hunk-handler
'byte-compile-file-form-defvar-function)
#'byte-compile-file-form-defvar-function)
(put 'custom-declare-face 'byte-hunk-handler
#'byte-compile--custom-declare-face)
@ -2717,14 +2717,14 @@ Call from the source buffer."
(setq form (byte-compile--list-with-n form 3 newdocs)))))
(byte-compile-keep-pending form)))
(put 'require 'byte-hunk-handler 'byte-compile-file-form-require)
(put 'require 'byte-hunk-handler #'byte-compile-file-form-require)
(defun byte-compile-file-form-require (form)
(let* ((args (mapcar 'eval (cdr form)))
(let* ((args (mapcar #'eval (cdr form)))
;; The following is for the byte-compile-warn in
;; `do-after-load-evaluation' (in subr.el).
(byte-compile-form-stack (cons (car args) byte-compile-form-stack))
hist-new prov-cons)
(apply 'require args)
(apply #'require args)
;; Record the functions defined by the require in `byte-compile-new-defuns'.
(setq hist-new load-history)
@ -3649,6 +3649,8 @@ This assumes the function has the `important-return-value' property."
(dolist (fa '((plist-put 4) (alist-get 5) (add-to-list 5)
(cl-merge 4 :key)
(custom-declare-variable :set :get :initialize :safe)
(define-widget :convert-widget :value-to-internal
:value-to-external :match)
(make-process :filter :sentinel)
(make-network-process :filter :sentinel)
(all-completions 2 3) (try-completion 2 3) (test-completion 2 3)

View file

@ -90,8 +90,13 @@ All bindings made in CONDITION for the BODY of the non-exit clause
are passed along to the rest of the clauses in this `cond*' construct.
\\[match*] for documentation of the patterns for use in `match*'."
;; FIXME: Want an Edebug declaration.
(cond*-convert clauses))
;; The following four macros are autoloaded for the sake of syntax
;; highlighting.
;;;###autoload
(defmacro match* (pattern _datum)
"This specifies matching DATUM against PATTERN.
It is not really a Lisp function, and it is meaningful
@ -158,6 +163,15 @@ ATOM (meaning any other kind of non-list not described above)
;; FIXME: `byte-compile-warn-x' is not necessarily defined here.
(byte-compile-warn-x pattern "`match*' used other than as a `cond*' condition"))
;;;###autoload
(defmacro bind* (&rest bindings)
"This macro evaluates BINDINGS like `let*'.
It is not really a Lisp function, and it is meaningful
only in the CONDITION of a `cond*' clause."
;; FIXME: `byte-compile-warn-x' is not necessarily defined here.
(byte-compile-warn-x bindings "`bind*' used other than as a `cond*' condition"))
;;;###autoload
(defmacro bind-and* (&rest bindings)
"This macro evaluates BINDINGS like `if-let*'.
It is not really a Lisp function, and it is meaningful
@ -165,6 +179,14 @@ only in the CONDITION of a `cond*' clause."
;; FIXME: `byte-compile-warn-x' is not necessarily defined here.
(byte-compile-warn-x bindings "`bind-and*' used other than as a `cond*' condition"))
;;;###autoload
(defmacro pcase* (pattern _datum)
"This macro evaluates BINDINGS like `pcase-let'.
It is not really a Lisp function, and it is meaningful
only in the CONDITION of a `cond*' clause."
;; FIXME: `byte-compile-warn-x' is not necessarily defined here.
(byte-compile-warn-x pattern "`pcase*' used other than as a `cond*' condition"))
(defun cond*-non-exit-clause-p (clause)
"If CLAUSE, a cond* clause, is a non-exit clause, return t."
(or (null (cdr-safe clause)) ;; clause has only one element.
@ -297,7 +319,9 @@ This is used for conditional exit clauses."
(dolist (bind (cdr condition))
(push (list (car bind) (list 'and last (cadr bind)))
checks)
(setq last (car bind)))
(when (eq (caar checks) '_)
(setcar (car checks) (make-symbol "s")))
(setq last (caar checks)))
(cond
;; For explanations on these cases, see "Ordinary
;; Lisp expression is the condition." below.

View file

@ -174,7 +174,8 @@ See Info node `(elisp)Derived Modes' for more details.
(declare (debug (&define name symbolp sexp [&optional stringp]
[&rest keywordp sexp] def-body))
(doc-string 4)
(indent defun))
(indent defun)
(autoload-macro expand))
(when (and docstring (not (stringp docstring)))
;; Some trickiness, since what appears to be the docstring may really be
@ -208,42 +209,44 @@ See Info node `(elisp)Derived Modes' for more details.
parent child docstring syntax abbrev))
`(progn
(defvar ,hook nil)
(unless (get ',hook 'variable-documentation)
(put ',hook 'variable-documentation
,(format "Hook run after entering `%S'.
(progn
:autoload-end
(defvar ,hook nil)
(unless (get ',hook 'variable-documentation)
(put ',hook 'variable-documentation
,(format "Hook run after entering `%S'.
No problems result if this variable is not bound.
`add-hook' automatically binds it. (This is true for all hook variables.)"
child)))
(unless (boundp ',map)
(put ',map 'definition-name ',child))
(with-no-warnings (defvar-keymap ,map))
(unless (get ',map 'variable-documentation)
(put ',map 'variable-documentation
,(format "Keymap for `%s'." child)))
,(if declare-syntax
`(progn
(defvar ,syntax)
(unless (boundp ',syntax)
(put ',syntax 'definition-name ',child)
(defvar ,syntax (make-syntax-table)))
(unless (get ',syntax 'variable-documentation)
(put ',syntax 'variable-documentation
,(format "Syntax table for `%s'." child)))))
,(if declare-abbrev
`(progn
(defvar ,abbrev)
(unless (boundp ',abbrev)
(put ',abbrev 'definition-name ',child)
(defvar ,abbrev
(progn (define-abbrev-table ',abbrev nil) ,abbrev)))
(unless (get ',abbrev 'variable-documentation)
(put ',abbrev 'variable-documentation
,(format "Abbrev table for `%s'." child)))))
(if (fboundp 'derived-mode-set-parent) ;; Emacs≥30.1
(derived-mode-set-parent ',child ',parent)
(put ',child 'derived-mode-parent ',parent))
,(if group `(put ',child 'custom-mode-group ,group))
child)))
(unless (boundp ',map)
(put ',map 'definition-name ',child))
(with-no-warnings (defvar-keymap ,map))
(unless (get ',map 'variable-documentation)
(put ',map 'variable-documentation
,(format "Keymap for `%s'." child)))
,(if declare-syntax
`(progn
(defvar ,syntax)
(unless (boundp ',syntax)
(put ',syntax 'definition-name ',child)
(defvar ,syntax (make-syntax-table)))
(unless (get ',syntax 'variable-documentation)
(put ',syntax 'variable-documentation
,(format "Syntax table for `%s'." child)))))
,(if declare-abbrev
`(progn
(defvar ,abbrev)
(unless (boundp ',abbrev)
(put ',abbrev 'definition-name ',child)
(defvar ,abbrev
(progn (define-abbrev-table ',abbrev nil) ,abbrev)))
(unless (get ',abbrev 'variable-documentation)
(put ',abbrev 'variable-documentation
,(format "Abbrev table for `%s'." child)))))
(if (fboundp 'derived-mode-set-parent) ;; Emacs≥30.1
(derived-mode-set-parent ',child ',parent)
(put ',child 'derived-mode-parent ',parent))
,(if group `(put ',child 'custom-mode-group ,group)))
(defun ,child ()
,docstring

View file

@ -152,23 +152,27 @@ See the file generic-x.el for some examples of `define-generic-mode'."
(declare (debug (sexp def-form def-form def-form form def-form
[&optional stringp] &rest [keywordp form]))
(indent 1)
(doc-string 7))
(doc-string 7)
(autoload-macro expand))
;; Backward compatibility.
(when (eq (car-safe mode) 'quote)
(setq mode (eval mode)))
(setq mode (eval mode t)))
(let* ((name (symbol-name mode))
(pretty-name (capitalize (replace-regexp-in-string
"-mode\\'" "" name))))
`(progn
;; Add a new entry.
(add-to-list 'generic-mode-list ,name)
(progn
:autoload-end
;; Add it to auto-mode-alist
(dolist (re ,auto-mode-list)
(add-to-list 'auto-mode-alist (cons re ',mode)))
;; Add a new entry.
(add-to-list 'generic-mode-list ,name)
;; Add it to auto-mode-alist
(dolist (re ,auto-mode-list)
(add-to-list 'auto-mode-alist (cons re ',mode))))
(defun ,mode ()
,(or docstring
@ -205,7 +209,7 @@ See the file generic-x.el for some examples of `define-generic-mode'."
(setq font-lock-defaults '(generic-font-lock-keywords))
;; Call a list of functions
(mapc 'funcall function-list)
(mapc #'funcall function-list)
(run-mode-hooks mode-hook)))

View file

@ -861,7 +861,7 @@ or to switch back to an existing one."
:type '(choice (const nil) integer)
:safe (lambda (x) (or (null x) (integerp x))))
(defcustom lisp-indent-function 'lisp-indent-function
(defcustom lisp-indent-function #'lisp-indent-function
"A function to be called by `calculate-lisp-indent'.
It indents the arguments of a Lisp function call. This function
should accept two arguments: the indent-point, and the
@ -1256,7 +1256,7 @@ Lisp function does not specify a special indentation."
(progn (forward-sexp 1) (point))))
method)
(setq method (or (function-get (intern-soft function)
'lisp-indent-function)
'lisp-indent-function 'macro)
(get (intern-soft function) 'lisp-indent-hook)))
(cond ((or (eq method 'defun)
;; Check whether we are in flet-like form.

View file

@ -91,7 +91,7 @@ follows:
The autoload file is assumed to contain a trailer starting with a
FormFeed character.")
;;;###autoload
(put 'generated-autoload-file 'safe-local-variable 'stringp)
(put 'generated-autoload-file 'safe-local-variable #'stringp)
(defvar generated-autoload-load-name nil
"Load name for `autoload' statements generated from autoload cookies.
@ -100,7 +100,7 @@ Typically, you need to set this when the directory containing the file
is not in `load-path'.
This also affects the generated cus-load.el file.")
;;;###autoload
(put 'generated-autoload-load-name 'safe-local-variable 'stringp)
(put 'generated-autoload-load-name 'safe-local-variable #'stringp)
(defun loaddefs-generate--file-load-name (file outfile)
"Compute the name that will be used to load FILE.
@ -154,15 +154,8 @@ scanning for autoloads and will be in the `load-path'."
;; they request such expansion and produce suitable output (e.g. by
;; employing :autoload-end to omit unneeded forms).
(defconst loaddefs--defining-macros
'( define-skeleton define-derived-mode define-compilation-mode
define-generic-mode define-globalized-minor-mode define-minor-mode
cl-defun defun* cl-defmacro defmacro* define-overloadable-function
transient-define-prefix transient-define-suffix transient-define-infix
transient-define-argument transient-define-group
;; Obsolete; keep until the alias is removed.
easy-mmode-define-global-mode
easy-mmode-define-minor-mode
define-global-minor-mode))
'( transient-define-prefix transient-define-suffix transient-define-infix
transient-define-argument transient-define-group))
(defvar loaddefs--load-error-files nil)
(defun loaddefs-generate--make-autoload (form file &optional expansion)
@ -251,20 +244,12 @@ expand)' among their `declare' forms."
;; For known special macros which define functions, use `autoload'
;; directly.
((memq car loaddefs--defining-macros)
(let* ((macrop (memq car '(defmacro cl-defmacro defmacro*)))
(name (nth 1 form))
(let* ((name (nth 1 form))
(args (pcase car
((or 'defun 'defmacro
'defun* 'defmacro* 'cl-defun 'cl-defmacro
'define-overloadable-function
'transient-define-prefix 'transient-define-suffix
((or 'transient-define-prefix 'transient-define-suffix
'transient-define-infix 'transient-define-argument
'transient-define-group)
(nth 2 form))
('define-skeleton '(&optional str arg))
((or 'define-generic-mode 'define-derived-mode
'define-compilation-mode)
nil)
(_ t)))
(body (nthcdr (or (function-get car 'doc-string-elt) 3) form))
(doc (if (stringp (car body)) (pop body))))
@ -275,26 +260,17 @@ expand)' among their `declare' forms."
(loaddefs-generate--shorten-autoload
`(autoload ,(if (listp name) name (list 'quote name))
,file ,doc
,(or (and (memq car '( define-skeleton define-derived-mode
define-generic-mode
define-globalized-minor-mode
define-minor-mode
transient-define-prefix
,(or (and (memq car '( transient-define-prefix
transient-define-suffix
transient-define-infix
transient-define-argument
transient-define-group
;; Obsolete; keep until the alias is removed.
easy-mmode-define-global-mode
easy-mmode-define-minor-mode
define-global-minor-mode))
transient-define-group))
t)
(and (eq (car-safe (car body)) 'interactive)
;; List of modes or just t.
(or (if (nthcdr 2 (car body))
(list 'quote (nthcdr 2 (car body)))
t))))
,(if macrop ''macro nil)))))
t))))))))
;; For defclass forms, use `eieio-defclass-autoload'.
((eq car 'defclass)
@ -406,7 +382,7 @@ expand)' among their `declare' forms."
nil))))
prefixes)))
`(register-definition-prefixes ,file ',(sort (delq nil strings)
'string<))))))
#'string<))))))
(defun loaddefs-generate--parse-file (file main-outfile &optional package-data)
"Examining FILE for ;;;###autoload statements.
@ -662,15 +638,7 @@ instead of just updating them with the new/changed autoloads."
(file-attributes file))))
;; If we're scanning for package versions, we want to look
;; at the file even if it's excluded.
(let* ((excluded
;; FIXME: In out-of-tree builds (bug#79694) `excluded-files'
;; (derived via `lisp-directory' from `invocation-directory')
;; may end up using names which don't quite match those of
;; `file' (derived from the command line arguments), w.r.t.
;; "c:/" vs "C:/" on MS-Windows, so use a test more lax
;; than `member'.
(let ((x (member-ignore-case file excluded-files)))
(and x (file-equal-p file (car x)))))
(let* ((excluded (member file excluded-files))
(package-data
(and include-package-version (if excluded 'only t))))
(when (or package-data (not excluded))
@ -789,8 +757,6 @@ instead of just updating them with the new/changed autoloads."
;; Exclude those files that are preloaded on ALL platforms.
;; These are the ones in loadup.el where "(load" is at the start
;; of the line (crude, but it works).
(unless (equal default-directory (file-name-as-directory lisp-directory))
(error "PWD is not set as expected: %S" default-directory))
(let ((excludes nil))
(with-temp-buffer
(insert-file-contents "loadup.el")
@ -821,11 +787,11 @@ use."
"Generate the loaddefs for the Emacs build.
This is like `loaddefs-generate-batch', but has some specific
rules for built-in packages and excluded files."
(let* ((args command-line-args-left)
(let* ((args (mapcar #'file-truename command-line-args-left))
;; We're run from $BUILDDIR/lisp but all the .el(c) files reside
;; (and are generated) in `lisp-directory' which is in $SRCDIR,
;; so go there and don't look back.
(default-directory lisp-directory)
(default-directory (file-truename lisp-directory))
(output-file (expand-file-name "loaddefs.el")))
(setq command-line-args-left nil)
(loaddefs-generate

View file

@ -1029,7 +1029,7 @@ untar into a directory named DIR; otherwise, signal an error."
(make-directory pkg-dir t)
(let ((file-list
(or (and (derived-mode-p 'dired-mode)
(dired-get-marked-files))
(dired-get-marked-files nil 'marked))
(directory-files-recursively default-directory "" nil))))
(dolist (source-file file-list)
(let ((target (expand-file-name
@ -1278,8 +1278,8 @@ The return result is a `package-desc'."
(package--read-pkg-desc 'dir))
(catch 'found
(let ((files (or (and (derived-mode-p 'dired-mode)
(dired-get-marked-files))
(directory-files-recursively default-directory "\\.el\\'"))))
(dired-get-marked-files nil 'marked))
(directory-files default-directory t "\\.el\\'" t))))
;; We sort the file names in lexicographical order, to ensure
;; that we check shorter file names first (ie. those further
;; up in the directory structure).

View file

@ -1140,7 +1140,8 @@ OPENER is non-nil if TOKEN is an opener and nil if it's a closer."
(defcustom smie-indent-basic 4
"Basic amount of indentation."
:type 'integer)
:type 'integer
:safe #'integerp)
(defvar smie-rules-function #'ignore
"Function providing the indentation rules.

View file

@ -282,10 +282,9 @@ If it can't be found, return nil and don't move point."
"Update OBJECT's representation in TABLE.
If OLD-OBJECT is non-nil, replace OLD-OBJECT with OBJECT and display it.
In either case, if the existing object is not found in the table (being
compared with `equal'), signal an error. Note a limitation: if TABLE's
buffer is not in a visible window, or if its window has changed width
since it was updated, updating the TABLE is not possible, and an error
is signaled."
compared with `equal'), signal an error.
TABLE must be at point in the current buffer."
(unless old-object
(setq old-object object))
(let* ((objects (vtable-objects table))
@ -299,17 +298,16 @@ is signaled."
(while (and (cdr objects)
(not (eq (cadr objects) old-object)))
(setq objects (cdr objects)))
(unless objects
(unless (cdr objects)
(error "Can't find the old object"))
(setcar (cdr objects) object))
;; Then update the cache...
;; FIXME: If the table's buffer has no visible window, or if its
;; width has changed since the table was updated, the cache key will
;; not match and the object can't be updated. (Bug #69837).
(if-let* ((line-number (seq-position (car (vtable--cache table)) old-object
(lambda (a b)
(equal (car a) b))))
(line (elt (car (vtable--cache table)) line-number)))
;; Then update the rendered vtable in the current buffer.
(if-let* ((cache (vtable--current-cache))
(line-number (seq-position (vtable--cache-lines cache)
old-object
(lambda (a b)
(equal (car a) b))))
(line (elt (vtable--cache-lines cache) line-number)))
(progn
(setcar line object)
(setcdr line (vtable--compute-cached-line table object))
@ -320,10 +318,11 @@ is signaled."
(start (point)))
(delete-line)
(vtable--insert-line table line line-number
(nth 1 (vtable--cache table))
(vtable--cache-widths cache)
(vtable--spacer table))
(add-text-properties start (point) (list 'keymap keymap
'vtable table))))
'vtable table
'vtable-cache cache))))
;; We may have inserted a non-numerical value into a previously
;; all-numerical table, so recompute.
(vtable--recompute-numerical table (cdr line)))
@ -335,11 +334,12 @@ This will also remove the displayed line."
;; First remove from the objects.
(setf (vtable-objects table) (delq object (vtable-objects table)))
;; Then adjust the cache and display.
(let ((cache (vtable--cache table))
(inhibit-read-only t))
(setcar cache (delq (assq object (car cache)) (car cache)))
(save-excursion
(vtable-goto-table table)
(save-excursion
(vtable-goto-table table)
(let ((cache (vtable--current-cache))
(inhibit-read-only t))
(setcar cache (delq (assq object (vtable--cache-lines cache))
(vtable--cache-lines cache)))
(when (vtable-goto-object object)
(delete-line)))))
@ -400,7 +400,7 @@ This also updates the displayed table."
;; Then adjust the cache and display.
(save-excursion
(vtable-goto-table table)
(let* ((cache (vtable--cache table))
(let* ((cache (vtable--current-cache))
(inhibit-read-only t)
(keymap (get-text-property (point) 'keymap))
(ellipsis (if (vtable-ellipsis table)
@ -408,13 +408,14 @@ This also updates the displayed table."
'face (vtable-face table))
""))
(ellipsis-width (string-pixel-width ellipsis))
(lines (vtable--cache-lines cache))
(elem (if location ; This binding mirrors the binding of `pos' above.
(if (integerp location)
(nth location (car cache))
(or (assq location (car cache))
(and before (caar cache))))
(if before (caar cache))))
(pos (memq elem (car cache)))
(nth location lines)
(or (assq location lines)
(and before (car lines))))
(if before (car lines))))
(pos (memq elem lines))
(line (cons object (vtable--compute-cached-line table object))))
(if (or before
(and pos (integerp location)))
@ -433,16 +434,17 @@ This also updates the displayed table."
(forward-line 1) ; Insert *after*.
(vtable-end-of-table)))
;; Otherwise, append the object.
(setcar cache (nconc (car cache) (list line)))
(setcar cache (nconc lines (list line)))
(vtable-end-of-table)))
(let ((start (point)))
;; FIXME: We have to adjust colors in lines below this if we
;; have :row-colors.
(vtable--insert-line table line 0
(nth 1 cache) (vtable--spacer table)
(vtable--cache-widths cache) (vtable--spacer table)
ellipsis ellipsis-width)
(add-text-properties start (point) (list 'keymap keymap
'vtable table)))
'vtable table
'vtable-cache cache)))
;; We may have inserted a non-numerical value into a previously
;; all-numerical table, so recompute.
(vtable--recompute-numerical table (cdr line))))))
@ -512,15 +514,11 @@ recompute the column specs when the table data has changed."
(defun vtable--spacer (table)
(vtable--compute-width table (vtable-separator-width table)))
(defun vtable--recompute-cache (table)
(let* ((data (vtable--compute-cache table))
(widths (vtable--compute-widths table data)))
(setf (gethash (vtable--cache-key) (slot-value table '-cache))
(list data widths))))
(defun vtable--cache-widths (cache)
(nth 1 cache))
(defun vtable--ensure-cache (table)
(or (vtable--cache table)
(vtable--recompute-cache table)))
(defun vtable--cache-lines (cache)
(car cache))
(defun vtable-insert (table)
(let* ((spacer (vtable--spacer table))
@ -533,7 +531,12 @@ recompute the column specs when the table data has changed."
;; We maintain a cache per screen/window width, so that we render
;; correctly if Emacs is open on two different screens (or the
;; user resizes the frame).
(widths (nth 1 (vtable--ensure-cache table))))
(cache (or (gethash (vtable--cache-key) (slot-value table '-cache))
(let* ((data (vtable--compute-cache table))
(widths (vtable--compute-widths table data)))
(setf (gethash (vtable--cache-key) (slot-value table '-cache))
(list data widths)))))
(widths (vtable--cache-widths cache)))
;; Don't insert any header or header line if the user hasn't
;; specified the columns.
(when (slot-value table '-has-column-spec)
@ -546,18 +549,20 @@ recompute the column specs when the table data has changed."
(add-text-properties start (point)
(list 'keymap vtable-header-line-map
'rear-nonsticky t
'vtable table))
'vtable table
'vtable-cache cache))
(setq start (point))))
(vtable--sort table)
(vtable--sort table cache)
;; Insert the data.
(let ((line-number 0))
(dolist (line (car (vtable--cache table)))
(dolist (line (vtable--cache-lines cache))
(vtable--insert-line table line line-number widths spacer
ellipsis ellipsis-width)
(setq line-number (1+ line-number))))
(add-text-properties start (point)
(list 'rear-nonsticky t
'vtable table))
'vtable table
'vtable-cache cache))
(goto-char start)))
(defun vtable--insert-line (table line line-number widths spacer
@ -659,16 +664,22 @@ recompute the column specs when the table data has changed."
(defun vtable--cache-key ()
(cons (frame-terminal) (window-width)))
(defun vtable--cache (table)
(gethash (vtable--cache-key) (slot-value table '-cache)))
(defun vtable--current-cache ()
"Return the current cache for the table at point.
In `vtable-insert', the lines and widths of the vtable text are computed
based on the current selected frame and window and stored in a cache.
Subsequent interaction with the text of the vtable should use that cache
via this function rather than by calling `vtable--cache-key' to look up
the cache."
(get-text-property (point) 'vtable-cache))
(defun vtable--clear-cache (table)
(setf (gethash (vtable--cache-key) (slot-value table '-cache)) nil))
(defun vtable--sort (table)
(defun vtable--sort (table cache)
(pcase-dolist (`(,index . ,direction) (vtable-sort-by table))
(let ((cache (vtable--cache table))
(numerical (vtable-column--numerical
(let ((numerical (vtable-column--numerical
(elt (vtable-columns table) index)))
(numcomp (if (eq direction 'descend)
#'> #'<))
@ -971,9 +982,6 @@ CACHE is TABLE's cache data as returned by `vtable--compute-cache'."
(when column
(vtable-goto-column column))))
(defun vtable--widths (table)
(nth 1 (vtable--ensure-cache table)))
;;; Commands.
(defvar-keymap vtable-header-mode-map
@ -998,7 +1006,7 @@ Interactively, N is the prefix argument."
(- (* (vtable--char-width table) (or n 1))))))
(defun vtable--alter-column-width (table column delta)
(let ((widths (vtable--widths table)))
(let ((widths (vtable--cache-widths (vtable--current-cache))))
(setf (aref widths column)
(max (* (vtable--char-width table) 2)
(+ (aref widths column) delta)))
@ -1020,14 +1028,14 @@ Interactively, N is the prefix argument."
(interactive)
(vtable-goto-column
(max 0 (1- (or (vtable-current-column)
(length (vtable--widths (vtable-current-table))))))))
(length (vtable--cache-widths (vtable--current-cache))))))))
(defun vtable-next-column ()
"Go to the next column."
(interactive)
(when (vtable-current-column)
(vtable-goto-column
(min (1- (length (vtable--widths (vtable-current-table))))
(min (1- (length (vtable--cache-widths (vtable--current-cache))))
(1+ (vtable-current-column))))))
(defun vtable-revert-command ()

View file

@ -372,7 +372,14 @@ entirely by setting `warning-suppress-types' or
(if (bolp)
(forward-char -1))
(message "%s" (buffer-substring start (point))))))
((and (daemonp) (null after-init-time))
((and (daemonp) (eq (selected-frame) terminal-frame))
;; Display daemon startup warnings on the first client frame.
(letrec ((afterfun
(lambda (frame)
(remove-hook 'after-make-frame-functions afterfun)
(with-selected-frame frame
(warning--display-buffer buffer)))))
(add-hook 'after-make-frame-functions afterfun))
;; Warnings assigned during daemon initialization go into
;; the messages buffer.
(message "%s"
@ -388,23 +395,27 @@ entirely by setting `warning-suppress-types' or
(or (< (warning-numeric-level level)
(warning-numeric-level warning-minimum-level))
(warning-suppress-p type warning-suppress-types)
(let ((window (display-buffer
buffer
(when warning-display-at-bottom
`(display-buffer--maybe-at-bottom
(window-height
. ,(lambda (window)
(fit-window-to-buffer window 10)))
(category . warning))))))
(when (and window (markerp warning-series)
(eq (marker-buffer warning-series) buffer))
(set-window-start window warning-series))
(when (and window warning-display-at-bottom)
(with-selected-window window
(goto-char (point-max))
(forward-line -1)
(recenter -1)))
(sit-for 0)))))))))
(warning--display-buffer buffer))))))))
(defun warning--display-buffer (buffer)
(let ((window (display-buffer
buffer
(when warning-display-at-bottom
`(display-buffer--maybe-at-bottom
(window-height
. ,(lambda (window)
(fit-window-to-buffer window 10)))
(category . warning))))))
(when (and window (markerp warning-series)
(eq (marker-buffer warning-series) buffer))
(set-window-start window warning-series))
(when (and window warning-display-at-bottom)
(with-selected-window window
(goto-char (point-max))
(forward-line -1)
(recenter -1)))
(sit-for 0)))
;; Use \\<special-mode-map> so that help-enable-autoload can do its thing.
;; Any keymap that is defined will do.

View file

@ -290,10 +290,10 @@ optional arg EXPOSURE \(interactively with prefix arg) changes this:-
"Return to the ARG'th enclosing fold view. With ARG = 0 exit all folds.
Normally causes exited folds to be hidden, but with ARG < 0, -ARG folds are
exited and text is left visible."
exited, text is left visible, and point position is preserved."
(interactive "p")
(let ((hide-fold t) start-marker end-marker
beginning-of-heading end-of-subtree)
beginning-of-heading end-of-subtree (original-point (point)))
;; check there are some folds to leave
(if (null foldout-fold-list)
@ -369,7 +369,10 @@ exited and text is left visible."
(if end-marker
(1- (marker-position end-marker))
(point-max)))))
(recenter)
(if hide-fold
(recenter)
(goto-char original-point))
;; update the mode line
(foldout-update-mode-line)))

View file

@ -1528,6 +1528,12 @@ the `background-mode' terminal parameter."
;; :background (face-attribute 'default :foreground))
;; (frame-set-background-mode (selected-frame))))
(defvar toolkit-theme-set-functions nil
"Abnormal hook run when the system theme is applied to Emacs.
Functions on this hook are called with the theme name as a symbol:
`light' or `dark'. By the time the hook is called, `toolkit-theme' will
already be set to one of these values as well.")
;;;; Frame configurations

View file

@ -2718,66 +2718,66 @@ are always t.")
It works along the same lines as a normal formatting string,
with some simple extensions.
%N Article number, left padded with spaces (string)
%S Subject (string)
%s Subject if it is at the root of a thread, and \"\"
otherwise (string)
%n Name of the poster (string)
%a Extracted name of the poster (string)
%A Extracted address of the poster (string)
%F Contents of the From: header (string)
%f Contents of the From: or To: headers (string)
%x Contents of the Xref: header (string)
%D Contents of the Date: header article (string)
%d Date of the article (string) in DD-MMM format
%o Date of the article (string) in YYYYMMDD`T'HHMMSS
format
%M Message-id of the article (string)
%r References of the article (string)
%c Number of characters in the article (integer)
%k Pretty-printed version of the above (string)
For example, \"1.2k\" or \"0.4M\".
%L Number of lines in the article (integer)
%Z RSV of the article; nil if not in an nnselect group (integer)
%G Originating group name for the article; nil if not
in an nnselect group (string)
%g Short from of the originating group name for the article;
nil if not in an nnselect group (string)
%I Indentation based on thread level (a string of
spaces)
%B A complex trn-style thread tree (string)
The variables `gnus-sum-thread-*' can be used for
customization.
%T A string with two possible values: 80 spaces if the
article is on thread level two or larger and 0 spaces
on level one
%R \"A\" if this article has been replied to, \" \"
otherwise (character)
%U \"Read\" status of this article.
See Info node `(gnus)Marking Articles'
%[ Opening bracket (character, \"[\" or \"<\")
%] Closing bracket (character, \"]\" or \">\")
%> Spaces of length thread-level (string)
%< Spaces of length (- 20 thread-level) (string)
%i Article score (number)
%z Article zcore (character)
%t Number of articles under the current thread (number).
%e Whether the thread is empty or not (character).
%V Total thread score (number).
%P The line number (number).
%O Download mark (character).
%* If present, indicates desired cursor position
(instead of after first colon).
%u User defined specifier. The next character in the
format string should be a letter. Gnus will call the
function gnus-user-format-function-X, where X is the
letter following %u. The function will be passed the
current header as argument. The function should
return a string, which will be inserted into the
summary just like information from any other summary
specifier.
&user-date; Age sensitive date format. Various date format is
defined in `gnus-user-date-format-alist'.
%N Article number, left padded with spaces (string)
%S Subject (string)
%s Subject if it is at the root of a thread, and \"\"
otherwise (string)
%n Name of the poster (string)
%a Extracted name of the poster (string)
%A Extracted address of the poster (string)
%F Contents of the From: header (string)
%f Contents of the From: or To: headers (string)
%x Contents of the Xref: header (string)
%D Contents of the Date: header article (string)
%d Date of the article (string) in DD-MMM format
%o Date of the article (string) in YYYYMMDD`T'HHMMSS
format
%M Message-id of the article (string)
%r References of the article (string)
%c Number of characters in the article (integer)
%k Pretty-printed version of the above (string)
For example, \"1.2k\" or \"0.4M\".
%L Number of lines in the article (integer)
%Z RSV of the article; nil if not in an nnselect group (integer)
%G Originating group name for the article; nil if not
in an nnselect group (string)
%g Short from of the originating group name for the article;
nil if not in an nnselect group (string)
%I Indentation based on thread level (a string of
spaces)
%B A complex trn-style thread tree (string)
The variables `gnus-sum-thread-*' can be used for
customization.
%T A string with two possible values: 80 spaces if the
article is on thread level two or larger and 0 spaces
on level one
%R \"A\" if this article has been replied to, \" \"
otherwise (character)
%U \"Read\" status of this article.
See Info node `(gnus)Marking Articles'
%[ Opening bracket (character, \"[\" or \"<\")
%] Closing bracket (character, \"]\" or \">\")
%> Spaces of length thread-level (string)
%< Spaces of length (- 20 thread-level) (string)
%i Article score (number)
%z Article zcore (character)
%t Number of articles under the current thread (number).
%e Whether the thread is empty or not (character).
%V Total thread score (number).
%P The line number (number).
%O Download mark (character).
%* If present, indicates desired cursor position
(instead of after first colon).
%u User defined specifier. The next character in the
format string should be a letter. Gnus will call the
function gnus-user-format-function-X, where X is the
letter following %u. The function will be passed the
current header as argument. The function should
return a string, which will be inserted into the
summary just like information from any other summary
specifier.
%&user-date; Age sensitive date format. Various date format is
defined in `gnus-user-date-format-alist'.
The %U (status), %R (replied) and %z (zcore) specs have to be handled

View file

@ -349,20 +349,40 @@ directory, like `default-directory'."
(make-obsolete-variable 'ibuffer-load-hook
"use `with-eval-after-load' instead." "28.1")
(defcustom ibuffer-marked-face 'warning
(defface ibuffer-marked '((t :inherit warning))
"Face used by default in `ibuffer-marked-face'."
:version "31.1")
(defface ibuffer-deletion '((t :inherit error))
"Face used by default in `ibuffer-deletion-face'."
:version "31.1")
(defface ibuffer-title '((t :inherit font-lock-type-face))
"Face used by default in `ibuffer-title-face'."
:version "31.1")
(defface ibuffer-filter-group-name '((t :inherit bold))
"Face used by default in `ibuffer-filter-group-name-face'."
:version "31.1")
(defcustom ibuffer-marked-face 'ibuffer-marked
"Face used for displaying marked buffers."
:version "31.1"
:type 'face)
(defcustom ibuffer-deletion-face 'error
(defcustom ibuffer-deletion-face 'ibuffer-deletion
"Face used for displaying buffers marked for deletion."
:version "31.1"
:type 'face)
(defcustom ibuffer-title-face 'font-lock-type-face
(defcustom ibuffer-title-face 'ibuffer-title
"Face used for the title string."
:version "31.1"
:type 'face)
(defcustom ibuffer-filter-group-name-face 'bold
(defcustom ibuffer-filter-group-name-face 'ibuffer-filter-group-name
"Face used for displaying filtering group names."
:version "31.1"
:type 'face)
(defcustom ibuffer-directory-abbrev-alist nil

View file

@ -1760,7 +1760,7 @@ in-place."
(defcustom auto-coding-alist
;; .exe and .EXE are added to support archive-mode looking at DOS
;; self-extracting exe archives.
'(("\\.\\(\
'(("\\.\\(\
arc\\|zip\\|lzh\\|lha\\|zoo\\|[jew]ar\\|xpi\\|rar\\|7z\\|squashfs\\|\
ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\|SQUASHFS\\)\\'"
. no-conversion-multibyte)
@ -1769,6 +1769,10 @@ ARC\\|ZIP\\|LZH\\|LHA\\|ZOO\\|[JEW]AR\\|XPI\\|RAR\\|7Z\\|SQUASHFS\\)\\'"
("\\.\\(gz\\|Z\\|bz\\|bz2\\|xz\\|gpg\\)\\'" . no-conversion)
("\\.\\(jpe?g\\|png\\|gif\\|tiff?\\|p[bpgn]m\\)\\'" . no-conversion)
("\\.pdf\\'" . no-conversion)
;; https://spec.editorconfig.org/ says:
;; EditorConfig files must be UTF-8 encoded,
;; with LF or CRLF line separators.
("/\\.editorconfig\\'" . utf-8-undecided)
("/#[^/]+#\\'" . utf-8-emacs-unix))
"Alist of filename patterns vs corresponding coding systems.
Each element looks like (REGEXP . CODING-SYSTEM).

File diff suppressed because it is too large Load diff

View file

@ -141,8 +141,7 @@ This metadata is an alist. Currently understood keys are:
- `cycle-sort-function': function to sort entries when cycling.
Works like `display-sort-function'.
- `eager-display': non-nil to request eager display of the
completion candidates. Can also be a function which is invoked
after minibuffer setup.
completion candidates.
The metadata of a completion table should be constant between two boundaries."
(let ((metadata (if (functionp table)
(funcall table string pred 'metadata))))
@ -1278,7 +1277,7 @@ an association list that can specify properties such as:
- `group-function': function for grouping the completion candidates.
- `annotation-function': function to add annotations in *Completions*.
- `affixation-function': function to prepend/append a prefix/suffix.
- `eager-display': function to show *Completions* eagerly.
- `eager-display': non-nil to show *Completions* eagerly.
Categories are symbols such as `buffer' and `file', used when
completing buffer and file names, respectively.
@ -1300,7 +1299,7 @@ possible values are the same as in `completions-sort'.
- `group-function': function for grouping the completion candidates.
- `annotation-function': function to add annotations in *Completions*.
- `affixation-function': function to prepend/append a prefix/suffix.
- `eager-display': function to show *Completions* eagerly.
- `eager-display': non-nil to show *Completions* eagerly.
See more description of metadata in `completion-metadata'.
Categories are symbols such as `buffer' and `file', used when
@ -2754,6 +2753,24 @@ so that the update is less likely to interfere with user typing."
((completion--eager-update-p (minibuffer-prompt-end))
(minibuffer-completion-help))))))
(defvar completion-eager-display--timer nil)
(defun completions--eager-display ()
"Try to display *Completions* without blocking input."
;; If the user has left the minibuffer, give up on eager display of
;; *Completions*.
(when (minibufferp nil t)
(when (while-no-input
(let ((non-essential t))
(minibuffer-completion-help)))
;; If we got interrupted, try again the next time the user is idle.
(completions--start-eager-display))))
(defun completions--start-eager-display ()
"Display the *Completions* buffer when the user is next idle."
(setq completion-eager-display--timer
(run-with-idle-timer 0 nil #'completions--eager-display)))
(defun completions--post-command-update ()
"Update displayed *Completions* buffer after command, once."
(remove-hook 'post-command-hook #'completions--post-command-update)
@ -5143,14 +5160,14 @@ See `completing-read' for the meaning of the arguments."
;; `completion-eager-display' is t or if eager display
;; has been requested by the completion table.
(when completion-eager-display
(let* ((md (completion-metadata
(when (or (eq completion-eager-display t)
(completion-metadata-get
(completion-metadata
(buffer-substring-no-properties
(minibuffer-prompt-end) (point))
collection predicate))
(fun (completion-metadata-get md 'eager-display)))
(when (or fun (eq completion-eager-display t))
(funcall (if (functionp fun)
fun #'minibuffer-completion-help))))))
collection predicate)
'eager-display))
(completions--start-eager-display))))
(read-from-minibuffer prompt initial-input keymap
nil hist def inherit-input-method))))
(when (and (equal result "") def)

View file

@ -406,10 +406,15 @@ modified buffer to be able to use unsaved changes."
(declare-function diff-setup-whitespace "diff-mode" ())
(declare-function diff-setup-buffer-type "diff-mode" ())
(defvar coding-system--for-buffer-diff nil
"Used to pass encoding down to callees of `multi-file-diff-no-select'.")
;;;###autoload
(defun multi-file-replace-as-diff (files from-string replacements regexp-flag delimited-flag)
"Show as diffs replacements of FROM-STRING with REPLACEMENTS.
FILES is a list of file names. REGEXP-FLAG and DELIMITED-FLAG have
the same meaning as in `perform-replace'."
FILES is a list of file names. Also it's possible to provide a list of
buffers in FILES. REGEXP-FLAG and DELIMITED-FLAG have the same meaning
as in `perform-replace'."
(require 'diff)
(let ((inhibit-message t)
(diff-buffer (get-buffer-create "*replace-diff*")))
@ -427,12 +432,23 @@ the same meaning as in `perform-replace'."
(setq buffer-read-only t)
(diff-mode))
(dolist (file-name files)
(let* ((file-exists (file-exists-p file-name))
(let* ((non-file-buffer (and (buffer-live-p file-name)
(not (buffer-local-value
'buffer-file-name file-name))))
(file-exists (unless non-file-buffer
(file-exists-p file-name)))
(file-buffer
(when (or (not file-exists)
(eq multi-file-diff-unsaved 'use-modified-buffer))
(find-buffer-visiting file-name))))
(when file-name
(if non-file-buffer
file-name
(when (or (not file-exists)
(eq multi-file-diff-unsaved 'use-modified-buffer))
(find-buffer-visiting file-name))))
;; Make sure any supported characters can be written to a
;; file without asking the user to select a safe
;; coding-system.
(coding-system--for-buffer-diff 'utf-8-emacs))
(when non-file-buffer (setq file-name (buffer-name file-name)))
(when (or file-exists file-buffer)
(with-temp-buffer
(if (and file-buffer
(or (not file-exists)
@ -488,7 +504,8 @@ you can later apply as a patch after reviewing the changes."
t t)))
(list (nth 0 common) (nth 1 common) (nth 2 common))))
(multi-file-replace-as-diff
(list buffer-file-name) regexp to-string t delimited))
(list (or buffer-file-name (current-buffer)))
regexp to-string t delimited))
(defvar diff-use-labels)
(declare-function diff-check-labels "diff" (&optional force))
@ -530,7 +547,9 @@ specify labels to use for file names."
(or new-alt new)))))
" ")))
(with-current-buffer buf
(let ((inhibit-read-only t))
(let ((inhibit-read-only t)
(coding-system-for-read (or coding-system--for-buffer-diff
coding-system-for-read)))
(insert command "\n")
(call-process shell-file-name nil buf nil
shell-command-switch command))

View file

@ -853,6 +853,17 @@ This command must be bound to a mouse click."
(split-window-horizontally
(min (max new-width first-col) last-col)))))))
(defun mouse-position-for-drag-line (tty)
"Return the last mouse position observed for the purposes of `mouse-drag-line'.
If TTY is non-nil, return the last attested position of the mouse
relative to the root frame. Otherwise, return the position of the mouse
relative to the selected frame, unless the current drag operation was
produced from a touch screen event, in which event, return the position
of the active touch-screen tool relative to the same."
(if tty (mouse-position-in-root-frame)
(or (touch-screen-last-drag-position)
(mouse-absolute-pixel-position))))
(defun mouse-drag-line (start-event line)
"Drag a mode, header, tab or vertical line with the mouse.
START-EVENT is the starting mouse event of the drag action. LINE
@ -888,9 +899,7 @@ must be one of the symbols `header', `mode', `tab' or `vertical'."
;; START-EVENT here because that would give us coordinates for
;; 'posn-window' of that event and we don't want that (see the
;; comment above).
(position-x-y (if tty
(mouse-position-in-root-frame)
(mouse-absolute-pixel-position)))
(position-x-y (mouse-position-for-drag-line tty))
;; 'position' records the x- (for vertical dragging) or y- (for
;; mode, header and tab line dragging) coordinate of the
;; current mouse position
@ -956,9 +965,7 @@ must be one of the symbols `header', `mode', `tab' or `vertical'."
nil)
((eq line 'vertical)
;; Drag right edge of 'window'.
(setq position (if tty
(car (mouse-position-in-root-frame))
(car (mouse-absolute-pixel-position))))
(setq position (car (mouse-position-for-drag-line tty)))
(unless (zerop (setq growth (- position last-position)))
;; When we drag characterwise and we either drag for
;; the first time or the dragging direction changes,
@ -989,9 +996,7 @@ must be one of the symbols `header', `mode', `tab' or `vertical'."
))
(t
;; Drag bottom edge of 'window'.
(setq position (cdr (if tty
(mouse-position-in-root-frame)
(mouse-absolute-pixel-position))))
(setq position (cdr (mouse-position-for-drag-line tty)))
(unless (zerop (setq growth (- position last-position)))
;; When we drag characterwise and we either drag for
;; the first time or the dragging direction changes,

View file

@ -148,8 +148,6 @@ Example: (\"Topmost group\" \"feed1\" (\"subgroup1\" \"feed 2\")
(defvar newsticker--treeview-feed-tree nil)
(defvar newsticker--treeview-vfeed-tree nil)
(declare-function newsticker-handle-url "newst-plainview" ())
;; maps for the clickable portions
(defvar newsticker--treeview-url-keymap
(let ((map (make-sparse-keymap 'newsticker--treeview-url-keymap)))
@ -157,7 +155,7 @@ Example: (\"Topmost group\" \"feed1\" (\"subgroup1\" \"feed 2\")
(define-key map [mouse-2] #'newsticker-treeview-mouse-browse-url)
(define-key map "\n" #'newsticker-treeview-browse-url)
(define-key map "\C-m" #'newsticker-treeview-browse-url)
(define-key map [(control return)] #'newsticker-handle-url)
(define-key map [(control return)] #'newsticker--treeview-handle-url)
map)
"Key map for click-able headings in the newsticker treeview buffers.")
@ -247,6 +245,19 @@ their id stays constant."
"Return current node in newsticker treeview tree."
(newsticker--treeview-get-node-by-id newsticker--treeview-current-node-id))
(defun newsticker--treeview-handle-url ()
"Ask for a program to open the link of the item at point."
(interactive)
(let ((url (get-text-property (point) 'nt-link)))
(when url
(let ((prog (read-string "Open url with: " nil
'newsticker-open-url-history)))
(when prog
(message "%s %s" prog url)
(start-process prog prog prog url)
(if newsticker-automatically-mark-visited-items-as-old
(newsticker-treeview-mark-item-old)))))))
;; ======================================================================
(declare-function w3m-toggle-inline-images "ext:w3m" (&optional force no-cache))

View file

@ -6,6 +6,7 @@
;; Maintainer: Thomas Fitzsimmons <fitzsim@fitzsim.org>
;; Keywords: NTLM, SASL, comm
;; Version: 2.1.0
;; Package-Requires: ((emacs "27.1"))
;; Created: February 2001
;; This is a GNU ELPA :core package. Avoid functionality that is not
@ -228,11 +229,12 @@ Return a random eight byte unibyte string."
(random 256) (random 256) (random 256) (random 256)))
(defun ntlm-build-auth-response (challenge user password-hashes)
"Return the response string to a challenge string CHALLENGE given by
the NTLM based server for the user USER and the password hash list
PASSWORD-HASHES. NTLM uses two hash values which are represented
by PASSWORD-HASHES. PASSWORD-HASHES should be a return value of
(list (ntlm-smb-passwd-hash password) (ntlm-md4hash password))"
"Return the NTLM authentication response string.
Return the response string to a challenge string CHALLENGE given by the
NTLM based server for the user USER and the password hash list
PASSWORD-HASHES. NTLM uses two hash values which are represented by
PASSWORD-HASHES. PASSWORD-HASHES should be the return value
of (list (ntlm-smb-passwd-hash password) (ntlm-md4hash password))"
(let* ((rchallenge (if (multibyte-string-p challenge)
(progn
;; FIXME: Maybe it would be better to
@ -615,7 +617,7 @@ length of STR is LEN."
(concat (substring str c len) (substring str 0 c))))
(defsubst ntlm-string-xor (in1 in2 n)
"Return exclusive-or of sequences in1 and in2."
"Return exclusive-or of sequences IN1 and IN2 of length N."
(let ((w (make-string n 0)) (i 0))
(while (< i n)
(aset w i (logxor (aref in1 i) (aref in2 i)))

View file

@ -1430,6 +1430,8 @@ either nil or one of the symbols `start-tag', `end-tag', `markup',
(if (memq context '(nil end-tag comment))
'end-tag
'mixed))
((eq xmltok-type 'cdata-section)
(or context 'markup))
((eq xmltok-type 'comment)
(cond ((memq context '(start-tag end-tag comment))
context)
@ -1519,7 +1521,9 @@ OPEN-DELIM and CLOSE-DELIM are strings giving the opening and closing
delimiters. POS is the position of the first non-whitespace character
of the line. This expects the xmltok-* variables to be set up as by
`xmltok-forward'."
(cond ((let ((end (+ pos (length close-delim))))
(cond ((string= open-delim "<![CDATA[")
(goto-char pos))
((let ((end (+ pos (length close-delim))))
(and (<= end (point-max))
(string= (buffer-substring-no-properties pos end)
close-delim)))

View file

@ -267,10 +267,13 @@ non-nil and point is located on the heading line.")
;; This is equivalent to adding ".*" in the regexp below.
(set-match-data
(list (match-beginning 0)
(save-excursion
(save-match-data
(re-search-forward
(concat ".*" outline-heading-end-regexp) nil t)))))
(or (save-excursion
(save-match-data
(re-search-forward
(concat ".*" outline-heading-end-regexp) nil t)))
;; Fall back to eol when there is no newline
;; at the end of outline at eob.
(pos-eol))))
ret)))
(concat "^\\(?:" outline-regexp "\\).*" outline-heading-end-regexp))
0 '(if outline-minor-mode
@ -531,10 +534,13 @@ outline font-lock faces to those of major mode."
;; This is equivalent to adding ".*" in the regexp above.
(set-match-data
(list (match-beginning 0)
(save-excursion
(save-match-data
(re-search-forward
(concat ".*" outline-heading-end-regexp) nil t)))))
(or (save-excursion
(save-match-data
(re-search-forward
(concat ".*" outline-heading-end-regexp) nil t)))
;; Fall back to eol when there is no newline
;; at the end of outline at eob.
(pos-eol))))
ret)
(re-search-forward regexp nil t))
(let ((overlay (make-overlay (match-beginning 0) (match-end 0))))
@ -2030,12 +2036,7 @@ With a prefix argument, show headings up to that LEVEL."
from to)
(restore-buffer-modified-p modified))))
(defvar outline-after-change-functions nil
"Hook run before updating buttons in a region in outline-mode.
Called with three arguments (BEG END DUMMY). Don't use DUMMY.")
(defun outline--fix-buttons (&optional beg end)
(run-hook-with-args 'outline-after-change-functions beg end 0)
;; Handle whole lines
(save-excursion
(setq beg (if (null beg) (point-min) (goto-char beg) (pos-bol)))

View file

@ -407,7 +407,7 @@ and /* */ comments. SOFT works the same as in
:language 'doxygen
:override t
:feature 'keyword
'((tag_name) @font-lock-constant-face
'((tag_name) @font-lock-doc-markup-face
(type) @font-lock-type-face
(emphasis) @bold
((tag_name) @bold (:match ".note" @bold))

View file

@ -86,6 +86,8 @@
;;; Variables also used at compile time.
;; IMPORTANT NOTE! On changing `c-version', also update the "version
;; header" near the beginning of cc-mode.el to match.
(defconst c-version "5.35.2"
"CC Mode version number.")

View file

@ -12,7 +12,7 @@
;; Created: a long, long, time ago. adapted from the original c-mode.el
;; Keywords: c languages
;; The version header below is used for ELPA packaging.
;; Version: 5.33.1
;; Version: 5.35.2
;; This file is part of GNU Emacs.

View file

@ -2443,7 +2443,8 @@ The parent is always `compilation-mode' and the customizable `compilation-...'
variables are also set from the name of the mode you have chosen,
by replacing the first word, e.g., `compilation-scroll-output' from
`grep-scroll-output' if that variable exists."
(declare (indent defun))
(declare (indent defun)
(autoload-macro expand))
(let ((mode-name (replace-regexp-in-string "-mode\\'" "" (symbol-name mode))))
`(define-derived-mode ,mode compilation-mode ,name
,doc

View file

@ -197,12 +197,11 @@
(c-lang-defconst c-at-vsemi-p-fn
csharp 'csharp-at-vsemi-p)
(defun csharp-vsemi-status-unknown () t)
(defun csharp-vsemi-status-unknown-p () t)
(c-lang-defconst c-vsemi-status-unknown-p-fn
csharp 'csharp-vsemi-status-unknown-p)
(c-lang-defconst c-modifier-kwds
csharp '("abstract" "default" "final" "native" "private" "protected"
"public" "partial" "internal" "readonly" "static" "event" "transient"
@ -240,9 +239,6 @@
(c-lang-defconst c-inexpr-class-kwds
csharp nil)
(c-lang-defconst c-class-decl-kwds
csharp '("class" "struct" "interface"))
(c-lang-defconst c-std-abbrev-keywords
csharp (append (c-lang-const c-std-abbrev-keywords) '("catch" "finally")))
@ -594,7 +590,6 @@ compilation and evaluation time conflicts."
"[[:blank:]]+Stack Trace:\n"
"[[:blank:]]+at [^\n]+ in \\([^\n]+\\):line \\([0-9]+\\)"))
(eval-after-load 'compile
(lambda ()
(dolist
@ -1036,6 +1031,7 @@ function is called. Subsequent calls return the first evaluated value."
(string_literal)
(binary_expression)
(invocation_expression)
(await_expression)
(member_access_expression)
(conditional_expression)])
@ -1080,11 +1076,6 @@ function is called. Subsequent calls return the first evaluated value."
name: (identifier) @font-lock-function-name-face
(lambda_expression)))
:language 'c-sharp
:feature 'escape-sequence
:override t
'((escape_sequence) @font-lock-escape-face)
:language 'c-sharp
:feature 'directives
:override t

View file

@ -573,6 +573,7 @@ under cursor."
(const :tag "Fold regions of buffer" :foldingRangeProvider)
(const :tag "Execute custom commands" :executeCommandProvider)
(const :tag "Inlay hints" :inlayHintProvider)
(const :tag "Semantic tokens" :semanticTokensProvider)
(const :tag "Type hierarchies" :typeHierarchyProvider)
(const :tag "Call hierarchies" :callHierarchyProvider)))
@ -660,6 +661,47 @@ This can be useful when using docker to run a language server.")
`((1 . eglot-diagnostic-tag-unnecessary-face)
(2 . eglot-diagnostic-tag-deprecated-face)))
(eval-when-compile
(defconst eglot--semtok-types
'(("namespace" . font-lock-keyword-face)
("type" . font-lock-type-face)
("class" . font-lock-type-face)
("enum" . font-lock-type-face)
("interface" . font-lock-type-face)
("struct" . font-lock-type-face)
("typeParameter" . font-lock-type-face)
("parameter" . font-lock-variable-name-face)
("variable" . font-lock-variable-name-face)
("property" . font-lock-property-use-face)
("enumMember" . font-lock-constant-face)
("event" . font-lock-variable-name-face)
("function" . font-lock-function-name-face)
("method" . font-lock-function-name-face)
("macro" . font-lock-preprocessor-face)
("keyword" . font-lock-keyword-face)
("modifier" . font-lock-function-name-face)
("comment" . font-lock-comment-face)
("string" . font-lock-string-face)
("number" . font-lock-constant-face)
("regexp" . font-lock-string-face)
("operator" . font-lock-function-name-face)
("decorator" . font-lock-type-face)))
(defconst eglot--semtok-modifiers
'(("declaration" . font-lock-function-name-face)
("definition" . font-lock-function-name-face)
("readonly" . font-lock-constant-face)
("static" . font-lock-keyword-face)
("deprecated" . eglot-diagnostic-tag-deprecated-face)
("abstract" . font-lock-keyword-face)
("async" . font-lock-preprocessor-face)
("modification" . font-lock-function-name-face)
("documentation" . font-lock-doc-face)
("defaultLibrary" . font-lock-builtin-face))))
(defvar eglot-semantic-token-types) ;; forward-declare
(defvar eglot-semantic-token-modifiers) ;; forward-declare
(defvaralias 'eglot-{} 'eglot--{})
(defconst eglot--{} (make-hash-table :size 0) "The empty JSON object.")
@ -711,6 +753,7 @@ This can be useful when using docker to run a language server.")
(ResponseError (:code :message) (:data))
(ShowMessageParams (:type :message))
(ShowMessageRequestParams (:type :message) (:actions))
(SemanticTokensLegend (:tokenTypes :tokenModifiers))
(SignatureHelp (:signatures) (:activeSignature :activeParameter))
(SignatureInformation (:label) (:documentation :parameters :activeParameter))
(SymbolInformation (:name :kind :location)
@ -1018,6 +1061,7 @@ object."
`(:dynamicRegistration
,(if (eglot--trampish-p s) :json-false t))
:symbol `(:dynamicRegistration :json-false)
:semanticTokens '(:refreshSupport t)
:configuration t
:workspaceFolders t)
:textDocument
@ -1080,6 +1124,13 @@ object."
:formatting `(:dynamicRegistration :json-false)
:rangeFormatting `(:dynamicRegistration :json-false)
:rename `(:dynamicRegistration :json-false)
:semanticTokens `(:dynamicRegistration :json-false
:requests '(:range t :full (:delta t))
:overlappingTokenSupport t
:multilineTokenSupport t
:tokenTypes [,@eglot-semantic-token-types]
:tokenModifiers [,@eglot-semantic-token-modifiers]
:formats ["relative"])
:inlayHint `(:dynamicRegistration :json-false)
:callHierarchy `(:dynamicRegistration :json-false)
:typeHierarchy `(:dynamicRegistration :json-false)
@ -1150,7 +1201,10 @@ object."
:accessor eglot--managed-buffers)
(saved-initargs
:documentation "Saved initargs for reconnection purposes."
:accessor eglot--saved-initargs))
:accessor eglot--saved-initargs)
(semtok-cache
:initform (make-hash-table :test #'equal)
:documentation "Map LSP token conses to face names."))
:documentation
"Represents a server. Wraps a process for LSP communication.")
@ -1205,13 +1259,18 @@ TRUENAMEP indicated PATH is already a truename."
eglot--uri-path-allowed-chars)))))
(defun eglot-range-region (range &optional markers)
"Return a cons (BEG . END) of positions representing LSP RANGE.
"Convert LSP \"Range\" RANGE to cons (BEG . END) of buffer positions.
If optional MARKERS, make markers instead."
(let* ((st (plist-get range :start))
(beg (eglot--lsp-position-to-point st markers))
(end (eglot--lsp-position-to-point (plist-get range :end) markers)))
(cons beg end)))
(defun eglot-region-range (from to)
"Convert FROM and TO buffer positions to an LSP \"Range\"."
(list :start (eglot--pos-to-lsp-position from)
:end (eglot--pos-to-lsp-position to)))
(defun eglot-server-capable (&rest feats)
"Determine if current server is capable of FEATS."
(unless (cl-some (lambda (feat)
@ -1898,7 +1957,13 @@ and also used as a hint of the request cancellation mechanism (see
moreargs))))
(when (and hint eglot-advertise-cancellation)
(push id
(plist-get eglot--inflight-async-requests hint))))))
(plist-get eglot--inflight-async-requests hint)))
id)))
(cl-defun eglot--delete-overlays (&optional (prop 'eglot--overlays))
(eglot--widening
(dolist (o (overlays-in (point-min) (point-max)))
(when (overlay-get o prop) (delete-overlay o)))))
;;; Encoding fever
@ -1992,21 +2057,19 @@ encoding and Eglot will set this variable automatically.")
(defun eglot--lsp-position-to-point (pos-plist &optional marker)
"Convert LSP position POS-PLIST to Emacs point.
If optional MARKER, return a marker instead"
(save-excursion
(save-restriction
(widen)
(goto-char (point-min))
(forward-line (min most-positive-fixnum
(plist-get pos-plist :line)))
(unless (eobp) ;; if line was excessive leave point at eob
(let ((col (plist-get pos-plist :character)))
(unless (wholenump col)
(eglot--warn
"Caution: LSP server sent invalid character position %s. Using 0 instead."
col)
(setq col 0))
(funcall eglot-move-to-linepos-function col)))
(if marker (copy-marker (point-marker)) (point)))))
(eglot--widening
(goto-char (point-min))
(forward-line (min most-positive-fixnum
(plist-get pos-plist :line)))
(unless (eobp) ;; if line was excessive leave point at eob
(let ((col (plist-get pos-plist :character)))
(unless (wholenump col)
(eglot--warn
"Caution: LSP server sent invalid character position %s. Using 0 instead."
col)
(setq col 0))
(funcall eglot-move-to-linepos-function col)))
(if marker (copy-marker (point-marker)) (point))))
;;; More helpers
@ -2206,8 +2269,9 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
(eldoc-mode 1))
(cl-pushnew (current-buffer) (eglot--managed-buffers (eglot-current-server))))
(t
(mapc #'delete-overlay eglot--highlights)
(delete-overlay eglot--suggestion-overlay)
(eglot-inlay-hints-mode -1)
(eglot-semantic-tokens-mode -1)
(eglot--delete-overlays 'eglot--overlay)
(remove-hook 'after-change-functions #'eglot--after-change t)
(remove-hook 'before-change-functions #'eglot--before-change t)
(remove-hook 'kill-buffer-hook #'eglot--managed-mode-off t)
@ -2248,8 +2312,6 @@ Use `eglot-managed-p' to determine if current buffer is managed.")
(defun eglot--managed-mode-off ()
"Turn off `eglot--managed-mode' unconditionally."
(remove-overlays nil nil 'eglot--overlay t)
(eglot-inlay-hints-mode -1)
(eglot--managed-mode -1))
(defun eglot-current-server ()
@ -2297,6 +2359,7 @@ If it is activated, also signal textDocument/didOpen."
;; Run user hook after 'textDocument/didOpen' so server knows
;; about the buffer.
(eglot-inlay-hints-mode 1)
(eglot-semantic-tokens-mode 1)
(run-hooks 'eglot-managed-mode-hook))))
(add-hook 'after-change-major-mode-hook #'eglot--maybe-activate-editing-mode)
@ -2964,6 +3027,13 @@ Records BEG, END and PRE-CHANGE-LENGTH locally."
`(,lsp-beg ,lsp-end ,pre-change-length
,(buffer-substring-no-properties beg end)))))
(_ (setf eglot--recent-changes :emacs-messup)))
;; JT@2025-11-14: Not 100% sure an idle timer is right to coalesce
;; multiple edits into a single didChange notification. It allows,
;; for example, user to modify the buffer in one place, spend
;; arbitrary time in quick successive movement and edit again. Only
;; after the idle delay will the change be sent. A regular timer
;; would be simpler would notify the server to start processing
;; changes sooner.
(when eglot--change-idle-timer (cancel-timer eglot--change-idle-timer))
(let ((buf (current-buffer)))
(setq eglot--change-idle-timer
@ -3396,8 +3466,7 @@ for which LSP on-type-formatting should be requested."
((and beg end)
`(:textDocument/rangeFormatting
:documentRangeFormattingProvider
(:range ,(list :start (eglot--pos-to-lsp-position beg)
:end (eglot--pos-to-lsp-position end)))))
(:range ,(eglot-region-range beg end))))
(t
'(:textDocument/formatting :documentFormattingProvider nil)))))
(eglot-server-capable-or-lose cap)
@ -3805,6 +3874,7 @@ for which LSP on-type-formatting should be requested."
(eglot-range-region range)))
(let ((ov (make-overlay beg end)))
(overlay-put ov 'face 'eglot-highlight-symbol-face)
(overlay-put ov 'eglot--overlay t)
(overlay-put ov 'modification-hooks
`(,(lambda (o &rest _) (delete-overlay o))))
ov)))
@ -4005,12 +4075,10 @@ edit proposed by the server."
(defun eglot-rename (newname)
"Rename the current symbol to NEWNAME."
(interactive
(list (read-from-minibuffer
(eglot--format "Rename `%s' to: "
(or (thing-at-point 'symbol t)
"unknown symbol"))
nil nil nil nil
(symbol-name (symbol-at-point)))))
(let ((tap (thing-at-point 'symbol t)))
(list (read-from-minibuffer
(format "Rename `%s' to: " (or tap "unknown symbol"))
tap nil nil nil tap))))
(eglot-server-capable-or-lose :renameProvider)
(eglot--apply-workspace-edit
(eglot--request (eglot--current-server-or-lose)
@ -4035,8 +4103,7 @@ edit proposed by the server."
(cl-defun eglot--code-action-params (&key (beg (point)) (end beg)
only triggerKind)
(list :textDocument (eglot--TextDocumentIdentifier)
:range (list :start (eglot--pos-to-lsp-position beg)
:end (eglot--pos-to-lsp-position end))
:range (eglot-region-range beg end)
:context
`(:diagnostics
[,@(mapcar #'eglot--diag-to-lsp-diag
@ -4163,6 +4230,7 @@ at point. With prefix argument, prompt for ACTION-KIND."
(goto-char (car bounds))
(let ((ov (make-overlay (car bounds) (cadr bounds))))
(overlay-put ov 'eglot--actions actions)
(overlay-put ov 'eglot--overlay t)
(overlay-put
ov
'before-string
@ -4470,8 +4538,7 @@ If NOERROR, return predicate, else erroring function."
(eglot--current-server-or-lose)
:textDocument/inlayHint
(list :textDocument (eglot--TextDocumentIdentifier)
:range (list :start (eglot--pos-to-lsp-position from)
:end (eglot--pos-to-lsp-position to)))
:range (eglot-region-range from to))
:success-fn (lambda (hints)
(eglot--when-live-buffer buf
(eglot--widening
@ -4500,7 +4567,259 @@ If NOERROR, return predicate, else erroring function."
(eglot-inlay-hints-mode -1)))
(t
(jit-lock-unregister #'eglot--update-hints)
(remove-overlays nil nil 'eglot--inlay-hint t))))
(eglot--delete-overlays 'eglot--inlay-hint))))
;;; Semantic tokens
(defmacro eglot--semtok-define-things ()
(cl-flet ((def-it (name def)
`(defface ,(intern (format "eglot-semantic-%s-face" name))
'((t (:inherit ,def)))
,(format "Face for painting a `%s' LSP semantic token" name)
:group 'eglot-semantic-fontification)))
(let ((types (mapcar #'car eglot--semtok-types))
(modifiers (mapcar #'car eglot--semtok-modifiers)))
`(progn
(defgroup eglot-semantic-faces nil
"Faces and options for LSP semantic fontification." :group 'eglot)
,@(cl-loop for (n . d) in eglot--semtok-types collect (def-it n d))
,@(cl-loop for (n . d) in eglot--semtok-modifiers collect (def-it n d))
(defcustom eglot-semantic-token-types
',types "LSP-supplied semantic types Eglot should consider."
:type '(set ,@(mapcar (lambda (o) `(const ,o)) types))
:group 'eglot-semantic-fontification)
(defcustom eglot-semantic-token-modifiers
',modifiers "LSP-supplied semantic modifiers Eglot should consider."
:type '(set ,@(mapcar (lambda (o) `(const ,o)) modifiers))
:group 'eglot-semantic-fontification)))))
(eglot--semtok-define-things)
(defun eglot--semtok-decode-token (tok)
"Decode TOK. Return (NAMES . FACES). Filter FACES via user options."
(with-slots (semtok-cache capabilities)
(eglot--current-server-or-lose)
(let ((probe (gethash tok semtok-cache :missing)))
(if (eq probe :missing)
(puthash
tok
(eglot--dbind ((SemanticTokensLegend) tokenTypes tokenModifiers)
(plist-get (plist-get capabilities :semanticTokensProvider) :legend)
(cl-loop
with tname = (aref tokenTypes (car tok))
for j from 0 for m across tokenModifiers
when (cl-plusp (logand (cdr tok) (ash 1 j)))
collect m into names
and when (member m eglot-semantic-token-modifiers)
collect (intern (format "eglot-semantic-%s-face" m)) into faces
finally
(when (member tname eglot-semantic-token-types)
(push (intern (format "eglot-semantic-%s-face" tname)) faces))
(cl-return (cons (cons tname names) faces))))
semtok-cache)
probe))))
(defvar-local eglot--semtok-cache nil
"List of plists describing recent semtok response.
See `eglot--semtok-request' implementation for details.")
(defvar-local eglot--semtok-inflight (make-hash-table)
"Map of JSONRPC request ID to (METHOD DOCVER . REGIONS).
REGIONS is a list of (BEG . END) of positions that can be serviced by
this request.")
(cl-defmethod eglot-handle-request
(server (_method (eql workspace/semanticTokens/refresh)))
"Handle a semanticTokens/refresh request from SERVER."
(dolist (buffer (eglot--managed-buffers server))
(eglot--when-live-buffer buffer
(eglot--widening
(font-lock-flush)))))
(define-minor-mode eglot-semantic-tokens-mode
"Minor mode for fontifying buffer with LSP server's semantic tokens."
:global nil
(setq eglot--semtok-cache nil)
(clrhash eglot--semtok-inflight)
(cond (eglot-semantic-tokens-mode
(if (not (eglot-server-capable :semanticTokensProvider))
(eglot-semantic-tokens-mode -1)
(font-lock-add-keywords nil '((eglot--semtok-font-lock)) 'append)
(font-lock-flush)))
(t
(font-lock-remove-keywords nil '((eglot--semtok-font-lock)))
(font-lock-flush))))
(defsubst eglot--semtok-apply-delta-edits (old-data edits)
"Apply EDITS obtained from full/delta request to OLD-DATA."
(cl-loop
for old-i = 0 then (+ (plist-get edit :start) (plist-get edit :deleteCount))
for edit across edits
when (< old-i (plist-get edit :start))
vconcat (substring old-data old-i (plist-get edit :start)) into new
vconcat (plist-get edit :data) into new
finally
(cl-return (vconcat new (substring old-data old-i (length old-data))))))
(cl-defun eglot--semtok-request
(beg end &aux (docver eglot--versioned-identifier) reused)
"Ask for tokens. Arrange for BEG..END to be font-lock flushed."
(cl-labels
((fullish-p (m)
(memq m '(:textDocument/semanticTokens/full/delta
:textDocument/semanticTokens/full)))
(prune-outdated ()
(setq eglot--semtok-cache
(cl-delete-if (lambda (e)
(not (eq docver (plist-get e :docver))))
eglot--semtok-cache)))
(req (method params &optional cont
&aux req-id (buf (current-buffer)))
(setq req-id
(eglot--async-request
(eglot--current-server-or-lose) method params
:success-fn
(lambda (response)
(eglot--when-live-buffer buf
(pcase-let ((`(,method ,docver ,regions)
(gethash req-id eglot--semtok-inflight)))
(remhash req-id eglot--semtok-inflight)
;; (trace-values "Response: "
;; method
;; eglot--versioned-identifier docver
;; "edits: "
;; (length (cl-getf response :edits))
;; "data: "
;; (length (cl-getf response :data)))
;; A user edit may have come in while the request
;; was inflight, changing the state of the buffer...
(when (eq docver eglot--versioned-identifier)
(push
(list :docver docver
:method method
:resultId (plist-get response :resultId)
:data (if cont (funcall cont response)
(plist-get response :data))
:valid (if (fullish-p method)
(eglot--widening
(cons (point-min) (point-max)))
(cons beg end)))
eglot--semtok-cache))
;; ... but we should flush unconditionally. If
;; this response was out-of-date,
;; `eglot--semtok-font-lock' should just trigger
;; another request.
(cl-loop for (b . e) in regions
do (font-lock-flush b e))
;; (trace-values "Flushed" (length regions)
;; "regions" regions)
)))
;; For "range" requests, make sure we have one unique
;; request defeating part of the "deferred" mechanism.
:hint (if (fullish-p method) method
(gensym (symbol-name method)))))
;; Can prune outdated entries now, not earlier, since "delta"
;; requests rely on outdated entries by definition.
(prune-outdated)
(puthash req-id (list method docver (list (cons beg end)))
eglot--semtok-inflight)))
;; JT@2025-11-16: Many back-to-back calls for
;; `eglot--semtok-request' and small regions occur even on
;; trivial/fast edits. We try to send just one request. If there
;; is a "full" or "full/delta" request in flight, we can piggy back
;; onto it our region and our docver, and exit. That's because very
;; likely it's not actually inflight yet (because of the "deferred"
;; mechanism, it's waiting for didChange), so we can still do
;; changes to the state it represents when it is actually sent.
(cl-loop for v being the hash-values of eglot--semtok-inflight
when (fullish-p (car v)) do
(push (cons beg end) (caddr v))
(setf (cadr v) docver)
(cl-return-from eglot--semtok-request (cons 'skipped docver)))
(cond
((and (eglot-server-capable :semanticTokensProvider :full :delta)
(setq reused (cl-find-if
(lambda (e) (fullish-p (plist-get e :method)))
eglot--semtok-cache)))
(req :textDocument/semanticTokens/full/delta
(list :textDocument (eglot--TextDocumentIdentifier)
:previousResultId (plist-get reused :resultId))
(lambda (response)
(if-let* ((edits (plist-get response :edits)))
(eglot--semtok-apply-delta-edits
(plist-get reused :data)
edits)
(plist-get response :data)))))
((eglot-server-capable :semanticTokensProvider :range)
(req :textDocument/semanticTokens/range
(list :textDocument (eglot--TextDocumentIdentifier)
:range (eglot-region-range beg end))))
(t
(req :textDocument/semanticTokens/full
(list :textDocument (eglot--TextDocumentIdentifier)))))))
(cl-defun eglot--semtok-font-lock (limit &aux (beg (point)) (end limit))
"Arrange for font-lock to happen from point until LIMIT.
Either do it immediately if the information available is up-to-date or
request new information from the server and return and hope the font
lock machinery calls us again."
(let ((probe
(cl-find-if
(jsonrpc-lambda (&key docver valid &allow-other-keys)
(and (eq docver eglot--versioned-identifier)
(<= (car valid) beg end (cdr valid))))
eglot--semtok-cache)))
(cond (probe
(eglot--semtok-font-lock-1 beg end (plist-get probe :data)))
(t
(eglot--semtok-font-lock-2 beg end)
(eglot--semtok-request beg end))))
nil)
(defun eglot--semtok-font-lock-1 (beg end data)
"Do the face-painting work for `eglot--semtok-font-lock'."
(eglot--widening
(with-silent-modifications
(remove-list-of-text-properties beg end '(eglot--semtok-token
eglot--semtok-faces))
(goto-char (point-min))
(cl-loop
with column = 0 with p-beg = 0 with p-end = 0
for i from 0 below (length data) by 5
when (> (aref data i) 0) do
(setq column 0)
(forward-line (aref data i))
unless (< (point) beg) do
(setq column (+ column (aref data (+ i 1))))
(funcall eglot-move-to-linepos-function column)
(when (> (point) end) (cl-return (cons napplied 'early)))
(setq p-beg (point))
(funcall eglot-move-to-linepos-function (+ column (aref data (+ i 2))))
(setq p-end (point))
(let* ((tok (cons (aref data (+ i 3))
(aref data (+ i 4))))
(decoded (eglot--semtok-decode-token tok)))
;; The `eglot--semtok-token' prop doesn't serve much purpose:
;; just for debug...
(put-text-property p-beg p-end 'eglot--semtok-names (car decoded))
(put-text-property p-beg p-end 'eglot--semtok-faces (cdr decoded))
(dolist (f (cdr decoded))
(add-face-text-property p-beg p-end f)))
count 1 into napplied
finally (cl-return (cons napplied 'normal))))))
(defun eglot--semtok-font-lock-2 (beg end)
"Repaint from stale-but-not-that-much local properties."
(eglot--widening
(with-silent-modifications
(save-excursion
(cl-loop
initially (goto-char beg)
for match = (text-property-search-forward 'eglot--semtok-faces)
while (and match (< (point) end))
do (dolist (f (prop-match-value match))
(add-face-text-property
(prop-match-beginning match) (prop-match-end match) f)))))))
;;; Call and type hierarchies
@ -4736,7 +5055,8 @@ If NOERROR, return predicate, else erroring function."
;; harder. For now, use `with-eval-after-load'. See also github#1183.
(with-eval-after-load 'desktop
(add-to-list 'desktop-minor-mode-handlers '(eglot--managed-mode . ignore))
(add-to-list 'desktop-minor-mode-handlers '(eglot-inlay-hints-mode . ignore)))
(add-to-list 'desktop-minor-mode-handlers '(eglot-inlay-hints-mode . ignore))
(add-to-list 'desktop-minor-mode-handlers '(eglot-semantic-tokens-mode . ignore)))
;;; Misc
@ -4765,6 +5085,7 @@ If NOERROR, return predicate, else erroring function."
eglot-format
eglot-format-buffer
eglot-inlay-hints-mode
eglot-semantic-tokens-mode
eglot-reconnect
eglot-rename
eglot-signal-didChangeConfiguration

View file

@ -134,7 +134,7 @@
("1.3.6" . "30.1")))
(defcustom flymake-error-bitmap '(flymake-double-exclamation-mark
compilation-error)
flymake-error-fringe)
"Bitmap (a symbol) used in the fringe for indicating errors.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
@ -142,13 +142,13 @@ symbols, see `fringe-bitmaps'. See also `flymake-warning-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:version "24.3"
:version "31.1"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-warning-bitmap '(exclamation-mark compilation-warning)
(defcustom flymake-warning-bitmap '(exclamation-mark flymake-warning-fringe)
"Bitmap (a symbol) used in the fringe for indicating warnings.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
@ -156,13 +156,13 @@ symbols, see `fringe-bitmaps'. See also `flymake-error-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:version "24.3"
:version "31.1"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
(face :tag "Face"))))
(defcustom flymake-note-bitmap '(exclamation-mark compilation-info)
(defcustom flymake-note-bitmap '(exclamation-mark flymake-note-fringe)
"Bitmap (a symbol) used in the fringe for indicating info notes.
The value may also be a list of two elements where the second
element specifies the face for the bitmap. For possible bitmap
@ -170,7 +170,7 @@ symbols, see `fringe-bitmaps'. See also `flymake-error-bitmap'.
The option `flymake-fringe-indicator-position' controls how and where
this is used."
:version "26.1"
:version "31.1"
:type '(choice (symbol :tag "Bitmap")
(list :tag "Bitmap and face"
(symbol :tag "Bitmap")
@ -618,6 +618,21 @@ See variable `flymake-show-diagnostics-at-end-of-line'."
"Face used for information about end-of-line diagnostics."
:package-version '(Flymake . "1.3.6"))
(defface flymake-error-fringe '((t :inherit compilation-error))
"Face used by default in the `flymake-error-bitmap'."
:version "31.1"
:package-version '(Flymake . "1.4.4"))
(defface flymake-warning-fringe '((t :inherit compilation-warning))
"Face used by default in the `flymake-warning-bitmap'."
:version "31.1"
:package-version '(Flymake . "1.4.4"))
(defface flymake-note-fringe '((t :inherit compilation-info))
"Face used by default in the `flymake-note-bitmap'."
:version "31.1"
:package-version '(Flymake . "1.4.4"))
(defcustom flymake-show-diagnostics-at-end-of-line nil
"If non-nil, add diagnostic summary messages at end-of-line.
The value `short' means that only the most severe diagnostic

View file

@ -146,7 +146,9 @@
;; (overlay-end ov)))
;; 'face 'font-lock-type-face)))))
;; * Adding support for a major mode
;; * Extending hideshow
;; ** Adding support for a major mode
;;
;; Normally, hideshow tries to determine appropriate values for block
;; and comment definitions by examining the major mode settings. If the
@ -170,7 +172,7 @@
;; cases, `hs-forward-sexp-function' specifies another function to use
;; instead.
;; ** Tree-sitter support
;; *** Tree-sitter support
;;
;; All the treesit based modes already have support for hidding/showing
;; using the treesit thing `list' (see `treesit-major-mode-setup').
@ -181,6 +183,26 @@
;; values in `hs-adjust-block-end-function' and `hs-adjust-block-beginning-function' to
;; properly hide the code block.
;; ** Migrating from `hs-special-modes-alist'
;;
;; Starting with Emacs 31, `hs-special-modes-alist' has been deprecated.
;; Instead, modes should use the buffer-local variables that replace
;; each of the options in `hs-special-modes-alist'. The following table
;; shows the old elements of `hs-special-modes-alist' and their
;; replacement buffer-local variables:
;;
;; Instead of this Use this
;; -----------------------------------------------------------------------
;; START `hs-block-start-regexp'
;; (START . MDATA) `hs-block-start-regexp' and `hs-block-start-mdata-select'
;; END `hs-block-end-regexp'
;; COMMENT-START `hs-c-start-regexp'
;; FORWARD-SEXP-FUNC `hs-forward-sexp-function'
;; ADJUST-BEG-FUNC `hs-adjust-block-beginning-function'
;; FIND-BLOCK-BEGINNING-FUNC `hs-find-block-beginning-function'
;; FIND-NEXT-BLOCK-FUNC `hs-find-next-block-function'
;; LOOKING-AT-BLOCK-START-P-FUNC `hs-looking-at-block-start-predicate')
;; * Bugs
;;
;; (1) Sometimes `hs-headline' can become out of sync. To reset, type
@ -266,7 +288,7 @@
:group 'languages)
(defface hs-ellipsis
'((t :height 0.80 :box (:line-width -1) :inherit default))
'((t :height 0.80 :box (:line-width -1) :inherit (shadow default)))
"Face used for hideshow ellipsis.
Note: If `selective-display' ellipsis already has a face, hideshow will
use that face for the ellipsis instead."
@ -446,6 +468,31 @@ info node `(elisp)Overlays'."
:type 'function
:version "28.1")
(defcustom hs-cycle-filter nil
"Control where typing a \\`TAB' cycles the visibility.
This option determines on which parts of a line where a block
begins \\`TAB' will be bound to visibility-cycling commands such
as `hs-toggle-hiding'. The value t means you can type \\`TAB'
anywhere on a headline. The value nil means \\`TAB' always has its
usual binding. The value can also be a function of no arguments,
then \\`TAB' will invoke the visibility-cycling commands where that
function returns non-nil. For example, if the value is `bolp',
those commands will be invoked at the headline's beginning.
This allows to preserve the usual bindings, as determined by the
major mode, elsewhere on the headlines."
:type `(choice (const :tag "Nowhere" nil)
(const :tag "Everywhere on the headline" t)
(const :tag "At block beginning"
,(lambda ()
(pcase-let ((`(,beg ,end) (hs-block-positions)))
(and beg (hs-hideable-region-p beg end)))))
(const :tag "At line beginning" bolp)
(const :tag "Not at line beginning"
,(lambda () (not (bolp))))
(const :tag "At line end" eolp)
(function :tag "Custom filter function"))
:version "31.1")
;;---------------------------------------------------------------------------
;; internal variables
@ -472,6 +519,18 @@ Use the command `hs-minor-mode' to toggle or set this variable.")
:doc "Keymap for hideshow minor mode."
"S-<mouse-2>" #'hs-toggle-hiding
"C-c @" hs-prefix-map
"TAB" `(menu-item
"" hs-toggle-hiding
:filter
,(lambda (cmd)
(when (and hs-cycle-filter
;; On the headline with hideable blocks
(save-excursion
(goto-char (line-beginning-position))
(hs-get-first-block))
(or (not (functionp hs-cycle-filter))
(funcall hs-cycle-filter)))
cmd)))
"<left-fringe> <mouse-1>" #'hs-indicator-mouse-toggle-hiding)
(defvar-keymap hs-indicators-map
@ -693,6 +752,15 @@ block at point."
(when-let* ((block (hs-block-positions)))
(apply #'hs-hideable-region-p block))))
(defun hs--discard-overlay-before-changes (o &rest _r)
"Remove overlay O before changes.
Intended to be used in `modification-hooks', `insert-in-front-hooks' and
`insert-behind-hooks'."
(let ((beg (overlay-start o))
(end (overlay-end o)))
(delete-overlay o)
(hs--refresh-indicators beg end)))
(defun hs-make-overlay (b e kind &optional b-offset e-offset)
"Return a new overlay in region defined by B and E with type KIND.
KIND is either `code' or `comment'. Optional fourth arg B-OFFSET
@ -710,24 +778,29 @@ to call with the newly initialized overlay."
(io (if (eq 'block hs-isearch-open)
;; backward compatibility -- `block'<=>`code'
'code
hs-isearch-open))
(map (make-sparse-keymap)))
hs-isearch-open)))
(overlay-put ov 'invisible 'hs)
(define-key map (kbd "<mouse-1>") #'hs-show-block)
(overlay-put ov 'display
(propertize
(hs--get-ellipsis b e)
'mouse-face
'highlight
'help-echo "mouse-1: show hidden lines"
'keymap map))
'keymap '(keymap (mouse-1 . hs-toggle-hiding))))
;; Internal properties
(overlay-put ov 'hs kind)
(overlay-put ov 'hs-b-offset b-offset)
(overlay-put ov 'hs-e-offset e-offset)
;; Isearch integration
(when (or (eq io t) (eq io kind))
(overlay-put ov 'isearch-open-invisible 'hs-isearch-show)
(overlay-put ov 'isearch-open-invisible-temporary
'hs-isearch-show-temporary))
;; Remove overlay after modifications
(overlay-put ov 'modification-hooks '(hs--discard-overlay-before-changes))
(overlay-put ov 'insert-in-front-hooks '(hs--discard-overlay-before-changes))
(overlay-put ov 'insert-behind-hooks '(hs--discard-overlay-before-changes))
(when hs-set-up-overlay (funcall hs-set-up-overlay ov))
(hs--refresh-indicators b e)
ov))
@ -737,34 +810,39 @@ to call with the newly initialized overlay."
This returns a list with the current code block beginning and end
positions. This does nothing if there is not a code block at current
point."
(save-match-data
(save-excursion
(when (funcall hs-looking-at-block-start-predicate)
(let ((mdata (match-data t))
(header-end (match-end 0))
block-beg block-end)
;; `block-start' is the point at the end of the block
;; beginning, which may need to be adjusted
(save-excursion
(when hs-adjust-block-beginning-function
(goto-char (funcall hs-adjust-block-beginning-function header-end)))
(setq block-beg (line-end-position)))
;; `block-end' is the point at the end of the block
(hs-forward-sexp mdata 1)
(setq block-end
(cond ((and (stringp hs-block-end-regexp)
(looking-back hs-block-end-regexp nil))
(match-beginning 0))
((functionp hs-block-end-regexp)
(funcall hs-block-end-regexp)
(match-beginning 0))
(t (point))))
;; adjust block end (if needed)
(when hs-adjust-block-end-function
;; `catch' is used here if the search fails due unbalanced parentheses
;; or any other unknown error caused in `hs-forward-sexp'.
(catch 'hs-sexp-error
(save-match-data
(save-excursion
(when (funcall hs-looking-at-block-start-predicate)
(let ((mdata (match-data t))
(header-end (match-end 0))
block-beg block-end)
;; `block-start' is the point at the end of the block
;; beginning, which may need to be adjusted
(save-excursion
(when hs-adjust-block-beginning-function
(goto-char (funcall hs-adjust-block-beginning-function header-end)))
(setq block-beg (line-end-position)))
;; `block-end' is the point at the end of the block
(condition-case _
(hs-forward-sexp mdata 1)
(scan-error (throw 'hs-sexp-error nil)))
(setq block-end
(or (funcall hs-adjust-block-end-function block-beg)
block-end)))
(list block-beg block-end))))))
(cond ((and (stringp hs-block-end-regexp)
(looking-back hs-block-end-regexp nil))
(match-beginning 0))
((functionp hs-block-end-regexp)
(funcall hs-block-end-regexp)
(match-beginning 0))
(t (point))))
;; adjust block end (if needed)
(when hs-adjust-block-end-function
(setq block-end
(or (funcall hs-adjust-block-end-function block-beg)
block-end)))
(list block-beg block-end)))))))
(defun hs--make-indicators-overlays (beg)
"Helper function to make the indicators overlays."
@ -798,7 +876,8 @@ point."
"+" 'display
`((margin left-margin)
,(or (plist-get (icon-elements face-or-icon) 'image)
(icon-string face-or-icon)))
(propertize (icon-string face-or-icon)
'keymap hs-indicators-map)))
'face face-or-icon
'keymap hs-indicators-map))
;; EOL string
@ -818,26 +897,12 @@ point."
(goto-char beg)
(remove-overlays beg end 'hs-indicator t)
(while (funcall hs-find-next-block-function hs-block-start-regexp end nil)
(when-let* ((b-beg (match-beginning 0))
(_ (save-excursion
(goto-char b-beg)
(funcall hs-looking-at-block-start-predicate)))
;; `catch' is used here if the search fails due
;; unbalanced parentheses or any other unknown error
;; caused in `hs-forward-sexp'.
(b-end (catch 'hs-indicator-error
(save-excursion
(goto-char b-beg)
(condition-case _
(funcall hs-forward-sexp-function 1)
(scan-error (throw 'hs-indicator-error nil)))
(point))))
;; Check if block is longer than 1 line.
(_ (hs-hideable-region-p b-beg b-end)))
;; Only 1 indicator per line
(when (hs--make-indicators-overlays b-beg)
(forward-line))))
(while (not (>= (point) end))
(save-excursion
(when-let* ((b-beg (hs-get-first-block)))
(hs--make-indicators-overlays b-beg)))
;; Only 1 indicator per line
(forward-line))
`(jit-lock-bounds ,beg . ,end))
(defun hs--refresh-indicators (from to)
@ -855,30 +920,34 @@ This returns the ellipsis string to use and its face."
(d-t-ellipsis
(display-table-slot standard-display-table 'selective-display))
;; Convert ellipsis vector to a propertized string
(ellipsis
(and (vectorp d-t-ellipsis) ; Ensure the vector is not empty
(not (length= d-t-ellipsis 0))
(mapconcat
(lambda (g)
(apply #'propertize (char-to-string (glyph-char g))
(and (glyph-face g) (list 'face (glyph-face g)))))
d-t-ellipsis)))
(ellipsis-face (and ellipsis (get-text-property 0 'face ellipsis)))
(apply-face (lambda (str)
(apply #'propertize str
(and ellipsis-face (list 'face ellipsis-face)))))
(lines (when-let* (hs-display-lines-hidden
(l (1- (count-lines b e)))
(l-str (format "%d %s" l
(if (= l 1) "line" "lines"))))
(funcall apply-face l-str)))
(tty-strings (and hs-display-lines-hidden (not (display-graphic-p))))
(string
(if (and (vectorp d-t-ellipsis)
;; Ensure the vector is not empty
(not (length= d-t-ellipsis 0)))
(mapconcat
(lambda (g)
(apply #'propertize (char-to-string (glyph-char g))
(if (glyph-face g) (list 'face (glyph-face g)))))
d-t-ellipsis)))
(string-face (if string (get-text-property 0 'face string)))
(lines (if-let* (hs-display-lines-hidden
(l (1- (count-lines b e)))
(l-str (concat (number-to-string l)
(if (= l 1) " line" " lines"))))
(apply #'propertize l-str
(if string-face
(list 'face string-face))))))
(if string-face
;; Return STRING and LINES if STRING has no face
(concat lines string)
(concat (and tty-strings (funcall apply-face "["))
lines
(or ellipsis (truncate-string-ellipsis))
(and tty-strings (funcall apply-face "]")))))
(if ellipsis-face
;; Return ELLIPSIS and LINES if ELLIPSIS has no face
string
;; Otherwise propertize both with `hs-ellipsis'
(propertize
(concat lines (or string (truncate-string-ellipsis)))
'face 'hs-ellipsis))))
(propertize string 'face 'hs-ellipsis))))
(defun hs-isearch-show (ov)
"Delete overlay OV, and set `hs-headline' to nil.
@ -972,6 +1041,22 @@ Otherwise, return nil."
(goto-char (if end q (min p (match-end 0))))
nil)))))
(defun hs-get-first-block ()
"Return the position of the first valid block found on the current line.
This searches for a valid block on the current line and returns the
first block found. Otherwise, if no block is found, it returns nil."
(let (exit)
(while (and (not exit)
(funcall hs-find-next-block-function
hs-block-start-regexp
(line-end-position) nil)
(save-excursion
(goto-char (match-beginning 0))
(if (hs-hideable-region-p)
(setq exit (match-beginning 0))
t))))
exit))
(defun hs-inside-comment-p ()
(declare (obsolete "Call `hs-inside-comment-predicate' instead." "31.1"))
(funcall hs-inside-comment-predicate))
@ -1113,8 +1198,11 @@ region (point MAXP)."
(not (nth 8 (syntax-ppss)))) ; not inside comments or strings
(if (> arg 1)
(hs-hide-level-recursive (1- arg) minp maxp)
(goto-char (match-beginning hs-block-start-mdata-select))
(hs-hide-block-at-point t))))
;; `hs-hide-block-at-point' already moves the cursor, but if it
;; fails, return to the previous position where we were.
(unless (and (goto-char (match-beginning hs-block-start-mdata-select))
(hs-hide-block-at-point t))
(goto-char (match-end hs-block-start-mdata-select))))))
(goto-char maxp))
(defmacro hs-life-goes-on (&rest body)
@ -1147,18 +1235,13 @@ Return point, or nil if original point was not in a block."
"Return non-nil if point is in an already-hidden block, otherwise nil."
(save-excursion
(let ((c-reg (funcall hs-inside-comment-predicate)))
(if (and c-reg (nth 0 c-reg))
;; point is inside a comment, and that comment is hideable
(goto-char (nth 0 c-reg))
(when (not c-reg)
(end-of-line)
(when (not (hs-find-block-beginning-match))
;; We should also consider ourselves "in" a hidden block when
;; point is right at the edge after a hidden block (bug#52092).
(beginning-of-line)
(hs-find-block-beginning-match)))))
(end-of-line)
(eq 'hs (get-char-property (point) 'invisible))))
(when (and c-reg (nth 0 c-reg))
;; point is inside a comment, and that comment is hideable
(goto-char (nth 0 c-reg))))
;; Search for a hidden block at EOL ...
(or (eq 'hs (get-char-property (line-end-position) 'invisible))
;; ... or behind the current cursor position
(eq 'hs (get-char-property (if (bobp) (point) (1- (point))) 'invisible)))))
;; This function is not used anymore (Bug#700).
(defun hs-c-like-adjust-block-beginning (initial)
@ -1240,8 +1323,7 @@ Upon completion, point is repositioned and the normal hook
`hs-hide-hook' is run. See documentation for `run-hooks'."
(interactive "P")
(hs-life-goes-on
(let ((c-reg (funcall hs-inside-comment-predicate))
(pos (point)))
(let ((c-reg (funcall hs-inside-comment-predicate)))
(cond
((and c-reg (or (null (nth 0 c-reg))
(not (hs-hideable-region-p (car c-reg) (nth 1 c-reg)))))
@ -1249,25 +1331,16 @@ Upon completion, point is repositioned and the normal hook
(c-reg (hs-hide-block-at-point end c-reg))
((or (and (eq hs-hide-block-behavior 'after-bol)
(setq pos (point))
(goto-char (line-beginning-position))
(catch 'hs--exit-hide
(while (and (funcall hs-find-next-block-function
hs-block-start-regexp
(line-end-position) nil)
(save-excursion
(goto-char (match-beginning 0))
(if (hs-hideable-region-p)
(throw 'hs--exit-hide t)
t)))))
(goto-char (match-beginning 0)))
(and (goto-char pos)
(funcall hs-looking-at-block-start-predicate)))
(hs-hide-block-at-point end))
((save-excursion
(and-let* ((_ (eq hs-hide-block-behavior 'after-bol))
(_ (goto-char (line-beginning-position)))
(pos (hs-get-first-block))
(_ (goto-char pos))
(_ (hs-hide-block-at-point end))))))
((and (goto-char (line-beginning-position))
(funcall hs-find-block-beginning-function))
((or (funcall hs-looking-at-block-start-predicate)
(and (goto-char (line-beginning-position))
(funcall hs-find-block-beginning-function)))
(hs-hide-block-at-point end)))
(run-hooks 'hs-hide-hook))))
@ -1341,6 +1414,8 @@ Argument E should be the event that triggered this action."
(interactive "e")
(hs-life-goes-on
(when hs-show-indicators
(when (mouse-event-p event)
(mouse-set-point event))
(let* ((overlays (save-excursion
(goto-char (posn-point (event-end event)))
(overlays-in (pos-bol) (pos-eol))))

View file

@ -3449,7 +3449,7 @@ Check if a node type is available, then return the right indent rules."
((parent-is "jsx_fragment") parent js-indent-level)))
(error
`(((match "<" "jsx_text") parent 0)
((parent-is "jsx_text") parent js-indent-level)))))
((parent-is "jsx_text") parent-bol js-indent-level)))))
(defun js--treesit-switch-body-helper (_node parent _bol &rest _args)
"Anchor helper for the switch body..
@ -3735,7 +3735,7 @@ function is called. Subsequent calls return the first evaluated value."
:language 'jsdoc
:override t
:feature 'keyword
'((tag_name) @font-lock-constant-face)
'((tag_name) @font-lock-doc-markup-face)
:language 'jsdoc
:override t

View file

@ -1801,7 +1801,8 @@ This function just searches for a `end' at the beginning of a line."
" error(e)"
" end"
" return x()"
"end")
"end"
"\n")
" "))
(defun lua-make-lua-string (str)
@ -1843,27 +1844,34 @@ The value nil means that no command history is saved."
;;;###autoload
(defun lua-start-process (&optional name program startfile &rest switches)
"Start a Lua process named NAME, running PROGRAM.
PROGRAM defaults to NAME, which defaults to `lua-default-application'.
When called interactively, switch to the process buffer.
STARTFILE is the name of a file, whose contents are sent to the process
as its initial input.
NAME is the name of the created process; default is
`lua-process-buffer-name' or `lua-default-application'.
SWITCHES is a list of strings passed as arguments to PROGRAM."
PROGRAM is the executable to run; default is `lua-default-application'.
STARTFILE is a file, whose contents are sent to the process as initial
input; default is `lua-process-startfile'.
SWITCHES is a list of strings passed as arguments to PROGRAM; default is
`lua-default-command-switches'."
(interactive)
(if (not lua-default-application)
(user-error "You must set `lua-default-application' to use this command")
(let* ((name (or name lua-process-buffer-name
(if (consp lua-default-application)
(car lua-default-application)
lua-default-application)))
(let* ((name (or name
lua-process-buffer-name
(if (consp lua-default-application)
(car lua-default-application)
lua-default-application)))
(program (or program lua-default-application)))
;; Don't re-initialize if there already is a Lua process.
(unless (comint-check-proc (format "*%s*" name))
(setq lua-process-buffer
(apply #'make-comint name program
(or startfile lua-process-startfile)
(or switches lua-default-command-switches)))
(or (flatten-tree switches)
lua-default-command-switches)))
(setq lua-process (get-buffer-process lua-process-buffer))
(set-process-query-on-exit-flag lua-process nil)
(with-current-buffer lua-process-buffer
@ -1877,10 +1885,13 @@ SWITCHES is a list of strings passed as arguments to PROGRAM."
(while (not (lua-prompt-line))
(accept-process-output (get-buffer-process (current-buffer)))
(goto-char (point-max)))
(lua-send-string lua-process-init-code)))
(process-send-string lua-process lua-process-init-code)))
;; When called interactively, switch to process buffer
(when (called-interactively-p 'any)
(switch-to-buffer lua-process-buffer)))))
(pop-to-buffer lua-process-buffer
'((display-buffer-pop-up-window
display-buffer-reuse-window)
(reusable-frames . t)))))))
(defun lua-get-create-process ()
"Return active Lua process creating one if necessary."

View file

@ -1213,7 +1213,7 @@ function is called. Subsequent calls return the first evaluated value."
:language 'phpdoc
:feature 'attribute
:override t
`((tag_name) @font-lock-constant-face
`((tag_name) @font-lock-doc-markup-face
(uri) @font-lock-doc-markup-face
(tag
[(version) (email_address)] @font-lock-doc-markup-face)

View file

@ -141,7 +141,7 @@ Check if a node type is available, then return the right indent rules."
((parent-is "jsx_fragment") parent typescript-ts-mode-indent-offset)))
(treesit-query-error
`(((match "<" "jsx_text") parent 0)
((parent-is "jsx_text") parent typescript-ts-mode-indent-offset)))))
((parent-is "jsx_text") parent-bol typescript-ts-mode-indent-offset)))))
(defun typescript-ts-mode--anchor-decl (_n parent &rest _)
"Return the position after the declaration keyword before PARENT.

View file

@ -2459,6 +2459,7 @@ To be added to `context-menu-functions'."
\\`U' to undo all replacements,
\\`e' to edit the replacement string.
\\`E' to edit the replacement string with exact case.
\\`d' to display the diff buffer with all replacements.
\\`C-l' to clear the screen, redisplay, and offer same replacement again,
\\`Y' to replace all remaining matches in all remaining buffers (in
multi-buffer replacements) with no more questions,
@ -2492,6 +2493,7 @@ re-executed as a normal key sequence."
(define-key map "^" 'backup)
(define-key map "u" 'undo)
(define-key map "U" 'undo-all)
(define-key map "d" 'diff)
(define-key map "\C-h" 'help)
(define-key map [f1] 'help)
(define-key map [help] 'help)
@ -2518,7 +2520,7 @@ The valid answers include `act', `skip', `act-and-show',
`scroll-down', `scroll-other-window', `scroll-other-window-down',
`edit', `edit-replacement', `edit-replacement-exact-case',
`delete-and-edit', `automatic', `backup', `undo', `undo-all',
`quit', and `help'.
`diff', `quit', and `help'.
This keymap is used by `y-or-n-p' as well as `query-replace'.")
@ -2779,23 +2781,23 @@ to a regexp that is actually used for the search.")
(isearch-clean-overlays))
;; A macro because we push STACK, i.e. a local var in `perform-replace'.
(defmacro replace--push-stack (replaced search-str next-replace stack)
(declare (indent 0) (debug (form form form gv-place)))
(defmacro replace--push-stack (replaced search-str next-replace next-replacement match-again stack)
(declare (indent 0) (debug (form form form form form gv-place)))
`(push (list (point) ,replaced
;;; If the replacement has already happened, all we need is the
;;; current match start and end. We could get this with a trivial
;;; match like
;;; (save-excursion (goto-char (match-beginning 0))
;;; (search-forward (match-string 0))
;;; (match-data t))
;;; if we really wanted to avoid manually constructing match data.
;;; Adding current-buffer is necessary so that match-data calls can
;;; return markers which are appropriate for editing.
;; If the replacement has already happened, all we need is the
;; current match start and end. We could get this with a trivial
;; match like
;; (save-excursion (goto-char (match-beginning 0))
;; (search-forward (match-string 0))
;; (match-data t))
;; if we really wanted to avoid manually constructing match data.
;; Adding current-buffer is necessary so that match-data calls
;; can return markers which are appropriate for editing.
(if ,replaced
(list
(match-beginning 0) (match-end 0) (current-buffer))
(match-data t))
,search-str ,next-replace)
(match-data))
,search-str ,next-replace ,next-replacement ,match-again)
,stack))
(defun replace--region-filter (bounds)
@ -2962,7 +2964,7 @@ characters."
(nth 0 match-again)
(nth 1 match-again)))
(replace-match-data
t real-match-data match-again))
nil real-match-data match-again))
;; MATCH-AGAIN non-nil means accept an
;; adjacent match.
(match-again
@ -2972,7 +2974,7 @@ characters."
case-fold-search backward)
;; For speed, use only integers and
;; reuse the list used last time.
(replace-match-data t real-match-data)))
(replace-match-data nil real-match-data)))
((and (if backward
(> (1- (point)) (point-min))
(< (1+ (point)) (point-max)))
@ -2990,7 +2992,7 @@ characters."
regexp-flag delimited-flag
case-fold-search backward)
(replace-match-data
t real-match-data)
nil real-match-data)
(goto-char opoint)
nil))))))
@ -3082,7 +3084,7 @@ characters."
(save-excursion
(goto-char (nth 0 real-match-data))
(looking-at search-string)
(match-data t real-match-data))))
(match-data nil real-match-data))))
;; Matched string and next-replacement-replaced
;; stored in stack.
(setq search-string-replaced (buffer-substring-no-properties
@ -3146,8 +3148,10 @@ characters."
(setq replaced (nth 1 elt)
real-match-data
(replace-match-data
t real-match-data
(nth 2 elt))))
nil real-match-data
(nth 2 elt))
next-replacement (nth 5 elt)
match-again (nth 6 elt)))
(message "No previous match")
(ding 'no-terminate)
(sit-for 1)))
@ -3194,7 +3198,7 @@ characters."
(goto-char (match-beginning 0))
;; We must quote the string (Bug#37073)
(looking-at (regexp-quote search-string))
(match-data t (nth 2 elt)))
(match-data nil (nth 2 elt)))
noedit
(replace-match-maybe-edit
last-replacement nocasify literal
@ -3203,10 +3207,11 @@ characters."
real-match-data
(save-excursion
(goto-char (match-beginning 0))
(if regexp-flag
(looking-at last-replacement)
(looking-at (regexp-quote last-replacement)))
(match-data t (nth 2 elt))))
(looking-at (if regexp-flag
last-replacement
(regexp-quote
last-replacement)))
(match-data nil (nth 2 elt))))
(when regexp-flag
(setq next-replacement (nth 4 elt)))
;; Set replaced nil to keep in loop
@ -3250,12 +3255,13 @@ characters."
noedit real-match-data backward)
replace-count (1+ replace-count)
real-match-data (replace-match-data
t real-match-data)
nil real-match-data)
replaced t last-was-act-and-show t)
(replace--push-stack
replaced
search-string-replaced
next-replacement-replaced stack)))
next-replacement-replaced next-replacement match-again
stack)))
((or (eq def 'automatic) (eq def 'automatic-all))
(or replaced
(setq noedit
@ -3333,6 +3339,16 @@ characters."
(replace-dehighlight)
(save-excursion (recursive-edit))
(setq replaced t))
((eq def 'diff)
(let ((display-buffer-overriding-action
'(nil (inhibit-same-window . t))))
(save-selected-window
(multi-file-replace-as-diff
(list (or buffer-file-name (current-buffer)))
from-string (or replacements next-replacement)
regexp-flag delimited-flag))))
((commandp def t)
(call-interactively def))
;; Note: we do not need to treat `exit-prefix'
@ -3359,7 +3375,8 @@ characters."
(replace--push-stack
replaced
search-string-replaced
next-replacement-replaced stack))
next-replacement-replaced next-replacement match-again
stack))
(setq next-replacement-replaced nil
search-string-replaced nil
last-was-act-and-show nil))))))

View file

@ -116,13 +116,11 @@ are integer buffer positions in the reverse order of the insertion order.")
DOCUMENTATION is that of the command.
SKELETON is as defined under `skeleton-insert'."
(declare (doc-string 2) (debug (&define name stringp skeleton-edebug-spec))
(indent defun))
(indent defun)
(autoload-macro expand))
(if skeleton-debug
(set command skeleton))
`(progn
;; Tell self-insert-command that this function, if called by an
;; abbrev, should cause the self-insert to be skipped.
(put ',command 'no-self-insert t)
(defun ,command (&optional str arg)
,(concat documentation
(if (string-match "\n\\'" documentation)
@ -139,7 +137,11 @@ A prefix argument of zero says to wrap around zero words---that is, nothing.
This is a way of overriding the use of a highlighted region.")
(interactive "*P\nP")
(atomic-change-group
(skeleton-proxy-new ',skeleton str arg)))))
(skeleton-proxy-new ',skeleton str arg)))
:autoload-end
;; Tell self-insert-command that this function, if called by an
;; abbrev, should cause the self-insert to be skipped.
(put ',command 'no-self-insert t)))
;;;###autoload
(defun skeleton-proxy-new (skeleton &optional str arg)
@ -257,7 +259,7 @@ available:
(while (and l1 (> skeleton-regions 0))
(push (copy-marker (pop l1) t) l2)
(setq skeleton-regions (1- skeleton-regions)))
(sort l2 '<))))
(sort l2 #'<))))
(goto-char (car skeleton-regions))
(setq skeleton-regions (cdr skeleton-regions)))
(let ((beg (point))
@ -327,7 +329,7 @@ automatically, and you are prompted to fill in the variable parts.")))
(symbol-value 'input))))))
((functionp prompt)
(funcall prompt))
(t (eval prompt))))
(t (eval prompt t))))
(or eolp
(delete-char 1))))
(if (and recursive
@ -436,7 +438,7 @@ automatically, and you are prompted to fill in the variable parts.")))
((eq element '@)
(push (point) skeleton-positions))
((eq 'quote (car-safe element))
(eval (nth 1 element)))
(eval (nth 1 element) t))
((and (consp element)
(or (stringp (car element)) (listp (car element))))
;; Don't forget: `symbolp' is also true for nil.
@ -449,7 +451,7 @@ automatically, and you are prompted to fill in the variable parts.")))
(skeleton-internal-list element (car literal))
(setq literal (cdr literal)))))
((null element))
(t (skeleton-internal-1 (eval element) t recursive))))
(t (skeleton-internal-1 (eval element t) t recursive))))
;; Maybe belongs into simple.el or elsewhere
;; ;;;###autoload

View file

@ -2961,12 +2961,14 @@ nil default-directory" name)
file file nil t
(lambda (buffer file)
(with-current-buffer buffer
(setq-local lexical-binding t)
(goto-char (point-min))
;; Removing the #! and then calling `eval-buffer' will make the
;; reader not signal an error if it then turns out that the
;; buffer is empty.
(when (looking-at "#!")
(delete-line))
(delete-line)
(insert ";; -*- lexical-binding: t -*-\n"))
(eval-buffer buffer nil file nil t)))))
(defun command-line--eval-script (file)
@ -2975,6 +2977,7 @@ nil default-directory" name)
(lambda (buffer _)
(with-current-buffer buffer
(goto-char (point-min))
(setq-local lexical-binding t)
(when (looking-at "#!")
(forward-line))
(let (value form)

View file

@ -4270,6 +4270,14 @@ Both should not be used to define a buffer-local dictionary."
;; If comment-normalize-vars is defined, newcomment must be loaded.
(declare-function comment-normalize-vars "newcomment" (&optional noerror))
(defun ispell--comment-prefix ()
"Return the comment marker for the current mode."
(progn
(comment-normalize-vars)
(comment-padright comment-start
(comment-add nil))
comment-start))
(defun ispell-add-per-file-word-list (word)
"Add WORD to the per-file word list."
(or ispell-buffer-local-name
@ -4280,37 +4288,34 @@ Both should not be used to define a buffer-local dictionary."
(while (not done)
(let ((case-fold-search nil))
(setq search (search-forward ispell-words-keyword nil t)
found (or found search)
line-okay (< (+ (length word) 1 ; 1 for space after word..
(progn (end-of-line) (current-column)))
found (or found search)
line-okay (< (+ (length word) 1 ; 1 for space after word..
(progn (end-of-line) (current-column)))
fill-column)))
(if (or (and search line-okay)
(null search))
(progn
(setq done t)
(if (null search)
(progn
(if found (insert "\n") ;; after an existing LocalWords
(goto-char (point-max)) ;; no LocalWords, go to end of file
(open-line 1)
(newline))
(insert (if comment-start
(concat
(progn
;; Try and use the proper comment marker,
;; e.g. ";;" rather than ";".
(comment-normalize-vars)
(comment-padright comment-start
(comment-add nil))
comment-start)
" ")
"")
ispell-words-keyword)
(if (and comment-end (> (length comment-end) 0))
(save-excursion
(newline)
(insert comment-end)))))
(insert (concat " " word))))))))
(if (or (and search line-okay)
(null search))
(progn
(setq done t)
(if (null search)
(progn
(let ((empty-comment-end (or (not comment-end) (= (length comment-end) 0))))
(progn
(if found (progn ;; after an existing LocalWords
(insert "\n")
(when (and empty-comment-end comment-start)
(insert (ispell--comment-prefix) " ")))
(goto-char (point-max)) ;; no LocalWords, go to end of file
(open-line 1)
(newline)
;; Insert an end marker if needed, preceded by a newline.
(if (not empty-comment-end)
(save-excursion
(newline)
(insert comment-end)))
(when comment-start
(insert (ispell--comment-prefix) (if (not empty-comment-end) "\n" " "))))
(insert ispell-words-keyword)))))
(insert (concat " " word))))))))
(provide 'ispell)

View file

@ -111,12 +111,13 @@ If your files might be edited by older versions of Emacs also, you should
limit yourself to the formats recommended by that older version."
:type 'string
:version "31.1")
;;;###autoload(put 'time-stamp-format 'safe-local-variable 'stringp)
;;;###autoload(put 'time-stamp-format 'safe-local-variable #'stringp)
(defcustom time-stamp-active t
"Non-nil enables time-stamping of buffers by \\[time-stamp].
Can be toggled by \\[time-stamp-toggle-active].
Can be toggled by \\[time-stamp-toggle-active] as an easy way to
temporarily disable time-stamp while saving a file.
This option does not affect when `time-stamp' is run, only what it
does when it runs. To activate automatic time-stamping of buffers
@ -142,8 +143,10 @@ otherwise would have been updated."
(defcustom time-stamp-time-zone nil
"The time zone to be used by \\[time-stamp].
Its format is that of the ZONE argument of the `format-time-string' function."
"The time zone used by \\[time-stamp]. t uses UTC.
nil (the default) uses local time, and t or \"UTC0\" uses
Coordinated Universal Time (UTC). For other possible values,
see the documentation of the ZONE argument of `format-time-string'."
:type '(choice (const :tag "Emacs local time" nil)
(const :tag "Universal Time" t)
(const :tag "system wall clock time" wall)
@ -153,12 +156,12 @@ Its format is that of the ZONE argument of the `format-time-string' function."
(string :tag "Time zone abbreviation"))
(integer :tag "Offset (seconds east of UTC)"))
:version "20.1")
;;;###autoload(put 'time-stamp-time-zone 'safe-local-variable 'time-stamp-zone-type-p)
;;;###autoload(put 'time-stamp-time-zone 'safe-local-variable #'time-stamp-zone-type-p)
;;;###autoload
(defun time-stamp-zone-type-p (zone)
"Return non-nil if ZONE is of the correct type for a timezone rule.
"Return non-nil if ZONE looks like a valid timezone rule.
Valid ZONE values are described in the documentation of `format-time-string'."
(or (memq zone '(nil t wall))
(stringp zone)
@ -171,17 +174,17 @@ Valid ZONE values are described in the documentation of `format-time-string'."
;;; Do not change time-stamp-line-limit, time-stamp-start,
;;; time-stamp-end, time-stamp-pattern, time-stamp-inserts-lines,
;;; or time-stamp-count in your .emacs or you will be incompatible
;;; with other people's files! If you must change them, do so only
;;; in the local variables section of the file itself.
;;; or time-stamp-count in your init file or you will be incompatible
;;; with other people's files. It is fine to change these variables
;;; in the local variables list of the file itself.
(defvar time-stamp-line-limit 8 ;Do not change!
"Lines of a file searched; positive counts from start, negative from end.
The patterns `time-stamp-start' and `time-stamp-end' must be found in
the first (last) `time-stamp-line-limit' lines of the file for the
file to be time-stamped by \\[time-stamp]. A value of 0 searches the
entire buffer (use with care).
"Lines searched; positive counts from start, negative from end.
The patterns `time-stamp-start' and `time-stamp-end' must be found
in the first (last) `time-stamp-line-limit' lines of the file for
\\[time-stamp] to update the region between them with the current
time stamp. A value of 0 searches the entire buffer (use with care).
It may be more convenient to use `time-stamp-pattern' if you set more
than one of `time-stamp-line-limit', `time-stamp-start', `time-stamp-end',
@ -191,7 +194,7 @@ These variables are best changed with file-local variables.
If you were to change `time-stamp-line-limit', `time-stamp-start',
`time-stamp-end', or `time-stamp-pattern' in your init file, you
would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-line-limit 'safe-local-variable 'integerp)
;;;###autoload(put 'time-stamp-line-limit 'safe-local-variable #'integerp)
(defvar time-stamp-start "Time-stamp:[ \t]+\\\\?[\"<]+" ;Do not change!
@ -205,7 +208,7 @@ These variables are best changed with file-local variables.
If you were to change `time-stamp-line-limit', `time-stamp-start',
`time-stamp-end', or `time-stamp-pattern' in your init file, you
would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-start 'safe-local-variable 'stringp)
;;;###autoload(put 'time-stamp-start 'safe-local-variable #'stringp)
(defvar time-stamp-end "\\\\?[\">]" ;Do not change!
@ -228,7 +231,7 @@ These variables are best changed with file-local variables.
If you were to change `time-stamp-line-limit', `time-stamp-start',
`time-stamp-end', `time-stamp-pattern', or `time-stamp-inserts-lines' in
your init file, you would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-end 'safe-local-variable 'stringp)
;;;###autoload(put 'time-stamp-end 'safe-local-variable #'stringp)
(defvar time-stamp-inserts-lines nil ;Do not change!
@ -244,7 +247,7 @@ for generating repeated time stamps.
These variables are best changed with file-local variables.
If you were to change `time-stamp-end' or `time-stamp-inserts-lines' in
your init file, you would be incompatible with other people's files.")
;;;###autoload(put 'time-stamp-inserts-lines 'safe-local-variable 'booleanp)
;;;###autoload(put 'time-stamp-inserts-lines 'safe-local-variable #'booleanp)
(defvar time-stamp-count 1 ;Do not change!
@ -262,7 +265,7 @@ with other people's files.")
(defvar time-stamp-pattern nil ;Do not change!
"Convenience variable setting all `time-stamp' location and format values.
"Shorthand variable for `time-stamp' location and format values.
This string has four parts, each of which is optional.
These four parts override `time-stamp-line-limit', `time-stamp-start',
`time-stamp-format' and `time-stamp-end', respectively. See the
@ -313,7 +316,7 @@ in-depth examples.
See also `time-stamp-count' and `time-stamp-inserts-lines'.")
;;;###autoload(put 'time-stamp-pattern 'safe-local-variable 'stringp)
;;;###autoload(put 'time-stamp-pattern 'safe-local-variable #'stringp)
@ -418,7 +421,7 @@ to customize the information in the time stamp and where it is written."
(defun time-stamp-once (start search-limit ts-start ts-end
ts-format format-lines end-lines)
"Update one time stamp. Internal routine called by \\[time-stamp].
"Update one time stamp. Internal routine called by `time-stamp'.
Returns the end point, which is where `time-stamp' begins the next search."
(let ((case-fold-search nil)
(end nil)
@ -489,8 +492,10 @@ Returns the end point, which is where `time-stamp' begins the next search."
;;;###autoload
(defun time-stamp-toggle-active (&optional arg)
"Toggle `time-stamp-active', setting whether \\[time-stamp] updates a buffer.
With ARG, turn time stamping on if and only if ARG is positive."
"Set `time-stamp-active' (whether \\[time-stamp] updates a buffer).
If ARG is unset, toggle `time-stamp-active'. With an arg, set
`time-stamp-active' to t (turning on time stamping) if
ARG is positive, otherwise nil."
(interactive "P")
(setq time-stamp-active
(if (null arg)
@ -504,7 +509,7 @@ Internal helper used by `time-stamp-string-preprocess'."
(format-time-string format time time-stamp-time-zone))
(defun time-stamp-string (&optional ts-format time)
"Return the current time and other info formatted for \\[time-stamp].
"Return the time, date and other info formatted for `time-stamp'.
Optional first argument TS-FORMAT gives the format to use; it defaults
to the value of `time-stamp-format'. Thus, with no arguments,
this function returns the string `time-stamp' would use to update
@ -798,9 +803,9 @@ and all `time-stamp-format' compatibility."
(defun time-stamp-do-letter-case (change-is-downcase
upcase title-case change-case text)
"Apply upper- and lower-case conversions to TEXT according to the flags.
CHANGE-IS-DOWNCASE non-nil indicates that modifier CHANGE-CASE requests
lowercase, otherwise the modifier requests uppercase.
"Apply upper- and lower-case conversions to TEXT per the flags.
CHANGE-IS-DOWNCASE non-nil indicates that modifier CHANGE-CASE
requests lowercase, otherwise the modifier requests uppercase.
UPCASE is non-nil if the \"^\" modifier is active.
TITLE-CASE is non-nil if the \"*\" modifier is active.
CHANGE-CASE is non-nil if the \"#\" modifier is active.
@ -819,7 +824,8 @@ This is an internal helper for `time-stamp-string-preprocess'."
text)))
(defun time-stamp-do-number (format-char colon-count field-width time)
"Handle compatible FORMAT-CHAR where only default width/padding will change.
"Handle a FORMAT-CHAR mostly compatible with `format-time-string'.
The default width/padding may be different from `format-time-string'.
COLON-COUNT is non-0 if \":\" was specified. FIELD-WIDTH is the string
width specification or \"\". TIME is the time to convert.
This is an internal helper for `time-stamp-string-preprocess'."
@ -829,8 +835,9 @@ This is an internal helper for `time-stamp-string-preprocess'."
(string-to-number (time-stamp--format format-string time)))))
(defun time-stamp-filtered-buffer-file-name (type)
"Return the buffer file name, but with non-graphic characters replaced by ?.
TYPE is :absolute for the full name or :nondirectory for base name only."
"Return a printable string representing the buffer file name.
Non-graphic characters are replaced by ?. TYPE is :absolute
for the full name or :nondirectory for base name only."
(declare (ftype (function ((member :absolute :nondirectory)) string)))
(let ((file-name buffer-file-name)
(safe-character-filter
@ -838,7 +845,7 @@ TYPE is :absolute for the full name or :nondirectory for base name only."
(let ((category (get-char-code-property chr 'general-category)))
(if (or
;; Letter, Mark, Number, Punctuation, or Symbol
(member (aref (symbol-name category) 0) '(?L ?M ?N ?P ?S))
(memq (aref (symbol-name category) 0) '(?L ?M ?N ?P ?S))
;; spaces of various widths, but not ctrl chars like CR or LF
(eq category 'Zs))
chr
@ -850,21 +857,29 @@ TYPE is :absolute for the full name or :nondirectory for base name only."
(defvar time-stamp-conversion-warn t
"Enable warnings about soon-to-be-unsupported forms in `time-stamp-format'.
If nil, these warnings are disabled, which would be a bad idea!
You really need to update your files instead.
"Enable warnings for old formats in `time-stamp-format'.
When non-nil, `time-stamp' warns about unstable and
soon-to-be-changing conversions found in that buffer's
`time-stamp-format' value. The warning is displayed only
when a buffer's time-stamp is updated; merely viewing a file
does not warn.
The new formats will work with old versions of Emacs.
If nil, these warnings are disabled, which would be a bad idea.
Since you are changing your file anyway, please make one more
change and update its local variables list.
The recommended replacements will work with old versions of Emacs.
New formats are being recommended now to allow `time-stamp-format'
to change in the future to be compatible with `format-time-string'.
The new forms being recommended now will continue to work then.")
The new formats being recommended now will continue to work then.")
(defun time-stamp-conv-warn (old-form new-form &optional standard-form)
(defun time-stamp-conv-warn (old-format new-format &optional standard-format)
"Display a warning about a soon-to-be-obsolete format.
Suggests replacing OLD-FORM with NEW-FORM (same effect, but stable)
or (if provided) STANDARD-FORM (the effect the user may have expected
if they didn't read the documentation)."
Suggests replacing OLD-FORMAT with NEW-FORMAT (same effect, but stable)
or (if provided) STANDARD-FORMAT (the effect the user may have expected
if they didn't read the documentation).
This is an internal function called by `time-stamp'."
(cond
(time-stamp-conversion-warn
(with-current-buffer (get-buffer-create "*Time-stamp-compatibility*")
@ -877,15 +892,15 @@ if they didn't read the documentation)."
"The conversions recognized in `time-stamp-format' will change in a future\n"
"release to be more compatible with the function `format-time-string'.\n"
(cond
(standard-form
(standard-format
(concat
"Conversions that are changing are ambiguous and should be replaced by\n"
"Conversions that are changing are ambiguous and are best replaced by\n"
"stable conversions that make your intention clear.\n")))
"\n"
"The following obsolescent `time-stamp-format' conversion(s) were found:\n\n")))))
(insert old-form " -- use " new-form)
(if standard-form
(insert " or " standard-form))
(insert old-format " -- use " new-format)
(if standard-format
(insert " or " standard-format))
(insert "\n")
(help-make-xrefs))
(display-buffer "*Time-stamp-compatibility*"))))

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