diff options
| author | Stefan Kangas | 2023-01-19 06:30:25 +0100 |
|---|---|---|
| committer | Stefan Kangas | 2023-01-19 06:30:25 +0100 |
| commit | 9161a302c9f9fbfa1a8f33181bb332d2c5df3aa7 (patch) | |
| tree | 21de62aa23f4ad770ff8afe322c0223ea7e0af76 | |
| parent | efb9ec11bbee3871d77dc4e9217bd9293d525d5d (diff) | |
| parent | db727873803a974ba210c4942ae7cbcc3d6268ab (diff) | |
| download | emacs-9161a302c9f9fbfa1a8f33181bb332d2c5df3aa7.tar.gz emacs-9161a302c9f9fbfa1a8f33181bb332d2c5df3aa7.zip | |
Merge from origin/emacs-29
db727873803 ruby-ts-mode: Use font-lock-constant-face for true/false/nil
819719330ad (ruby-ts--indent-rules): Add a rule for continuation of a...
94b9cbf96fb (ruby-ts--parent-call-or-bol): Handle more cases with nes...
ba33b83ce4b (ruby-ts--statement-container-regexp): Remove "parenthesi...
f2bedf695c1 ruby-ts-mode: Handle indent in parenless calls much close...
758ac5eabbe Fix split-window-below for the case when split-window-kee...
8e9783b4ce4 Rebind in read-regexp-map ‘M-c’ to ‘M-s c’ compatible wit...
78f93d92b28 * lisp/vc/vc-dir.el: Make keys ‘% m’ and ‘* %’ compatible...
dc3f85fd4b0 Use proper types for Eshell warnings
6a8338a8bc8 ; Avoid byte-compiler warning in cc-fonts.el.
9186be20aeb ; Clarify doc strings of some functions in files.el
bd5ef3ef95e Improve the documentation of 'auto-mode-alist' search
1798ff5a663 ; Fix minor mistakes in documentation
faee7e1f1bd ; * lisp/treesit.el (treesit-font-lock-fontify-region): M...
24f0dfd3731 Revert "Revert "Add c-or-c++-ts-mode (bug#59613)""
ac3bc775b6f Make it harder to misactivate tree-sitter font-lock fast ...
bdd82fa7977 ; * src/treesit.c: Remove unused boilerplate.
343b9b3dfe3 ruby-ts-mode: Obey the option ruby-method-call-indent
045404d1aac ruby-ts-mode: Obey the option ruby-after-operator-indent
300ca6ac372 ruby-ts-mode: Fix indent after operator or conditional
ac5516bd7d5 ruby-ts-mode: Fix/change indentation of a continuation me...
5e2e68a0c2d ruby-ts-mode: Fix indent inside parenthesized_expr and el...
9ed9ff4690a ruby-ts-mode: Fix the rules for hanging arrays and hashes
c4f0b6ccea1 Add more detail about how to invoke Eshell commands
dbac923b9df CC Mode: On removal of "typedef", remove pertinent types ...
56d69c2fc47 ; Relax timeouts for failing ERC test
183e7492702 Don't preserve non-module minor modes in erc-open
7b8322f6285 Use correct buffer for local-module vars in erc-open
7b13422298a ; Avoid plist-get as generalized var in erc-compat
09e9d7c7496 Fix display of warnings on w32 console
bd094207c76 Fix buffer-list-update-hook for indirect buffers
9e7a5d58eea ; Fix tree-sitter indent anchor preset
7c61a304104 Fix treesit-node-first-child-for-pos (bug#60127)
b36cc7e7bbb ; * src/treesit.c (Ftreesit_induce_sparse_tree): Minor ch...
# Conflicts:
# etc/NEWS
33 files changed, 808 insertions, 265 deletions
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 8c77ded55d3..5191bb2918d 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi | |||
| @@ -1331,11 +1331,18 @@ point is on a directory entry, mark all files in that directory tree | |||
| 1331 | listed files and directories. | 1331 | listed files and directories. |
| 1332 | 1332 | ||
| 1333 | @findex vc-dir-mark-by-regexp | 1333 | @findex vc-dir-mark-by-regexp |
| 1334 | @item % | 1334 | @item % m |
| 1335 | @itemx * % | ||
| 1335 | You can use this command to mark files by regexp | 1336 | You can use this command to mark files by regexp |
| 1336 | (@code{vc-dir-mark-by-regexp}). If given a prefix, unmark files | 1337 | (@code{vc-dir-mark-by-regexp}). If given a prefix, unmark files |
| 1337 | instead. | 1338 | instead. |
| 1338 | 1339 | ||
| 1340 | @findex vc-dir-mark-registered-files | ||
| 1341 | @item * r | ||
| 1342 | You can use this command to mark files that are in one of registered | ||
| 1343 | states, including edited, added or removed. | ||
| 1344 | (@code{vc-dir-mark-registered-files}). | ||
| 1345 | |||
| 1339 | @item G | 1346 | @item G |
| 1340 | Add the file under point to the list of files that the VC should | 1347 | Add the file under point to the list of files that the VC should |
| 1341 | ignore (@code{vc-dir-ignore}). For instance, if the VC is Git, it | 1348 | ignore (@code{vc-dir-ignore}). For instance, if the VC is Git, it |
diff --git a/doc/emacs/modes.texi b/doc/emacs/modes.texi index d0eacce0842..06f9929092c 100644 --- a/doc/emacs/modes.texi +++ b/doc/emacs/modes.texi | |||
| @@ -430,10 +430,15 @@ For example, one element normally found in the list has the form | |||
| 430 | mode for files whose names end in @file{.c}. (Note that @samp{\\} is | 430 | mode for files whose names end in @file{.c}. (Note that @samp{\\} is |
| 431 | needed in Lisp syntax to include a @samp{\} in the string, which must | 431 | needed in Lisp syntax to include a @samp{\} in the string, which must |
| 432 | be used to suppress the special meaning of @samp{.} in regexps.) If | 432 | be used to suppress the special meaning of @samp{.} in regexps.) If |
| 433 | the element has the form @code{(@var{regexp} @var{mode-function} | 433 | the element has the form @w{@code{(@var{regexp} @var{mode-function} |
| 434 | @var{flag})} and @var{flag} is non-@code{nil}, then after calling | 434 | @var{flag})}} and @var{flag} is non-@code{nil}, then after calling |
| 435 | @var{mode-function}, Emacs discards the suffix that matched | 435 | @var{mode-function} (if it is non-@code{nil}), Emacs discards the |
| 436 | @var{regexp} and searches the list again for another match. | 436 | suffix that matched @var{regexp} and searches the list again for |
| 437 | another match. This ``recursive extension stripping'' is used for | ||
| 438 | files which have multiple extensions, and the ``outer'' extension | ||
| 439 | hides the ``inner'' one that actually specifies the right mode. For | ||
| 440 | example, backup files and GPG-encrypted files with @file{.gpg} | ||
| 441 | extension use this feature. | ||
| 437 | 442 | ||
| 438 | @vindex auto-mode-case-fold | 443 | @vindex auto-mode-case-fold |
| 439 | On GNU/Linux and other systems with case-sensitive file names, Emacs | 444 | On GNU/Linux and other systems with case-sensitive file names, Emacs |
diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 18125c372ce..114e5d38a80 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi | |||
| @@ -312,7 +312,7 @@ to @code{regexp-history}. | |||
| 312 | 312 | ||
| 313 | @cindex @code{case-fold}, text property | 313 | @cindex @code{case-fold}, text property |
| 314 | @findex read-regexp-case-fold-search | 314 | @findex read-regexp-case-fold-search |
| 315 | The user can use the @kbd{M-c} command to indicate whether case | 315 | The user can use the @kbd{M-s c} command to indicate whether case |
| 316 | folding should be on or off. If the user has used this command, the | 316 | folding should be on or off. If the user has used this command, the |
| 317 | returned string will have the text property @code{case-fold} set to | 317 | returned string will have the text property @code{case-fold} set to |
| 318 | either @code{fold} or @code{inhibit-fold}. It is up to the caller of | 318 | either @code{fold} or @code{inhibit-fold}. It is up to the caller of |
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi index ca18f0a9cc1..3d86a87516b 100644 --- a/doc/lispref/strings.texi +++ b/doc/lispref/strings.texi | |||
| @@ -911,8 +911,8 @@ This function returns a new string containing one character, | |||
| 911 | @end defun | 911 | @end defun |
| 912 | 912 | ||
| 913 | @defun string-to-char string | 913 | @defun string-to-char string |
| 914 | This function returns the first character in @var{string}. This | 914 | This function returns the first character in @var{string}. This is |
| 915 | mostly identical to @code{(aref string 0)}, except that it returns 0 | 915 | mostly identical to @w{@code{(aref string 0)}}, except that it returns 0 |
| 916 | if the string is empty. (The value is also 0 when the first character | 916 | if the string is empty. (The value is also 0 when the first character |
| 917 | of @var{string} is the null character, @acronym{ASCII} code 0.) This | 917 | of @var{string} is the null character, @acronym{ASCII} code 0.) This |
| 918 | function may be eliminated in the future if it does not seem useful | 918 | function may be eliminated in the future if it does not seem useful |
diff --git a/doc/misc/eshell.texi b/doc/misc/eshell.texi index c40ff58f42c..57a2020fdca 100644 --- a/doc/misc/eshell.texi +++ b/doc/misc/eshell.texi | |||
| @@ -64,10 +64,11 @@ modify this GNU manual.'' | |||
| 64 | 64 | ||
| 65 | Eshell is a shell-like command interpreter implemented in Emacs Lisp. | 65 | Eshell is a shell-like command interpreter implemented in Emacs Lisp. |
| 66 | It invokes no external processes except for those requested by the | 66 | It invokes no external processes except for those requested by the |
| 67 | user. It is intended to be an alternative to the IELM (@pxref{Lisp Interaction, Emacs Lisp Interaction, , emacs, The Emacs Editor}) | 67 | user. It is intended to be an alternative to the IELM (@pxref{Lisp |
| 68 | REPL for Emacs @emph{and} with an interface similar to command shells | 68 | Interaction, Emacs Lisp Interaction, , emacs, The Emacs Editor}) |
| 69 | such as @command{bash}, @command{zsh}, @command{rc}, or | 69 | REPL@footnote{Short for ``Read-Eval-Print Loop''.} for Emacs |
| 70 | @command{4dos}. | 70 | @emph{and} with an interface similar to command shells such as |
| 71 | @command{bash}, @command{zsh}, @command{rc}, or @command{4dos}. | ||
| 71 | @c This manual is updated to release 2.4 of Eshell. | 72 | @c This manual is updated to release 2.4 of Eshell. |
| 72 | 73 | ||
| 73 | @insertcopying | 74 | @insertcopying |
| @@ -193,6 +194,13 @@ In a command shell, everything is done by invoking commands. This | |||
| 193 | chapter covers command invocations in Eshell, including the command | 194 | chapter covers command invocations in Eshell, including the command |
| 194 | history and invoking commands in a script file. | 195 | history and invoking commands in a script file. |
| 195 | 196 | ||
| 197 | Unlike regular system shells, Eshell never invokes kernel functions | ||
| 198 | directly, such as @code{exec(3)}. Instead, it uses the Lisp functions | ||
| 199 | available in the Emacs Lisp library. It does this by transforming the | ||
| 200 | input line into a callable Lisp form.@footnote{To see the Lisp form | ||
| 201 | that will be invoked, type this as the Eshell prompt: | ||
| 202 | @kbd{eshell-parse-command 'echo hello'}} | ||
| 203 | |||
| 196 | @menu | 204 | @menu |
| 197 | * Invocation:: | 205 | * Invocation:: |
| 198 | * Arguments:: | 206 | * Arguments:: |
| @@ -207,23 +215,16 @@ history and invoking commands in a script file. | |||
| 207 | 215 | ||
| 208 | @node Invocation | 216 | @node Invocation |
| 209 | @section Invocation | 217 | @section Invocation |
| 210 | Unlike regular system shells, Eshell never invokes kernel functions | 218 | Eshell is both a command shell and an Emacs Lisp @acronym{REPL}. As a |
| 211 | directly, such as @code{exec(3)}. Instead, it uses the Lisp functions | 219 | result, you can invoke commands in two different ways: in @dfn{command |
| 212 | available in the Emacs Lisp library. It does this by transforming the | 220 | form} or in @dfn{lisp form}. |
| 213 | input line into a callable Lisp form.@footnote{To see the Lisp form that will be invoked, type: @samp{eshell-parse-command "echo hello"}} | ||
| 214 | 221 | ||
| 215 | The command can be either an Elisp function or an external command. | 222 | You can use the semicolon (@code{;}) to separate multiple command |
| 216 | Eshell looks first for an alias (@pxref{Aliases}) with the same name as the | 223 | invocations on a single line, executing each in turn. You can also |
| 217 | command, then a built-in (@pxref{Built-ins}) or a function with the | 224 | separate commands with @code{&&} or @code{||}. When using @code{&&}, |
| 218 | same name; if there is no match, it then tries to execute it as an | 225 | Eshell will execute the second command only if the first succeeds |
| 219 | external command. | 226 | (i.e.@: has an exit status of 0); with @code{||}, Eshell will execute |
| 220 | 227 | the second command only if the first fails. | |
| 221 | The semicolon (@code{;}) can be used to separate multiple command | ||
| 222 | invocations on a single line. You can also separate commands with | ||
| 223 | @code{&&} or @code{||}. When using @code{&&}, Eshell will execute the | ||
| 224 | second command only if the first succeeds (i.e.@: has an exit | ||
| 225 | status of 0); with @code{||}, Eshell will execute the second command | ||
| 226 | only if the first fails. | ||
| 227 | 228 | ||
| 228 | A command invocation followed by an ampersand (@code{&}) will be run | 229 | A command invocation followed by an ampersand (@code{&}) will be run |
| 229 | in the background. Eshell has no job control, so you can not suspend | 230 | in the background. Eshell has no job control, so you can not suspend |
| @@ -232,12 +233,80 @@ the foreground. That said, background processes invoked from Eshell | |||
| 232 | can be controlled the same way as any other background process in | 233 | can be controlled the same way as any other background process in |
| 233 | Emacs. | 234 | Emacs. |
| 234 | 235 | ||
| 236 | @subsection Command form | ||
| 237 | Command form looks much the same as in other shells. A command | ||
| 238 | consists of arguments separated by spaces; the first argument is the | ||
| 239 | command to run, with any subsequent arguments being passed to that | ||
| 240 | command. | ||
| 241 | |||
| 242 | @example | ||
| 243 | ~ $ echo hello | ||
| 244 | hello | ||
| 245 | @end example | ||
| 246 | |||
| 247 | @cindex order of looking for commands | ||
| 248 | @cindex command lookup order | ||
| 249 | The command can be either an Elisp function or an external command. | ||
| 250 | Eshell looks for the command in the following order: | ||
| 251 | |||
| 252 | @enumerate | ||
| 253 | @item | ||
| 254 | As a command alias (@pxref{Aliases}) | ||
| 255 | |||
| 256 | @item | ||
| 257 | As a built-in command (@pxref{Built-ins}) | ||
| 258 | |||
| 259 | @item | ||
| 260 | As an external program | ||
| 261 | |||
| 262 | @item | ||
| 263 | As an ordinary Lisp function | ||
| 264 | @end enumerate | ||
| 265 | |||
| 266 | @vindex eshell-prefer-lisp-functions | ||
| 267 | If you would prefer to use ordinary Lisp functions over external | ||
| 268 | programs, set the option @code{eshell-prefer-lisp-functions} to | ||
| 269 | @code{t}. This will swap the lookup order of the last two items. | ||
| 270 | |||
| 271 | You can also group command forms together into a subcommand with curly | ||
| 272 | braces (@code{@{@}}). This lets you use the output of a subcommand as | ||
| 273 | an argument to another command, or within control flow statements | ||
| 274 | (@pxref{Control Flow}). | ||
| 275 | |||
| 276 | @example | ||
| 277 | ~ $ echo @{echo hello; echo there@} | ||
| 278 | hellothere | ||
| 279 | @end example | ||
| 280 | |||
| 281 | @subsection Lisp form | ||
| 282 | Lisp form looks like ordinary Emacs Lisp code, because that's what it | ||
| 283 | is. As a result, you can use any syntax normally available to an | ||
| 284 | Emacs Lisp program (@pxref{Top, , , elisp, The Emacs Lisp Reference | ||
| 285 | Manual}). | ||
| 286 | |||
| 287 | @example | ||
| 288 | ~ $ (format "hello, %s" user-login-name) | ||
| 289 | hello, user | ||
| 290 | @end example | ||
| 291 | |||
| 292 | In addition, you can @emph{combine} command forms and Lisp forms | ||
| 293 | together into single statements, letting you use whatever form is the | ||
| 294 | most convenient for expressing your intentions. | ||
| 295 | |||
| 296 | @example | ||
| 297 | ~ $ ls *.patch > (format-time-string "%F.log") | ||
| 298 | @end example | ||
| 299 | |||
| 300 | This command writes a list of all files matching the glob pattern | ||
| 301 | @code{*.patch} (@pxref{Globbing}) to a file named | ||
| 302 | @code{@var{current-date}.log} (@pxref{Redirection}). | ||
| 303 | |||
| 235 | @node Arguments | 304 | @node Arguments |
| 236 | @section Arguments | 305 | @section Arguments |
| 237 | Ordinarily, command arguments are parsed by Eshell as either strings | 306 | Ordinarily, Eshell parses arguments in command form as either strings |
| 238 | or numbers, depending on what the parser thinks they look like. To | 307 | or numbers, depending on what the parser thinks they look like. To |
| 239 | specify an argument of some other data type, you can use an | 308 | specify an argument of some other data type, you can use a Lisp form |
| 240 | @ref{Dollars Expansion, Elisp expression}: | 309 | (@pxref{Invocation}): |
| 241 | 310 | ||
| 242 | @example | 311 | @example |
| 243 | ~ $ echo (list 1 2 3) | 312 | ~ $ echo (list 1 2 3) |
| @@ -354,10 +423,6 @@ eshell/sudo is a compiled Lisp function in `em-tramp.el'. | |||
| 354 | sudo is an alias, defined as "*sudo $@@*" | 423 | sudo is an alias, defined as "*sudo $@@*" |
| 355 | @end example | 424 | @end example |
| 356 | 425 | ||
| 357 | @vindex eshell-prefer-lisp-functions | ||
| 358 | If you would prefer to use the built-in commands instead of the external | ||
| 359 | commands, set @code{eshell-prefer-lisp-functions} to @code{t}. | ||
| 360 | |||
| 361 | Some of the built-in commands have different behavior from their | 426 | Some of the built-in commands have different behavior from their |
| 362 | external counterparts, and some have no external counterpart. Most of | 427 | external counterparts, and some have no external counterpart. Most of |
| 363 | these will print a usage message when given the @code{--help} option. | 428 | these will print a usage message when given the @code{--help} option. |
| @@ -923,15 +988,14 @@ For example, you could handle a subset of the options for the | |||
| 923 | @node Variables | 988 | @node Variables |
| 924 | @section Variables | 989 | @section Variables |
| 925 | @vindex eshell-prefer-lisp-variables | 990 | @vindex eshell-prefer-lisp-variables |
| 926 | Since Eshell is a combination of an Emacs @acronym{REPL}@footnote{ | 991 | Since Eshell is a combination of an Emacs @acronym{REPL} and a command |
| 927 | Short for ``Read-Eval-Print Loop''. | 992 | shell, it can refer to variables from two different sources: ordinary |
| 928 | } and a command shell, it can refer to variables from two different | 993 | Emacs Lisp variables, as well as environment variables. By default, |
| 929 | sources: ordinary Emacs Lisp variables, as well as environment | 994 | when using a variable in Eshell, it will first look in the list of |
| 930 | variables. By default, when using a variable in Eshell, it will first | 995 | built-in variables, then in the list of environment variables, and |
| 931 | look in the list of built-in variables, then in the list of | 996 | finally in the list of Lisp variables. If you would prefer to use |
| 932 | environment variables, and finally in the list of Lisp variables. If | 997 | Lisp variables over environment variables, you can set |
| 933 | you would prefer to use Lisp variables over environment variables, you | 998 | @code{eshell-prefer-lisp-variables} to @code{t}. |
| 934 | can set @code{eshell-prefer-lisp-variables} to @code{t}. | ||
| 935 | 999 | ||
| 936 | You can set variables in a few different ways. To set a Lisp | 1000 | You can set variables in a few different ways. To set a Lisp |
| 937 | variable, you can use the command @samp{setq @var{name} @var{value}}, | 1001 | variable, you can use the command @samp{setq @var{name} @var{value}}, |
diff --git a/etc/NEWS.29 b/etc/NEWS.29 index d1ddd0194c1..9f735bec443 100644 --- a/etc/NEWS.29 +++ b/etc/NEWS.29 | |||
| @@ -2079,7 +2079,7 @@ The VC Directory buffer now uses the prefix 'b' for these branch-related | |||
| 2079 | commands. | 2079 | commands. |
| 2080 | 2080 | ||
| 2081 | +++ | 2081 | +++ |
| 2082 | *** New command '%' ('vc-dir-mark-by-regexp'). | 2082 | *** New command 'vc-dir-mark-by-regexp' bound to '% m' and '* %'. |
| 2083 | This command marks files based on a regexp. If given a prefix | 2083 | This command marks files based on a regexp. If given a prefix |
| 2084 | argument, unmark instead. | 2084 | argument, unmark instead. |
| 2085 | 2085 | ||
| @@ -3236,6 +3236,11 @@ An optional major mode based on the tree-sitter library for editing | |||
| 3236 | programs in the C++ language. | 3236 | programs in the C++ language. |
| 3237 | 3237 | ||
| 3238 | +++ | 3238 | +++ |
| 3239 | *** New command 'c-or-c++-ts-mode'. | ||
| 3240 | A command that automatically guesses the language of a header file, | ||
| 3241 | and enables either 'c-ts-mode' or 'c++-ts-mode' accordingly. | ||
| 3242 | |||
| 3243 | +++ | ||
| 3239 | *** New major mode 'java-ts-mode'. | 3244 | *** New major mode 'java-ts-mode'. |
| 3240 | An optional major mode based on the tree-sitter library for editing | 3245 | An optional major mode based on the tree-sitter library for editing |
| 3241 | programs in the Java language. | 3246 | programs in the Java language. |
| @@ -3802,7 +3807,7 @@ These function now take an optional comparison PREDICATE argument. | |||
| 3802 | ** 'read-multiple-choice' can now use long-form answers. | 3807 | ** 'read-multiple-choice' can now use long-form answers. |
| 3803 | 3808 | ||
| 3804 | +++ | 3809 | +++ |
| 3805 | ** 'M-c' in 'read-regexp' now toggles case folding. | 3810 | ** 'M-s c' in 'read-regexp' now toggles case folding. |
| 3806 | 3811 | ||
| 3807 | +++ | 3812 | +++ |
| 3808 | ** 'completing-read' now allows a function as its REQUIRE-MATCH argument. | 3813 | ** 'completing-read' now allows a function as its REQUIRE-MATCH argument. |
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 36aab087d94..cffe8b09f53 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -2811,7 +2811,7 @@ values. Note that this macro is *not* available in Common Lisp. | |||
| 2811 | As a special case, if `(PLACE)' is used instead of `(PLACE VALUE)', | 2811 | As a special case, if `(PLACE)' is used instead of `(PLACE VALUE)', |
| 2812 | the PLACE is not modified before executing BODY. | 2812 | the PLACE is not modified before executing BODY. |
| 2813 | 2813 | ||
| 2814 | See info node `(cl) Function Bindings' for details. | 2814 | See info node `(cl) Modify Macros' for details. |
| 2815 | 2815 | ||
| 2816 | \(fn ((PLACE VALUE) ...) BODY...)" | 2816 | \(fn ((PLACE VALUE) ...) BODY...)" |
| 2817 | (declare (indent 1) (debug ((&rest [&or (symbolp form) | 2817 | (declare (indent 1) (debug ((&rest [&or (symbolp form) |
diff --git a/lisp/emacs-lisp/warnings.el b/lisp/emacs-lisp/warnings.el index 9505c935816..31b840d6c83 100644 --- a/lisp/emacs-lisp/warnings.el +++ b/lisp/emacs-lisp/warnings.el | |||
| @@ -204,8 +204,12 @@ SUPPRESS-LIST is the list of kinds of warnings to suppress." | |||
| 204 | some-match)) | 204 | some-match)) |
| 205 | 205 | ||
| 206 | (define-icon warnings-suppress button | 206 | (define-icon warnings-suppress button |
| 207 | '((emoji "⛔") | 207 | `((emoji "⛔") |
| 208 | (symbol " ■ ") | 208 | ;; Many MS-Windows console fonts don't have good glyphs for U+25A0. |
| 209 | (symbol ,(if (and (eq system-type 'windows-nt) | ||
| 210 | (null window-system)) | ||
| 211 | " » " | ||
| 212 | " ■ ")) | ||
| 209 | (text " stop ")) | 213 | (text " stop ")) |
| 210 | "Suppress warnings." | 214 | "Suppress warnings." |
| 211 | :version "29.1" | 215 | :version "29.1" |
diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index 9eb4f1a9000..994555acecf 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el | |||
| @@ -202,12 +202,13 @@ if ARG is omitted or nil. | |||
| 202 | (,disable))) | 202 | (,disable))) |
| 203 | ,(erc--assemble-toggle local-p name enable mode t enable-body) | 203 | ,(erc--assemble-toggle local-p name enable mode t enable-body) |
| 204 | ,(erc--assemble-toggle local-p name disable mode nil disable-body) | 204 | ,(erc--assemble-toggle local-p name disable mode nil disable-body) |
| 205 | ,(when (and alias (not (eq name alias))) | 205 | ,@(and-let* ((alias) |
| 206 | `(defalias | 206 | ((not (eq name alias))) |
| 207 | ',(intern | 207 | (aname (intern (format "erc-%s-mode" |
| 208 | (format "erc-%s-mode" | 208 | (downcase (symbol-name alias)))))) |
| 209 | (downcase (symbol-name alias)))) | 209 | `((defalias ',aname #',mode) |
| 210 | #',mode)) | 210 | (put ',aname 'erc-module ',(erc--normalize-module-symbol name)))) |
| 211 | (put ',mode 'erc-module ',(erc--normalize-module-symbol name)) | ||
| 211 | ;; For find-function and find-variable. | 212 | ;; For find-function and find-variable. |
| 212 | (put ',mode 'definition-name ',name) | 213 | (put ',mode 'definition-name ',name) |
| 213 | (put ',enable 'definition-name ',name) | 214 | (put ',enable 'definition-name ',name) |
diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el index 73ce612a33d..5601ede27a5 100644 --- a/lisp/erc/erc-compat.el +++ b/lisp/erc/erc-compat.el | |||
| @@ -260,8 +260,8 @@ If START or END is negative, it counts from the end." | |||
| 260 | (dolist (e rv out) | 260 | (dolist (e rv out) |
| 261 | (when-let* ((s (plist-get e :secret)) | 261 | (when-let* ((s (plist-get e :secret)) |
| 262 | (v (auth-source--obfuscate s))) | 262 | (v (auth-source--obfuscate s))) |
| 263 | (setf (plist-get e :secret) | 263 | (setq e (plist-put e :secret (apply-partially |
| 264 | (apply-partially #'auth-source--deobfuscate v))) | 264 | #'auth-source--deobfuscate v)))) |
| 265 | (push e out))) | 265 | (push e out))) |
| 266 | rv))) | 266 | rv))) |
| 267 | 267 | ||
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index ba7db15cf8c..7f51b7bfb2e 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el | |||
| @@ -1305,6 +1305,14 @@ See also `erc-show-my-nick'." | |||
| 1305 | 1305 | ||
| 1306 | (defvar-local erc-dbuf nil) | 1306 | (defvar-local erc-dbuf nil) |
| 1307 | 1307 | ||
| 1308 | ;; See comments in `erc-scenarios-base-local-modules' explaining why | ||
| 1309 | ;; this is insufficient as a public interface. | ||
| 1310 | |||
| 1311 | (defvar erc--target-priors nil | ||
| 1312 | "Analogous to `erc--server-reconnecting' but for target buffers. | ||
| 1313 | Bound to local variables from an existing (logical) session's | ||
| 1314 | buffer during local-module setup and `erc-mode-hook' activation.") | ||
| 1315 | |||
| 1308 | (defun erc--target-from-string (string) | 1316 | (defun erc--target-from-string (string) |
| 1309 | "Construct an `erc--target' variant from STRING." | 1317 | "Construct an `erc--target' variant from STRING." |
| 1310 | (funcall (if (erc-channel-p string) | 1318 | (funcall (if (erc-channel-p string) |
| @@ -1950,7 +1958,8 @@ nil." | |||
| 1950 | (let ((out (list (reverse new-modes)))) | 1958 | (let ((out (list (reverse new-modes)))) |
| 1951 | (pcase-dolist (`(,k . ,v) old-vars) | 1959 | (pcase-dolist (`(,k . ,v) old-vars) |
| 1952 | (when (and (string-prefix-p "erc-" (symbol-name k)) | 1960 | (when (and (string-prefix-p "erc-" (symbol-name k)) |
| 1953 | (string-suffix-p "-mode" (symbol-name k))) | 1961 | (string-suffix-p "-mode" (symbol-name k)) |
| 1962 | (get k 'erc-module)) | ||
| 1954 | (if v | 1963 | (if v |
| 1955 | (cl-pushnew k (car out)) | 1964 | (cl-pushnew k (car out)) |
| 1956 | (setf (car out) (delq k (car out))) | 1965 | (setf (car out) (delq k (car out))) |
| @@ -1985,7 +1994,9 @@ Returns the buffer for the given server or channel." | |||
| 1985 | (let* ((target (and channel (erc--target-from-string channel))) | 1994 | (let* ((target (and channel (erc--target-from-string channel))) |
| 1986 | (buffer (erc-get-buffer-create server port nil target id)) | 1995 | (buffer (erc-get-buffer-create server port nil target id)) |
| 1987 | (old-buffer (current-buffer)) | 1996 | (old-buffer (current-buffer)) |
| 1988 | (old-vars (and target (buffer-local-variables))) | 1997 | (erc--target-priors (and target ; buf from prior session |
| 1998 | (buffer-local-value 'erc--target buffer) | ||
| 1999 | (buffer-local-variables buffer))) | ||
| 1989 | (old-recon-count erc-server-reconnect-count) | 2000 | (old-recon-count erc-server-reconnect-count) |
| 1990 | (old-point nil) | 2001 | (old-point nil) |
| 1991 | (delayed-modules nil) | 2002 | (delayed-modules nil) |
| @@ -1998,7 +2009,8 @@ Returns the buffer for the given server or channel." | |||
| 1998 | (setq old-point (point)) | 2009 | (setq old-point (point)) |
| 1999 | (setq delayed-modules | 2010 | (setq delayed-modules |
| 2000 | (erc--merge-local-modes (erc--update-modules) | 2011 | (erc--merge-local-modes (erc--update-modules) |
| 2001 | (or erc--server-reconnecting old-vars))) | 2012 | (or erc--server-reconnecting |
| 2013 | erc--target-priors))) | ||
| 2002 | 2014 | ||
| 2003 | (delay-mode-hooks (erc-mode)) | 2015 | (delay-mode-hooks (erc-mode)) |
| 2004 | 2016 | ||
| @@ -2071,9 +2083,7 @@ Returns the buffer for the given server or channel." | |||
| 2071 | 2083 | ||
| 2072 | (erc-determine-parameters server port nick full-name user passwd) | 2084 | (erc-determine-parameters server port nick full-name user passwd) |
| 2073 | 2085 | ||
| 2074 | (save-excursion (run-mode-hooks)) | 2086 | ;; FIXME consolidate this prompt-setup logic with the pass above. |
| 2075 | (dolist (mod (car delayed-modules)) (funcall mod +1)) | ||
| 2076 | (dolist (var (cdr delayed-modules)) (set var nil)) | ||
| 2077 | 2087 | ||
| 2078 | ;; set up prompt | 2088 | ;; set up prompt |
| 2079 | (unless continued-session | 2089 | (unless continued-session |
| @@ -2086,6 +2096,10 @@ Returns the buffer for the given server or channel." | |||
| 2086 | (erc-display-prompt) | 2096 | (erc-display-prompt) |
| 2087 | (goto-char (point-max))) | 2097 | (goto-char (point-max))) |
| 2088 | 2098 | ||
| 2099 | (save-excursion (run-mode-hooks) | ||
| 2100 | (dolist (mod (car delayed-modules)) (funcall mod +1)) | ||
| 2101 | (dolist (var (cdr delayed-modules)) (set var nil))) | ||
| 2102 | |||
| 2089 | ;; Saving log file on exit | 2103 | ;; Saving log file on exit |
| 2090 | (run-hook-with-args 'erc-connect-pre-hook buffer) | 2104 | (run-hook-with-args 'erc-connect-pre-hook buffer) |
| 2091 | 2105 | ||
diff --git a/lisp/eshell/em-basic.el b/lisp/eshell/em-basic.el index dfbe4db0896..bfff3bdf56e 100644 --- a/lisp/eshell/em-basic.el +++ b/lisp/eshell/em-basic.el | |||
| @@ -132,7 +132,8 @@ or `eshell-printn' for display." | |||
| 132 | ;; bug#27361. | 132 | ;; bug#27361. |
| 133 | (when (equal output-newline '(nil)) | 133 | (when (equal output-newline '(nil)) |
| 134 | (display-warning | 134 | (display-warning |
| 135 | :warning "To terminate with a newline, you should use -N instead.")) | 135 | '(eshell echo) |
| 136 | "To terminate with a newline, you should use -N instead.")) | ||
| 136 | (eshell-echo args output-newline)))) | 137 | (eshell-echo args output-newline)))) |
| 137 | 138 | ||
| 138 | (defun eshell/printnl (&rest args) | 139 | (defun eshell/printnl (&rest args) |
diff --git a/lisp/eshell/esh-var.el b/lisp/eshell/esh-var.el index fd76a2c6f09..27e68138aa2 100644 --- a/lisp/eshell/esh-var.el +++ b/lisp/eshell/esh-var.el | |||
| @@ -628,9 +628,10 @@ If QUOTED is non-nil, this was invoked inside double-quotes." | |||
| 628 | (if (or (eq max-arity 'many) (>= max-arity 2)) | 628 | (if (or (eq max-arity 'many) (>= max-arity 2)) |
| 629 | (funcall target indices quoted) | 629 | (funcall target indices quoted) |
| 630 | (display-warning | 630 | (display-warning |
| 631 | :warning (concat "Function for `eshell-variable-aliases-list' " | 631 | '(eshell variable-alias) |
| 632 | "entry should accept two arguments: INDICES " | 632 | (concat "Function for `eshell-variable-aliases-list' " |
| 633 | "and QUOTED.'")) | 633 | "entry should accept two arguments: INDICES " |
| 634 | "and QUOTED.'")) | ||
| 634 | (funcall target indices))))) | 635 | (funcall target indices))))) |
| 635 | ((symbolp target) | 636 | ((symbolp target) |
| 636 | (eshell-apply-indices (symbol-value target) indices quoted)) | 637 | (eshell-apply-indices (symbol-value target) indices quoted)) |
diff --git a/lisp/files.el b/lisp/files.el index daa86e94d76..29ba523fa69 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -5059,7 +5059,8 @@ This is a separate procedure so your site-init or startup file can | |||
| 5059 | redefine it. | 5059 | redefine it. |
| 5060 | If the optional argument KEEP-BACKUP-VERSION is non-nil, | 5060 | If the optional argument KEEP-BACKUP-VERSION is non-nil, |
| 5061 | we do not remove backup version numbers, only true file version numbers. | 5061 | we do not remove backup version numbers, only true file version numbers. |
| 5062 | See also `file-name-version-regexp'." | 5062 | See `file-name-version-regexp' for what constitutes backup versions |
| 5063 | and version strings." | ||
| 5063 | (let ((handler (find-file-name-handler name 'file-name-sans-versions))) | 5064 | (let ((handler (find-file-name-handler name 'file-name-sans-versions))) |
| 5064 | (if handler | 5065 | (if handler |
| 5065 | (funcall handler 'file-name-sans-versions name keep-backup-version) | 5066 | (funcall handler 'file-name-sans-versions name keep-backup-version) |
| @@ -5111,9 +5112,12 @@ the group would be preserved too." | |||
| 5111 | (file-attribute-group-id attributes))))))))))) | 5112 | (file-attribute-group-id attributes))))))))))) |
| 5112 | 5113 | ||
| 5113 | (defun file-name-sans-extension (filename) | 5114 | (defun file-name-sans-extension (filename) |
| 5114 | "Return FILENAME sans final \"extension\". | 5115 | "Return FILENAME sans final \"extension\" and any backup version strings. |
| 5115 | The extension, in a file name, is the part that begins with the last `.', | 5116 | The extension, in a file name, is the part that begins with the last `.', |
| 5116 | except that a leading `.' of the file name, if there is one, doesn't count." | 5117 | except that a leading `.' of the file name, if there is one, doesn't count. |
| 5118 | Any extensions that indicate backup versions and version strings are | ||
| 5119 | removed by calling `file-name-sans-versions', which see, before looking | ||
| 5120 | for the \"real\" file extension." | ||
| 5117 | (save-match-data | 5121 | (save-match-data |
| 5118 | (let ((file (file-name-sans-versions (file-name-nondirectory filename))) | 5122 | (let ((file (file-name-sans-versions (file-name-nondirectory filename))) |
| 5119 | directory) | 5123 | directory) |
| @@ -5127,12 +5131,14 @@ except that a leading `.' of the file name, if there is one, doesn't count." | |||
| 5127 | filename)))) | 5131 | filename)))) |
| 5128 | 5132 | ||
| 5129 | (defun file-name-extension (filename &optional period) | 5133 | (defun file-name-extension (filename &optional period) |
| 5130 | "Return FILENAME's final \"extension\". | 5134 | "Return FILENAME's final \"extension\" sans any backup version strings. |
| 5131 | The extension, in a file name, is the part that begins with the last `.', | 5135 | The extension, in a file name, is the part that begins with the last `.', |
| 5132 | excluding version numbers and backup suffixes, except that a leading `.' | 5136 | except that a leading `.' of the file name, if there is one, doesn't count. |
| 5133 | of the file name, if there is one, doesn't count. | 5137 | This function calls `file-name-sans-versions', which see, to remove from |
| 5138 | the extension it returns any parts that indicate backup versions and | ||
| 5139 | version strings. | ||
| 5134 | Return nil for extensionless file names such as `foo'. | 5140 | Return nil for extensionless file names such as `foo'. |
| 5135 | Return the empty string for file names such as `foo.'. | 5141 | Return the empty string for file names such as `foo.' that end in a period. |
| 5136 | 5142 | ||
| 5137 | By default, the returned value excludes the period that starts the | 5143 | By default, the returned value excludes the period that starts the |
| 5138 | extension, but if the optional argument PERIOD is non-nil, the period | 5144 | extension, but if the optional argument PERIOD is non-nil, the period |
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index c066a79815a..b3d162cd3ab 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el | |||
| @@ -976,6 +976,50 @@ This mode is independent from the classic cc-mode.el based | |||
| 976 | 976 | ||
| 977 | (treesit-major-mode-setup))) | 977 | (treesit-major-mode-setup))) |
| 978 | 978 | ||
| 979 | ;; We could alternatively use parsers, but if this works well, I don't | ||
| 980 | ;; see the need to change. This is copied verbatim from cc-guess.el. | ||
| 981 | (defconst c-ts-mode--c-or-c++-regexp | ||
| 982 | (eval-when-compile | ||
| 983 | (let ((id "[a-zA-Z_][a-zA-Z0-9_]*") (ws "[ \t]+") (ws-maybe "[ \t]*") | ||
| 984 | (headers '("string" "string_view" "iostream" "map" "unordered_map" | ||
| 985 | "set" "unordered_set" "vector" "tuple"))) | ||
| 986 | (concat "^" ws-maybe "\\(?:" | ||
| 987 | "using" ws "\\(?:namespace" ws | ||
| 988 | "\\|" id "::" | ||
| 989 | "\\|" id ws-maybe "=\\)" | ||
| 990 | "\\|" "\\(?:inline" ws "\\)?namespace" | ||
| 991 | "\\(:?" ws "\\(?:" id "::\\)*" id "\\)?" ws-maybe "{" | ||
| 992 | "\\|" "class" ws id | ||
| 993 | "\\(?:" ws "final" "\\)?" ws-maybe "[:{;\n]" | ||
| 994 | "\\|" "struct" ws id "\\(?:" ws "final" ws-maybe "[:{\n]" | ||
| 995 | "\\|" ws-maybe ":\\)" | ||
| 996 | "\\|" "template" ws-maybe "<.*?>" | ||
| 997 | "\\|" "#include" ws-maybe "<" (regexp-opt headers) ">" | ||
| 998 | "\\)"))) | ||
| 999 | "A regexp applied to C header files to check if they are really C++.") | ||
| 1000 | |||
| 1001 | ;;;###autoload | ||
| 1002 | (defun c-or-c++-ts-mode () | ||
| 1003 | "Analyze buffer and enable either C or C++ mode. | ||
| 1004 | |||
| 1005 | Some people and projects use .h extension for C++ header files | ||
| 1006 | which is also the one used for C header files. This makes | ||
| 1007 | matching on file name insufficient for detecting major mode that | ||
| 1008 | should be used. | ||
| 1009 | |||
| 1010 | This function attempts to use file contents to determine whether | ||
| 1011 | the code is C or C++ and based on that chooses whether to enable | ||
| 1012 | `c-ts-mode' or `c++-ts-mode'." | ||
| 1013 | (interactive) | ||
| 1014 | (if (save-excursion | ||
| 1015 | (save-restriction | ||
| 1016 | (save-match-data ; Why `save-match-data'? | ||
| 1017 | (widen) | ||
| 1018 | (goto-char (point-min)) | ||
| 1019 | (re-search-forward c-ts-mode--c-or-c++-regexp nil t)))) | ||
| 1020 | (c++-ts-mode) | ||
| 1021 | (c-ts-mode))) | ||
| 1022 | |||
| 979 | (provide 'c-ts-mode) | 1023 | (provide 'c-ts-mode) |
| 980 | 1024 | ||
| 981 | ;;; c-ts-mode.el ends here | 1025 | ;;; c-ts-mode.el ends here |
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el index 493035d38b4..bdbc03e7c94 100644 --- a/lisp/progmodes/cc-defs.el +++ b/lisp/progmodes/cc-defs.el | |||
| @@ -1361,6 +1361,28 @@ nil; point is then left undefined." | |||
| 1361 | (search-forward-regexp "\\(\n\\|.\\)") ; to set the match-data. | 1361 | (search-forward-regexp "\\(\n\\|.\\)") ; to set the match-data. |
| 1362 | (point)))) | 1362 | (point)))) |
| 1363 | 1363 | ||
| 1364 | (defmacro c-search-forward-non-nil-char-property (property &optional limit) | ||
| 1365 | "Search forward for a text-property PROPERTY value non-nil. | ||
| 1366 | LIMIT bounds the search. | ||
| 1367 | |||
| 1368 | Leave point just after the character. The match data remain | ||
| 1369 | unchanged. Return the value of PROPERTY. If a non-nil value | ||
| 1370 | isn't found, return nil; point is then left undefined." | ||
| 1371 | (declare (debug t)) | ||
| 1372 | `(let* ((-limit- (or ,limit (point-max))) | ||
| 1373 | (value (c-get-char-property (point) ,property))) | ||
| 1374 | (cond | ||
| 1375 | ((>= (point) -limit-) | ||
| 1376 | nil) | ||
| 1377 | (value | ||
| 1378 | (forward-char) | ||
| 1379 | value) | ||
| 1380 | (t (let ((place (c-next-single-property-change | ||
| 1381 | (point) ,property nil -limit-))) | ||
| 1382 | (when place | ||
| 1383 | (goto-char (1+ place)) | ||
| 1384 | (c-get-char-property place ,property))))))) | ||
| 1385 | |||
| 1364 | (defmacro c-search-backward-char-property (property value &optional limit) | 1386 | (defmacro c-search-backward-char-property (property value &optional limit) |
| 1365 | "Search backward for a text-property PROPERTY having value VALUE. | 1387 | "Search backward for a text-property PROPERTY having value VALUE. |
| 1366 | LIMIT bounds the search. The comparison is done with `equal'. | 1388 | LIMIT bounds the search. The comparison is done with `equal'. |
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 45d90ea2431..3fa407dd338 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -142,6 +142,10 @@ | |||
| 142 | ;; Put on the brace which introduces a brace list and on the commas | 142 | ;; Put on the brace which introduces a brace list and on the commas |
| 143 | ;; which separate the elements within it. | 143 | ;; which separate the elements within it. |
| 144 | ;; | 144 | ;; |
| 145 | ;; 'c-typedef This property is applied to the first character of a | ||
| 146 | ;; "typedef" keyword. It's value is a list of the identifiers that | ||
| 147 | ;; the "typedef" declares as types. | ||
| 148 | ;; | ||
| 145 | ;; 'c-<>-c-types-set | 149 | ;; 'c-<>-c-types-set |
| 146 | ;; This property is set on an opening angle bracket, and indicates that | 150 | ;; This property is set on an opening angle bracket, and indicates that |
| 147 | ;; any "," separators within the template/generic expression have been | 151 | ;; any "," separators within the template/generic expression have been |
| @@ -10024,10 +10028,10 @@ This function might do hidden buffer changes." | |||
| 10024 | ;; an identifier instead. | 10028 | ;; an identifier instead. |
| 10025 | (declare (debug nil)) | 10029 | (declare (debug nil)) |
| 10026 | `(progn | 10030 | `(progn |
| 10031 | (setq identifier-start type-start) | ||
| 10027 | ,(unless short | 10032 | ,(unless short |
| 10028 | ;; These identifiers are bound only in the inner let. | 10033 | ;; These identifiers are bound only in the inner let. |
| 10029 | '(setq identifier-type at-type | 10034 | '(setq identifier-type at-type |
| 10030 | identifier-start type-start | ||
| 10031 | got-parens nil | 10035 | got-parens nil |
| 10032 | got-identifier t | 10036 | got-identifier t |
| 10033 | got-suffix t | 10037 | got-suffix t |
| @@ -10102,10 +10106,11 @@ This function might do hidden buffer changes." | |||
| 10102 | ;; The second element of the return value is non-nil when something | 10106 | ;; The second element of the return value is non-nil when something |
| 10103 | ;; indicating the identifier is a type occurs in the declaration. | 10107 | ;; indicating the identifier is a type occurs in the declaration. |
| 10104 | ;; Specifically it is nil, or a three element list (A B C) where C is t | 10108 | ;; Specifically it is nil, or a three element list (A B C) where C is t |
| 10105 | ;; when context is '<> and the "identifier" is a found type, B is t when a | 10109 | ;; when context is '<> and the "identifier" is a found type, B is the |
| 10106 | ;; `c-typedef-kwds' ("typedef") is present, and A is t when some other | 10110 | ;; position of the `c-typedef-kwds' keyword ("typedef") when such is |
| 10107 | ;; `c-typedef-decl-kwds' (e.g. class, struct, enum) specifier is present. | 10111 | ;; present, and A is t when some other `c-typedef-decl-kwds' (e.g. class, |
| 10108 | ;; I.e., (some of) the declared identifier(s) are types. | 10112 | ;; struct, enum) specifier is present. I.e., (some of) the declared |
| 10113 | ;; identifier(s) are types. | ||
| 10109 | ;; | 10114 | ;; |
| 10110 | ;; The third element of the return value is non-nil when the declaration | 10115 | ;; The third element of the return value is non-nil when the declaration |
| 10111 | ;; parsed might be an expression. The fourth element is the position of | 10116 | ;; parsed might be an expression. The fourth element is the position of |
| @@ -10173,6 +10178,9 @@ This function might do hidden buffer changes." | |||
| 10173 | ;; `c-decl-hangon-kwds' and their associated clauses that | 10178 | ;; `c-decl-hangon-kwds' and their associated clauses that |
| 10174 | ;; occurs after the type. | 10179 | ;; occurs after the type. |
| 10175 | id-start | 10180 | id-start |
| 10181 | ;; The earlier value of `type-start' if we've shifted the type | ||
| 10182 | ;; backwards. | ||
| 10183 | identifier-start | ||
| 10176 | ;; These store `at-type', `type-start' and `id-start' of the | 10184 | ;; These store `at-type', `type-start' and `id-start' of the |
| 10177 | ;; identifier before the one in those variables. The previous | 10185 | ;; identifier before the one in those variables. The previous |
| 10178 | ;; identifier might turn out to be the real type in a | 10186 | ;; identifier might turn out to be the real type in a |
| @@ -10183,7 +10191,8 @@ This function might do hidden buffer changes." | |||
| 10183 | ;; Set if we've found a specifier (apart from "typedef") that makes | 10191 | ;; Set if we've found a specifier (apart from "typedef") that makes |
| 10184 | ;; the defined identifier(s) types. | 10192 | ;; the defined identifier(s) types. |
| 10185 | at-type-decl | 10193 | at-type-decl |
| 10186 | ;; Set if we've a "typedef" keyword. | 10194 | ;; If we've a "typedef" keyword (?or similar), the buffer position of |
| 10195 | ;; its first character. | ||
| 10187 | at-typedef | 10196 | at-typedef |
| 10188 | ;; Set if `context' is '<> and the identifier is definitely a type, or | 10197 | ;; Set if `context' is '<> and the identifier is definitely a type, or |
| 10189 | ;; has already been recorded as a found type. | 10198 | ;; has already been recorded as a found type. |
| @@ -10266,7 +10275,7 @@ This function might do hidden buffer changes." | |||
| 10266 | (looking-at "@[A-Za-z0-9]+"))) | 10275 | (looking-at "@[A-Za-z0-9]+"))) |
| 10267 | (save-match-data | 10276 | (save-match-data |
| 10268 | (if (looking-at c-typedef-key) | 10277 | (if (looking-at c-typedef-key) |
| 10269 | (setq at-typedef t))) | 10278 | (setq at-typedef (point)))) |
| 10270 | (setq kwd-sym (c-keyword-sym (match-string 1))) | 10279 | (setq kwd-sym (c-keyword-sym (match-string 1))) |
| 10271 | (save-excursion | 10280 | (save-excursion |
| 10272 | (c-forward-keyword-clause 1) | 10281 | (c-forward-keyword-clause 1) |
| @@ -10486,9 +10495,9 @@ This function might do hidden buffer changes." | |||
| 10486 | ;; True if we've parsed the type decl to a token that is | 10495 | ;; True if we've parsed the type decl to a token that is |
| 10487 | ;; known to end declarations in this context. | 10496 | ;; known to end declarations in this context. |
| 10488 | at-decl-end | 10497 | at-decl-end |
| 10489 | ;; The earlier values of `at-type' and `type-start' if we've | 10498 | ;; The earlier value of `at-type' if we've shifted the type |
| 10490 | ;; shifted the type backwards. | 10499 | ;; backwards. |
| 10491 | identifier-type identifier-start | 10500 | identifier-type |
| 10492 | ;; If `c-parse-and-markup-<>-arglists' is set we need to | 10501 | ;; If `c-parse-and-markup-<>-arglists' is set we need to |
| 10493 | ;; turn it off during the name skipping below to avoid | 10502 | ;; turn it off during the name skipping below to avoid |
| 10494 | ;; getting `c-type' properties that might be bogus. That | 10503 | ;; getting `c-type' properties that might be bogus. That |
| @@ -10530,6 +10539,10 @@ This function might do hidden buffer changes." | |||
| 10530 | (progn (setq got-identifier nil) t) | 10539 | (progn (setq got-identifier nil) t) |
| 10531 | ;; It turned out to be the real identifier, | 10540 | ;; It turned out to be the real identifier, |
| 10532 | ;; so stop. | 10541 | ;; so stop. |
| 10542 | (save-excursion | ||
| 10543 | (c-backward-syntactic-ws) | ||
| 10544 | (c-simple-skip-symbol-backward) | ||
| 10545 | (setq identifier-start (point))) | ||
| 10533 | nil)) | 10546 | nil)) |
| 10534 | t)) | 10547 | t)) |
| 10535 | 10548 | ||
| @@ -10555,6 +10568,10 @@ This function might do hidden buffer changes." | |||
| 10555 | (and (looking-at c-identifier-start) | 10568 | (and (looking-at c-identifier-start) |
| 10556 | (setq pos (point)) | 10569 | (setq pos (point)) |
| 10557 | (setq got-identifier (c-forward-name)) | 10570 | (setq got-identifier (c-forward-name)) |
| 10571 | (save-excursion | ||
| 10572 | (c-backward-syntactic-ws) | ||
| 10573 | (c-simple-skip-symbol-backward) | ||
| 10574 | (setq identifier-start (point))) | ||
| 10558 | (setq name-start pos)) | 10575 | (setq name-start pos)) |
| 10559 | (when (looking-at "[0-9]") | 10576 | (when (looking-at "[0-9]") |
| 10560 | (setq got-number t)) ; We probably have an arithmetic expression. | 10577 | (setq got-number t)) ; We probably have an arithmetic expression. |
| @@ -10573,7 +10590,8 @@ This function might do hidden buffer changes." | |||
| 10573 | (setq at-type nil | 10590 | (setq at-type nil |
| 10574 | name-start type-start | 10591 | name-start type-start |
| 10575 | id-start type-start | 10592 | id-start type-start |
| 10576 | got-identifier t))) | 10593 | got-identifier t) |
| 10594 | (setq identifier-start type-start))) | ||
| 10577 | 10595 | ||
| 10578 | ;; Skip over type decl suffix operators and trailing noise macros. | 10596 | ;; Skip over type decl suffix operators and trailing noise macros. |
| 10579 | (while | 10597 | (while |
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 4dcc3e0ade9..c220d8d8789 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el | |||
| @@ -85,6 +85,8 @@ | |||
| 85 | 85 | ||
| 86 | (cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only. | 86 | (cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only. |
| 87 | 87 | ||
| 88 | (declare-function cl-set-difference "cl-seq" (cl-list1 cl-list2 &rest cl-keys)) | ||
| 89 | |||
| 88 | ;; Need to declare these local symbols during compilation since | 90 | ;; Need to declare these local symbols during compilation since |
| 89 | ;; they're referenced from lambdas in `byte-compile' calls that are | 91 | ;; they're referenced from lambdas in `byte-compile' calls that are |
| 90 | ;; executed at compile time. They don't need to have the proper | 92 | ;; executed at compile time. They don't need to have the proper |
| @@ -1109,10 +1111,12 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1109 | ;; additionally, mark the commas with c-type property 'c-decl-id-start or | 1111 | ;; additionally, mark the commas with c-type property 'c-decl-id-start or |
| 1110 | ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. | 1112 | ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. |
| 1111 | ;; | 1113 | ;; |
| 1112 | ;; If TYPES is t, fontify all identifiers as types, if it is nil fontify as | 1114 | ;; If TYPES is t, fontify all identifiers as types; if it is a number, a |
| 1113 | ;; either variables or functions, otherwise TYPES is a face to use. If | 1115 | ;; buffer position, additionally set the `c-deftype' text property on the |
| 1114 | ;; NOT-TOP is non-nil, we are not at the top-level ("top-level" includes | 1116 | ;; keyword at that position; if it is nil fontify as either variables or |
| 1115 | ;; being directly inside a class or namespace, etc.). | 1117 | ;; functions, otherwise TYPES is a face to use. If NOT-TOP is non-nil, we |
| 1118 | ;; are not at the top-level ("top-level" includes being directly inside a | ||
| 1119 | ;; class or namespace, etc.). | ||
| 1116 | ;; | 1120 | ;; |
| 1117 | ;; TEMPLATE-CLASS is non-nil when the declaration is in template delimiters | 1121 | ;; TEMPLATE-CLASS is non-nil when the declaration is in template delimiters |
| 1118 | ;; and was introduced by, e.g. "typename" or "class", such that if there is | 1122 | ;; and was introduced by, e.g. "typename" or "class", such that if there is |
| @@ -1129,17 +1133,28 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1129 | ;;(message "c-font-lock-declarators from %s to %s" (point) limit) | 1133 | ;;(message "c-font-lock-declarators from %s to %s" (point) limit) |
| 1130 | (c-fontify-types-and-refs | 1134 | (c-fontify-types-and-refs |
| 1131 | () | 1135 | () |
| 1136 | ;; If we're altering the declarators in a typedef, we need to scan ALL of | ||
| 1137 | ;; them because of the way we check for changes. | ||
| 1138 | (let ((c-do-decl-limit (if (numberp types) (point-max) limit)) | ||
| 1139 | decl-ids) | ||
| 1132 | (c-do-declarators | 1140 | (c-do-declarators |
| 1133 | limit list not-top | 1141 | c-do-decl-limit |
| 1134 | (cond ((eq types t) 'c-decl-type-start) | 1142 | list not-top |
| 1143 | (cond ((or (numberp types) | ||
| 1144 | (eq types t)) | ||
| 1145 | 'c-decl-type-start) | ||
| 1135 | ((null types) 'c-decl-id-start)) | 1146 | ((null types) 'c-decl-id-start)) |
| 1136 | (lambda (id-start id-end end-pos _not-top is-function init-char) | 1147 | (lambda (id-start id-end end-pos _not-top is-function init-char) |
| 1137 | (if (eq types t) | 1148 | (if (or (numberp types) |
| 1149 | (eq types t)) | ||
| 1138 | (when id-start | 1150 | (when id-start |
| 1139 | ;; Register and fontify the identifier as a type. | 1151 | ;; Register and fontify the identifier as a type. |
| 1140 | (let ((c-promote-possible-types t)) | 1152 | (let ((c-promote-possible-types t)) |
| 1141 | (goto-char id-start) | 1153 | (goto-char id-start) |
| 1142 | (c-forward-type))) | 1154 | (c-forward-type)) |
| 1155 | (when (numberp types) | ||
| 1156 | (push (buffer-substring-no-properties id-start id-end) | ||
| 1157 | decl-ids))) | ||
| 1143 | (when id-start | 1158 | (when id-start |
| 1144 | (goto-char id-start) | 1159 | (goto-char id-start) |
| 1145 | (when c-opt-identifier-prefix-key | 1160 | (when c-opt-identifier-prefix-key |
| @@ -1147,7 +1162,7 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1147 | (eq (match-end 1) id-end)) | 1162 | (eq (match-end 1) id-end)) |
| 1148 | (while (and (< (point) id-end) | 1163 | (while (and (< (point) id-end) |
| 1149 | (re-search-forward c-opt-identifier-prefix-key id-end t)) | 1164 | (re-search-forward c-opt-identifier-prefix-key id-end t)) |
| 1150 | (c-forward-syntactic-ws limit)))) | 1165 | (c-forward-syntactic-ws c-do-decl-limit)))) |
| 1151 | ;; Only apply the face when the text doesn't have one yet. | 1166 | ;; Only apply the face when the text doesn't have one yet. |
| 1152 | ;; Exception: The "" in C++'s operator"" will already wrongly have | 1167 | ;; Exception: The "" in C++'s operator"" will already wrongly have |
| 1153 | ;; string face. | 1168 | ;; string face. |
| @@ -1164,7 +1179,7 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1164 | (equal (buffer-substring-no-properties id-start id-end) | 1179 | (equal (buffer-substring-no-properties id-start id-end) |
| 1165 | "\"\"")) | 1180 | "\"\"")) |
| 1166 | (goto-char id-end) | 1181 | (goto-char id-end) |
| 1167 | (c-forward-syntactic-ws limit) | 1182 | (c-forward-syntactic-ws c-do-decl-limit) |
| 1168 | (when (c-on-identifier) | 1183 | (when (c-on-identifier) |
| 1169 | (c-put-font-lock-face | 1184 | (c-put-font-lock-face |
| 1170 | (point) | 1185 | (point) |
| @@ -1174,10 +1189,21 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1174 | (eq init-char ?=) ; C++ "<class X = Y>"? | 1189 | (eq init-char ?=) ; C++ "<class X = Y>"? |
| 1175 | (progn | 1190 | (progn |
| 1176 | (goto-char end-pos) | 1191 | (goto-char end-pos) |
| 1177 | (c-forward-token-2 1 nil limit) ; Over "=" | 1192 | (c-forward-token-2 1 nil c-do-decl-limit) ; Over "=" |
| 1178 | (let ((c-promote-possible-types t)) | 1193 | (let ((c-promote-possible-types t)) |
| 1179 | (c-forward-type t))))) | 1194 | (c-forward-type t))))) |
| 1180 | accept-anon) ; Last argument to c-do-declarators. | 1195 | accept-anon) ; Last argument to c-do-declarators. |
| 1196 | ;; If we've changed types declared by a "typedef", update the `c-typedef' | ||
| 1197 | ;; text property. | ||
| 1198 | (when (numberp types) | ||
| 1199 | (let* ((old-decl-ids (c-get-char-property types 'c-typedef)) | ||
| 1200 | (old-types (c--set-difference old-decl-ids decl-ids :test #'equal)) | ||
| 1201 | (new-types (c--set-difference decl-ids old-decl-ids :test #'equal))) | ||
| 1202 | (dolist (type old-types) | ||
| 1203 | (c-unfind-type type)) | ||
| 1204 | ;; The new types have already been added to `c-found-types', as needed. | ||
| 1205 | (when (or old-types new-types) | ||
| 1206 | (c-put-char-property types 'c-typedef decl-ids))))) | ||
| 1181 | nil)) | 1207 | nil)) |
| 1182 | 1208 | ||
| 1183 | (defun c-get-fontification-context (match-pos not-front-decl &optional toplev) | 1209 | (defun c-get-fontification-context (match-pos not-front-decl &optional toplev) |
| @@ -1433,7 +1459,10 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1433 | (c-font-lock-declarators | 1459 | (c-font-lock-declarators |
| 1434 | (min limit (point-max)) | 1460 | (min limit (point-max)) |
| 1435 | decl-list | 1461 | decl-list |
| 1436 | (not (null (cadr decl-or-cast))) | 1462 | (cond ((null (cadr decl-or-cast)) |
| 1463 | nil) | ||
| 1464 | ((cadr (cadr decl-or-cast))) | ||
| 1465 | (t t)) | ||
| 1437 | (not toplev) | 1466 | (not toplev) |
| 1438 | template-class | 1467 | template-class |
| 1439 | (memq context '(decl <>)))) | 1468 | (memq context '(decl <>)))) |
| @@ -1749,12 +1778,21 @@ casts and declarations are fontified. Used on level 2 and higher." | |||
| 1749 | ; speeds up lisp.h tremendously. | 1778 | ; speeds up lisp.h tremendously. |
| 1750 | (save-excursion | 1779 | (save-excursion |
| 1751 | (when (not (c-back-over-member-initializers decl-search-lim)) | 1780 | (when (not (c-back-over-member-initializers decl-search-lim)) |
| 1781 | (setq paren-state (c-parse-state)) | ||
| 1752 | (unless (or (eobp) | 1782 | (unless (or (eobp) |
| 1753 | (looking-at "\\s(\\|\\s)")) | 1783 | (looking-at "\\s(\\|\\s)")) |
| 1754 | (forward-char)) | 1784 | (forward-char)) |
| 1755 | (c-syntactic-skip-backward "^;{}" decl-search-lim t) | 1785 | (c-syntactic-skip-backward "^;{}" decl-search-lim t) |
| 1756 | (when (eq (char-before) ?}) | 1786 | ;; Do we have the brace block of a struct, etc.? |
| 1757 | (c-go-list-backward) ; brace block of struct, etc.? | 1787 | (when (cond |
| 1788 | ((and (consp (car paren-state)) | ||
| 1789 | (eq (char-before) ?})) | ||
| 1790 | (goto-char (caar paren-state)) | ||
| 1791 | t) | ||
| 1792 | ((and (numberp (car paren-state)) | ||
| 1793 | (eq (char-after (car paren-state)) ?{)) | ||
| 1794 | (goto-char (car paren-state)) | ||
| 1795 | t)) | ||
| 1758 | (c-syntactic-skip-backward "^;{}" decl-search-lim t)) | 1796 | (c-syntactic-skip-backward "^;{}" decl-search-lim t)) |
| 1759 | (when (or (bobp) | 1797 | (when (or (bobp) |
| 1760 | (memq (char-before) '(?\; ?{ ?}))) | 1798 | (memq (char-before) '(?\; ?{ ?}))) |
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index b04ed7584c4..330202bb5f9 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -2077,6 +2077,37 @@ with // and /*, not more generic line and block comments." | |||
| 2077 | (not (eobp)))) | 2077 | (not (eobp)))) |
| 2078 | (forward-char)))))) | 2078 | (forward-char)))))) |
| 2079 | 2079 | ||
| 2080 | (defun c-before-change-de-typedef (beg end) | ||
| 2081 | ;; For each "typedef" starting in (BEG END), remove the defined types from | ||
| 2082 | ;; c-found-types | ||
| 2083 | (let (prop) | ||
| 2084 | (save-excursion | ||
| 2085 | (goto-char beg) | ||
| 2086 | (while (and (< (point) end) | ||
| 2087 | (setq prop (c-search-forward-non-nil-char-property | ||
| 2088 | 'c-typedef))) | ||
| 2089 | (dolist (type prop) | ||
| 2090 | (c-unfind-type type)))))) | ||
| 2091 | |||
| 2092 | (defun c-after-change-de-typedef (beg end _old-len) | ||
| 2093 | ;; For each former "typedef" in (BEG END), remove the defined types from | ||
| 2094 | ;; those which are no longer typedefs. | ||
| 2095 | (let (prop) | ||
| 2096 | (save-excursion | ||
| 2097 | (goto-char beg) | ||
| 2098 | (c-backward-token-2 | ||
| 2099 | 1 nil (- (point) 20)) | ||
| 2100 | (while (and (< (point) end) | ||
| 2101 | (setq prop (c-search-forward-non-nil-char-property | ||
| 2102 | 'c-typedef end))) | ||
| 2103 | (backward-char) | ||
| 2104 | (when (or (not (looking-at c-typedef-key)) | ||
| 2105 | (<= (match-end 1) beg)) | ||
| 2106 | (dolist (type prop) | ||
| 2107 | (c-unfind-type type)) | ||
| 2108 | (c-clear-char-property (point) 'c-typedef)) | ||
| 2109 | (forward-char))))) | ||
| 2110 | |||
| 2080 | (defun c-update-new-id (end) | 2111 | (defun c-update-new-id (end) |
| 2081 | ;; Note the bounds of any identifier that END is in or just after, in | 2112 | ;; Note the bounds of any identifier that END is in or just after, in |
| 2082 | ;; `c-new-id-start' and `c-new-id-end'. Otherwise set these variables to | 2113 | ;; `c-new-id-start' and `c-new-id-end'. Otherwise set these variables to |
| @@ -2086,7 +2117,9 @@ with // and /*, not more generic line and block comments." | |||
| 2086 | (let ((id-beg (c-on-identifier))) | 2117 | (let ((id-beg (c-on-identifier))) |
| 2087 | (setq c-new-id-start id-beg | 2118 | (setq c-new-id-start id-beg |
| 2088 | c-new-id-end (and id-beg | 2119 | c-new-id-end (and id-beg |
| 2089 | (progn (c-end-of-current-token) (point))) | 2120 | (progn (goto-char id-beg) |
| 2121 | (c-forward-token-2) | ||
| 2122 | (point))) | ||
| 2090 | c-new-id-is-type nil)))) | 2123 | c-new-id-is-type nil)))) |
| 2091 | 2124 | ||
| 2092 | (defun c-post-command () | 2125 | (defun c-post-command () |
| @@ -2215,6 +2248,10 @@ with // and /*, not more generic line and block comments." | |||
| 2215 | term-pos) | 2248 | term-pos) |
| 2216 | (buffer-substring-no-properties beg end))))))) | 2249 | (buffer-substring-no-properties beg end))))))) |
| 2217 | 2250 | ||
| 2251 | ;; If we're about to delete "typedef"s, clear the identifiers from | ||
| 2252 | ;; `c-found-types'. | ||
| 2253 | (c-before-change-de-typedef beg end) | ||
| 2254 | |||
| 2218 | (if c-get-state-before-change-functions | 2255 | (if c-get-state-before-change-functions |
| 2219 | (mapc (lambda (fn) | 2256 | (mapc (lambda (fn) |
| 2220 | (funcall fn beg end)) | 2257 | (funcall fn beg end)) |
| @@ -2306,6 +2343,7 @@ with // and /*, not more generic line and block comments." | |||
| 2306 | (c-update-new-id end) | 2343 | (c-update-new-id end) |
| 2307 | (c-trim-found-types beg end old-len) ; maybe we don't | 2344 | (c-trim-found-types beg end old-len) ; maybe we don't |
| 2308 | ; need all of these. | 2345 | ; need all of these. |
| 2346 | (c-after-change-de-typedef beg end old-len) | ||
| 2309 | (c-invalidate-sws-region-after beg end old-len) | 2347 | (c-invalidate-sws-region-after beg end old-len) |
| 2310 | ;; (c-invalidate-state-cache beg) ; moved to | 2348 | ;; (c-invalidate-state-cache beg) ; moved to |
| 2311 | ;; `c-before-change'. | 2349 | ;; `c-before-change'. |
diff --git a/lisp/progmodes/ruby-ts-mode.el b/lisp/progmodes/ruby-ts-mode.el index 939c054b041..f075824591d 100644 --- a/lisp/progmodes/ruby-ts-mode.el +++ b/lisp/progmodes/ruby-ts-mode.el | |||
| @@ -152,7 +152,6 @@ | |||
| 152 | "then" | 152 | "then" |
| 153 | "ensure" | 153 | "ensure" |
| 154 | "body_statement" | 154 | "body_statement" |
| 155 | "parenthesized_statements" | ||
| 156 | "interpolation") | 155 | "interpolation") |
| 157 | string-end) | 156 | string-end) |
| 158 | "Regular expression of the nodes that can contain statements.") | 157 | "Regular expression of the nodes that can contain statements.") |
| @@ -221,9 +220,9 @@ values of OVERRIDE" | |||
| 221 | 220 | ||
| 222 | :language language | 221 | :language language |
| 223 | :feature 'constant | 222 | :feature 'constant |
| 224 | '((true) @font-lock-doc-markup-face | 223 | '((true) @font-lock-constant-face |
| 225 | (false) @font-lock-doc-markup-face | 224 | (false) @font-lock-constant-face |
| 226 | (nil) @font-lock-doc-markup-face) | 225 | (nil) @font-lock-constant-face) |
| 227 | 226 | ||
| 228 | ;; Before 'operator so (unary) works. | 227 | ;; Before 'operator so (unary) works. |
| 229 | :language language | 228 | :language language |
| @@ -512,10 +511,6 @@ array or hash." | |||
| 512 | (first-child (ruby-ts--first-non-comment-child parent))) | 511 | (first-child (ruby-ts--first-non-comment-child parent))) |
| 513 | (= (ruby-ts--lineno open-brace) (ruby-ts--lineno first-child)))) | 512 | (= (ruby-ts--lineno open-brace) (ruby-ts--lineno first-child)))) |
| 514 | 513 | ||
| 515 | (defun ruby-ts--assignment-ancestor (node &rest _) | ||
| 516 | "Return the assignment ancestor of NODE if any." | ||
| 517 | (treesit-parent-until node (ruby-ts--type-pred "\\`assignment\\'"))) | ||
| 518 | |||
| 519 | (defun ruby-ts--statement-ancestor (node &rest _) | 514 | (defun ruby-ts--statement-ancestor (node &rest _) |
| 520 | "Return the statement ancestor of NODE if any. | 515 | "Return the statement ancestor of NODE if any. |
| 521 | A statement is defined as a child of a statement container where | 516 | A statement is defined as a child of a statement container where |
| @@ -531,26 +526,6 @@ a statement container is a node that matches | |||
| 531 | parent (treesit-node-parent parent))) | 526 | parent (treesit-node-parent parent))) |
| 532 | statement)) | 527 | statement)) |
| 533 | 528 | ||
| 534 | (defun ruby-ts--is-in-condition (node &rest _) | ||
| 535 | "Return the condition node if NODE is within a condition." | ||
| 536 | (while (and node | ||
| 537 | (not (equal "condition" (treesit-node-field-name node))) | ||
| 538 | (not (string-match-p ruby-ts--statement-container-regexp | ||
| 539 | (treesit-node-type node)))) | ||
| 540 | (setq node (treesit-node-parent node))) | ||
| 541 | (and (equal "condition" (treesit-node-field-name node)) node)) | ||
| 542 | |||
| 543 | (defun ruby-ts--endless-method (node &rest _) | ||
| 544 | "Return the expression node if NODE is in an endless method. | ||
| 545 | i.e. expr of def foo(args) = expr is returned." | ||
| 546 | (let* ((method node)) | ||
| 547 | (while (and method | ||
| 548 | (not (string-match-p ruby-ts--method-regex (treesit-node-type method)))) | ||
| 549 | (setq method (treesit-node-parent method))) | ||
| 550 | (when method | ||
| 551 | (if (equal "=" (treesit-node-type (treesit-node-child method 3 nil))) | ||
| 552 | (treesit-node-child method 4 nil))))) | ||
| 553 | |||
| 554 | ;; | 529 | ;; |
| 555 | ;; end of functions that can be used for queries | 530 | ;; end of functions that can be used for queries |
| 556 | ;; | 531 | ;; |
| @@ -587,11 +562,11 @@ i.e. expr of def foo(args) = expr is returned." | |||
| 587 | ;; | 562 | ;; |
| 588 | ;; I'm using very restrictive patterns hoping to reduce rules | 563 | ;; I'm using very restrictive patterns hoping to reduce rules |
| 589 | ;; triggering unintentionally. | 564 | ;; triggering unintentionally. |
| 590 | ((match "else" "if") | 565 | ((match "else" "if\\|unless") |
| 591 | (ruby-ts--align-keywords ruby-ts--parent-node) 0) | 566 | (ruby-ts--align-keywords ruby-ts--parent-node) 0) |
| 592 | ((match "elsif" "if") | 567 | ((match "elsif" "if") |
| 593 | (ruby-ts--align-keywords ruby-ts--parent-node) 0) | 568 | (ruby-ts--align-keywords ruby-ts--parent-node) 0) |
| 594 | ((match "end" "if") | 569 | ((match "end" "if\\|unless") |
| 595 | (ruby-ts--align-keywords ruby-ts--parent-node) 0) | 570 | (ruby-ts--align-keywords ruby-ts--parent-node) 0) |
| 596 | ((n-p-gp nil "then\\|else\\|elsif" "if\\|unless") | 571 | ((n-p-gp nil "then\\|else\\|elsif" "if\\|unless") |
| 597 | (ruby-ts--align-keywords ruby-ts--grand-parent-node) ruby-indent-level) | 572 | (ruby-ts--align-keywords ruby-ts--grand-parent-node) ruby-indent-level) |
| @@ -664,6 +639,13 @@ i.e. expr of def foo(args) = expr is returned." | |||
| 664 | ;; else the second query aligns | 639 | ;; else the second query aligns |
| 665 | ;; `ruby-indent-level' spaces in from the parent. | 640 | ;; `ruby-indent-level' spaces in from the parent. |
| 666 | ((and ruby-ts--align-chain-p (match "\\." "call")) ruby-ts--align-chain 0) | 641 | ((and ruby-ts--align-chain-p (match "\\." "call")) ruby-ts--align-chain 0) |
| 642 | ;; Obery ruby-method-call-indent, whether the dot is on | ||
| 643 | ;; this line or the previous line. | ||
| 644 | ((and (not ruby-ts--method-call-indent-p) | ||
| 645 | (or | ||
| 646 | (match "\\." "call") | ||
| 647 | (query "(call \".\" (identifier) @indent)"))) | ||
| 648 | parent 0) | ||
| 667 | ((match "\\." "call") parent ruby-indent-level) | 649 | ((match "\\." "call") parent ruby-indent-level) |
| 668 | 650 | ||
| 669 | ;; ruby-indent-after-block-in-continued-expression | 651 | ;; ruby-indent-after-block-in-continued-expression |
| @@ -697,23 +679,27 @@ i.e. expr of def foo(args) = expr is returned." | |||
| 697 | ;; 2) With paren, 1st arg on next line | 679 | ;; 2) With paren, 1st arg on next line |
| 698 | ((and (query "(argument_list \"(\" _ @indent)") | 680 | ((and (query "(argument_list \"(\" _ @indent)") |
| 699 | (node-is ")")) | 681 | (node-is ")")) |
| 700 | (ruby-ts--bol ruby-ts--grand-parent-node) 0) | 682 | ruby-ts--parent-call-or-bol 0) |
| 701 | ((query "(argument_list \"(\" _ @indent)") | 683 | ((query "(argument_list \"(\" _ @indent)") |
| 702 | (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level) | 684 | ruby-ts--parent-call-or-bol ruby-indent-level) |
| 703 | ;; 3) No paren, ruby-parenless-call-arguments-indent is t | 685 | ;; 3) No paren, ruby-parenless-call-arguments-indent is t |
| 704 | ((and ruby-ts--parenless-call-arguments-indent-p (parent-is "argument_list")) | 686 | ((and ruby-ts--parenless-call-arguments-indent-p (parent-is "argument_list")) |
| 705 | first-sibling 0) | 687 | first-sibling 0) |
| 706 | ;; 4) No paren, ruby-parenless-call-arguments-indent is nil | 688 | ;; 4) No paren, ruby-parenless-call-arguments-indent is nil |
| 707 | ((parent-is "argument_list") (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level) | 689 | ((parent-is "argument_list") |
| 690 | (ruby-ts--bol ruby-ts--statement-ancestor) ruby-indent-level) | ||
| 708 | 691 | ||
| 709 | ;; Old... probably too simple | 692 | ;; Old... probably too simple |
| 710 | ((parent-is "block_parameters") first-sibling 1) | 693 | ((parent-is "block_parameters") first-sibling 1) |
| 711 | 694 | ||
| 712 | ((and (parent-is "binary") | 695 | ((and (not ruby-ts--after-op-indent-p) |
| 713 | (or ruby-ts--assignment-ancestor | 696 | (parent-is "binary\\|conditional")) |
| 714 | ruby-ts--is-in-condition | 697 | (ruby-ts--bol ruby-ts--statement-ancestor) ruby-indent-level) |
| 715 | ruby-ts--endless-method)) | 698 | |
| 716 | first-sibling 0) | 699 | ((parent-is "binary") |
| 700 | ruby-ts--binary-indent-anchor 0) | ||
| 701 | |||
| 702 | ((parent-is "conditional") parent ruby-indent-level) | ||
| 717 | 703 | ||
| 718 | ;; ruby-mode does not touch these... | 704 | ;; ruby-mode does not touch these... |
| 719 | ((match "bare_string" "string_array") no-indent 0) | 705 | ((match "bare_string" "string_array") no-indent 0) |
| @@ -732,37 +718,15 @@ i.e. expr of def foo(args) = expr is returned." | |||
| 732 | ((and ruby-ts--same-line-hash-array-p (parent-is "array")) | 718 | ((and ruby-ts--same-line-hash-array-p (parent-is "array")) |
| 733 | (nth-sibling 0 ruby-ts--true) 0) | 719 | (nth-sibling 0 ruby-ts--true) 0) |
| 734 | 720 | ||
| 735 | ;; NOTE to folks trying to understand my insanity... | 721 | ((match "}" "hash") ruby-ts--parent-call-or-bol 0) |
| 736 | ;; I having trouble understanding the "logic" of why things | 722 | ((parent-is "hash") ruby-ts--parent-call-or-bol ruby-indent-level) |
| 737 | ;; are indented like they are so I am adding special cases | 723 | ((match "]" "array") ruby-ts--parent-call-or-bol 0) |
| 738 | ;; hoping at some point I will be struck by lightning. | 724 | ((parent-is "array") ruby-ts--parent-call-or-bol ruby-indent-level) |
| 739 | ((and (n-p-gp "}" "hash" "pair") | 725 | |
| 740 | (not ruby-ts--same-line-hash-array-p)) | 726 | ((parent-is "pair") ruby-ts--parent-call-or-bol 0) |
| 741 | grand-parent 0) | 727 | |
| 742 | ((and (n-p-gp "pair" "hash" "pair") | 728 | ((match ")" "parenthesized_statements") parent-bol 0) |
| 743 | (not ruby-ts--same-line-hash-array-p)) | 729 | ((parent-is "parenthesized_statements") parent-bol ruby-indent-level) |
| 744 | grand-parent ruby-indent-level) | ||
| 745 | ((and (n-p-gp "}" "hash" "method") | ||
| 746 | (not ruby-ts--same-line-hash-array-p)) | ||
| 747 | grand-parent 0) | ||
| 748 | ((and (n-p-gp "pair" "hash" "method") | ||
| 749 | (not ruby-ts--same-line-hash-array-p)) | ||
| 750 | grand-parent ruby-indent-level) | ||
| 751 | |||
| 752 | ((n-p-gp "}" "hash" "assignment") (ruby-ts--bol ruby-ts--grand-parent-node) 0) | ||
| 753 | ((n-p-gp nil "hash" "assignment") (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level) | ||
| 754 | ((n-p-gp "]" "array" "assignment") (ruby-ts--bol ruby-ts--grand-parent-node) 0) | ||
| 755 | ((n-p-gp nil "array" "assignment") (ruby-ts--bol ruby-ts--grand-parent-node) ruby-indent-level) | ||
| 756 | |||
| 757 | ((n-p-gp "}" "hash" "argument_list") first-sibling 0) | ||
| 758 | ((n-p-gp nil "hash" "argument_list") first-sibling ruby-indent-level) | ||
| 759 | ((n-p-gp "]" "array" "argument_list") first-sibling 0) | ||
| 760 | ((n-p-gp nil "array" "argument_list") first-sibling ruby-indent-level) | ||
| 761 | |||
| 762 | ((match "}" "hash") first-sibling 0) | ||
| 763 | ((parent-is "hash") first-sibling ruby-indent-level) | ||
| 764 | ((match "]" "array") first-sibling 0) | ||
| 765 | ((parent-is "array") first-sibling ruby-indent-level) | ||
| 766 | 730 | ||
| 767 | ;; If the previous method isn't finished yet, this will get | 731 | ;; If the previous method isn't finished yet, this will get |
| 768 | ;; the next method indented properly. | 732 | ;; the next method indented properly. |
| @@ -814,6 +778,66 @@ i.e. expr of def foo(args) = expr is returned." | |||
| 814 | (back-to-indentation) | 778 | (back-to-indentation) |
| 815 | (point))))) | 779 | (point))))) |
| 816 | 780 | ||
| 781 | (defun ruby-ts--binary-indent-anchor (_node parent _bol &rest _) | ||
| 782 | (save-excursion | ||
| 783 | (goto-char (treesit-node-start parent)) | ||
| 784 | (when (string-match-p ruby-ts--statement-container-regexp | ||
| 785 | (treesit-node-type (treesit-node-parent parent))) | ||
| 786 | ;; Hack alert: it's not the proper place to alter the offset. | ||
| 787 | ;; Redoing the analysis in the OFFSET form seems annoying, | ||
| 788 | ;; though. (**) | ||
| 789 | (forward-char ruby-indent-level)) | ||
| 790 | (point))) | ||
| 791 | |||
| 792 | (defun ruby-ts--parent-call-or-bol (_not parent _bol &rest _) | ||
| 793 | (let* ((parent-bol (save-excursion | ||
| 794 | (goto-char (treesit-node-start parent)) | ||
| 795 | (back-to-indentation) | ||
| 796 | (point))) | ||
| 797 | (found | ||
| 798 | (treesit-parent-until | ||
| 799 | parent | ||
| 800 | (lambda (node) | ||
| 801 | (or (< (treesit-node-start node) parent-bol) | ||
| 802 | (string-match-p "\\`array\\|hash\\'" (treesit-node-type node)) | ||
| 803 | ;; Method call on same line. | ||
| 804 | (equal (treesit-node-type node) "argument_list")))))) | ||
| 805 | (cond | ||
| 806 | ((null found) | ||
| 807 | parent-bol) | ||
| 808 | ;; No paren/curly/brace found on the same line. | ||
| 809 | ((< (treesit-node-start found) parent-bol) | ||
| 810 | parent-bol) | ||
| 811 | ;; Hash or array opener on the same line. | ||
| 812 | ((string-match-p "\\`array\\|hash\\'" (treesit-node-type found)) | ||
| 813 | (save-excursion | ||
| 814 | (goto-char (treesit-node-start (treesit-node-child found 1))) | ||
| 815 | (point))) | ||
| 816 | ;; Parenless call found: indent to stmt with offset. | ||
| 817 | ((not ruby-parenless-call-arguments-indent) | ||
| 818 | (save-excursion | ||
| 819 | (goto-char (treesit-node-start | ||
| 820 | (ruby-ts--statement-ancestor found))) | ||
| 821 | ;; (**) Same. | ||
| 822 | (+ (point) ruby-indent-level))) | ||
| 823 | ;; Call with parens -- ident to first arg. | ||
| 824 | ((equal (treesit-node-type (treesit-node-child found 0)) | ||
| 825 | "(") | ||
| 826 | (save-excursion | ||
| 827 | (goto-char (treesit-node-start (treesit-node-child found 1))) | ||
| 828 | (point))) | ||
| 829 | ;; Indent to the parenless call args beginning. | ||
| 830 | (t | ||
| 831 | (save-excursion | ||
| 832 | (goto-char (treesit-node-start found)) | ||
| 833 | (point)))))) | ||
| 834 | |||
| 835 | (defun ruby-ts--after-op-indent-p (&rest _) | ||
| 836 | ruby-after-operator-indent) | ||
| 837 | |||
| 838 | (defun ruby-ts--method-call-indent-p (&rest _) | ||
| 839 | ruby-method-call-indent) | ||
| 840 | |||
| 817 | (defun ruby-ts--class-or-module-p (node) | 841 | (defun ruby-ts--class-or-module-p (node) |
| 818 | "Predicate if NODE is a class or module." | 842 | "Predicate if NODE is a class or module." |
| 819 | (string-match-p ruby-ts--class-or-module-regex (treesit-node-type node))) | 843 | (string-match-p ruby-ts--class-or-module-regex (treesit-node-type node))) |
diff --git a/lisp/replace.el b/lisp/replace.el index 2f063bbf66b..3c2b925ea92 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -824,11 +824,11 @@ by this function to the end of values available via | |||
| 824 | 824 | ||
| 825 | (defvar-keymap read-regexp-map | 825 | (defvar-keymap read-regexp-map |
| 826 | :parent minibuffer-local-map | 826 | :parent minibuffer-local-map |
| 827 | "M-c" #'read-regexp-toggle-case-folding) | 827 | "M-s c" #'read-regexp-toggle-case-fold) |
| 828 | 828 | ||
| 829 | (defvar read-regexp--case-fold nil) | 829 | (defvar read-regexp--case-fold nil) |
| 830 | 830 | ||
| 831 | (defun read-regexp-toggle-case-folding () | 831 | (defun read-regexp-toggle-case-fold () |
| 832 | (interactive) | 832 | (interactive) |
| 833 | (setq read-regexp--case-fold | 833 | (setq read-regexp--case-fold |
| 834 | (if (or (eq read-regexp--case-fold 'fold) | 834 | (if (or (eq read-regexp--case-fold 'fold) |
| @@ -875,7 +875,7 @@ in \":\", followed by optional whitespace), DEFAULT is added to the prompt. | |||
| 875 | The optional argument HISTORY is a symbol to use for the history list. | 875 | The optional argument HISTORY is a symbol to use for the history list. |
| 876 | If nil, use `regexp-history'. | 876 | If nil, use `regexp-history'. |
| 877 | 877 | ||
| 878 | If the user has used the \\<read-regexp-map>\\[read-regexp-toggle-case-folding] command to specify case | 878 | If the user has used the \\<read-regexp-map>\\[read-regexp-toggle-case-fold] command to specify case |
| 879 | sensitivity, the returned string will have a text property named | 879 | sensitivity, the returned string will have a text property named |
| 880 | `case-fold' that has a value of either `fold' or | 880 | `case-fold' that has a value of either `fold' or |
| 881 | `inhibit-fold'. (It's up to the caller of `read-regexp' to | 881 | `inhibit-fold'. (It's up to the caller of `read-regexp' to |
diff --git a/lisp/treesit.el b/lisp/treesit.el index 69bfff21df3..e8571d43db3 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el | |||
| @@ -905,6 +905,14 @@ This is not a general optimization and should be RARELY needed! | |||
| 905 | See comments in `treesit-font-lock-fontify-region' for more | 905 | See comments in `treesit-font-lock-fontify-region' for more |
| 906 | detail.") | 906 | detail.") |
| 907 | 907 | ||
| 908 | (defvar-local treesit--font-lock-fast-mode-grace-count 5 | ||
| 909 | "Grace counts before we turn on the fast mode. | ||
| 910 | |||
| 911 | When query takes abnormally long time to execute, we turn on the | ||
| 912 | \"fast mode\", but just to be on the safe side, we only turn on | ||
| 913 | the fast mode after this number of offenses. See bug#60691, | ||
| 914 | bug#60223.") | ||
| 915 | |||
| 908 | ;; Some details worth explaining: | 916 | ;; Some details worth explaining: |
| 909 | ;; | 917 | ;; |
| 910 | ;; 1. When we apply face to a node, we clip the face into the | 918 | ;; 1. When we apply face to a node, we clip the face into the |
| @@ -927,13 +935,13 @@ detail.") | |||
| 927 | ;; parse it into a enormously tall tree (10k levels tall). In that | 935 | ;; parse it into a enormously tall tree (10k levels tall). In that |
| 928 | ;; case querying the root node is very slow. So we try to get | 936 | ;; case querying the root node is very slow. So we try to get |
| 929 | ;; top-level nodes and query them. This ensures that querying is fast | 937 | ;; top-level nodes and query them. This ensures that querying is fast |
| 930 | ;; everywhere else, except for the problematic region. | 938 | ;; everywhere else, except for the problematic region. (Bug#59415). |
| 931 | ;; | 939 | ;; |
| 932 | ;; Some other time the source file has a top-level node that contains | 940 | ;; Some other time the source file has a top-level node that contains |
| 933 | ;; a huge number of children (say, 10k children), querying that node | 941 | ;; a huge number of immediate children (say, 10k children), querying |
| 934 | ;; is also very slow, so instead of getting the top-level node, we | 942 | ;; that node is also very slow, so instead of getting the top-level |
| 935 | ;; recursively go down the tree to find nodes that cover the region | 943 | ;; node, we recursively go down the tree to find nodes that cover the |
| 936 | ;; but are reasonably small. | 944 | ;; region but are reasonably small. (Bug#59738). |
| 937 | ;; | 945 | ;; |
| 938 | ;; 3. It is possible to capture a node that's completely outside the | 946 | ;; 3. It is possible to capture a node that's completely outside the |
| 939 | ;; region between START and END: as long as the whole pattern | 947 | ;; region between START and END: as long as the whole pattern |
| @@ -941,8 +949,8 @@ detail.") | |||
| 941 | ;; returned. If the node is outside of that region, (max node-start | 949 | ;; returned. If the node is outside of that region, (max node-start |
| 942 | ;; start) and friends return bad values, so we filter them out. | 950 | ;; start) and friends return bad values, so we filter them out. |
| 943 | ;; However, we don't filter these nodes out if a function will process | 951 | ;; However, we don't filter these nodes out if a function will process |
| 944 | ;; the node, because could (and often do) fontify the relatives of the | 952 | ;; the node, because it could (and often do) fontify the relatives of |
| 945 | ;; captured node, not just the node itself. If we took out those | 953 | ;; the captured node, not just the node itself. If we took out those |
| 946 | ;; nodes author of those functions would be very confused. | 954 | ;; nodes author of those functions would be very confused. |
| 947 | (defun treesit-font-lock-fontify-region (start end &optional loudly) | 955 | (defun treesit-font-lock-fontify-region (start end &optional loudly) |
| 948 | "Fontify the region between START and END. | 956 | "Fontify the region between START and END. |
| @@ -979,9 +987,12 @@ If LOUDLY is non-nil, display some debugging information." | |||
| 979 | (end-time (current-time))) | 987 | (end-time (current-time))) |
| 980 | ;; If for any query the query time is strangely long, | 988 | ;; If for any query the query time is strangely long, |
| 981 | ;; switch to fast mode (see comments above). | 989 | ;; switch to fast mode (see comments above). |
| 982 | (when (> (time-to-seconds (time-subtract end-time start-time)) | 990 | (when (and (> (time-to-seconds |
| 983 | 0.01) | 991 | (time-subtract end-time start-time)) |
| 984 | (setq-local treesit--font-lock-fast-mode t)) | 992 | 0.01)) |
| 993 | (if (> treesit--font-lock-fast-mode-grace-count 0) | ||
| 994 | (cl-decf treesit--font-lock-fast-mode-grace-count) | ||
| 995 | (setq-local treesit--font-lock-fast-mode t))) | ||
| 985 | 996 | ||
| 986 | ;; For each captured node, fontify that node. | 997 | ;; For each captured node, fontify that node. |
| 987 | (with-silent-modifications | 998 | (with-silent-modifications |
| @@ -1152,6 +1163,9 @@ See `treesit-simple-indent-presets'.") | |||
| 1152 | (and (>= (point) comment-start-bol) | 1163 | (and (>= (point) comment-start-bol) |
| 1153 | adaptive-fill-regexp | 1164 | adaptive-fill-regexp |
| 1154 | (looking-at adaptive-fill-regexp) | 1165 | (looking-at adaptive-fill-regexp) |
| 1166 | ;; If previous line is an empty line, don't | ||
| 1167 | ;; indent. | ||
| 1168 | (not (looking-at (rx (* whitespace) eol))) | ||
| 1155 | (match-end 0)))))) | 1169 | (match-end 0)))))) |
| 1156 | ;; TODO: Document. | 1170 | ;; TODO: Document. |
| 1157 | (cons 'grand-parent | 1171 | (cons 'grand-parent |
diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 312556f644a..53d58870b32 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el | |||
| @@ -325,7 +325,6 @@ See `run-hooks'." | |||
| 325 | (define-key map "U" #'vc-dir-unmark-all-files) | 325 | (define-key map "U" #'vc-dir-unmark-all-files) |
| 326 | (define-key map "\C-?" #'vc-dir-unmark-file-up) | 326 | (define-key map "\C-?" #'vc-dir-unmark-file-up) |
| 327 | (define-key map "\M-\C-?" #'vc-dir-unmark-all-files) | 327 | (define-key map "\M-\C-?" #'vc-dir-unmark-all-files) |
| 328 | (define-key map "%" #'vc-dir-mark-by-regexp) | ||
| 329 | ;; Movement. | 328 | ;; Movement. |
| 330 | (define-key map "n" #'vc-dir-next-line) | 329 | (define-key map "n" #'vc-dir-next-line) |
| 331 | (define-key map " " #'vc-dir-next-line) | 330 | (define-key map " " #'vc-dir-next-line) |
| @@ -361,8 +360,13 @@ See `run-hooks'." | |||
| 361 | (define-key branch-map "l" #'vc-print-branch-log) | 360 | (define-key branch-map "l" #'vc-print-branch-log) |
| 362 | (define-key branch-map "s" #'vc-switch-branch)) | 361 | (define-key branch-map "s" #'vc-switch-branch)) |
| 363 | 362 | ||
| 363 | (let ((regexp-map (make-sparse-keymap))) | ||
| 364 | (define-key map "%" regexp-map) | ||
| 365 | (define-key regexp-map "m" #'vc-dir-mark-by-regexp)) | ||
| 366 | |||
| 364 | (let ((mark-map (make-sparse-keymap))) | 367 | (let ((mark-map (make-sparse-keymap))) |
| 365 | (define-key map "*" mark-map) | 368 | (define-key map "*" mark-map) |
| 369 | (define-key mark-map "%" #'vc-dir-mark-by-regexp) | ||
| 366 | (define-key mark-map "r" #'vc-dir-mark-registered-files)) | 370 | (define-key mark-map "r" #'vc-dir-mark-registered-files)) |
| 367 | 371 | ||
| 368 | ;; Hook up the menu. | 372 | ;; Hook up the menu. |
| @@ -791,7 +795,7 @@ MARK-FILES should be a list of absolute filenames." | |||
| 791 | vc-ewoc)) | 795 | vc-ewoc)) |
| 792 | 796 | ||
| 793 | (defun vc-dir-mark-registered-files () | 797 | (defun vc-dir-mark-registered-files () |
| 794 | "Mark files that are in one of registered state: edited, added or removed." | 798 | "Mark files that are in one of registered states: edited, added or removed." |
| 795 | (interactive) | 799 | (interactive) |
| 796 | (vc-dir-mark-state-files '(edited added removed))) | 800 | (vc-dir-mark-state-files '(edited added removed))) |
| 797 | 801 | ||
diff --git a/lisp/window.el b/lisp/window.el index 4099b707009..84f5c5c3f5a 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -5670,7 +5670,8 @@ the original point in both windows." | |||
| 5670 | 5670 | ||
| 5671 | (defun split-window-below (&optional size window-to-split) | 5671 | (defun split-window-below (&optional size window-to-split) |
| 5672 | "Split WINDOW-TO-SPLIT into two windows, one above the other. | 5672 | "Split WINDOW-TO-SPLIT into two windows, one above the other. |
| 5673 | WINDOW-TO-SPLIT is above. The newly split-off window is | 5673 | WINDOW-TO-SPLIT defaults to the selected window and and will be above |
| 5674 | the other window after splitting. The newly split-off window is | ||
| 5674 | below and displays the same buffer. Return the new window. | 5675 | below and displays the same buffer. Return the new window. |
| 5675 | 5676 | ||
| 5676 | If optional argument SIZE is omitted or nil, both windows get the | 5677 | If optional argument SIZE is omitted or nil, both windows get the |
| @@ -5691,7 +5692,9 @@ amount of redisplay; this is convenient on slow terminals." | |||
| 5691 | ;; `split-window' would not signal an error here. | 5692 | ;; `split-window' would not signal an error here. |
| 5692 | (error "Size of new window too small")) | 5693 | (error "Size of new window too small")) |
| 5693 | (setq new-window (split-window window-to-split size)) | 5694 | (setq new-window (split-window window-to-split size)) |
| 5694 | (unless split-window-keep-point | 5695 | (when (and (null split-window-keep-point) |
| 5696 | (or (null window-to-split) | ||
| 5697 | (eq window-to-split (selected-window)))) | ||
| 5695 | (with-current-buffer (window-buffer window-to-split) | 5698 | (with-current-buffer (window-buffer window-to-split) |
| 5696 | ;; Use `save-excursion' around vertical movements below | 5699 | ;; Use `save-excursion' around vertical movements below |
| 5697 | ;; (Bug#10971). Note: When WINDOW-TO-SPLIT's buffer has a | 5700 | ;; (Bug#10971). Note: When WINDOW-TO-SPLIT's buffer has a |
| @@ -5732,8 +5735,9 @@ handled as in `split-window-below'." | |||
| 5732 | 5735 | ||
| 5733 | (defun split-window-right (&optional size window-to-split) | 5736 | (defun split-window-right (&optional size window-to-split) |
| 5734 | "Split WINDOW-TO-SPLIT into two side-by-side windows. | 5737 | "Split WINDOW-TO-SPLIT into two side-by-side windows. |
| 5735 | WINDOW-TO-SPLIT is on the left. The newly split-off window is on | 5738 | WINDOW-TO-SPLIT defaults to the selected window and and will be on the |
| 5736 | the right and displays the same buffer. Return the new window. | 5739 | left after splitting. The newly split-off window is on the right and |
| 5740 | displays the same buffer. Return the new window. | ||
| 5737 | 5741 | ||
| 5738 | If optional argument SIZE is omitted or nil, both windows get the | 5742 | If optional argument SIZE is omitted or nil, both windows get the |
| 5739 | same width, or close to it. If SIZE is positive, the left-hand | 5743 | same width, or close to it. If SIZE is positive, the left-hand |
diff --git a/src/buffer.c b/src/buffer.c index 100e42fc1f9..88ca69b0dd8 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -525,14 +525,14 @@ get_truename_buffer (register Lisp_Object filename) | |||
| 525 | return Qnil; | 525 | return Qnil; |
| 526 | } | 526 | } |
| 527 | 527 | ||
| 528 | /* Run buffer-list-update-hook if Vrun_hooks is non-nil, and BUF is NULL | 528 | /* Run buffer-list-update-hook if Vrun_hooks is non-nil and BUF does |
| 529 | or does not have buffer hooks inhibited. BUF is NULL when called by | 529 | not have buffer hooks inhibited. */ |
| 530 | make-indirect-buffer, since it does not inhibit buffer hooks. */ | ||
| 531 | 530 | ||
| 532 | static void | 531 | static void |
| 533 | run_buffer_list_update_hook (struct buffer *buf) | 532 | run_buffer_list_update_hook (struct buffer *buf) |
| 534 | { | 533 | { |
| 535 | if (! (NILP (Vrun_hooks) || (buf && buf->inhibit_buffer_hooks))) | 534 | eassert (buf); |
| 535 | if (! (NILP (Vrun_hooks) || buf->inhibit_buffer_hooks)) | ||
| 536 | call1 (Vrun_hooks, Qbuffer_list_update_hook); | 536 | call1 (Vrun_hooks, Qbuffer_list_update_hook); |
| 537 | } | 537 | } |
| 538 | 538 | ||
| @@ -907,7 +907,7 @@ does not run the hooks `kill-buffer-hook', | |||
| 907 | set_buffer_internal_1 (old_b); | 907 | set_buffer_internal_1 (old_b); |
| 908 | } | 908 | } |
| 909 | 909 | ||
| 910 | run_buffer_list_update_hook (NULL); | 910 | run_buffer_list_update_hook (b); |
| 911 | 911 | ||
| 912 | return buf; | 912 | return buf; |
| 913 | } | 913 | } |
diff --git a/src/treesit.c b/src/treesit.c index 3886fed346e..917db582676 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -42,8 +42,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 42 | #undef ts_node_end_byte | 42 | #undef ts_node_end_byte |
| 43 | #undef ts_node_eq | 43 | #undef ts_node_eq |
| 44 | #undef ts_node_field_name_for_child | 44 | #undef ts_node_field_name_for_child |
| 45 | #undef ts_node_first_child_for_byte | ||
| 46 | #undef ts_node_first_named_child_for_byte | ||
| 47 | #undef ts_node_has_error | 45 | #undef ts_node_has_error |
| 48 | #undef ts_node_is_extra | 46 | #undef ts_node_is_extra |
| 49 | #undef ts_node_is_missing | 47 | #undef ts_node_is_missing |
| @@ -99,8 +97,6 @@ DEF_DLL_FN (TSNode, ts_node_descendant_for_byte_range, | |||
| 99 | DEF_DLL_FN (uint32_t, ts_node_end_byte, (TSNode)); | 97 | DEF_DLL_FN (uint32_t, ts_node_end_byte, (TSNode)); |
| 100 | DEF_DLL_FN (bool, ts_node_eq, (TSNode, TSNode)); | 98 | DEF_DLL_FN (bool, ts_node_eq, (TSNode, TSNode)); |
| 101 | DEF_DLL_FN (const char *, ts_node_field_name_for_child, (TSNode, uint32_t)); | 99 | DEF_DLL_FN (const char *, ts_node_field_name_for_child, (TSNode, uint32_t)); |
| 102 | DEF_DLL_FN (TSNode, ts_node_first_child_for_byte, (TSNode, uint32_t)); | ||
| 103 | DEF_DLL_FN (TSNode, ts_node_first_named_child_for_byte, (TSNode, uint32_t)); | ||
| 104 | DEF_DLL_FN (bool, ts_node_has_error, (TSNode)); | 100 | DEF_DLL_FN (bool, ts_node_has_error, (TSNode)); |
| 105 | DEF_DLL_FN (bool, ts_node_is_extra, (TSNode)); | 101 | DEF_DLL_FN (bool, ts_node_is_extra, (TSNode)); |
| 106 | DEF_DLL_FN (bool, ts_node_is_missing, (TSNode)); | 102 | DEF_DLL_FN (bool, ts_node_is_missing, (TSNode)); |
| @@ -174,8 +170,6 @@ init_treesit_functions (void) | |||
| 174 | LOAD_DLL_FN (library, ts_node_end_byte); | 170 | LOAD_DLL_FN (library, ts_node_end_byte); |
| 175 | LOAD_DLL_FN (library, ts_node_eq); | 171 | LOAD_DLL_FN (library, ts_node_eq); |
| 176 | LOAD_DLL_FN (library, ts_node_field_name_for_child); | 172 | LOAD_DLL_FN (library, ts_node_field_name_for_child); |
| 177 | LOAD_DLL_FN (library, ts_node_first_child_for_byte); | ||
| 178 | LOAD_DLL_FN (library, ts_node_first_named_child_for_byte); | ||
| 179 | LOAD_DLL_FN (library, ts_node_has_error); | 173 | LOAD_DLL_FN (library, ts_node_has_error); |
| 180 | LOAD_DLL_FN (library, ts_node_is_extra); | 174 | LOAD_DLL_FN (library, ts_node_is_extra); |
| 181 | LOAD_DLL_FN (library, ts_node_is_missing); | 175 | LOAD_DLL_FN (library, ts_node_is_missing); |
| @@ -232,8 +226,6 @@ init_treesit_functions (void) | |||
| 232 | #define ts_node_end_byte fn_ts_node_end_byte | 226 | #define ts_node_end_byte fn_ts_node_end_byte |
| 233 | #define ts_node_eq fn_ts_node_eq | 227 | #define ts_node_eq fn_ts_node_eq |
| 234 | #define ts_node_field_name_for_child fn_ts_node_field_name_for_child | 228 | #define ts_node_field_name_for_child fn_ts_node_field_name_for_child |
| 235 | #define ts_node_first_child_for_byte fn_ts_node_first_child_for_byte | ||
| 236 | #define ts_node_first_named_child_for_byte fn_ts_node_first_named_child_for_byte | ||
| 237 | #define ts_node_has_error fn_ts_node_has_error | 229 | #define ts_node_has_error fn_ts_node_has_error |
| 238 | #define ts_node_is_extra fn_ts_node_is_extra | 230 | #define ts_node_is_extra fn_ts_node_is_extra |
| 239 | #define ts_node_is_missing fn_ts_node_is_missing | 231 | #define ts_node_is_missing fn_ts_node_is_missing |
| @@ -2095,6 +2087,41 @@ return nil. */) | |||
| 2095 | return make_treesit_node (XTS_NODE (node)->parser, sibling); | 2087 | return make_treesit_node (XTS_NODE (node)->parser, sibling); |
| 2096 | } | 2088 | } |
| 2097 | 2089 | ||
| 2090 | /* Our reimplementation of ts_node_first_child_for_byte. The current | ||
| 2091 | implementation of that function has problems (see bug#60127), so | ||
| 2092 | before it's fixed upstream, we use our own reimplementation of it. | ||
| 2093 | Return true if there is a valid sibling, return false otherwise. | ||
| 2094 | If the return value is false, the position of the cursor is | ||
| 2095 | undefined. (We use cursor because technically we can't make a null | ||
| 2096 | node for ourselves, also, using cursor is more convenient.) | ||
| 2097 | |||
| 2098 | TODO: Remove this function once tree-sitter fixed the bug. */ | ||
| 2099 | static bool treesit_cursor_first_child_for_byte | ||
| 2100 | (TSTreeCursor *cursor, ptrdiff_t pos, bool named) | ||
| 2101 | { | ||
| 2102 | if (!ts_tree_cursor_goto_first_child (cursor)) | ||
| 2103 | return false; | ||
| 2104 | |||
| 2105 | TSNode node = ts_tree_cursor_current_node (cursor); | ||
| 2106 | while (ts_node_end_byte (node) <= pos) | ||
| 2107 | { | ||
| 2108 | if (ts_tree_cursor_goto_next_sibling (cursor)) | ||
| 2109 | node = ts_tree_cursor_current_node (cursor); | ||
| 2110 | else | ||
| 2111 | /* Reached the end and still can't find a valid sibling. */ | ||
| 2112 | return false; | ||
| 2113 | } | ||
| 2114 | while (named && (!ts_node_is_named (node))) | ||
| 2115 | { | ||
| 2116 | if (ts_tree_cursor_goto_next_sibling (cursor)) | ||
| 2117 | node = ts_tree_cursor_current_node (cursor); | ||
| 2118 | else | ||
| 2119 | /* Reached the end and still can't find a named sibling. */ | ||
| 2120 | return false; | ||
| 2121 | } | ||
| 2122 | return true; | ||
| 2123 | } | ||
| 2124 | |||
| 2098 | DEFUN ("treesit-node-first-child-for-pos", | 2125 | DEFUN ("treesit-node-first-child-for-pos", |
| 2099 | Ftreesit_node_first_child_for_pos, | 2126 | Ftreesit_node_first_child_for_pos, |
| 2100 | Streesit_node_first_child_for_pos, 2, 3, 0, | 2127 | Streesit_node_first_child_for_pos, 2, 3, 0, |
| @@ -2119,16 +2146,17 @@ Note that this function returns an immediate child, not the smallest | |||
| 2119 | 2146 | ||
| 2120 | ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); | 2147 | ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); |
| 2121 | TSNode treesit_node = XTS_NODE (node)->node; | 2148 | TSNode treesit_node = XTS_NODE (node)->node; |
| 2122 | TSNode child; | ||
| 2123 | if (NILP (named)) | ||
| 2124 | child = ts_node_first_child_for_byte (treesit_node, byte_pos - visible_beg); | ||
| 2125 | else | ||
| 2126 | child = ts_node_first_named_child_for_byte (treesit_node, | ||
| 2127 | byte_pos - visible_beg); | ||
| 2128 | 2149 | ||
| 2129 | if (ts_node_is_null (child)) | 2150 | TSTreeCursor cursor = ts_tree_cursor_new (treesit_node); |
| 2130 | return Qnil; | 2151 | ptrdiff_t treesit_pos = byte_pos - visible_beg; |
| 2152 | bool success; | ||
| 2153 | success = treesit_cursor_first_child_for_byte (&cursor, treesit_pos, | ||
| 2154 | !NILP (named)); | ||
| 2155 | TSNode child = ts_tree_cursor_current_node (&cursor); | ||
| 2156 | ts_tree_cursor_delete (&cursor); | ||
| 2131 | 2157 | ||
| 2158 | if (!success) | ||
| 2159 | return Qnil; | ||
| 2132 | return make_treesit_node (XTS_NODE (node)->parser, child); | 2160 | return make_treesit_node (XTS_NODE (node)->parser, child); |
| 2133 | } | 2161 | } |
| 2134 | 2162 | ||
| @@ -3270,9 +3298,9 @@ a regexp. */) | |||
| 3270 | 3298 | ||
| 3271 | Lisp_Object parser = XTS_NODE (root)->parser; | 3299 | Lisp_Object parser = XTS_NODE (root)->parser; |
| 3272 | Lisp_Object parent = Fcons (Qnil, Qnil); | 3300 | Lisp_Object parent = Fcons (Qnil, Qnil); |
| 3273 | TSTreeCursor cursor; | 3301 | /* In this function we never traverse above NODE, so we don't need |
| 3274 | if (!treesit_cursor_helper (&cursor, XTS_NODE (root)->node, parser)) | 3302 | to use treesit_cursor_helper. */ |
| 3275 | return Qnil; | 3303 | TSTreeCursor cursor = ts_tree_cursor_new (XTS_NODE (root)->node); |
| 3276 | 3304 | ||
| 3277 | treesit_build_sparse_tree (&cursor, parent, predicate, process_fn, | 3305 | treesit_build_sparse_tree (&cursor, parent, predicate, process_fn, |
| 3278 | the_limit, parser); | 3306 | the_limit, parser); |
diff --git a/test/lisp/erc/erc-scenarios-base-local-modules.el b/test/lisp/erc/erc-scenarios-base-local-modules.el index d4001df45de..916d105779a 100644 --- a/test/lisp/erc/erc-scenarios-base-local-modules.el +++ b/test/lisp/erc/erc-scenarios-base-local-modules.el | |||
| @@ -19,8 +19,17 @@ | |||
| 19 | 19 | ||
| 20 | ;;; Commentary: | 20 | ;;; Commentary: |
| 21 | 21 | ||
| 22 | ;; These tests all use `sasl' because, as of ERC 5.5, it's the one | 22 | ;; A local module doubles as a minor mode whose mode variable and |
| 23 | ;; and only local module. | 23 | ;; associated local data can withstand service disruptions. |
| 24 | ;; Unfortunately, the current implementation is too unwieldy to be | ||
| 25 | ;; made public because it doesn't perform any of the boiler plate | ||
| 26 | ;; needed to save and restore buffer-local and "network-local" copies | ||
| 27 | ;; of user options. Ultimately, a user-friendly framework must fill | ||
| 28 | ;; this void if third-party local modules are ever to become | ||
| 29 | ;; practical. | ||
| 30 | ;; | ||
| 31 | ;; The following tests all use `sasl' because, as of ERC 5.5, it's the | ||
| 32 | ;; only local module. | ||
| 24 | 33 | ||
| 25 | ;;; Code: | 34 | ;;; Code: |
| 26 | 35 | ||
| @@ -206,7 +215,7 @@ | |||
| 206 | (erc-cmd-QUIT "") | 215 | (erc-cmd-QUIT "") |
| 207 | (funcall expect 10 "finished"))) | 216 | (funcall expect 10 "finished"))) |
| 208 | 217 | ||
| 209 | (ert-info ("Disabling works from a target buffer.") | 218 | (ert-info ("Disabling works from a target buffer") |
| 210 | (with-current-buffer "#chan" | 219 | (with-current-buffer "#chan" |
| 211 | (should erc-sasl-mode) | 220 | (should erc-sasl-mode) |
| 212 | (call-interactively #'erc-sasl-disable) | 221 | (call-interactively #'erc-sasl-disable) |
| @@ -214,10 +223,9 @@ | |||
| 214 | (should (local-variable-p 'erc-sasl-mode)) | 223 | (should (local-variable-p 'erc-sasl-mode)) |
| 215 | (should-not (buffer-local-value 'erc-sasl-mode (get-buffer "foonet"))) | 224 | (should-not (buffer-local-value 'erc-sasl-mode (get-buffer "foonet"))) |
| 216 | (erc-cmd-RECONNECT) | 225 | (erc-cmd-RECONNECT) |
| 217 | (with-current-buffer "#chan" | 226 | (funcall expect 10 "Some enigma, some riddle") |
| 218 | (funcall expect 10 "Some enigma, some riddle") | 227 | (should-not erc-sasl-mode) ; regression |
| 219 | (should-not erc-sasl-mode) ; regression | 228 | (should (local-variable-p 'erc-sasl-mode))) |
| 220 | (should (local-variable-p 'erc-sasl-mode)))) | ||
| 221 | 229 | ||
| 222 | (with-current-buffer "foonet" | 230 | (with-current-buffer "foonet" |
| 223 | (should (local-variable-p 'erc-sasl-mode)) | 231 | (should (local-variable-p 'erc-sasl-mode)) |
| @@ -239,4 +247,82 @@ | |||
| 239 | (should erc-sasl-mode) | 247 | (should erc-sasl-mode) |
| 240 | (funcall expect 10 "User modes for tester"))))) | 248 | (funcall expect 10 "User modes for tester"))))) |
| 241 | 249 | ||
| 250 | (defvar-local erc-scenarios-base-local-modules--local-var nil) | ||
| 251 | |||
| 252 | (define-erc-module -phony-sblm- nil | ||
| 253 | "Test module for `erc-scenarios-base-local-modules--var-persistence'." | ||
| 254 | ((when-let ((vars (or erc--server-reconnecting erc--target-priors))) | ||
| 255 | (should (assq 'erc--phony-sblm--mode vars)) | ||
| 256 | (setq erc-scenarios-base-local-modules--local-var | ||
| 257 | (alist-get 'erc-scenarios-base-local-modules--local-var vars))) | ||
| 258 | (setq erc-scenarios-base-local-modules--local-var | ||
| 259 | (or erc-scenarios-base-local-modules--local-var | ||
| 260 | (if erc--target 100 0)))) | ||
| 261 | ((kill-local-variable 'erc-scenarios-base-local-modules--local-var)) | ||
| 262 | 'local) | ||
| 263 | |||
| 264 | ;; Note: this file has grown too expensive (time-wise) and must be | ||
| 265 | ;; split up. When that happens, this test should be rewritten without | ||
| 266 | ;; any time-saving hacks, namely, server-initiated JOINs and an | ||
| 267 | ;; absence of QUITs. (That said, three connections in under 2 seconds | ||
| 268 | ;; is pretty nice.) | ||
| 269 | |||
| 270 | (ert-deftest erc-scenarios-base-local-modules--var-persistence () | ||
| 271 | :tags '(:expensive-test) | ||
| 272 | (erc-scenarios-common-with-cleanup | ||
| 273 | ((erc-scenarios-common-dialog "base/reconnect") | ||
| 274 | (erc-server-flood-penalty 0.1) | ||
| 275 | (dumb-server (erc-d-run "localhost" t 'options 'options 'options)) | ||
| 276 | (port (process-contact dumb-server :service)) | ||
| 277 | (erc-modules (cons '-phony-sblm- (remq 'autojoin erc-modules))) | ||
| 278 | (expect (erc-d-t-make-expecter)) | ||
| 279 | (server-buffer-name (format "127.0.0.1:%d" port))) | ||
| 280 | |||
| 281 | (ert-info ("Initial authentication succeeds as expected") | ||
| 282 | (with-current-buffer (erc :server "127.0.0.1" | ||
| 283 | :port port | ||
| 284 | :nick "tester" | ||
| 285 | :password "changeme" | ||
| 286 | :full-name "tester") | ||
| 287 | (should (string= (buffer-name) server-buffer-name))) | ||
| 288 | |||
| 289 | (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "FooNet")) | ||
| 290 | (funcall expect 10 "This server is in debug mode") | ||
| 291 | (should erc--phony-sblm--mode) | ||
| 292 | (should (eql erc-scenarios-base-local-modules--local-var 0)) | ||
| 293 | (setq erc-scenarios-base-local-modules--local-var 1))) | ||
| 294 | |||
| 295 | (ert-info ("Save module's local var in target buffer") | ||
| 296 | (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) | ||
| 297 | (should (eql erc-scenarios-base-local-modules--local-var 100)) | ||
| 298 | (setq erc-scenarios-base-local-modules--local-var 101) | ||
| 299 | (funcall expect 20 "welcome"))) | ||
| 300 | |||
| 301 | (with-current-buffer "FooNet" (funcall expect 20 "terminated")) | ||
| 302 | |||
| 303 | (ert-info ("Vars reused when mode was left enabled") | ||
| 304 | (with-current-buffer "#chan" | ||
| 305 | (erc-cmd-RECONNECT) | ||
| 306 | (funcall expect 20 "welcome") | ||
| 307 | (should (eql erc-scenarios-base-local-modules--local-var 101)) | ||
| 308 | (erc--phony-sblm--mode -1)) | ||
| 309 | |||
| 310 | (with-current-buffer "FooNet" | ||
| 311 | (funcall expect 10 "User modes for tester") | ||
| 312 | (should (eql erc-scenarios-base-local-modules--local-var 1)))) | ||
| 313 | |||
| 314 | (with-current-buffer "FooNet" (funcall expect 20 "terminated")) | ||
| 315 | |||
| 316 | (ert-info ("Local binding gone when mode disabled in target") | ||
| 317 | (with-current-buffer "#chan" | ||
| 318 | (erc-cmd-RECONNECT) | ||
| 319 | (funcall expect 20 "welcome") | ||
| 320 | (should-not erc--phony-sblm--mode) | ||
| 321 | (should-not erc-scenarios-base-local-modules--local-var)) | ||
| 322 | |||
| 323 | ;; But value retained in server buffer, where mode is active. | ||
| 324 | (with-current-buffer "FooNet" | ||
| 325 | (funcall expect 10 "User modes for tester") | ||
| 326 | (should (eql erc-scenarios-base-local-modules--local-var 1)))))) | ||
| 327 | |||
| 242 | ;;; erc-scenarios-local-modules.el ends here | 328 | ;;; erc-scenarios-local-modules.el ends here |
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 85506c3d27e..40a2d2de657 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el | |||
| @@ -1251,18 +1251,28 @@ | |||
| 1251 | (setq calls nil))))) | 1251 | (setq calls nil))))) |
| 1252 | 1252 | ||
| 1253 | (ert-deftest erc--merge-local-modes () | 1253 | (ert-deftest erc--merge-local-modes () |
| 1254 | 1254 | (cl-letf (((get 'erc-b-mode 'erc-module) 'b) | |
| 1255 | (ert-info ("No existing modes") | 1255 | ((get 'erc-c-mode 'erc-module) 'c) |
| 1256 | (let ((old '((a) (b . t))) | 1256 | ((get 'erc-d-mode 'erc-module) 'd) |
| 1257 | (new '(erc-c-mode erc-d-mode))) | 1257 | ((get 'erc-e-mode 'erc-module) 'e)) |
| 1258 | (should (equal (erc--merge-local-modes new old) | 1258 | |
| 1259 | '((erc-c-mode erc-d-mode)))))) | 1259 | (ert-info ("No existing modes") |
| 1260 | 1260 | (let ((old '((a) (b . t))) | |
| 1261 | (ert-info ("Active existing added, inactive existing removed, deduped") | 1261 | (new '(erc-c-mode erc-d-mode))) |
| 1262 | (let ((old '((a) (erc-b-mode) (c . t) (erc-d-mode . t) (erc-e-mode . t))) | 1262 | (should (equal (erc--merge-local-modes new old) |
| 1263 | (new '(erc-b-mode erc-d-mode))) | 1263 | '((erc-c-mode erc-d-mode)))))) |
| 1264 | (should (equal (erc--merge-local-modes new old) | 1264 | |
| 1265 | '((erc-d-mode erc-e-mode) . (erc-b-mode))))))) | 1265 | (ert-info ("Active existing added, inactive existing removed, deduped") |
| 1266 | (let ((old '((a) (erc-b-mode) (c . t) (erc-d-mode . t) (erc-e-mode . t))) | ||
| 1267 | (new '(erc-b-mode erc-d-mode))) | ||
| 1268 | (should (equal (erc--merge-local-modes new old) | ||
| 1269 | '((erc-d-mode erc-e-mode) . (erc-b-mode)))))) | ||
| 1270 | |||
| 1271 | (ert-info ("Non-module erc-prefixed mode ignored") | ||
| 1272 | (let ((old '((erc-b-mode) (erc-f-mode . t) (erc-d-mode . t))) | ||
| 1273 | (new '(erc-b-mode))) | ||
| 1274 | (should (equal (erc--merge-local-modes new old) | ||
| 1275 | '((erc-d-mode) . (erc-b-mode)))))))) | ||
| 1266 | 1276 | ||
| 1267 | (ert-deftest define-erc-module--global () | 1277 | (ert-deftest define-erc-module--global () |
| 1268 | (let ((global-module '(define-erc-module mname malias | 1278 | (let ((global-module '(define-erc-module mname malias |
| @@ -1300,13 +1310,15 @@ Some docstring" | |||
| 1300 | (ignore c) (ignore d)) | 1310 | (ignore c) (ignore d)) |
| 1301 | 1311 | ||
| 1302 | (defalias 'erc-malias-mode #'erc-mname-mode) | 1312 | (defalias 'erc-malias-mode #'erc-mname-mode) |
| 1313 | (put 'erc-malias-mode 'erc-module 'mname) | ||
| 1303 | 1314 | ||
| 1315 | (put 'erc-mname-mode 'erc-module 'mname) | ||
| 1304 | (put 'erc-mname-mode 'definition-name 'mname) | 1316 | (put 'erc-mname-mode 'definition-name 'mname) |
| 1305 | (put 'erc-mname-enable 'definition-name 'mname) | 1317 | (put 'erc-mname-enable 'definition-name 'mname) |
| 1306 | (put 'erc-mname-disable 'definition-name 'mname)))))) | 1318 | (put 'erc-mname-disable 'definition-name 'mname)))))) |
| 1307 | 1319 | ||
| 1308 | (ert-deftest define-erc-module--local () | 1320 | (ert-deftest define-erc-module--local () |
| 1309 | (let* ((global-module '(define-erc-module mname malias | 1321 | (let* ((global-module '(define-erc-module mname nil ; no alias |
| 1310 | "Some docstring" | 1322 | "Some docstring" |
| 1311 | ((ignore a) (ignore b)) | 1323 | ((ignore a) (ignore b)) |
| 1312 | ((ignore c) (ignore d)) | 1324 | ((ignore c) (ignore d)) |
| @@ -1353,8 +1365,7 @@ When called interactively, do so in all buffers for the current connection." | |||
| 1353 | (setq erc-mname-mode nil) | 1365 | (setq erc-mname-mode nil) |
| 1354 | (ignore c) (ignore d)))) | 1366 | (ignore c) (ignore d)))) |
| 1355 | 1367 | ||
| 1356 | (defalias 'erc-malias-mode #'erc-mname-mode) | 1368 | (put 'erc-mname-mode 'erc-module 'mname) |
| 1357 | |||
| 1358 | (put 'erc-mname-mode 'definition-name 'mname) | 1369 | (put 'erc-mname-mode 'definition-name 'mname) |
| 1359 | (put 'erc-mname-enable 'definition-name 'mname) | 1370 | (put 'erc-mname-enable 'definition-name 'mname) |
| 1360 | (put 'erc-mname-disable 'definition-name 'mname)))))) | 1371 | (put 'erc-mname-disable 'definition-name 'mname)))))) |
diff --git a/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld b/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld index e2fe1430283..a270c743d90 100644 --- a/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld +++ b/test/lisp/erc/resources/base/netid/bouncer/barnet-again.eld | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ;; -*- mode: lisp-data; -*- | 1 | ;; -*- mode: lisp-data; -*- |
| 2 | ((pass 10 "PASS :barnet:changeme")) | 2 | ((pass 10 "PASS :barnet:changeme")) |
| 3 | ((nick 3 "NICK tester")) | 3 | ((nick 10 "NICK tester")) |
| 4 | ((user 3 "USER user 0 * :tester") | 4 | ((user 10 "USER user 0 * :tester") |
| 5 | (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester") | 5 | (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester") |
| 6 | (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16") | 6 | (0 ":irc.barnet.org 002 tester :Your host is irc.barnet.org, running version oragono-2.6.0-7481bf0385b95b16") |
| 7 | (0 ":irc.barnet.org 003 tester :This server was created Wed, 12 May 2021 07:41:08 UTC") | 7 | (0 ":irc.barnet.org 003 tester :This server was created Wed, 12 May 2021 07:41:08 UTC") |
| @@ -17,7 +17,7 @@ | |||
| 17 | (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3") | 17 | (0 ":irc.barnet.org 266 tester 3 3 :Current global users 3, max 3") |
| 18 | (0 ":irc.barnet.org 422 tester :MOTD File is missing")) | 18 | (0 ":irc.barnet.org 422 tester :MOTD File is missing")) |
| 19 | 19 | ||
| 20 | ((mode-user 10.2 "MODE tester +i") | 20 | ((mode-user 10 "MODE tester +i") |
| 21 | ;; No mode answer ^ | 21 | ;; No mode answer ^ |
| 22 | 22 | ||
| 23 | (0 ":tester!~u@xrir8fpe4d7ak.irc JOIN #chan") | 23 | (0 ":tester!~u@xrir8fpe4d7ak.irc JOIN #chan") |
| @@ -36,9 +36,9 @@ | |||
| 36 | (0 ":irc.znc.in 306 tester :You have been marked as being away") | 36 | (0 ":irc.znc.in 306 tester :You have been marked as being away") |
| 37 | (0 ":irc.barnet.org 305 tester :You are no longer marked as being away")) | 37 | (0 ":irc.barnet.org 305 tester :You are no longer marked as being away")) |
| 38 | 38 | ||
| 39 | ((~join 3 "JOIN #chan")) | 39 | ((~join 10 "JOIN #chan")) |
| 40 | 40 | ||
| 41 | ((mode 5 "MODE #chan") | 41 | ((mode 10 "MODE #chan") |
| 42 | (0 ":irc.barnet.org 324 tester #chan +nt") | 42 | (0 ":irc.barnet.org 324 tester #chan +nt") |
| 43 | (0 ":irc.barnet.org 329 tester #chan 1620805269") | 43 | (0 ":irc.barnet.org 329 tester #chan 1620805269") |
| 44 | (0.1 ":joe!~u@svpn88yjcdj42.irc PRIVMSG #chan :mike: But, in defense, by mercy, 'tis most just.") | 44 | (0.1 ":joe!~u@svpn88yjcdj42.irc PRIVMSG #chan :mike: But, in defense, by mercy, 'tis most just.") |
diff --git a/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld b/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld index bf8712305a4..a8c352daaa7 100644 --- a/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld +++ b/test/lisp/erc/resources/base/netid/bouncer/foonet-again.eld | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ;; -*- mode: lisp-data; -*- | 1 | ;; -*- mode: lisp-data; -*- |
| 2 | ((pass 10 "PASS :foonet:changeme")) | 2 | ((pass 10 "PASS :foonet:changeme")) |
| 3 | ((nick 3 "NICK tester")) | 3 | ((nick 10 "NICK tester")) |
| 4 | ((user 3 "USER user 0 * :tester") | 4 | ((user 10 "USER user 0 * :tester") |
| 5 | (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") | 5 | (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") |
| 6 | (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16") | 6 | (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16") |
| 7 | (0 ":irc.foonet.org 003 tester :This server was created Wed, 12 May 2021 07:41:09 UTC") | 7 | (0 ":irc.foonet.org 003 tester :This server was created Wed, 12 May 2021 07:41:09 UTC") |
| @@ -17,7 +17,7 @@ | |||
| 17 | (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") | 17 | (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") |
| 18 | (0 ":irc.foonet.org 422 tester :MOTD File is missing")) | 18 | (0 ":irc.foonet.org 422 tester :MOTD File is missing")) |
| 19 | 19 | ||
| 20 | ((mode-user 10.2 "MODE tester +i") | 20 | ((mode-user 10 "MODE tester +i") |
| 21 | ;; No mode answer ^ | 21 | ;; No mode answer ^ |
| 22 | (0 ":tester!~u@nvfhxvqm92rm6.irc JOIN #chan") | 22 | (0 ":tester!~u@nvfhxvqm92rm6.irc JOIN #chan") |
| 23 | (0 ":irc.foonet.org 353 tester = #chan :alice @bob tester") | 23 | (0 ":irc.foonet.org 353 tester = #chan :alice @bob tester") |
| @@ -36,9 +36,9 @@ | |||
| 36 | (0 ":irc.foonet.org NOTICE tester :[07:00:32] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.") | 36 | (0 ":irc.foonet.org NOTICE tester :[07:00:32] This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.") |
| 37 | (0 ":irc.foonet.org 305 tester :You are no longer marked as being away")) | 37 | (0 ":irc.foonet.org 305 tester :You are no longer marked as being away")) |
| 38 | 38 | ||
| 39 | ((~join 3 "JOIN #chan")) | 39 | ((~join 10 "JOIN #chan")) |
| 40 | 40 | ||
| 41 | ((mode 8 "MODE #chan") | 41 | ((mode 10 "MODE #chan") |
| 42 | (0 ":irc.foonet.org 324 tester #chan +nt") | 42 | (0 ":irc.foonet.org 324 tester #chan +nt") |
| 43 | (0 ":irc.foonet.org 329 tester #chan 1620805271") | 43 | (0 ":irc.foonet.org 329 tester #chan 1620805271") |
| 44 | (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: Grows, lives, and dies, in single blessedness.") | 44 | (0.1 ":alice!~u@svpn88yjcdj42.irc PRIVMSG #chan :bob: Grows, lives, and dies, in single blessedness.") |
diff --git a/test/lisp/progmodes/ruby-mode-resources/ruby-ts.rb b/test/lisp/progmodes/ruby-mode-resources/ruby-ts.rb new file mode 100644 index 00000000000..4be532a5e9d --- /dev/null +++ b/test/lisp/progmodes/ruby-mode-resources/ruby-ts.rb | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | variable = foo( | ||
| 2 | [ | ||
| 3 | qwe | ||
| 4 | ], [ | ||
| 5 | rty | ||
| 6 | ], { | ||
| 7 | a: 3 | ||
| 8 | } | ||
| 9 | ) | ||
| 10 | |||
| 11 | tee = [ | ||
| 12 | qwe | ||
| 13 | ] | ||
| 14 | |||
| 15 | qux = [1, | ||
| 16 | 2] | ||
| 17 | |||
| 18 | att = {a: 1, | ||
| 19 | b: 2} | ||
| 20 | |||
| 21 | a = 1 ? 2 :( | ||
| 22 | 2 + 3 | ||
| 23 | ) | ||
| 24 | |||
| 25 | unless bismark | ||
| 26 | sink += 12 | ||
| 27 | else | ||
| 28 | dog = 99 | ||
| 29 | end | ||
| 30 | |||
| 31 | foo1 = | ||
| 32 | subject.update( | ||
| 33 | 1 | ||
| 34 | ) | ||
| 35 | |||
| 36 | foo2 = | ||
| 37 | subject. | ||
| 38 | update( | ||
| 39 | # Might make sense to indent this to 'subject' instead; but this | ||
| 40 | # style seems more popular. | ||
| 41 | 2 | ||
| 42 | ) | ||
| 43 | |||
| 44 | foo > bar && | ||
| 45 | tee < qux | ||
| 46 | |||
| 47 | 1 .. 2 && | ||
| 48 | 3 | ||
| 49 | |||
| 50 | a = foo(j, k) - | ||
| 51 | bar_tee | ||
| 52 | |||
| 53 | qux = foo.fee ? | ||
| 54 | bar : | ||
| 55 | tee | ||
| 56 | |||
| 57 | with_paren = (a + b * | ||
| 58 | c * d + | ||
| 59 | 12) | ||
| 60 | |||
| 61 | without_paren = a + b * | ||
| 62 | c * d + | ||
| 63 | 12 | ||
| 64 | |||
| 65 | {'a' => { | ||
| 66 | 'b' => 'c', | ||
| 67 | 'd' => %w(e f) | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | [1, 2, { | ||
| 72 | 'b' => 'c', | ||
| 73 | 'd' => %w(e f) | ||
| 74 | } | ||
| 75 | ] | ||
| 76 | |||
| 77 | foo(a, { | ||
| 78 | a: b, | ||
| 79 | c: d | ||
| 80 | }) | ||
| 81 | |||
| 82 | foo(foo, bar: | ||
| 83 | tee) | ||
| 84 | |||
| 85 | foo(foo, :bar => | ||
| 86 | tee) | ||
| 87 | |||
| 88 | # Local Variables: | ||
| 89 | # mode: ruby-ts | ||
| 90 | # ruby-after-operator-indent: t | ||
| 91 | # ruby-block-indent: t | ||
| 92 | # ruby-method-call-indent: t | ||
| 93 | # ruby-method-params-indent: t | ||
| 94 | # End: | ||
diff --git a/test/lisp/progmodes/ruby-ts-mode-tests.el b/test/lisp/progmodes/ruby-ts-mode-tests.el index eaf6367a306..d34c235e82b 100644 --- a/test/lisp/progmodes/ruby-ts-mode-tests.el +++ b/test/lisp/progmodes/ruby-ts-mode-tests.el | |||
| @@ -250,8 +250,12 @@ The whitespace before and including \"|\" on each line is removed." | |||
| 250 | (should (equal (buffer-string) orig)))) | 250 | (should (equal (buffer-string) orig)))) |
| 251 | (kill-buffer buf))))) | 251 | (kill-buffer buf))))) |
| 252 | 252 | ||
| 253 | (ruby-ts-deftest-indent "ruby-method-params-indent.rb") | 253 | (ruby-ts-deftest-indent "ruby-ts.rb") |
| 254 | (ruby-ts-deftest-indent "ruby-after-operator-indent.rb") | ||
| 254 | (ruby-ts-deftest-indent "ruby-block-indent.rb") | 255 | (ruby-ts-deftest-indent "ruby-block-indent.rb") |
| 256 | (ruby-ts-deftest-indent "ruby-method-call-indent.rb") | ||
| 257 | (ruby-ts-deftest-indent "ruby-method-params-indent.rb") | ||
| 258 | (ruby-ts-deftest-indent "ruby-parenless-call-arguments-indent.rb") | ||
| 255 | 259 | ||
| 256 | (provide 'ruby-ts-mode-tests) | 260 | (provide 'ruby-ts-mode-tests) |
| 257 | 261 | ||
diff --git a/test/src/buffer-tests.el b/test/src/buffer-tests.el index e5de8f3464a..9d4bbf3e040 100644 --- a/test/src/buffer-tests.el +++ b/test/src/buffer-tests.el | |||
| @@ -8315,29 +8315,35 @@ dicta sunt, explicabo. ")) | |||
| 8315 | (remove-hook 'buffer-list-update-hook bluh)))) | 8315 | (remove-hook 'buffer-list-update-hook bluh)))) |
| 8316 | 8316 | ||
| 8317 | (ert-deftest buffer-tests-inhibit-buffer-hooks-indirect () | 8317 | (ert-deftest buffer-tests-inhibit-buffer-hooks-indirect () |
| 8318 | "Indirect buffers do not call `get-buffer-create'." | 8318 | "Test `make-indirect-buffer' argument INHIBIT-BUFFER-HOOKS." |
| 8319 | (dolist (inhibit '(nil t)) | 8319 | (let* ( base run-bluh run-kbh run-kbqf |
| 8320 | (let ((base (get-buffer-create "foo" inhibit))) | 8320 | (bluh (lambda () (setq run-bluh t))) |
| 8321 | (kbh (lambda () (setq run-kbh t))) | ||
| 8322 | (kbqf (lambda () (setq run-kbqf t)))) | ||
| 8323 | (dolist (inhibit-base '(nil t)) | ||
| 8321 | (unwind-protect | 8324 | (unwind-protect |
| 8322 | (dotimes (_i 11) | 8325 | (let (indirect) |
| 8323 | (let* (flag* | 8326 | (setq base (generate-new-buffer " base" inhibit-base)) |
| 8324 | (flag (lambda () (prog1 t (setq flag* t)))) | 8327 | (dolist (inhibit-indirect '(nil t)) |
| 8325 | (indirect (make-indirect-buffer base "foo[indirect]" nil | 8328 | (dotimes (_ 11) |
| 8326 | inhibit))) | 8329 | (unwind-protect |
| 8327 | (unwind-protect | 8330 | (let ((name (generate-new-buffer-name " indirect"))) |
| 8328 | (progn | 8331 | (setq run-bluh nil run-kbh nil run-kbqf nil) |
| 8329 | (with-current-buffer indirect | 8332 | (add-hook 'buffer-list-update-hook bluh) |
| 8330 | (add-hook 'kill-buffer-query-functions flag nil t)) | 8333 | (with-current-buffer |
| 8331 | (kill-buffer indirect) | 8334 | (setq indirect (make-indirect-buffer |
| 8332 | (if inhibit | 8335 | base name nil inhibit-indirect)) |
| 8333 | (should-not flag*) | 8336 | (add-hook 'kill-buffer-hook kbh nil t) |
| 8334 | (should flag*))) | 8337 | (add-hook 'kill-buffer-query-functions kbqf nil t) |
| 8335 | (let (kill-buffer-query-functions) | 8338 | (kill-buffer)) |
| 8339 | (should (xor inhibit-indirect run-bluh)) | ||
| 8340 | (should (xor inhibit-indirect run-kbh)) | ||
| 8341 | (should (xor inhibit-indirect run-kbqf))) | ||
| 8342 | (remove-hook 'buffer-list-update-hook bluh) | ||
| 8336 | (when (buffer-live-p indirect) | 8343 | (when (buffer-live-p indirect) |
| 8337 | (kill-buffer indirect)))))) | 8344 | (kill-buffer indirect)))))) |
| 8338 | (let (kill-buffer-query-functions) | 8345 | (when (buffer-live-p base) |
| 8339 | (when (buffer-live-p base) | 8346 | (kill-buffer base)))))) |
| 8340 | (kill-buffer base))))))) | ||
| 8341 | 8347 | ||
| 8342 | (ert-deftest zero-length-overlays-and-not () | 8348 | (ert-deftest zero-length-overlays-and-not () |
| 8343 | (with-temp-buffer | 8349 | (with-temp-buffer |