Merge remote-tracking branch 'origin/master' into feature/android

This commit is contained in:
Po Lu 2023-06-25 08:16:34 +08:00
commit 7b5d32fa87
37 changed files with 2607 additions and 859 deletions

File diff suppressed because it is too large Load diff

View file

@ -6761,16 +6761,13 @@ The name of the @code{cons} function is not unreasonable: it is an
abbreviation of the word ``construct''. The origins of the names for
@code{car} and @code{cdr}, on the other hand, are esoteric: @code{car}
is an acronym from the phrase ``Contents of the Address part of the
Register''; and @code{cdr} (pronounced ``could-er'') is an acronym from
the phrase ``Contents of the Decrement part of the Register''. These
phrases refer to specific pieces of hardware on the very early
computer on which the original Lisp was developed. Besides being
obsolete, the phrases have been completely irrelevant for more than 25
years to anyone thinking about Lisp. Nonetheless, although a few
brave scholars have begun to use more reasonable names for these
functions, the old terms are still in use. In particular, since the
terms are used in the Emacs Lisp source code, we will use them in this
introduction.
Register''; and @code{cdr} (pronounced ``could-er'') is an acronym
from the phrase ``Contents of the Decrement part of the Register''.
These phrases refer to the IBM 704 computer on which the original Lisp
was developed.
The IBM 704 is a footnote in history, but these names are now beloved
traditions of Lisp.
@node car & cdr
@section @code{car} and @code{cdr}
@ -6791,9 +6788,6 @@ evaluating the following:
After evaluating the expression, @code{rose} will appear in the echo
area.
Clearly, a more reasonable name for the @code{car} function would be
@code{first} and this is often suggested.
@code{car} does not remove the first item from the list; it only reports
what it is. After @code{car} has been applied to a list, the list is
still the same as it was. In the jargon, @code{car} is
@ -6825,6 +6819,22 @@ Incidentally, in the example, the list of flowers is quoted. If it were
not, the Lisp interpreter would try to evaluate the list by calling
@code{rose} as a function. In this example, we do not want to do that.
For operating on lists, the names @code{first} and @code{rest} would
make more sense than the names @code{car} and @code{cdr}. Indeed,
some programmers define @code{first} and @code{rest} as aliases for
@code{car} and @code{cdr}, then write @code{first} and @code{rest} in
their code.
However, lists in Lisp are built using a lower-level structure known
as ``cons cells'' (@pxref{List Implementation}), in which there is no
such thing as ``first'' or ``rest,''and the @sc{car} and the @sc{cdr}
are symmetrical. Lisp does not try to hide the existence of cons
cells, and programs do use them for things other than lists. For this
reason, the names are helpful for reminding programmers that
@code{car} and @code{cdr} are in fact symmetrical, despite the
asymmetrical way they are used in lists.
@ignore
Clearly, a more reasonable name for @code{cdr} would be @code{rest}.
(There is a lesson here: when you name new functions, consider very
@ -6834,6 +6844,7 @@ these names is that the Emacs Lisp source code uses them, and if I did
not use them, you would have a hard time reading the code; but do,
please, try to avoid using these terms yourself. The people who come
after you will be grateful to you.)
@end ignore
When @code{car} and @code{cdr} are applied to a list made up of symbols,
such as the list @code{(pine fir oak maple)}, the element of the list
@ -9429,13 +9440,15 @@ pointed to. Hence, a list is kept as a series of electronic addresses.
@unnumberedsec Lists diagrammed
@end ifnottex
For example, the list @code{(rose violet buttercup)} has three elements,
@samp{rose}, @samp{violet}, and @samp{buttercup}. In the computer, the
electronic address of @samp{rose} is recorded in a segment of computer
memory along with the address that gives the electronic address of where
the atom @samp{violet} is located; and that address (the one that tells
where @samp{violet} is located) is kept along with an address that tells
where the address for the atom @samp{buttercup} is located.
For example, the list @code{(rose violet buttercup)} has three
elements, @samp{rose}, @samp{violet}, and @samp{buttercup}. In the
computer, the electronic address of @samp{rose} is recorded in a
segment of computer memory called a @dfn{cons cell} (because it's what
the function @code{cons} actually creates). That cons cell also holds
the address of a second cons cell, whose @sc{car} is the atom
@samp{violet}; and that address (the one that tells where to find
@samp{violet}) is kept along with the address of a third cons cell
which holds the address for the atom @samp{buttercup}.
@need 1200
This sounds more complicated than it is and is easier seen in a diagram:
@ -9652,6 +9665,8 @@ to say, the symbol @code{flowers} holds the address of the pair of
address-boxes, the first of which holds the address of @code{violet},
and the second of which holds the address of @code{buttercup}.
@cindex dotted pair
@cindex cons cell
A pair of address-boxes is called a @dfn{cons cell} or @dfn{dotted
pair}. @xref{Cons Cell Type, , Cons Cell and List Types, elisp, The GNU Emacs Lisp
Reference Manual}, and @ref{Dotted Pair Notation, , Dotted Pair

View file

@ -1792,34 +1792,43 @@ of them:
@table @code
@item priority
@kindex priority @r{(overlay property)}
This property's value determines the priority of the overlay.
If you want to specify a priority value, use either @code{nil}
(or zero), or a positive integer. Any other value has undefined behavior.
This property's value determines the priority of the overlay. If you
want to specify a priority value, use either @code{nil} (or zero), or
a positive integer, or a cons of two values. Any other value triggers
undefined behavior.
The priority matters when two or more overlays cover the same
character and both specify the same property with different values;
the one whose @code{priority} value is larger overrides the other.
the one whose @code{priority} value is higher overrides the other.
(For the @code{face} property, the higher priority overlay's value
does not completely override the other value; instead, its face
attributes override the face attributes of the @code{face} property
whose priority is lower.) If two overlays have the same priority
value, and one is nested in the other, then the inner one will prevail
over the outer one. If neither is nested in the other then you should
not make assumptions about which overlay will prevail.
does not completely override the other value; instead, its individual
face attributes override the corresponding face attributes of the
@code{face} property whose priority is lower.) If two overlays have
the same priority value, and one is ``nested'' in the other (i.e.,
covers fewer buffer or string positions), then the inner one will
prevail over the outer one. If neither is nested in the other then
you should not make assumptions about which overlay will prevail.
When a Lisp program puts overlays with defined priorities on text that
might have overlays without priorities, this could cause undesirable
results, because any overlay with a positive priority value will
override all the overlays without a priority. Since most Emacs
features that use overlays don't specify priorities for their
overlays, integer priorities should be used with care. Instead of
using integer priorities and risk overriding other overlays, you can
use priority values of the form @w{@code{(@var{primary} . @var{secondary})}},
where the @var{primary} value is used as described above, and
@var{secondary} is the fallback value used when @var{primary} and the
nesting considerations fail to resolve the precedence between
overlays. In particular, priority value @w{@code{(nil . @var{n})}},
with @var{n} a positive integer, allows to have the overlays ordered
by priority when necessary without completely overriding other
overlays.
Currently, all overlays take priority over text properties.
Note that Emacs sometimes uses non-numeric priority values for some of
its internal overlays, so do not try to do arithmetic on the priority
of an overlay (unless it is one that you created). In particular, the
overlay used for showing the region uses a priority value of the form
@w{@code{(@var{primary} . @var{secondary})}}, where the @var{primary}
value is used as described above, and @var{secondary} is the fallback
value used when @var{primary} and the nesting considerations fail to
resolve the precedence between overlays. However, you are advised not
to design Lisp programs based on this implementation detail; if you
need to put overlays in priority order, use the @var{sorted} argument
of @code{overlays-at}. @xref{Finding Overlays}.
If you need to put overlays in priority order, use the @var{sorted}
argument of @code{overlays-at}. @xref{Finding Overlays}.
@item window
@kindex window @r{(overlay property)}
@ -3330,8 +3339,8 @@ enough to the overlay, Emacs applies the face or face attributes
specified by the @code{mouse-face} property instead. @xref{Overlay
Properties}.
When multiple overlays cover one character, an overlay with higher
priority overrides those with lower priority. @xref{Overlays}.
When multiple overlays cover the same character, an overlay with
higher priority overrides those with lower priority. @xref{Overlays}.
@item
If the text contains a @code{face} or @code{mouse-face} property,

View file

@ -2813,13 +2813,23 @@ minibuffer window, it returns @code{nil}.
@vindex minibuffer-message-timeout
@defun minibuffer-message string &rest args
This function displays @var{string} temporarily at the end of the
minibuffer text, for a few seconds, or until the next input event
arrives, whichever comes first. The variable
@code{minibuffer-message-timeout} specifies the number of seconds to
wait in the absence of input. It defaults to 2. If @var{args} is
non-@code{nil}, the actual message is obtained by passing @var{string}
and @var{args} through @code{format-message}. @xref{Formatting Strings}.
This function is like @code{message} (@pxref{Displaying Messages}),
but it displays the messages specially when the user types in the
minibuffer, typically because Emacs prompted the user for some input.
When the minibuffer is the current buffer, this function displays the
message specified by @var{string} temporarily at the end of the
minibuffer text, and thus avoids hiding the minibuffer text by the
echo-area display of the message. It leaves the message on display
for a few seconds, or until the next input event arrives, whichever
comes first. The variable @code{minibuffer-message-timeout} specifies
the number of seconds to wait in the absence of input. It defaults to
2. If @var{args} is non-@code{nil}, the actual message is obtained by
passing @var{string} and @var{args} through @code{format-message}.
@xref{Formatting Strings}.
If called when the minibuffer is not the current buffer, this function
just calls @code{message}, and thus @var{string} will be shown in the
echo-area.
@end defun
@deffn Command minibuffer-inactive-mode

View file

@ -1888,11 +1888,14 @@ user option called the same as the global mode variable, but with
@code{-modes} instead of @code{-mode} at the end, i.e.@:
@code{@var{global-mode}s}. This variable will be used in a predicate
function that determines whether the minor mode should be activated in
a particular major mode. Valid values of @code{:predicate} include
@code{t} (use in all major modes), @code{nil} (don't use in any major
modes), or a list of mode names, optionally preceded with @code{not}
(as in @w{@code{(not @var{mode-name} @dots{})}}). These elements can
be mixed, as shown in the following examples.
a particular major mode, and users can customize the value of the
variable to control the modes in which the minor mode will be switched
on. Valid values of @code{:predicate} (and thus valid values of the
user option it creates) include @code{t} (use in all major modes),
@code{nil} (don't use in any major modes), or a list of mode names,
optionally preceded with @code{not} (as in @w{@code{(not
@var{mode-name} @dots{})}}). These elements can be mixed, as shown in
the following examples.
@example
(c-mode (not mail-mode message-mode) text-mode)

View file

@ -1131,9 +1131,9 @@ Now we can introduce the @dfn{query functions}.
@defun treesit-query-capture node query &optional beg end node-only
This function matches patterns in @var{query} within @var{node}. The
argument @var{query} can be either a string, an s-expression, or a
compiled query object. For now, we focus on the string syntax;
s-expression syntax and compiled queries are described at the end of
argument @var{query} can be either an s-expression, a string, or a
compiled query object. For now, we focus on the s-expression syntax;
string syntax and compiled queries are described at the end of
the section.
The argument @var{node} can also be a parser or a language symbol. A
@ -1165,8 +1165,8 @@ For example, suppose @var{node}'s text is @code{1 + 2}, and
@example
@group
(setq query
"(binary_expression
(number_literal) @@number-in-exp) @@biexp")
'((binary_expression
(number_literal) @@number-in-exp) @@biexp)
@end group
@end example
@ -1187,8 +1187,8 @@ For example, it could have two top-level patterns:
@example
@group
(setq query
"(binary_expression) @@biexp
(number_literal) @@number @@biexp")
'((binary_expression) @@biexp
(number_literal) @@number @@biexp)
@end group
@end example
@ -1246,23 +1246,23 @@ field, say, a @code{function_definition} without a @code{body} field:
@subheading Quantify node
@cindex quantify node, tree-sitter
Tree-sitter recognizes quantification operators @samp{*}, @samp{+},
and @samp{?}. Their meanings are the same as in regular expressions:
@samp{*} matches the preceding pattern zero or more times, @samp{+}
matches one or more times, and @samp{?} matches zero or one times.
Tree-sitter recognizes quantification operators @samp{:*}, @samp{:+},
and @samp{:?}. Their meanings are the same as in regular expressions:
@samp{:*} matches the preceding pattern zero or more times, @samp{:+}
matches one or more times, and @samp{:?} matches zero or one times.
For example, the following pattern matches @code{type_declaration}
nodes that have @emph{zero or more} @code{long} keywords.
@example
(type_declaration "long"*) @@long-type
(type_declaration "long" :*) @@long-type
@end example
The following pattern matches a type declaration that may or may not
have a @code{long} keyword:
@example
(type_declaration "long"?) @@long-type
(type_declaration "long" :?) @@long-type
@end example
@subheading Grouping
@ -1272,15 +1272,14 @@ groups and apply quantification operators to them. For example, to
express a comma-separated list of identifiers, one could write
@example
(identifier) ("," (identifier))*
(identifier) ("," (identifier)) :*
@end example
@subheading Alternation
Again, similar to regular expressions, we can express ``match any one
of these patterns'' in a pattern. The syntax is a list of patterns
enclosed in square brackets. For example, to capture some keywords in
C, the pattern would be
of these patterns'' in a pattern. The syntax is a vector of patterns.
For example, to capture some keywords in C, the pattern would be
@example
@group
@ -1295,7 +1294,7 @@ C, the pattern would be
@subheading Anchor
The anchor operator @samp{.} can be used to enforce juxtaposition,
The anchor operator @code{:anchor} can be used to enforce juxtaposition,
i.e., to enforce two things to be directly next to each other. The
two ``things'' can be two nodes, or a child and the end of its parent.
For example, to capture the first child, the last child, or two
@ -1304,19 +1303,19 @@ adjacent children:
@example
@group
;; Anchor the child with the end of its parent.
(compound_expression (_) @@last-child .)
(compound_expression (_) @@last-child :anchor)
@end group
@group
;; Anchor the child with the beginning of its parent.
(compound_expression . (_) @@first-child)
(compound_expression :anchor (_) @@first-child)
@end group
@group
;; Anchor two adjacent children.
(compound_expression
(_) @@prev-child
.
:anchor
(_) @@next-child)
@end group
@end example
@ -1332,8 +1331,8 @@ example, with the following pattern:
@example
@group
(
(array . (_) @@first (_) @@last .)
(#equal @@first @@last)
(array :anchor (_) @@first (_) @@last :anchor)
(:equal @@first @@last)
)
@end group
@end example
@ -1341,22 +1340,22 @@ example, with the following pattern:
@noindent
tree-sitter only matches arrays where the first element is equal to
the last element. To attach a predicate to a pattern, we need to
group them together. A predicate always starts with a @samp{#}.
Currently there are three predicates: @code{#equal}, @code{#match},
and @code{#pred}.
group them together. Currently there are three predicates:
@code{:equal}, @code{:match}, and @code{:pred}.
@deffn Predicate equal arg1 arg2
@deffn Predicate :equal arg1 arg2
Matches if @var{arg1} is equal to @var{arg2}. Arguments can be either
strings or capture names. Capture names represent the text that the
captured node spans in the buffer.
@end deffn
@deffn Predicate match regexp capture-name
@deffn Predicate :match regexp capture-name
Matches if the text that @var{capture-name}'s node spans in the buffer
matches regular expression @var{regexp}. Matching is case-sensitive.
matches regular expression @var{regexp}, given as a string literal.
Matching is case-sensitive.
@end deffn
@deffn Predicate pred fn &rest nodes
@deffn Predicate :pred fn &rest nodes
Matches if function @var{fn} returns non-@code{nil} when passed each
node in @var{nodes} as arguments. The function runs with the current
buffer set to the buffer of node being queried.
@ -1366,28 +1365,13 @@ Note that a predicate can only refer to capture names that appear in
the same pattern. Indeed, it makes little sense to refer to capture
names in other patterns.
@heading S-expression patterns
@heading String patterns
@cindex tree-sitter patterns as sexps
@cindex patterns, tree-sitter, in sexp form
Besides strings, Emacs provides an s-expression based syntax for
tree-sitter patterns. It largely resembles the string-based syntax.
For example, the following query
@example
@group
(treesit-query-capture
node "(addition_expression
left: (_) @@left
\"+\" @@plus-sign
right: (_) @@right) @@addition
[\"return\" \"break\"] @@keyword")
@end group
@end example
@noindent
is equivalent to
@cindex tree-sitter patterns as strings
@cindex patterns, tree-sitter, in string form
Besides s-expressions, Emacs allows the tree-sitter's native query
syntax to be used by writing them as strings. It largely resembles
the s-expression syntax. For example, the following query
@example
@group
@ -1401,36 +1385,40 @@ is equivalent to
@end group
@end example
Most patterns can be written directly as strange but nevertheless
valid s-expressions. Only a few of them need modification:
@itemize
@item
Anchor @samp{.} is written as @code{:anchor}.
@item
@samp{?} is written as @samp{:?}.
@item
@samp{*} is written as @samp{:*}.
@item
@samp{+} is written as @samp{:+}.
@item
@code{#equal} is written as @code{:equal}. In general, predicates
change their @samp{#} to @samp{:}.
@end itemize
For example,
@noindent
is equivalent to
@example
@group
"(
(compound_expression . (_) @@first (_)* @@rest)
(#match \"love\" @@first)
)"
(treesit-query-capture
node "(addition_expression
left: (_) @@left
\"+\" @@plus-sign
right: (_) @@right) @@addition
[\"return\" \"break\"] @@keyword")
@end group
@end example
@noindent
is written in s-expression syntax as
Most patterns can be written directly as s-expressions inside a string.
Only a few of them need modification:
@itemize
@item
Anchor @code{:anchor} is written as @samp{.}.
@item
@samp{:?} is written as @samp{?}.
@item
@samp{:*} is written as @samp{*}.
@item
@samp{:+} is written as @samp{+}.
@item
@code{:equal}, @code{:match} and @code{:pred} are written as
@code{#equal}, @code{#match} and @code{#pred}, respectively.
In general, predicates change their @samp{:} to @samp{#}.
@end itemize
For example,
@example
@group
@ -1441,6 +1429,18 @@ is written in s-expression syntax as
@end group
@end example
@noindent
is written in string form as
@example
@group
"(
(compound_expression . (_) @@first (_)* @@rest)
(#match \"love\" @@first)
)"
@end group
@end example
@heading Compiling queries
@cindex compiling tree-sitter queries
@ -1461,7 +1461,7 @@ validate and debug the query.
@end defun
@defun treesit-query-language query
This function return the language of @var{query}.
This function returns the language of @var{query}.
@end defun
@defun treesit-query-expand query
@ -1653,7 +1653,7 @@ ranges for @acronym{CSS} and JavaScript parsers:
(setq css-range
(treesit-query-range
'html
"(style_element (raw_text) @@capture)"))
'((style_element (raw_text) @@capture))))
(treesit-parser-set-included-ranges css css-range)
@end group
@ -1662,7 +1662,7 @@ ranges for @acronym{CSS} and JavaScript parsers:
(setq js-range
(treesit-query-range
'html
"(script_element (raw_text) @@capture)"))
'((script_element (raw_text) @@capture))))
(treesit-parser-set-included-ranges js js-range)
@end group
@end example

View file

@ -115,6 +115,21 @@ web page hit @kbd{g} (@code{eww-reload}).
@kbd{w} calls @code{eww-copy-page-url}, which will copy the current
page's URL to the kill ring instead.
@findex eww-copy-alternate-url
@kindex A
The @kbd{A} command (@code{eww-copy-alternate-url}) copies the URL
of an alternate link on the current page into the kill ring. If the
page specifies multiple alternate links, this command prompts for one
of them in the minibuffer, with completion. Alternate links are
references that an @acronym{HTML} page may include to point to other
documents that act as its alternative representations. Notably,
@acronym{HTML} pages can use alternate links to point to their
translated versions and to @acronym{RSS} feeds. Alternate links
appear in the @samp{<head>} section of @acronym{HTML} pages as
@samp{<link>} elements with @samp{rel} attribute equal to
@samp{``alternate''}; they are part of the page's metadata and are not
visible in its rendered content.
@findex eww-open-in-new-buffer
@kindex M-RET
The @kbd{M-@key{RET}} command (@code{eww-open-in-new-buffer}) opens the

File diff suppressed because it is too large Load diff

View file

@ -283,6 +283,13 @@ The interactive minibuffer prompt when invoking 'eww' now provides
completions from 'eww-suggest-uris'. 'eww-suggest-uris' now includes
bookmark URIs.
+++
*** New command 'eww-copy-alternate-url'.
It copies an alternate link on the page currently visited in EWW into
the kill ring. Alternate links are optional metadata that HTML pages
use for linking to their alternative representations, such as
translated versions or associated RSS feeds.
** go-ts-mode
+++

View file

@ -3492,6 +3492,39 @@ See
https://lists.gnu.org/r/emacs-devel/2010-07/msg01266.html
*** Building the MS-Windows port with native compilation fails
This is known to happen when using MinGW64 GCC 13.1, and seems to
affect byte-compilation: the built Emacs crashes while byte-compiling
some Lisp files. (This doesn't happen when building a release
tarball, because all the Lisp files are already byte-compiled there,
but then Emacs could crash later when you use it to byte-compile your
or third-party Lisp packages.)
The reason seems to be specific to MS-Windows or the MinGW64 port of
GCC 13.1, and is somehow related to optimizations in this GCC version.
There are several known workarounds:
. Use non-default optimization flags. For example, configuring the
build like this will avoid the problem:
CFLAGS='-O1 -gdwarf-4 -g3' ./configure ...
(replace the ellipsis "..." with the rest of 'configure' options
and arguments).
. Prevent GCC from performing a specific optimization:
CFLAGS='-O2 -gdwarf-4 -g3 -fno-optimize-sibling-calls' ./configure ...
This is actually a variant of the previous workaround, except that
it allows you to have almost the full set of optimizations used by
-O2.
. Downgrade to GCC 12.x.
. Build Emacs without native compilation.
*** Building the native MS-Windows port fails due to unresolved externals
The linker error messages look like this:

View file

@ -437,6 +437,42 @@ ifeq ($(HAVE_NATIVE_COMP),yes)
$(emacs) -l comp -f comp-compile-all-trampolines
endif
.PHONY: compile-eln-targets compile-eln-aot
# ELNDONE is defined by ../src/Makefile, as the list of preloaded
# *.eln files, which are therefore already compiled by the time
# compile-eln-aot is called.
ifeq ($(NATIVE_COMPILATION_AOT),yes)
%.eln: %.el
$(AM_V_ELN)$(emacs) $(BYTE_COMPILE_FLAGS) \
-l comp -f byte-compile-refresh-preloaded \
--eval '(batch-native-compile t)' $<
compile-eln-targets: $(filter-out $(ELNDONE),$(TARGETS))
else
compile-eln-targets:
endif
# This is called from ../src/Makefile when building a release tarball
# configured --with-native-compilation=aot.
compile-eln-aot:
@(cd $(lisp) && \
els=`echo "${SUBDIRS_REL} " | sed -e 's|/\./|/|g' -e 's|/\. | |g' -e 's| |/*.el |g'`; \
for el in $$els; do \
test -f $$el || continue; \
test -f $${el}c || continue; \
GREP_OPTIONS= grep '^;.*[^a-zA-Z]no-byte-compile: *t' $$el > /dev/null && \
continue; \
GREP_OPTIONS= grep '^;.*[^a-zA-Z]no-native-compile: *t' $$el > /dev/null && \
continue; \
echo "$${el}n"; \
done | xargs $(XARGS_LIMIT) echo) | \
while read chunk; do \
$(MAKE) compile-eln-targets \
TARGETS="$$chunk" ELNDONE="$(ELNDONE)"; \
done
.PHONY: backup-compiled-files compile-after-backup
# Backup compiled Lisp files in elc.tar.gz. If that file already

View file

@ -167,8 +167,8 @@ Earlier variables shadow later ones with the same name.")
((or `(lambda . ,_) `(closure . ,_))
;; While byte-compile-unfold-bcf can inline dynbind byte-code into
;; letbind byte-code (or any other combination for that matter), we
;; can only inline dynbind source into dynbind source or letbind
;; source into letbind source.
;; can only inline dynbind source into dynbind source or lexbind
;; source into lexbind source.
;; When the function comes from another file, we byte-compile
;; the inlined function first, and then inline its byte-code.
;; This also has the advantage that the final code does not
@ -176,7 +176,10 @@ Earlier variables shadow later ones with the same name.")
;; the build more reproducible.
(if (eq fn localfn)
;; From the same file => same mode.
(macroexp--unfold-lambda `(,fn ,@(cdr form)))
(let* ((newform `(,fn ,@(cdr form)))
(unfolded (macroexp--unfold-lambda newform)))
;; Use the newform only if it could be optimized.
(if (eq unfolded newform) form unfolded))
;; Since we are called from inside the optimizer, we need to make
;; sure not to propagate lexvar values.
(let ((byte-optimize--lexvars nil)
@ -452,13 +455,6 @@ for speeding up processing.")
`(progn ,@(byte-optimize-body env t))
`(,fn ,vars ,(mapcar #'byte-optimize-form env) . ,rest)))
(`((lambda . ,_) . ,_)
(let ((newform (macroexp--unfold-lambda form)))
(if (eq newform form)
;; Some error occurred, avoid infinite recursion.
form
(byte-optimize-form newform for-effect))))
(`(setq ,var ,expr)
(let ((lexvar (assq var byte-optimize--lexvars))
(value (byte-optimize-form expr nil)))
@ -1412,15 +1408,15 @@ See Info node `(elisp) Integer Basics'."
(defun byte-optimize-funcall (form)
;; (funcall #'(lambda ...) ...) -> ((lambda ...) ...)
;; (funcall #'(lambda ...) ...) -> (let ...)
;; (funcall #'SYM ...) -> (SYM ...)
;; (funcall 'SYM ...) -> (SYM ...)
(let* ((fn (nth 1 form))
(head (car-safe fn)))
(if (or (eq head 'function)
(and (eq head 'quote) (symbolp (nth 1 fn))))
(cons (nth 1 fn) (cdr (cdr form)))
form)))
(pcase form
(`(,_ #'(lambda . ,_) . ,_)
(macroexp--unfold-lambda form))
(`(,_ ,(or `#',f `',(and f (pred symbolp))) . ,actuals)
`(,f ,@actuals))
(_ form)))
(defun byte-optimize-apply (form)
(let ((len (length form)))

View file

@ -3556,12 +3556,6 @@ lambda-expression."
((and (byte-code-function-p (car form))
(memq byte-optimize '(t lap)))
(byte-compile-unfold-bcf form))
((and (eq (car-safe (car form)) 'lambda)
;; if the form comes out the same way it went in, that's
;; because it was malformed, and we couldn't unfold it.
(not (eq form (setq form (macroexp--unfold-lambda form)))))
(byte-compile-form form byte-compile--for-effect)
(setq byte-compile--for-effect nil))
((byte-compile-normal-call form)))
(if byte-compile--for-effect
(byte-compile-discard))

View file

@ -245,17 +245,18 @@ The name is made by appending a number to PREFIX, default \"T\"."
(defun cl--slet (bindings body)
"Like `cl--slet*' but for \"parallel let\"."
(cond
((seq-some (lambda (binding) (macroexp--dynamic-variable-p (car binding)))
bindings)
;; FIXME: We use `identity' to obfuscate the code enough to
;; circumvent the known bug in `macroexp--unfold-lambda' :-(
`(funcall (identity (lambda (,@(mapcar #'car bindings))
,@(macroexp-unprogn body)))
,@(mapcar #'cadr bindings)))
((null (cdr bindings))
(macroexp-let* bindings body))
(t `(let ,bindings ,@(macroexp-unprogn body)))))
(let ((dyn nil)) ;Is there a var declared as dynbound among the bindings?
;; `seq-some' lead to bootstrap problems.
(dolist (binding bindings)
(if (macroexp--dynamic-variable-p (car binding)) (setq dyn t)))
(cond
(dyn
`(funcall (lambda (,@(mapcar #'car bindings))
,@(macroexp-unprogn body))
,@(mapcar #'cadr bindings)))
((null (cdr bindings))
(macroexp-let* bindings body))
(t `(let ,bindings ,@(macroexp-unprogn body))))))
(defun cl--slet* (bindings body)
"Like `macroexp-let*' but uses static scoping for all the BINDINGS."

View file

@ -63,16 +63,19 @@ redefine OBJECT if it is a symbol."
(list (intern (completing-read (format-prompt "Disassemble function" fn)
obarray 'fboundp t nil nil def))
nil 0 t)))
(if (and (consp object) (not (functionp object)))
(setq object `(lambda () ,object)))
(or indent (setq indent 0)) ;Default indent to zero
(save-excursion
(if (or interactive-p (null buffer))
(with-output-to-temp-buffer "*Disassemble*"
(set-buffer "*Disassemble*")
(disassemble-internal object indent (not interactive-p)))
(set-buffer buffer)
(disassemble-internal object indent nil)))
(let ((lb lexical-binding))
(if (and (consp object) (not (functionp object)))
(setq object `(lambda () ,object)))
(or indent (setq indent 0)) ;Default indent to zero
(save-excursion
(if (or interactive-p (null buffer))
(with-output-to-temp-buffer "*Disassemble*"
(set-buffer "*Disassemble*")
(let ((lexical-binding lb))
(disassemble-internal object indent (not interactive-p))))
(set-buffer buffer)
(let ((lexical-binding lb))
(disassemble-internal object indent nil)))))
nil)
(declare-function native-comp-unit-file "data.c")

View file

@ -453,14 +453,17 @@ TURN-ON is a function that will be called with no args in every buffer
and that should try to turn MODE on if applicable for that buffer.
Each of KEY VALUE is a pair of CL-style keyword arguments.
The :predicate argument specifies in which major modes should the
The :predicate key specifies in which major modes should the
globalized minor mode be switched on. The value should be t (meaning
switch on the minor mode in all major modes), nil (meaning don't
switch on in any major mode), a list of modes (meaning switch on only
in those modes and their descendants), or a list (not MODES...),
meaning switch on in any major mode except MODES. The value can also
mix all of these forms, see the info node `Defining Minor Modes' for
details.
details. The :predicate key causes the macro to create a user option
named the same as MODE, but ending with \"-modes\" instead of \"-mode\".
That user option can then be used to customize in which modes this
globalized minor mode will be switched on.
As the minor mode defined by this function is always global, any
:global keyword is ignored.
Other keywords have the same meaning as in `define-minor-mode',

View file

@ -407,7 +407,7 @@ The search is done in the source for library LIBRARY."
(setq library (substring library 0 (match-beginning 1))))
;; Strip extension from .emacs.el to make sure symbol is searched in
;; .emacs too.
(when (string-match "\\.emacs\\(.el\\)" library)
(when (string-match "\\.emacs\\(.el\\)\\'" library)
(setq library (substring library 0 (match-beginning 1))))
(let* ((filename (find-library-name library))
(regexp-symbol (cdr (assq type find-function-regexp-alist))))

View file

@ -244,68 +244,64 @@ It should normally be a symbol with position and it defaults to FORM."
new-form)))
(defun macroexp--unfold-lambda (form &optional name)
;; In lexical-binding mode, let and functions don't bind vars in the same way
;; (let obey special-variable-p, but functions don't). But luckily, this
;; doesn't matter here, because function's behavior is underspecified so it
;; can safely be turned into a `let', even though the reverse is not true.
(or name (setq name "anonymous lambda"))
(let* ((lambda (car form))
(values (cdr form))
(arglist (nth 1 lambda))
(body (cdr (cdr lambda)))
optionalp restp
bindings)
(if (and (stringp (car body)) (cdr body))
(setq body (cdr body)))
(if (and (consp (car body)) (eq 'interactive (car (car body))))
(setq body (cdr body)))
;; FIXME: The checks below do not belong in an optimization phase.
(while arglist
(cond ((eq (car arglist) '&optional)
;; ok, I'll let this slide because funcall_lambda() does...
;; (if optionalp (error "Multiple &optional keywords in %s" name))
(if restp (error "&optional found after &rest in %s" name))
(if (null (cdr arglist))
(error "Nothing after &optional in %s" name))
(setq optionalp t))
((eq (car arglist) '&rest)
;; ...but it is by no stretch of the imagination a reasonable
;; thing that funcall_lambda() allows (&rest x y) and
;; (&rest x &optional y) in arglists.
(if (null (cdr arglist))
(error "Nothing after &rest in %s" name))
(if (cdr (cdr arglist))
(error "Multiple vars after &rest in %s" name))
(setq restp t))
(restp
(setq bindings (cons (list (car arglist)
(and values (cons 'list values)))
bindings)
values nil))
((and (not optionalp) (null values))
(setq arglist nil values 'too-few))
(t
(setq bindings (cons (list (car arglist) (car values))
bindings)
values (cdr values))))
(setq arglist (cdr arglist)))
(if values
(macroexp-warn-and-return
(format-message
(if (eq values 'too-few)
"attempt to open-code `%s' with too few arguments"
"attempt to open-code `%s' with too many arguments")
name)
form nil nil arglist)
;; The following leads to infinite recursion when loading a
;; file containing `(defsubst f () (f))', and then trying to
;; byte-compile that file.
;;(setq body (mapcar 'byte-optimize-form body)))
(if bindings
`(let ,(nreverse bindings) . ,body)
(macroexp-progn body)))))
(pcase form
((or `(funcall (function ,lambda) . ,actuals) `(,lambda . ,actuals))
(let* ((formals (nth 1 lambda))
(body (cdr (macroexp-parse-body (cddr lambda))))
optionalp restp
(dynboundarg nil)
bindings)
;; FIXME: The checks below do not belong in an optimization phase.
(while formals
(if (macroexp--dynamic-variable-p (car formals))
(setq dynboundarg t))
(cond ((eq (car formals) '&optional)
;; ok, I'll let this slide because funcall_lambda() does...
;; (if optionalp (error "Multiple &optional keywords in %s" name))
(if restp (error "&optional found after &rest in %s" name))
(if (null (cdr formals))
(error "Nothing after &optional in %s" name))
(setq optionalp t))
((eq (car formals) '&rest)
;; ...but it is by no stretch of the imagination a reasonable
;; thing that funcall_lambda() allows (&rest x y) and
;; (&rest x &optional y) in formalss.
(if (null (cdr formals))
(error "Nothing after &rest in %s" name))
(if (cdr (cdr formals))
(error "Multiple vars after &rest in %s" name))
(setq restp t))
(restp
(setq bindings (cons (list (car formals)
(and actuals (cons 'list actuals)))
bindings)
actuals nil))
((and (not optionalp) (null actuals))
(setq formals nil actuals 'too-few))
(t
(setq bindings (cons (list (car formals) (car actuals))
bindings)
actuals (cdr actuals))))
(setq formals (cdr formals)))
(cond
(actuals
(macroexp-warn-and-return
(format-message
(if (eq actuals 'too-few)
"attempt to open-code `%s' with too few arguments"
"attempt to open-code `%s' with too many arguments")
name)
form nil nil formals))
;; In lexical-binding mode, let and functions don't bind vars in
;; the same way (let obey special-variable-p, but functions
;; don't). So if one of the vars is declared as dynamically scoped, we
;; can't just convert the call to `let'.
;; FIXME: We should α-rename the affected args and then use `let'.
(dynboundarg form)
(bindings `(let ,(nreverse bindings) . ,body))
(t (macroexp-progn body)))))
(_ (error "Not an unfoldable form: %S" form))))
(defun macroexp--dynamic-variable-p (var)
"Whether the variable VAR is dynamically scoped.
@ -437,27 +433,22 @@ Assumes the caller has bound `macroexpand-all-environment'."
(setq args (cddr args)))
(cons 'progn (nreverse assignments))))))
(`(,(and fun `(lambda . ,_)) . ,args)
;; Embedded lambda in function position.
;; If the byte-optimizer is loaded, try to unfold this,
;; i.e. rewrite it to (let (<args>) <body>). We'd do it in the optimizer
;; anyway, but doing it here (i.e. earlier) can sometimes avoid the
;; creation of a closure, thus resulting in much better code.
(let ((newform (macroexp--unfold-lambda form)))
(if (eq newform form)
;; Unfolding failed for some reason, avoid infinite recursion.
(macroexp--cons (macroexp--all-forms fun 2)
(macroexp--all-forms args)
form)
(macroexp--expand-all newform))))
(macroexp--cons (macroexp--all-forms fun 2)
(macroexp--all-forms args)
form))
(`(funcall ,exp . ,args)
(let ((eexp (macroexp--expand-all exp))
(eargs (macroexp--all-forms args)))
;; Rewrite (funcall #'foo bar) to (foo bar), in case `foo'
;; has a compiler-macro, or to unfold it.
(pcase eexp
;; Rewrite (funcall #'foo bar) to (foo bar), in case `foo'
;; has a compiler-macro, or to unfold it.
((and `#',f
(guard (not (or (special-form-p f) (macrop f))))) ;; bug#46636
(guard (and (symbolp f)
;; bug#46636
(not (or (special-form-p f) (macrop f))))))
(macroexp--expand-all `(,f . ,eargs)))
(`#'(lambda . ,_)
(macroexp--unfold-lambda `(,fn ,eexp . ,eargs)))
(_ `(,fn ,eexp . ,eargs)))))
(`(funcall . ,_) form) ;bug#53227
(`(,func . ,_)

View file

@ -187,8 +187,10 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
:eval (format "This number is %d" 4))
"Manipulating Strings"
(substring
:eval (substring "foobar" 0 3)
:eval (substring "foobar" 3))
:eval (substring "abcde" 1 3)
:eval (substring "abcde" 2)
:eval (substring "abcde" 1 -1)
:eval (substring "abcde" -4 4))
(string-limit
:eval (string-limit "foobar" 3)
:eval (string-limit "foobar" 3 t)

View file

@ -715,11 +715,21 @@ for use at QPOS."
"Text properties added to the text shown by `minibuffer-message'.")
(defun minibuffer-message (message &rest args)
"Temporarily display MESSAGE at the end of the minibuffer.
The text is displayed for `minibuffer-message-timeout' seconds,
or until the next input event arrives, whichever comes first.
Enclose MESSAGE in [...] if this is not yet the case.
If ARGS are provided, then pass MESSAGE through `format-message'."
"Temporarily display MESSAGE at the end of minibuffer text.
This function is designed to be called from the minibuffer, i.e.,
when Emacs prompts the user for some input, and the user types
into the minibuffer. If called when the current buffer is not
the minibuffer, this function just calls `message', and thus
displays MESSAGE in the echo-area.
When called from the minibuffer, this function displays MESSAGE
at the end of minibuffer text for `minibuffer-message-timeout'
seconds, or until the next input event arrives, whichever comes first.
It encloses MESSAGE in [...] if it is not yet enclosed.
The intent is to show the message without hiding what the user typed.
If ARGS are provided, then the function first passes MESSAGE
through `format-message'.
If some of the minibuffer text has the `minibuffer-message' text
property, MESSAGE is shown at that position instead of EOB."
(if (not (minibufferp (current-buffer) t))
(progn
(if args
@ -796,7 +806,7 @@ The minibuffer message functions include `minibuffer-message' and
(next-single-property-change pt 'minibuffer-message nil (point-max)))))
(defun set-minibuffer-message (message)
"Temporarily display MESSAGE at the end of the minibuffer.
"Temporarily display MESSAGE at the end of the active minibuffer window.
If some part of the minibuffer text has the `minibuffer-message' property,
the message will be displayed before the first such character, instead of
at the end of the minibuffer.
@ -954,7 +964,7 @@ is at its default value `grow-only'."
multi-message-separator)))
(defun clear-minibuffer-message ()
"Clear minibuffer message.
"Clear message temporarily shown in the minibuffer.
Intended to be called via `clear-message-function'."
(when (not noninteractive)
(when (timerp minibuffer-message-timer)

View file

@ -1086,6 +1086,7 @@ the like."
"&" #'eww-browse-with-external-browser
"d" #'eww-download
"w" #'eww-copy-page-url
"A" #'eww-copy-alternate-url
"C" #'url-cookie-list
"v" #'eww-view-source
"R" #'eww-readable
@ -2576,4 +2577,83 @@ Otherwise, the restored buffer will contain a prompt to do so by using
(provide 'eww)
;;; Alternate links (RSS and Atom feeds, etc.)
(defun eww--alternate-urls (dom &optional base)
"Return an alist of alternate links in DOM.
Each element is a list of the form (URL TYPE TITLE) where URL is
the href attribute of the link expanded relative to BASE, TYPE is
its type attribute, and TITLE is its title attribute. If any of
these attributes is absent, the corresponding element is nil."
(let ((alternates
(seq-filter
(lambda (attrs) (string= (alist-get 'rel attrs)
"alternate"))
(mapcar #'dom-attributes (dom-by-tag dom 'link)))))
(mapcar (lambda (alternate)
(list (url-expand-file-name (alist-get 'href alternate)
base)
(alist-get 'type alternate)
(alist-get 'title alternate)))
alternates)))
(defun eww-read-alternate-url ()
"Get the URL of an alternate link of this page.
If there is just one alternate link, return its URL. If there
are multiple alternate links, prompt for one in the minibuffer
with completion. If there are none, return nil."
(when-let ((alternates (eww--alternate-urls
(plist-get eww-data :dom)
(plist-get eww-data :url))))
(let ((url-max-width
(seq-max (mapcar #'string-pixel-width
(mapcar #'car alternates))))
(title-max-width
(seq-max (mapcar #'string-pixel-width
(mapcar #'caddr alternates))))
(sep-width (string-pixel-width " ")))
(if (cdr alternates)
(let ((completion-extra-properties
(list :annotation-function
(lambda (feed)
(let* ((attrs (alist-get feed
alternates
nil
nil
#'string=))
(type (car attrs))
(title (cadr attrs)))
(concat
(propertize " " 'display
`(space :align-to
(,(+ sep-width
url-max-width))))
title
(when type
(concat
(propertize " " 'display
`(space :align-to
(,(+ (* 2 sep-width)
url-max-width
title-max-width))))
"[" type "]"))))))))
(completing-read "Alternate URL: " alternates nil t))
(caar alternates)))))
(defun eww-copy-alternate-url ()
"Copy the alternate URL of the current page into the kill ring.
If there are multiple alternate links on the current page, prompt
for one in the minibuffer, with completion.
Alternate links are references that an HTML page may include to
point to its alternative representations, such as a translated
version or an RSS feed."
(interactive nil eww-mode)
(if-let ((url (eww-read-alternate-url)))
(progn
(kill-new url)
(message "Copied %s to kill ring" url))
(user-error "No alternate links found on this page!")))
;;; eww.el ends here

View file

@ -2659,7 +2659,7 @@ need for `c-font-lock-extra-types'.")
;; prevent a repeat invocation. See elisp/lispref page "Search-based
;; fontification".
(let (pos)
(while
(while
(and (< (point) limit)
(c-syntactic-re-search-forward c-using-key limit 'end))
(while ; Do one declarator of a comma separated list, each time around.

View file

@ -230,7 +230,7 @@ chosen (interactively or automatically)."
. ,(eglot-alternatives '("digestif" "texlab")))
(erlang-mode . ("erlang_ls" "--transport" "stdio"))
((yaml-ts-mode yaml-mode) . ("yaml-language-server" "--stdio"))
(nix-mode . ,(eglot-alternatives '("nil" "rnix-lsp")))
(nix-mode . ,(eglot-alternatives '("nil" "rnix-lsp" "nixd")))
(nickel-mode . ("nls"))
(gdscript-mode . ("localhost" 6008))
((fortran-mode f90-mode) . ("fortls"))
@ -3769,7 +3769,7 @@ If NOERROR, return predicate, else erroring function."
(if peg-after-p
(make-overlay (point) (1+ (point)) nil t)
(make-overlay (1- (point)) (point) nil nil nil)))
(do-it (label lpad rpad i)
(do-it (label lpad rpad i n)
(let* ((firstp (zerop i))
(tweak-cursor-p (and firstp peg-after-p))
(ov (make-ov))
@ -3782,18 +3782,18 @@ If NOERROR, return predicate, else erroring function."
(1 'eglot-type-hint-face)
(2 'eglot-parameter-hint-face)
(_ 'eglot-inlay-hint-face))))
(overlay-put ov 'priority i)
(overlay-put ov 'priority (if peg-after-p i (- n i)))
(overlay-put ov 'eglot--inlay-hint t)
(overlay-put ov 'evaporate t)
(overlay-put ov 'eglot--overlay t))))
(if (stringp label) (do-it label left-pad right-pad 0)
(if (stringp label) (do-it label left-pad right-pad 0 1)
(cl-loop
for i from 0 for ldetail across label
do (eglot--dbind ((InlayHintLabelPart) value) ldetail
(do-it value
(and (zerop i) left-pad)
(and (= i (1- (length label))) right-pad)
i)))))))))
i (length label))))))))))
(jsonrpc-async-request
(eglot--current-server-or-lose)
:textDocument/inlayHint

View file

@ -453,7 +453,9 @@ valid signal handlers.")
(const :tag "Unlimited" nil))
:version "22.1")
(defcustom gdb-non-stop-setting (not (eq system-type 'windows-nt))
;; This is disabled by default because we don't really support
;; asynchronous execution of the debuggee; see bug#63084. FIXME.
(defcustom gdb-non-stop-setting nil
"If non-nil, GDB sessions are expected to support the non-stop mode.
When in the non-stop mode, stopped threads can be examined while
other threads continue to execute.
@ -468,7 +470,7 @@ don't support the non-stop mode.
GDB session needs to be restarted for this setting to take effect."
:type 'boolean
:group 'gdb-non-stop
:version "26.1")
:version "29.1")
(defcustom gdb-debuginfod-enable-setting
;; debuginfod servers are only for ELF executables, and elfutils, of

View file

@ -80,6 +80,7 @@
((parent-is "const_declaration") parent-bol go-ts-mode-indent-offset)
((parent-is "default_case") parent-bol go-ts-mode-indent-offset)
((parent-is "expression_case") parent-bol go-ts-mode-indent-offset)
((parent-is "selector_expression") parent-bol go-ts-mode-indent-offset)
((parent-is "expression_switch_statement") parent-bol 0)
((parent-is "field_declaration_list") parent-bol go-ts-mode-indent-offset)
((parent-is "import_spec_list") parent-bol go-ts-mode-indent-offset)

View file

@ -1406,6 +1406,10 @@ keyword
- Point is inside a paren from a block start followed by some
items on the same line.
- START is the first non space char position *after* the open paren.
:inside-paren-continuation-line
- Point is on a continuation line inside a paren.
- START is the position where the previous line (excluding lines
for inner parens) starts.
:after-backslash
- Fallback case when point is after backslash.
@ -1460,7 +1464,21 @@ keyword
(= (line-number-at-pos)
(progn
(python-util-forward-comment)
(line-number-at-pos))))))))
(line-number-at-pos)))))))
(continuation-start
(when start
(save-excursion
(forward-line -1)
(back-to-indentation)
;; Skip inner parens.
(cl-loop with prev-start = (python-syntax-context 'paren)
while (and prev-start (>= prev-start start))
if (= prev-start start)
return (point)
else do (goto-char prev-start)
(back-to-indentation)
(setq prev-start
(python-syntax-context 'paren)))))))
(when start
(cond
;; Current line only holds the closing paren.
@ -1476,6 +1494,9 @@ keyword
(back-to-indentation)
(python-syntax-closing-paren-p))
(cons :inside-paren-at-closing-nested-paren start))
;; This line is a continuation of the previous line.
(continuation-start
(cons :inside-paren-continuation-line continuation-start))
;; This line starts from an opening block in its own line.
((save-excursion
(goto-char start)
@ -1591,7 +1612,8 @@ possibilities can be narrowed to specific indentation points."
(`(,(or :after-line
:after-comment
:inside-string
:after-backslash) . ,start)
:after-backslash
:inside-paren-continuation-line) . ,start)
;; Copy previous indentation.
(goto-char start)
(current-indentation))

View file

@ -1121,10 +1121,15 @@ possible values of STATE are explained in `vc-state', and MODEL in
the returned list.
BEWARE: this function may change the current buffer."
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(vc-deduce-fileset-1 not-state-changing
allow-unregistered
state-model-only-files)))
(let (new-buf res)
(with-current-buffer (or (buffer-base-buffer) (current-buffer))
(setq res
(vc-deduce-fileset-1 not-state-changing
allow-unregistered
state-model-only-files))
(setq new-buf (current-buffer)))
(set-buffer new-buf)
res))
(defun vc-deduce-fileset-1 (not-state-changing
allow-unregistered

View file

@ -284,71 +284,79 @@ The user is asked to choose between each NAME from ITEMS.
If ITEMS has simple item definitions, then this function returns the VALUE of
the chosen element. If ITEMS is a keymap, then the return value is the symbol
in the key vector, as in the argument of `define-key'."
(cond ((and (< (length items) widget-menu-max-size)
event (display-popup-menus-p))
;; Mouse click.
(if (keymapp items)
;; Modify the keymap prompt, and then restore the old one, if any.
(let ((prompt (keymap-prompt items)))
(unwind-protect
(progn
(setq items (delete prompt items))
(push title (cdr items))
;; Return just the first element of the list of events.
(car (x-popup-menu event items)))
(setq items (delete title items))
(when prompt
(push prompt (cdr items)))))
(x-popup-menu event (list title (cons "" items)))))
((or widget-menu-minibuffer-flag
(> (length items) widget-menu-max-shortcuts))
(when (keymapp items)
(setq items (widget--simplify-menu items)))
;; Read the choice of name from the minibuffer.
(setq items (cl-remove-if 'stringp items))
(let ((val (completing-read (concat title ": ") items nil t)))
(if (stringp val)
(let ((try (try-completion val items)))
(when (stringp try)
(setq val try))
(cdr (assoc val items))))))
(t
(when (keymapp items)
(setq items (widget--simplify-menu items)))
;; Construct a menu of the choices
;; and then use it for prompting for a single character.
(let* ((next-digit ?0)
alist choice some-choice-enabled value)
(with-current-buffer (get-buffer-create " widget-choose")
(erase-buffer)
(insert "Available choices:\n\n")
(while items
(setq choice (pop items))
(when (consp choice)
(let* ((name (substitute-command-keys (car choice)))
(function (cdr choice)))
(insert (format "%c = %s\n" next-digit name))
(push (cons next-digit function) alist)
(setq some-choice-enabled t)))
;; Allocate digits to disabled alternatives
;; so that the digit of a given alternative never varies.
(setq next-digit (1+ next-digit)))
(insert "\nC-g = Quit")
(goto-char (point-min))
(forward-line))
(or some-choice-enabled
(error "None of the choices is currently meaningful"))
(save-window-excursion
;; Select window to be able to scroll it from minibuffer
(with-selected-window
(display-buffer (get-buffer " widget-choose")
'(display-buffer-in-direction
(direction . bottom)
(window-height . fit-window-to-buffer)))
(setq value (read-char-choice
(format "%s: " title)
(mapcar #'car alist)))))
(cdr (assoc value alist))))))
;; Apply quote substitution to customize choice menu item text,
;; whether it occurs in a widget buffer or in a popup menu.
(let ((items (mapc (lambda (x)
(when (consp x)
(dotimes (i (1- (length x)))
(when (char-or-string-p (nth i x))
(setcar (nthcdr i x)
(substitute-command-keys
(car (nthcdr i x))))))))
items)))
(cond ((and (< (length items) widget-menu-max-size)
event (display-popup-menus-p))
;; Mouse click.
(if (keymapp items)
;; Modify the keymap prompt, and then restore the old one, if any.
(let ((prompt (keymap-prompt items)))
(unwind-protect
(progn
(setq items (delete prompt items))
(push title (cdr items))
;; Return just the first element of the list of events.
(car (x-popup-menu event items)))
(setq items (delete title items))
(when prompt
(push prompt (cdr items)))))
(x-popup-menu event (list title (cons "" items)))))
((or widget-menu-minibuffer-flag
(> (length items) widget-menu-max-shortcuts))
(when (keymapp items)
(setq items (widget--simplify-menu items)))
;; Read the choice of name from the minibuffer.
(setq items (cl-remove-if 'stringp items))
(let ((val (completing-read (concat title ": ") items nil t)))
(if (stringp val)
(let ((try (try-completion val items)))
(when (stringp try)
(setq val try))
(cdr (assoc val items))))))
(t
(when (keymapp items)
(setq items (widget--simplify-menu items)))
;; Construct a menu of the choices
;; and then use it for prompting for a single character.
(let ((next-digit ?0)
alist choice some-choice-enabled value)
(with-current-buffer (get-buffer-create " widget-choose")
(erase-buffer)
(insert "Available choices:\n\n")
(while items
(setq choice (pop items))
(when (consp choice)
(insert (format "%c = %s\n" next-digit (car choice)))
(push (cons next-digit (cdr choice)) alist)
(setq some-choice-enabled t))
;; Allocate digits to disabled alternatives
;; so that the digit of a given alternative never varies.
(setq next-digit (1+ next-digit)))
(insert "\nC-g = Quit")
(goto-char (point-min))
(forward-line))
(or some-choice-enabled
(error "None of the choices is currently meaningful"))
(save-window-excursion
;; Select window to be able to scroll it from minibuffer
(with-selected-window
(display-buffer (get-buffer " widget-choose")
'(display-buffer-in-direction
(direction . bottom)
(window-height . fit-window-to-buffer)))
(setq value (read-char-choice
(format "%s: " title)
(mapcar #'car alist)))))
(cdr (assoc value alist)))))))
;;; Widget text specifications.
;;

View file

@ -933,6 +933,11 @@ elnlisp := $(addprefix ${lispsource}/,${elnlisp}) $(lisp:.elc=.eln)
## native-lisp where the *.eln files will be produced, and the exact
## names of those *.eln files, cannot be known in advance; we must ask
## Emacs to produce them.
## If AOT native compilation is requested, we additionally
## native-compile all the *.el files in ../lisp that need to be
## compiled and haven't yet been compiled. ELDONE holds the list
## of *.el files that were already native-compiled.
NATIVE_COMPILATION_AOT = @NATIVE_COMPILATION_AOT@
../native-lisp: | $(pdmp)
@if test ! -d $@; then \
mkdir $@ && $(MAKE) $(AM_V_NO_PD) $(elnlisp); \
@ -943,6 +948,9 @@ elnlisp := $(addprefix ${lispsource}/,${elnlisp}) $(lisp:.elc=.eln)
--bin-dest $(BIN_DESTDIR) --eln-dest $(ELN_DESTDIR) \
&& cp -f emacs$(EXEEXT) bootstrap-emacs$(EXEEXT) \
&& cp -f $(pdmp) $(bootstrap_pdmp); \
if test $(NATIVE_COMPILATION_AOT) = yes; then \
$(MAKE) $(AM_V_NO_PD) -C ../lisp compile-eln-aot EMACS="../src/emacs$(EXEEXT)" ELNDONE="$(addprefix %,$(notdir $(elnlisp))))"; \
fi; \
fi
endif

View file

@ -4602,6 +4602,8 @@ by calling `format-decode', which see. */)
if (unprocessed > 0)
{
BUF_TEMP_SET_PT (XBUFFER (conversion_buffer),
BUF_Z (XBUFFER (conversion_buffer)));
coding.mode |= CODING_MODE_LAST_BLOCK;
decode_coding_c_string (&coding, (unsigned char *) read_buf,
unprocessed, conversion_buffer);

View file

@ -1464,6 +1464,10 @@ affects all frames on the same terminal device. */)
If FRAME is a switch-frame event `(switch-frame FRAME1)', use
FRAME1 as frame.
If TRACK is non-zero and the frame that currently has the focus
redirects its focus to the selected frame, redirect that focused
frame's focus to FRAME instead.
FOR_DELETION non-zero means that the selected frame is being
deleted, which includes the possibility that the frame's terminal
is dead.
@ -1471,7 +1475,7 @@ affects all frames on the same terminal device. */)
The value of NORECORD is passed as argument to Fselect_window. */
Lisp_Object
do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
do_switch_frame (Lisp_Object frame, int track, int for_deletion, Lisp_Object norecord)
{
struct frame *sf = SELECTED_FRAME (), *f;
@ -1493,6 +1497,44 @@ do_switch_frame (Lisp_Object frame, int for_deletion, Lisp_Object norecord)
else if (f == sf)
return frame;
/* If the frame with GUI focus has had it's Emacs focus redirected
toward the currently selected frame, we should change the
redirection to point to the newly selected frame. This means
that if the focus is redirected from a minibufferless frame to a
surrogate minibuffer frame, we can use `other-window' to switch
between all the frames using that minibuffer frame, and the focus
redirection will follow us around. This code is necessary when
we have a minibufferless frame using the MB in another (normal)
frame (bug#64152) (ACM, 2023-06-20). */
#ifdef HAVE_WINDOW_SYSTEM
if (track && FRAME_WINDOW_P (f) && FRAME_TERMINAL (f)->get_focus_frame)
{
Lisp_Object gfocus; /* The frame which still has focus on the
current terminal, according to the GUI
system. */
Lisp_Object focus; /* The frame to which Emacs has redirected
the focus from `gfocus'. This might be a
frame with a minibuffer when `gfocus'
doesn't have a MB. */
gfocus = FRAME_TERMINAL (f)->get_focus_frame (f);
if (FRAMEP (gfocus))
{
focus = FRAME_FOCUS_FRAME (XFRAME (gfocus));
if (FRAMEP (focus) && XFRAME (focus) == SELECTED_FRAME ())
/* Redirect frame focus also when FRAME has its minibuffer
window on the selected frame (see Bug#24500).
Don't do that: It causes redirection problem with a
separate minibuffer frame (Bug#24803) and problems
when updating the cursor on such frames.
|| (NILP (focus)
&& EQ (FRAME_MINIBUF_WINDOW (f), sf->selected_window))) */
Fredirect_frame_focus (gfocus, frame);
}
}
#endif /* HAVE_X_WINDOWS */
if (!for_deletion && FRAME_HAS_MINIBUF_P (sf))
resize_mini_window (XWINDOW (FRAME_MINIBUF_WINDOW (sf)), 1);
@ -1594,7 +1636,7 @@ This function returns FRAME, or nil if FRAME has been deleted. */)
/* Do not select a tooltip frame (Bug#47207). */
error ("Cannot select a tooltip frame");
else
return do_switch_frame (frame, 0, norecord);
return do_switch_frame (frame, 1, 0, norecord);
}
DEFUN ("handle-switch-frame", Fhandle_switch_frame,
@ -1610,7 +1652,7 @@ necessarily represent user-visible input focus. */)
kset_prefix_arg (current_kboard, Vcurrent_prefix_arg);
run_hook (Qmouse_leave_buffer_hook);
return do_switch_frame (event, 0, Qnil);
return do_switch_frame (event, 0, 0, Qnil);
}
DEFUN ("selected-frame", Fselected_frame, Sselected_frame, 0, 0, 0,
@ -2177,7 +2219,7 @@ delete_frame (Lisp_Object frame, Lisp_Object force)
Fraise_frame (frame1);
#endif
do_switch_frame (frame1, 1, Qnil);
do_switch_frame (frame1, 0, 1, Qnil);
sf = SELECTED_FRAME ();
}
else

View file

@ -11882,7 +11882,7 @@ quit_throw_to_read_char (bool from_signal)
if (FRAMEP (internal_last_event_frame)
&& !EQ (internal_last_event_frame, selected_frame))
do_switch_frame (make_lispy_switch_frame (internal_last_event_frame),
0, Qnil);
0, 0, Qnil);
sys_longjmp (getcjmp, 1);
}

View file

@ -4888,7 +4888,7 @@ extern void syms_of_indent (void);
/* Defined in frame.c. */
extern void store_frame_param (struct frame *, Lisp_Object, Lisp_Object);
extern void store_in_alist (Lisp_Object *, Lisp_Object, Lisp_Object);
extern Lisp_Object do_switch_frame (Lisp_Object, int, Lisp_Object);
extern Lisp_Object do_switch_frame (Lisp_Object, int, int, Lisp_Object);
extern Lisp_Object get_frame_param (struct frame *, Lisp_Object);
extern void frames_discard_buffer (Lisp_Object);
extern void init_frame_once (void);

View file

@ -1125,8 +1125,8 @@ read_minibuf_unwind (void)
found:
if (!EQ (exp_MB_frame, saved_selected_frame)
&& !NILP (exp_MB_frame))
do_switch_frame (exp_MB_frame, 0, Qt); /* This also sets
minibuf_window */
do_switch_frame (exp_MB_frame, 0, 0, Qt); /* This also sets
minibuf_window */
/* To keep things predictable, in case it matters, let's be in the
minibuffer when we reset the relevant variables. Don't depend on
@ -1238,7 +1238,7 @@ read_minibuf_unwind (void)
/* Restore the selected frame. */
if (!EQ (exp_MB_frame, saved_selected_frame)
&& !NILP (exp_MB_frame))
do_switch_frame (saved_selected_frame, 0, Qt);
do_switch_frame (saved_selected_frame, 0, 0, Qt);
}
/* Replace the expired minibuffer in frame exp_MB_frame with the next less

View file

@ -7416,7 +7416,7 @@ the return value is nil. Otherwise the value is t. */)
do_switch_frame (NILP (dont_set_frame)
? data->selected_frame
: old_frame
, 0, Qnil);
, 0, 0, Qnil);
}
FRAME_WINDOW_CHANGE (f) = true;

View file

@ -26181,7 +26181,7 @@ x_try_restore_frame (void)
FOR_EACH_FRAME (tail, frame)
{
if (!NILP (do_switch_frame (frame, 1, Qnil)))
if (!NILP (do_switch_frame (frame, 0, 1, Qnil)))
return;
}
}

View file

@ -683,7 +683,7 @@ def long_function_name(
(should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "var_four):")
(should (eq (car (python-indent-context))
:inside-paren-newline-start-from-block))
:inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "print (var_one)")
(should (eq (car (python-indent-context))
@ -707,8 +707,8 @@ foo = long_function_name(
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "var_three, var_four)")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 2))))
(ert-deftest python-indent-hanging-close-paren ()
"Like first pep8 case, but with hanging close paren." ;; See Bug#20742.
@ -864,7 +864,7 @@ data = {
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "{")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 4))
(python-tests-look-at "'objlist': [")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
@ -876,20 +876,20 @@ data = {
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "'name': 'first',")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "},")
(should (eq (car (python-indent-context))
:inside-paren-at-closing-nested-paren))
(should (= (python-indent-calculate-indentation) 12))
(python-tests-look-at "{")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 12))
(python-tests-look-at "'pk': 2,")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "'name': 'second',")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 16))
(python-tests-look-at "}")
(should (eq (car (python-indent-context))
@ -933,7 +933,7 @@ data = {'key': {
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 9))
(python-tests-look-at "{'pk': 2,")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))
(python-tests-look-at "'name': 'second'}")
(should (eq (car (python-indent-context)) :inside-paren))
@ -966,10 +966,10 @@ data = ('these',
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 8))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))))
(ert-deftest python-indent-inside-paren-4 ()
@ -1023,7 +1023,7 @@ CHOICES = (('some', 'choice'),
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 11))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 11))))
(ert-deftest python-indent-inside-paren-7 ()
@ -1034,6 +1034,71 @@ CHOICES = (('some', 'choice'),
;; This signals an error if the test fails
(should (eq (car (python-indent-context)) :inside-paren-newline-start))))
(ert-deftest python-indent-inside-paren-8 ()
"Test for Bug#63959."
(python-tests-with-temp-buffer
"
for a in [ # comment
'some', # Manually indented.
'thing']: # Respect indentation of the previous line.
"
(python-tests-look-at "for a in [ # comment")
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(forward-line 1)
(should (eq (car (python-indent-context))
:inside-paren-newline-start-from-block))
(should (= (python-indent-calculate-indentation) 8))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 10))))
(ert-deftest python-indent-inside-paren-9 ()
"Test `:inside-paren-continuation-line'."
(python-tests-with-temp-buffer
"
a = (((
1, 2),
3), # Do not respect the indentation of the previous line
4) # Do not respect the indentation of the previous line
b = ((
1, 2), # Manually indented
3, # Do not respect the indentation of the previous line
4, # Respect the indentation of the previous line
5, # Manually indented
6) # Respect the indentation of the previous line
"
(python-tests-look-at "a = (((")
(should (eq (car (python-indent-context)) :no-indent))
(should (= (python-indent-calculate-indentation) 0))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 6))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :after-line))
(should (= (python-indent-calculate-indentation) 0))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 4))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 5))
(forward-line 1)
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 8))))
(ert-deftest python-indent-inside-paren-block-1 ()
"`python-indent-block-paren-deeper' set to nil (default).
See Bug#62696."
@ -1271,7 +1336,7 @@ objects = Thing.objects.all() \\
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (= (python-indent-calculate-indentation) 27))
(python-tests-look-at "status='bought'")
(should (eq (car (python-indent-context)) :inside-paren-newline-start))
(should (eq (car (python-indent-context)) :inside-paren-continuation-line))
(should (= (python-indent-calculate-indentation) 27))
(python-tests-look-at ") \\")
(should (eq (car (python-indent-context)) :inside-paren-at-closing-paren))