diff --git a/admin/git-bisect-start b/admin/git-bisect-start index 65bfffc0ad6..511111c7f65 100755 --- a/admin/git-bisect-start +++ b/admin/git-bisect-start @@ -82,7 +82,7 @@ done # SKIP-BRANCH 58cc931e92ece70c3e64131ee12a799d65409100 ## The list below is the exhaustive list of all commits between Dec 1 -## 2016 and Jan 31 2023 on which building Emacs with the default +## 2016 and Feb 28 2023 on which building Emacs with the default ## options, on a GNU/Linux computer and with GCC, fails. It is ## possible (though unlikely) that building Emacs with non-default ## options, with other compilers, or on other platforms, would succeed @@ -1707,3 +1707,16 @@ $REAL_GIT bisect skip $(cat $0 | grep '^# SKIP-SINGLE ' | sed 's/^# SKIP-SINGLE # SKIP-SINGLE 1c3ca3bb649b7e812a84b4a559463462d4357080 # SKIP-SINGLE 48ed4228a75907ae1bb7a2d4314ffb3277c75e3a # SKIP-SINGLE b9025c507a3a7dae4de19b18cafaa09b18183832 +# SKIP-SINGLE 8d8464bd5a98598e7a6fe63370545c7f07574926 +# SKIP-SINGLE 11c4177430230ef41cb700c48afecf475cf39893 +# SKIP-SINGLE cf3c89423fabc2c5a7891a5b5465fa995e461218 +# SKIP-SINGLE 8d5d7509b0a2c248084fa349b0b188d4de4af804 +# SKIP-SINGLE b6e2799aa1c3887c2995e115e6ff2f69d59f0e44 +# SKIP-SINGLE 1795839babcf8572a79aaee3c76ca5b357937a59 +# SKIP-SINGLE abfd00e5c02ec0aed8bbac1eca0d0db1874f020a +# SKIP-SINGLE 8aef401b4f66a64ddfa9390590fb2cae1f96d522 +# SKIP-SINGLE d5bf26f488b7968feed9f43e612a90da2aab15a8 +# SKIP-SINGLE 5d0912f1445e33f1ccf23a84f0dc6d08c4ee2b60 +# SKIP-SINGLE 95692f6754c3a8f55a90df2d6f7ce62be55cdcfc +# SKIP-SINGLE a3edacd3f547195740304139cb68aaa94d7b18ee +# SKIP-SINGLE ae4ff4f25fbf704446f8f38d8e818f223b79042b diff --git a/admin/notes/tree-sitter/build-module/README b/admin/notes/tree-sitter/build-module/README deleted file mode 100644 index 2fcb9778dae..00000000000 --- a/admin/notes/tree-sitter/build-module/README +++ /dev/null @@ -1,17 +0,0 @@ -To build the language definition for a particular language, run - - ./build.sh - -eg, - - ./build.sh html - -The dynamic module will be in /dist directory - -To build all modules at once, run - - ./batch.sh - -This gives you C, JSON, Go, HTML, Javascript, CSS, Python, Typescript -(tsx), C# (csharp), C++ (cpp), Rust. More can be added to batch.sh -unless it's directory structure is not standard. \ No newline at end of file diff --git a/admin/notes/tree-sitter/html-manual/Accessing-Node.html b/admin/notes/tree-sitter/html-manual/Accessing-Node.html deleted file mode 100644 index afbbdaa11b5..00000000000 --- a/admin/notes/tree-sitter/html-manual/Accessing-Node.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - -Accessing Node (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - - -
- -
-

37.4 Accessing Node Information

- -

Before going further, make sure you have read the basic conventions -about tree-sitter nodes in the previous node. -

-

Basic information

- -

Every node is associated with a parser, and that parser is associated -with a buffer. The following functions let you retrieve them. -

-
-
Function: treesit-node-parser node
-

This function returns node’s associated parser. -

- -
-
Function: treesit-node-buffer node
-

This function returns node’s parser’s associated buffer. -

- -
-
Function: treesit-node-language node
-

This function returns node’s parser’s associated language. -

- -

Each node represents a piece of text in the buffer. Functions below -finds relevant information about that text. -

-
-
Function: treesit-node-start node
-

Return the start position of node. -

- -
-
Function: treesit-node-end node
-

Return the end position of node. -

- -
-
Function: treesit-node-text node &optional object
-

Returns the buffer text that node represents. (If node is -retrieved from parsing a string, it will be text from that string.) -

- -

Here are some basic checks on tree-sitter nodes. -

-
-
Function: treesit-node-p object
-

Checks if object is a tree-sitter syntax node. -

- -
-
Function: treesit-node-eq node1 node2
-

Checks if node1 and node2 are the same node in a syntax -tree. -

- -

Property information

- -

In general, nodes in a concrete syntax tree fall into two categories: -named nodes and anonymous nodes. Whether a node is named -or anonymous is determined by the language definition -(see named node). -

- -

Apart from being named/anonymous, a node can have other properties. A -node can be “missing”: missing nodes are inserted by the parser in -order to recover from certain kinds of syntax errors, i.e., something -should probably be there according to the grammar, but not there. -

- -

A node can be “extra”: extra nodes represent things like comments, -which can appear anywhere in the text. -

- -

A node “has changes” if the buffer changed since when the node is -retrieved, i.e., outdated. -

- -

A node “has error” if the text it spans contains a syntax error. It -can be the node itself has an error, or one of its -children/grandchildren... has an error. -

-
-
Function: treesit-node-check node property
-

This function checks if node has property. property -can be 'named, 'missing, 'extra, -'has-changes, or 'has-error. -

- - -
-
Function: treesit-node-type node
-

Named nodes have “types” (see node type). -For example, a named node can be a string_literal node, where -string_literal is its type. -

-

This function returns node’s type as a string. -

- -

Information as a child or parent

- -
-
Function: treesit-node-index node &optional named
-

This function returns the index of node as a child node of its -parent. If named is non-nil, it only count named nodes -(see named node). -

- -
-
Function: treesit-node-field-name node
-

A child of a parent node could have a field name (see field name). This function returns the field name -of node as a child of its parent. -

- -
-
Function: treesit-node-field-name-for-child node n
-

This function returns the field name of the n’th child of -node. -

- -
-
Function: treesit-node-child-count node &optional named
-

This function finds the number of children of node. If -named is non-nil, it only counts named child (see named node). -

- -
-
-
-

-Next: Pattern Matching Tree-sitter Nodes, Previous: Retrieving Node, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Language-Definitions.html b/admin/notes/tree-sitter/html-manual/Language-Definitions.html deleted file mode 100644 index 9b1e0021272..00000000000 --- a/admin/notes/tree-sitter/html-manual/Language-Definitions.html +++ /dev/null @@ -1,401 +0,0 @@ - - - - - - -Language Definitions (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - -
- -
-

37.1 Tree-sitter Language Definitions

- - -

Loading a language definition

- - - -

Tree-sitter relies on language definitions to parse text in that -language. In Emacs, a language definition is represented by a symbol. -For example, the C language definition is represented as the symbol -c, and c can be passed to tree-sitter functions as the -language argument. -

- - - -

Tree-sitter language definitions are distributed as dynamic libraries. -In order to use a language definition in Emacs, you need to make sure -that the dynamic library is installed on the system. Emacs looks for -language definitions in several places, in the following order: -

- - -

In each of these directories, Emacs looks for a file with file-name -extensions specified by the variable dynamic-library-suffixes. -

-

If Emacs cannot find the library or has problems loading it, Emacs -signals the treesit-load-language-error error. The data of -that signal could be one of the following: -

-
-
(not-found error-msg …)
-

This means that Emacs could not find the language definition library. -

-
(symbol-error error-msg)
-

This means that Emacs could not find in the library the expected function -that every language definition library should export. -

-
(version-mismatch error-msg)
-

This means that the version of language definition library is incompatible -with that of the tree-sitter library. -

-
- -

In all of these cases, error-msg might provide additional -details about the failure. -

-
-
Function: treesit-language-available-p language &optional detail
-

This function returns non-nil if the language definitions for -language exist and can be loaded. -

-

If detail is non-nil, return (t . nil) when -language is available, and (nil . data) when it’s -unavailable. data is the signal data of -treesit-load-language-error. -

- - -

By convention, the file name of the dynamic library for language is -libtree-sitter-language.ext, where ext is the -system-specific extension for dynamic libraries. Also by convention, -the function provided by that library is named -tree_sitter_language. If a language definition library -doesn’t follow this convention, you should add an entry -

-
-
(language library-base-name function-name)
-
- -

to the list in the variable treesit-load-name-override-list, where -library-base-name is the basename of the dynamic library’s file name, -(usually, libtree-sitter-language), and -function-name is the function provided by the library -(usually, tree_sitter_language). For example, -

-
-
(cool-lang "libtree-sitter-coool" "tree_sitter_cooool")
-
- -

for a language that considers itself too “cool” to abide by -conventions. -

- -
-
Function: treesit-language-version &optional min-compatible
-

This function returns the version of the language-definition -Application Binary Interface (ABI) supported by the -tree-sitter library. By default, it returns the latest ABI version -supported by the library, but if min-compatible is -non-nil, it returns the oldest ABI version which the library -still can support. Language definition libraries must be built for -ABI versions between the oldest and the latest versions supported by -the tree-sitter library, otherwise the library will be unable to load -them. -

- -

Concrete syntax tree

- - -

A syntax tree is what a parser generates. In a syntax tree, each node -represents a piece of text, and is connected to each other by a -parent-child relationship. For example, if the source text is -

-
-
1 + 2
-
- -

its syntax tree could be -

-
-
                  +--------------+
-                  | root "1 + 2" |
-                  +--------------+
-                         |
-        +--------------------------------+
-        |       expression "1 + 2"       |
-        +--------------------------------+
-           |             |            |
-+------------+   +--------------+   +------------+
-| number "1" |   | operator "+" |   | number "2" |
-+------------+   +--------------+   +------------+
-
- -

We can also represent it as an s-expression: -

-
-
(root (expression (number) (operator) (number)))
-
- -

Node types

- - - - - -

Names like root, expression, number, and -operator specify the type of the nodes. However, not all -nodes in a syntax tree have a type. Nodes that don’t have a type are -known as anonymous nodes, and nodes with a type are named -nodes. Anonymous nodes are tokens with fixed spellings, including -punctuation characters like bracket ‘]’, and keywords like -return. -

-

Field names

- - - -

To make the syntax tree easier to analyze, many language definitions -assign field names to child nodes. For example, a -function_definition node could have a declarator and a -body: -

-
-
(function_definition
- declarator: (declaration)
- body: (compound_statement))
-
- -

Exploring the syntax tree

- - - -

To aid in understanding the syntax of a language and in debugging of -Lisp program that use the syntax tree, Emacs provides an “explore” -mode, which displays the syntax tree of the source in the current -buffer in real time. Emacs also comes with an “inspect mode”, which -displays information of the nodes at point in the mode-line. -

-
-
Command: treesit-explore-mode
-

This mode pops up a window displaying the syntax tree of the source in -the current buffer. Selecting text in the source buffer highlights -the corresponding nodes in the syntax tree display. Clicking -on nodes in the syntax tree highlights the corresponding text in the -source buffer. -

- -
-
Command: treesit-inspect-mode
-

This minor mode displays on the mode-line the node that starts -at point. For example, the mode-line can display -

-
-
parent field: (node (child (…)))
-
- -

where node, child, etc., are nodes which begin at point. -parent is the parent of node. node is displayed in -a bold typeface. field-names are field names of node and -of child, etc. -

-

If no node starts at point, i.e., point is in the middle of a node, -then the mode line displays the earliest node that spans point, and -its immediate parent. -

-

This minor mode doesn’t create parsers on its own. It uses the first -parser in (treesit-parser-list) (see Using Tree-sitter Parser). -

- -

Reading the grammar definition

- - -

Authors of language definitions define the grammar of a -programming language, which determines how a parser constructs a -concrete syntax tree out of the program text. In order to use the -syntax tree effectively, you need to consult the grammar file. -

-

The grammar file is usually grammar.js in a language -definition’s project repository. The link to a language definition’s -home page can be found on -tree-sitter’s -homepage. -

-

The grammar definition is written in JavaScript. For example, the -rule matching a function_definition node looks like -

-
-
function_definition: $ => seq(
-  $.declaration_specifiers,
-  field('declarator', $.declaration),
-  field('body', $.compound_statement)
-)
-
- -

The rules are represented by functions that take a single argument -$, representing the whole grammar. The function itself is -constructed by other functions: the seq function puts together -a sequence of children; the field function annotates a child -with a field name. If we write the above definition in the so-called -Backus-Naur Form (BNF) syntax, it would look like -

-
-
function_definition :=
-  <declaration_specifiers> <declaration> <compound_statement>
-
- -

and the node returned by the parser would look like -

-
-
(function_definition
-  (declaration_specifier)
-  declarator: (declaration)
-  body: (compound_statement))
-
- -

Below is a list of functions that one can see in a grammar definition. -Each function takes other rules as arguments and returns a new rule. -

-
-
seq(rule1, rule2, …)
-

matches each rule one after another. -

-
choice(rule1, rule2, …)
-

matches one of the rules in its arguments. -

-
repeat(rule)
-

matches rule for zero or more times. -This is like the ‘*’ operator in regular expressions. -

-
repeat1(rule)
-

matches rule for one or more times. -This is like the ‘+’ operator in regular expressions. -

-
optional(rule)
-

matches rule for zero or one time. -This is like the ‘?’ operator in regular expressions. -

-
field(name, rule)
-

assigns field name name to the child node matched by rule. -

-
alias(rule, alias)
-

makes nodes matched by rule appear as alias in the syntax -tree generated by the parser. For example, -

-
-
alias(preprocessor_call_exp, call_expression)
-
- -

makes any node matched by preprocessor_call_exp appear as -call_expression. -

-
- -

Below are grammar functions of lesser importance for reading a -language definition. -

-
-
token(rule)
-

marks rule to produce a single leaf node. That is, instead of -generating a parent node with individual child nodes under it, -everything is combined into a single leaf node. See Retrieving Nodes. -

-
token.immediate(rule)
-

Normally, grammar rules ignore preceding whitespace; this -changes rule to match only when there is no preceding -whitespaces. -

-
prec(n, rule)
-

gives rule the level-n precedence. -

-
prec.left([n,] rule)
-

marks rule as left-associative, optionally with level n. -

-
prec.right([n,] rule)
-

marks rule as right-associative, optionally with level n. -

-
prec.dynamic(n, rule)
-

this is like prec, but the precedence is applied at runtime -instead. -

-
- -

The documentation of the tree-sitter project has -more -about writing a grammar. Read especially “The Grammar DSL” -section. -

-
-
-
-

-Next: Using Tree-sitter Parser, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Multiple-Languages.html b/admin/notes/tree-sitter/html-manual/Multiple-Languages.html deleted file mode 100644 index 390d9082590..00000000000 --- a/admin/notes/tree-sitter/html-manual/Multiple-Languages.html +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - -Multiple Languages (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - - -
- -
-

37.6 Parsing Text in Multiple Languages

- - -

Sometimes, the source of a programming language could contain snippets -of other languages; HTML + CSS + JavaScript is one -example. In that case, text segments written in different languages -need to be assigned different parsers. Traditionally, this is -achieved by using narrowing. While tree-sitter works with narrowing -(see narrowing), the recommended way is -instead to set regions of buffer text (i.e., ranges) in which a parser -will operate. This section describes functions for setting and -getting ranges for a parser. -

-

Lisp programs should call treesit-update-ranges to make sure -the ranges for each parser are correct before using parsers in a -buffer, and call treesit-language-at to figure out the language -responsible for the text at some position. These two functions don’t -work by themselves, they need major modes to set -treesit-range-settings and -treesit-language-at-point-function, which do the actual work. -These functions and variables are explained in more detail towards the -end of the section. -

-

Getting and setting ranges

- -
-
Function: treesit-parser-set-included-ranges parser ranges
-

This function sets up parser to operate on ranges. The -parser will only read the text of the specified ranges. Each -range in ranges is a list of the form (beg . end). -

-

The ranges in ranges must come in order and must not overlap. -That is, in pseudo code: -

-
-
(cl-loop for idx from 1 to (1- (length ranges))
-         for prev = (nth (1- idx) ranges)
-         for next = (nth idx ranges)
-         should (<= (car prev) (cdr prev)
-                    (car next) (cdr next)))
-
- - -

If ranges violates this constraint, or something else went -wrong, this function signals the treesit-range-invalid error. -The signal data contains a specific error message and the ranges we -are trying to set. -

-

This function can also be used for disabling ranges. If ranges -is nil, the parser is set to parse the whole buffer. -

-

Example: -

-
-
(treesit-parser-set-included-ranges
- parser '((1 . 9) (16 . 24) (24 . 25)))
-
-
- -
-
Function: treesit-parser-included-ranges parser
-

This function returns the ranges set for parser. The return -value is the same as the ranges argument of -treesit-parser-included-ranges: a list of cons cells of the form -(beg . end). If parser doesn’t have any -ranges, the return value is nil. -

-
-
(treesit-parser-included-ranges parser)
-    ⇒ ((1 . 9) (16 . 24) (24 . 25))
-
-
- -
-
Function: treesit-query-range source query &optional beg end
-

This function matches source with query and returns the -ranges of captured nodes. The return value is a list of cons cells of -the form (beg . end), where beg and -end specify the beginning and the end of a region of text. -

-

For convenience, source can be a language symbol, a parser, or a -node. If it’s a language symbol, this function matches in the root -node of the first parser using that language; if a parser, this -function matches in the root node of that parser; if a node, this -function matches in that node. -

-

The argument query is the query used to capture nodes -(see Pattern Matching Tree-sitter Nodes). The capture names don’t matter. The -arguments beg and end, if both non-nil, limit the -range in which this function queries. -

-

Like other query functions, this function raises the -treesit-query-error error if query is malformed. -

- -

Supporting multiple languages in Lisp programs

- -

It should suffice for general Lisp programs to call the following two -functions in order to support program sources that mixes multiple -languages. -

-
-
Function: treesit-update-ranges &optional beg end
-

This function updates ranges for parsers in the buffer. It makes sure -the parsers’ ranges are set correctly between beg and end, -according to treesit-range-settings. If omitted, beg -defaults to the beginning of the buffer, and end defaults to the -end of the buffer. -

-

For example, fontification functions use this function before querying -for nodes in a region. -

- -
-
Function: treesit-language-at pos
-

This function returns the language of the text at buffer position -pos. Under the hood it calls -treesit-language-at-point-function and returns its return -value. If treesit-language-at-point-function is nil, -this function returns the language of the first parser in the returned -value of treesit-parser-list. If there is no parser in the -buffer, it returns nil. -

- -

Supporting multiple languages in major modes

- - - - -

Normally, in a set of languages that can be mixed together, there is a -host language and one or more embedded languages. A Lisp -program usually first parses the whole document with the host -language’s parser, retrieves some information, sets ranges for the -embedded languages with that information, and then parses the embedded -languages. -

-

Take a buffer containing HTML, CSS and JavaScript -as an example. A Lisp program will first parse the whole buffer with -an HTML parser, then query the parser for -style_element and script_element nodes, which -correspond to CSS and JavaScript text, respectively. Then -it sets the range of the CSS and JavaScript parser to the -ranges in which their corresponding nodes span. -

-

Given a simple HTML document: -

-
-
<html>
-  <script>1 + 2</script>
-  <style>body { color: "blue"; }</style>
-</html>
-
- -

a Lisp program will first parse with a HTML parser, then set -ranges for CSS and JavaScript parsers: -

-
-
;; Create parsers.
-(setq html (treesit-parser-create 'html))
-(setq css (treesit-parser-create 'css))
-(setq js (treesit-parser-create 'javascript))
-
-
-
;; Set CSS ranges.
-(setq css-range
-      (treesit-query-range
-       'html
-       "(style_element (raw_text) @capture)"))
-(treesit-parser-set-included-ranges css css-range)
-
-
-
;; Set JavaScript ranges.
-(setq js-range
-      (treesit-query-range
-       'html
-       "(script_element (raw_text) @capture)"))
-(treesit-parser-set-included-ranges js js-range)
-
- -

Emacs automates this process in treesit-update-ranges. A -multi-language major mode should set treesit-range-settings so -that treesit-update-ranges knows how to perform this process -automatically. Major modes should use the helper function -treesit-range-rules to generate a value that can be assigned to -treesit-range-settings. The settings in the following example -directly translate into operations shown above. -

-
-
(setq-local treesit-range-settings
-            (treesit-range-rules
-             :embed 'javascript
-             :host 'html
-             '((script_element (raw_text) @capture))
-
-
-
             :embed 'css
-             :host 'html
-             '((style_element (raw_text) @capture))))
-
- -
-
Function: treesit-range-rules &rest query-specs
-

This function is used to set treesit-range-settings. It -takes care of compiling queries and other post-processing, and outputs -a value that treesit-range-settings can have. -

-

It takes a series of query-specs, where each query-spec is -a query preceded by zero or more keyword/value -pairs. Each query is a tree-sitter query in either the -string, s-expression or compiled form, or a function. -

-

If query is a tree-sitter query, it should be preceded by two -:keyword/value pairs, where the :embed keyword -specifies the embedded language, and the :host keyword -specified the host language. -

-

treesit-update-ranges uses query to figure out how to set -the ranges for parsers for the embedded language. It queries -query in a host language parser, computes the ranges in which -the captured nodes span, and applies these ranges to embedded -language parsers. -

-

If query is a function, it doesn’t need any :keyword and -value pair. It should be a function that takes 2 arguments, -start and end, and sets the ranges for parsers in the -current buffer in the region between start and end. It is -fine for this function to set ranges in a larger region that -encompasses the region between start and end. -

- -
-
Variable: treesit-range-settings
-

This variable helps treesit-update-ranges in updating the -ranges for parsers in the buffer. It is a list of settings -where the exact format of a setting is considered internal. You -should use treesit-range-rules to generate a value that this -variable can have. -

-
- - -
-
Variable: treesit-language-at-point-function
-

This variable’s value should be a function that takes a single -argument, pos, which is a buffer position, and returns the -language of the buffer text at pos. This variable is used by -treesit-language-at. -

- -
-
-
-

-Next: Developing major modes with tree-sitter, Previous: Pattern Matching Tree-sitter Nodes, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html b/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html deleted file mode 100644 index a3fe6622162..00000000000 --- a/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - - - -Parser-based Font Lock (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - -
- -
-

24.6.10 Parser-based Font Lock

- - - -

Besides simple syntactic font lock and regexp-based font lock, Emacs -also provides complete syntactic font lock with the help of a parser. -Currently, Emacs uses the tree-sitter library (see Parsing Program Source) for this purpose. -

-

Parser-based font lock and other font lock mechanisms are not mutually -exclusive. By default, if enabled, parser-based font lock runs first, -replacing syntactic font lock, then the regexp-based font lock. -

-

Although parser-based font lock doesn’t share the same customization -variables with regexp-based font lock, it uses similar customization -schemes. The tree-sitter counterpart of font-lock-keywords is -treesit-font-lock-settings. -

- - -

In general, tree-sitter fontification works as follows: -

- - -

For more information about queries, patterns, and capture names, see -Pattern Matching Tree-sitter Nodes. -

-

To setup tree-sitter fontification, a major mode should first set -treesit-font-lock-settings with the output of -treesit-font-lock-rules, then call -treesit-major-mode-setup. -

-
-
Function: treesit-font-lock-rules &rest query-specs
-

This function is used to set treesit-font-lock-settings. It -takes care of compiling queries and other post-processing, and outputs -a value that treesit-font-lock-settings accepts. Here’s an -example: -

-
-
(treesit-font-lock-rules
- :language 'javascript
- :feature 'constant
- :override t
- '((true) @font-lock-constant-face
-   (false) @font-lock-constant-face)
- :language 'html
- :feature 'script
- "(script_element) @font-lock-builtin-face")
-
- -

This function takes a series of query-specs, where each -query-spec is a query preceded by one or more -:keyword/value pairs. Each query is a -tree-sitter query in either the string, s-expression or compiled form. -

-

For each query, the :keyword/value pairs that -precede it add meta information to it. The :language keyword -declares query’s language. The :feature keyword sets the -feature name of query. Users can control which features are -enabled with font-lock-maximum-decoration and -treesit-font-lock-feature-list (described below). These two -keywords are mandatory. -

-

Other keywords are optional: -

- - - - - - - -
KeywordValueDescription
:overridenilIf the region already has a face, discard the new face
tAlways apply the new face
appendAppend the new face to existing ones
prependPrepend the new face to existing ones
keepFill-in regions without an existing face
- -

Lisp programs mark patterns in query with capture names (names -that starts with @), and tree-sitter will return matched nodes -tagged with those same capture names. For the purpose of -fontification, capture names in query should be face names like -font-lock-keyword-face. The captured node will be fontified -with that face. -

- -

Capture names can also be function names, in which case the function -is called with 4 arguments: node and override, start -and end, where node is the node itself, override is -the override property of the rule which captured this node, and -start and end limits the region in which this function -should fontify. (If this function wants to respect the override -argument, it can use treesit-fontify-with-override.) -

-

Beyond the 4 arguments presented, this function should accept more -arguments as optional arguments for future extensibility. -

-

If a capture name is both a face and a function, the face takes -priority. If a capture name is neither a face nor a function, it is -ignored. -

- -
-
Variable: treesit-font-lock-feature-list
-

This is a list of lists of feature symbols. Each element of the list -is a list that represents a decoration level. -font-lock-maximum-decoration controls which levels are -activated. -

-

Each element of the list is a list of the form (feature …), where each feature corresponds to the -:feature value of a query defined in -treesit-font-lock-rules. Removing a feature symbol from this -list disables the corresponding query during font-lock. -

-

Common feature names, for many programming languages, include -definition, type, assignment, builtin, -constant, keyword, string-interpolation, -comment, doc, string, operator, -preprocessor, escape-sequence, and key. Major -modes are free to subdivide or extend these common features. -

-

Some of these features warrant some explanation: definition -highlights whatever is being defined, e.g., the function name in a -function definition, the struct name in a struct definition, the -variable name in a variable definition; assignment highlights -the whatever is being assigned to, e.g., the variable or field in an -assignment statement; key highlights keys in key-value pairs, -e.g., keys in a JSON object, or a Python dictionary; doc -highlights docstrings or doc-comments. -

-

For example, the value of this variable could be: -

-
((comment string doc) ; level 1
- (function-name keyword type builtin constant) ; level 2
- (variable-name string-interpolation key)) ; level 3
-
- -

Major modes should set this variable before calling -treesit-major-mode-setup. -

- -

For this variable to take effect, a Lisp program should call -treesit-font-lock-recompute-features (which resets -treesit-font-lock-settings accordingly), or -treesit-major-mode-setup (which calls -treesit-font-lock-recompute-features). -

- -
-
Variable: treesit-font-lock-settings
-

A list of settings for tree-sitter based font lock. The exact format -of each setting is considered internal. One should always use -treesit-font-lock-rules to set this variable. -

-
- -

Multi-language major modes should provide range functions in -treesit-range-functions, and Emacs will set the ranges -accordingly before fontifing a region (see Parsing Text in Multiple Languages). -

-
-
-
-

-Previous: Multiline Font Lock Constructs, Up: Font Lock Mode   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Parser_002dbased-Indentation.html b/admin/notes/tree-sitter/html-manual/Parser_002dbased-Indentation.html deleted file mode 100644 index cf1257f3102..00000000000 --- a/admin/notes/tree-sitter/html-manual/Parser_002dbased-Indentation.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - -Parser-based Indentation (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - -
- -
-

24.7.2 Parser-based Indentation

- - - -

When built with the tree-sitter library (see Parsing Program Source), Emacs is capable of parsing the program source and producing -a syntax tree. This syntax tree can be used for guiding the program -source indentation commands. For maximum flexibility, it is possible -to write a custom indentation function that queries the syntax tree -and indents accordingly for each language, but that is a lot of work. -It is more convenient to use the simple indentation engine described -below: then the major mode needs only to write some indentation rules -and the engine takes care of the rest. -

-

To enable the parser-based indentation engine, either set -treesit-simple-indent-rules and call -treesit-major-mode-setup, or equivalently, set the value of -indent-line-function to treesit-indent. -

-
-
Variable: treesit-indent-function
-

This variable stores the actual function called by -treesit-indent. By default, its value is -treesit-simple-indent. In the future we might add other, -more complex indentation engines. -

- -

Writing indentation rules

- - -
-
Variable: treesit-simple-indent-rules
-

This local variable stores indentation rules for every language. It is -a list of the form: (language . rules), where -language is a language symbol, and rules is a list of the -form (matcher anchor offset). -

-

First, Emacs passes the smallest tree-sitter node at the beginning of -the current line to matcher; if it returns non-nil, this -rule is applicable. Then Emacs passes the node to anchor, which -returns a buffer position. Emacs takes the column number of that -position, adds offset to it, and the result is the indentation -column for the current line. offset can be an integer or a -variable whose value is an integer. -

-

The matcher and anchor are functions, and Emacs provides -convenient defaults for them. -

-

Each matcher or anchor is a function that takes three -arguments: node, parent, and bol. The argument -bol is the buffer position whose indentation is required: the -position of the first non-whitespace character after the beginning of -the line. The argument node is the largest (highest-in-tree) -node that starts at that position; and parent is the parent of -node. However, when that position is in a whitespace or inside -a multi-line string, no node can start at that position, so -node is nil. In that case, parent would be the -smallest node that spans that position. -

-

Emacs finds bol, node and parent and -passes them to each matcher and anchor. matcher -should return non-nil if the rule is applicable, and -anchor should return a buffer position. -

- -
-
Variable: treesit-simple-indent-presets
-

This is a list of defaults for matchers and anchors in -treesit-simple-indent-rules. Each of them represents a function -that takes 3 arguments: node, parent and bol. The -available default functions are: -

-
-
no-node
-

This matcher is a function that is called with 3 arguments: -node, parent, and bol, and returns non-nil, -indicating a match, if node is nil, i.e., there is no -node that starts at bol. This is the case when bol is on -an empty line or inside a multi-line string, etc. -

-
-
parent-is
-

This matcher is a function of one argument, type; it returns a -function that is called with 3 arguments: node, parent, -and bol, and returns non-nil (i.e., a match) if -parent’s type matches regexp type. -

-
-
node-is
-

This matcher is a function of one argument, type; it returns a -function that is called with 3 arguments: node, parent, -and bol, and returns non-nil if node’s type matches -regexp type. -

-
-
query
-

This matcher is a function of one argument, query; it returns a -function that is called with 3 arguments: node, parent, -and bol, and returns non-nil if querying parent -with query captures node (see Pattern Matching Tree-sitter Nodes). -

-
-
match
-

This matcher is a function of 5 arguments: node-type, -parent-type, node-field, node-index-min, and -node-index-max). It returns a function that is called with 3 -arguments: node, parent, and bol, and returns -non-nil if node’s type matches regexp node-type, -parent’s type matches regexp parent-type, node’s -field name in parent matches regexp node-field, and -node’s index among its siblings is between node-index-min -and node-index-max. If the value of an argument is nil, -this matcher doesn’t check that argument. For example, to match the -first child where parent is argument_list, use -

-
-
(match nil "argument_list" nil nil 0 0)
-
- -
-
comment-end
-

This matcher is a function that is called with 3 arguments: -node, parent, and bol, and returns non-nil if -point is before a comment ending token. Comment ending tokens are -defined by regular expression treesit-comment-end -(see treesit-comment-end). -

-
-
first-sibling
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the start of the first child -of parent. -

-
-
parent
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the start of parent. -

-
-
parent-bol
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the first non-space character -on the line of parent. -

-
-
prev-sibling
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the start of the previous -sibling of node. -

-
-
no-indent
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the start of node. -

-
-
prev-line
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the first non-whitespace -character on the previous line. -

-
-
point-min
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the beginning of the buffer. -This is useful as the beginning of the buffer is always at column 0. -

-
-
comment-start
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the position right after the -comment-start token. Comment-start tokens are defined by regular -expression treesit-comment-start (see treesit-comment-start). This function assumes parent is -the comment node. -

-
-
comment-start-skip
-

This anchor is a function that is called with 3 arguments: node, -parent, and bol, and returns the position after the -comment-start token and any whitespace characters following that -token. Comment-start tokens are defined by regular expression -treesit-comment-start. This function assumes parent is -the comment node. -

-
-
- -

Indentation utilities

- - -

Here are some utility functions that can help writing parser-based -indentation rules. -

-
-
Function: treesit-check-indent mode
-

This function checks the current buffer’s indentation against major -mode mode. It indents the current buffer according to -mode and compares the results with the current indentation. -Then it pops up a buffer showing the differences. Correct -indentation (target) is shown in green color, current indentation is -shown in red color.

- -

It is also helpful to use treesit-inspect-mode (see Tree-sitter Language Definitions) when writing indentation rules. -

-
-
-
-

-Previous: Simple Minded Indentation Engine, Up: Automatic Indentation of code   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html b/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html deleted file mode 100644 index 58f6b4e9d5a..00000000000 --- a/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - -Parsing Program Source (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - - -
- -
-

37 Parsing Program Source

- - -

Emacs provides various ways to parse program source text and produce a -syntax tree. In a syntax tree, text is no longer considered a -one-dimensional stream of characters, but a structured tree of nodes, -where each node representing a piece of text. Thus, a syntax tree can -enable interesting features like precise fontification, indentation, -navigation, structured editing, etc. -

-

Emacs has a simple facility for parsing balanced expressions -(see Parsing Expressions). There is also the SMIE library for -generic navigation and indentation (see Simple Minded Indentation Engine). -

-

In addition to those, Emacs also provides integration with -the tree-sitter -library) if support for it was compiled in. The tree-sitter library -implements an incremental parser and has support from a wide range of -programming languages. -

-
-
Function: treesit-available-p
-

This function returns non-nil if tree-sitter features are -available for the current Emacs session. -

- -

To be able to parse the program source using the tree-sitter library -and access the syntax tree of the program, a Lisp program needs to -load a language definition library, and create a parser for that -language and the current buffer. After that, the Lisp program can -query the parser about specific nodes of the syntax tree. Then, it -can access various kinds of information about each node, and search -for nodes using a powerful pattern-matching syntax. This chapter -explains how to do all this, and also how a Lisp program can work with -source files that mix multiple programming languages. -

- - -
-
-
-

-Next: Abbrevs and Abbrev Expansion, Previous: Syntax Tables, Up: Emacs Lisp   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Pattern-Matching.html b/admin/notes/tree-sitter/html-manual/Pattern-Matching.html deleted file mode 100644 index 9ef536b79dd..00000000000 --- a/admin/notes/tree-sitter/html-manual/Pattern-Matching.html +++ /dev/null @@ -1,450 +0,0 @@ - - - - - - -Pattern Matching (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - - -
- -
-

37.5 Pattern Matching Tree-sitter Nodes

- - - -

Tree-sitter lets Lisp programs match patterns using a small -declarative language. This pattern matching consists of two steps: -first tree-sitter matches a pattern against nodes in the syntax -tree, then it captures specific nodes that matched the pattern -and returns the captured nodes. -

-

We describe first how to write the most basic query pattern and how to -capture nodes in a pattern, then the pattern-matching function, and -finally the more advanced pattern syntax. -

-

Basic query syntax

- - - - -

A query consists of multiple patterns. Each pattern is an -s-expression that matches a certain node in the syntax node. A -pattern has the form (type (child…)) -

-

For example, a pattern that matches a binary_expression node that -contains number_literal child nodes would look like -

-
-
(binary_expression (number_literal))
-
- -

To capture a node using the query pattern above, append -@capture-name after the node pattern you want to -capture. For example, -

-
-
(binary_expression (number_literal) @number-in-exp)
-
- -

captures number_literal nodes that are inside a -binary_expression node with the capture name -number-in-exp. -

-

We can capture the binary_expression node as well, with, for -example, the capture name biexp: -

-
-
(binary_expression
- (number_literal) @number-in-exp) @biexp
-
- -

Query function

- - -

Now we can introduce the query functions. -

-
-
Function: treesit-query-capture node query &optional beg end node-only
-

This function matches patterns in query within node. -The argument query can be either a string, a s-expression, or a -compiled query object. For now, we focus on the string syntax; -s-expression syntax and compiled query are described at the end of the -section. -

-

The argument node can also be a parser or a language symbol. A -parser means using its root node, a language symbol means find or -create a parser for that language in the current buffer, and use the -root node. -

-

The function returns all the captured nodes in a list of the form -(capture_name . node). If node-only is -non-nil, it returns the list of nodes instead. By default the -entire text of node is searched, but if beg and end -are both non-nil, they specify the region of buffer text where -this function should match nodes. Any matching node whose span -overlaps with the region between beg and end are captured, -it doesn’t have to be completely in the region. -

- - -

This function raises the treesit-query-error error if -query is malformed. The signal data contains a description of -the specific error. You can use treesit-query-validate to -validate and debug the query. -

- -

For example, suppose node’s text is 1 + 2, and -query is -

-
-
(setq query
-      "(binary_expression
-        (number_literal) @number-in-exp) @biexp")
-
- -

Matching that query would return -

-
-
(treesit-query-capture node query)
-    ⇒ ((biexp . <node for "1 + 2">)
-       (number-in-exp . <node for "1">)
-       (number-in-exp . <node for "2">))
-
- -

As mentioned earlier, query could contain multiple patterns. -For example, it could have two top-level patterns: -

-
-
(setq query
-      "(binary_expression) @biexp
-       (number_literal)  @number @biexp")
-
- -
-
Function: treesit-query-string string query language
-

This function parses string with language, matches its -root node with query, and returns the result. -

- -

More query syntax

- -

Besides node type and capture, tree-sitter’s pattern syntax can -express anonymous node, field name, wildcard, quantification, -grouping, alternation, anchor, and predicate. -

-

Anonymous node

- -

An anonymous node is written verbatim, surrounded by quotes. A -pattern matching (and capturing) keyword return would be -

-
-
"return" @keyword
-
- -

Wild card

- -

In a pattern, ‘(_)’ matches any named node, and ‘_’ matches -any named and anonymous node. For example, to capture any named child -of a binary_expression node, the pattern would be -

-
-
(binary_expression (_) @in_biexp)
-
- -

Field name

- -

It is possible to capture child nodes that have specific field names. -In the pattern below, declarator and body are field -names, indicated by the colon following them. -

-
-
(function_definition
-  declarator: (_) @func-declarator
-  body: (_) @func-body)
-
- -

It is also possible to capture a node that doesn’t have a certain -field, say, a function_definition without a body field. -

-
-
(function_definition !body) @func-no-body
-
- -

Quantify node

- - -

Tree-sitter recognizes quantification operators ‘*’, ‘+’ and -‘?’. Their meanings are the same as in regular expressions: -‘*’ matches the preceding pattern zero or more times, ‘+’ -matches one or more times, and ‘?’ matches zero or one time. -

-

For example, the following pattern matches type_declaration -nodes that has zero or more long keyword. -

-
-
(type_declaration "long"*) @long-type
-
- -

The following pattern matches a type declaration that has zero or one -long keyword: -

-
-
(type_declaration "long"?) @long-type
-
- -

Grouping

- -

Similar to groups in regular expression, we can bundle patterns into -groups and apply quantification operators to them. For example, to -express a comma separated list of identifiers, one could write -

-
-
(identifier) ("," (identifier))*
-
- -

Alternation

- -

Again, similar to regular expressions, we can express “match anyone -from this group of 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 -

-
-
[
-  "return"
-  "break"
-  "if"
-  "else"
-] @keyword
-
- -

Anchor

- -

The anchor operator ‘.’ 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 -adjacent children: -

-
-
;; Anchor the child with the end of its parent.
-(compound_expression (_) @last-child .)
-
-
-
;; Anchor the child with the beginning of its parent.
-(compound_expression . (_) @first-child)
-
-
-
;; Anchor two adjacent children.
-(compound_expression
- (_) @prev-child
- .
- (_) @next-child)
-
- -

Note that the enforcement of juxtaposition ignores any anonymous -nodes. -

-

Predicate

- -

It is possible to add predicate constraints to a pattern. For -example, with the following pattern: -

-
-
(
- (array . (_) @first (_) @last .)
- (#equal @first @last)
-)
-
- -

tree-sitter only matches arrays where the first element equals to -the last element. To attach a predicate to a pattern, we need to -group them together. A predicate always starts with a ‘#’. -Currently there are two predicates, #equal and #match. -

-
-
Predicate: equal arg1 arg2
-

Matches if arg1 equals to arg2. Arguments can be either -strings or capture names. Capture names represent the text that the -captured node spans in the buffer. -

- -
-
Predicate: match regexp capture-name
-

Matches if the text that capture-name’s node spans in the buffer -matches regular expression regexp. Matching is case-sensitive. -

- -

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. -

-

S-expression patterns

- - - -

Besides strings, Emacs provides a s-expression based syntax for -tree-sitter patterns. It largely resembles the string-based syntax. -For example, the following query -

-
-
(treesit-query-capture
- node "(addition_expression
-        left: (_) @left
-        \"+\" @plus-sign
-        right: (_) @right) @addition
-
-        [\"return\" \"break\"] @keyword")
-
- -

is equivalent to -

-
-
(treesit-query-capture
- node '((addition_expression
-         left: (_) @left
-         "+" @plus-sign
-         right: (_) @right) @addition
-
-         ["return" "break"] @keyword))
-
- -

Most patterns can be written directly as strange but nevertheless -valid s-expressions. Only a few of them needs modification: -

- - -

For example, -

-
-
"(
-  (compound_expression . (_) @first (_)* @rest)
-  (#match \"love\" @first)
-  )"
-
- -

is written in s-expression as -

-
-
'((
-   (compound_expression :anchor (_) @first (_) :* @rest)
-   (:match "love" @first)
-   ))
-
- -

Compiling queries

- - - -

If a query is intended to be used repeatedly, especially in tight -loops, it is important to compile that query, because a compiled query -is much faster than an uncompiled one. A compiled query can be used -anywhere a query is accepted. -

-
-
Function: treesit-query-compile language query
-

This function compiles query for language into a compiled -query object and returns it. -

-

This function raises the treesit-query-error error if -query is malformed. The signal data contains a description of -the specific error. You can use treesit-query-validate to -validate and debug the query. -

- -
-
Function: treesit-query-language query
-

This function return the language of query. -

- -
-
Function: treesit-query-expand query
-

This function converts the s-expression query into the string -format. -

- -
-
Function: treesit-pattern-expand pattern
-

This function converts the s-expression pattern into the string -format. -

- -

For more details, read the tree-sitter project’s documentation about -pattern-matching, which can be found at -https://tree-sitter.github.io/tree-sitter/using-parsers#pattern-matching-with-queries. -

-
-
-
-

-Next: Parsing Text in Multiple Languages, Previous: Accessing Node Information, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Retrieving-Node.html b/admin/notes/tree-sitter/html-manual/Retrieving-Node.html deleted file mode 100644 index 16eeb0b1091..00000000000 --- a/admin/notes/tree-sitter/html-manual/Retrieving-Node.html +++ /dev/null @@ -1,420 +0,0 @@ - - - - - - -Retrieving Node (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - - -
- -
-

37.3 Retrieving Node

- - - - - -

Here’s some terminology and conventions we use when documenting -tree-sitter functions. -

-

We talk about a node being “smaller” or “larger”, and “lower” or -“higher”. A smaller and lower node is lower in the syntax tree and -therefore spans a smaller portion of buffer text; a larger and higher -node is higher up in the syntax tree, it contains many smaller nodes -as its children, and therefore spans a larger portion of text. -

-

When a function cannot find a node, it returns nil. For -convenience, all functions that take a node as argument and return -a node, also accept the node argument of nil and in that case -just return nil. -

- -

Nodes are not automatically updated when the associated buffer is -modified, and there is no way to update a node once it is retrieved. -Using an outdated node signals the treesit-node-outdated error. -

-

Retrieving node from syntax tree

- - - -
-
Function: treesit-node-at pos &optional parser-or-lang named
-

This function returns the smallest node that starts at or after -the buffer position pos. In other words, the start of the node -is greater or equal to pos. -

-

When parser-or-lang is nil or omitted, this function uses -the first parser in (treesit-parser-list) of the current -buffer. If parser-or-lang is a parser object, it uses that -parser; if parser-or-lang is a language, it finds the first -parser using that language in (treesit-parser-list), and uses -that. -

-

If named is non-nil, this function looks for a named node -only (see named node). -

-

When pos is after all the text in the buffer, technically there -is no node after pos. But for convenience, this function will -return the last leaf node in the parse tree. If strict is -non-nil, this function will strictly comply to the semantics and -return nil. -

-

Example: -

-
-
;; Find the node at point in a C parser's syntax tree.
-(treesit-node-at (point) 'c)
-  ⇒ #<treesit-node (primitive_type) in 23-27>
-
-
- -
-
Function: treesit-node-on beg end &optional parser-or-lang named
-

This function returns the smallest node that covers the region -of buffer text between beg and end. In other words, the -start of the node is before or at beg, and the end of the node -is at or after end. -

-

Beware: calling this function on an empty line that is not -inside any top-level construct (function definition, etc.) most -probably will give you the root node, because the root node is the -smallest node that covers that empty line. Most of the time, you want -to use treesit-node-at, described above, instead. -

-

When parser-or-lang is nil, this function uses the first -parser in (treesit-parser-list) of the current buffer. If -parser-or-lang is a parser object, it uses that parser; if -parser-or-lang is a language, it finds the first parser using -that language in (treesit-parser-list), and uses that. -

-

If named is non-nil, this function looks for a named node -only (see named node). -

- -
-
Function: treesit-parser-root-node parser
-

This function returns the root node of the syntax tree generated by -parser. -

- -
-
Function: treesit-buffer-root-node &optional language
-

This function finds the first parser that uses language in -(treesit-parser-list) of the current buffer, and returns the -root node generated by that parser. If it cannot find an appropriate -parser, it returns nil. -

- -

Given a node, a Lisp program can retrieve other nodes starting from -it, or query for information about this node. -

-

Retrieving node from other nodes

- - -

By kinship

- - - - -
-
Function: treesit-node-parent node
-

This function returns the immediate parent of node. -

- -
-
Function: treesit-node-child node n &optional named
-

This function returns the n’th child of node. If -named is non-nil, it counts only named nodes -(see named node). -

-

For example, in a node that represents a string "text", there -are three children nodes: the opening quote ", the string text -text, and the closing quote ". Among these nodes, the -first child is the opening quote ", and the first named child -is the string text. -

-

This function returns nil if there is no n’th child. -n could be negative, e.g., -1 represents the last child. -

- -
-
Function: treesit-node-children node &optional named
-

This function returns all of node’s children as a list. If -named is non-nil, it retrieves only named nodes. -

- -
-
Function: treesit-node-next-sibling node &optional named
-

This function finds the next sibling of node. If named is -non-nil, it finds the next named sibling. -

- -
-
Function: treesit-node-prev-sibling node &optional named
-

This function finds the previous sibling of node. If -named is non-nil, it finds the previous named sibling. -

- -

By field name

- - - -

To make the syntax tree easier to analyze, many language definitions -assign field names to child nodes (see field name). For example, a function_definition node -could have a declarator node and a body node. -

-
-
Function: treesit-node-child-by-field-name node field-name
-

This function finds the child of node whose field name is -field-name, a string. -

-
-
;; Get the child that has "body" as its field name.
-(treesit-node-child-by-field-name node "body")
-  ⇒ #<treesit-node (compound_statement) in 45-89>
-
-
- -

By position

- - - -
-
Function: treesit-node-first-child-for-pos node pos &optional named
-

This function finds the first child of node that extends beyond -buffer position pos. “Extends beyond” means the end of the -child node is greater or equal to pos. This function only looks -for immediate children of node, and doesn’t look in its -grandchildren. If named is non-nil, it looks for the -first named child (see named node). -

- -
-
Function: treesit-node-descendant-for-range node beg end &optional named
-

This function finds the smallest descendant node of node -that spans the region of text between positions beg and -end. It is similar to treesit-node-at. If named -is non-nil, it looks for smallest named child. -

- -

Searching for node

- -
-
Function: treesit-search-subtree node predicate &optional backward all limit
-

This function traverses the subtree of node (including -node itself), looking for a node for which predicate -returns non-nil. predicate is a regexp that is matched -against each node’s type, or a predicate function that takes a node -and returns non-nil if the node matches. The function returns -the first node that matches, or nil if none does. -

-

By default, this function only traverses named nodes, but if all -is non-nil, it traverses all the nodes. If backward is -non-nil, it traverses backwards (i.e., it visits the last child first -when traversing down the tree). If limit is non-nil, it -must be a number that limits the tree traversal to that many levels -down the tree. -

- -
-
Function: treesit-search-forward start predicate &optional backward all
-

Like treesit-search-subtree, this function also traverses the -parse tree and matches each node with predicate (except for -start), where predicate can be a regexp or a function. -For a tree like the below where start is marked S, this function -traverses as numbered from 1 to 12: -

-
-
              12
-              |
-     S--------3----------11
-     |        |          |
-o--o-+--o  1--+--2    6--+-----10
-|  |                  |        |
-o  o                +-+-+   +--+--+
-                    |   |   |  |  |
-                    4   5   7  8  9
-
- -

Note that this function doesn’t traverse the subtree of start, -and it always traverse leaf nodes first, then upwards. -

-

Like treesit-search-subtree, this function only searches for -named nodes by default, but if all is non-nil, it -searches for all nodes. If backward is non-nil, it -searches backwards. -

-

While treesit-search-subtree traverses the subtree of a node, -this function starts with node start and traverses every node -that comes after it in the buffer position order, i.e., nodes with -start positions greater than the end position of start. -

-

In the tree shown above, treesit-search-subtree traverses node -S (start) and nodes marked with o, where this function -traverses the nodes marked with numbers. This function is useful for -answering questions like “what is the first node after start in -the buffer that satisfies some condition?” -

- -
-
Function: treesit-search-forward-goto node predicate &optional start backward all
-

This function moves point to the start or end of the next node after -node in the buffer that matches predicate. If start -is non-nil, stop at the beginning rather than the end of a node. -

-

This function guarantees that the matched node it returns makes -progress in terms of buffer position: the start/end position of the -returned node is always greater than that of node. -

-

Arguments predicate, backward and all are the same -as in treesit-search-forward. -

- -
-
Function: treesit-induce-sparse-tree root predicate &optional process-fn limit
-

This function creates a sparse tree from root’s subtree. -

-

It takes the subtree under root, and combs it so only the nodes -that match predicate are left. Like previous functions, the -predicate can be a regexp string that matches against each -node’s type, or a function that takes a node and return non-nil -if it matches. -

-

For example, for a subtree on the left that consist of both numbers -and letters, if predicate is “letter only”, the returned tree -is the one on the right. -

-
-
    a                 a              a
-    |                 |              |
-+---+---+         +---+---+      +---+---+
-|   |   |         |   |   |      |   |   |
-b   1   2         b   |   |      b   c   d
-    |   |     =>      |   |  =>      |
-    c   +--+          c   +          e
-    |   |  |          |   |
- +--+   d  4       +--+   d
- |  |              |
- e  5              e
-
- -

If process-fn is non-nil, instead of returning the matched -nodes, this function passes each node to process-fn and uses the -returned value instead. If non-nil, limit is the number of -levels to go down from root. -

-

Each node in the returned tree looks like -(tree-sitter-node . (child …)). The -tree-sitter-node of the root of this tree will be nil if -root doesn’t match predicate. If no node matches -predicate, the function returns nil. -

- -

More convenience functions

- -
-
Function: treesit-filter-child node predicate &optional named
-

This function finds immediate children of node that satisfy -predicate. -

-

The predicate function takes a node as the argument and should -return non-nil to indicate that the node should be kept. If -named is non-nil, this function only examines the named -nodes. -

- -
-
Function: treesit-parent-until node predicate
-

This function repeatedly finds the parents of node, and returns -the parent that satisfies predicate, a function that takes a -node as the argument. If no parent satisfies predicate, this -function returns nil. -

- -
-
Function: treesit-parent-while node predicate
-

This function repeatedly finds the parent of node, and keeps -doing so as long as the nodes satisfy predicate, a function that -takes a node as the argument. That is, this function returns the -farthest parent that still satisfies predicate. -

- -
-
Function: treesit-node-top-level node &optional type
-

This function returns the highest parent of node that has the -same type as node. If no such parent exists, it returns -nil. Therefore this function is also useful for testing -whether node is top-level. -

-

If type is non-nil, this function matches each parent’s -type with type as a regexp, rather than using node’s type. -

- -
-
-
-

-Next: Accessing Node Information, Previous: Using Tree-sitter Parser, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Tree_002dsitter-C-API.html b/admin/notes/tree-sitter/html-manual/Tree_002dsitter-C-API.html deleted file mode 100644 index 1d992b828ea..00000000000 --- a/admin/notes/tree-sitter/html-manual/Tree_002dsitter-C-API.html +++ /dev/null @@ -1,211 +0,0 @@ - - - - - - -Tree-sitter C API (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - -
- -
-

37.8 Tree-sitter C API Correspondence

- -

Emacs’ tree-sitter integration doesn’t expose every feature -provided by tree-sitter’s C API. Missing features include: -

- - -

In addition, Emacs makes some changes to the C API to make the API more -convenient and idiomatic: -

- - -

Below is the correspondence between all C API functions and their -ELisp counterparts. Sometimes one ELisp function corresponds to -multiple C functions, and many C functions don’t have an ELisp -counterpart. -

-
-
ts_parser_new                           treesit-parser-create
-ts_parser_delete
-ts_parser_set_language
-ts_parser_language                      treesit-parser-language
-ts_parser_set_included_ranges           treesit-parser-set-included-ranges
-ts_parser_included_ranges               treesit-parser-included-ranges
-ts_parser_parse
-ts_parser_parse_string                  treesit-parse-string
-ts_parser_parse_string_encoding
-ts_parser_reset
-ts_parser_set_timeout_micros
-ts_parser_timeout_micros
-ts_parser_set_cancellation_flag
-ts_parser_cancellation_flag
-ts_parser_set_logger
-ts_parser_logger
-ts_parser_print_dot_graphs
-ts_tree_copy
-ts_tree_delete
-ts_tree_root_node
-ts_tree_language
-ts_tree_edit
-ts_tree_get_changed_ranges
-ts_tree_print_dot_graph
-ts_node_type                            treesit-node-type
-ts_node_symbol
-ts_node_start_byte                      treesit-node-start
-ts_node_start_point
-ts_node_end_byte                        treesit-node-end
-ts_node_end_point
-ts_node_string                          treesit-node-string
-ts_node_is_null
-ts_node_is_named                        treesit-node-check
-ts_node_is_missing                      treesit-node-check
-ts_node_is_extra                        treesit-node-check
-ts_node_has_changes
-ts_node_has_error                       treesit-node-check
-ts_node_parent                          treesit-node-parent
-ts_node_child                           treesit-node-child
-ts_node_field_name_for_child            treesit-node-field-name-for-child
-ts_node_child_count                     treesit-node-child-count
-ts_node_named_child                     treesit-node-child
-ts_node_named_child_count               treesit-node-child-count
-ts_node_child_by_field_name             treesit-node-by-field-name
-ts_node_child_by_field_id
-ts_node_next_sibling                    treesit-node-next-sibling
-ts_node_prev_sibling                    treesit-node-prev-sibling
-ts_node_next_named_sibling              treesit-node-next-sibling
-ts_node_prev_named_sibling              treesit-node-prev-sibling
-ts_node_first_child_for_byte            treesit-node-first-child-for-pos
-ts_node_first_named_child_for_byte      treesit-node-first-child-for-pos
-ts_node_descendant_for_byte_range       treesit-descendant-for-range
-ts_node_descendant_for_point_range
-ts_node_named_descendant_for_byte_range treesit-descendant-for-range
-ts_node_named_descendant_for_point_range
-ts_node_edit
-ts_node_eq                              treesit-node-eq
-ts_tree_cursor_new
-ts_tree_cursor_delete
-ts_tree_cursor_reset
-ts_tree_cursor_current_node
-ts_tree_cursor_current_field_name
-ts_tree_cursor_current_field_id
-ts_tree_cursor_goto_parent
-ts_tree_cursor_goto_next_sibling
-ts_tree_cursor_goto_first_child
-ts_tree_cursor_goto_first_child_for_byte
-ts_tree_cursor_goto_first_child_for_point
-ts_tree_cursor_copy
-ts_query_new
-ts_query_delete
-ts_query_pattern_count
-ts_query_capture_count
-ts_query_string_count
-ts_query_start_byte_for_pattern
-ts_query_predicates_for_pattern
-ts_query_step_is_definite
-ts_query_capture_name_for_id
-ts_query_string_value_for_id
-ts_query_disable_capture
-ts_query_disable_pattern
-ts_query_cursor_new
-ts_query_cursor_delete
-ts_query_cursor_exec                    treesit-query-capture
-ts_query_cursor_did_exceed_match_limit
-ts_query_cursor_match_limit
-ts_query_cursor_set_match_limit
-ts_query_cursor_set_byte_range
-ts_query_cursor_set_point_range
-ts_query_cursor_next_match
-ts_query_cursor_remove_match
-ts_query_cursor_next_capture
-ts_language_symbol_count
-ts_language_symbol_name
-ts_language_symbol_for_name
-ts_language_field_count
-ts_language_field_name_for_id
-ts_language_field_id_for_name
-ts_language_symbol_type
-ts_language_version
-
-
-
-
-

-Previous: Developing major modes with tree-sitter, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/Using-Parser.html b/admin/notes/tree-sitter/html-manual/Using-Parser.html deleted file mode 100644 index fd8fc482f46..00000000000 --- a/admin/notes/tree-sitter/html-manual/Using-Parser.html +++ /dev/null @@ -1,230 +0,0 @@ - - - - - - -Using Parser (GNU Emacs Lisp Reference Manual) - - - - - - - - - - - - - - - - - - - - - -
- -
-

37.2 Using Tree-sitter Parser

- - -

This section describes how to create and configure a tree-sitter -parser. In Emacs, each tree-sitter parser is associated with a -buffer. As the user edits the buffer, the associated parser and -syntax tree are automatically kept up-to-date. -

-
-
Variable: treesit-max-buffer-size
-

This variable contains the maximum size of buffers in which -tree-sitter can be activated. Major modes should check this value -when deciding whether to enable tree-sitter features. -

- -
-
Function: treesit-can-enable-p
-

This function checks whether the current buffer is suitable for -activating tree-sitter features. It basically checks -treesit-available-p and treesit-max-buffer-size. -

- - - -
-
Function: treesit-parser-create language &optional buffer no-reuse
-

Create a parser for the specified buffer and language -(see Tree-sitter Language Definitions). If buffer is omitted or -nil, it stands for the current buffer. -

-

By default, this function reuses a parser if one already exists for -language in buffer, but if no-reuse is -non-nil, this function always creates a new parser. -

- -

Given a parser, we can query information about it. -

-
-
Function: treesit-parser-buffer parser
-

This function returns the buffer associated with parser. -

- -
-
Function: treesit-parser-language parser
-

This function returns the language used by parser. -

- -
-
Function: treesit-parser-p object
-

This function checks if object is a tree-sitter parser, and -returns non-nil if it is, and nil otherwise. -

- -

There is no need to explicitly parse a buffer, because parsing is done -automatically and lazily. A parser only parses when a Lisp program -queries for a node in its syntax tree. Therefore, when a parser is -first created, it doesn’t parse the buffer; it waits until the Lisp -program queries for a node for the first time. Similarly, when some -change is made in the buffer, a parser doesn’t re-parse immediately. -

- -

When a parser does parse, it checks for the size of the buffer. -Tree-sitter can only handle buffer no larger than about 4GB. If the -size exceeds that, Emacs signals the treesit-buffer-too-large -error with signal data being the buffer size. -

-

Once a parser is created, Emacs automatically adds it to the -internal parser list. Every time a change is made to the buffer, -Emacs updates parsers in this list so they can update their syntax -tree incrementally. -

-
-
Function: treesit-parser-list &optional buffer
-

This function returns the parser list of buffer. If -buffer is nil or omitted, it defaults to the current -buffer. -

- -
-
Function: treesit-parser-delete parser
-

This function deletes parser. -

- - -

Normally, a parser “sees” the whole buffer, but when the buffer is -narrowed (see Narrowing), the parser will only see the accessible -portion of the buffer. As far as the parser can tell, the hidden -region was deleted. When the buffer is later widened, the parser -thinks text is inserted at the beginning and at the end. Although -parsers respect narrowing, modes should not use narrowing as a means -to handle a multi-language buffer; instead, set the ranges in which the -parser should operate. See Parsing Text in Multiple Languages. -

-

Because a parser parses lazily, when the user or a Lisp program -narrows the buffer, the parser is not affected immediately; as long as -the mode doesn’t query for a node while the buffer is narrowed, the -parser is oblivious of the narrowing. -

- - -

Besides creating a parser for a buffer, a Lisp program can also parse a -string. Unlike a buffer, parsing a string is a one-off operation, and -there is no way to update the result. -

-
-
Function: treesit-parse-string string language
-

This function parses string using language, and returns -the root node of the generated syntax tree. -

- -

Be notified by changes to the parse tree

- - - - - -

A Lisp program might want to be notified of text affected by -incremental parsing. For example, inserting a comment-closing token -converts text before that token into a comment. Even -though the text is not directly edited, it is deemed to be “changed” -nevertheless. -

-

Emacs lets a Lisp program to register callback functions -(a.k.a. notifiers) for this kind of changes. A notifier -function takes two arguments: ranges and parser. -ranges is a list of cons cells of the form (start . end), where start and end mark the start and the -end positions of a range. parser is the parser issuing the -notification. -

-

Every time a parser reparses a buffer, it compares the old and new -parse-tree, computes the ranges in which nodes have changed, and -passes the ranges to notifier functions. -

-
-
Function: treesit-parser-add-notifier parser function
-

This function adds function to parser’s list of -after-change notifier functions. function must be a function -symbol, not a lambda function (see Anonymous Functions). -

- -
-
Function: treesit-parser-remove-notifier parser function
-

This function removes function from the list of parser’s -after-change notifier functions. function must be a function -symbol, rather than a lambda function. -

- -
-
Function: treesit-parser-notifiers parser
-

This function returns the list of parser’s notifier functions. -

- -
-
-
-

-Next: Retrieving Nodes, Previous: Tree-sitter Language Definitions, Up: Parsing Program Source   [Contents][Index]

-
- - - - - diff --git a/admin/notes/tree-sitter/html-manual/build-manual.sh b/admin/notes/tree-sitter/html-manual/build-manual.sh deleted file mode 100755 index 8d931b143b2..00000000000 --- a/admin/notes/tree-sitter/html-manual/build-manual.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -MANUAL_DIR="../../../../doc/lispref" -THIS_DIR=$(pwd) - -echo "Build manual" -cd "${MANUAL_DIR}" -make elisp.html HTML_OPTS="--html --css-ref=./manual.css" - -cd "${THIS_DIR}" - -echo "Copy manual" -cp -f "${MANUAL_DIR}/elisp.html/Parsing-Program-Source.html" . -cp -f "${MANUAL_DIR}/elisp.html/Language-Definitions.html" . -cp -f "${MANUAL_DIR}/elisp.html/Using-Parser.html" . -cp -f "${MANUAL_DIR}/elisp.html/Retrieving-Node.html" . -cp -f "${MANUAL_DIR}/elisp.html/Accessing-Node.html" . -cp -f "${MANUAL_DIR}/elisp.html/Pattern-Matching.html" . -cp -f "${MANUAL_DIR}/elisp.html/Multiple-Languages.html" . -cp -f "${MANUAL_DIR}/elisp.html/Tree_002dsitter-C-API.html" . - -cp -f "${MANUAL_DIR}/elisp.html/Parser_002dbased-Font-Lock.html" . -cp -f "${MANUAL_DIR}/elisp.html/Parser_002dbased-Indentation.html" . diff --git a/admin/notes/tree-sitter/html-manual/manual.css b/admin/notes/tree-sitter/html-manual/manual.css deleted file mode 100644 index c03e0d37009..00000000000 --- a/admin/notes/tree-sitter/html-manual/manual.css +++ /dev/null @@ -1,374 +0,0 @@ -/* Style-sheet to use for Emacs manuals */ - -/* Copyright (C) 2013-2014, 2023 Free Software Foundation, Inc. - -Copying and distribution of this file, with or without modification, -are permitted in any medium without royalty provided the copyright -notice and this notice are preserved. This file is offered as-is, -without any warranty. -*/ - -/* style.css begins here */ - -/* This stylesheet is used by manuals and a few older resources. */ - -/* reset.css begins here */ - -/* -Software License Agreement (BSD License) - -Copyright (c) 2006, Yahoo! Inc. -All rights reserved. - -Redistribution and use of this software in source and -binary forms, with or without modification, arepermitted -provided that the following conditions are met: - -* Redistributions of source code must retain the above -copyright notice, this list of conditions and the -following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the -following disclaimer in the documentation and/or other -materials provided with the distribution. - -* Neither the name of Yahoo! Inc. nor the names of its -contributors may be used to endorse or promote products -derived from this software without specific prior -written permission of Yahoo! Inc. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, -INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER -IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. -*/ - -html { - color: #000; - background: #FFF; -} - -body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, -h5, h6, pre, code, form, fieldset, legend, input, -button, textarea, p, blockquote, th, td { - margin: 0; - padding: 0; -} - -table { - border-collapse: collapse; - border-spacing: 0; -} - -fieldset, img { - border: 0; -} - -address, caption, cite, code, dfn, em, strong, -th, var, optgroup { - font-style: inherit; - font-weight: inherit; -} - -del, ins { - text-decoration: none; -} - -li { - list-style:none; -} - -caption, th { - text-align: left; -} - -h1, h2, h3, h4, h5, h6 { - font-size: 100%; - font-weight: normal; -} - -q:before, q:after { - content:''; -} - -abbr, acronym { - border: 0; - font-variant: normal; -} - -sup { - vertical-align: baseline; -} -sub { - vertical-align: baseline; -} - -legend { - color: #000; -} - -input, button, textarea, select, optgroup, option { - font-family: inherit; - font-size: inherit; - font-style: inherit; - font-weight: inherit; -} - -input, button, textarea, select { - *font-size: 100%; -} - - -/* reset.css ends here */ - -/*** PAGE LAYOUT ***/ - -html, body { - font-size: 1em; - text-align: left; - text-decoration: none; -} -html { background-color: #e7e7e7; } - -body { - max-width: 74.92em; - margin: 0 auto; - padding: .5em 1em 1em 1em; - background-color: white; - border: .1em solid #c0c0c0; -} - - -/*** BASIC ELEMENTS ***/ - -/* Size and positioning */ - -p, pre, li, dt, dd, table, code, address { line-height: 1.3em; } - -h1 { font-size: 2em; margin: 1em 0 } -h2 { font-size: 1.50em; margin: 1.0em 0 0.87em 0; } -h3 { font-size: 1.30em; margin: 1.0em 0 0.87em 0; } -h4 { font-size: 1.13em; margin: 1.0em 0 0.88em 0; } -h5 { font-size: 1.00em; margin: 1.0em 0 1.00em 0; } - -p, pre { margin: 1em 0; } -pre { overflow: auto; padding-bottom: .3em; } - -ul, ol, blockquote { margin-left: 1.5%; margin-right: 1.5%; } -hr { margin: 1em 0; } -/* Lists of underlined links are difficult to read. The top margin - gives a little more spacing between entries. */ -ul li { margin: .5em 1em; } -ol li { margin: 1em; } -ol ul li { margin: .5em 1em; } -ul li p, ul ul li { margin-top: .3em; margin-bottom: .3em; } -ul ul, ol ul { margin-top: 0; margin-bottom: 0; } - -/* Separate description lists from preceding text */ -dl { margin: 1em 0 0 0; } -/* separate the "term" from subsequent "description" */ -dt { margin: .5em 0; } -/* separate the "description" from subsequent list item - when the final
child is an anonymous box */ -dd { margin: .5em 3% 1em 3%; } -/* separate anonymous box (used to be the first element in
) - from subsequent

*/ -dd p { margin: .5em 0; } - -table { - display: block; overflow: auto; - margin-top: 1.5em; margin-bottom: 1.5em; -} -th { padding: .3em .5em; text-align: center; } -td { padding: .2em .5em; } - -address { margin-bottom: 1em; } -caption { margin-bottom: .5em; text-align: center; } -sup { vertical-align: super; } -sub { vertical-align: sub; } - -/* Style */ - -h1, h2, h3, h4, h5, h6, strong, dt, th { font-weight: bold; } - -/* The default color (black) is too dark for large text in - bold font. */ -h1, h2, h3, h4 { color: #333; } -h5, h6, dt { color: #222; } - -a[href] { color: #005090; } -a[href]:visited { color: #100070; } -a[href]:active, a[href]:hover { - color: #100070; - text-decoration: none; -} - -h1 a[href]:visited, h2 a[href]:visited, h3 a[href]:visited, -h4 a[href]:visited { color: #005090; } -h1 a[href]:hover, h2 a[href]:hover, h3 a[href]:hover, -h4 a[href]:hover { color: #100070; } - -ol { list-style: decimal outside;} -ul { list-style: square outside; } -ul ul, ol ul { list-style: circle; } -li { list-style: inherit; } - -hr { background-color: #ede6d5; } -table { border: 0; } - -abbr,acronym { - border-bottom:1px dotted #000; - text-decoration: none; - cursor:help; -} -del { text-decoration: line-through; } -em { font-style: italic; } -small { font-size: .9em; } - -img { max-width: 100%} - - -/*** SIMPLE CLASSES ***/ - -.center, .c { text-align: center; } -.nocenter{ text-align: left; } - -.underline { text-decoration: underline; } -.nounderline { text-decoration: none; } - -.no-bullet { list-style: none; } -.inline-list li { display: inline } - -.netscape4, .no-display { display: none; } - - -/*** MANUAL PAGES ***/ - -/* This makes the very long tables of contents in Gnulib and other - manuals easier to read. */ -.contents ul, .shortcontents ul { font-weight: bold; } -.contents ul ul, .shortcontents ul ul { font-weight: normal; } -.contents ul { list-style: none; } - -/* For colored navigation bars (Emacs manual): make the bar extend - across the whole width of the page and give it a decent height. */ -.header, .node { margin: 0 -1em; padding: 0 1em; } -.header p, .node p { line-height: 2em; } - -/* For navigation links */ -.node a, .header a { display: inline-block; line-height: 2em; } -.node a:hover, .header a:hover { background: #f2efe4; } - -/* Inserts */ -table.cartouche td { padding: 1.5em; } - -div.display, div.lisp, div.smalldisplay, -div.smallexample, div.smalllisp { margin-left: 3%; } - -div.example { padding: .8em 1.2em .4em; } -pre.example { padding: .8em 1.2em; } -div.example, pre.example { - margin: 1em 0 1em 3% ; - -webkit-border-radius: .3em; - -moz-border-radius: .3em; - border-radius: .3em; - border: 1px solid #d4cbb6; - background-color: #f2efe4; -} -div.example > pre.example { - padding: 0 0 .4em; - margin: 0; - border: none; -} - -pre.menu-comment { padding-top: 1.3em; margin: 0; } - - -/*** FOR WIDE SCREENS ***/ - -@media (min-width: 40em) { - body { padding: .5em 3em 1em 3em; } - div.header, div.node { margin: 0 -3em; padding: 0 3em; } -} - -/* style.css ends here */ - -/* makeinfo convert @deffn and similar functions to something inside -

. style.css uses italic for blockquote. This looks poor - in the Emacs manuals, which make extensive use of @defun (etc). - In particular, references to function arguments appear as - inside
. Since is also italic, it makes it - impossible to distinguish variables. We could change to - e.g. bold-italic, or normal, or a different color, but that does - not look as good IMO. So we just override blockquote to be non-italic. - */ -blockquote { font-style: normal; } - -var { font-style: italic; } - -div.header { - background-color: #DDDDFF; - padding-top: 0.2em; -} - - -/*** Customization ***/ - -body { - font-family: Charter, serif; - font-size: 14pt; - line-height: 1.4; - background-color: #fefefc; - color: #202010; -} - -pre.menu-comment { - font-family: Charter, serif; - font-size: 14pt; -} - -body > *, body > div.display, body > div.lisp, body > div.smalldisplay, -body > div.example, body > div.smallexample, body > div.smalllisp { - width: 700px; - margin-left: auto; - margin-right: auto; -} - -div.header { - width: 100%; - min-height: 3em; - font-size: 13pt; -} - -/* Documentation block for functions and variables. Make then - narrower*/ -dd { - margin: .5em 6% 1em 6% -} - -code, pre, kbd, samp, tt { - font-size: 12pt; - font-family: monospace; -} - -/* In each node we have index table to all sub-nodes. Make more space - for the first column, which is the name to each sub-node. */ -table.menu tbody tr td:nth-child(1) { - white-space: nowrap; -} - -div.header p { - text-align: center; - margin: 0.5em auto 0.5em auto; -} diff --git a/admin/notes/tree-sitter/starter-guide b/admin/notes/tree-sitter/starter-guide index b8910aab5ca..846614f1446 100644 --- a/admin/notes/tree-sitter/starter-guide +++ b/admin/notes/tree-sitter/starter-guide @@ -17,6 +17,7 @@ TOC: - More features? - Common tasks (code snippets) - Manual +- Appendix 1 * Building Emacs with tree-sitter @@ -42,11 +43,9 @@ You can use this script that I put together here: https://github.com/casouri/tree-sitter-module -You can also find them under this directory in /build-modules. - This script automatically pulls and builds language definitions for C, C++, Rust, JSON, Go, HTML, JavaScript, CSS, Python, Typescript, -and C#. Better yet, I pre-built these language definitions for +C#, etc. Better yet, I pre-built these language definitions for GNU/Linux and macOS, they can be downloaded here: https://github.com/casouri/tree-sitter-module/releases/tag/v2.1 @@ -68,6 +67,10 @@ organization has all the "official" language definitions: https://github.com/tree-sitter +Alternatively, you can use treesit-install-language-grammar command +and follow its instructions. If everything goes right, it should +automatically download and compile the language grammar for you. + * Setting up for adding major mode features Start Emacs and load tree-sitter with @@ -78,6 +81,10 @@ Now check if Emacs is built with tree-sitter library (treesit-available-p) +Make sure Emacs can find the language grammar you want to use + + (treesit-language-available-p 'lang) + * Tree-sitter major modes Tree-sitter modes should be separate major modes, so other modes @@ -89,12 +96,15 @@ modes. If the tree-sitter variant and the "native" variant could share some setup, you can create a "base mode", which only contains the common -setup. For example, there is python-base-mode (shared), python-mode -(native), and python-ts-mode (tree-sitter). +setup. For example, python.el defines python-base-mode (shared), +python-mode (native), and python-ts-mode (tree-sitter). In the tree-sitter mode, check if we can use tree-sitter with treesit-ready-p, it will error out if tree-sitter is not ready. +In Emacs 30 we'll introduce some mechanism to more gracefully inherit +modes and fallback to other modes. + * Naming convention Use tree-sitter for text (documentation, comment), use treesit for @@ -180,18 +190,17 @@ mark the offending part in red. To enable tree-sitter font-lock, set ‘treesit-font-lock-settings’ and ‘treesit-font-lock-feature-list’ buffer-locally and call ‘treesit-major-mode-setup’. For example, see -‘python--treesit-settings’ in python.el. Below I paste a snippet of -it. +‘python--treesit-settings’ in python.el. Below is a snippet of it. -Note that like the current font-lock, if the to-be-fontified region -already has a face (ie, an earlier match fontified part/all of the -region), the new face is discarded rather than applied. If you want -later matches always override earlier matches, use the :override -keyword. +Just like the current font-lock, if the to-be-fontified region already +has a face (ie, an earlier match fontified part/all of the region), +the new face is discarded rather than applied. If you want later +matches always override earlier matches, use the :override keyword. Each rule should have a :feature, like function-name, string-interpolation, builtin, etc. Users can then enable/disable each -feature individually. +feature individually. See Appendix 1 at the bottom for a set of common +features names. #+begin_src elisp (defvar python--treesit-settings @@ -247,8 +256,7 @@ Concretely, something like this: (string-interpolation decorator))) (treesit-major-mode-setup)) (t - ;; No tree-sitter - (setq-local font-lock-defaults ...) + ;; No tree-sitter, do nothing or fallback to another mode. ...))) #+end_src @@ -289,6 +297,7 @@ For ANCHOR we have first-sibling => start of the first sibling parent => start of parent parent-bol => BOL of the line parent is on. + standalone-parent => Like parent-bol but handles more edge cases prev-sibling => start of previous sibling no-indent => current position (don’t indent) prev-line => start of previous line @@ -329,7 +338,8 @@ tells you which rule is applied in the echo area. ...)))) #+end_src -Then you set ‘treesit-simple-indent-rules’ to your rules, and call +To setup indentation for your major mode, set +‘treesit-simple-indent-rules’ to your rules, and call ‘treesit-major-mode-setup’: #+begin_src elisp @@ -339,36 +349,14 @@ Then you set ‘treesit-simple-indent-rules’ to your rules, and call * Imenu -Not much to say except for utilizing ‘treesit-induce-sparse-tree’ (and -explicitly pass a LIMIT argument: most of the time you don't need more -than 10). See ‘js--treesit-imenu-1’ in js.el for an example. - -Once you have the index builder, set ‘imenu-create-index-function’ to -it. +Set ‘treesit-simple-imenu-settings’ and call +‘treesit-major-mode-setup’. * Navigation -Mainly ‘beginning-of-defun-function’ and ‘end-of-defun-function’. -You can find the end of a defun with something like - -(treesit-search-forward-goto "function_definition" 'end) - -where "function_definition" matches the node type of a function -definition node, and ’end means we want to go to the end of that node. - -Tree-sitter has default implementations for -‘beginning-of-defun-function’ and ‘end-of-defun-function’. So for -ordinary languages, it is enough to set ‘treesit-defun-type-regexp’ -to something that matches all the defun struct types in the language, -and call ‘treesit-major-mode-setup’. For example, - -#+begin_src emacs-lisp -(setq-local treesit-defun-type-regexp (rx bol - (or "function" "class") - "_definition" - eol)) -(treesit-major-mode-setup) -#+end_src> +Set ‘treesit-defun-type-regexp’ and call +‘treesit-major-mode-setup’. You can additionally set +‘treesit-defun-name-function’. * Which-func @@ -376,36 +364,7 @@ If you have an imenu implementation, set ‘which-func-functions’ to nil, and which-func will automatically use imenu’s data. If you want an independent implementation for which-func, you can -find the current function by going up the tree and looking for the -function_definition node. See the function below for an example. -Since Python allows nested function definitions, that function keeps -going until it reaches the root node, and records all the function -names along the way. - -#+begin_src elisp -(defun python-info-treesit-current-defun (&optional include-type) - "Identical to `python-info-current-defun' but use tree-sitter. -For INCLUDE-TYPE see `python-info-current-defun'." - (let ((node (treesit-node-at (point))) - (name-list ()) - (type nil)) - (cl-loop while node - if (pcase (treesit-node-type node) - ("function_definition" - (setq type 'def)) - ("class_definition" - (setq type 'class)) - (_ nil)) - do (push (treesit-node-text - (treesit-node-child-by-field-name node "name") - t) - name-list) - do (setq node (treesit-node-parent node)) - finally return (concat (if include-type - (format "%s " type) - "") - (string-join name-list "."))))) -#+end_src +find the current function by ‘treesit-defun-at-point’. * More features? @@ -449,7 +408,51 @@ section is Parsing Program Source. Typing C-h i d m elisp RET g Parsing Program Source RET -will bring you to that section. You can also read the HTML version -under /html-manual in this directory. I find the HTML version easier -to read. You don’t need to read through every sentence, just read the -text paragraphs and glance over function names. +will bring you to that section. You don’t need to read through every +sentence, just read the text paragraphs and glance over function +names. + +* Appendix 1 + +Below is a set of common features used by built-in major mode. + +Basic tokens: + +delimiter ,.; (delimit things) +operator == != || (produces a value) +bracket []{}() +misc-punctuation (other punctuation that you want to highlight) + +constant true, false, null +number +keyword +comment (includes doc-comments) +string (includes chars and docstrings) +string-interpolation f"text {variable}" +escape-sequence "\n\t\\" +function every function identifier +variable every variable identifier +type every type identifier +property a.b <--- highlight b +key { a: b, c: d } <--- highlight a, c +error highlight parse error + +Abstract features: + +assignment: the LHS of an assignment (thing being assigned to), eg: + +a = b <--- highlight a +a.b = c <--- highlight b +a[1] = d <--- highlight a + +definition: the thing being defined, eg: + +int a(int b) { <--- highlight a + return 0 +} + +int a; <-- highlight a + +struct a { <--- highlight a + int b; <--- highlight b +} diff --git a/configure.ac b/configure.ac index 47e5227a148..1097be48e26 100644 --- a/configure.ac +++ b/configure.ac @@ -5040,8 +5040,8 @@ If you really want to try it anyway, use the configure option fi if test "${with_native_compilation}" != "no"; then - if test "${HAVE_PDUMPER}" = no; then - AC_MSG_ERROR(['--with-native-compilation' requires '--with-dumping=pdumper']) + if test "$with_unexec" = yes; then + AC_MSG_ERROR(['--with-native-compilation' is not compatible with unexec]) fi if test "${HAVE_ZLIB}" = no; then AC_MSG_ERROR(['--with-native-compilation' requires zlib]) diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index f5bbc4d65c0..7d49e28d11f 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -2283,16 +2283,25 @@ buffer, but doesn't select any of them. @kindex M-, @findex xref-go-back - To go back to places @emph{from where} you've displayed the definition, -use @kbd{M-,} (@code{xref-go-back}). It jumps back to the + To go back to places @emph{from where} you've displayed the +definition, use @kbd{M-,} (@code{xref-go-back}). It jumps back to the point of the last invocation of @kbd{M-.}. Thus you can find and examine the definition of something with @kbd{M-.} and then return to -where you were with @kbd{M-,}. +where you were with @kbd{M-,}. @kbd{M-,} allows you to retrace the +steps you made forward in the history of places, all the way to the +first place in history, where you first invoked @kbd{M-.}, or to any +place in-between. @kindex C-M-, @findex xref-go-forward - If you previously went back too far with @kbd{M-,}, @kbd{C-M-,} -(@code{xref-go-forward}) can be used to go forward again. + If you previously went back too far with @kbd{M-,}, or want to +re-examine a place from which you went back, you can use @kbd{C-M-,} +(@code{xref-go-forward}) to go forward again. This is similar to +using @kbd{M-.}, except that you don't need on each step to move point +to the identifier whose definition you want to look up. @kbd{C-M-,} +allows you to retrace all the steps you made back in the history of +places, all the way to the last place in history, where you invoked +@kbd{M-,}, or to any place in-between. @findex xref-etags-mode Some major modes install @code{xref} support facilities that might diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi index d993b7b071f..7a2bc11d03c 100644 --- a/doc/emacs/package.texi +++ b/doc/emacs/package.texi @@ -558,29 +558,6 @@ regular package listing. If you just wish to clone the source of a package, without adding it to the package list, use @code{package-vc-checkout}. -@vindex package-vc-selected-packages -@findex package-vc-install-selected-packages - An alternative way to use @code{package-vc-install} is via the -@code{package-vc-selected-packages} user option. This is an alist of -packages to install, where each key is a package name and the value is -@code{nil}, indicating that any revision is to install, a string, -indicating a specific revision or a package specification plist. The -side effect of setting the user option is to install the package, but -the process can also be manually triggered using the function -@code{package-vc-install-selected-packages}. Here is an example of -how the user option: - -@example -@group -(setopt package-vc-selected-packages - '((modus-themes . "0f39eb3fd9") ;specific revision - (auctex . nil) ;any revision - (foo ;a package specification - :url "https://git.sv.gnu.org/r/foo-mode.git" - :branch "trunk"))) -@end group -@end example - @findex package-report-bug @findex package-vc-prepare-patch With the source checkout, you might want to reproduce a bug against diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index 7876780dcd4..c17c8a2dc3f 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -1438,6 +1438,18 @@ If there was previously no binding for @var{key} in @var{keymap}, the new binding is added at the beginning of @var{keymap}. The order of bindings in a keymap makes no difference for keyboard input, but it does matter for menu keymaps (@pxref{Menu Keymaps}). +@end defun + +@findex keymap-unset +@defun keymap-unset keymap key &optional remove +This function is the inverse of @code{keymap-set}, it unsets the +binding for @var{key} in @var{keymap}, which is the same as setting +the binding to @code{nil}. In order to instead remove the binding +completely, specify @var{remove} as non-@code{nil}. This only makes a +difference if @var{keymap} has a parent keymap: if you just unset a key +in a child map, it will still shadow the same key in the parent +keymap; using @var{remove} instead will allow the key in the parent keymap +to be used. @end defun This example creates a sparse keymap and makes a number of diff --git a/doc/lispref/objects.texi b/doc/lispref/objects.texi index 2fe7e6db560..ad079e0d63a 100644 --- a/doc/lispref/objects.texi +++ b/doc/lispref/objects.texi @@ -466,19 +466,20 @@ You can specify characters by their Unicode values. @code{?\u@var{xxxx}} and @code{?\U@var{xxxxxxxx}} represent code points @var{xxxx} and @var{xxxxxxxx}, respectively, where each @var{x} is a single hexadecimal digit. For example, @code{?\N@{U+E0@}}, -@code{?\u00e0} and @code{?\U000000E0} are all equivalent to @code{?à} -and to @samp{?\N@{LATIN SMALL LETTER A WITH GRAVE@}}. The Unicode -Standard defines code points only up to @samp{U+@var{10ffff}}, so if -you specify a code point higher than that, Emacs signals an error. +@code{?\u00e0} and @code{?\U000000E0} are all equivalent to +@code{?@`a} and to @samp{?\N@{LATIN SMALL LETTER A WITH GRAVE@}}. The +Unicode Standard defines code points only up to @samp{U+@var{10ffff}}, +so if you specify a code point higher than that, Emacs signals an +error. @item You can specify characters by their hexadecimal character codes. A hexadecimal escape sequence consists of a backslash, @samp{x}, and the hexadecimal character code. Thus, @samp{?\x41} is the character @kbd{A}, @samp{?\x1} is the character @kbd{C-a}, and -@code{?\xe0} is the character @kbd{à} (@kbd{a} with grave accent). -You can use any number of hex digits, so you can represent any -character code in this way. +@code{?\xe0} is the character @kbd{@`a} (@kbd{a} with grave accent). +You can use one or more hex digits after @samp{x}, so you can +represent any character code in this way. @item @cindex octal character code diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index 5b53cbe310a..c6a0408abd1 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi @@ -276,9 +276,8 @@ This function returns the string that is @var{symbol}'s name. For example: @end group @end example -@strong{Warning:} Changing the string by substituting characters does -change the name of the symbol, but fails to update the obarray, so don't -do it! +@strong{Warning:} Never alter the string returned by that function. +Doing that might make Emacs dysfunctional, and might even crash Emacs. @end defun @cindex uninterned symbol, and generating Lisp code diff --git a/doc/misc/eglot.texi b/doc/misc/eglot.texi index 735da5f0163..defdf59e865 100644 --- a/doc/misc/eglot.texi +++ b/doc/misc/eglot.texi @@ -154,11 +154,11 @@ Use Eglot. Most Eglot facilities are integrated into Emacs features, such as ElDoc, Flymake, Xref, and Imenu. However, Eglot also provides -commands of its own, mainly to perform tasks by the LSP server, such -as @kbd{M-x eglot-rename} (to rename an identifier across the entire -project), @kbd{M-x eglot-format} (to reformat and reindent code), and -some others. @xref{Eglot Commands}, for the detailed list of Eglot -commands. +commands of its own, mainly to perform tasks by the language server, +such as @kbd{M-x eglot-rename} (to rename an identifier across the +entire project), @kbd{M-x eglot-format} (to reformat and reindent +code), and some others. @xref{Eglot Commands}, for the detailed list +of Eglot commands. @item That's it! @@ -465,52 +465,10 @@ ElDoc look nicer on display. @item In addition to enabling and enhancing other features and packages, -Eglot also provides a small number of user commands based directly on -the capabilities of language servers. These commands are: - -@table @kbd -@item M-x eglot-rename -This prompts for a new name for the symbol at point, and then modifies -all the project source files to rename the symbol to the new name, -based on editing data received from the language-server. @xref{Eglot -and Buffers}, for the details of how project files are defined. - -@item M-x eglot-format -This reformats and prettifies the current active region according to -source formatting rules of the language-server. If the region is not -active, it reformats the entire buffer instead. - -@item M-x eglot-format-buffer -This reformats and prettifies the current buffer according to source -formatting rules of the language-server. - -@cindex code actions -@item M-x eglot-code-actions -@itemx M-x eglot-code-action-organize-imports -@itemx M-x eglot-code-action-quickfix -@itemx M-x eglot-code-action-extract -@itemx M-x eglot-code-action-inline -@itemx M-x eglot-code-action-rewrite -These command allow you to invoke the so-called @dfn{code actions}: -requests for the language-server to provide editing commands for -various code fixes, typically either to fix an error diagnostic or to -beautify/refactor code. For example, -@code{eglot-code-action-organize-imports} rearranges the program -@dfn{imports}---declarations of modules whose capabilities the program -uses. These commands affect all the files that belong to the -project. The command @kbd{M-x eglot-code-actions} will pop up a menu -of code applicable actions at point. -@end table - -@item M-x eglot-inlay-hints-mode -This command toggles LSP ``inlay hints'' on and off for the current -buffer. Inlay hints are small text annotations to specific parts of -the whole buffer, not unlike diagnostics, but designed to help -readability instead of indicating problems. For example, a C++ LSP -server can 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. - +Eglot also provides a number of user commands based on the +capabilities of language servers. Examples include renaming symbols +with @kbd{eglot-rename} and asking to automatically correct problems +with @kbd{eglot-code-actions}. @xref{Eglot Commands}. @end itemize Not all servers support the full set of LSP capabilities, but most of @@ -713,20 +671,44 @@ entire current buffer. This command reformats the current buffer, in the same manner as @code{eglot-format} does. +@cindex code actions @item M-x eglot-code-actions -@itemx mouse-1 -This command asks the server for any @dfn{code actions} applicable at -point. It can also be invoked by @kbd{mouse-1} clicking on -diagnostics provided by the server. - -@item M-x eglot-code-action-organize-imports +@itemx M-x eglot-code-action-organize-imports @itemx M-x eglot-code-action-quickfix @itemx M-x eglot-code-action-extract @itemx M-x eglot-code-action-inline @itemx M-x eglot-code-action-rewrite -These commands invoke specific code actions supported by the language -server. -@c FIXME: Need more detailed description of each action. +These commands allow you to invoke the so-called @dfn{code actions}: +requests for the language server to provide editing commands for +correcting, refactoring or beautifying your code. These commands may +affect more than one visited file belong to the project. + +The command @code{eglot-code-actions} asks the server if there any +code actions for any point in the buffer or contained in the active +region. If there are, you the choice to execute one of them via the +minibuffer. + +A common use of code actions is fixing the Flymake error diagnostics +issued by Eglot (@pxref{Top,,, flymake, GNU Flymake manual}). +Clicking on a diagnostic with @kbd{mouse-2} invokes +@code{eglot-code-actions-at-mouse} which pops up a menu of available +code actions. The variable @code{eglot-diagnostics-map} can be used +to control the mouse binding. + +Other commands execute a specific code action. For example, +@code{eglot-code-action-organize-imports} rearranges the program's +@dfn{imports}---declarations of modules whose capabilities the program +uses. + +@cindex inlay hints +@item M-x eglot-inlay-hints-mode +This command toggles LSP @dfn{inlay hints} on and off for the current +buffer. Inlay hints are small text annotations to specific parts of +the whole buffer, not unlike diagnostics, but designed to help +readability instead of indicating problems. For example, a C++ +language server can 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. @end ftable The following Eglot commands are used less commonly, mostly for @@ -968,7 +950,7 @@ mechanism. @cindex progress @item eglot-report-progress Set this variable to true if you'd like progress notifications coming -from the LSP server to be handled as Emacs's progress reporting +from the language server to be handled as Emacs's progress reporting facilities. @end table @@ -977,9 +959,9 @@ facilities. Though many language servers work well out-of-the-box, most allow fine-grained control of their operation via specific configuration -options that vary from server to server. A small number of servers -require such special configuration to work acceptably, or even to work -at all. +options that are transmitted over the LSP protocol and vary from +server to server. A small number of servers require such special +configuration to work acceptably, or even to work at all. After having setup a server executable program in @code{eglot-server-programs} (@pxref{Setting Up LSP Servers}) and @@ -1016,8 +998,9 @@ server reads the file @file{~/.config/pycodestyle} for user configuration. The @command{clangd} C/C++ server reads both @file{~/.config/clangd/config.yaml} for user configuration and @file{.clangd} for project configuration. It may be advantageous to -use these mechanisms instead of Eglot's, as the latter have the -advantage of working with other LSP clients. +use these mechanisms instead of Eglot's, as this will probably work +with other LSP clients and may be easier to debug than options riding +on the LSP wire. @node Project-specific configuration @section Project-specific configuration @@ -1078,10 +1061,11 @@ plists. Some examples are useful. Let's say you want to configure two language servers to be used in a project written in a combination of the Python and Go languages. You -want to use the @command{pylsp} and @command{gopls} LSP servers. In -the documentation of the servers in question (or in some other editor's -configuration file, or in some blog article), you find the following -configuration options in informal dotted-notation syntax: +want to use the @command{pylsp} and @command{gopls} languages +servers. In the documentation of the servers in question (or in some +other editor's configuration file, or in some blog article), you find +the following configuration options in informal dotted-notation +syntax: @example pylsp.plugins.jedi_completion.include_params: true @@ -1201,7 +1185,7 @@ the LSP handshake. This is done using the The argument @code{(:compilationDatabasePath "/tmp")} is Emacs's representation in plist format of a simple JSON object @code{@{"compilationDatabasePath": "/tmp"@}}. To learn how to -represent more deeply nested options in this format, @xref{JSONRPC +represent more deeply nested options in this format, @pxref{JSONRPC objects in Elisp}. In this case, the two examples achieve exactly the same, but notice @@ -1214,7 +1198,7 @@ supported. It consists of @emph{globally} setting @code{eglot-workspace-configuration}, a variable originally intended for project-specific configuration. This has the same effect as giving all your projects a certain default configuration, as described -in @xref{Project-specific configuration}. Here is an example. +in @ref{Project-specific configuration}. Here is an example: @lisp (setq-default eglot-workspace-configuration @@ -1241,17 +1225,21 @@ keyword-value property sub-plists corresponding to JSON sub-objects. For representing the JSON leaf values @code{true}, @code{false}, @code{null} and @code{@{@}}, you can use the Lisp values @code{t}, @code{:json-false}, @code{nil}, and @code{eglot-@{@}}, respectively. +JSON arrays are represented as Elisp vectors surrounded by square brackets +(@pxref{Vectors,,,elisp,GNU Emacs Lisp Reference Manual}). -For example, this plist: +For example, the plist @lisp (:pylsp (:plugins (:jedi_completion (:include_params t - :fuzzy t) - :pylint (:enabled :json-false))) + :fuzzy t + :cache_for ["pandas" "numpy"] + :pylint (:enabled :json-false)))) :gopls (:usePlaceholders t)) @end lisp -Is serialized by Eglot to the following JSON text: +@noindent +is serialized by Eglot to the following JSON text: @example @{ @@ -1259,7 +1247,8 @@ Is serialized by Eglot to the following JSON text: "plugins": @{ "jedi_completion": @{ "include_params": true, - "fuzzy": true + "fuzzy": true, + "cache_for": [ "pandas", "numpy" ], @}, "pylint": @{ "enabled": false @@ -1286,53 +1275,104 @@ pop up special buffers that can be used to inspect the communications between the Eglot and language server. In many cases, this will indicate the problems or at least provide a hint. +@cindex performance A common and easy-to-fix cause of performance problems is the length -of these two buffers. If Eglot is operating correctly but slowly, -customize the variable @code{eglot-events-buffer-size} (@pxref{Eglot -Variables}) to limit logging, and thus speed things up. +of the Eglot events buffer because it represent additional work that +Eglot must do. After verifying Eglot is operating correctly but +slowly, try to customize the variable @code{eglot-events-buffer-size} +(@pxref{Eglot Variables}) to 0. This will disable any debug logging +and may speed things up. -If you need to report an Eglot bug, please keep in mind that, because -there are so many variables involved, it is generally both very -@emph{difficult} and @emph{absolutely essential} to reproduce bugs -exactly as they happened to you, the user. Therefore, every bug -report should include: +In other situations, the cause of poor performance lies in the +language server itself. Servers use aggressive caching and other +techniques to improve their performance. Often, this can be tweaked +by changing the server configuration (@pxref{Advanced server +configuration}). + +If you think you have found a bug, we want to hear about it. Before +reporting a bug, keep in mind that interaction with language servers +represents a large quantity of unknown variables. Therefore, it is +generally both @emph{difficult} and @emph{absolutely essential} that +the maintainers reproduce bugs exactly as they happened to you, the +user. + +To report an Eglot bug, send e-mail to @email{bug-gnu-emacs@@gnu.org}. + +Get acquainted with Emacs's bug reporting guidelines (@pxref{Bugs,,, +emacs, GNU Emacs Manual}). Then, follow this checklist specific to +Eglot bug rerpots. @enumerate @item -The transcript of events obtained from the buffer popped up by -@kbd{M-x eglot-events-buffer}. If the transcript can be narrowed down -to show the problematic exchange, so much the better. This is -invaluable for the investigation and reproduction of the problem. +Include the transcript of JSONRPC events obtained from the buffer +popped up by @kbd{M-x eglot-events-buffer}. You may narrow down the +transcript if you are sure of where the problematic exchange is, but +it's safer to include the whole transcript, either attached or inline. @item If Emacs signaled an error (an error message was seen or heard), make -sure to repeat the process after toggling @code{debug-on-error} on -(via @kbd{M-x toggle-debug-on-error}). This normally produces a -backtrace of the error that should also be attached to the bug report. +sure to repeat the process after turning on @code{debug-on-error} via +@kbd{M-x toggle-debug-on-error}. This normally produces a backtrace +of the error that should also be attached to the bug report. @item -An explanation of how to obtain, install, and configure the language -server you used. If possible, try to replicate the problem with the -C/C@t{++} or Python servers, as these are very easy to install. +Include a description of how the maintainer should obtain, install, +and configure the language server you used. Maintainers usually have +access to GNU/Linux systems, though not necessarily the distribution +that you may be using. If possible, try to replicate the problem with +the C/C@t{++} or Python servers, as these are very easy to install. @item -A description of how to setup the @emph{minimal} project (one or two -files and their contents) where the problem happens. +Describe how to setup a @emph{minimal} project directory where Eglot +should be started for the problem to happen. Describe each file's +name and its contents. Alternatively, you can supply the address of a +public Git repository. @item -A recipe to replicate the problem with @emph{a clean Emacs run}. This -means @kbd{emacs -Q} invocation or a very minimal (no more that 10 -lines) @file{.emacs} initialization file. @code{eglot-ensure} and -@code{use-package} calls are generally @emph{not} needed. +Include versions of the software used. The Emacs version can be +obtained with @kbd{M-x emacs-version}. + +It's also essential to include the version of ELPA packages that are +explicitly or implicitly loaded. The optional but popular Company or +Markdown packages are distributed as GNU ELPA packages, not to mention +Eglot itself in some situations. Some major modes (Go, Rust, etc.) +are provided by ELPA packages. It's sometimes easy to miss these, +since they are usually implicitly loaded when visiting a file in that +language. + +ELPA packages usually live in @code{~/.emacs.d/elpa} (or what is in +@code{package-user-dir}). Please show the listing of files in that +directory as well. @item -Make sure to double check all the above elements and re-run the -recipe to see that the problem is reproducible. +Include a recipe to replicate the problem with @emph{a clean Emacs +run}. This means @kbd{emacs -Q -f package-initialize} invocation +which starts Emacs with no configuration and initializes the ELPA +packages. A very minimal (no more that 10 lines) @file{.emacs} +initialization file is also acceptable and good means to describe +changes to variables. + +There is usually no need to include @kbd{require} statements in the +recipe, as Eglot's functionality uses autoloads. + +Likewise, there is rarely the need to use things like +@code{use-package} or @code{eglot-ensure}. This just makes the recipe +harder to follow. Prefer setting variables with @code{setq} and +adding to hooks with @code{add-hook}. Prefer starting Eglot with +@code{M-x eglot}. + +@item +Make sure to double check all the above elements and re-run the recipe +to see that the problem is reproducible. Following the recipe should +produce event transcript and error backtraces that are exactly the +same or very similar to the ones you included. If the problem only +happens sometimes, include this information in your bug report. @end enumerate Please keep in mind that some problems reported against Eglot may actually be bugs in the language server or the Emacs feature/package -that used Eglot to communicate with the language server. +that used Eglot to communicate with the language server. Eglot is, in +many cases, just a frontend to that functionality. @node GNU Free Documentation License @appendix GNU Free Documentation License diff --git a/doc/misc/idlwave.texi b/doc/misc/idlwave.texi index 3ec07fb4a50..10fc4c85c7b 100644 --- a/doc/misc/idlwave.texi +++ b/doc/misc/idlwave.texi @@ -1372,10 +1372,9 @@ among, with differing advantages and disadvantages. The variable to (as long as @code{idlwave-help-use-assistant} is not set). This function is used to set the variable @code{browse-url-browser-function} locally for IDLWAVE help only. Customize the latter variable to see -what choices of browsers your system offers. Certain browsers like -@code{w3} (bundled with many versions of Emacs) and @code{w3m} -(@uref{http://emacs-w3m.namazu.org/}) are run within Emacs, and use -Emacs buffers to display the HTML help. This can be convenient, +what choices of browsers your system offers. Certain browsers like EWW +(@pxref{Top, EWW,, eww, The Emacs Web Wowser Manual}) are run within Emacs, +and use Emacs buffers to display the HTML help. This can be convenient, especially on small displays, and images can even be displayed in-line on newer Emacs versions. However, better formatting results are often achieved with external browsers, like Mozilla. IDLWAVE assumes any diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index acf32726895..6f14fc875f4 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -1247,6 +1247,7 @@ syntax requires a leading volume (share) name, for example: @item @option{dav} @item @option{davs} +@cindex WebDAV @cindex method @option{dav} @cindex method @option{davs} @cindex @option{dav} method @@ -2758,32 +2759,32 @@ allows you to set the @option{ControlPath} provided the variable Note how @samp{%r}, @samp{%h} and @samp{%p} must be encoded as @samp{%%r}, @samp{%%h} and @samp{%%p}. -@vindex tramp-use-ssh-controlmaster-options +@vindex tramp-use-connection-share Using a predefined string in @code{tramp-ssh-controlmaster-options}, or puzzling an own string, happens only when user option -@code{tramp-use-ssh-controlmaster-options} is set to @code{t}. If the +@code{tramp-use-connection-share} is set to @code{t}. If the @file{~/.ssh/config} file is configured appropriately for the above behavior, then any changes to @command{ssh} can be suppressed with this @code{nil} setting: @lisp -(customize-set-variable 'tramp-use-ssh-controlmaster-options nil) +(customize-set-variable 'tramp-use-connection-share nil) @end lisp Sometimes, it is not possible to use OpenSSH's @option{ControlMaster} option for remote processes. This could result in concurrent access to the OpenSSH socket when reading data by different processes, which could block Emacs. In this case, setting -@code{tramp-use-ssh-controlmaster-options} to @code{suppress} disables -shared access. It is not needed to set this user option permanently -to @code{suppress}, binding the user option prior calling +@code{tramp-use-connection-share} to @code{suppress} disables shared +access. It is not needed to set this user option permanently to +@code{suppress}, binding the user option prior calling @code{make-process} is sufficient. @value{tramp} does this for esxample for compilation processes on its own. @vindex ProxyCommand@r{, ssh option} @vindex ProxyJump@r{, ssh option} -@code{tramp-use-ssh-controlmaster-options} should also be set to -@code{nil} or @code{suppress} if you use the @option{ProxyCommand} or +@code{tramp-use-connection-share} should also be set to @code{nil} or +@code{suppress} if you use the @option{ProxyCommand} or @option{ProxyJump} options in your @command{ssh} configuration. In order to use the @option{ControlMaster} option, @value{tramp} must @@ -2806,12 +2807,16 @@ Host * Check the @samp{ssh_config(5)} man page whether these options are supported on your proxy host. -On MS Windows, @code{tramp-use-ssh-controlmaster-options} is set to -@code{nil} by default, because the MS Windows and MSYS2 -implementations of @command{OpenSSH} do not support this option properly. +On MS Windows, @code{tramp-use-connection-share} is set to @code{nil} +by default, because the MS Windows and MSYS2 implementations of +@command{OpenSSH} do not support this option properly. -In PuTTY, you can achieve connection sharing in the @option{Connection/SSH} -entry, enabling the @option{Share SSH connections if possible} option. +In PuTTY, you can achieve connection sharing in the +@option{Connection/SSH} entry, enabling the @option{Share SSH +connections if possible} option. @code{tramp-use-connection-share} +must be set to @code{nil}. If @code{tramp-use-connection-share} is +set to @code{t} or @code{suppress}, @command{plink} is called with the +option @option{-share} or @option{-noshare}, respectively. @subsection Configure direct copying between two remote servers @@ -4300,9 +4305,9 @@ It does not use @code{tramp-remote-path}. In order to gain even more performance, it is recommended to bind @code{tramp-verbose} to 0 when running @code{make-process} or @code{start-file-process}. Furthermore, you might set -@code{tramp-use-ssh-controlmaster-options} to @code{nil} in order to -bypass @value{tramp}'s handling of the @option{ControlMaster} options, -and use your own settings in @file{~/.ssh/config}, @ref{Using ssh +@code{tramp-use-connection-share} to @code{nil} in order to bypass +@value{tramp}'s handling of the @option{ControlMaster} options, and +use your own settings in @file{~/.ssh/config}, @ref{Using ssh connection sharing}. diff --git a/etc/NEWS b/etc/NEWS index 5915ca7e74a..0064d7f95c4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -203,10 +203,12 @@ point is not in a comment or a string. It is by default bound to This allows accessing system containers provided by Toolbox. +++ -*** New value 'suppress' for user option 'tramp-use-ssh-controlmaster-options'. -This user option allows now the values t, nil, and 'suppress'. The -latter suppresses also "ControlMaster" settings in the user's -"~/.ssh/config" file. +*** Rename 'tramp-use-ssh-controlmaster-options' to 'tramp-use-connection-share. +The old name still exists as defvaralias. This user option controls +now connection sharing for both ssh-based and plink-based methods. It +allows the values t, nil, and 'suppress'. The latter suppresses +also "ControlMaster" settings in the user's "~/.ssh/config" file, +or connection share configuration in PuTTY sessions, respectively. ** EWW diff --git a/etc/NEWS.29 b/etc/NEWS.29 index a5f9f8c6ec1..0b651f7a519 100644 --- a/etc/NEWS.29 +++ b/etc/NEWS.29 @@ -2540,8 +2540,16 @@ the project by a VC project based on that VCS. +++ *** New command 'xref-go-forward'. -It is bound to 'C-M-,' and jumps to the location where 'xref-go-back' -('M-,', also known as 'xref-pop-marker-stack') was invoked previously. +It is bound to 'C-M-,' and jumps to the location where you previously +invoked 'xref-go-back' ('M-,', also known as 'xref-pop-marker-stack'). + ++++ +*** The depth of the Xref marker stack is now infinite. +The implementation of the Xref marker stack was changed in a way that +allows as many places to be saved on the stack as needed, limited only +by the available memory. Therefore, the variables +'find-tag-marker-ring-length' and 'xref-marker-ring-length' are now +obsolete and unused; setting them has no effect. +++ *** 'xref-query-replace-in-results' prompting change. diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS index d610a63b09d..5f92c056018 100644 --- a/etc/ORG-NEWS +++ b/etc/ORG-NEWS @@ -332,7 +332,7 @@ When the block type starts from the upper case, structure template will now insert =#+BEGIN_TYPE=. Previously, lower-case =#+begin_type= was inserted unconditionally. *** New ox-latex tabbing support for tables. -Latex tables can now be exported to the latex tabbing environment +LaTeX tables can now be exported to the latex tabbing environment tabbing environment]]. This is done by adding =#+ATTR_LATEX: :mode tabbing= at the top of the table. @@ -4284,7 +4284,7 @@ parameters specific to some pre-defined translators, e.g., ~:environment~ and ~:booktabs~ for ~orgtbl-to-latex~. See translators docstrings (including ~orgtbl-to-generic~) for details. -*** Non-floating minted listings in Latex export +*** Non-floating minted listings in LaTeX export It is not possible to specify =#+attr_latex: :float nil= in conjunction with source blocks exported by the minted package. @@ -6540,7 +6540,7 @@ that Calc formulas can operate on them. *** Hyperlinks -**** Org-Bibtex -- major improvements +**** Org-BibTeX -- major improvements Provides support for managing bibtex bibliographical references data in headline properties. Each headline corresponds to a diff --git a/lisp/abbrev.el b/lisp/abbrev.el index ef8ef1ab5a6..1a665efb0a5 100644 --- a/lisp/abbrev.el +++ b/lisp/abbrev.el @@ -1250,17 +1250,17 @@ which see." ;; asked to. (and save-abbrevs abbrevs-changed - (progn - (if (or arg - (eq save-abbrevs 'silently) - (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name))) - (progn - (write-abbrev-file nil) - nil) - ;; Don't keep bothering user if they say no. - (setq abbrevs-changed nil) - ;; Inhibit message in `save-some-buffers'. - t))))) + (prog1 + (if (or arg + (eq save-abbrevs 'silently) + (y-or-n-p (format "Save abbrevs in %s? " abbrev-file-name))) + (progn + (write-abbrev-file nil) + nil) + ;; Inhibit message in `save-some-buffers'. + t) + ;; Don't ask again whether saved or user said no. + (setq abbrevs-changed nil))))) (add-hook 'save-some-buffers-functions #'abbrev--possibly-save) diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el index ea2766b8dc4..253b35f1f1a 100644 --- a/lisp/emacs-lisp/package-vc.el +++ b/lisp/emacs-lisp/package-vc.el @@ -48,7 +48,6 @@ ;;; Code: (eval-when-compile (require 'rx)) -(eval-when-compile (require 'inline)) (eval-when-compile (require 'map)) (eval-when-compile (require 'cl-lib)) (require 'package) @@ -139,7 +138,6 @@ the `clone' function." (package-desc-create :name name :kind 'vc)) spec))))))) -;;;###autoload (defcustom package-vc-selected-packages '() "List of packages that must be installed. Each member of the list is of the form (NAME . SPEC), where NAME @@ -174,13 +172,9 @@ is a symbol designating the package and SPEC is one of: All other keys are ignored. -This user option differs from `package-selected-packages' in that -it is meant to be specified manually. If you want to install all -the packages in the list, you cal also use -`package-vc-install-selected-packages'. - -Note that this option will not override an existing source -package installation or revert the checked out revision." +This user option will be automatically updated to store package +specifications for packages that are not specified in any +archive." :type '(alist :tag "List of packages you want to be installed" :key-type (symbol :tag "Package") :value-type @@ -191,10 +185,6 @@ package installation or revert the checked out revision." (:lisp-dir string) (:main-file string) (:vc-backend symbol))))) - :initialize #'custom-initialize-default - :set (lambda (sym val) - (custom-set-default sym val) - (package-vc-install-selected-packages)) :version "29.1") (defvar package-vc--archive-spec-alist nil @@ -224,19 +214,17 @@ All other values are ignored.") The optional argument NAME can be used to override the default name for PKG-DESC." (alist-get - (or name (package-desc-name pkg-desc)) - (if (package-desc-archive pkg-desc) + (setq name (or name (package-desc-name pkg-desc))) + (if (and (package-desc-archive pkg-desc) + (not (alist-get name package-vc-selected-packages + nil nil #'string=))) (alist-get (intern (package-desc-archive pkg-desc)) package-vc--archive-spec-alist) - (apply #'append (mapcar #'cdr package-vc--archive-spec-alist))) - nil nil #'string=)) - -(define-inline package-vc--query-spec (pkg-desc prop) - "Query the property PROP for the package specification of PKG-DESC. -If no package specification can be determined, the function will -return nil." - (inline-letevals (pkg-desc prop) - (inline-quote (plist-get (package-vc--desc->spec ,pkg-desc) ,prop)))) + ;; Consult both our local list of package specifications, as well + ;; as the lists provided by the archives. + (apply #'append (cons package-vc-selected-packages + (mapcar #'cdr package-vc--archive-spec-alist)))) + '() nil #'string=)) (defun package-vc--read-archive-data (archive) "Update `package-vc--archive-spec-alist' for ARCHIVE. @@ -309,12 +297,11 @@ asynchronously." (directory (file-name-concat (or (package-desc-dir pkg-desc) (expand-file-name name package-user-dir)) - (and-let* ((extras (package-desc-extras pkg-desc))) - (alist-get :lisp-dir extras)))) - (file (or (plist-get pkg-spec :main-file) - (expand-file-name - (concat name ".el") - directory)))) + (plist-get pkg-spec :lisp-dir))) + (file (expand-file-name + (or (plist-get pkg-spec :main-file) + (concat name ".el")) + directory))) (if (file-exists-p file) file ;; The following heuristic is only necessary when fetching a ;; repository with URL that would break the above assumptions. @@ -495,12 +482,12 @@ documentation and marking the package as installed." missing))) (let ((default-directory (file-name-as-directory pkg-dir)) - (pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir))) + (pkg-file (expand-file-name (package--description-file pkg-dir) pkg-dir)) + (pkg-spec (package-vc--desc->spec pkg-desc))) ;; Generate autoloads (let* ((name (package-desc-name pkg-desc)) (auto-name (format "%s-autoloads.el" name)) - (extras (package-desc-extras pkg-desc)) - (lisp-dir (alist-get :lisp-dir extras))) + (lisp-dir (plist-get pkg-spec :lisp-dir))) (package-generate-autoloads name (file-name-concat pkg-dir lisp-dir)) (when lisp-dir @@ -520,8 +507,7 @@ documentation and marking the package as installed." (package-vc--generate-description-file pkg-desc pkg-file) ;; Detect a manual - (when-let ((pkg-spec (package-vc--desc->spec pkg-desc)) - ((executable-find "install-info"))) + (when (executable-find "install-info") (dolist (doc-file (ensure-list (plist-get pkg-spec :doc))) (package-vc--build-documentation pkg-desc doc-file)))) @@ -584,7 +570,6 @@ attribute in PKG-SPEC." (unless (file-exists-p dir) (make-directory (file-name-directory dir) t) (let ((backend (or (plist-get pkg-spec :vc-backend) - (package-vc--query-spec pkg-desc :vc-backend) (package-vc--guess-backend url) (plist-get (alist-get (package-desc-archive pkg-desc) package-vc--archive-data-alist @@ -659,9 +644,14 @@ abort installation?" name)) ;; file system or between installations. (throw 'done (setq lisp-dir name))))) - (when lisp-dir - (push (cons :lisp-dir lisp-dir) - (package-desc-extras pkg-desc))) + ;; Ensure we have a copy of the package specification + (unless (equal (alist-get name (mapcar #'cdr package-vc--archive-spec-alist)) pkg-spec) + (customize-save-variable + 'package-vc-selected-packages + (cons (cons name pkg-spec) + (seq-remove (lambda (spec) (string= name (car spec))) + package-vc-selected-packages)))) + (package-vc--unpack-1 pkg-desc pkg-dir))) (defun package-vc--read-package-name (prompt &optional allow-url installed) diff --git a/lisp/eshell/em-dirs.el b/lisp/eshell/em-dirs.el index eb679b80cb5..4bc6342d422 100644 --- a/lisp/eshell/em-dirs.el +++ b/lisp/eshell/em-dirs.el @@ -253,11 +253,17 @@ Thus, this does not include the current directory.") (throw 'eshell-replace-command (eshell-parse-command "cd" (flatten-tree args))))) +(defun eshell-expand-user-reference (file) + "Expand a user reference in FILE to its real directory name." + (replace-regexp-in-string + (rx bos (group "~" (*? anychar)) (or "/" eos)) + #'expand-file-name file)) + (defun eshell-parse-user-reference () "An argument beginning with ~ is a filename to be expanded." (when (and (not eshell-current-argument) - (eq (char-after) ?~)) - (add-to-list 'eshell-current-modifiers 'expand-file-name) + (eq (char-after) ?~)) + (add-to-list 'eshell-current-modifiers #'eshell-expand-user-reference) (forward-char) (char-to-string (char-before)))) diff --git a/lisp/frame.el b/lisp/frame.el index b62074d6263..ba5d1caafa2 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -239,7 +239,8 @@ that's not the whole story: see `after-focus-change-function'." This function runs the abnormal hook `move-frame-functions'." (interactive "e") (let ((frame (posn-window (event-start event)))) - (run-hook-with-args 'move-frame-functions frame))) + (when (frame-live-p frame) ;Experience shows it can die in the meantime. + (run-hook-with-args 'move-frame-functions frame)))) ;;;; Arrangement of frames at startup diff --git a/lisp/htmlfontify.el b/lisp/htmlfontify.el index a06387687b9..6c303226e54 100644 --- a/lisp/htmlfontify.el +++ b/lisp/htmlfontify.el @@ -758,7 +758,9 @@ may happen." 255)) '(0 1 2)))))) -(defun hfy-family (family) (list (cons "font-family" family))) +(defun hfy-family (family) + (list (cons "font-family" + (format "\"%s\"" (string-replace "\"" "\\\\\"" family))))) (defun hfy-bgcol (color) (list (cons "background" (hfy-triplet color)))) (defun hfy-color (color) (list (cons "color" (hfy-triplet color)))) (define-obsolete-function-alias 'hfy-colour #'hfy-color "27.1") diff --git a/lisp/international/textsec.el b/lisp/international/textsec.el index 1540f806e3b..e69e7c19842 100644 --- a/lisp/international/textsec.el +++ b/lisp/international/textsec.el @@ -320,7 +320,8 @@ affected by bidi controls in STRING." ;; state at end of STRING which could then affect the following ;; text. (insert string "a1א:!") - (let ((pos (bidi-find-overridden-directionality 1 (point-max) nil))) + (let ((pos (bidi-find-overridden-directionality + (point-min) (point-max) nil))) (and (fixnump pos) (1- pos))))) diff --git a/lisp/mpc.el b/lisp/mpc.el index db1da2ac030..b937a6b5945 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -1104,7 +1104,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (interactive) (mpc-constraints-push 'noerror) (mpc-constraints-restore - ',(list (list tag text))))))))) + (list (list tag text))))))))) (funcall insert (concat (when size (propertize " " 'display diff --git a/lisp/net/tramp-integration.el b/lisp/net/tramp-integration.el index 3ef4b55acd3..5b3259eab03 100644 --- a/lisp/net/tramp-integration.el +++ b/lisp/net/tramp-integration.el @@ -53,7 +53,7 @@ (defvar shortdoc--groups) (defvar tramp-current-connection) (defvar tramp-postfix-host-format) -(defvar tramp-use-ssh-controlmaster-options) +(defvar tramp-use-connection-share) ;;; Fontification of `read-file-name': @@ -302,7 +302,7 @@ NAME must be equal to `tramp-current-connection'." ;; Bug#45518. So we don't use ssh ControlMaster options. (defun tramp-compile-disable-ssh-controlmaster-options () "Don't allow ssh ControlMaster while compiling." - (setq-local tramp-use-ssh-controlmaster-options nil)) + (setq-local tramp-use-connection-share 'suppress)) (with-eval-after-load 'compile (add-hook 'compilation-mode-hook diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 875ad096ad6..24e90447b24 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -106,21 +106,27 @@ detected as prompt when being sent on echoing hosts, therefore.") (defconst tramp-end-of-heredoc (md5 tramp-end-of-output) "String used to recognize end of heredoc strings.") -(defcustom tramp-use-ssh-controlmaster-options (not (eq system-type 'windows-nt)) - "Whether to use `tramp-ssh-controlmaster-options'. -Set it to t, if you want Tramp to apply these options. +(defcustom tramp-use-connection-share (not (eq system-type 'windows-nt)) + "Whether to use connection share in ssh or PuTTY. +Set it to t, if you want Tramp to apply respective options. These +are `tramp-ssh-controlmaster-options' for ssh, and \"-share\" for PuTTY. Set it to nil, if you use Control* or Proxy* options in your ssh configuration. Set it to `suppress' if you want to disable settings in your -\"~/.ssh/config¸\"." +\"~/.ssh/config\" file or in your PuTTY session." :group 'tramp - :version "29.2" + :version "30.1" :type '(choice (const :tag "Set ControlMaster" t) (const :tag "Don't set ControlMaster" nil) (const :tag "Suppress ControlMaster" suppress)) - ;; Check with (safe-local-variable-p 'tramp-use-ssh-controlmaster-options 'suppress) + ;; Check with (safe-local-variable-p 'tramp-use-connection-share 'suppress) :safe (lambda (val) (and (memq val '(t nil suppress)) t))) +(defvaralias 'tramp-use-connection-share 'tramp-use-ssh-controlmaster-options) +(make-obsolete-variable + 'tramp-use-ssh-controlmaster-options + "Use `tramp-use-connection-share' instead" "30.1") + (defvar tramp-ssh-controlmaster-options nil "Which ssh Control* arguments to use. @@ -130,8 +136,8 @@ If it is a string, it should have the form spec must be doubled, because the string is used as format string. Otherwise, it will be auto-detected by Tramp, if -`tramp-use-ssh-controlmaster-options' is t. The value depends on -the installed local ssh version. +`tramp-use-connection-share' is t. The value depends on the +installed local ssh version. The string is used in `tramp-methods'.") @@ -348,7 +354,7 @@ The string is used in `tramp-methods'.") (add-to-list 'tramp-methods `("plink" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%c") ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" @@ -361,7 +367,7 @@ The string is used in `tramp-methods'.") (add-to-list 'tramp-methods `("plinkx" (tramp-login-program "plink") - (tramp-login-args (("-load") ("%h") ("-t") ("\"") + (tramp-login-args (("-load") ("%h") ("%c") ("-t") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" tramp-terminal-type @@ -373,7 +379,7 @@ The string is used in `tramp-methods'.") (add-to-list 'tramp-methods `("pscp" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%c") ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" @@ -391,7 +397,7 @@ The string is used in `tramp-methods'.") (add-to-list 'tramp-methods `("psftp" (tramp-login-program "plink") - (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") + (tramp-login-args (("-l" "%u") ("-P" "%p") ("-ssh") ("%c") ("-t") ("%h") ("\"") (,(format "env 'TERM=%s' 'PROMPT_COMMAND=' 'PS1=%s'" @@ -403,7 +409,7 @@ The string is used in `tramp-methods'.") (tramp-remote-shell-args ("-c")) (tramp-copy-program "pscp") (tramp-copy-args (("-l" "%u") ("-P" "%p") ("-sftp") - ("-p" "%k") ("-q"))) + ("-p" "%k"))) (tramp-copy-keep-date t))) (add-to-list 'tramp-methods `("fcp" @@ -4839,12 +4845,19 @@ Goes through the list `tramp-inline-compress-commands'." "Return the Control* arguments of the local ssh." (cond ;; No options to be computed. - ((or (null tramp-use-ssh-controlmaster-options) + ((or (null tramp-use-connection-share) (null (assoc "%c" (tramp-get-method-parameter vec 'tramp-login-args)))) "") + ;; Use plink option. + ((string-match-p + (rx "plink" (? ".exe") eol) + (tramp-get-method-parameter vec 'tramp-login-program)) + (if (eq tramp-use-connection-share 'suppress) + "-noshare" "-share")) + ;; There is already a value to be used. - ((and (eq tramp-use-ssh-controlmaster-options t) + ((and (eq tramp-use-connection-share t) (stringp tramp-ssh-controlmaster-options)) tramp-ssh-controlmaster-options) @@ -4854,18 +4867,18 @@ Goes through the list `tramp-inline-compress-commands'." (when (tramp-ssh-option-exists-p vec "ControlMaster=auto") (concat "-o ControlMaster=" - (if (eq tramp-use-ssh-controlmaster-options 'suppress) + (if (eq tramp-use-connection-share 'suppress) "no" "auto") " -o ControlPath=" - (if (eq tramp-use-ssh-controlmaster-options 'suppress) + (if (eq tramp-use-connection-share 'suppress) "none" ;; Hashed tokens are introduced in OpenSSH 6.7. (if (tramp-ssh-option-exists-p vec "ControlPath=tramp.%C") "tramp.%%C" "tramp.%%r@%%h:%%p")) ;; ControlPersist option is introduced in OpenSSH 5.6. - (when (and (not (eq tramp-use-ssh-controlmaster-options 'suppress)) + (when (and (not (eq tramp-use-connection-share 'suppress)) (tramp-ssh-option-exists-p vec "ControlPersist=no")) " -o ControlPersist=no"))))))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 6e2c895a6bf..6eff5b2ca60 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -685,7 +685,7 @@ See also `tramp-yn-prompt-regexp'." :type 'regexp) (defcustom tramp-yn-prompt-regexp - (rx (| "Store key in cache? (y/n)" + (rx (| (: "Store key in cache? (y/n" (* nonl) ")") "Update cached key? (y/n, Return cancels connection)") (* blank)) "Regular expression matching all y/n queries which need to be confirmed. diff --git a/lisp/nxml/xmltok.el b/lisp/nxml/xmltok.el index c36d225c7c9..6f9df554da0 100644 --- a/lisp/nxml/xmltok.el +++ b/lisp/nxml/xmltok.el @@ -734,8 +734,13 @@ and VALUE-END, otherwise a STRING giving the value." (atts-needing-normalization nil)) (while (cond ((or (looking-at (xmltok-attribute regexp)) ;; use non-greedy group - (when (looking-at (concat "[^<>\n]+?" - (xmltok-attribute regexp))) + ;; Limit the search to 10000 characters, to + ;; avoid slowdowns due to the quadratic + ;; complexity of the regexp. See bug#61514. + (when (with-restriction + (point) (min (+ (point) 10000) (point-max)) + (looking-at (concat "[^<>\n]+?" + (xmltok-attribute regexp)))) (unless recovering (xmltok-add-error "Malformed attribute" (point) diff --git a/lisp/org/ob-latex.el b/lisp/org/ob-latex.el index 428907a270d..ce39628d642 100644 --- a/lisp/org/ob-latex.el +++ b/lisp/org/ob-latex.el @@ -141,7 +141,7 @@ exporting the literal LaTeX source." (org-trim body)) (defun org-babel-execute:latex (body params) - "Execute a block of Latex code with Babel. + "Execute a block of LaTeX code with Babel. This function is called by `org-babel-execute-src-block'." (setq body (org-babel-expand-body:latex body params)) (if (cdr (assq :file params)) @@ -180,7 +180,7 @@ This function is called by `org-babel-execute-src-block'." tmp-pdf (list org-babel-latex-pdf-svg-process) extension err-msg log-buf))) - (shell-command (format "mv %s %s" img-out out-file))))) + (rename-file img-out out-file t)))) ((string-suffix-p ".tikz" out-file) (when (file-exists-p out-file) (delete-file out-file)) (with-temp-file out-file @@ -218,17 +218,14 @@ This function is called by `org-babel-execute-src-block'." (if (string-suffix-p ".svg" out-file) (progn (shell-command "pwd") - (shell-command (format "mv %s %s" - (concat (file-name-sans-extension tex-file) "-1.svg") - out-file))) + (rename-file (concat (file-name-sans-extension tex-file) "-1.svg") + out-file t)) (error "SVG file produced but HTML file requested"))) ((file-exists-p (concat (file-name-sans-extension tex-file) ".html")) (if (string-suffix-p ".html" out-file) - (shell-command "mv %s %s" - (concat (file-name-sans-extension tex-file) - ".html") - out-file) - (error "HTML file produced but SVG file requested"))))) + (rename-file (concat (file-name-sans-extension tex-file) ".html") + out-file t) + (error "HTML file produced but SVG file requested"))))) ((or (string= "pdf" extension) imagemagick) (with-temp-file tex-file (require 'ox-latex) diff --git a/lisp/org/ol-bibtex.el b/lisp/org/ol-bibtex.el index 7d6ed85345f..fd9517233e0 100644 --- a/lisp/org/ol-bibtex.el +++ b/lisp/org/ol-bibtex.el @@ -86,8 +86,8 @@ ;; the active region, then call `org-bibtex-write' in a .org file to ;; insert a heading for the read bibtex entry ;; -;; - All Bibtex information is taken from the document compiled by -;; Andrew Roberts from the Bibtex manual, available at +;; - All BibTeX information is taken from the document compiled by +;; Andrew Roberts from the BibTeX manual, available at ;; https://www.andy-roberts.net/res/writing/latex/bibentries.pdf ;; ;;; History: @@ -99,7 +99,7 @@ ;; and then implemented by Bastien Guerry. ;; ;; Eric Schulte eventually added the functions for translating between -;; Org headlines and Bibtex entries, and for fleshing out the Bibtex +;; Org headlines and BibTeX entries, and for fleshing out the BibTeX ;; fields of existing Org headlines. ;; ;; Org mode loads this module by default - if this is not what you want, @@ -144,7 +144,7 @@ (declare-function org-search-view "org-agenda" (&optional todo-only string edit-at)) -;;; Bibtex data +;;; BibTeX data (defvar org-bibtex-types '((:article (:description . "An article from a journal or magazine") @@ -202,7 +202,7 @@ (:description . "A document having an author and title, but not formally published.") (:required :author :title :note) (:optional :month :year :doi :url))) - "Bibtex entry types with required and optional parameters.") + "BibTeX entry types with required and optional parameters.") (defvar org-bibtex-fields '((:address . "Usually the address of the publisher or other type of institution. For major publishing houses, van Leunen recommends omitting the information entirely. For small publishers, on the other hand, you can help the reader by giving the complete address.") @@ -231,7 +231,7 @@ (:url . "Uniform resource locator.") (:volume . "The volume of a journal or multi-volume book.") (:year . "The year of publication or, for an unpublished work, the year it was written. Generally it should consist of four numerals, such as 1984, although the standard styles can handle any year whose last four nonpunctuation characters are numerals, such as '(about 1984)'")) - "Bibtex fields with descriptions.") + "BibTeX fields with descriptions.") (defvar org-bibtex-entries nil "List to hold parsed bibtex entries.") @@ -439,7 +439,7 @@ at point." (error "Field:%s is not known" field)) (save-window-excursion (let* ((name (substring (symbol-name field) 1)) - (buf-name (format "*Bibtex Help %s*" name))) + (buf-name (format "*BibTeX Help %s*" name))) (with-output-to-temp-buffer buf-name (princ (cdr (assoc field org-bibtex-fields)))) (with-current-buffer buf-name (visual-line-mode 1)) @@ -496,7 +496,7 @@ With optional argument OPTIONAL, also prompt for optional fields." (org-bibtex-autokey))) -;;; Bibtex link functions +;;; BibTeX link functions (org-link-set-parameters "bibtex" :follow #'org-bibtex-open :store #'org-bibtex-store-link) @@ -593,13 +593,13 @@ ARG, when non-nil, is a universal prefix argument. See (add-hook 'org-execute-file-search-functions 'org-execute-file-search-in-bibtex) -;;; Bibtex <-> Org headline translation functions +;;; BibTeX <-> Org headline translation functions (defun org-bibtex (filename) "Export each headline in the current file to a bibtex entry. Headlines are exported using `org-bibtex-headline'." (interactive (list (read-file-name - "Bibtex file: " nil nil nil + "BibTeX file: " nil nil nil (let ((file (buffer-file-name (buffer-base-buffer)))) (and file (file-name-nondirectory @@ -619,7 +619,7 @@ Headlines are exported using `org-bibtex-headline'." nil)))) (when error-point (goto-char error-point) - (message "Bibtex error at %S" (nth 4 (org-heading-components)))))) + (message "BibTeX error at %S" (nth 4 (org-heading-components)))))) (defun org-bibtex-check (&optional optional) "Check the current headline for required fields. diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el index a33d84f1cd4..2ec2f4c00bc 100644 --- a/lisp/org/org-agenda.el +++ b/lisp/org/org-agenda.el @@ -3348,7 +3348,7 @@ s Search for keywords M Like m, but only TODO entries (`agenda (call-interactively 'org-agenda-list)) (`agenda* - (funcall 'org-agenda-list nil nil t)) + (funcall 'org-agenda-list nil nil nil t)) (`alltodo (call-interactively 'org-todo-list)) (`search diff --git a/lisp/org/org-element.el b/lisp/org/org-element.el index 8524dd29d83..51729b3f33d 100644 --- a/lisp/org/org-element.el +++ b/lisp/org/org-element.el @@ -2462,7 +2462,7 @@ CDR is a plist containing `:key', `:value', `:begin', `:end', (org-element-property :value keyword))) -;;;; Latex Environment +;;;; LaTeX Environment (defconst org-element--latex-begin-environment "^[ \t]*\\\\begin{\\([A-Za-z0-9*]+\\)}" @@ -3412,7 +3412,7 @@ CONTENTS is the contents of the object." (format "/%s/" contents)) -;;;; Latex Fragment +;;;; LaTeX Fragment (defun org-element-latex-fragment-parser () "Parse LaTeX fragment at point, if any. diff --git a/lisp/org/org-persist.el b/lisp/org/org-persist.el index a0652b99c56..01078f4596d 100644 --- a/lisp/org/org-persist.el +++ b/lisp/org/org-persist.el @@ -540,13 +540,13 @@ COLLECTION is the plist holding data collection." (defun org-persist-read:file (_ path __) "Read file container from PATH." - (when (and path (file-exists-p (concat org-persist-directory path))) - (concat org-persist-directory path))) + (when (and path (file-exists-p (org-file-name-concat org-persist-directory path))) + (org-file-name-concat org-persist-directory path))) (defun org-persist-read:url (_ path __) "Read file container from PATH." - (when (and path (file-exists-p (concat org-persist-directory path))) - (concat org-persist-directory path))) + (when (and path (file-exists-p (org-file-name-concat org-persist-directory path))) + (org-file-name-concat org-persist-directory path))) (defun org-persist-read:index (cont index-file _) "Read index container CONT from INDEX-FILE." diff --git a/lisp/org/org-src.el b/lisp/org/org-src.el index 9e439281118..aadd8eba579 100644 --- a/lisp/org/org-src.el +++ b/lisp/org/org-src.el @@ -315,7 +315,7 @@ is 0.") (defun org-src--construct-edit-buffer-name (org-buffer-name lang) "Construct the buffer name for a source editing buffer. -Format is \"*Org Src ORG-BUFFER-NAME [ LANG ]*\"." +Format is \"*Org Src ORG-BUFFER-NAME[ LANG ]*\"." (concat "*Org Src " org-buffer-name "[ " lang " ]*")) (defun org-src--edit-buffer (beg end) diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el index a8a13152dc8..20636a3dd04 100644 --- a/lisp/org/org-version.el +++ b/lisp/org/org-version.el @@ -11,7 +11,7 @@ Inserted by installing Org mode or when a release is made." (defun org-git-version () "The Git version of Org mode. Inserted by installing Org or when a release is made." - (let ((org-git-version "release_9.6.1-40-g3d817c")) + (let ((org-git-version "release_9.6.1-48-g92471e")) org-git-version)) (provide 'org-version) diff --git a/lisp/org/ox-ascii.el b/lisp/org/ox-ascii.el index 9c4424b14f1..692dd216d61 100644 --- a/lisp/org/ox-ascii.el +++ b/lisp/org/ox-ascii.el @@ -1549,7 +1549,7 @@ information." keyword info))))) -;;;; Latex Environment +;;;; LaTeX Environment (defun org-ascii-latex-environment (latex-environment _contents info) "Transcode a LATEX-ENVIRONMENT element from Org to ASCII. @@ -1561,7 +1561,7 @@ information." latex-environment info))) -;;;; Latex Fragment +;;;; LaTeX Fragment (defun org-ascii-latex-fragment (latex-fragment _contents info) "Transcode a LATEX-FRAGMENT object from Org to ASCII. diff --git a/lisp/org/ox-html.el b/lisp/org/ox-html.el index 7b79c57d4a4..b27254b8ac5 100644 --- a/lisp/org/ox-html.el +++ b/lisp/org/ox-html.el @@ -2969,7 +2969,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." ((string= "listings" value) (org-html-list-of-listings info)) ((string= "tables" value) (org-html-list-of-tables info)))))))) -;;;; Latex Environment +;;;; LaTeX Environment (defun org-html-format-latex (latex-frag processing-type info) "Format a LaTeX fragment LATEX-FRAG into HTML. @@ -3086,7 +3086,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." info caption label))))) (t (org-html--wrap-latex-environment latex-frag info caption label))))) -;;;; Latex Fragment +;;;; LaTeX Fragment (defun org-html-latex-fragment (latex-fragment _contents info) "Transcode a LATEX-FRAGMENT object from Org to HTML. diff --git a/lisp/org/ox-latex.el b/lisp/org/ox-latex.el index 5ac9c378133..50a0950aa04 100644 --- a/lisp/org/ox-latex.el +++ b/lisp/org/ox-latex.el @@ -1272,7 +1272,7 @@ used. When nil, no theme is applied." (defun org-latex-generate-engraved-preamble (info) "Generate the preamble to setup engraved code. The result is constructed from the :latex-engraved-preamble and -:latex-engraved-optionsn export options, the default values of +:latex-engraved-options export options, the default values of which are given by `org-latex-engraved-preamble' and `org-latex-engraved-options' respectively." (let* ((engraved-options @@ -2600,7 +2600,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." (otherwise "\\lstlistoflistings"))))))))) -;;;; Latex Environment +;;;; LaTeX Environment (defun org-latex--environment-type (latex-environment) "Return the TYPE of LATEX-ENVIRONMENT. @@ -2658,7 +2658,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." (insert caption) (buffer-string)))))) -;;;; Latex Fragment +;;;; LaTeX Fragment (defun org-latex-latex-fragment (latex-fragment _contents _info) "Transcode a LATEX-FRAGMENT object from Org to LaTeX. diff --git a/lisp/org/ox-md.el b/lisp/org/ox-md.el index 5cb79ef2396..5be0ca22e07 100644 --- a/lisp/org/ox-md.el +++ b/lisp/org/ox-md.el @@ -486,7 +486,7 @@ channel." (_ (org-export-with-backend 'html keyword contents info)))) -;;;; Latex Environment +;;;; LaTeX Environment (defun org-md-latex-environment (latex-environment _contents info) "Transcode a LATEX-ENVIRONMENT object from Org to Markdown. @@ -501,7 +501,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." latex-frag) latex-frag)))) -;;;; Latex Fragment +;;;; LaTeX Fragment (defun org-md-latex-fragment (latex-fragment _contents info) "Transcode a LATEX-FRAGMENT object from Org to Markdown. diff --git a/lisp/org/ox-odt.el b/lisp/org/ox-odt.el index 949c8f9b5b2..cf217c9e781 100644 --- a/lisp/org/ox-odt.el +++ b/lisp/org/ox-odt.el @@ -1986,7 +1986,7 @@ information." (ignore)))))))) -;;;; Latex Environment +;;;; LaTeX Environment ;; (eval-after-load 'ox-odt '(ad-deactivate 'org-format-latex-as-mathml)) ;; (advice-add 'org-format-latex-as-mathml ; FIXME @@ -2007,7 +2007,7 @@ CONTENTS is nil. INFO is a plist holding contextual information." (org-odt-do-format-code latex-frag info))) -;;;; Latex Fragment +;;;; LaTeX Fragment ;; (when latex-frag ; FIXME ;; (setq href (propertize href :title "LaTeX Fragment" diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 209b44824e4..1c55c7fbdde 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -1100,10 +1100,15 @@ the code is C or C++ and based on that chooses whether to enable '("\\(\\.ii\\|\\.\\(CC?\\|HH?\\)\\|\\.[ch]\\(pp\\|xx\\|\\+\\+\\)\\|\\.\\(cc\\|hh\\)\\)\\'" . c++-ts-mode))) -(if (treesit-ready-p 'c) - (add-to-list 'auto-mode-alist - '("\\(\\.[chi]\\|\\.lex\\|\\.y\\(acc\\)?\\|\\.x[bp]m\\)\\'" - . c-ts-mode))) +(when (treesit-ready-p 'c) + (add-to-list 'auto-mode-alist + '("\\(\\.[chi]\\|\\.lex\\|\\.y\\(acc\\)?\\)\\'" . c-ts-mode)) + (add-to-list 'auto-mode-alist '("\\.x[pb]m\\'" . c-ts-mode)) + ;; image-mode's association must be before the C mode, otherwise XPM + ;; images will be initially visited as C files. Also note that the + ;; regexp must be different from what files.el does, or else + ;; add-to-list will not add the association where we want it. + (add-to-list 'auto-mode-alist '("\\.x[pb]m\\'" . image-mode))) (if (and (treesit-ready-p 'cpp) (treesit-ready-p 'c)) diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 6c1b9eafe43..fe9bc510049 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -759,7 +759,9 @@ treated as in `eglot--dbind'." :completion (list :dynamicRegistration :json-false :completionItem `(:snippetSupport - ,(if (eglot--snippet-expansion-fn) + ,(if (and + (not (eglot--stay-out-of-p 'yasnippet)) + (eglot--snippet-expansion-fn)) t :json-false) :deprecatedSupport t @@ -1257,7 +1259,7 @@ This docstring appeases checkdoc, that's all." ;; very much data so we turn it off ;; unconditionally -- just for our ;; process. - (tramp-use-ssh-controlmaster-options t) + (tramp-use-ssh-controlmaster-options 'suppress) (tramp-ssh-controlmaster-options "-o ControlMaster=no -o ControlPath=none")) (make-process @@ -1627,9 +1629,11 @@ If optional MARKER, return a marker instead" (defun eglot--snippet-expansion-fn () "Compute a function to expand snippets. Doubles as an indicator of snippet support." - (and (boundp 'yas-minor-mode) - (symbol-value 'yas-minor-mode) - 'yas-expand-snippet)) + (and (fboundp 'yas-minor-mode) + (lambda (&rest args) + (with-no-warnings + (unless (bound-and-true-p yas-minor-mode) (yas-minor-mode 1)) + (apply #'yas-expand-snippet args))))) (defun eglot--format-markup (markup) "Format MARKUP according to LSP's spec." @@ -1940,8 +1944,8 @@ If it is activated, also signal textDocument/didOpen." (put 'eglot--mode-line-format 'risky-local-variable t) -(defun eglot--mouse-call (what) - "Make an interactive lambda for calling WHAT from mode-line." +(defun eglot--mouse-call (what &optional update-mode-line) + "Make an interactive lambda for calling WHAT with the mouse." (lambda (event) (interactive "e") (let ((start (event-start event))) (with-selected-window (posn-window start) @@ -1949,7 +1953,8 @@ If it is activated, also signal textDocument/didOpen." (goto-char (or (posn-point start) (point))) (call-interactively what) - (force-mode-line-update t)))))) + (when update-mode-line + (force-mode-line-update t))))))) (defun eglot-manual () "Open documentation." (declare (obsolete info "29.1")) @@ -2023,7 +2028,7 @@ Uses THING, FACE, DEFS and PREPEND." (cl-loop with map = (make-sparse-keymap) for (elem . rest) on defs for (key def help) = elem - do (define-key map `[mode-line ,key] (eglot--mouse-call def)) + do (define-key map `[mode-line ,key] (eglot--mouse-call def t)) concat (format "%s: %s" key help) into blurb when rest concat "\n" into blurb finally (return `(:propertize ,thing @@ -2084,15 +2089,18 @@ still unanswered LSP requests to the server\n")))))))) (defalias 'eglot--make-diag 'flymake-make-diagnostic) (defalias 'eglot--diag-data 'flymake-diagnostic-data) +(defvar eglot-diagnostics-map + (let ((map (make-sparse-keymap))) + (define-key map [mouse-2] 'eglot-code-actions-at-mouse) + map) + "Keymap active in Eglot-backed Flymake diagnostic overlays.") + (cl-loop for i from 1 for type in '(eglot-note eglot-warning eglot-error) do (put type 'flymake-overlay-control `((mouse-face . highlight) (priority . ,(+ 50 i)) - (keymap . ,(let ((map (make-sparse-keymap))) - (define-key map [mouse-1] - (eglot--mouse-call 'eglot-code-actions)) - map))))) + (keymap . ,eglot-diagnostics-map)))) ;;; Protocol implementation (Requests, notifications, etc) @@ -2353,7 +2361,6 @@ THINGS are either registrations or unregisterations (sic)." (defun eglot--before-change (beg end) "Hook onto `before-change-functions' with BEG and END." - (remove-overlays beg end 'eglot--overlay t) (when (listp eglot--recent-changes) ;; Records BEG and END, crucially convert them into LSP ;; (line/char) positions before that information is lost (because @@ -2373,25 +2380,23 @@ THINGS are either registrations or unregisterations (sic)." "Hook onto `after-change-functions'. Records BEG, END and PRE-CHANGE-LENGTH locally." (cl-incf eglot--versioned-identifier) - (pcase (and (listp eglot--recent-changes) - (car eglot--recent-changes)) + (pcase (car-safe eglot--recent-changes) (`(,lsp-beg ,lsp-end (,b-beg . ,b-beg-marker) (,b-end . ,b-end-marker)) - ;; github#259 and github#367: With `capitalize-word' or somesuch, - ;; `before-change-functions' always records the whole word's - ;; `b-beg' and `b-end'. Similarly, when coalescing two lines - ;; into one, `fill-paragraph' they mark the end of the first line - ;; up to the end of the second line. In both situations, args - ;; received here contradict that information: `beg' and `end' - ;; will differ by 1 and will likely only encompass the letter - ;; that was capitalized or, in the sentence-joining situation, - ;; the replacement of the newline with a space. That's we keep - ;; markers _and_ positions so we're able to detect and correct - ;; this. We ignore `beg', `len' and `pre-change-len' and send - ;; "fuller" information about the region from the markers. I've - ;; also experimented with doing this unconditionally but it seems - ;; to break when newlines are added. + ;; github#259 and github#367: with `capitalize-word' & friends, + ;; `before-change-functions' records the whole word's `b-beg' and + ;; `b-end'. Similarly, when `fill-paragraph' coalesces two + ;; lines, `b-beg' and `b-end' mark end of first line and end of + ;; second line, resp. In both situations, `beg' and `end' + ;; received here seemingly contradict that: they will differ by 1 + ;; and encompass the capitalized character or, in the coalescing + ;; case, the replacement of the newline with a space. We keep + ;; both markers and positions to detect and correct this. In + ;; this specific case, we ignore `beg', `len' and + ;; `pre-change-len' and send richer information about the region + ;; from the markers. I've also experimented with doing this + ;; unconditionally but it seems to break when newlines are added. (if (and (= b-end b-end-marker) (= b-beg b-beg-marker) (or (/= beg b-beg) (/= end b-end))) (setcar eglot--recent-changes @@ -2892,8 +2897,7 @@ for which LSP on-type-formatting should be requested." ;; it'll be adjusted. If no usable ;; insertText at all, label is best, ;; too. - (cond ((or (and (eql insertTextFormat 2) - (eglot--snippet-expansion-fn)) + (cond ((or (eql insertTextFormat 2) textEdit (null insertText) (string-empty-p insertText)) @@ -3220,8 +3224,9 @@ Returns a list as described in docstring of `imenu--index-alist'." ,(eglot--TextDocumentIdentifier)) :cancel-on-input non-essential)))))) -(defun eglot--apply-text-edits (edits &optional version) +(cl-defun eglot--apply-text-edits (edits &optional version) "Apply EDITS for current buffer if at VERSION, or if it's nil." + (unless edits (cl-return-from eglot--apply-text-edits)) (unless (or (not version) (equal version eglot--versioned-identifier)) (jsonrpc-error "Edits on `%s' require version %d, you have %d" (current-buffer) version eglot--versioned-identifier)) @@ -3339,6 +3344,9 @@ at point. With prefix argument, prompt for ACTION-KIND." (eglot--read-execute-code-action actions server action-kind) actions))) +(defalias 'eglot-code-actions-at-mouse (eglot--mouse-call 'eglot-code-actions) + "Like `eglot-code-actions', but intended for mouse events.") + (defun eglot--read-execute-code-action (actions server &optional action-kind) "Helper for interactive calls to `eglot-code-actions'." (let* ((menu-items @@ -3376,7 +3384,7 @@ at point. With prefix argument, prompt for ACTION-KIND." `(defun ,name (beg &optional end) ,(format "Execute `%s' code actions between BEG and END." kind) (interactive (eglot--region-bounds)) - (eglot-code-actions beg end ,kind))) + (eglot-code-actions beg end ,kind t))) (eglot--code-action eglot-code-action-organize-imports "source.organizeImports") (eglot--code-action eglot-code-action-extract "refactor.extract") @@ -3607,31 +3615,41 @@ If NOERROR, return predicate, else erroring function." (eglot--lambda ((InlayHint) position kind label paddingLeft paddingRight) (goto-char (eglot--lsp-position-to-point position)) (when (or (> (point) to) (< (point) from)) (cl-return)) - (let ((left-pad (and paddingLeft - (not (eq paddingLeft :json-false)) - (not (memq (char-before) '(32 9))) " ")) - (right-pad (and paddingRight - (not (eq paddingRight :json-false)) - (not (memq (char-after) '(32 9))) " "))) - (cl-flet - ((do-it (text lpad rpad) - (let ((ov (make-overlay (point) (point)))) - (overlay-put ov 'before-string + (let* ((left-pad (and paddingLeft + (not (eq paddingLeft :json-false)) + (not (memq (char-before) '(32 9))) " ")) + (right-pad (and paddingRight + (not (eq paddingRight :json-false)) + (not (memq (char-after) '(32 9))) " ")) + (peg-after-p (eql kind 1))) + (cl-labels + ((make-ov () + (if peg-after-p + (make-overlay (point) (1+ (point)) nil t) + (make-overlay (1- (point)) (point) nil nil nil))) + (do-it (label lpad rpad firstp) + (let* ((tweak-cursor-p (and firstp peg-after-p)) + (ov (make-ov)) + (text (concat lpad label rpad))) + (when tweak-cursor-p (put-text-property 0 1 'cursor 1 text)) + (overlay-put ov (if peg-after-p 'before-string 'after-string) (propertize - (concat lpad text rpad) + text 'face (pcase kind (1 'eglot-type-hint-face) (2 'eglot-parameter-hint-face) (_ 'eglot-inlay-hint-face)))) (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) + (if (stringp label) (do-it label left-pad right-pad t) (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)))))))))) + (and (= i (1- (length label))) right-pad) + (zerop i)))))))))) (jsonrpc-async-request (eglot--current-server-or-lose) :textDocument/inlayHint @@ -3659,13 +3677,11 @@ If NOERROR, return predicate, else erroring function." ;;; Hacks ;;; -;; FIXME: Although desktop.el compatibility is Emacs bug#56407, the -;; optimal solution agreed to there is a bit more work than what I -;; have time to right now. See -;; e.g. https://debbugs.gnu.org/cgi/bugreport.cgi?bug=bug%2356407#68. -;; For now, just use `with-eval-after-load' +;; Emacs bug#56407, the optimal solution is in desktop.el, but that's +;; 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--managed-mode . ignore)) + (add-to-list 'desktop-minor-mode-handlers '(eglot-inlay-hints-mode . ignore))) ;;; Misc diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index 8efdae6060f..cb95f29b5fe 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el @@ -146,7 +146,10 @@ Otherwise, `find-tag-default' is used." (define-obsolete-variable-alias 'find-tag-marker-ring-length 'tags-location-ring-length "25.1") -(defvar tags-location-ring-length 16) +(defvar tags-location-ring-length 16 + "Size of the find-tag marker ring. +This variable has no effect, and is kept only for backward compatibility. +The actual size of the find-tag marker ring is unlimited.") (defcustom tags-tag-face 'default "Face for tags in the output of `tags-apropos'." @@ -181,8 +184,9 @@ Example value: (sexp :tag "Tags to search"))) :version "21.1") -;; Obsolete variable kept for compatibility. We don't use it in any way. -(defvar find-tag-marker-ring (make-ring 16)) +(defvar find-tag-marker-ring (make-ring 16) + "Find-tag marker ring. +Obsolete variable kept for compatibility. It is not used in any way.") (make-obsolete-variable 'find-tag-marker-ring "use `xref-push-marker-stack' or `xref-go-back' instead." diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 8793fdc6458..2fe88323c35 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -511,19 +511,28 @@ This variant of `rx' supports common Python named REGEXPS." (''string `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) (and (nth 3 ppss) (nth 8 ppss)))) + (''single-quoted-string + `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) + (and (characterp (nth 3 ppss)) (nth 8 ppss)))) + (''triple-quoted-string + `(let ((ppss (or ,syntax-ppss (syntax-ppss)))) + (and (eq t (nth 3 ppss)) (nth 8 ppss)))) (''paren `(nth 1 (or ,syntax-ppss (syntax-ppss)))) (_ form)))) (defun python-syntax-context (type &optional syntax-ppss) "Return non-nil if point is on TYPE using SYNTAX-PPSS. -TYPE can be `comment', `string' or `paren'. It returns the start +TYPE can be `comment', `string', `single-quoted-string', +`triple-quoted-string' or `paren'. It returns the start character address of the specified TYPE." (declare (compiler-macro python-syntax--context-compiler-macro)) (let ((ppss (or syntax-ppss (syntax-ppss)))) (pcase type ('comment (and (nth 4 ppss) (nth 8 ppss))) ('string (and (nth 3 ppss) (nth 8 ppss))) + ('single-quoted-string (and (characterp (nth 3 ppss)) (nth 8 ppss))) + ('triple-quoted-string (and (eq t (nth 3 ppss)) (nth 8 ppss))) ('paren (nth 1 ppss)) (_ nil)))) @@ -4805,9 +4814,7 @@ Optional argument JUSTIFY defines if the paragraph should be justified." ((python-syntax-context 'comment) (funcall python-fill-comment-function justify)) ;; Strings/Docstrings - ((save-excursion (or (python-syntax-context 'string) - (equal (string-to-syntax "|") - (syntax-after (point))))) + ((python-info-triple-quoted-string-p) (funcall python-fill-string-function justify)) ;; Decorators ((equal (char-after (save-excursion @@ -4833,10 +4840,7 @@ JUSTIFY should be used (if applicable) as in `fill-paragraph'." (let* ((str-start-pos (set-marker (make-marker) - (or (python-syntax-context 'string) - (and (equal (string-to-syntax "|") - (syntax-after (point))) - (point))))) + (python-info-triple-quoted-string-p))) ;; JT@2021-09-21: Since bug#49518's fix this will always be 1 (num-quotes (python-syntax-count-quotes (char-after str-start-pos) str-start-pos)) @@ -6043,6 +6047,21 @@ point's current `syntax-ppss'." ((python-info-looking-at-beginning-of-defun)) (t nil)))))) +(defun python-info-triple-quoted-string-p () + "Check if point is in a triple quoted string including quotes. +It returns the position of the third quote character of the start +of the string." + (save-excursion + (let ((pos (point))) + (cl-loop + for offset in '(0 3 -2 2 -1 1) + if (let ((check-pos (+ pos offset))) + (and (>= check-pos (point-min)) + (<= check-pos (point-max)) + (python-syntax-context + 'triple-quoted-string (syntax-ppss check-pos)))) + return it)))) + (defun python-info-encoding-from-cookie () "Detect current buffer's encoding from its coding cookie. Returns the encoding as a symbol." diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index d4e34f7e55a..ee4253960c5 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -355,8 +355,10 @@ backward." (t (goto-char start) nil)))) -;; Dummy variable retained for compatibility. -(defvar xref-marker-ring-length 16) +(defvar xref-marker-ring-length 16 + "Xref marker ring length. +This is a dummy variable retained for backward compatibility, and +otherwise unused.") (make-obsolete-variable 'xref-marker-ring-length nil "29.1") (defcustom xref-prompt-for-identifier '(not xref-find-definitions @@ -453,7 +455,9 @@ are predefined: (make-obsolete-variable 'xref--marker-ring 'xref--history "29.1") (defun xref-set-marker-ring-length (_var _val) - (declare (obsolete nil "29.1")) + (declare (obsolete + "this function has no effect: Xref marker ring is now unlimited in size" + "29.1")) nil) (defun xref--make-xref-history () @@ -499,7 +503,7 @@ Override existing value with NEW-VALUE if NEW-VALUE is set." (defun xref-push-marker-stack (&optional m) "Add point M (defaults to `point-marker') to the marker stack. -The future stack is erased." +Erase the stack slots following this one." (xref--push-backward (or m (point-marker))) (let ((history (xref--get-history))) (dolist (mk (cdr history)) @@ -527,7 +531,7 @@ To undo, use \\[xref-go-forward]." ;;;###autoload (defun xref-go-forward () - "Got to the point where a previous \\[xref-go-back] was invoked." + "Go to the point where a previous \\[xref-go-back] was invoked." (interactive) (let ((history (xref--get-history))) (if (null (cdr history)) diff --git a/lisp/subr.el b/lisp/subr.el index 2f72945789b..c67c7158b76 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -163,7 +163,7 @@ of previous VARs. (defmacro setq-local (&rest pairs) "Make each VARIABLE buffer-local and assign to it the corresponding VALUE. -The arguments are variable/value pairs For each VARIABLE in a pair, +The arguments are variable/value pairs. For each VARIABLE in a pair, make VARIABLE buffer-local and assign to it the corresponding VALUE of the pair. The VARIABLEs are literal symbols and should not be quoted. diff --git a/lisp/url/url-gw.el b/lisp/url/url-gw.el index f16be980945..4d7297f6f2e 100644 --- a/lisp/url/url-gw.el +++ b/lisp/url/url-gw.el @@ -208,7 +208,7 @@ linked Emacs under SunOS 4.x." proc))) (defvar url-gw-rlogin-obsolete-warned-once nil) -(make-obsolete-variable url-gw-rlogin-obsolete-warned-once nil "29.1") +(make-obsolete-variable 'url-gw-rlogin-obsolete-warned-once nil "29.1") ;;;###autoload (defun url-open-stream (name buffer host service &optional gateway-method) diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el index 3caaf49f58e..96f5c46ea00 100644 --- a/lisp/url/url-misc.el +++ b/lisp/url/url-misc.el @@ -48,7 +48,7 @@ nil)) (defvar url-misc-rlogin-obsolete-warned-once nil) -(make-obsolete-variable url-misc-rlogin-obsolete-warned-once nil "29.1") +(make-obsolete-variable 'url-misc-rlogin-obsolete-warned-once nil "29.1") (defun url-do-terminal-emulator (type server port user) (switch-to-buffer diff --git a/src/data.c b/src/data.c index d2f4d40d7bc..8dc5000424e 100644 --- a/src/data.c +++ b/src/data.c @@ -773,7 +773,10 @@ DEFUN ("symbol-plist", Fsymbol_plist, Ssymbol_plist, 1, 1, 0, } DEFUN ("symbol-name", Fsymbol_name, Ssymbol_name, 1, 1, 0, - doc: /* Return SYMBOL's name, a string. */) + doc: /* Return SYMBOL's name, a string. + +Warning: never alter the string returned by `symbol-name'. +Doing that might make Emacs dysfunctional, and might even crash Emacs. */) (register Lisp_Object symbol) { register Lisp_Object name; diff --git a/src/keyboard.c b/src/keyboard.c index aa7c81f48f1..f1857bdc607 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -114,6 +114,13 @@ static bool single_kboard; /* Minimum allowed size of the recent_keys vector. */ #define MIN_NUM_RECENT_KEYS (100) +/* Maximum allowed size of the recent_keys vector. */ +#if INTPTR_MAX <= INT_MAX +# define MAX_NUM_RECENT_KEYS (INT_MAX / EMACS_INT_WIDTH / 10) +#else +# define MAX_NUM_RECENT_KEYS (INT_MAX / EMACS_INT_WIDTH) +#endif + /* Index for storing next element into recent_keys. */ static int recent_keys_index; @@ -11210,10 +11217,10 @@ The saved keystrokes are shown by `view-lossage'. */) if (!FIXNATP (arg)) user_error ("Value must be a positive integer"); - int osize = ASIZE (recent_keys); + ptrdiff_t osize = ASIZE (recent_keys); eassert (lossage_limit == osize); int min_size = MIN_NUM_RECENT_KEYS; - int new_size = XFIXNAT (arg); + EMACS_INT new_size = XFIXNAT (arg); if (new_size == osize) return make_fixnum (lossage_limit); @@ -11223,6 +11230,12 @@ The saved keystrokes are shown by `view-lossage'. */) AUTO_STRING (fmt, "Value must be >= %d"); Fsignal (Quser_error, list1 (CALLN (Fformat, fmt, make_fixnum (min_size)))); } + if (new_size > MAX_NUM_RECENT_KEYS) + { + AUTO_STRING (fmt, "Value must be <= %d"); + Fsignal (Quser_error, list1 (CALLN (Fformat, fmt, + make_fixnum (MAX_NUM_RECENT_KEYS)))); + } int kept_keys = new_size > osize ? total_keys : min (new_size, total_keys); update_recent_keys (new_size, kept_keys); diff --git a/src/keymap.c b/src/keymap.c index 23453eaa9a6..efac410d317 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -887,22 +887,23 @@ store_in_keymap (Lisp_Object keymap, register Lisp_Object idx, keymap_end: /* We have scanned the entire keymap, and not found a binding for IDX. Let's add one. */ - { - Lisp_Object elt; + if (!remove) + { + Lisp_Object elt; - if (CONSP (idx) && CHARACTERP (XCAR (idx))) - { - /* IDX specifies a range of characters, and not all of them - were handled yet, which means this keymap doesn't have a - char-table. So, we insert a char-table now. */ - elt = Fmake_char_table (Qkeymap, Qnil); - Fset_char_table_range (elt, idx, NILP (def) ? Qt : def); - } - else - elt = Fcons (idx, def); - CHECK_IMPURE (insertion_point, XCONS (insertion_point)); - XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point))); - } + if (CONSP (idx) && CHARACTERP (XCAR (idx))) + { + /* IDX specifies a range of characters, and not all of them + were handled yet, which means this keymap doesn't have a + char-table. So, we insert a char-table now. */ + elt = Fmake_char_table (Qkeymap, Qnil); + Fset_char_table_range (elt, idx, NILP (def) ? Qt : def); + } + else + elt = Fcons (idx, def); + CHECK_IMPURE (insertion_point, XCONS (insertion_point)); + XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point))); + } } return def; diff --git a/test/infra/Dockerfile.emba b/test/infra/Dockerfile.emba index c005d872cb8..872591333e6 100644 --- a/test/infra/Dockerfile.emba +++ b/test/infra/Dockerfile.emba @@ -24,7 +24,7 @@ # Maintainer: Ted Zlatanov # URL: https://emba.gnu.org/emacs/emacs -FROM debian:stretch as emacs-base +FROM debian:bullseye as emacs-base RUN apt-get update && \ apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \ @@ -34,9 +34,10 @@ RUN apt-get update && \ FROM emacs-base as emacs-inotify +# We install clangd for Eglot tests. RUN apt-get update && \ apt-get install -y --no-install-recommends -o=Dpkg::Use-Pty=0 \ - inotify-tools \ + inotify-tools clangd \ && rm -rf /var/lib/apt/lists/* COPY . /checkout diff --git a/test/lisp/abbrev-tests.el b/test/lisp/abbrev-tests.el index ecca21df4bc..abac8dd6f0b 100644 --- a/test/lisp/abbrev-tests.el +++ b/test/lisp/abbrev-tests.el @@ -305,6 +305,22 @@ (should-not (abbrev-table-p translation-table-vector)) (should (abbrev-table-p (make-abbrev-table)))) +(ert-deftest abbrev--possibly-save-test () + "Test that `abbrev--possibly-save' properly resets +`abbrevs-changed'." + (ert-with-temp-file temp-test-file + (let ((abbrev-file-name temp-test-file) + (save-abbrevs t)) + ;; Save + (let ((abbrevs-changed t)) + (should-not (abbrev--possibly-save nil t)) + (should-not abbrevs-changed)) + ;; Don't save + (let ((abbrevs-changed t)) + (ert-simulate-keys '(?n ?\C-m) + (should (abbrev--possibly-save nil))) + (should-not abbrevs-changed))))) + (provide 'abbrev-tests) ;;; abbrev-tests.el ends here diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index e5a9d128bc5..ed4a08da6ab 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -255,6 +255,27 @@ aliqua." ;;; Font-lock and syntax +(ert-deftest python-syntax-context-1 () + (python-tests-with-temp-buffer + " +# Comment +s = 'Single Quoted String' +t = '''Triple Quoted String''' +p = (1 + 2) +" + (python-tests-look-at "Comment") + (should (= (python-syntax-context 'comment) (pos-bol))) + (python-tests-look-at "Single") + (should (= (python-syntax-context 'string) (1- (point)))) + (should (= (python-syntax-context 'single-quoted-string) (1- (point)))) + (should-not (python-syntax-context 'triple-quoted-string)) + (python-tests-look-at "Triple") + (should (= (python-syntax-context 'string) (1- (point)))) + (should-not (python-syntax-context 'single-quoted-string)) + (should (= (python-syntax-context 'triple-quoted-string) (1- (point)))) + (python-tests-look-at "1 + 2") + (should (= (python-syntax-context 'paren) (1- (point)))))) + (ert-deftest python-syntax-after-python-backspace () ;; `python-indent-dedent-line-backspace' garbles syntax (python-tests-with-temp-buffer @@ -2052,6 +2073,54 @@ this is a test this is a test this is a test this is a test this is a test this (fill-paragraph) (should (= (current-indentation) 0)))) +(ert-deftest python-fill-paragraph-single-quoted-string-1 () + "Single quoted string should not be filled." + (let ((contents " +s = 'abc def ghi jkl mno pqr stu vwx yz' +") + (fill-column 20)) + (python-tests-with-temp-buffer + contents + (python-tests-look-at "abc") + (fill-paragraph) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + contents))))) + +(ert-deftest python-fill-paragraph-single-quoted-string-2 () + "Ensure no fill is performed after the end of the single quoted string." + (let ((contents " +s1 = 'abc' +s2 = 'def' +")) + (python-tests-with-temp-buffer + contents + (python-tests-look-at "abc") + (fill-paragraph) + (should (string= (buffer-substring-no-properties (point-min) (point-max)) + contents))))) + +(ert-deftest python-fill-paragraph-triple-quoted-string-1 () + "Triple quoted string should be filled." + (let ((contents " +s = '''abc def ghi jkl mno pqr stu vwx yz''' +") + (expected " +s = '''abc def ghi +jkl mno pqr stu vwx +yz''' +") + (fill-column 20)) + (dolist (look-at '("'''abc" "z'''")) + (dolist (offset '(0 1 2 3)) + (python-tests-with-temp-buffer + contents + (python-tests-look-at look-at) + (forward-char offset) + (fill-paragraph) + (should (string= + (buffer-substring-no-properties (point-min) (point-max)) + expected))))))) + ;;; Mark @@ -6491,6 +6560,56 @@ class Class: (python-tests-look-at "'''Not a method docstring.'''") (should (not (python-info-docstring-p))))) +(ert-deftest python-info-triple-quoted-string-p-1 () + "Test triple quoted string." + (python-tests-with-temp-buffer + " +t = '''Triple''' +" + (python-tests-look-at " '''Triple") + (should-not + (python-tests-should-not-move + #'python-info-triple-quoted-string-p)) + (forward-char) + (let ((start-pos (+ (point) 2)) + (eol (pos-eol))) + (while (< (point) eol) + (should (= (python-tests-should-not-move + #'python-info-triple-quoted-string-p) + start-pos)) + (forward-char))) + (dolist (pos `(,(point) ,(point-min) ,(point-max))) + (goto-char pos) + (should-not + (python-tests-should-not-move + #'python-info-triple-quoted-string-p))))) + +(ert-deftest python-info-triple-quoted-string-p-2 () + "Test empty triple quoted string." + (python-tests-with-temp-buffer + " +e = '''''' +" + (python-tests-look-at "''''''") + (let ((start-pos (+ (point) 2)) + (eol (pos-eol))) + (while (< (point) eol) + (should (= (python-tests-should-not-move + #'python-info-triple-quoted-string-p) + start-pos)) + (forward-char))))) + +(ert-deftest python-info-triple-quoted-string-p-3 () + "Test single quoted string." + (python-tests-with-temp-buffer + " +s = 'Single' +" + (while (< (point) (point-max)) + (should-not (python-tests-should-not-move + #'python-info-triple-quoted-string-p)) + (forward-char)))) + (ert-deftest python-info-encoding-from-cookie-1 () "Should detect it on first line." (python-tests-with-temp-buffer diff --git a/test/src/keymap-tests.el b/test/src/keymap-tests.el index aa710519825..29220c95395 100644 --- a/test/src/keymap-tests.el +++ b/test/src/keymap-tests.el @@ -475,6 +475,24 @@ g .. h foo "a" #'next-line "a" #'previous-line))) +(ert-deftest keymap-unset-test-remove-and-inheritance () + "Check various behaviors of keymap-unset. (Bug#62207)" + (let ((map (make-sparse-keymap)) + (parent (make-sparse-keymap))) + (set-keymap-parent map parent) + ;; Removing an unset key should not add a key. + (keymap-set parent "u" #'undo) + (keymap-unset map "u" t) + (should (equal (keymap-lookup map "u") #'undo)) + ;; Non-removed child bindings should shadow parent + (keymap-set map "u" #'identity) + (keymap-unset map "u") + ;; From the child, but nil. + (should-not (keymap-lookup map "u")) + (keymap-unset map "u" t) + ;; From the parent this time/ + (should (equal (keymap-lookup map "u") #'undo)))) + (provide 'keymap-tests) ;;; keymap-tests.el ends here