aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2022-12-10 13:22:48 +0200
committerEli Zaretskii2022-12-10 13:22:48 +0200
commitd3494f1bded55a3dce3dcaee1e10a76b7b8765f4 (patch)
treeb7df895d605ce45027167cb7f2800c3163d787b5
parent3785fe52e4692ffef14c0a1e50361c22d66fabe8 (diff)
downloademacs-d3494f1bded55a3dce3dcaee1e10a76b7b8765f4.tar.gz
emacs-d3494f1bded55a3dce3dcaee1e10a76b7b8765f4.zip
Resurrect changes omitted by a recent merge from emacs-29 (bug#59921)
This includes the changes for the following commits: 670daa8b b429e524 c83c95634e7 6479691cf07 b710ca62c00 d31a2539834 a669d5fae54 f7262b8f81e fef17557365 bf81df86e52 bfc00f1c120 d2411615e8b dcf69a1d
-rw-r--r--lisp/auth-source-pass.el12
-rw-r--r--lisp/erc/erc-compat.el8
-rw-r--r--lisp/icomplete.el1
-rw-r--r--lisp/progmodes/c-ts-mode.el28
-rw-r--r--lisp/progmodes/csharp-mode.el1
-rw-r--r--lisp/progmodes/eglot.el65
-rw-r--r--lisp/progmodes/java-ts-mode.el5
-rw-r--r--lisp/progmodes/json-ts-mode.el8
-rw-r--r--lisp/progmodes/typescript-ts-mode.el9
-rw-r--r--lisp/textmodes/css-mode.el1
-rw-r--r--lisp/treesit.el25
-rw-r--r--src/treesit.c50
-rw-r--r--test/lisp/auth-source-pass-tests.el31
-rw-r--r--test/lisp/comint-tests.el16
-rw-r--r--test/src/sqlite-tests.el1
-rw-r--r--test/src/treesit-tests.el8
16 files changed, 157 insertions, 112 deletions
diff --git a/lisp/auth-source-pass.el b/lisp/auth-source-pass.el
index 74d38084480..fbb6944e26f 100644
--- a/lisp/auth-source-pass.el
+++ b/lisp/auth-source-pass.el
@@ -111,12 +111,12 @@ HOSTS can be a string or a list of strings."
111(defun auth-source-pass--match-regexp (s) 111(defun auth-source-pass--match-regexp (s)
112 (rx-to-string ; autoloaded 112 (rx-to-string ; autoloaded
113 `(: (or bot "/") 113 `(: (or bot "/")
114 (or (: (? (group-n 20 (+ (not (in ?\ ?/ ,s)))) "@") 114 (or (: (? (group-n 20 (+ (not (in ?/ ,s)))) "@") ; user prefix
115 (group-n 10 (+ (not (in ?\ ?/ ?@ ,s)))) 115 (group-n 10 (+ (not (in ?/ ?@ ,s)))) ; host
116 (? ,s (group-n 30 (+ (not (in ?\ ?/ ,s)))))) 116 (? ,s (group-n 30 (+ (not (in ?\s ?/ ,s)))))) ; port
117 (: (group-n 11 (+ (not (in ?\ ?/ ?@ ,s)))) 117 (: (group-n 11 (+ (not (in ?/ ?@ ,s)))) ; host
118 (? ,s (group-n 31 (+ (not (in ?\ ?/ ,s))))) 118 (? ,s (group-n 31 (+ (not (in ?\s ?/ ,s))))) ; port
119 (? "/" (group-n 21 (+ (not (in ?\ ?/ ,s))))))) 119 (? "/" (group-n 21 (+ (not (in ?/ ,s))))))) ; user suffix
120 eot) 120 eot)
121 'no-group)) 121 'no-group))
122 122
diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el
index abbaafcd936..bd932547586 100644
--- a/lisp/erc/erc-compat.el
+++ b/lisp/erc/erc-compat.el
@@ -176,12 +176,12 @@ If START or END is negative, it counts from the end."
176;; This hard codes `auth-source-pass-port-separator' to ":" 176;; This hard codes `auth-source-pass-port-separator' to ":"
177(defun erc-compat--29-auth-source-pass--retrieve-parsed (seen e port-number-p) 177(defun erc-compat--29-auth-source-pass--retrieve-parsed (seen e port-number-p)
178 (when (string-match (rx (or bot "/") 178 (when (string-match (rx (or bot "/")
179 (or (: (? (group-n 20 (+ (not (in " /:")))) "@") 179 (or (: (? (group-n 20 (+ (not (in "/:")))) "@")
180 (group-n 10 (+ (not (in " /:@")))) 180 (group-n 10 (+ (not (in "/:@"))))
181 (? ":" (group-n 30 (+ (not (in " /:")))))) 181 (? ":" (group-n 30 (+ (not (in " /:"))))))
182 (: (group-n 11 (+ (not (in " /:@")))) 182 (: (group-n 11 (+ (not (in "/:@"))))
183 (? ":" (group-n 31 (+ (not (in " /:"))))) 183 (? ":" (group-n 31 (+ (not (in " /:")))))
184 (? "/" (group-n 21 (+ (not (in " /:"))))))) 184 (? "/" (group-n 21 (+ (not (in "/:")))))))
185 eot) 185 eot)
186 e) 186 e)
187 (puthash e `( :host ,(or (match-string 10 e) (match-string 11 e)) 187 (puthash e `( :host ,(or (match-string 10 e) (match-string 11 e))
diff --git a/lisp/icomplete.el b/lisp/icomplete.el
index ef710d582d3..983931c20ca 100644
--- a/lisp/icomplete.el
+++ b/lisp/icomplete.el
@@ -416,7 +416,6 @@ if that doesn't produce a completion match."
416 icomplete-scroll (not (null icomplete-vertical-mode)) 416 icomplete-scroll (not (null icomplete-vertical-mode))
417 completion-styles '(flex) 417 completion-styles '(flex)
418 completion-flex-nospace nil 418 completion-flex-nospace nil
419 completion-category-defaults nil
420 completion-ignore-case t 419 completion-ignore-case t
421 read-buffer-completion-ignore-case t 420 read-buffer-completion-ignore-case t
422 read-file-name-completion-ignore-case t))) 421 read-file-name-completion-ignore-case t)))
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 08b03d5666a..7b41718a745 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -78,6 +78,8 @@ follows the form of `treesit-simple-indent-rules'."
78 (modify-syntax-entry ?\240 "." table) 78 (modify-syntax-entry ?\240 "." table)
79 (modify-syntax-entry ?/ ". 124b" table) 79 (modify-syntax-entry ?/ ". 124b" table)
80 (modify-syntax-entry ?* ". 23" table) 80 (modify-syntax-entry ?* ". 23" table)
81 (modify-syntax-entry ?\n "> b" table)
82 (modify-syntax-entry ?\^m "> b" table)
81 table) 83 table)
82 "Syntax table for `c-ts-mode'.") 84 "Syntax table for `c-ts-mode'.")
83 85
@@ -232,7 +234,8 @@ MODE is either `c' or `cpp'."
232 (false) @font-lock-constant-face 234 (false) @font-lock-constant-face
233 (null) @font-lock-constant-face 235 (null) @font-lock-constant-face
234 ,@(when (eq mode 'cpp) 236 ,@(when (eq mode 'cpp)
235 '((this) @font-lock-constant-face))) 237 '((this) @font-lock-constant-face
238 (nullptr) @font-lock-constant-face)))
236 239
237 :language mode 240 :language mode
238 :feature 'keyword 241 :feature 'keyword
@@ -516,9 +519,30 @@ the subtrees."
516 (if (looking-at "\\s<\\|\n") 519 (if (looking-at "\\s<\\|\n")
517 (forward-line 1))))) 520 (forward-line 1)))))
518 521
522(defun c-ts-mode-indent-defun ()
523 "Indent the current top-level declaration syntactically.
524
525`treesit-defun-type-regexp' defines what constructs to indent."
526 (interactive "*")
527 (let ((orig-point (point-marker)))
528 ;; If `treesit-beginning-of-defun' returns nil, we are not in a
529 ;; defun, so don't indent anything.
530 (when (treesit-beginning-of-defun)
531 (let ((start (point)))
532 (treesit-end-of-defun)
533 (indent-region start (point))))
534 (goto-char orig-point)))
535
536(defvar-keymap c-ts-mode-map
537 :doc "Keymap for the C language with tree-sitter"
538 :parent prog-mode-map
539 "C-c C-q" #'c-ts-mode-indent-defun)
540
519;;;###autoload 541;;;###autoload
520(define-derived-mode c-ts-base-mode prog-mode "C" 542(define-derived-mode c-ts-base-mode prog-mode "C"
521 "Major mode for editing C, powered by tree-sitter." 543 "Major mode for editing C, powered by tree-sitter.
544
545\\{c-ts-mode-map}"
522 :syntax-table c-ts-mode--syntax-table 546 :syntax-table c-ts-mode--syntax-table
523 547
524 ;; Navigation. 548 ;; Navigation.
diff --git a/lisp/progmodes/csharp-mode.el b/lisp/progmodes/csharp-mode.el
index 8ab5fbc91df..f08e8d6506e 100644
--- a/lisp/progmodes/csharp-mode.el
+++ b/lisp/progmodes/csharp-mode.el
@@ -893,6 +893,7 @@ Key bindings:
893;;;###autoload 893;;;###autoload
894(define-derived-mode csharp-ts-mode prog-mode "C#" 894(define-derived-mode csharp-ts-mode prog-mode "C#"
895 "Major mode for editing C# code." 895 "Major mode for editing C# code."
896 :syntax-table (csharp--make-mode-syntax-table)
896 897
897 (unless (treesit-ready-p 'c-sharp) 898 (unless (treesit-ready-p 'c-sharp)
898 (error "Tree-sitter for C# isn't available")) 899 (error "Tree-sitter for C# isn't available"))
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index c266f6e18a3..cafb99c6d80 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -7,7 +7,7 @@
7;; Maintainer: João Távora <joaotavora@gmail.com> 7;; Maintainer: João Távora <joaotavora@gmail.com>
8;; URL: https://github.com/joaotavora/eglot 8;; URL: https://github.com/joaotavora/eglot
9;; Keywords: convenience, languages 9;; Keywords: convenience, languages
10;; Package-Requires: ((emacs "26.3") (jsonrpc "1.0.14") (flymake "1.2.1") (project "0.3.0") (xref "1.0.1") (eldoc "1.11.0") (seq "2.23")) 10;; Package-Requires: ((emacs "26.3") (jsonrpc "1.0.14") (flymake "1.2.1") (project "0.3.0") (xref "1.0.1") (eldoc "1.11.0") (seq "2.23") (external-completion "0.1"))
11 11
12;; This is a GNU ELPA :core package. Avoid adding functionality 12;; This is a GNU ELPA :core package. Avoid adding functionality
13;; that is not available in the version of Emacs recorded above or any 13;; that is not available in the version of Emacs recorded above or any
@@ -110,6 +110,7 @@
110(require 'filenotify) 110(require 'filenotify)
111(require 'ert) 111(require 'ert)
112(require 'array) 112(require 'array)
113(require 'external-completion)
113 114
114;; ElDoc is preloaded in Emacs, so `require'-ing won't guarantee we are 115;; ElDoc is preloaded in Emacs, so `require'-ing won't guarantee we are
115;; using the latest version from GNU Elpa when we load eglot.el. Use an 116;; using the latest version from GNU Elpa when we load eglot.el. Use an
@@ -2060,9 +2061,11 @@ COMMAND is a symbol naming the command."
2060 (t 'eglot-note))) 2061 (t 'eglot-note)))
2061 (mess (source code message) 2062 (mess (source code message)
2062 (concat source (and code (format " [%s]" code)) ": " message))) 2063 (concat source (and code (format " [%s]" code)) ": " message)))
2063 (if-let ((buffer (find-buffer-visiting (eglot--uri-to-path uri)))) 2064 (if-let* ((path (expand-file-name (eglot--uri-to-path uri)))
2065 (buffer (find-buffer-visiting path)))
2064 (with-current-buffer buffer 2066 (with-current-buffer buffer
2065 (cl-loop 2067 (cl-loop
2068 initially (assoc-delete-all path flymake-list-only-diagnostics #'string=)
2066 for diag-spec across diagnostics 2069 for diag-spec across diagnostics
2067 collect (eglot--dbind ((Diagnostic) range code message severity source tags) 2070 collect (eglot--dbind ((Diagnostic) range code message severity source tags)
2068 diag-spec 2071 diag-spec
@@ -2105,7 +2108,6 @@ COMMAND is a symbol naming the command."
2105 (t 2108 (t
2106 (setq eglot--diagnostics diags))))) 2109 (setq eglot--diagnostics diags)))))
2107 (cl-loop 2110 (cl-loop
2108 with path = (expand-file-name (eglot--uri-to-path uri))
2109 for diag-spec across diagnostics 2111 for diag-spec across diagnostics
2110 collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec 2112 collect (eglot--dbind ((Diagnostic) code range message severity source) diag-spec
2111 (setq message (mess source code message)) 2113 (setq message (mess source code message))
@@ -2571,7 +2573,7 @@ If BUFFER, switch to it before."
2571 (let ((probe (gethash pat cache :missing))) 2573 (let ((probe (gethash pat cache :missing)))
2572 (if (eq probe :missing) (puthash pat (refresh pat) cache) 2574 (if (eq probe :missing) (puthash pat (refresh pat) cache)
2573 probe))) 2575 probe)))
2574 (lookup (pat) 2576 (lookup (pat _point)
2575 (let ((res (lookup-1 pat)) 2577 (let ((res (lookup-1 pat))
2576 (def (and (string= pat "") (gethash :default cache)))) 2578 (def (and (string= pat "") (gethash :default cache))))
2577 (append def res nil))) 2579 (append def res nil)))
@@ -2579,16 +2581,12 @@ If BUFFER, switch to it before."
2579 (cl-getf (get-text-property 2581 (cl-getf (get-text-property
2580 0 'eglot--lsp-workspaceSymbol c) 2582 0 'eglot--lsp-workspaceSymbol c)
2581 :score 0))) 2583 :score 0)))
2582 (lambda (string _pred action) 2584 (external-completion-table
2583 (pcase action 2585 'eglot-indirection-joy
2584 (`metadata `(metadata 2586 #'lookup
2585 (cycle-sort-function 2587 `((cycle-sort-function
2586 . ,(lambda (completions) 2588 . ,(lambda (completions)
2587 (cl-sort completions #'> :key #'score))) 2589 (cl-sort completions #'> :key #'score))))))))
2588 (category . eglot-indirection-joy)))
2589 (`(eglot--lsp-tryc . ,point) `(eglot--lsp-tryc . (,string . ,point)))
2590 (`(eglot--lsp-allc . ,_point) `(eglot--lsp-allc . ,(lookup string)))
2591 (_ nil))))))
2592 2590
2593(defun eglot--recover-workspace-symbol-meta (string) 2591(defun eglot--recover-workspace-symbol-meta (string)
2594 "Search `eglot--workspace-symbols-cache' for rich entry of STRING." 2592 "Search `eglot--workspace-symbols-cache' for rich entry of STRING."
@@ -2600,9 +2598,6 @@ If BUFFER, switch to it before."
2600 (setq v (cdr v)))) 2598 (setq v (cdr v))))
2601 eglot--workspace-symbols-cache))) 2599 eglot--workspace-symbols-cache)))
2602 2600
2603(add-to-list 'completion-category-overrides
2604 '(eglot-indirection-joy (styles . (eglot--lsp-backend-style))))
2605
2606(cl-defmethod xref-backend-identifier-at-point ((_backend (eql eglot))) 2601(cl-defmethod xref-backend-identifier-at-point ((_backend (eql eglot)))
2607 (let ((attempt 2602 (let ((attempt
2608 (and (xref--prompt-p this-command) 2603 (and (xref--prompt-p this-command)
@@ -3437,42 +3432,6 @@ If NOERROR, return predicate, else erroring function."
3437 'eglot-managed-mode-hook "1.6") 3432 'eglot-managed-mode-hook "1.6")
3438(provide 'eglot) 3433(provide 'eglot)
3439 3434
3440
3441;;; Backend completion
3442
3443;; Written by Stefan Monnier circa 2016. Something to move to
3444;; minibuffer.el "ASAP" (with all the `eglot--lsp-' replaced by
3445;; something else. The very same code already in SLY and stable for a
3446;; long time.
3447
3448;; This "completion style" delegates all the work to the "programmable
3449;; completion" table which is then free to implement its own
3450;; completion style. Typically this is used to take advantage of some
3451;; external tool which already has its own completion system and
3452;; doesn't give you efficient access to the prefix completion needed
3453;; by other completion styles. The table should recognize the symbols
3454;; 'eglot--lsp-tryc and 'eglot--lsp-allc as ACTION, reply with
3455;; (eglot--lsp-tryc COMP...) or (eglot--lsp-allc . (STRING . POINT)),
3456;; accordingly. tryc/allc names made akward/recognizable on purpose.
3457
3458(add-to-list 'completion-styles-alist
3459 '(eglot--lsp-backend-style
3460 eglot--lsp-backend-style-try-completion
3461 eglot--lsp-backend-style-all-completions
3462 "Ad-hoc completion style provided by the completion table."))
3463
3464(defun eglot--lsp-backend-style-call (op string table pred point)
3465 (when (functionp table)
3466 (let ((res (funcall table string pred (cons op point))))
3467 (when (eq op (car-safe res))
3468 (cdr res)))))
3469
3470(defun eglot--lsp-backend-style-try-completion (string table pred point)
3471 (eglot--lsp-backend-style-call 'eglot--lsp-tryc string table pred point))
3472
3473(defun eglot--lsp-backend-style-all-completions (string table pred point)
3474 (eglot--lsp-backend-style-call 'eglot--lsp-allc string table pred point))
3475
3476 3435
3477;; Local Variables: 3436;; Local Variables:
3478;; bug-reference-bug-regexp: "\\(github#\\([0-9]+\\)\\)" 3437;; bug-reference-bug-regexp: "\\(github#\\([0-9]+\\)\\)"
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index 96e0d5244c7..23e166ee4c3 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -57,6 +57,11 @@
57 (modify-syntax-entry ?| "." table) 57 (modify-syntax-entry ?| "." table)
58 (modify-syntax-entry ?\' "\"" table) 58 (modify-syntax-entry ?\' "\"" table)
59 (modify-syntax-entry ?\240 "." table) 59 (modify-syntax-entry ?\240 "." table)
60 (modify-syntax-entry ?/ ". 124b" table)
61 (modify-syntax-entry ?* ". 23" table)
62 (modify-syntax-entry ?\n "> b" table)
63 (modify-syntax-entry ?\^m "> b" table)
64 (modify-syntax-entry ?@ "'" table)
60 table) 65 table)
61 "Syntax table for `java-ts-mode'.") 66 "Syntax table for `java-ts-mode'.")
62 67
diff --git a/lisp/progmodes/json-ts-mode.el b/lisp/progmodes/json-ts-mode.el
index 0a0113d1d88..a118908a00c 100644
--- a/lisp/progmodes/json-ts-mode.el
+++ b/lisp/progmodes/json-ts-mode.el
@@ -45,9 +45,7 @@
45 45
46(defvar json-ts-mode--syntax-table 46(defvar json-ts-mode--syntax-table
47 (let ((table (make-syntax-table))) 47 (let ((table (make-syntax-table)))
48 ;; Taken from the cc-langs version
49 (modify-syntax-entry ?_ "_" table) 48 (modify-syntax-entry ?_ "_" table)
50 (modify-syntax-entry ?$ "_" table)
51 (modify-syntax-entry ?\\ "\\" table) 49 (modify-syntax-entry ?\\ "\\" table)
52 (modify-syntax-entry ?+ "." table) 50 (modify-syntax-entry ?+ "." table)
53 (modify-syntax-entry ?- "." table) 51 (modify-syntax-entry ?- "." table)
@@ -57,8 +55,12 @@
57 (modify-syntax-entry ?> "." table) 55 (modify-syntax-entry ?> "." table)
58 (modify-syntax-entry ?& "." table) 56 (modify-syntax-entry ?& "." table)
59 (modify-syntax-entry ?| "." table) 57 (modify-syntax-entry ?| "." table)
60 (modify-syntax-entry ?` "\"" table) 58 (modify-syntax-entry ?\' "\"" table)
61 (modify-syntax-entry ?\240 "." table) 59 (modify-syntax-entry ?\240 "." table)
60 (modify-syntax-entry ?/ ". 124b" table)
61 (modify-syntax-entry ?* ". 23" table)
62 (modify-syntax-entry ?\n "> b" table)
63 (modify-syntax-entry ?\^m "> b" table)
62 table) 64 table)
63 "Syntax table for `json-ts-mode'.") 65 "Syntax table for `json-ts-mode'.")
64 66
diff --git a/lisp/progmodes/typescript-ts-mode.el b/lisp/progmodes/typescript-ts-mode.el
index 20916eaf373..243f6146ae7 100644
--- a/lisp/progmodes/typescript-ts-mode.el
+++ b/lisp/progmodes/typescript-ts-mode.el
@@ -44,7 +44,6 @@
44 (let ((table (make-syntax-table))) 44 (let ((table (make-syntax-table)))
45 ;; Taken from the cc-langs version 45 ;; Taken from the cc-langs version
46 (modify-syntax-entry ?_ "_" table) 46 (modify-syntax-entry ?_ "_" table)
47 (modify-syntax-entry ?$ "_" table)
48 (modify-syntax-entry ?\\ "\\" table) 47 (modify-syntax-entry ?\\ "\\" table)
49 (modify-syntax-entry ?+ "." table) 48 (modify-syntax-entry ?+ "." table)
50 (modify-syntax-entry ?- "." table) 49 (modify-syntax-entry ?- "." table)
@@ -54,8 +53,14 @@
54 (modify-syntax-entry ?> "." table) 53 (modify-syntax-entry ?> "." table)
55 (modify-syntax-entry ?& "." table) 54 (modify-syntax-entry ?& "." table)
56 (modify-syntax-entry ?| "." table) 55 (modify-syntax-entry ?| "." table)
57 (modify-syntax-entry ?` "\"" table) 56 (modify-syntax-entry ?\' "\"" table)
58 (modify-syntax-entry ?\240 "." table) 57 (modify-syntax-entry ?\240 "." table)
58 (modify-syntax-entry ?/ ". 124b" table)
59 (modify-syntax-entry ?* ". 23" table)
60 (modify-syntax-entry ?\n "> b" table)
61 (modify-syntax-entry ?\^m "> b" table)
62 (modify-syntax-entry ?$ "_" table)
63 (modify-syntax-entry ?` "\"" table)
59 table) 64 table)
60 "Syntax table for `typescript-ts-mode'.") 65 "Syntax table for `typescript-ts-mode'.")
61 66
diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el
index 8a66986dc6f..822097a86d8 100644
--- a/lisp/textmodes/css-mode.el
+++ b/lisp/textmodes/css-mode.el
@@ -1822,6 +1822,7 @@ Use `\\[fill-paragraph]' to reformat CSS declaration blocks. It
1822can also be used to fill comments. 1822can also be used to fill comments.
1823 1823
1824\\{css-mode-map}" 1824\\{css-mode-map}"
1825 :syntax-table css-mode-syntax-table
1825 (when (treesit-ready-p 'css) 1826 (when (treesit-ready-p 'css)
1826 ;; Borrowed from `css-mode'. 1827 ;; Borrowed from `css-mode'.
1827 (add-hook 'completion-at-point-functions 1828 (add-hook 'completion-at-point-functions
diff --git a/lisp/treesit.el b/lisp/treesit.el
index dbbf7ec18c3..85154d0d1c7 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -833,21 +833,28 @@ The range is between START and END."
833 (nreverse result)) 833 (nreverse result))
834 (list node))) 834 (list node)))
835 835
836(defun treesit--children-covering-range-recurse (node start end threshold) 836(defun treesit--children-covering-range-recurse
837 (node start end threshold &optional limit)
837 "Return a list of children of NODE covering a range. 838 "Return a list of children of NODE covering a range.
839
838Recursively go down the parse tree and collect children, until 840Recursively go down the parse tree and collect children, until
839all nodes in the returned list are smaller than THRESHOLD. The 841all nodes in the returned list are smaller than THRESHOLD. The
840range is between START and END." 842range is between START and END.
843
844LIMIT is the recursion limit, which defaults to 100."
841 (let* ((child (treesit-node-first-child-for-pos node start)) 845 (let* ((child (treesit-node-first-child-for-pos node start))
846 (limit (or limit 100))
842 result) 847 result)
843 (while (and child (<= (treesit-node-start child) end)) 848 ;; If LIMIT is exceeded, we are probably seeing the erroneously
849 ;; tall tree, in that case, just give up.
850 (while (and (> limit 0) child (<= (treesit-node-start child) end))
844 ;; If child still too large, recurse down. Otherwise collect 851 ;; If child still too large, recurse down. Otherwise collect
845 ;; child. 852 ;; child.
846 (if (> (- (treesit-node-end child) 853 (if (> (- (treesit-node-end child)
847 (treesit-node-start child)) 854 (treesit-node-start child))
848 threshold) 855 threshold)
849 (dolist (r (treesit--children-covering-range-recurse 856 (dolist (r (treesit--children-covering-range-recurse
850 child start end threshold)) 857 child start end threshold (1- limit)))
851 (push r result)) 858 (push r result))
852 (push child result)) 859 (push child result))
853 (setq child (treesit-node-next-sibling child))) 860 (setq child (treesit-node-next-sibling child)))
@@ -888,6 +895,12 @@ detail.")
888;; top-level nodes and query them. This ensures that querying is fast 895;; top-level nodes and query them. This ensures that querying is fast
889;; everywhere else, except for the problematic region. 896;; everywhere else, except for the problematic region.
890;; 897;;
898;; Some other time the source file has a top-level node that contains
899;; a huge number of children (say, 10k children), querying that node
900;; is also very slow, so instead of getting the top-level node, we
901;; recursively go down the tree to find nodes that cover the region
902;; but are reasonably small.
903;;
891;; 3. It is possible to capture a node that's completely outside the 904;; 3. It is possible to capture a node that's completely outside the
892;; region between START and END: as long as the whole pattern 905;; region between START and END: as long as the whole pattern
893;; intersects the region, all the captured nodes in that pattern are 906;; intersects the region, all the captured nodes in that pattern are
@@ -917,8 +930,8 @@ If LOUDLY is non-nil, display some debugging information."
917 ;; If we run into problematic files, use the "fast mode" to 930 ;; If we run into problematic files, use the "fast mode" to
918 ;; try to recover. See comment #2 above for more explanation. 931 ;; try to recover. See comment #2 above for more explanation.
919 (when treesit--font-lock-fast-mode 932 (when treesit--font-lock-fast-mode
920 (setq nodes (treesit--children-covering-range 933 (setq nodes (treesit--children-covering-range-recurse
921 (car nodes) start end))) 934 (car nodes) start end (* 4 jit-lock-chunk-size))))
922 935
923 ;; Query each node. 936 ;; Query each node.
924 (dolist (sub-node nodes) 937 (dolist (sub-node nodes)
diff --git a/src/treesit.c b/src/treesit.c
index 9926806612a..8b485ca4ece 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -1642,6 +1642,17 @@ treesit_check_node (Lisp_Object obj)
1642 xsignal1 (Qtreesit_node_outdated, obj); 1642 xsignal1 (Qtreesit_node_outdated, obj);
1643} 1643}
1644 1644
1645/* Checks that OBJ is a positive integer and it is within the visible
1646 portion of BUF. */
1647static void
1648treesit_check_position (Lisp_Object obj, struct buffer *buf)
1649{
1650 treesit_check_positive_integer (obj);
1651 ptrdiff_t pos = XFIXNUM (obj);
1652 if (pos < BUF_BEGV (buf) || pos > BUF_ZV (buf))
1653 xsignal1 (Qargs_out_of_range, obj);
1654}
1655
1645bool 1656bool
1646treesit_node_uptodate_p (Lisp_Object obj) 1657treesit_node_uptodate_p (Lisp_Object obj)
1647{ 1658{
@@ -1990,14 +2001,12 @@ Note that this function returns an immediate child, not the smallest
1990 if (NILP (node)) 2001 if (NILP (node))
1991 return Qnil; 2002 return Qnil;
1992 treesit_check_node (node); 2003 treesit_check_node (node);
1993 treesit_check_positive_integer (pos);
1994 2004
1995 struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); 2005 struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer);
1996 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; 2006 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg;
1997 ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos)); 2007 ptrdiff_t byte_pos = buf_charpos_to_bytepos (buf, XFIXNUM (pos));
1998 2008
1999 if (byte_pos < BUF_BEGV_BYTE (buf) || byte_pos > BUF_ZV_BYTE (buf)) 2009 treesit_check_position (pos, buf);
2000 xsignal1 (Qargs_out_of_range, pos);
2001 2010
2002 treesit_initialize (); 2011 treesit_initialize ();
2003 2012
@@ -2028,19 +2037,14 @@ If NODE is nil, return nil. */)
2028{ 2037{
2029 if (NILP (node)) return Qnil; 2038 if (NILP (node)) return Qnil;
2030 treesit_check_node (node); 2039 treesit_check_node (node);
2031 CHECK_INTEGER (beg);
2032 CHECK_INTEGER (end);
2033 2040
2034 struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer); 2041 struct buffer *buf = XBUFFER (XTS_PARSER (XTS_NODE (node)->parser)->buffer);
2035 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg; 2042 ptrdiff_t visible_beg = XTS_PARSER (XTS_NODE (node)->parser)->visible_beg;
2036 ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, XFIXNUM (beg)); 2043 ptrdiff_t byte_beg = buf_charpos_to_bytepos (buf, XFIXNUM (beg));
2037 ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, XFIXNUM (end)); 2044 ptrdiff_t byte_end = buf_charpos_to_bytepos (buf, XFIXNUM (end));
2038 2045
2039 /* Checks for BUFFER_BEG <= BEG <= END <= BUFFER_END. */ 2046 treesit_check_position (beg, buf);
2040 if (!(BUF_BEGV_BYTE (buf) <= byte_beg 2047 treesit_check_position (end, buf);
2041 && byte_beg <= byte_end
2042 && byte_end <= BUF_ZV_BYTE (buf)))
2043 xsignal2 (Qargs_out_of_range, beg, end);
2044 2048
2045 treesit_initialize (); 2049 treesit_initialize ();
2046 2050
@@ -2426,21 +2430,24 @@ the query. */)
2426 (Lisp_Object node, Lisp_Object query, 2430 (Lisp_Object node, Lisp_Object query,
2427 Lisp_Object beg, Lisp_Object end, Lisp_Object node_only) 2431 Lisp_Object beg, Lisp_Object end, Lisp_Object node_only)
2428{ 2432{
2429 if (!NILP (beg))
2430 CHECK_INTEGER (beg);
2431 if (!NILP (end))
2432 CHECK_INTEGER (end);
2433
2434 if (!(TS_COMPILED_QUERY_P (query) 2433 if (!(TS_COMPILED_QUERY_P (query)
2435 || CONSP (query) || STRINGP (query))) 2434 || CONSP (query) || STRINGP (query)))
2436 wrong_type_argument (Qtreesit_query_p, query); 2435 wrong_type_argument (Qtreesit_query_p, query);
2437 2436
2437 treesit_initialize ();
2438
2438 /* Resolve NODE into an actual node. */ 2439 /* Resolve NODE into an actual node. */
2439 Lisp_Object lisp_node; 2440 Lisp_Object lisp_node;
2440 if (TS_NODEP (node)) 2441 if (TS_NODEP (node))
2441 lisp_node = node; 2442 {
2443 treesit_check_node (node); /* Check if up-to-date. */
2444 lisp_node = node;
2445 }
2442 else if (TS_PARSERP (node)) 2446 else if (TS_PARSERP (node))
2443 lisp_node = Ftreesit_parser_root_node (node); 2447 {
2448 treesit_check_parser (node); /* Check if deleted. */
2449 lisp_node = Ftreesit_parser_root_node (node);
2450 }
2444 else if (SYMBOLP (node)) 2451 else if (SYMBOLP (node))
2445 { 2452 {
2446 Lisp_Object parser 2453 Lisp_Object parser
@@ -2452,8 +2459,6 @@ the query. */)
2452 list4 (Qor, Qtreesit_node_p, Qtreesit_parser_p, Qsymbolp), 2459 list4 (Qor, Qtreesit_node_p, Qtreesit_parser_p, Qsymbolp),
2453 node); 2460 node);
2454 2461
2455 treesit_initialize ();
2456
2457 /* Extract C values from Lisp objects. */ 2462 /* Extract C values from Lisp objects. */
2458 TSNode treesit_node 2463 TSNode treesit_node
2459 = XTS_NODE (lisp_node)->node; 2464 = XTS_NODE (lisp_node)->node;
@@ -2464,6 +2469,13 @@ the query. */)
2464 const TSLanguage *lang 2469 const TSLanguage *lang
2465 = ts_parser_language (XTS_PARSER (lisp_parser)->parser); 2470 = ts_parser_language (XTS_PARSER (lisp_parser)->parser);
2466 2471
2472 /* Check BEG and END. */
2473 struct buffer *buf = XBUFFER (XTS_PARSER (lisp_parser)->buffer);
2474 if (!NILP (beg))
2475 treesit_check_position (beg, buf);
2476 if (!NILP (end))
2477 treesit_check_position (end, buf);
2478
2467 /* Initialize query objects. At the end of this block, we should 2479 /* Initialize query objects. At the end of this block, we should
2468 have a working TSQuery and a TSQueryCursor. */ 2480 have a working TSQuery and a TSQueryCursor. */
2469 TSQuery *treesit_query; 2481 TSQuery *treesit_query;
diff --git a/test/lisp/auth-source-pass-tests.el b/test/lisp/auth-source-pass-tests.el
index 1107e09b51b..d6d42ce942e 100644
--- a/test/lisp/auth-source-pass-tests.el
+++ b/test/lisp/auth-source-pass-tests.el
@@ -175,7 +175,8 @@ HOSTNAME, USER and PORT are passed unchanged to
175(ert-deftest auth-source-pass-any-host () 175(ert-deftest auth-source-pass-any-host ()
176 (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user")) 176 (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user"))
177 ("bar")) 177 ("bar"))
178 (should-not (auth-source-pass-search :host t)))) 178 (let ((inhibit-message t)) ; silence "... does not handle host wildcards."
179 (should-not (auth-source-pass-search :host t)))))
179 180
180(ert-deftest auth-source-pass-undefined-host () 181(ert-deftest auth-source-pass-undefined-host ()
181 (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user")) 182 (auth-source-pass--with-store '(("foo" ("port" . "foo-port") ("host" . "foo-user"))
@@ -697,29 +698,29 @@ machine Libera.Chat password b
697;; with slightly more realistic and less legible values. 698;; with slightly more realistic and less legible values.
698 699
699(ert-deftest auth-source-pass-extra-query-keywords--suffixed-user () 700(ert-deftest auth-source-pass-extra-query-keywords--suffixed-user ()
700 (let ((store (sort (copy-sequence '(("x.com:42/b@r" (secret . "a")) 701 (let ((store (sort (copy-sequence '(("x.com:42/s p@m" (secret . "a"))
701 ("b@r@x.com" (secret . "b")) 702 ("s p@m@x.com" (secret . "b"))
702 ("x.com" (secret . "?")) 703 ("x.com" (secret . "?"))
703 ("b@r@y.org" (secret . "c")) 704 ("s p@m@y.org" (secret . "c"))
704 ("fake.com" (secret . "?")) 705 ("fa ke" (secret . "?"))
705 ("fake.com/b@r" (secret . "d")) 706 ("fa ke/s p@m" (secret . "d"))
706 ("y.org/b@r" (secret . "?")) 707 ("y.org/s p@m" (secret . "?"))
707 ("b@r@fake.com" (secret . "e")))) 708 ("s p@m@fa ke" (secret . "e"))))
708 (lambda (&rest _) (zerop (random 2)))))) 709 (lambda (&rest _) (zerop (random 2))))))
709 (auth-source-pass--with-store store 710 (auth-source-pass--with-store store
710 (auth-source-pass-enable) 711 (auth-source-pass-enable)
711 (let* ((auth-source-pass-extra-query-keywords t) 712 (let* ((auth-source-pass-extra-query-keywords t)
712 (results (auth-source-search :host '("x.com" "fake.com" "y.org") 713 (results (auth-source-search :host '("x.com" "fa ke" "y.org")
713 :user "b@r" 714 :user "s p@m"
714 :require '(:user) :max 5))) 715 :require '(:user) :max 5)))
715 (dolist (result results) 716 (dolist (result results)
716 (setf (plist-get result :secret) (auth-info-password result))) 717 (setf (plist-get result :secret) (auth-info-password result)))
717 (should (equal results 718 (should (equal results
718 '((:host "x.com" :user "b@r" :secret "b") 719 '((:host "x.com" :user "s p@m" :secret "b")
719 (:host "x.com" :user "b@r" :port "42" :secret "a") 720 (:host "x.com" :user "s p@m" :port "42" :secret "a")
720 (:host "fake.com" :user "b@r" :secret "e") 721 (:host "fa ke" :user "s p@m" :secret "e")
721 (:host "fake.com" :user "b@r" :secret "d") 722 (:host "fa ke" :user "s p@m" :secret "d")
722 (:host "y.org" :user "b@r" :secret "c")))))))) 723 (:host "y.org" :user "s p@m" :secret "c"))))))))
723 724
724;; This is a more distilled version of `suffixed-user', above. It 725;; This is a more distilled version of `suffixed-user', above. It
725;; better illustrates that search order takes precedence over "/user" 726;; better illustrates that search order takes precedence over "/user"
diff --git a/test/lisp/comint-tests.el b/test/lisp/comint-tests.el
index 8402c13daf3..ce1a6865b65 100644
--- a/test/lisp/comint-tests.el
+++ b/test/lisp/comint-tests.el
@@ -59,9 +59,23 @@
59 (dolist (str comint-testsuite-password-strings) 59 (dolist (str comint-testsuite-password-strings)
60 (should (string-match comint-password-prompt-regexp str)))) 60 (should (string-match comint-password-prompt-regexp str))))
61 61
62(declare-function w32-application-type "w32proc.c")
63(defun w32-native-executable-p (fname)
64 "Predicate to test program FNAME for being a native Windows application."
65 (and (memq (w32-application-type fname) '(w32-native dos))
66 (file-executable-p fname)))
67
68(defun w32-native-executable-find (name)
69 "Find a native MS-Windows application named NAME.
70This is needed to avoid invoking MSYS or Cygwin executables that
71happen to lurk on PATH when running the test suite."
72 (locate-file name exec-path exec-suffixes 'w32-native-executable-p))
73
62(defun comint-tests/test-password-function (password-function) 74(defun comint-tests/test-password-function (password-function)
63 "PASSWORD-FUNCTION can return nil or a string." 75 "PASSWORD-FUNCTION can return nil or a string."
64 (when-let ((cat (executable-find "cat"))) 76 (when-let ((cat (if (eq system-type 'windows-nt)
77 (w32-native-executable-find "cat")
78 (executable-find "cat"))))
65 (let ((comint-password-function password-function)) 79 (let ((comint-password-function password-function))
66 (cl-letf (((symbol-function 'read-passwd) 80 (cl-letf (((symbol-function 'read-passwd)
67 (lambda (&rest _args) "non-nil"))) 81 (lambda (&rest _args) "non-nil")))
diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el
index e9ddf9c0bef..a2472c43dad 100644
--- a/test/src/sqlite-tests.el
+++ b/test/src/sqlite-tests.el
@@ -36,6 +36,7 @@
36(declare-function sqlite-select "sqlite.c") 36(declare-function sqlite-select "sqlite.c")
37(declare-function sqlite-open "sqlite.c") 37(declare-function sqlite-open "sqlite.c")
38(declare-function sqlite-load-extension "sqlite.c") 38(declare-function sqlite-load-extension "sqlite.c")
39(declare-function sqlite-version "sqlite.c")
39 40
40(ert-deftest sqlite-select () 41(ert-deftest sqlite-select ()
41 (skip-unless (sqlite-available-p)) 42 (skip-unless (sqlite-available-p))
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el
index 80fde408cd3..aba12759c34 100644
--- a/test/src/treesit-tests.el
+++ b/test/src/treesit-tests.el
@@ -143,6 +143,8 @@
143 (treesit-node-string 143 (treesit-node-string
144 (treesit-node-first-child-for-pos 144 (treesit-node-first-child-for-pos
145 doc-node 3)))) 145 doc-node 3))))
146 (should-error (treesit-node-first-child-for-pos doc-node 100)
147 :type 'args-out-of-range)
146 ;; `treesit-node-descendant-for-range'. 148 ;; `treesit-node-descendant-for-range'.
147 (should (equal "(\"{\")" 149 (should (equal "(\"{\")"
148 (treesit-node-string 150 (treesit-node-string
@@ -152,6 +154,9 @@
152 (treesit-node-string 154 (treesit-node-string
153 (treesit-node-descendant-for-range 155 (treesit-node-descendant-for-range
154 root-node 6 7 t)))) 156 root-node 6 7 t))))
157 (should-error (treesit-node-descendant-for-range
158 root-node 100 101)
159 :type 'args-out-of-range)
155 ;; `treesit-node-eq'. 160 ;; `treesit-node-eq'.
156 (should (treesit-node-eq root-node root-node)) 161 (should (treesit-node-eq root-node root-node))
157 (should (not (treesit-node-eq root-node doc-node)))))) 162 (should (not (treesit-node-eq root-node doc-node))))))
@@ -167,6 +172,9 @@
167 (setq root-node (treesit-parser-root-node 172 (setq root-node (treesit-parser-root-node
168 parser))) 173 parser)))
169 174
175 (should-error (treesit-query-capture root-node "" 100 101)
176 :type 'args-out-of-range)
177
170 ;; Test `treesit-query-capture' on string, sexp and compiled 178 ;; Test `treesit-query-capture' on string, sexp and compiled
171 ;; queries. 179 ;; queries.
172 (dolist (query1 180 (dolist (query1