emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master d492be400e: Merge from origin/emacs-29


From: Stefan Kangas
Subject: master d492be400e: Merge from origin/emacs-29
Date: Wed, 8 Feb 2023 00:45:25 -0500 (EST)

branch: master
commit d492be400e1676cee68432a1dc1009a0fa8b9a2b
Merge: 2273cdb40e c9ba05af8d
Author: Stefan Kangas <stefankangas@gmail.com>
Commit: Stefan Kangas <stefankangas@gmail.com>

    Merge from origin/emacs-29
    
    c9ba05af8df Fix crashes inside 'xfree' called from treesit.c
    746748f5c28 Make java-ts-mode use the c-ts-common-indent-type-regexp-...
    87d39a30b12 Fix c-ts-mode indentation
    7cb92b53987 Fix c-ts-mode indentation
    d68ff6016d0 Fix c-ts-mode indentation (bug#61291)
    2ac8c4bbd6f (eglot-completion-at-point): Return correct values in :co...
    321cbd9a601 Tighten and simplify typescript compilation-mode regexps ...
    97533e73ad6 ; * lisp/progmodes/c-ts-common.el (treesit-node-prev-sibl...
    9dfccb89fc5 Clarify bug-reference-auto-setup-functions docstring.
    17ab426670a * lisp/treesit.el (treesit): Fix shortdoc example form (b...
    5a6dfab1e4d Use c-ts-common-statement-offset in java-ts-mode (bug#61142)
    c3262216abb Add array_initializer to java-ts-mode
    79ab62e0bb5 go-ts-mode: Highlight variable declarations
    1fab91d852e go-ts-mode: Fix highlighting of function name in call_exp...
    07ffe902c63 c-ts-mode: Highlight "property functions" as functions
    a529b0d6463 rust-ts-mode: Fix highlighting of function name in call_e...
    088425538f2 rust-ts-mode--font-lock-settings: Improve consistency
    793c24a6ac7 Make sure 'M-x show-paren-local-mode' turns on right away
    60089dcfe06 Add to bug-reference-auto-setup-functions after its decla...
    26e947ccb14 * lisp/vc/vc.el (vc-find-revision-no-save): Fix parens (b...
    948e343496b ; Fix byte-compilation warning
    6568a1aaf9a Fix inability to turn show-paren-local-mode on manually (...
    24085ba6105 ; go-ts-mode--indent-rules: Indent to 0 at top level
    0862a79fef5 Merge branch 'emacs-29' of git.savannah.gnu.org:/srv/git/...
    bb999df5d6f ; Fix whitespace of last change
    929daafa1d6 ; Fix trivial mistake in emoji--choose-emoji
    d7b4a8487f6 ; * lisp/isearch.el (emoji--read-emoji): Avoid compilatio...
    e38ff004631 rust-ts-mode: Highlight variable declarations
    d12727057d4 rust-ts-mode--indent-rules: Indent to 0 at top level
    85705a7059f ; Move misplaces parenthesis in emoji--choose-emoji
    18c43bb9d6c Ensure upper bound of font-lock region is less than point...
    94f291d1505 ; * lisp/paren.el (show-paren-predicate): Doc fix.  (Bug#...
    3ffd0eddce6 Highlight more complex function parameters
    58dc03ba7e4 No longer use transient in isearch-emoji-by-name
    0c125fcc67a Make highlighting more regular across TS modes (bug#61205)
    1dd751c3ac4 ; Improve documentation of 'proper-list-p'
    96181ed3f09 Document 'plistp'
    03d9d18513b Fix display of raised/lowered composed text
    f13479d9556 Fix installation of tree-sitter grammar on MS-Windows
    0358267204d Update the Emacs FAQ for Emacs 29
    2c33e2889b4 Fix byte-compilation of *-ts-mode.el files
    b40a929a3f2 ; ruby-ts--syntax-propertize: Amend commentary
    b80f36b88c7 Make c-ts-mode-set-style's effect local (bug#61245)
    671e5d9fad5 ; * lisp/treesit.el (treesit--font-lock-level-setter): Mi...
    69380a88e92 c-ts-mode: Highlight name in parameter declarations
    89b550eac29 Fix switch statement indentation for go-ts-mode (bug#61238)
    1a123feb181 Fix bidi reordering of sequence of whitespace characters ...
    8870b54db99 Add tests for compilation support for TypeScript (bug#61104)
    873a0a15085 Add support for TypeScript compilation to compile.el (bug...
    3a64f81ebc1 Don't clobber match data in 'y-or-n-p'
    4c765d93ab3 Refine the previous change
    d99b5151f8c Add syntax-propertize-function to ruby-ts-mode
    f25c15ceb7d ; Fix typos
    35e238cae8b Improve documentation of 'header-line-indent-mode'
    c3f58a66514 Don't casemap erc-sasl-user when set to :nick
    e444115d026 Improve keymap-global-set and keymap-local-set interactiv...
    
    # Conflicts:
    #       etc/NEWS
---
 admin/notes/tree-sitter/treesit_record_change      |   2 +-
 doc/emacs/display.texi                             |   4 +-
 doc/lispref/display.texi                           |  46 ++++++--
 doc/lispref/lists.texi                             |  10 +-
 doc/lispref/modes.texi                             |  67 +++++++++--
 doc/misc/efaq.texi                                 | 120 ++++++++++++++++++++
 etc/NEWS.29                                        |   8 +-
 etc/compilation.txt                                |  14 +++
 lisp/display-line-numbers.el                       |  49 +++++---
 lisp/erc/erc-sasl.el                               |  11 +-
 lisp/font-lock.el                                  |   2 +
 lisp/international/emoji.el                        |  36 +++---
 lisp/isearch.el                                    |  21 ++--
 lisp/keymap.el                                     |  18 +--
 lisp/paren.el                                      |  27 +++--
 lisp/progmodes/bug-reference.el                    |  38 +++++--
 lisp/progmodes/c-ts-common.el                      | 123 ++++++++++++---------
 lisp/progmodes/c-ts-mode.el                        |  84 +++++++++-----
 lisp/progmodes/cmake-ts-mode.el                    |   3 +
 lisp/progmodes/compile.el                          |  30 +++++
 lisp/progmodes/eglot.el                            |   5 +-
 lisp/progmodes/go-ts-mode.el                       |  48 +++++---
 lisp/progmodes/java-ts-mode.el                     |  39 +++++--
 lisp/progmodes/ruby-ts-mode.el                     |  93 +++++++++++++++-
 lisp/progmodes/rust-ts-mode.el                     |  73 +++++++-----
 lisp/subr.el                                       |  14 ++-
 lisp/treesit.el                                    |  74 ++++++++-----
 lisp/vc/vc.el                                      |   4 +-
 src/bidi.c                                         |  15 ++-
 src/buffer.c                                       |   4 +-
 src/treesit.c                                      |   2 +-
 src/xdisp.c                                        |   5 +
 .../progmodes/c-ts-mode-resources/indent-bsd.erts  |   2 +-
 .../lisp/progmodes/c-ts-mode-resources/indent.erts |  87 ++++++++++++++-
 test/lisp/progmodes/compile-tests.el               |   6 +-
 .../progmodes/go-ts-mode-resources/indent.erts     |  47 ++++++++
 test/lisp/progmodes/go-ts-mode-tests.el            |  31 ++++++
 37 files changed, 976 insertions(+), 286 deletions(-)

diff --git a/admin/notes/tree-sitter/treesit_record_change 
b/admin/notes/tree-sitter/treesit_record_change
index bb0f9edc35..0dc6491e2d 100644
--- a/admin/notes/tree-sitter/treesit_record_change
+++ b/admin/notes/tree-sitter/treesit_record_change
@@ -5,7 +5,7 @@ buffer, lest tree-sitter's parse tree would be corrupted/out of 
sync.
 
 All buffer changes in Emacs are made through functions in insdel.c
 (and casefiddle.c), I augmented functions in those files with calls to
-treesit_record_change.  Below is a manifest of all the relavent
+treesit_record_change.  Below is a manifest of all the relevant
 functions in insdel.c as of Emacs 29:
 
 Function                          Calls
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 97732b65e3..a86c12a0db 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -1159,11 +1159,11 @@ function definitions.
 This level adds fontification of keywords, strings, and data types.
 @item Level 3
 This is the default level; it adds fontification of assignments,
-numbers, properties, etc.
+numbers, etc.
 @item Level 4
 This level adds everything else that can be fontified: operators,
 delimiters, brackets, other punctuation, function names in function
-calls, variables, etc.
+calls, property look ups, variables, etc.
 @end table
 
 @vindex treesit-font-lock-feature-list
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 5a9a9f95f7..c5374e1481 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5285,9 +5285,10 @@ space taken by the line-number display.
   The @code{left}, @code{center}, and @code{right} positions can be
 used with @code{:align-to} to specify a position relative to the left
 edge, center, or right edge of the text area.  When the window
-displays line numbers, the @code{left} and the @code{center} positions
-are offset to account for the screen space taken by the line-number
-display.
+displays line numbers, and @code{:align-to} is used in display
+properties of buffer text (as opposed to header line, see below), the
+@code{left} and the @code{center} positions are offset to account for
+the screen space taken by the line-number display.
 
   Any of the above window elements (except @code{text}) can also be
 used with @code{:align-to} to specify that the position is relative to
@@ -5301,11 +5302,11 @@ the left-margin, use
 :align-to (+ left-margin (0.5 . left-margin))
 @end example
 
-  If no specific base offset is set for alignment, it is always relative
-to the left edge of the text area.  For example, @samp{:align-to 0} in a
-header-line aligns with the first text column in the text area.  When
-the window displays line numbers, the text is considered to start where
-the space used for line-number display ends.
+  If no specific base offset is set for alignment, it is always
+relative to the left edge of the text area.  For example,
+@samp{:align-to 0} aligns with the first text column in the text area.
+When the window displays line numbers, the text is considered to start
+where the space used for line-number display ends.
 
   A value of the form @code{(@var{num} . @var{expr})} stands for the
 product of the values of @var{num} and @var{expr}.  For example,
@@ -5317,6 +5318,35 @@ product of the values of @var{num} and @var{expr}.  For 
example,
 expressions.  The form @code{(- @var{expr} ...)} negates or subtracts
 the value of the expressions.
 
+@vindex header-line-format@r{, and } :align-to
+@cindex aligning header line, when line numbers are displayed
+@cindex header line alignment when line numbers are displayed
+  Text shown in the header line that uses @code{:align-to} display
+specifications is not automatically realigned when
+@code{display-line-numbers-mode} is turned on and off, or when the
+width of line numbers on display changes.  To arrange for the
+header-line text alignment to be updated, thus keeping the header-line
+text aligned with the buffer text, turn on the
+@code{header-line-indent-mode} in the buffer and use its two
+variables, @code{header-line-indent} and
+@code{header-line-indent-width}, in the display specification.
+@xref{Header Lines}.  Here's a simple example:
+
+@lisp
+(setq header-line-format
+      (concat (propertize " "
+                          'display
+                          '(space :align-to
+                                  (+ header-line-indent-width 10)))
+              "Column"))
+@end lisp
+
+@noindent
+This will keep the text @samp{Column} on the header line aligned with
+column 10 of buffer text, regardless of whether
+@code{display-line-numbers-mode} is on or off, and also when
+line-number display changes its width.
+
 @node Other Display Specs
 @subsection Other Display Specifications
 
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index 44b7058e19..f3758f5ce6 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -79,7 +79,10 @@ circular or dotted.  If a program doesn't look far enough 
down the
 list to see the @sc{cdr} of the final cons cell, it won't care.
 However, some functions that operate on lists demand proper lists and
 signal errors if given a dotted list.  Most functions that try to find
-the end of a list enter infinite loops if given a circular list.
+the end of a list enter infinite loops if given a circular list.  You
+can use the function @code{proper-list-p}, described in the next
+section (@pxref{List-related Predicates, proper-list-p}), to determine
+whether a list is a proper one.
 
 @cindex list structure
   Because most cons cells are used as part of lists, we refer to any
@@ -1914,6 +1917,11 @@ properties.  Every symbol possesses a list of 
properties, used to
 record miscellaneous information about the symbol; these properties
 are stored in the form of a property list.  @xref{Symbol Properties}.
 
+@defun plistp object
+This predicate function returns non-@code{nil} if @var{object} is a
+valid property list.
+@end defun
+
 @menu
 * Plists and Alists::           Comparison of the advantages of property
                                   lists and association lists.
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index fe5eb8a1b8..750c4b4789 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -2578,21 +2578,70 @@ header line, for windows displaying the buffer.  The 
format of the value
 is the same as for @code{mode-line-format} (@pxref{Mode Line Data}).
 It is normally @code{nil}, so that ordinary buffers have no header
 line.
+@end defvar
+
+If @code{display-line-numbers-mode} is turned on in a buffer
+(@pxref{Display Custom, display-line-numbers-mode,, emacs, The GNU
+Emacs Manual}), the buffer text is indented on display by the amount
+of screen space needed to show the line numbers.  By contrast, text of
+the header line is not automatically indented, because a header line
+never displays a line number, and because the text of the header line
+is not necessarily directly related to buffer text below it.  If a
+Lisp program needs the header-line text to be aligned with buffer text
+(for example, if the buffer displays columnar data, like
+@code{tabulated-list-mode} does, @pxref{Tabulated List Mode}), it
+should turn on the minor mode @code{header-line-indent-mode}.
+
+@deffn Command header-line-indent-mode
+This buffer-local minor mode tracks the changes of the width of the
+line-number display on screen (which may vary depending on the range
+of line numbers shown in the window), and allows Lisp programs to
+arrange that header-line text is always aligned with buffer text when
+the line-number width changes.  Such Lisp programs should turn on this
+mode in the buffer, and use the variables @code{header-line-indent}
+and @code{header-line-indent-width} in the @code{header-line-format}
+to ensure it is adjusted to the text indentation at all times.
+@end deffn
 
-@findex header-line-indent-mode
-If @code{display-line-numbers-mode} is used, and you want the header
-line to be indented by the same amount as the buffer contents, you can
-use the @code{header-line-indent-mode} minor mode.  This minor mode
-keeps the @code{header-line-indent} variable updated, so that you can
-say something like:
+@defvar header-line-indent
+This variable's value is a whitespace string whose width is kept equal
+to the current width of line-numbers on display, provided that
+@code{header-line-indent-mode} is turned on in the buffer shown in the
+window.  The number of spaces is calculated under the assumption that
+the face of the header-line text uses the same font, including size,
+as the frame's default font; if that assumption is false, use
+@code{header-line-indent-width}, described below, instead.  This
+variable is intended to be used in simple situations where the
+header-line text needs to be indented as a whole to be realigned with
+buffer text, by prepending this variable's value to the actual
+header-line text.  For example, the following definition of
+@code{header-line-format}:
 
 @lisp
 (setq header-line-format
-      `("" header-line-format ,my-header-line))
+      `("" header-line-indent ,my-header-line))
 @end lisp
 
-This can be useful if you're displaying columnar data, and the header
-line should align with that data in the buffer.
+@noindent
+where @code{my-header-line} is the format string that produces the
+actual text of the header line, will make sure the header-line text
+is always indented like the buffer text below it.
+@end defvar
+
+@defvar header-line-indent-width
+This variable's value is kept updated to provide the current width, in
+units of the frame's canonical character width, used for displaying
+the line numbers, provided that @code{header-line-indent-mode} is
+turned on in the buffer shown in the window.  It can be used for
+aligning the header-line text with the buffer text when
+@code{header-line-indent} is not flexible enough.  For example, if the
+header line uses a font whose metrics is different from the default
+face's font, your Lisp program can calculate the width of line-number
+display in pixels, by multiplying the value of this variable by the
+value returned by @code{frame-char-width} (@pxref{Frame Font}), and
+then use the result to align header-line text using the
+@code{:align-to} display property spec (@pxref{Specified Space}) in
+pixels on the relevant parts of @code{header-line-frormat}.
 @end defvar
 
 @defun window-header-line-height &optional window
diff --git a/doc/misc/efaq.texi b/doc/misc/efaq.texi
index 396a475384..4a8c863230 100644
--- a/doc/misc/efaq.texi
+++ b/doc/misc/efaq.texi
@@ -847,6 +847,7 @@ in the Emacs development repository (@pxref{Latest version 
of Emacs}).
 @menu
 * Origin of the term Emacs::
 * Latest version of Emacs::
+* New in Emacs 29::
 * New in Emacs 28::
 * New in Emacs 27::
 * New in Emacs 26::
@@ -919,6 +920,125 @@ Emacs, type @kbd{C-h C-n} (@kbd{M-x view-emacs-news}).  
You can give
 this command a prefix argument to read about which features were new
 in older versions.
 
+@node New in Emacs 29
+@section What is different about Emacs 29?
+@cindex Differences between Emacs 28 and Emacs 29
+@cindex Emacs 29, new features in
+
+Here's a list of the most important changes in Emacs 29 as compared to
+Emacs 28 (the full list is too long, and can be read in the Emacs
+@file{NEWS} file by typing @kbd{C-h n} inside Emacs).
+
+@itemize
+@item
+Emacs can now be built with the
+@uref{https://tree-sitter.github.io/tree-sitter/, tree-sitter
+library}, which provides incremental parsing capabilities for several
+programming languages.  Emacs comes with several major modes which use
+this library for syntax highlighting (a.k.a. ``fontification''),
+indentation, Imenu support, etc.  These modes have names
+@code{@var{lang}-ts-mode}, where @var{lang} is the programming
+language.  For example, @code{c-ts-mode}, @code{ruby-ts-mode}, etc.
+There are several new font-lock faces, such as
+@code{font-lock-number-face} and @code{font-lock-operator-face},
+intended to be used with these modes.
+
+@item
+Emacs can now be built in the PGTK (``pure GTK'') configuration, which
+supports running Emacs on window systems other than X, such as Wayland
+and Broadway.
+
+@item
+Emacs now has built-in support for accessing SQLite databases.  This
+requires Emacs to be built with the optional @file{sqlite3} library.
+
+@item
+Emacs comes with the popular @code{use-package} package bundled.
+
+@item
+Emacs can now display WebP images, if it was built with the optional
+@file{libwebp} library.
+
+@item
+On X window system, Emacs now supports the XInput2 specification for
+input events.
+
+@item
+Emacs now comes with a client library for using Language Server
+Protocol (@acronym{LSP}) servers.  This library, named @file{eglot.el}
+(the name stands for ``Emacs polyGlot'') provides LSP support for
+various software development and maintenance features, such as
+@code{xref}, Imenu, ElDoc, etc.
+
+@item
+Emacs can now cope with files with very long lines much better.  It no
+longer hangs when displaying such long lines, and allows
+reasonably-responsive editing when such lines are present in the
+visible portion of a buffer.
+
+@item
+Emacs now supports the latest version 15.0 of the Unicode Standard.
+
+@item
+The new mode @code{pixel-scroll-precision-mode} allows precise and
+smooth scrolling of the display at pixel resolution, if your mouse
+supports this.
+
+@item
+Emacs now supports 24-bit true colors on more terminals.
+
+@item
+On capable X terminal emulators, Emacs now supports setting the X
+primary selection on TTY frames.
+
+@item
+New convenient commands are now available for inserting, searching,
+listing, and describing Emoji.  These commands are on the @w{@kbd{C-x
+8 e}} prefix key.  The commands @kbd{C-u C-x =}
+(@code{what-cursor-position}) and @kbd{M-x describe-char} now show the
+names of Emoji sequences at point.
+
+@item
+The Help commands were enhanced:
+
+@itemize @minus
+@item
+@kbd{M-x apropos-variable} shows the values of the matching variables.
+@item
+@kbd{C-h b} activates @code{outline-minor-mode} in the buffer, which
+makes it easier to browse long lists of key bindings.
+@item
+@kbd{I} in the @file{*Help*} buffer displays the corresponding
+documentation in the Emacs Lisp Reference manual.
+@item
+New command @code{help-quick} displays a buffer with overview of
+common Help commands.
+@end itemize
+
+@item
+Outline Minor mode uses buttons to hide and show outlines.
+
+@item
+Deleted frames can now be undeleted using @kbd{C-x 5 u}, if the
+optional @code{undelete-frame-mode} is enabled.
+
+@item
+You can now delete the entire composed sequence of characters with
+@key{Delete} and edits the composed sequence by turning on the
+@code{composition-break-at-point} option.
+
+@item
+Support is added for many old scripts and writing systems, such as Tai
+Tham, Brahmi, Tirhuta, Modi, Lepcha, and many others.
+
+@item
+New translations of the Emacs tutorial: Ukrainian and Greek.
+
+@item
+New major modes for Typescript, Csharp, CMake, Go, Rust, and Yaml.
+@end itemize
+
+
 @node New in Emacs 28
 @section What is different about Emacs 28?
 @cindex Differences between Emacs 27 and Emacs 28
diff --git a/etc/NEWS.29 b/etc/NEWS.29
index e3cbeb84d3..2d15e39036 100644
--- a/etc/NEWS.29
+++ b/etc/NEWS.29
@@ -3946,9 +3946,11 @@ This argument can be used to override values of 
print-related settings.
 
 +++
 ** New minor mode 'header-line-indent-mode'.
-This is meant to be used in modes that have a header line that should
-be kept aligned with the buffer contents when the user switches
-'display-line-numbers-mode' on or off.
+This is meant to be used by Lisp programs that show a header line
+which should be kept aligned with the buffer contents when the user
+switches 'display-line-numbers-mode' on or off, and when the width of
+line-number display changes.  See the "(elisp) Header Lines" node in
+the Emacs Lisp Reference manual for more information.
 
 +++
 ** New global minor mode 'lost-selection-mode'.
diff --git a/etc/compilation.txt b/etc/compilation.txt
index 672cbebaff..5f6ecb09cc 100644
--- a/etc/compilation.txt
+++ b/etc/compilation.txt
@@ -639,6 +639,20 @@ symbol: weblint
 index.html (13:1) Unknown element <fdjsk>
 
 
+* Typescript prior to tsc version 2.7, "plain" format
+
+symbol: typescript-tsc-plain
+
+greeter.ts(30,12): error TS2339: Property 'foo' does not exist.
+
+
+* Typescript after tsc version 2.7, "pretty" format
+
+symbol: typescript-tsc-pretty
+
+src/resources/document.ts:140:22 - error TS2362: something.
+
+
 * Directory tracking
 
 Directories are matched via 'compilation-directory-matcher'.  Files which are
diff --git a/lisp/display-line-numbers.el b/lisp/display-line-numbers.el
index 37cf7ade46..4f87ffd0e2 100644
--- a/lisp/display-line-numbers.el
+++ b/lisp/display-line-numbers.el
@@ -112,19 +112,27 @@ the mode is on, set `display-line-numbers' directly."
 
 ;;;###autoload
 (defvar header-line-indent ""
-  "String to indent at the start if the header line.
-This is used in `header-line-indent-mode', and buffers that have
-this switched on should have a `header-line-format' that look like:
+  "String of spaces to indent the beginning of header-line due to line numbers.
+This is intended to be used in `header-line-format', and requires
+the `header-line-indent-mode' to be turned on, in order for the width
+of this string to be kept updated when the line-number width changes
+on display.  An example of a `header-line-format' that uses this
+variable might look like this:
 
   (\"\" header-line-indent THE-REST...)
 
+where THE-REST is the format string which produces the actual text
+of the header-line.
 Also see `header-line-indent-width'.")
 
 ;;;###autoload
 (defvar header-line-indent-width 0
-  "The width of the current line numbers displayed.
-This is updated when `header-line-indent-mode' is switched on.
-
+  "The width of the current line number display in the window.
+This is measured in units of the frame's canonical columns.
+This is updated when `header-line-indent-mode' is switched on,
+and is intended for use in `:align-to' display specifications
+that are part of `header-line-format', when portions of header-line
+text should be aligned to respective parts of buffer text.
 Also see `header-line-indent'.")
 
 (defun header-line-indent--line-number-width ()
@@ -155,21 +163,30 @@ Also see `header-line-indent'.")
 
 ;;;###autoload
 (define-minor-mode header-line-indent-mode
-  "Mode to indent the header line in `display-line-numbers-mode' buffers.
-This means that the header line will be kept indented so that it
-has blank space that's as wide as the displayed line numbers in
-the buffer.
+  "Minor mode to help with alignment of header line when line numbers are 
shown.
+This minor mode should be turned on in buffers which display header-line
+that needs to be aligned with buffer text when `display-line-numbers-mode'
+is turned on in the buffer.
 
-Buffers that have this switched on should have a
-`header-line-format' that look like:
+Buffers that have this switched on should have a `header-line-format'
+that uses the `header-line-indent' or the `header-line-indent-width'
+variables, which this mode will keep up-to-date with the current
+display of line numbers.  For example, a `header-line-format' that
+looks like this:
 
   (\"\" header-line-indent THE-REST...)
 
-The `header-line-indent-width' variable is also kept updated, and
-has the width of `header-line-format'.  This can be used, for
-instance, in `:align-to' specs, like:
+will make sure the text produced by THE-REST (which should be
+a header-line format string) is always indented to be aligned on
+display with the first column of buffer text.
+
+The `header-line-indent-width' variable is also kept updated,
+and can be used, for instance, in `:align-to' specs as part
+of `header-line-format', like this:
+
+  (space :align-to (+ header-line-indent-width 10))
 
-  (space :align-to (+ header-line-indent-width 10))"
+See also `line-number-display-width'."
   :lighter nil
   (if header-line-indent-mode
       (progn
diff --git a/lisp/erc/erc-sasl.el b/lisp/erc/erc-sasl.el
index a0b36d0761..97c7c54a51 100644
--- a/lisp/erc/erc-sasl.el
+++ b/lisp/erc/erc-sasl.el
@@ -67,12 +67,11 @@ Note that any value other than nil or `external' likely 
requires
 
 (defcustom erc-sasl-user :user
   "Account username to send when authenticating.
-This is also referred to as the authentication identity or
+This option specifies the SASL authentication identity, or
 \"authcid\".  A value of `:user' or `:nick' indicates that the
-corresponding connection parameter on file should be used.  These
-are most often derived from arguments provided to the `erc' and
-`erc-tls' entry points.  In the case of `:nick', a downcased
-version is used."
+corresponding connection parameter on file should be used.  ERC
+typically obtains these from arguments given to its entry-point
+commands, `erc' and `erc-tls'."
   :type '(choice string (const :user) (const :nick)))
 
 (defcustom erc-sasl-password :password
@@ -129,7 +128,7 @@ integration."
 (defun erc-sasl--get-user ()
   (pcase (alist-get 'user erc-sasl--options)
     (:user erc-session-username)
-    (:nick (erc-downcase (erc-current-nick)))
+    (:nick (erc-current-nick))
     (v v)))
 
 (defun erc-sasl-auth-source-password-as-host (&rest plist)
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index 1fa45379b9..9e944fe188 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -1154,6 +1154,8 @@ Put first the functions more likely to cause a change and 
cheaper to compute.")
   "Fontify the text between BEG and END.
 If LOUDLY is non-nil, print status messages while fontifying.
 This function is the default `font-lock-fontify-region-function'."
+  (or (<= end (point-max))
+      (setq end (point-max)))
   (with-silent-modifications
    ;; Use the fontification syntax table, if any.
    (with-syntax-table (or font-lock-syntax-table (syntax-table))
diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el
index 2d17cf639b..bcd4aac4f2 100644
--- a/lisp/international/emoji.el
+++ b/lisp/international/emoji.el
@@ -245,6 +245,7 @@ the name is not known."
           (error "Emoji name is unknown")
         (message "%s" name)))))
 
+;;;###autoload
 (defun emoji--init (&optional force inhibit-adjust)
   (when (or (not emoji--labels)
             force)
@@ -638,7 +639,7 @@ We prefer the earliest unique letter."
                          collect (cons (concat (string prefix) "-group")
                                        (seq-take bit 77))))))))
 
-(defun emoji--choose-emoji ()
+(defun emoji--read-emoji ()
   ;; Use the list of names.
   (let* ((table
           (if (not emoji-alternate-names)
@@ -678,21 +679,24 @@ We prefer the earliest unique letter."
               (complete-with-action action table string pred)))
            nil t)))
     (when (cl-plusp (length name))
-      (let* ((glyph (if emoji-alternate-names
-                        (cadr (split-string name "\t"))
-                      (gethash name emoji--all-bases)))
-             (derived (gethash glyph emoji--derived)))
-        (if (not derived)
-            ;; Simple glyph with no derivations.
-            (progn
-              (emoji--add-recent glyph)
-              (insert glyph))
-          ;; Choose a derived version.
-          (let ((emoji--done-derived (make-hash-table :test #'equal)))
-            (setf (gethash glyph emoji--done-derived) t)
-            (funcall
-             (emoji--define-transient
-              (cons "Choose Emoji" (cons glyph derived))))))))))
+      (let ((glyph (if emoji-alternate-names
+                       (cadr (split-string name "\t"))
+                     (gethash name emoji--all-bases))))
+        (cons glyph (gethash glyph emoji--derived))))))
+
+(defun emoji--choose-emoji ()
+  (pcase-let ((`(,glyph . ,derived) (emoji--read-emoji)))
+    (if (not derived)
+        ;; Simple glyph with no derivations.
+        (progn
+          (emoji--add-recent glyph)
+          (insert glyph))
+      ;; Choose a derived version.
+      (let ((emoji--done-derived (make-hash-table :test #'equal)))
+        (setf (gethash glyph emoji--done-derived) t)
+        (funcall
+         (emoji--define-transient
+          (cons "Choose Emoji" (cons glyph derived))))))))
 
 (defvar-keymap emoji-zoom-map
   "+" #'emoji-zoom-increase
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 22e2776412..094e02d605 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -2774,25 +2774,22 @@ With argument, add COUNT copies of the character."
                                           (mapconcat 
'isearch-text-char-description
                                                      string ""))))))))
 
-(defvar emoji--derived)
+(autoload 'emoji--read-emoji "emoji")
 (defun isearch-emoji-by-name (&optional count)
   "Read an Emoji name and add it to the search string COUNT times.
 COUNT (interactively, the prefix argument) defaults to 1.
 The command accepts Unicode names like \"smiling face\" or
 \"heart with arrow\", and completion is available."
   (interactive "p")
+  (emoji--init)
   (with-isearch-suspended
-   (let ((emoji (with-temp-buffer
-                  ;; Derived emoji not supported yet (bug#60740).
-                  ;; So first load `emoji--labels', then `emoji--init'
-                  ;; will not fill `emoji--derived' that is set
-                  ;; to an empty hash table below.
-                  (ignore-errors (require 'emoji-labels))
-                  (let ((emoji--derived (make-hash-table :test #'equal)))
-                    (emoji-search))
-                  (if (and (integerp count) (> count 1))
-                      (apply 'concat (make-list count (buffer-string)))
-                    (buffer-string)))))
+   (pcase-let* ((`(,glyph . ,derived) (emoji--read-emoji))
+                (emoji (if derived
+                           (completing-read "Select derivation: "
+                                            (cons glyph derived) nil t)
+                         glyph)))
+     (when (and (integerp count) (> count 1))
+       (setq emoji (apply 'concat (make-list count emoji))))
      (when emoji
        (setq isearch-new-string (concat isearch-string emoji)
              isearch-new-message (concat isearch-message
diff --git a/lisp/keymap.el b/lisp/keymap.el
index 201a49cef8..4f02639ffe 100644
--- a/lisp/keymap.el
+++ b/lisp/keymap.el
@@ -65,7 +65,7 @@ DEFINITION is anything that can be a key's definition:
     (setq definition (key-parse definition)))
   (define-key keymap (key-parse key) definition))
 
-(defun keymap-global-set (key command)
+(defun keymap-global-set (key command &optional interactive)
   "Give KEY a global binding as COMMAND.
 COMMAND is the command definition to use; usually it is
 a symbol naming an interactively-callable function.
@@ -75,13 +75,14 @@ KEY is a string that satisfies `key-valid-p'.
 Note that if KEY has a local binding in the current buffer,
 that local binding will continue to shadow any global binding
 that you make with this function."
-  (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
-  (interactive "KSet key globally:\nCSet key %s globally to command: ")
-  (unless (stringp key)
+  (declare (compiler-macro (lambda (form) (keymap--compile-check key) form))
+           (advertised-calling-convention (key command) "29.1"))
+  (interactive "KSet key globally: \nCSet key %s globally to command: \np")
+  (when interactive
     (setq key (key-description key)))
   (keymap-set (current-global-map) key command))
 
-(defun keymap-local-set (key command)
+(defun keymap-local-set (key command &optional interactive)
   "Give KEY a local binding as COMMAND.
 COMMAND is the command definition to use; usually it is
 a symbol naming an interactively-callable function.
@@ -90,12 +91,13 @@ KEY is a string that satisfies `key-valid-p'.
 
 The binding goes in the current buffer's local map, which in most
 cases is shared with all other buffers in the same major mode."
-  (declare (compiler-macro (lambda (form) (keymap--compile-check key) form)))
-  (interactive "KSet key locally:\nCSet key %s locally to command: ")
+  (declare (compiler-macro (lambda (form) (keymap--compile-check key) form))
+           (advertised-calling-convention (key command) "29.1"))
+  (interactive "KSet key locally: \nCSet key %s locally to command: \np")
   (let ((map (current-local-map)))
     (unless map
       (use-local-map (setq map (make-sparse-keymap))))
-    (unless (stringp key)
+    (when interactive
       (setq key (key-description key)))
     (keymap-set map key command)))
 
diff --git a/lisp/paren.el b/lisp/paren.el
index b2a79624c0..4c91fd2949 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -122,7 +122,8 @@ On non-graphical frames, the context is shown in the echo 
area."
   "Whether to use `show-paren-mode' in a buffer.
 The default is to enable the mode in all buffers that don't
 derive from `special-mode', which means that it's on (by default)
-in all editing buffers."
+in all editing buffers.
+The predicate is passed as argument to `buffer-match-p', which see."
   :type 'buffer-predicate
   :safe #'booleanp
   :version "29.1")
@@ -160,13 +161,14 @@ use `show-paren-local-mode'."
 ;;;###autoload
 (define-minor-mode show-paren-local-mode
   "Toggle `show-paren-mode' only in this buffer."
-  :variable ( show-paren-mode .
-              (lambda (val) (setq-local show-paren-mode val)))
+  :variable ((show-paren--enabled-p)
+             .
+             (lambda (val) (setq-local show-paren-mode val)))
   (cond
    ((eq show-paren-mode (default-value 'show-paren-mode))
     (unless show-paren-mode
-      (show-paren--delete-overlays))
-    (kill-local-variable 'show-paren-mode))
+      (show-paren--delete-overlays)
+      (kill-local-variable 'show-paren-mode)))
    ((not (default-value 'show-paren-mode))
     ;; Locally enabled, but globally disabled.
     (show-paren-mode 1)                ; Setup the timer.
@@ -427,14 +429,17 @@ It is the default value of `show-paren-data-function'."
 ;; `show-paren-delay'.
 (defvar-local show-paren--last-pos nil)
 
+(defun show-paren--enabled-p ()
+  (and show-paren-mode
+       ;; If we're using `show-paren-local-mode', then
+       ;; always heed the value.
+       (or (local-variable-p 'show-paren-mode)
+           ;; If not, check that the predicate matches.
+           (buffer-match-p show-paren-predicate (current-buffer)))))
+
 (defun show-paren-function ()
   "Highlight the parentheses until the next input arrives."
-  (let ((data (and show-paren-mode
-                   ;; If we're using `show-paren-local-mode', then
-                   ;; always heed the value.
-                   (or (local-variable-p 'show-paren-mode)
-                       ;; If not, check that the predicate matches.
-                       (buffer-match-p show-paren-predicate (current-buffer)))
+  (let ((data (and (show-paren--enabled-p)
                    (funcall show-paren-data-function))))
     (if (not data)
         (progn
diff --git a/lisp/progmodes/bug-reference.el b/lisp/progmodes/bug-reference.el
index d7dd3ed1c9..9f1439e6a0 100644
--- a/lisp/progmodes/bug-reference.el
+++ b/lisp/progmodes/bug-reference.el
@@ -599,12 +599,7 @@ and set it if applicable."
      (erc-format-target)
      (erc-network-name))))
 
-(defvar bug-reference-auto-setup-functions
-  (list #'bug-reference-try-setup-from-vc
-        #'bug-reference-try-setup-from-gnus
-        #'bug-reference-try-setup-from-rmail
-        #'bug-reference-try-setup-from-rcirc
-        #'bug-reference-try-setup-from-erc)
+(defvar bug-reference-auto-setup-functions nil
   "Functions trying to auto-setup `bug-reference-mode'.
 These functions are run after `bug-reference-mode' has been
 activated in a buffer and try to guess suitable values for
@@ -616,7 +611,36 @@ guesswork is based on these variables:
 - `bug-reference-setup-from-mail-alist' for guessing based on
   mail group names or mail header values.
 - `bug-reference-setup-from-irc-alist' for guessing based on IRC
-  channel or network names.")
+  channel or network names.
+
+Note: This variable's purpose is to allow packages to provide
+bug-reference auto-setup support in buffers managed by this
+package.  Therefore, such auto-setup function should check if the
+current buffer is \"their\" buffer and only act if that's the
+case, e.g., in terms of `derived-mode-p'.
+
+The variable is not intended for users.  Those are advised to set
+`bug-reference-bug-regexp' and `bug-reference-url-format' using
+other means such as file-local variable sections, a
+`.dir-locals.el' file, or compute and set their values in
+`bug-reference-mode-hook' or `bug-reference-prog-mode-hook'.  If
+the bug regexp and URL format are already set after those hooks
+have been run, the auto-setup is inhibited.")
+
+;; Add the default auto-setup functions.  We don't have them as
+;; init value of bug-reference-auto-setup-functions because then
+;; they wouldn't be added if some package uses
+;;
+;;   (add-hook 'bug-reference-auto-setup-functions
+;;             #'my-pkg--bug-reference-try-setup-from-my-pkg)
+;;
+;; before bug-reference.el is loaded.
+(dolist (fn (list #'bug-reference-try-setup-from-vc
+                  #'bug-reference-try-setup-from-gnus
+                  #'bug-reference-try-setup-from-rmail
+                  #'bug-reference-try-setup-from-rcirc
+                  #'bug-reference-try-setup-from-erc))
+  (add-hook 'bug-reference-auto-setup-functions fn))
 
 (defun bug-reference--run-auto-setup ()
   (when (or bug-reference-mode
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 8729cae4ba..8262e6261d 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -51,6 +51,7 @@
 (declare-function treesit-node-end "treesit.c")
 (declare-function treesit-node-type "treesit.c")
 (declare-function treesit-node-parent "treesit.c")
+(declare-function treesit-node-prev-sibling "treesit.c")
 
 ;;; Comment indentation and filling
 
@@ -266,26 +267,56 @@ This should be the symbol of the indent offset variable 
for the
 particular major mode.  This cannot be nil for `c-ts-common'
 statement indent functions to work.")
 
-(defvar c-ts-common-indent-block-type-regexp nil
-  "Regexp matching types of block nodes (i.e., {} blocks).
+(defvar c-ts-common-indent-type-regexp-alist nil
+  "An alist of of node type regexps.
 
-This cannot be nil for `c-ts-common' statement indent functions
-to work.")
+Each key in the alist is one of `if', `else', `do', `while',
+`for', `block', `close-bracket'.  Each value in the alist
+is the regexp matching the type of that kind of node.  Most of
+these types are self-explanatory, e.g., `if' corresponds to
+\"if_statement\" in C.  `block' corresponds to the {} block.
 
-(defvar c-ts-common-indent-bracketless-type-regexp nil
-  "A regexp matching types of bracketless constructs.
+Some types, specifically `else', is usually not identified by a
+standalone node, but a child under the \"if_statement\", under a
+field name like \"alternative\", etc.  In that case, use a
+cons (TYPE . FIELD-NAME) as the value, where TYPE is the node's
+parent's type, and FIELD-NAME is the field name of the node.
 
-These constructs include if, while, do-while, for statements.  In
-these statements, the body can omit the bracket, which requires
-special handling from our bracket-counting indent algorithm.
+If the language doesn't have a particular type, it is fine to
+omit it.")
 
-This can be nil, meaning such special handling is not needed.")
+(defun c-ts-common--node-is (node &rest types)
+  "Return non-nil if NODE is any one of the TYPES.
 
-(defun c-ts-common-statement-offset (node parent bol &rest _)
+TYPES can be any of `if', `else', `while', `do', `for', and
+`block'.
+
+If NODE is nil, return nil."
+  (declare (indent 2))
+  (catch 'ret
+    (when (null node)
+      (throw 'ret nil))
+    (dolist (type types)
+      (let ((regexp (alist-get
+                     type c-ts-common-indent-type-regexp-alist))
+            (parent (treesit-node-parent node)))
+        (when (and regexp
+                   (if (consp regexp)
+                       (and parent
+                            (string-match-p (car regexp)
+                                            (treesit-node-type parent))
+                            (string-match-p (cdr regexp)
+                                            (treesit-node-field-name
+                                             node)))
+                     (string-match-p regexp (treesit-node-type node))))
+          (throw 'ret t))))
+    nil))
+
+(defun c-ts-common-statement-offset (node parent &rest _)
   "This anchor is used for children of a statement inside a block.
 
 This function basically counts the number of block nodes (i.e.,
-brackets) (defined by `c-ts-mode--indent-block-type-regexp')
+brackets) (defined by `c-ts-common-indent-block-type-regexp')
 between NODE and the root node (not counting NODE itself), and
 multiply that by `c-ts-common-indent-offset'.
 
@@ -299,10 +330,7 @@ characters on the current line."
     ;; If NODE is a opening/closing bracket on its own line, take off
     ;; one level because the code below assumes NODE is a statement
     ;; _inside_ a {} block.
-    (when (and node
-               (or (string-match-p c-ts-common-indent-block-type-regexp
-                                   (treesit-node-type node))
-                   (save-excursion (goto-char bol) (looking-at-p "}"))))
+    (when (c-ts-common--node-is node 'block 'close-bracket)
       (cl-decf level))
     ;; If point is on an empty line, NODE would be nil, but we pretend
     ;; there is a statement node.
@@ -312,48 +340,35 @@ characters on the current line."
     (while (if (eq node t)
                (setq node parent)
              node)
-      (when (string-match-p c-ts-common-indent-block-type-regexp
-                            (treesit-node-type node))
-        (cl-incf level)
-        (save-excursion
-          (goto-char (treesit-node-start node))
-          ;; Add an extra level if the opening bracket is on its own
-          ;; line, except (1) it's at top-level, or (2) it's immediate
-          ;; parent is another block.
-          (cond ((bolp) nil) ; Case (1).
-                ((let ((parent-type (treesit-node-type
-                                     (treesit-node-parent node))))
-                   ;; Case (2).
-                   (and parent-type
-                        (string-match-p
-                         c-ts-common-indent-block-type-regexp
-                         parent-type)))
-                 nil)
-                ;; Add a level.
-                ((looking-back (rx bol (* whitespace))
-                               (line-beginning-position))
-                 (cl-incf level)))))
-      (setq level (c-ts-mode--fix-bracketless-indent level node))
+      (let ((parent (treesit-node-parent node)))
+        ;; Increment level for every bracket (with exception).
+        (when (c-ts-common--node-is node 'block)
+          (cl-incf level)
+          (save-excursion
+            (goto-char (treesit-node-start node))
+            ;; Add an extra level if the opening bracket is on its own
+            ;; line, except (1) it's at top-level, or (2) it's immediate
+            ;; parent is another block.
+            (cond ((bolp) nil) ; Case (1).
+                  ((c-ts-common--node-is parent 'block) ; Case (2).
+                   nil)
+                  ;; Add a level.
+                  ((looking-back (rx bol (* whitespace))
+                                 (line-beginning-position))
+                   (cl-incf level)))))
+        ;; Fix bracketless statements.
+        (when (and (c-ts-common--node-is parent
+                       'if 'do 'while 'for)
+                   (not (c-ts-common--node-is node 'block)))
+          (cl-incf level))
+        ;; Flatten "else if" statements.
+        (when (and (c-ts-common--node-is node 'else)
+                   (c-ts-common--node-is node 'if))
+          (cl-decf level)))
       ;; Go up the tree.
       (setq node (treesit-node-parent node)))
     (* level (symbol-value c-ts-common-indent-offset))))
 
-(defun c-ts-mode--fix-bracketless-indent (level node)
-  "Takes LEVEL and NODE and return adjusted LEVEL.
-This fixes indentation for cases shown in bug#61026.  Basically
-in C-like syntax, statements like if, for, while sometimes omit
-the bracket in the body."
-  (let ((block-re c-ts-common-indent-block-type-regexp)
-        (statement-re
-         c-ts-common-indent-bracketless-type-regexp)
-        (node-type (treesit-node-type node))
-        (parent-type (treesit-node-type (treesit-node-parent node))))
-    (if (and block-re statement-re node-type parent-type
-             (not (string-match-p block-re node-type))
-             (string-match-p statement-re parent-type))
-        (1+ level)
-      level)))
-
 (provide 'c-ts-common)
 
 ;;; c-ts-common.el ends here
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 586849e9a3..dbee53cd7a 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -89,18 +89,19 @@
 
 (defun c-ts-mode--indent-style-setter (sym val)
   "Custom setter for `c-ts-mode-set-style'.
+
 Apart from setting the default value of SYM to VAL, also change
-the value of SYM in `c-ts-mode' and `c++-ts-mode' buffers to VAL."
+the value of SYM in `c-ts-mode' and `c++-ts-mode' buffers to VAL.
+
+SYM should be `c-ts-mode-indent-style', and VAL should be a style
+symbol."
   (set-default sym val)
   (named-let loop ((res nil)
                    (buffers (buffer-list)))
     (if (null buffers)
         (mapc (lambda (b)
                 (with-current-buffer b
-                  (setq-local treesit-simple-indent-rules
-                              (treesit--indent-rules-optimize
-                               (c-ts-mode--get-indent-style
-                                (if (derived-mode-p 'c-ts-mode) 'c 'cpp))))))
+                  (c-ts-mode-set-style val)))
               res)
       (let ((buffer (car buffers)))
         (with-current-buffer buffer
@@ -112,8 +113,8 @@ the value of SYM in `c-ts-mode' and `c++-ts-mode' buffers 
to VAL."
   "Style used for indentation.
 
 The selected style could be one of GNU, K&R, LINUX or BSD.  If
-one of the supplied styles doesn't suffice a function could be
-set instead.  This function is expected return a list that
+one of the supplied styles doesn't suffice, a function could be
+set instead.  This function is expected to return a list that
 follows the form of `treesit-simple-indent-rules'."
   :version "29.1"
   :type '(choice (symbol :tag "Gnu" gnu)
@@ -134,7 +135,7 @@ MODE is either `c' or `cpp'."
     `((,mode ,@style))))
 
 (defun c-ts-mode--prompt-for-style ()
-  "Prompt for a indent style and return the symbol for it."
+  "Prompt for an indent style and return the symbol for it."
   (let ((mode (if (derived-mode-p 'c-ts-mode) 'c 'c++)))
     (intern
      (completing-read
@@ -142,16 +143,20 @@ MODE is either `c' or `cpp'."
       (mapcar #'car (c-ts-mode--indent-styles mode))
       nil t nil nil "gnu"))))
 
-(defun c-ts-mode-set-style (style)
+(defun c-ts-mode-set-global-style (style)
   "Set the indent style of C/C++ modes globally to STYLE.
 
 This changes the current indent style of every C/C++ buffer and
-the default C/C++ indent style in this Emacs session."
+the default C/C++ indent style for `c-ts-mode' and `c++-ts-mode'
+in this Emacs session."
   (interactive (list (c-ts-mode--prompt-for-style)))
   (c-ts-mode--indent-style-setter 'c-ts-mode-indent-style style))
 
-(defun c-ts-mode-set-local-style (style)
-  "Set the C/C++ indent style of the current buffer to STYLE."
+(defun c-ts-mode-set-style (style)
+  "Set the C/C++ indent style of the current buffer to STYLE.
+
+To set the default indent style globally, use
+`c-ts-mode-set-global-style'."
   (interactive (list (c-ts-mode--prompt-for-style)))
   (if (not (derived-mode-p 'c-ts-mode 'c++-ts-mode))
       (user-error "The current buffer is not in `c-ts-mode' nor `c++-ts-mode'")
@@ -233,6 +238,13 @@ MODE is either `c' or `cpp'."
            ((parent-is "labeled_statement")
             point-min c-ts-common-statement-offset)
 
+           ;; Bracketless statement matchers.
+           ((match nil "while_statement" "condition") parent-bol 
c-ts-mode-indent-offset)
+           ((match nil "if_statement" "consequence") parent-bol 
c-ts-mode-indent-offset)
+           ((match nil "if_statement" "alternative") parent-bol 
c-ts-mode-indent-offset)
+           ((match nil "do_statement" "body") parent-bol 
c-ts-mode-indent-offset)
+           ((match nil "for_statement" "body") parent-bol 
c-ts-mode-indent-offset)
+
            ((match "preproc_ifdef" "compound_statement") point-min 0)
            ((match "#endif" "preproc_ifdef") point-min 0)
            ((match "preproc_if" "compound_statement") point-min 0)
@@ -273,6 +285,14 @@ MODE is either `c' or `cpp'."
            ((node-is "}") point-min c-ts-common-statement-offset)
            ;; Opening bracket.
            ((node-is "compound_statement") point-min 
c-ts-common-statement-offset)
+           ;; Bug#61291.
+           ((match "expression_statement" nil "body") point-min 
c-ts-common-statement-offset)
+           ;; These rules are for cases where the body is bracketless.
+           ;; Tested by the "Bracketless Simple Statement" test.
+           ((parent-is "if_statement") point-min c-ts-common-statement-offset)
+           ((parent-is "for_statement") point-min c-ts-common-statement-offset)
+           ((parent-is "while_statement") point-min 
c-ts-common-statement-offset)
+           ((parent-is "do_statement") point-min c-ts-common-statement-offset)
 
            ,@(when (eq mode 'cpp)
                `(((node-is "field_initializer_list") parent-bol ,(* 
c-ts-mode-indent-offset 2)))))))
@@ -440,11 +460,10 @@ MODE is either `c' or `cpp'."
       declarator: (_) @c-ts-mode--fontify-declarator)
 
      (function_definition
-      declarator: (_) @c-ts-mode--fontify-declarator))
+      declarator: (_) @c-ts-mode--fontify-declarator)
 
-   ;; Should we highlight identifiers in the parameter list?
-   ;; (parameter_declaration
-   ;;  declarator: (_) @c-ts-mode--fontify-declarator))
+     (parameter_declaration
+      declarator: (_) @c-ts-mode--fontify-declarator))
 
    :language mode
    :feature 'assignment
@@ -466,7 +485,9 @@ MODE is either `c' or `cpp'."
    :language mode
    :feature 'function
    '((call_expression
-      function: (identifier) @font-lock-function-name-face))
+      function:
+      [(identifier) @font-lock-function-name-face
+       (field_expression field: (field_identifier) 
@font-lock-function-name-face)]))
 
    :language mode
    :feature 'variable
@@ -552,9 +573,10 @@ For NODE, OVERRIDE, START, END, and ARGS, see
                                               identifier)))
                  ("function_declarator" 'font-lock-function-name-face)
                  (_ 'font-lock-variable-name-face))))
-    (treesit-fontify-with-override
-     (treesit-node-start identifier) (treesit-node-end identifier)
-     face override start end)))
+    (when identifier
+      (treesit-fontify-with-override
+       (treesit-node-start identifier) (treesit-node-end identifier)
+       face override start end))))
 
 (defun c-ts-mode--fontify-variable (node override start end &rest _)
   "Fontify an identifier node if it is a variable.
@@ -774,14 +796,16 @@ the semicolon.  This function skips the semicolon."
   (when (eq c-ts-mode-indent-style 'linux)
     (setq-local indent-tabs-mode t))
   (setq-local c-ts-common-indent-offset 'c-ts-mode-indent-offset)
-  (setq-local c-ts-common-indent-block-type-regexp
-              (rx (or "compound_statement"
-                      "field_declaration_list"
-                      "enumerator_list")))
-  (setq-local c-ts-common-indent-bracketless-type-regexp
-              (rx (or "if_statement" "do_statement"
-                      "for_statement" "while_statement")))
-
+  (setq-local c-ts-common-indent-type-regexp-alist
+              `((block . ,(rx (or "compound_statement"
+                                  "field_declaration_list"
+                                  "enumerator_list")))
+                (if . "if_statement")
+                (else . ("if_statement" . "alternative"))
+                (do . "do_statement")
+                (while . "while_statement")
+                (for . "for_statement")
+                (close-bracket . "}")))
   ;; Comment
   (c-ts-common-comment-setup)
 
@@ -805,8 +829,8 @@ the semicolon.  This function skips the semicolon."
   (setq-local treesit-font-lock-feature-list
               '(( comment definition)
                 ( keyword preprocessor string type)
-                ( assignment constant escape-sequence label literal property )
-                ( bracket delimiter error function operator variable))))
+                ( assignment constant escape-sequence label literal)
+                ( bracket delimiter error function operator property 
variable))))
 
 ;;;###autoload
 (define-derived-mode c-ts-mode c-ts-base-mode "C"
diff --git a/lisp/progmodes/cmake-ts-mode.el b/lisp/progmodes/cmake-ts-mode.el
index c241a2868e..04f5d6bdac 100644
--- a/lisp/progmodes/cmake-ts-mode.el
+++ b/lisp/progmodes/cmake-ts-mode.el
@@ -220,6 +220,9 @@ the subtrees."
     (setq-local treesit-font-lock-feature-list
                 '((comment)
                   (keyword string)
+                  ;; 'function' and 'variable' here play slightly
+                  ;; different roles than in other ts modes, so we
+                  ;; kept them at level 3.
                   (builtin constant escape-sequence function number variable)
                   (bracket error misc-punctuation)))
 
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 5758eadf99..ccf64fb670 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -649,6 +649,36 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = 
\\([0-9]+\\)\\)?"
     ;; we do not know what lines will follow.
     (guile-file "^In \\(.+\\..+\\):\n" 1 nil nil 0)
     (guile-line "^ *\\([0-9]+\\): *\\([0-9]+\\)" nil 1 2)
+
+    ;; Typescript compilation prior to tsc version 2.7, "plain" format:
+    ;; greeter.ts(30,12): error TS2339: Property 'foo' does not exist.
+    (typescript-tsc-plain
+     ,(rx bol
+          (group (not (in " \t\n()"))   ; 1: file
+                 (* (not (in "\n()"))))
+          "("
+          (group (+ (in "0-9")))        ; 2: line
+          ","
+          (group (+ (in "0-9")))        ; 3: column
+          "): error "
+          (+ (in "0-9A-Z"))             ; error code
+          ": ")
+     1 2 3 2)
+
+    ;; Typescript compilation after tsc version 2.7, "pretty" format:
+    ;; src/resources/document.ts:140:22 - error TS2362: something.
+    (typescript-tsc-pretty
+     ,(rx bol
+          (group (not (in " \t\n()"))   ; 1: file
+                 (* (not (in "\n()"))))
+          ":"
+          (group (+ (in "0-9")))        ; 2: line
+          ":"
+          (group (+ (in "0-9")))        ; 3: column
+          " - error "
+          (+ (in "0-9A-Z"))             ; error code
+          ": ")
+     1 2 3 2)
     ))
   "Alist of values for `compilation-error-regexp-alist'.")
 
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 4fa886bc78..6caf5894ed 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -2873,7 +2873,10 @@ for which LSP on-type-formatting should be requested."
          (when-let* ((lsp-item (get-text-property 0 'eglot--lsp-item proxy))
                      (kind (alist-get (plist-get lsp-item :kind)
                                       eglot--kind-names)))
-           (intern (downcase kind))))
+           (pcase kind
+             ("EnumMember" 'enum-member)
+             ("TypeParameter" 'type-parameter)
+             (_ (intern (downcase kind))))))
        :company-deprecated
        (lambda (proxy)
          (when-let ((lsp-item (get-text-property 0 'eglot--lsp-item proxy)))
diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 7dafe9b2e3..2a2783f45f 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -67,12 +67,14 @@
 
 (defvar go-ts-mode--indent-rules
   `((go
+     ((parent-is "source_file") point-min 0)
      ((node-is ")") parent-bol 0)
      ((node-is "]") parent-bol 0)
      ((node-is "}") parent-bol 0)
      ((node-is "labeled_statement") no-indent)
      ((parent-is "argument_list") parent-bol go-ts-mode-indent-offset)
      ((parent-is "block") parent-bol go-ts-mode-indent-offset)
+     ((parent-is "communication_case") parent-bol go-ts-mode-indent-offset)
      ((parent-is "const_declaration") parent-bol go-ts-mode-indent-offset)
      ((parent-is "default_case") parent-bol go-ts-mode-indent-offset)
      ((parent-is "expression_case") parent-bol go-ts-mode-indent-offset)
@@ -83,7 +85,10 @@
      ((parent-is "labeled_statement") parent-bol go-ts-mode-indent-offset)
      ((parent-is "literal_value") parent-bol go-ts-mode-indent-offset)
      ((parent-is "parameter_list") parent-bol go-ts-mode-indent-offset)
+     ((parent-is "select_statement") parent-bol 0)
+     ((parent-is "type_case") parent-bol go-ts-mode-indent-offset)
      ((parent-is "type_spec") parent-bol go-ts-mode-indent-offset)
+     ((parent-is "type_switch_statement") parent-bol 0)
      ((parent-is "var_declaration") parent-bol go-ts-mode-indent-offset)
      (no-node parent-bol 0)))
   "Tree-sitter indent rules for `go-ts-mode'.")
@@ -120,17 +125,32 @@
    :feature 'delimiter
    '((["," "." ";" ":"]) @font-lock-delimiter-face)
 
+   :language 'go
+   :feature 'definition
+   '((function_declaration
+      name: (identifier) @font-lock-function-name-face)
+     (method_declaration
+      name: (field_identifier) @font-lock-function-name-face)
+     (method_spec
+      name: (field_identifier) @font-lock-function-name-face)
+     (field_declaration
+      name: (field_identifier) @font-lock-property-face)
+     (parameter_declaration
+      name: (identifier) @font-lock-variable-name-face)
+     (short_var_declaration
+      left: (expression_list
+             (identifier) @font-lock-variable-name-face
+             ("," (identifier) @font-lock-variable-name-face)*))
+     (var_spec name: (identifier) @font-lock-variable-name-face
+               ("," name: (identifier) @font-lock-variable-name-face)*))
+
    :language 'go
    :feature 'function
    '((call_expression
       function: (identifier) @font-lock-function-name-face)
      (call_expression
       function: (selector_expression
-                 field: (field_identifier) @font-lock-function-name-face))
-     (function_declaration
-      name: (identifier) @font-lock-function-name-face)
-     (method_declaration
-      name: (field_identifier) @font-lock-function-name-face))
+                 field: (field_identifier) @font-lock-function-name-face)))
 
    :language 'go
    :feature 'keyword
@@ -156,6 +176,11 @@
    :feature 'type
    '([(package_identifier) (type_identifier)] @font-lock-type-face)
 
+   :language 'go
+   :feature 'property
+   '((field_identifier) @font-lock-property-face
+     (keyed_element (_ (identifier) @font-lock-property-face)))
+
    :language 'go
    :feature 'variable
    '((identifier) @font-lock-variable-name-face)
@@ -165,12 +190,6 @@
    :override t
    '((escape_sequence) @font-lock-escape-face)
 
-   :language 'go
-   :feature 'property
-   :override t
-   '((field_identifier) @font-lock-property-face
-     (keyed_element (_ (identifier) @font-lock-property-face)))
-
    :language 'go
    :feature 'error
    :override t
@@ -225,11 +244,10 @@
     ;; Font-lock.
     (setq-local treesit-font-lock-settings go-ts-mode--font-lock-settings)
     (setq-local treesit-font-lock-feature-list
-                '(( comment)
+                '(( comment definition)
                   ( keyword string type)
-                  ( constant escape-sequence function label number
-                    property variable)
-                  ( bracket delimiter error operator)))
+                  ( constant escape-sequence label number)
+                  ( bracket delimiter error function operator property 
variable)))
 
     (treesit-major-mode-setup)))
 
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index e4153725ef..5523b112d4 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -70,21 +70,25 @@
 (defvar java-ts-mode--indent-rules
   `((java
      ((parent-is "program") point-min 0)
-     ((node-is "}") (and parent parent-bol) 0)
+     ((match "}" "element_value_array_initializer")
+      parent-bol 0)
+     ((node-is "}") point-min c-ts-common-statement-offset)
      ((node-is ")") parent-bol 0)
+     ((node-is "else") parent-bol 0)
      ((node-is "]") parent-bol 0)
      ((and (parent-is "comment") c-ts-common-looking-at-star)
       c-ts-common-comment-start-after-first-star -1)
      ((parent-is "comment") prev-adaptive-prefix 0)
      ((parent-is "text_block") no-indent)
-     ((parent-is "class_body") parent-bol java-ts-mode-indent-offset)
-     ((parent-is "annotation_type_body") parent-bol java-ts-mode-indent-offset)
-     ((parent-is "interface_body") parent-bol java-ts-mode-indent-offset)
-     ((parent-is "constructor_body") parent-bol java-ts-mode-indent-offset)
+     ((parent-is "class_body") point-min c-ts-common-statement-offset)
+     ((parent-is "array_initializer") parent-bol java-ts-mode-indent-offset)
+     ((parent-is "annotation_type_body") point-min 
c-ts-common-statement-offset)
+     ((parent-is "interface_body") point-min c-ts-common-statement-offset)
+     ((parent-is "constructor_body") point-min c-ts-common-statement-offset)
      ((parent-is "enum_body_declarations") parent-bol 0)
-     ((parent-is "enum_body") parent-bol java-ts-mode-indent-offset)
-     ((parent-is "switch_block") parent-bol java-ts-mode-indent-offset)
-     ((parent-is "record_declaration_body") parent-bol 
java-ts-mode-indent-offset)
+     ((parent-is "enum_body") point-min c-ts-common-statement-offset)
+     ((parent-is "switch_block") point-min c-ts-common-statement-offset)
+     ((parent-is "record_declaration_body") point-min 
c-ts-common-statement-offset)
      ((query "(method_declaration (block _ @indent))") parent-bol 
java-ts-mode-indent-offset)
      ((query "(method_declaration (block (_) @indent))") parent-bol 
java-ts-mode-indent-offset)
      ((parent-is "local_variable_declaration") parent-bol 
java-ts-mode-indent-offset)
@@ -117,7 +121,7 @@
      ((parent-is "case_statement") parent-bol java-ts-mode-indent-offset)
      ((parent-is "labeled_statement") parent-bol java-ts-mode-indent-offset)
      ((parent-is "do_statement") parent-bol java-ts-mode-indent-offset)
-     ((parent-is "block") (and parent parent-bol) java-ts-mode-indent-offset)))
+     ((parent-is "block") point-min c-ts-common-statement-offset)))
   "Tree-sitter indent rules.")
 
 (defvar java-ts-mode--keywords
@@ -304,6 +308,23 @@ Return nil if there is no name or if NODE is not a defun 
node."
                             "text_block")))
 
   ;; Indent.
+  (setq-local c-ts-common-indent-type-regexp-alist
+              `((block . ,(rx (or "class_body"
+                                  "array_initializer"
+                                  "constructor_body"
+                                  "annotation_type_body"
+                                  "interface_body"
+                                  "enum_body"
+                                  "switch_block"
+                                  "record_declaration_body"
+                                  "block")))
+                (close-bracket . "}")
+                (if . "if_statement")
+                (else . ("if_statement" . "alternative"))
+                (for . "for_statement")
+                (while . "while_statement")
+                (do . "do_statement")))
+  (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
   (setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
 
   ;; Electric
diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el
index beaab2e76e..7a130f42dc 100644
--- a/lisp/progmodes/ruby-ts-mode.el
+++ b/lisp/progmodes/ruby-ts-mode.el
@@ -95,6 +95,11 @@
 (declare-function treesit-node-end "treesit.c")
 (declare-function treesit-node-start "treesit.c")
 (declare-function treesit-node-string "treesit.c")
+(declare-function treesit-query-compile "treesit.c")
+(declare-function treesit-query-capture "treesit.c")
+(declare-function treesit-parser-add-notifier "treesit.c")
+(declare-function treesit-parser-buffer "treesit.c")
+(declare-function treesit-parser-list "treesit.c")
 
 (defgroup ruby-ts nil
   "Major mode for editing Ruby code."
@@ -1002,6 +1007,78 @@ leading double colon is not added."
         (concat result sep method-name)
       result)))
 
+(defvar ruby-ts--s-p-query
+  (when (treesit-available-p)
+    (treesit-query-compile 'ruby
+                           '(((heredoc_body) @heredoc)
+                             ;; $' $" $`.
+                             ((global_variable) @global_var
+                              (:match "\\`\\$[#\"'`:?]" @global_var))
+                             ;; ?' ?" ?` are character literals.
+                             ((character) @char
+                              (:match "\\`?[#\"'`:?]" @char))
+                             ;; Symbols like :+, :<=> or :foo=.
+                             ((simple_symbol) @symbol
+                              (:match "[[:punct:]]" @symbol))
+                             ;; Method calls with name ending with ? or !.
+                             ((call method: (identifier) @ident)
+                              (:match "[?!]\\'" @ident))
+                             ;; Backtick method redefinition.
+                             ((operator "`" @backtick))
+                             ;; TODO: Stop at interpolations.
+                             ((regex "/" @regex_slash))
+                             ;; =begin...=end
+                             ((comment) @comm
+                              (:match "\\`=" @comm))
+                             ;; Percent literals: %w[], %q{}, ...
+                             ((string) @percent
+                              (:match "\\`%" @percent))))))
+
+(defun ruby-ts--syntax-propertize (beg end)
+  (let ((captures (treesit-query-capture 'ruby ruby-ts--s-p-query beg end)))
+    (pcase-dolist (`(,name . ,node) captures)
+      (pcase-exhaustive name
+        ('regex_slash
+         ;; N.B.: A regexp literal with modifiers actually includes them in
+         ;; the trailing "/" node.
+         (put-text-property (treesit-node-start node) (1+ (treesit-node-start 
node))
+                            'syntax-table
+                            ;; Differentiate the %r{...} literals.
+                            (if (eq ?/ (char-after (treesit-node-start node)))
+                                (string-to-syntax "\"/")
+                              (string-to-syntax "|"))))
+        ('ident
+         (put-text-property (1- (treesit-node-end node)) (treesit-node-end 
node)
+                            'syntax-table (string-to-syntax "_")))
+        ('symbol
+         (put-text-property (1+ (treesit-node-start node)) (treesit-node-end 
node)
+                            'syntax-table (string-to-syntax "_")))
+        ('heredoc
+         (put-text-property (treesit-node-start node) (1+ (treesit-node-start 
node))
+                            'syntax-table (string-to-syntax "\""))
+         (put-text-property (treesit-node-end node) (1+ (treesit-node-end 
node))
+                            'syntax-table (string-to-syntax "\"")))
+        ('percent
+         ;; FIXME: Put the first one on the first paren in both %Q{} and %().
+         ;; That would stop electric-pair-mode from pairing, though.  Hmm.
+         (put-text-property (treesit-node-start node) (1+ (treesit-node-start 
node))
+                            'syntax-table (string-to-syntax "|"))
+         (put-text-property (1- (treesit-node-end node)) (treesit-node-end 
node)
+                            'syntax-table (string-to-syntax "|")))
+        ((or 'global_var 'char)
+         (put-text-property (treesit-node-start node) (1+ (treesit-node-start 
node))
+                            'syntax-table (string-to-syntax "'"))
+         (put-text-property (1+ (treesit-node-start node)) (treesit-node-end 
node)
+                            'syntax-table (string-to-syntax "_")))
+        ('backtick
+         (put-text-property (treesit-node-start node) (treesit-node-end node)
+                            'syntax-table (string-to-syntax "_")))
+        ('comm
+         (dolist (pos (list (treesit-node-start node)
+                            (1- (treesit-node-end node))))
+           (put-text-property pos (1+ pos) 'syntax-table
+                              (string-to-syntax "!"))))))))
+
 (defvar-keymap ruby-ts-mode-map
   :doc "Keymap used in Ruby mode"
   :parent prog-mode-map
@@ -1066,7 +1143,21 @@ leading double colon is not added."
                   interpolation literal symbol assignment)
                 ( bracket error function operator punctuation)))
 
-  (treesit-major-mode-setup))
+  (treesit-major-mode-setup)
+
+  (treesit-parser-add-notifier (car (treesit-parser-list))
+                               #'ruby-ts--parser-after-change)
+
+  (setq-local syntax-propertize-function #'ruby-ts--syntax-propertize))
+
+(defun ruby-ts--parser-after-change (ranges parser)
+  ;; Make sure we re-syntax-propertize the full node that is being
+  ;; edited.  This is most pertinent to multi-line complex nodes such
+  ;; as heredocs.
+  (when ranges
+    (with-current-buffer (treesit-parser-buffer parser)
+      (syntax-ppss-flush-cache (cl-loop for r in ranges
+                                        minimize (car r))))))
 
 (if (treesit-ready-p 'ruby)
     ;; Copied from ruby-mode.el.
diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el
index e317793d21..5c71a8ad46 100644
--- a/lisp/progmodes/rust-ts-mode.el
+++ b/lisp/progmodes/rust-ts-mode.el
@@ -38,6 +38,7 @@
 (declare-function treesit-node-start "treesit.c")
 (declare-function treesit-node-type "treesit.c")
 (declare-function treesit-node-parent "treesit.c")
+(declare-function treesit-query-compile "treesit.c")
 
 (defcustom rust-ts-mode-indent-offset 4
   "Number of spaces for each indentation step in `rust-ts-mode'."
@@ -69,6 +70,7 @@
 
 (defvar rust-ts-mode--indent-rules
   `((rust
+     ((parent-is "source_file") point-min 0)
      ((node-is ")") parent-bol 0)
      ((node-is "]") parent-bol 0)
      ((node-is "}") (and parent parent-bol) 0)
@@ -155,6 +157,18 @@
    :feature 'delimiter
    '((["," "." ";" ":" "::"]) @font-lock-delimiter-face)
 
+   :language 'rust
+   :feature 'definition
+   '((function_item name: (identifier) @font-lock-function-name-face)
+     (macro_definition "macro_rules!" @font-lock-constant-face)
+     (macro_definition (identifier) @font-lock-preprocessor-face)
+     (field_declaration name: (field_identifier) @font-lock-property-face)
+     (parameter) @rust-ts-mode--fontify-pattern
+     (let_declaration) @rust-ts-mode--fontify-pattern
+     (for_expression) @rust-ts-mode--fontify-pattern
+     (let_condition) @rust-ts-mode--fontify-pattern
+     (match_arm) @rust-ts-mode--fontify-pattern)
+
    :language 'rust
    :feature 'function
    '((call_expression
@@ -164,15 +178,12 @@
         field: (field_identifier) @font-lock-function-name-face)
        (scoped_identifier
         name: (identifier) @font-lock-function-name-face)])
-     (function_item (identifier) @font-lock-function-name-face)
      (generic_function
       function: [(identifier) @font-lock-function-name-face
                  (field_expression
                   field: (field_identifier) @font-lock-function-name-face)
                  (scoped_identifier
                   name: (identifier) @font-lock-function-name-face)])
-     (macro_definition "macro_rules!" @font-lock-constant-face)
-     (macro_definition (identifier) @font-lock-preprocessor-face)
      (macro_invocation macro: (identifier) @font-lock-preprocessor-face))
 
    :language 'rust
@@ -195,10 +206,7 @@
 
    :language 'rust
    :feature 'type
-   `((call_expression
-      function: (scoped_identifier
-                 path: (identifier) @font-lock-type-face))
-     (enum_variant name: (identifier) @font-lock-type-face)
+   `((enum_variant name: (identifier) @font-lock-type-face)
      (match_arm
       pattern: (match_pattern (_ type: (identifier) @font-lock-type-face)))
      (match_arm
@@ -208,24 +216,29 @@
      (mod_item name: (identifier) @font-lock-constant-face)
      (primitive_type) @font-lock-type-face
      (type_identifier) @font-lock-type-face
-     (scoped_identifier name: (identifier) @font-lock-type-face)
-     (scoped_identifier path: (identifier) @font-lock-constant-face)
-     (scoped_identifier
-      (scoped_identifier
-       path: (identifier) @font-lock-constant-face))
+     ((scoped_identifier name: (identifier) @font-lock-type-face)
+      (:match "^[A-Z]" @font-lock-type-face))
+     ((scoped_identifier path: (identifier) @font-lock-type-face)
+      (:match "^[A-Z]" @font-lock-type-face))
+     ((scoped_identifier
+        (scoped_identifier
+         path: (identifier) @font-lock-type-face))
+      (:match "^[A-Z]" @font-lock-type-face))
      ((scoped_identifier
        path: [(identifier) @font-lock-type-face
               (scoped_identifier
                name: (identifier) @font-lock-type-face)])
       (:match "^[A-Z]" @font-lock-type-face))
-     (scoped_type_identifier path: (identifier) @font-lock-constant-face)
-     (scoped_use_list
-      path: [(identifier) @font-lock-constant-face
-             (scoped_identifier (identifier) @font-lock-constant-face)])
+     (scoped_type_identifier path: (identifier) @font-lock-type-face)
      (type_identifier) @font-lock-type-face
      (use_as_clause alias: (identifier) @font-lock-type-face)
      (use_list (identifier) @font-lock-type-face))
 
+   :language 'rust
+   :feature 'property
+   '((field_identifier) @font-lock-property-face
+     (shorthand_field_initializer (identifier) @font-lock-property-face))
+
    :language 'rust
    :feature 'variable
    '((identifier) @font-lock-variable-name-face
@@ -237,18 +250,28 @@
    :override t
    '((escape_sequence) @font-lock-escape-face)
 
-   :language 'rust
-   :feature 'property
-   :override t
-   '((field_identifier) @font-lock-property-face
-     (shorthand_field_initializer (identifier) @font-lock-property-face))
-
    :language 'rust
    :feature 'error
    :override t
    '((ERROR) @font-lock-warning-face))
   "Tree-sitter font-lock settings for `rust-ts-mode'.")
 
+(defalias 'rust-ts-mode--fontify-pattern
+  (and
+   (treesit-available-p)
+   `(lambda (node override start end &rest _)
+      (let ((captures (treesit-query-capture
+                       (treesit-node-child-by-field-name node "pattern")
+                       ,(treesit-query-compile 'rust '((identifier) @id
+                                                       
(shorthand_field_identifier) @id)))))
+        (pcase-dolist (`(_name . ,id) captures)
+          (unless (string-match-p "\\`scoped_\\(?:type_\\)?identifier\\'"
+                                  (treesit-node-type
+                                   (treesit-node-parent id)))
+            (treesit-fontify-with-override
+             (treesit-node-start id) (treesit-node-end id)
+             'font-lock-variable-name-face override start end)))))))
+
 (defun rust-ts-mode--defun-name (node)
   "Return the defun name of NODE.
 Return nil if there is no name or if NODE is not a defun node."
@@ -317,11 +340,11 @@ delimiters < and >'s."
     ;; Font-lock.
     (setq-local treesit-font-lock-settings rust-ts-mode--font-lock-settings)
     (setq-local treesit-font-lock-feature-list
-                '(( comment)
+                '(( comment definition)
                   ( keyword string)
                   ( attribute builtin constant escape-sequence
-                    function number property type variable)
-                  ( bracket delimiter error operator)))
+                    number type)
+                  ( bracket delimiter error function operator property 
variable)))
 
     ;; Imenu.
     (setq-local treesit-simple-imenu-settings
diff --git a/lisp/subr.el b/lisp/subr.el
index f909b63aab..f749c9e6d2 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -3595,12 +3595,14 @@ like) while `y-or-n-p' is running)."
                            (if (or (zerop l) (eq ?\s (aref prompt (1- l))))
                                "" " ")
                            (if dialog ""
-                              (substitute-command-keys
-                               (if help-form
-                                   (format "(\\`y', \\`n' or \\`%s') "
-                                           (key-description
-                                            (vector help-char)))
-                                 "(\\`y' or \\`n') ")))))))
+                              ;; Don't clobber caller's match data.
+                              (save-match-data
+                                (substitute-command-keys
+                                 (if help-form
+                                     (format "(\\`y', \\`n' or \\`%s') "
+                                             (key-description
+                                              (vector help-char)))
+                                   "(\\`y' or \\`n') "))))))))
         ;; Preserve the actual command that eventually called
         ;; `y-or-n-p' (otherwise `repeat' will be repeating
         ;; `exit-minibuffer').
diff --git a/lisp/treesit.el b/lisp/treesit.el
index d11e57fef8..749781894b 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -555,8 +555,35 @@ omitted, default END to BEG."
               "Generic tree-sitter font-lock error"
               'treesit-error)
 
+(defvar-local treesit-font-lock-settings nil
+  "A list of SETTINGs for treesit-based fontification.
+
+The exact format of each SETTING is considered internal.  Use
+`treesit-font-lock-rules' to set this variable.
+
+Each SETTING has the form:
+
+    (QUERY ENABLE FEATURE OVERRIDE)
+
+QUERY must be a compiled query.  See Info node `(elisp)Pattern
+Matching' for how to write a query and compile it.
+
+For SETTING to be activated for font-lock, ENABLE must be t.  To
+disable this SETTING, set ENABLE to nil.
+
+FEATURE is the \"feature name\" of the query.  Users can control
+which features are enabled with `treesit-font-lock-level' and
+`treesit-font-lock-feature-list'.
+
+OVERRIDE is the override flag for this query.  Its value can be
+t, nil, append, prepend, keep.  See more in
+`treesit-font-lock-rules'.")
+
 (defun treesit--font-lock-level-setter (sym val)
-  "Custom setter for `treesit-font-lock-level'."
+  "Custom setter for `treesit-font-lock-level'.
+Set the default value of SYM to VAL, recompute fontification
+features and refontify for every buffer where tree-sitter-based
+fontification is enabled."
   (set-default sym val)
   (and (treesit-available-p)
        (named-let loop ((res nil)
@@ -571,7 +598,7 @@ omitted, default END to BEG."
                    res)
            (let ((buffer (car buffers)))
              (with-current-buffer buffer
-               (if (treesit-parser-list)
+               (if treesit-font-lock-settings
                    (loop (append res (list buffer)) (cdr buffers))
                  (loop res (cdr buffers)))))))))
 
@@ -585,9 +612,10 @@ fontifications.
 Level 1 usually contains only comments and definitions.
 Level 2 usually adds keywords, strings, data types, etc.
 Level 3 usually represents full-blown fontifications, including
-assignments, constants, numbers and literals, properties, etc.
+assignments, constants, numbers and literals, etc.
 Level 4 adds everything else that can be fontified: delimiters,
-operators, brackets, punctuation, all functions and variables, etc.
+operators, brackets, punctuation, all functions, properties,
+variables, etc.
 
 In addition to the decoration level, individual features can be
 turned on/off by calling `treesit-font-lock-recompute-features'.
@@ -634,30 +662,6 @@ See the manual for more explanations on some of the 
features.
 For changes to this variable to take effect, run
 `treesit-font-lock-recompute-features'.")
 
-(defvar-local treesit-font-lock-settings nil
-  "A list of SETTINGs for treesit-based fontification.
-
-The exact format of each SETTING is considered internal.  Use
-`treesit-font-lock-rules' to set this variable.
-
-Each SETTING has the form:
-
-    (QUERY ENABLE FEATURE OVERRIDE)
-
-QUERY must be a compiled query.  See Info node `(elisp)Pattern
-Matching' for how to write a query and compile it.
-
-For SETTING to be activated for font-lock, ENABLE must be t.  To
-disable this SETTING, set ENABLE to nil.
-
-FEATURE is the \"feature name\" of the query.  Users can control
-which features are enabled with `treesit-font-lock-level' and
-`treesit-font-lock-feature-list'.
-
-OVERRIDE is the override flag for this query.  Its value can be
-t, nil, append, prepend, keep.  See more in
-`treesit-font-lock-rules'.")
-
 (defun treesit-font-lock-rules (&rest query-specs)
   "Return a value suitable for `treesit-font-lock-settings'.
 
@@ -2963,7 +2967,17 @@ function signals an error."
           ;; Copy out.
           (unless (file-exists-p out-dir)
             (make-directory out-dir t))
-          (copy-file lib-name (file-name-as-directory out-dir) t t)
+          (let* ((library-fname (expand-file-name lib-name out-dir))
+                 (old-fname (concat library-fname ".old")))
+            ;; Rename the existing shared library, if any, then
+            ;; install the new one, and try deleting the old one.
+            ;; This is for Windows systems, where we cannot simply
+            ;; overwrite a DLL that is being used.
+            (if (file-exists-p library-fname)
+                (rename-file library-fname old-fname t))
+            (copy-file lib-name (file-name-as-directory out-dir) t t)
+            ;; Ignore errors, in case the old version is still used.
+            (ignore-errors (delete-file old-fname)))
           (message "Library installed to %s/%s" out-dir lib-name))
       (when (file-exists-p workdir)
         (delete-directory workdir t)))))
@@ -3031,7 +3045,7 @@ function signals an error."
 
   "Parsers"
   (treesit-parser-create
-   :no-eval (treesit-parser-create)
+   :no-eval (treesit-parser-create 'c)
    :eg-result-string "#<treesit-parser for c>")
   (treesit-parser-delete
    :no-value (treesit-parser-delete parser))
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 72160c35f5..00a887f6ce 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -2342,8 +2342,8 @@ Unlike `vc-find-revision-save', doesn't save the buffer 
to the file."
                       (ignore-errors (delay-mode-hooks (set-auto-mode))))
                   (normal-mode))
                (set-buffer-modified-p nil)
-                (setq buffer-read-only t))
-               (setq failed nil)
+                (setq buffer-read-only t)
+                (setq failed nil))
            (when (and failed (unless buffer (get-file-buffer filename)))
              (with-current-buffer (get-file-buffer filename)
                (set-buffer-modified-p nil))
diff --git a/src/bidi.c b/src/bidi.c
index e01251263b..93875d243e 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -3300,12 +3300,15 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
      it belongs to a sequence of WS characters preceding a newline
      or a TAB or a paragraph separator.  */
   if ((bidi_it->orig_type == NEUTRAL_WS
-       || bidi_it->orig_type == WEAK_BN
+       || (bidi_it->orig_type == WEAK_BN
+          /* If this BN character is already at base level, we don't
+             need to consider resetting it, since I1 and I2 below
+             will not change the level, so avoid the potentially
+             costly loop below.  */
+          && level != bidi_it->level_stack[0].level)
        || bidi_isolate_fmt_char (bidi_it->orig_type))
-      && bidi_it->next_for_ws.charpos < bidi_it->charpos
-      /* If this character is already at base level, we don't need to
-        reset it, so avoid the potentially costly loop below.  */
-      && level != bidi_it->level_stack[0].level)
+      /* This means the informaition about WS resolution is not valid.  */
+      && bidi_it->next_for_ws.charpos < bidi_it->charpos)
     {
       int ch;
       ptrdiff_t clen = bidi_it->ch_len;
@@ -3340,7 +3343,7 @@ bidi_level_of_next_char (struct bidi_it *bidi_it)
       || bidi_it->orig_type == NEUTRAL_S
       || bidi_it->ch == '\n' || bidi_it->ch == BIDI_EOB
       || ((bidi_it->orig_type == NEUTRAL_WS
-          || bidi_it->orig_type == WEAK_BN
+          || bidi_it->orig_type == WEAK_BN /* L1/Retaining */
           || bidi_isolate_fmt_char (bidi_it->orig_type)
           || bidi_explicit_dir_char (bidi_it->ch))
          && (bidi_it->next_for_ws.type == NEUTRAL_B
diff --git a/src/buffer.c b/src/buffer.c
index 88ca69b0dd..38648519ba 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -5081,8 +5081,8 @@ the mode line appears at the bottom.  */);
 The header line appears, optionally, at the top of a window; the mode
 line appears at the bottom.
 
-Also see `header-line-indent-mode' if `display-line-number-mode' is
-used.  */);
+Also see `header-line-indent-mode' if `display-line-numbers-mode' is
+turned on and header-line text should be aligned with buffer text.  */);
 
   DEFVAR_PER_BUFFER ("mode-line-format", &BVAR (current_buffer, 
mode_line_format),
                     Qnil,
diff --git a/src/treesit.c b/src/treesit.c
index 8e772523cc..b15d44fca0 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -620,7 +620,7 @@ treesit_load_language (Lisp_Object language_symbol,
   char *c_name = xstrdup (SSDATA (base_name));
   treesit_symbol_to_c_name (c_name);
   if (found_override)
-    c_name = SSDATA (override_c_name);
+    c_name = xstrdup (SSDATA (override_c_name));
   langfn = dynlib_sym (handle, c_name);
   xfree (c_name);
   error = dynlib_error ();
diff --git a/src/xdisp.c b/src/xdisp.c
index 398056144a..66c2d5e47f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -29364,6 +29364,7 @@ fill_gstring_glyph_string (struct glyph_string *s, int 
face_id,
                           int start, int end, int overlaps)
 {
   struct glyph *glyph, *last;
+  int voffset;
   Lisp_Object lgstring;
   int i;
   bool glyph_not_available_p;
@@ -29371,6 +29372,7 @@ fill_gstring_glyph_string (struct glyph_string *s, int 
face_id,
   s->for_overlaps = overlaps;
   glyph = s->row->glyphs[s->area] + start;
   last = s->row->glyphs[s->area] + end;
+  voffset = glyph->voffset;
   glyph_not_available_p = glyph->glyph_not_available_p;
   s->cmp_id = glyph->u.cmp.id;
   s->cmp_from = glyph->slice.cmp.from;
@@ -29421,6 +29423,9 @@ fill_gstring_glyph_string (struct glyph_string *s, int 
face_id,
   if (glyph_not_available_p)
     s->font_not_found_p = true;
 
+  /* Adjust base line for subscript/superscript text.  */
+  s->ybase += voffset;
+
   return glyph - s->row->glyphs[s->area];
 }
 
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent-bsd.erts 
b/test/lisp/progmodes/c-ts-mode-resources/indent-bsd.erts
index ba4f854baf..74e34fe821 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/indent-bsd.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/indent-bsd.erts
@@ -3,7 +3,7 @@ Code:
     (c-ts-mode)
     (setq-local indent-tabs-mode nil)
     (setq-local c-ts-mode-indent-offset 2)
-    (c-ts-mode-set-local-style 'bsd)
+    (c-ts-mode-set-style 'bsd)
     (indent-region (point-min) (point-max)))
 
 Point-Char: |
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent.erts 
b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
index 058c6e9099..21b84c2e7e 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
@@ -3,7 +3,7 @@ Code:
     (c-ts-mode)
     (setq-local indent-tabs-mode nil)
     (setq-local c-ts-mode-indent-offset 2)
-    (c-ts-mode-set-local-style 'gnu)
+    (c-ts-mode-set-style 'gnu)
     (indent-region (point-min) (point-max)))
 
 Point-Char: |
@@ -144,6 +144,44 @@ int f2(int x,
 };
 =-=-=
 
+Name: Semi-colon in While Loop (bug#61291)
+
+=-=
+while (true)
+  ;
+for (int i = 0;
+     i < 5;
+     i++)
+  ;
+=-=-=
+
+Name: Bracketless Simple Statement
+
+=-=
+for (int i = 0; i < 5; i++)
+  continue;
+
+while (true)
+  return 1;
+
+do
+  i++;
+while (true)
+=-=-=
+
+Name: Nested If-Else
+
+=-=
+if (true)
+  return 0;
+else if (false)
+  return 1;
+else if (true)
+  return 2;
+else if (false)
+  return 3;
+=-=-=
+
 Name: Multiline Block Comments 1 (bug#60270)
 
 =-=
@@ -196,7 +234,7 @@ Code:
     (c-ts-mode)
     (setq-local indent-tabs-mode nil)
     (setq-local c-ts-mode-indent-offset 8)
-    (c-ts-mode-set-local-style 'linux)
+    (c-ts-mode-set-style 'linux)
     (indent-region (point-min) (point-max)))
 
 Name: Labels (Linux Style)
@@ -244,3 +282,48 @@ int main() {
     }
 }
 =-=-=
+
+Name: Complicated mixed bracket matching indentation (bug#61142)
+
+=-=
+void foo(
+         int foo) {
+  for (;;)
+    return 5;
+
+  if (a == 0
+      && b == 1
+      && foo)
+    {
+      return 0;
+    }
+  else if (a == 1)
+    {
+      return 1;
+    }
+  else if (true)
+    return 5;
+  else
+    {
+      if (a == 0
+          && b == 1
+          && foo)
+        for (
+             int i = 0;
+             i < 5;
+             i++)
+          if (true)
+            do
+              i = 5;
+            while (true);
+          else if (false)
+            {
+              return 6;
+            }
+          else
+            if (true
+                && false)
+              return 6;
+    }
+}
+=-=-=
diff --git a/test/lisp/progmodes/compile-tests.el 
b/test/lisp/progmodes/compile-tests.el
index 53dc7f2a13..078eef3677 100644
--- a/test/lisp/progmodes/compile-tests.el
+++ b/test/lisp/progmodes/compile-tests.el
@@ -382,6 +382,10 @@
     ;; sun-ada
     (sun-ada "/home3/xdhar/rcds_rc/main.a, line 361, char 6:syntax error: 
\",\" inserted"
      1 6 361 "/home3/xdhar/rcds_rc/main.a")
+    (typescript-tsc-plain "/home/foo/greeter.ts(30,12): error TS2339: Property 
'foo' does not exist."
+     1 12 30 "/home/foo/greeter.ts")
+    (typescript-tsc-pretty "src/resources/document.ts:140:22 - error TS2362: 
something."
+     1 22 140 "src/resources/document.ts")
     ;; 4bsd
     (edg-1 "/usr/src/foo/foo.c(8): warning: w may be used before set"
      1 nil 8 "/usr/src/foo/foo.c")
@@ -495,7 +499,7 @@ The test data is in `compile-tests--test-regexps-data'."
           (compilation-num-warnings-found 0)
           (compilation-num-infos-found 0))
       (mapc #'compile--test-error-line compile-tests--test-regexps-data)
-      (should (eq compilation-num-errors-found 98))
+      (should (eq compilation-num-errors-found 100))
       (should (eq compilation-num-warnings-found 35))
       (should (eq compilation-num-infos-found 28)))))
 
diff --git a/test/lisp/progmodes/go-ts-mode-resources/indent.erts 
b/test/lisp/progmodes/go-ts-mode-resources/indent.erts
new file mode 100644
index 0000000000..a89d69b307
--- /dev/null
+++ b/test/lisp/progmodes/go-ts-mode-resources/indent.erts
@@ -0,0 +1,47 @@
+Code:
+  (lambda ()
+    (go-ts-mode)
+    (indent-region (point-min) (point-max)))
+
+Point-Char: |
+
+Name: Basic
+
+=-=
+package main
+
+func main() {
+}
+=-=-=
+
+Name: Switch and Select
+
+=-=
+package main
+
+func main() {
+       var x any
+       switch x {
+       case 1:
+               println("one")
+       default:
+               println("default case")
+       }
+
+       switch x.(type) {
+       case int:
+               println("integer")
+       default:
+               println("don't know the type")
+       }
+
+       var c chan int
+       select {
+       case x := <-c:
+               println(x)
+       default:
+               println("no communication")
+       }
+}
+
+=-=-=
diff --git a/test/lisp/progmodes/go-ts-mode-tests.el 
b/test/lisp/progmodes/go-ts-mode-tests.el
new file mode 100644
index 0000000000..548465208f
--- /dev/null
+++ b/test/lisp/progmodes/go-ts-mode-tests.el
@@ -0,0 +1,31 @@
+;;; go-ts-mode-tests.el --- Tests for Tree-sitter-based Go mode         -*- 
lexical-binding: t; -*-
+
+;; Copyright (C) 2023 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'ert-x)
+(require 'treesit)
+
+(ert-deftest go-ts-mode-test-indentation ()
+  (skip-unless (treesit-ready-p 'go))
+  (ert-test-erts-file (ert-resource-file "indent.erts")))
+
+(provide 'go-ts-mode-tests)
+;;; go-ts-mode-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]