aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2024-09-11 13:21:58 +0800
committerPo Lu2024-09-11 13:21:58 +0800
commit76487b7454b88557d7c8dec7136b7a09aacfb5bf (patch)
tree842ee1c5078c962b39f227608fca99ddf9d1ccd3
parent652a8a0838b38a6eab85c55fc61cedd1c61ef20f (diff)
parentee3e3a6311196129104881d6e9097bb54d8843af (diff)
downloademacs-76487b7454b88557d7c8dec7136b7a09aacfb5bf.tar.gz
emacs-76487b7454b88557d7c8dec7136b7a09aacfb5bf.zip
Merge from savannah/emacs-30
ee3e3a63111 ; Update version number of exec/configure.ac c5925b6ba5f Fix heex-ts-mode indentation following previews elixir-mo... c3383be5f04 ; * admin/make-tarball.txt: Improve last change. 8ddb54117f1 ; * admin/make-tarball.txt: Remove now unnecessary config... 7e194d33f90 * lisp/ldefs-boot.el: Update. 9019536ea66 Fix use of Uniscribe font driver in MinGW build 5c55c860db7 Avoid crashes in redisplay in batch-mode testing ba2190e1ae7 ; * etc/NEWS: Fix indentation. 818c0cc9a51 eglot-test-rust-completion-exit-function: Fix failure in ... f47297782bd ; * doc/lispref/searching.texi (Rx Notation): Simplify rx... 03e56981675 Clarify the semantics of 'string-pixel-width' 9f0603207b1 ; * src/treesit.c: Minor cleanups of recent changes. e0d3f743957 * src/treesit.c (treesit_debug_print_parser_list): Fix fo... bed38ded730 ; * src/treesit.c (treesit_debug_print_parser_list): Fix ... 18c6487dbd0 ; * src/treesit.c: Add a prototype so there's no warning ... bf23382f1f2 Read more on each call to treesit's buffer reader 3435464452b Fix the range handling in treesit.c 3fcec09f754 Add debugging function for treesit.c 0fd259d166c Fix elixir-ts-mode's range query 2329b36b1fb ; project-files-relative-names: Update docstring (bug#72701) e55e2e1c6ba Make json-serialize always return a unibyte string (bug#7... 89c99891b2b ; * doc/lispref/os.texi (Suspending Emacs): Fix last change. 4f044d0d3df ; Improve documentation of 'suspend-emacs'
-rw-r--r--admin/admin.el4
-rw-r--r--admin/make-tarball.txt8
-rw-r--r--doc/lispref/display.texi8
-rw-r--r--doc/lispref/os.texi16
-rw-r--r--doc/lispref/searching.texi12
-rw-r--r--doc/lispref/text.texi2
-rw-r--r--etc/NEWS.307
-rw-r--r--exec/configure.ac2
-rw-r--r--lisp/emacs-lisp/subr-x.el5
-rw-r--r--lisp/progmodes/elixir-ts-mode.el4
-rw-r--r--lisp/progmodes/heex-ts-mode.el8
-rw-r--r--lisp/progmodes/project.el5
-rw-r--r--src/json.c14
-rw-r--r--src/keyboard.c7
-rw-r--r--src/treesit.c148
-rw-r--r--src/treesit.h9
-rw-r--r--src/w32uniscribe.c2
-rw-r--r--src/xdisp.c7
-rw-r--r--test/lisp/progmodes/eglot-tests.el10
-rw-r--r--test/src/json-tests.el50
20 files changed, 223 insertions, 105 deletions
diff --git a/admin/admin.el b/admin/admin.el
index edd3246a1a3..b3f63eef5bb 100644
--- a/admin/admin.el
+++ b/admin/admin.el
@@ -112,6 +112,10 @@ Root must be the root of an Emacs source tree."
112 (rx (and "AC_INIT" (1+ (not (in ?,))) 112 (rx (and "AC_INIT" (1+ (not (in ?,)))
113 ?, (0+ space) ?\[ 113 ?, (0+ space) ?\[
114 (submatch (1+ (in "0-9.")))))) 114 (submatch (1+ (in "0-9."))))))
115 (set-version-in-file root "exec/configure.ac" version
116 (rx (and "AC_INIT" (1+ (not (in ?,)))
117 ?, (0+ space) ?\[
118 (submatch (1+ (in "0-9."))))))
115 (set-version-in-file root "nt/README.W32" version 119 (set-version-in-file root "nt/README.W32" version
116 (rx (and "version" (1+ space) 120 (rx (and "version" (1+ space)
117 (submatch (1+ (in "0-9.")))))) 121 (submatch (1+ (in "0-9."))))))
diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt
index 85a8ef2624d..8e23165b257 100644
--- a/admin/make-tarball.txt
+++ b/admin/make-tarball.txt
@@ -55,14 +55,8 @@ General steps (for each step, check for possible errors):
55 because some of the commands below run Make, so they need 55 because some of the commands below run Make, so they need
56 Makefiles to be present. 56 Makefiles to be present.
57 57
58 For Emacs 28 and later, as long as --with-native-compilation is
59 not the default, the tree needs to be configured with
60 native-compilation enabled, to ensure all the pertinent *.elc
61 files will end up in the tarball. Otherwise, the *.eln files
62 might not build correctly on the user's system.
63
64 ./autogen.sh 58 ./autogen.sh
65 ./configure --with-native-compilation && make 59 ./configure --without-native-compilation && make
66 60
67 For a release (as opposed to pretest), visit etc/NEWS and use the 61 For a release (as opposed to pretest), visit etc/NEWS and use the
68 "M-x emacs-news-delete-temporary-markers" command to delete any 62 "M-x emacs-news-delete-temporary-markers" command to delete any
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 57796c5d856..5d0a3bcc87a 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2238,7 +2238,7 @@ displayed in a given window. This function is used by
2238it contains. 2238it contains.
2239 2239
2240@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end 2240@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end
2241This function returns the size of the text of @var{window}'s buffer in 2241This function returns the dimensions of the text of @var{window}'s buffer in
2242pixels. @var{window} must be a live window and defaults to the 2242pixels. @var{window} must be a live window and defaults to the
2243selected one. The return value is a cons of the maximum pixel-width 2243selected one. The return value is a cons of the maximum pixel-width
2244of any text line and the maximum pixel-height of all text lines. This 2244of any text line and the maximum pixel-height of all text lines. This
@@ -2387,7 +2387,11 @@ meaning as with @code{window-text-pixel-size}.
2387 2387
2388@defun string-pixel-width string &optional buffer 2388@defun string-pixel-width string &optional buffer
2389This is a convenience function that uses @code{window-text-pixel-size} 2389This is a convenience function that uses @code{window-text-pixel-size}
2390to compute the width of @var{string} (in pixels). If @var{buffer} is 2390to compute the width of @var{string} (in pixels). Caveat: if you call
2391this function to measure the width of a string with embedded newlines,
2392it will then return the width of the widest substring that does not
2393include newlines. The meaning of this result is the widest line taken
2394by the string if inserted into a buffer. If @var{buffer} is
2391non-@code{nil}, use any face remappings (@pxref{Face Remapping}) from 2395non-@code{nil}, use any face remappings (@pxref{Face Remapping}) from
2392that buffer when computing the width of @var{string}. 2396that buffer when computing the width of @var{string}.
2393@end defun 2397@end defun
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index fc456a79032..be26fb5063c 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -811,9 +811,6 @@ before suspending Emacs, or this function signals an error.
811 811
812If @var{string} is non-@code{nil}, its characters are sent to Emacs's 812If @var{string} is non-@code{nil}, its characters are sent to Emacs's
813superior shell, to be read as terminal input. 813superior shell, to be read as terminal input.
814@c FIXME? It seems to me that shell does echo STRING.
815The characters in @var{string} are not echoed by the superior shell;
816only the results appear.
817 814
818Before suspending, @code{suspend-emacs} runs the normal hook 815Before suspending, @code{suspend-emacs} runs the normal hook
819@code{suspend-hook}. After the user resumes Emacs, 816@code{suspend-hook}. After the user resumes Emacs,
@@ -849,7 +846,8 @@ Really suspend? @kbd{y}
849 846
850@group 847@group
851---------- Parent Shell ---------- 848---------- Parent Shell ----------
852bash$ /home/username 849bash$ pwd
850/home/username
853bash$ fg 851bash$ fg
854@end group 852@end group
855 853
@@ -859,9 +857,13 @@ Resumed!
859@end group 857@end group
860@end smallexample 858@end smallexample
861 859
862@c FIXME? AFAICS, it is echoed. 860Note that on some operating systems, sending @var{string} to the Emacs
863Note that @samp{pwd} is not echoed after Emacs is suspended. But it 861parent shell might require special privileges, in which case it might
864is read and executed by the shell. 862silently fail to send @var{string} to the shell for execution. On other
863systems this is not supported, and Emacs will signal an error if you
864try. Also, @var{string} might not be echoed, even if it is executed by
865the shell. So we don't recommend relying on this feature in portable
866Lisp programs.
865@end deffn 867@end deffn
866 868
867@defvar suspend-hook 869@defvar suspend-hook
diff --git a/doc/lispref/searching.texi b/doc/lispref/searching.texi
index 7b4a9100e77..4691a6557e8 100644
--- a/doc/lispref/searching.texi
+++ b/doc/lispref/searching.texi
@@ -1028,13 +1028,13 @@ programming language:
1028 1028
1029@example 1029@example
1030@group 1030@group
1031(rx "/*" ; Initial /* 1031(rx "/*" ; Initial /*
1032 (zero-or-more 1032 (zero-or-more
1033 (or (not (any "*")) ; Either non-*, 1033 (or (not "*") ; Either non-*,
1034 (seq "*" ; or * followed by 1034 (seq "*" ; or * followed by
1035 (not (any "/"))))) ; non-/ 1035 (not "/")))) ; non-/
1036 (one-or-more "*") ; At least one star, 1036 (one-or-more "*") ; At least one star,
1037 "/") ; and the final / 1037 "/") ; and the final /
1038@end group 1038@end group
1039@end example 1039@end example
1040 1040
diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 278b53d7f65..df56433fd18 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -5844,7 +5844,7 @@ can be serialized to JSON@. Likewise, the parsing functions will
5844return any of the possible types described above. 5844return any of the possible types described above.
5845 5845
5846@defun json-serialize object &rest args 5846@defun json-serialize object &rest args
5847This function returns a new Lisp string which contains the JSON 5847This function returns a new Lisp unibyte string which contains the JSON
5848representation of @var{object}. The argument @var{args} is a list of 5848representation of @var{object}. The argument @var{args} is a list of
5849keyword/argument pairs. The following keywords are accepted: 5849keyword/argument pairs. The following keywords are accepted:
5850 5850
diff --git a/etc/NEWS.30 b/etc/NEWS.30
index a61bdc4a7f3..18d4c6b2158 100644
--- a/etc/NEWS.30
+++ b/etc/NEWS.30
@@ -3071,6 +3071,13 @@ entire SQL file.
3071 3071
3072** JSON 3072** JSON
3073 3073
3074+++
3075*** 'json-serialize' now always returns a unibyte string.
3076This is appropriate since it is an encoding operation. In the unlikely
3077event that a multibyte string is needed, the result can be decoded using
3078
3079 (decode-coding-string RESULT 'utf-8)
3080
3074--- 3081---
3075*** The parser keeps duplicated object keys in alist and plist output. 3082*** The parser keeps duplicated object keys in alist and plist output.
3076A JSON object such as '{"a":1,"a":2}' will now be translated into the 3083A JSON object such as '{"a":1,"a":2}' will now be translated into the
diff --git a/exec/configure.ac b/exec/configure.ac
index c3e895740be..41c4c8b5d42 100644
--- a/exec/configure.ac
+++ b/exec/configure.ac
@@ -22,7 +22,7 @@ dnl You should have received a copy of the GNU General Public License
22dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. 22dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
23 23
24AC_PREREQ([2.65]) 24AC_PREREQ([2.65])
25AC_INIT([libexec], [30.0.50], [bug-gnu-emacs@gnu.org], [], 25AC_INIT([libexec], [30.0.90], [bug-gnu-emacs@gnu.org], [],
26 [https://www.gnu.org/software/emacs/]) 26 [https://www.gnu.org/software/emacs/])
27 27
28AH_TOP([/* Copyright (C) 2024 Free Software Foundation, Inc. 28AH_TOP([/* Copyright (C) 2024 Free Software Foundation, Inc.
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index 4cdb065feeb..66347e7b584 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -387,7 +387,10 @@ buffer when possible, instead of creating a new one on each call."
387(defun string-pixel-width (string &optional buffer) 387(defun string-pixel-width (string &optional buffer)
388 "Return the width of STRING in pixels. 388 "Return the width of STRING in pixels.
389If BUFFER is non-nil, use the face remappings from that buffer when 389If BUFFER is non-nil, use the face remappings from that buffer when
390determining the width." 390determining the width.
391If you call this function to measure pixel width of a string
392with embedded newlines, it returns the width of the widest
393substring that does not include newlines."
391 (declare (important-return-value t)) 394 (declare (important-return-value t))
392 (if (zerop (length string)) 395 (if (zerop (length string))
393 0 396 0
diff --git a/lisp/progmodes/elixir-ts-mode.el b/lisp/progmodes/elixir-ts-mode.el
index 9804152d9ab..815827ed13c 100644
--- a/lisp/progmodes/elixir-ts-mode.el
+++ b/lisp/progmodes/elixir-ts-mode.el
@@ -572,7 +572,9 @@
572 (treesit-range-rules 572 (treesit-range-rules
573 :embed 'heex 573 :embed 'heex
574 :host 'elixir 574 :host 'elixir
575 '((sigil (sigil_name) @name (:match "^[HF]$" @name) (quoted_content) @heex))))) 575 '((sigil (sigil_name) @_name
576 (:match "^[HF]$" @_name)
577 (quoted_content) @heex)))))
576 578
577(defvar heex-ts--sexp-regexp) 579(defvar heex-ts--sexp-regexp)
578(defvar heex-ts--indent-rules) 580(defvar heex-ts--indent-rules)
diff --git a/lisp/progmodes/heex-ts-mode.el b/lisp/progmodes/heex-ts-mode.el
index 07b8bfdc74f..b527d96b579 100644
--- a/lisp/progmodes/heex-ts-mode.el
+++ b/lisp/progmodes/heex-ts-mode.el
@@ -64,16 +64,18 @@
64 (let ((offset heex-ts-indent-offset)) 64 (let ((offset heex-ts-indent-offset))
65 `((heex 65 `((heex
66 ((parent-is "fragment") 66 ((parent-is "fragment")
67 (lambda (node parent &rest _) 67 (lambda (_node _parent bol &rest _)
68 ;; If HEEx is embedded indent to parent 68 ;; If HEEx is embedded indent to parent
69 ;; otherwise indent to the bol. 69 ;; otherwise indent to the bol.
70 (if (eq (treesit-language-at (point-min)) 'heex) 70 (if (eq (treesit-language-at (point-min)) 'heex)
71 (point-min) 71 (point-min)
72 (save-excursion 72 (save-excursion
73 (goto-char (treesit-node-start parent)) 73 (goto-char (treesit-node-start
74 (treesit-node-at bol 'elixir)))
74 (back-to-indentation) 75 (back-to-indentation)
75 (point)) 76 (point))
76 )) 0) 77 ))
78 0)
77 ((node-is "end_tag") parent-bol 0) 79 ((node-is "end_tag") parent-bol 0)
78 ((node-is "end_component") parent-bol 0) 80 ((node-is "end_component") parent-bol 0)
79 ((node-is "end_slot") parent-bol 0) 81 ((node-is "end_slot") parent-bol 0)
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index ab884935a77..220d4dfe853 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -331,7 +331,10 @@ end it with `/'. DIR must be either `project-root' or one of
331The file names should be relative to the project root. And this can 331The file names should be relative to the project root. And this can
332only happen when all returned files are in the same directory. 332only happen when all returned files are in the same directory.
333In other words, the DIRS argument of `project-files' has to be nil or a 333In other words, the DIRS argument of `project-files' has to be nil or a
334list of only one element.") 334list of only one element.
335
336This variable is only meant to be set by Lisp code, not customized by
337the user.")
335 338
336(cl-defgeneric project-files (project &optional dirs) 339(cl-defgeneric project-files (project &optional dirs)
337 "Return a list of files in directories DIRS in PROJECT. 340 "Return a list of files in directories DIRS in PROJECT.
diff --git a/src/json.c b/src/json.c
index eb2fa0472c8..282dca6e8ff 100644
--- a/src/json.c
+++ b/src/json.c
@@ -559,16 +559,6 @@ json_out_something (json_out_t *jo, Lisp_Object obj)
559 wrong_type_argument (Qjson_value_p, obj); 559 wrong_type_argument (Qjson_value_p, obj);
560} 560}
561 561
562static Lisp_Object
563json_out_to_string (json_out_t *jo)
564{
565 /* FIXME: should this be a unibyte or multibyte string?
566 Right now we make a multibyte string for test compatibility,
567 but we are really encoding so unibyte would make more sense. */
568 ptrdiff_t nchars = jo->size - jo->chars_delta;
569 return make_multibyte_string (jo->buf, nchars, jo->size);
570}
571
572static void 562static void
573json_serialize (json_out_t *jo, Lisp_Object object, 563json_serialize (json_out_t *jo, Lisp_Object object,
574 ptrdiff_t nargs, Lisp_Object *args) 564 ptrdiff_t nargs, Lisp_Object *args)
@@ -596,7 +586,7 @@ json_serialize (json_out_t *jo, Lisp_Object object,
596 586
597DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY, 587DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY,
598 NULL, 588 NULL,
599 doc: /* Return the JSON representation of OBJECT as a string. 589 doc: /* Return the JSON representation of OBJECT as a unibyte string.
600 590
601OBJECT is translated as follows: 591OBJECT is translated as follows:
602 592
@@ -629,7 +619,7 @@ usage: (json-serialize OBJECT &rest ARGS) */)
629 specpdl_ref count = SPECPDL_INDEX (); 619 specpdl_ref count = SPECPDL_INDEX ();
630 json_out_t jo; 620 json_out_t jo;
631 json_serialize (&jo, args[0], nargs - 1, args + 1); 621 json_serialize (&jo, args[0], nargs - 1, args + 1);
632 return unbind_to (count, json_out_to_string (&jo)); 622 return unbind_to (count, make_unibyte_string (jo.buf, jo.size));
633} 623}
634 624
635DEFUN ("json-insert", Fjson_insert, Sjson_insert, 1, MANY, 625DEFUN ("json-insert", Fjson_insert, Sjson_insert, 1, MANY,
diff --git a/src/keyboard.c b/src/keyboard.c
index 0992fab653b..6d28dca9aeb 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -11917,7 +11917,12 @@ Before suspending, run the normal hook `suspend-hook'.
11917After resumption run the normal hook `suspend-resume-hook'. 11917After resumption run the normal hook `suspend-resume-hook'.
11918 11918
11919Some operating systems cannot stop the Emacs process and resume it later. 11919Some operating systems cannot stop the Emacs process and resume it later.
11920On such systems, Emacs starts a subshell instead of suspending. */) 11920On such systems, Emacs starts a subshell instead of suspending.
11921
11922On some operating systems, stuffing characters into terminal input
11923buffer requires special privileges or is not supported at all.
11924On such systems, calling this function with non-nil STUFFSTRING might
11925either signal an error or silently fail to stuff the characters. */)
11921 (Lisp_Object stuffstring) 11926 (Lisp_Object stuffstring)
11922{ 11927{
11923 specpdl_ref count = SPECPDL_INDEX (); 11928 specpdl_ref count = SPECPDL_INDEX ();
diff --git a/src/treesit.c b/src/treesit.c
index 5aedca44489..0ba6c733d64 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -489,6 +489,56 @@ treesit_initialize (void)
489} 489}
490 490
491 491
492/*** Debugging */
493
494void treesit_debug_print_parser_list (char *, Lisp_Object);
495
496void
497treesit_debug_print_parser_list (char *msg, Lisp_Object parser)
498{
499 struct buffer *buf = XBUFFER (XTS_PARSER (parser)->buffer);
500 char *buf_name = SSDATA (BVAR (buf, name));
501 printf ("%s (%s) [%s] <%s>: %ld(%ld)-(%ld)%ld {\n",
502 msg == NULL ? "" : msg,
503 SSDATA (SYMBOL_NAME (Vthis_command)),
504 SSDATA (SYMBOL_NAME (XTS_PARSER (parser)->language_symbol)),
505 buf_name, BUF_BEG (buf),
506 BUF_BEGV (buf), BUF_Z (buf), BUF_ZV (buf));
507 Lisp_Object tail = BVAR (buf, ts_parser_list);
508
509 FOR_EACH_TAIL (tail)
510 {
511 struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail));
512 printf ("[%s %s %s %ld-%ld T:%ld]\n", SSDATA (SYMBOL_NAME (parser->language_symbol)),
513 SSDATA (SYMBOL_NAME (parser->tag)),
514 parser->need_reparse ? "NEED-R" : "NONEED",
515 parser->visible_beg, parser->visible_end,
516 parser->timestamp);
517 /* Print ranges. */
518 uint32_t len;
519 const TSRange *ranges
520 = ts_parser_included_ranges (parser->parser, &len);
521
522 if (!(len == 1 && ranges[0].start_byte == 0 && ranges[0].end_byte == -1))
523 {
524 for (int idx = 0; idx < len; idx++)
525 {
526 TSRange range = ranges[idx];
527 printf (" [%"PRIu32", %"PRIu32")", range.start_byte, range.end_byte);
528
529 /* if (!parser->need_reparse) */
530 /* { */
531 /* eassert (BUF_BEGV_BYTE (buf) <= range.start_byte + parser->visible_beg); */
532 /* eassert (range.end_byte + parser->visible_beg <= BUF_ZV_BYTE (buf)); */
533 /* } */
534 }
535 printf ("\n");
536 }
537 }
538 printf ("}\n\n");
539}
540
541
492/*** Loading language library */ 542/*** Loading language library */
493 543
494/* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */ 544/* Translate a symbol treesit-<lang> to a C name treesit_<lang>. */
@@ -1002,6 +1052,48 @@ treesit_sync_visible_region (Lisp_Object parser)
1002 1052
1003 XTS_PARSER (parser)->visible_beg = visible_beg; 1053 XTS_PARSER (parser)->visible_beg = visible_beg;
1004 XTS_PARSER (parser)->visible_end = visible_end; 1054 XTS_PARSER (parser)->visible_end = visible_end;
1055
1056 /* Fix ranges so that the ranges stays with in visible_end. Here we
1057 try to do minimal work so that the ranges is minimally correct such
1058 that there's no OOB error. Usually treesit-update-ranges should
1059 update the parser with actually correct ranges. */
1060 if (NILP (XTS_PARSER (parser)->last_set_ranges)) return;
1061 uint32_t len;
1062 const TSRange *ranges
1063 = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len);
1064 /* We might need to discard some ranges that exceeds visible_end, in
1065 that case, new_len is the length of the new ranges array (which
1066 will be shorter than len). */
1067 uint32_t new_len = 0;
1068 uint32_t new_end = 0;
1069 for (int idx = 0; idx < len; idx++)
1070 {
1071 TSRange range = ranges[idx];
1072 /* If this range starts after visible_end, we don't include this
1073 range and the ranges after it in the new ranges. */
1074 if (range.start_byte + visible_beg >= visible_end)
1075 break;
1076 /* If this range's end is after visible_end, we don't include any
1077 ranges after it, and changes the end of this range to
1078 visible_end. */
1079 if (range.end_byte + visible_beg > visible_end)
1080 {
1081 new_end = visible_end - visible_beg;
1082 new_len++;
1083 break;
1084 }
1085 new_len++;
1086 }
1087 if (new_len != len || new_end != 0)
1088 {
1089 TSRange *new_ranges = xmalloc (sizeof (TSRange) * new_len);
1090 memcpy (new_ranges, ranges, sizeof (TSRange) * new_len);
1091 new_ranges[new_len - 1].end_byte = new_end;
1092 /* TODO: What should we do if this fails? */
1093 ts_parser_set_included_ranges (XTS_PARSER (parser)->parser,
1094 new_ranges, new_len);
1095 xfree (new_ranges);
1096 }
1005} 1097}
1006 1098
1007static void 1099static void
@@ -1014,7 +1106,8 @@ treesit_check_buffer_size (struct buffer *buffer)
1014 make_fixnum (buffer_size_bytes)); 1106 make_fixnum (buffer_size_bytes));
1015} 1107}
1016 1108
1017static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *); 1109static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t,
1110 Lisp_Object, struct buffer *);
1018 1111
1019static void 1112static void
1020treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree, 1113treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree,
@@ -1028,7 +1121,7 @@ treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree,
1028 { 1121 {
1029 uint32_t len; 1122 uint32_t len;
1030 TSRange *ranges = ts_tree_get_changed_ranges (old_tree, new_tree, &len); 1123 TSRange *ranges = ts_tree_get_changed_ranges (old_tree, new_tree, &len);
1031 lisp_ranges = treesit_make_ranges (ranges, len, buf); 1124 lisp_ranges = treesit_make_ranges (ranges, len, parser, buf);
1032 xfree (ranges); 1125 xfree (ranges);
1033 } 1126 }
1034 else 1127 else
@@ -1055,6 +1148,9 @@ treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree,
1055static void 1148static void
1056treesit_ensure_parsed (Lisp_Object parser) 1149treesit_ensure_parsed (Lisp_Object parser)
1057{ 1150{
1151 if (XTS_PARSER (parser)->within_reparse) return;
1152 XTS_PARSER (parser)->within_reparse = true;
1153
1058 struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); 1154 struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer);
1059 1155
1060 /* Before we parse, catch up with the narrowing situation. */ 1156 /* Before we parse, catch up with the narrowing situation. */
@@ -1063,10 +1159,11 @@ treesit_ensure_parsed (Lisp_Object parser)
1063 because it might set the flag to true. */ 1159 because it might set the flag to true. */
1064 treesit_sync_visible_region (parser); 1160 treesit_sync_visible_region (parser);
1065 1161
1066 /* Make sure this comes before everything else, see comment
1067 (ref:notifier-inside-ensure-parsed) for more detail. */
1068 if (!XTS_PARSER (parser)->need_reparse) 1162 if (!XTS_PARSER (parser)->need_reparse)
1069 return; 1163 {
1164 XTS_PARSER (parser)->within_reparse = false;
1165 return;
1166 }
1070 1167
1071 TSParser *treesit_parser = XTS_PARSER (parser)->parser; 1168 TSParser *treesit_parser = XTS_PARSER (parser)->parser;
1072 TSTree *tree = XTS_PARSER (parser)->tree; 1169 TSTree *tree = XTS_PARSER (parser)->tree;
@@ -1091,14 +1188,10 @@ treesit_ensure_parsed (Lisp_Object parser)
1091 XTS_PARSER (parser)->need_reparse = false; 1188 XTS_PARSER (parser)->need_reparse = false;
1092 XTS_PARSER (parser)->timestamp++; 1189 XTS_PARSER (parser)->timestamp++;
1093 1190
1094 /* After-change functions should run at the very end, most crucially
1095 after need_reparse is set to false, this way if the function
1096 calls some tree-sitter function which invokes
1097 treesit_ensure_parsed again, it returns early and do not
1098 recursively call the after change functions again.
1099 (ref:notifier-inside-ensure-parsed) */
1100 treesit_call_after_change_functions (tree, new_tree, parser); 1191 treesit_call_after_change_functions (tree, new_tree, parser);
1101 ts_tree_delete (tree); 1192 ts_tree_delete (tree);
1193
1194 XTS_PARSER (parser)->within_reparse = false;
1102} 1195}
1103 1196
1104/* This is the read function provided to tree-sitter to read from a 1197/* This is the read function provided to tree-sitter to read from a
@@ -1139,11 +1232,13 @@ treesit_read_buffer (void *parser, uint32_t byte_index,
1139 beg = NULL; 1232 beg = NULL;
1140 len = 0; 1233 len = 0;
1141 } 1234 }
1142 /* Normal case, read a character. */ 1235 /* Normal case, read until the gap or visible end. */
1143 else 1236 else
1144 { 1237 {
1145 beg = (char *) BUF_BYTE_ADDRESS (buffer, byte_pos); 1238 beg = (char *) BUF_BYTE_ADDRESS (buffer, byte_pos);
1146 len = BYTES_BY_CHAR_HEAD ((int) *beg); 1239 ptrdiff_t gap_bytepos = BUF_GPT_BYTE (buffer);
1240 len = (byte_pos < gap_bytepos)
1241 ? gap_bytepos - byte_pos : visible_end - byte_pos;
1147 } 1242 }
1148 /* We never let tree-sitter to parse buffers that large so this 1243 /* We never let tree-sitter to parse buffers that large so this
1149 assertion should never hit. */ 1244 assertion should never hit. */
@@ -1182,6 +1277,7 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser,
1182 lisp_parser->timestamp = 0; 1277 lisp_parser->timestamp = 0;
1183 lisp_parser->deleted = false; 1278 lisp_parser->deleted = false;
1184 lisp_parser->need_to_gc_buffer = false; 1279 lisp_parser->need_to_gc_buffer = false;
1280 lisp_parser->within_reparse = false;
1185 eassert (lisp_parser->visible_beg <= lisp_parser->visible_end); 1281 eassert (lisp_parser->visible_beg <= lisp_parser->visible_end);
1186 return make_lisp_ptr (lisp_parser, Lisp_Vectorlike); 1282 return make_lisp_ptr (lisp_parser, Lisp_Vectorlike);
1187} 1283}
@@ -1671,14 +1767,14 @@ treesit_check_range_argument (Lisp_Object ranges)
1671 convert between tree-sitter buffer offset and buffer position. */ 1767 convert between tree-sitter buffer offset and buffer position. */
1672static Lisp_Object 1768static Lisp_Object
1673treesit_make_ranges (const TSRange *ranges, uint32_t len, 1769treesit_make_ranges (const TSRange *ranges, uint32_t len,
1674 struct buffer *buffer) 1770 Lisp_Object parser, struct buffer *buffer)
1675{ 1771{
1676 Lisp_Object list = Qnil; 1772 Lisp_Object list = Qnil;
1677 for (int idx = 0; idx < len; idx++) 1773 for (int idx = 0; idx < len; idx++)
1678 { 1774 {
1679 TSRange range = ranges[idx]; 1775 TSRange range = ranges[idx];
1680 uint32_t beg_byte = range.start_byte + BUF_BEGV_BYTE (buffer); 1776 uint32_t beg_byte = range.start_byte + XTS_PARSER (parser)->visible_beg;
1681 uint32_t end_byte = range.end_byte + BUF_BEGV_BYTE (buffer); 1777 uint32_t end_byte = range.end_byte + XTS_PARSER (parser)->visible_beg;
1682 eassert (BUF_BEGV_BYTE (buffer) <= beg_byte); 1778 eassert (BUF_BEGV_BYTE (buffer) <= beg_byte);
1683 eassert (beg_byte <= end_byte); 1779 eassert (beg_byte <= end_byte);
1684 eassert (end_byte <= BUF_ZV_BYTE (buffer)); 1780 eassert (end_byte <= BUF_ZV_BYTE (buffer));
@@ -1724,11 +1820,9 @@ buffer. */)
1724 if (NILP (ranges)) 1820 if (NILP (ranges))
1725 { 1821 {
1726 /* If RANGES is nil, make parser to parse the whole document. 1822 /* If RANGES is nil, make parser to parse the whole document.
1727 To do that we give tree-sitter a 0 length, the range is a 1823 To do that we give tree-sitter a 0 length. */
1728 dummy. */
1729 TSRange treesit_range = {{0, 0}, {0, 0}, 0, 0};
1730 success = ts_parser_set_included_ranges (XTS_PARSER (parser)->parser, 1824 success = ts_parser_set_included_ranges (XTS_PARSER (parser)->parser,
1731 &treesit_range , 0); 1825 NULL , 0);
1732 } 1826 }
1733 else 1827 else
1734 { 1828 {
@@ -1741,7 +1835,6 @@ buffer. */)
1741 1835
1742 /* We can use XFIXNUM, XCAR, XCDR freely because we have checked 1836 /* We can use XFIXNUM, XCAR, XCDR freely because we have checked
1743 the input by treesit_check_range_argument. */ 1837 the input by treesit_check_range_argument. */
1744
1745 for (int idx = 0; !NILP (ranges); idx++, ranges = XCDR (ranges)) 1838 for (int idx = 0; !NILP (ranges); idx++, ranges = XCDR (ranges))
1746 { 1839 {
1747 Lisp_Object range = XCAR (ranges); 1840 Lisp_Object range = XCAR (ranges);
@@ -1786,6 +1879,10 @@ See also `treesit-parser-set-included-ranges'. */)
1786 treesit_check_parser (parser); 1879 treesit_check_parser (parser);
1787 treesit_initialize (); 1880 treesit_initialize ();
1788 1881
1882 /* Our return value depends on the buffer state (BUF_BEGV_BYTE,
1883 etc), so we need to sync up. */
1884 treesit_check_buffer_size (XBUFFER (XTS_PARSER (parser)->buffer));
1885 treesit_sync_visible_region (parser);
1789 /* When the parser doesn't have a range set and we call 1886 /* When the parser doesn't have a range set and we call
1790 ts_parser_included_ranges on it, it doesn't return an empty list, 1887 ts_parser_included_ranges on it, it doesn't return an empty list,
1791 but rather return DEFAULT_RANGE. (A single range where start_byte 1888 but rather return DEFAULT_RANGE. (A single range where start_byte
@@ -1798,13 +1895,10 @@ See also `treesit-parser-set-included-ranges'. */)
1798 const TSRange *ranges 1895 const TSRange *ranges
1799 = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len); 1896 = ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len);
1800 1897
1801 /* Our return value depends on the buffer state (BUF_BEGV_BYTE,
1802 etc), so we need to sync up. */
1803 treesit_check_buffer_size (XBUFFER (XTS_PARSER (parser)->buffer));
1804 treesit_sync_visible_region (parser);
1805
1806 struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer); 1898 struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer);
1807 return treesit_make_ranges (ranges, len, buffer); 1899
1900
1901 return treesit_make_ranges (ranges, len, parser, buffer);
1808} 1902}
1809 1903
1810DEFUN ("treesit-parser-notifiers", Ftreesit_parser_notifiers, 1904DEFUN ("treesit-parser-notifiers", Ftreesit_parser_notifiers,
diff --git a/src/treesit.h b/src/treesit.h
index cd84fa358c5..40b8b531ac4 100644
--- a/src/treesit.h
+++ b/src/treesit.h
@@ -45,9 +45,12 @@ struct Lisp_TS_Parser
45 same tag. A tag is primarily used to differentiate between 45 same tag. A tag is primarily used to differentiate between
46 parsers for the same language. */ 46 parsers for the same language. */
47 Lisp_Object tag; 47 Lisp_Object tag;
48 /* The Lisp ranges last set. This is use to compare to the new 48 /* The Lisp ranges last set. This is use to compare to the new ranges
49 ranges the users wants to set, and avoid reparse if the new 49 the users wants to set, and avoid reparse if the new ranges is the
50 ranges is the same as the last set one. */ 50 same as the last set one. This might go out of sync with the
51 ranges we return from Ftreesit_parser_included_ranges, if we did a
52 ranges fix in treesit_sync_visible_region, but I don't think
53 that'll cause any harm. */
51 Lisp_Object last_set_ranges; 54 Lisp_Object last_set_ranges;
52 /* The buffer associated with this parser. */ 55 /* The buffer associated with this parser. */
53 Lisp_Object buffer; 56 Lisp_Object buffer;
diff --git a/src/w32uniscribe.c b/src/w32uniscribe.c
index 751963705d2..b77bf56b8cf 100644
--- a/src/w32uniscribe.c
+++ b/src/w32uniscribe.c
@@ -1573,9 +1573,9 @@ syms_of_w32uniscribe_for_pdumper (void)
1573 pfnScriptGetGlyphABCWidth = &ScriptGetGlyphABCWidth; 1573 pfnScriptGetGlyphABCWidth = &ScriptGetGlyphABCWidth;
1574 pfnScriptFreeCache = &ScriptFreeCache; 1574 pfnScriptFreeCache = &ScriptFreeCache;
1575 pfnScriptGetCMap = &ScriptGetCMap; 1575 pfnScriptGetCMap = &ScriptGetCMap;
1576#endif /* Cygwin */
1576 1577
1577 uniscribe_available = 1; 1578 uniscribe_available = 1;
1578#endif /* Cygwin */
1579 1579
1580 register_font_driver (&uniscribe_font_driver, NULL); 1580 register_font_driver (&uniscribe_font_driver, NULL);
1581 1581
diff --git a/src/xdisp.c b/src/xdisp.c
index 18834c6b781..7883c579815 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11869,7 +11869,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
11869} 11869}
11870 11870
11871DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0, 11871DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0,
11872 doc: /* Return the size of the text of WINDOW's buffer in pixels. 11872 doc: /* Return the dimensions of the text of WINDOW's buffer in pixels.
11873WINDOW must be a live window and defaults to the selected one. The 11873WINDOW must be a live window and defaults to the selected one. The
11874return value is a cons of the maximum pixel-width of any text line and 11874return value is a cons of the maximum pixel-width of any text line and
11875the pixel-height of all the text lines in the accessible portion of 11875the pixel-height of all the text lines in the accessible portion of
@@ -11949,7 +11949,7 @@ screen line that includes TO to the returned height of the text. */)
11949} 11949}
11950 11950
11951DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_size, 0, 4, 0, 11951DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_size, 0, 4, 0,
11952 doc: /* Return size of whole text of BUFFER-OR-NAME in WINDOW. 11952 doc: /* Return the dimensions of whole text of BUFFER-OR-NAME in WINDOW.
11953BUFFER-OR-NAME must specify a live buffer or the name of a live buffer 11953BUFFER-OR-NAME must specify a live buffer or the name of a live buffer
11954and defaults to the current buffer. WINDOW must be a live window and 11954and defaults to the current buffer. WINDOW must be a live window and
11955defaults to the selected one. The return value is a cons of the maximum 11955defaults to the selected one. The return value is a cons of the maximum
@@ -22182,7 +22182,8 @@ try_window_id (struct window *w)
22182 22182
22183 /* Window must either use window-based redisplay or be full width. */ 22183 /* Window must either use window-based redisplay or be full width. */
22184 if (!FRAME_WINDOW_P (f) 22184 if (!FRAME_WINDOW_P (f)
22185 && (!FRAME_LINE_INS_DEL_OK (f) 22185 && (FRAME_INITIAL_P (f)
22186 || !FRAME_LINE_INS_DEL_OK (f)
22186 || !WINDOW_FULL_WIDTH_P (w))) 22187 || !WINDOW_FULL_WIDTH_P (w)))
22187 GIVE_UP (4); 22188 GIVE_UP (4);
22188 22189
diff --git a/test/lisp/progmodes/eglot-tests.el b/test/lisp/progmodes/eglot-tests.el
index c0e30172482..eaef990d5ea 100644
--- a/test/lisp/progmodes/eglot-tests.el
+++ b/test/lisp/progmodes/eglot-tests.el
@@ -136,9 +136,11 @@ directory hierarchy."
136 (jsonrpc-events-buffer server))))) 136 (jsonrpc-events-buffer server)))))
137 (cond (noninteractive 137 (cond (noninteractive
138 (dolist (buffer buffers) 138 (dolist (buffer buffers)
139 (eglot--test-message "contents of `%s':" (buffer-name buffer)) 139 (eglot--test-message "contents of `%s' %S:" (buffer-name buffer) buffer)
140 (princ (with-current-buffer buffer (buffer-string)) 140 (if (buffer-live-p buffer)
141 'external-debugging-output))) 141 (princ (with-current-buffer buffer (buffer-string))
142 'external-debugging-output)
143 (princ "Killed\n" #'external-debugging-output))))
142 (t 144 (t
143 (eglot--test-message "Preserved for inspection: %s" 145 (eglot--test-message "Preserved for inspection: %s"
144 (mapconcat #'buffer-name buffers ", ")))))))) 146 (mapconcat #'buffer-name buffers ", "))))))))
@@ -724,7 +726,7 @@ directory hierarchy."
724 (minibuffer-choose-completion t)) 726 (minibuffer-choose-completion t))
725 (should 727 (should
726 (equal 728 (equal
727 "fn test() -> i32 { let v: usize = 1; v.count_ones().1234567890;" 729 "fn test() -> i32 { let v: usize = 1; v.count_ones.1234567890;"
728 (buffer-string)))))) 730 (buffer-string))))))
729 731
730(ert-deftest eglot-test-basic-xref () 732(ert-deftest eglot-test-basic-xref ()
diff --git a/test/src/json-tests.el b/test/src/json-tests.el
index ebac70fb1c7..1d7491a4593 100644
--- a/test/src/json-tests.el
+++ b/test/src/json-tests.el
@@ -36,7 +36,7 @@
36 (json 36 (json
37 "[null,false,true,0,123,-456,3.75,\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\"]") 37 "[null,false,true,0,123,-456,3.75,\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\"]")
38 (json-bytes (encode-coding-string json 'utf-8))) 38 (json-bytes (encode-coding-string json 'utf-8)))
39 (should (equal (json-serialize lisp) json)) ; or `json-bytes'? 39 (should (equal (json-serialize lisp) json-bytes))
40 (with-temp-buffer 40 (with-temp-buffer
41 ;; multibyte buffer 41 ;; multibyte buffer
42 (json-insert lisp) 42 (json-insert lisp)
@@ -82,28 +82,29 @@
82 "\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\""))) 82 "\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\"")))
83 (cl-destructuring-bind (lisp json) case 83 (cl-destructuring-bind (lisp json) case
84 (ert-info ((format "%S ↔ %S" lisp json)) 84 (ert-info ((format "%S ↔ %S" lisp json))
85 (should (equal (json-serialize lisp) json)) 85 (let ((json-bytes (encode-coding-string json 'utf-8)))
86 (with-temp-buffer 86 (should (equal (json-serialize lisp) json-bytes))
87 (json-insert lisp) 87 (with-temp-buffer
88 (should (equal (buffer-string) json)) 88 (json-insert lisp)
89 (should (eobp))) 89 (should (equal (buffer-string) json))
90 (with-temp-buffer 90 (should (eobp)))
91 (set-buffer-multibyte nil) 91 (with-temp-buffer
92 (json-insert lisp) 92 (set-buffer-multibyte nil)
93 (should (equal (buffer-string) (encode-coding-string json 'utf-8))) 93 (json-insert lisp)
94 (should (eobp))) 94 (should (equal (buffer-string) (encode-coding-string json 'utf-8)))
95 (should (equal (json-parse-string json) lisp)) 95 (should (eobp)))
96 (with-temp-buffer 96 (should (equal (json-parse-string json) lisp))
97 (insert json) 97 (with-temp-buffer
98 (goto-char 1) 98 (insert json)
99 (should (equal (json-parse-buffer) lisp)) 99 (goto-char 1)
100 (should (eobp))) 100 (should (equal (json-parse-buffer) lisp))
101 (with-temp-buffer 101 (should (eobp)))
102 (set-buffer-multibyte nil) 102 (with-temp-buffer
103 (insert (encode-coding-string json 'utf-8)) 103 (set-buffer-multibyte nil)
104 (goto-char 1) 104 (insert (encode-coding-string json 'utf-8))
105 (should (equal (json-parse-buffer) lisp)) 105 (goto-char 1)
106 (should (eobp))))))) 106 (should (equal (json-parse-buffer) lisp))
107 (should (eobp))))))))
107 108
108(ert-deftest json-serialize/object () 109(ert-deftest json-serialize/object ()
109 (let ((table (make-hash-table :test #'equal))) 110 (let ((table (make-hash-table :test #'equal)))
@@ -226,7 +227,8 @@
226 (should (equal (json-serialize ["foo"]) "[\"foo\"]")) 227 (should (equal (json-serialize ["foo"]) "[\"foo\"]"))
227 (should (equal (json-serialize ["a\n\fb"]) "[\"a\\n\\fb\"]")) 228 (should (equal (json-serialize ["a\n\fb"]) "[\"a\\n\\fb\"]"))
228 (should (equal (json-serialize ["\nasdфыв\u001f\u007ffgh\t"]) 229 (should (equal (json-serialize ["\nasdфыв\u001f\u007ffgh\t"])
229 "[\"\\nasdфыв\\u001F\u007ffgh\\t\"]")) 230 (encode-coding-string "[\"\\nasdфыв\\u001F\u007ffgh\\t\"]"
231 'utf-8)))
230 (should (equal (json-serialize ["a\0b"]) "[\"a\\u0000b\"]")) 232 (should (equal (json-serialize ["a\0b"]) "[\"a\\u0000b\"]"))
231 (should-error (json-serialize ["\xC3\x84"])) 233 (should-error (json-serialize ["\xC3\x84"]))
232 (should-error (json-serialize ["\u00C4\xC3\x84"]))) 234 (should-error (json-serialize ["\u00C4\xC3\x84"])))