Merge from savannah/emacs-30

ee3e3a6311 ; Update version number of exec/configure.ac
c5925b6ba5 Fix heex-ts-mode indentation following previews elixir-mo...
c3383be5f0 ; * admin/make-tarball.txt: Improve last change.
8ddb54117f ; * admin/make-tarball.txt: Remove now unnecessary config...
7e194d33f9 * lisp/ldefs-boot.el: Update.
9019536ea6 Fix use of Uniscribe font driver in MinGW build
5c55c860db Avoid crashes in redisplay in batch-mode testing
ba2190e1ae ; * etc/NEWS: Fix indentation.
818c0cc9a5 eglot-test-rust-completion-exit-function: Fix failure in ...
f47297782b ; * doc/lispref/searching.texi (Rx Notation): Simplify rx...
03e5698167 Clarify the semantics of 'string-pixel-width'
9f0603207b ; * src/treesit.c: Minor cleanups of recent changes.
e0d3f74395 * src/treesit.c (treesit_debug_print_parser_list): Fix fo...
bed38ded73 ; * src/treesit.c (treesit_debug_print_parser_list): Fix ...
18c6487dbd ; * src/treesit.c: Add a prototype so there's no warning ...
bf23382f1f Read more on each call to treesit's buffer reader
3435464452 Fix the range handling in treesit.c
3fcec09f75 Add debugging function for treesit.c
0fd259d166 Fix elixir-ts-mode's range query
2329b36b1f ; project-files-relative-names: Update docstring (bug#72701)
e55e2e1c6b Make json-serialize always return a unibyte string (bug#7...
89c99891b2 ; * doc/lispref/os.texi (Suspending Emacs): Fix last change.
4f044d0d3d ; Improve documentation of 'suspend-emacs'
This commit is contained in:
Po Lu 2024-09-11 13:21:58 +08:00
commit 76487b7454
20 changed files with 223 additions and 105 deletions

View file

@ -112,6 +112,10 @@ Root must be the root of an Emacs source tree."
(rx (and "AC_INIT" (1+ (not (in ?,)))
?, (0+ space) ?\[
(submatch (1+ (in "0-9."))))))
(set-version-in-file root "exec/configure.ac" version
(rx (and "AC_INIT" (1+ (not (in ?,)))
?, (0+ space) ?\[
(submatch (1+ (in "0-9."))))))
(set-version-in-file root "nt/README.W32" version
(rx (and "version" (1+ space)
(submatch (1+ (in "0-9."))))))

View file

@ -55,14 +55,8 @@ General steps (for each step, check for possible errors):
because some of the commands below run Make, so they need
Makefiles to be present.
For Emacs 28 and later, as long as --with-native-compilation is
not the default, the tree needs to be configured with
native-compilation enabled, to ensure all the pertinent *.elc
files will end up in the tarball. Otherwise, the *.eln files
might not build correctly on the user's system.
./autogen.sh
./configure --with-native-compilation && make
./configure --without-native-compilation && make
For a release (as opposed to pretest), visit etc/NEWS and use the
"M-x emacs-news-delete-temporary-markers" command to delete any

View file

@ -2238,7 +2238,7 @@ displayed in a given window. This function is used by
it contains.
@defun window-text-pixel-size &optional window from to x-limit y-limit mode-lines ignore-line-at-end
This function returns the size of the text of @var{window}'s buffer in
This function returns the dimensions of the text of @var{window}'s buffer in
pixels. @var{window} must be a live window and defaults to the
selected one. The return value is a cons of the maximum pixel-width
of 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}.
@defun string-pixel-width string &optional buffer
This is a convenience function that uses @code{window-text-pixel-size}
to compute the width of @var{string} (in pixels). If @var{buffer} is
to compute the width of @var{string} (in pixels). Caveat: if you call
this function to measure the width of a string with embedded newlines,
it will then return the width of the widest substring that does not
include newlines. The meaning of this result is the widest line taken
by the string if inserted into a buffer. If @var{buffer} is
non-@code{nil}, use any face remappings (@pxref{Face Remapping}) from
that buffer when computing the width of @var{string}.
@end defun

View file

@ -811,9 +811,6 @@ before suspending Emacs, or this function signals an error.
If @var{string} is non-@code{nil}, its characters are sent to Emacs's
superior shell, to be read as terminal input.
@c FIXME? It seems to me that shell does echo STRING.
The characters in @var{string} are not echoed by the superior shell;
only the results appear.
Before suspending, @code{suspend-emacs} runs the normal hook
@code{suspend-hook}. After the user resumes Emacs,
@ -849,7 +846,8 @@ Really suspend? @kbd{y}
@group
---------- Parent Shell ----------
bash$ /home/username
bash$ pwd
/home/username
bash$ fg
@end group
@ -859,9 +857,13 @@ Resumed!
@end group
@end smallexample
@c FIXME? AFAICS, it is echoed.
Note that @samp{pwd} is not echoed after Emacs is suspended. But it
is read and executed by the shell.
Note that on some operating systems, sending @var{string} to the Emacs
parent shell might require special privileges, in which case it might
silently fail to send @var{string} to the shell for execution. On other
systems this is not supported, and Emacs will signal an error if you
try. Also, @var{string} might not be echoed, even if it is executed by
the shell. So we don't recommend relying on this feature in portable
Lisp programs.
@end deffn
@defvar suspend-hook

View file

@ -1028,13 +1028,13 @@ programming language:
@example
@group
(rx "/*" ; Initial /*
(rx "/*" ; Initial /*
(zero-or-more
(or (not (any "*")) ; Either non-*,
(seq "*" ; or * followed by
(not (any "/"))))) ; non-/
(one-or-more "*") ; At least one star,
"/") ; and the final /
(or (not "*") ; Either non-*,
(seq "*" ; or * followed by
(not "/")))) ; non-/
(one-or-more "*") ; At least one star,
"/") ; and the final /
@end group
@end example

View file

@ -5844,7 +5844,7 @@ can be serialized to JSON@. Likewise, the parsing functions will
return any of the possible types described above.
@defun json-serialize object &rest args
This function returns a new Lisp string which contains the JSON
This function returns a new Lisp unibyte string which contains the JSON
representation of @var{object}. The argument @var{args} is a list of
keyword/argument pairs. The following keywords are accepted:

View file

@ -3071,6 +3071,13 @@ entire SQL file.
** JSON
+++
*** 'json-serialize' now always returns a unibyte string.
This is appropriate since it is an encoding operation. In the unlikely
event that a multibyte string is needed, the result can be decoded using
(decode-coding-string RESULT 'utf-8)
---
*** The parser keeps duplicated object keys in alist and plist output.
A JSON object such as '{"a":1,"a":2}' will now be translated into the

View file

@ -22,7 +22,7 @@ dnl You should have received a copy of the GNU General Public License
dnl along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
AC_PREREQ([2.65])
AC_INIT([libexec], [30.0.50], [bug-gnu-emacs@gnu.org], [],
AC_INIT([libexec], [30.0.90], [bug-gnu-emacs@gnu.org], [],
[https://www.gnu.org/software/emacs/])
AH_TOP([/* Copyright (C) 2024 Free Software Foundation, Inc.

View file

@ -387,7 +387,10 @@ buffer when possible, instead of creating a new one on each call."
(defun string-pixel-width (string &optional buffer)
"Return the width of STRING in pixels.
If BUFFER is non-nil, use the face remappings from that buffer when
determining the width."
determining the width.
If you call this function to measure pixel width of a string
with embedded newlines, it returns the width of the widest
substring that does not include newlines."
(declare (important-return-value t))
(if (zerop (length string))
0

View file

@ -572,7 +572,9 @@
(treesit-range-rules
:embed 'heex
:host 'elixir
'((sigil (sigil_name) @name (:match "^[HF]$" @name) (quoted_content) @heex)))))
'((sigil (sigil_name) @_name
(:match "^[HF]$" @_name)
(quoted_content) @heex)))))
(defvar heex-ts--sexp-regexp)
(defvar heex-ts--indent-rules)

View file

@ -64,16 +64,18 @@
(let ((offset heex-ts-indent-offset))
`((heex
((parent-is "fragment")
(lambda (node parent &rest _)
(lambda (_node _parent bol &rest _)
;; If HEEx is embedded indent to parent
;; otherwise indent to the bol.
(if (eq (treesit-language-at (point-min)) 'heex)
(point-min)
(save-excursion
(goto-char (treesit-node-start parent))
(goto-char (treesit-node-start
(treesit-node-at bol 'elixir)))
(back-to-indentation)
(point))
)) 0)
))
0)
((node-is "end_tag") parent-bol 0)
((node-is "end_component") parent-bol 0)
((node-is "end_slot") parent-bol 0)

View file

@ -331,7 +331,10 @@ end it with `/'. DIR must be either `project-root' or one of
The file names should be relative to the project root. And this can
only happen when all returned files are in the same directory.
In other words, the DIRS argument of `project-files' has to be nil or a
list of only one element.")
list of only one element.
This variable is only meant to be set by Lisp code, not customized by
the user.")
(cl-defgeneric project-files (project &optional dirs)
"Return a list of files in directories DIRS in PROJECT.

View file

@ -559,16 +559,6 @@ json_out_something (json_out_t *jo, Lisp_Object obj)
wrong_type_argument (Qjson_value_p, obj);
}
static Lisp_Object
json_out_to_string (json_out_t *jo)
{
/* FIXME: should this be a unibyte or multibyte string?
Right now we make a multibyte string for test compatibility,
but we are really encoding so unibyte would make more sense. */
ptrdiff_t nchars = jo->size - jo->chars_delta;
return make_multibyte_string (jo->buf, nchars, jo->size);
}
static void
json_serialize (json_out_t *jo, Lisp_Object object,
ptrdiff_t nargs, Lisp_Object *args)
@ -596,7 +586,7 @@ json_serialize (json_out_t *jo, Lisp_Object object,
DEFUN ("json-serialize", Fjson_serialize, Sjson_serialize, 1, MANY,
NULL,
doc: /* Return the JSON representation of OBJECT as a string.
doc: /* Return the JSON representation of OBJECT as a unibyte string.
OBJECT is translated as follows:
@ -629,7 +619,7 @@ usage: (json-serialize OBJECT &rest ARGS) */)
specpdl_ref count = SPECPDL_INDEX ();
json_out_t jo;
json_serialize (&jo, args[0], nargs - 1, args + 1);
return unbind_to (count, json_out_to_string (&jo));
return unbind_to (count, make_unibyte_string (jo.buf, jo.size));
}
DEFUN ("json-insert", Fjson_insert, Sjson_insert, 1, MANY,

View file

@ -11917,7 +11917,12 @@ Before suspending, run the normal hook `suspend-hook'.
After resumption run the normal hook `suspend-resume-hook'.
Some operating systems cannot stop the Emacs process and resume it later.
On such systems, Emacs starts a subshell instead of suspending. */)
On such systems, Emacs starts a subshell instead of suspending.
On some operating systems, stuffing characters into terminal input
buffer requires special privileges or is not supported at all.
On such systems, calling this function with non-nil STUFFSTRING might
either signal an error or silently fail to stuff the characters. */)
(Lisp_Object stuffstring)
{
specpdl_ref count = SPECPDL_INDEX ();

View file

@ -488,6 +488,56 @@ treesit_initialize (void)
}
}
/*** Debugging */
void treesit_debug_print_parser_list (char *, Lisp_Object);
void
treesit_debug_print_parser_list (char *msg, Lisp_Object parser)
{
struct buffer *buf = XBUFFER (XTS_PARSER (parser)->buffer);
char *buf_name = SSDATA (BVAR (buf, name));
printf ("%s (%s) [%s] <%s>: %ld(%ld)-(%ld)%ld {\n",
msg == NULL ? "" : msg,
SSDATA (SYMBOL_NAME (Vthis_command)),
SSDATA (SYMBOL_NAME (XTS_PARSER (parser)->language_symbol)),
buf_name, BUF_BEG (buf),
BUF_BEGV (buf), BUF_Z (buf), BUF_ZV (buf));
Lisp_Object tail = BVAR (buf, ts_parser_list);
FOR_EACH_TAIL (tail)
{
struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail));
printf ("[%s %s %s %ld-%ld T:%ld]\n", SSDATA (SYMBOL_NAME (parser->language_symbol)),
SSDATA (SYMBOL_NAME (parser->tag)),
parser->need_reparse ? "NEED-R" : "NONEED",
parser->visible_beg, parser->visible_end,
parser->timestamp);
/* Print ranges. */
uint32_t len;
const TSRange *ranges
= ts_parser_included_ranges (parser->parser, &len);
if (!(len == 1 && ranges[0].start_byte == 0 && ranges[0].end_byte == -1))
{
for (int idx = 0; idx < len; idx++)
{
TSRange range = ranges[idx];
printf (" [%"PRIu32", %"PRIu32")", range.start_byte, range.end_byte);
/* if (!parser->need_reparse) */
/* { */
/* eassert (BUF_BEGV_BYTE (buf) <= range.start_byte + parser->visible_beg); */
/* eassert (range.end_byte + parser->visible_beg <= BUF_ZV_BYTE (buf)); */
/* } */
}
printf ("\n");
}
}
printf ("}\n\n");
}
/*** Loading language library */
@ -1002,6 +1052,48 @@ treesit_sync_visible_region (Lisp_Object parser)
XTS_PARSER (parser)->visible_beg = visible_beg;
XTS_PARSER (parser)->visible_end = visible_end;
/* Fix ranges so that the ranges stays with in visible_end. Here we
try to do minimal work so that the ranges is minimally correct such
that there's no OOB error. Usually treesit-update-ranges should
update the parser with actually correct ranges. */
if (NILP (XTS_PARSER (parser)->last_set_ranges)) return;
uint32_t len;
const TSRange *ranges
= ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len);
/* We might need to discard some ranges that exceeds visible_end, in
that case, new_len is the length of the new ranges array (which
will be shorter than len). */
uint32_t new_len = 0;
uint32_t new_end = 0;
for (int idx = 0; idx < len; idx++)
{
TSRange range = ranges[idx];
/* If this range starts after visible_end, we don't include this
range and the ranges after it in the new ranges. */
if (range.start_byte + visible_beg >= visible_end)
break;
/* If this range's end is after visible_end, we don't include any
ranges after it, and changes the end of this range to
visible_end. */
if (range.end_byte + visible_beg > visible_end)
{
new_end = visible_end - visible_beg;
new_len++;
break;
}
new_len++;
}
if (new_len != len || new_end != 0)
{
TSRange *new_ranges = xmalloc (sizeof (TSRange) * new_len);
memcpy (new_ranges, ranges, sizeof (TSRange) * new_len);
new_ranges[new_len - 1].end_byte = new_end;
/* TODO: What should we do if this fails? */
ts_parser_set_included_ranges (XTS_PARSER (parser)->parser,
new_ranges, new_len);
xfree (new_ranges);
}
}
static void
@ -1014,7 +1106,8 @@ treesit_check_buffer_size (struct buffer *buffer)
make_fixnum (buffer_size_bytes));
}
static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t, struct buffer *);
static Lisp_Object treesit_make_ranges (const TSRange *, uint32_t,
Lisp_Object, struct buffer *);
static void
treesit_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,
{
uint32_t len;
TSRange *ranges = ts_tree_get_changed_ranges (old_tree, new_tree, &len);
lisp_ranges = treesit_make_ranges (ranges, len, buf);
lisp_ranges = treesit_make_ranges (ranges, len, parser, buf);
xfree (ranges);
}
else
@ -1055,6 +1148,9 @@ treesit_call_after_change_functions (TSTree *old_tree, TSTree *new_tree,
static void
treesit_ensure_parsed (Lisp_Object parser)
{
if (XTS_PARSER (parser)->within_reparse) return;
XTS_PARSER (parser)->within_reparse = true;
struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer);
/* Before we parse, catch up with the narrowing situation. */
@ -1063,10 +1159,11 @@ treesit_ensure_parsed (Lisp_Object parser)
because it might set the flag to true. */
treesit_sync_visible_region (parser);
/* Make sure this comes before everything else, see comment
(ref:notifier-inside-ensure-parsed) for more detail. */
if (!XTS_PARSER (parser)->need_reparse)
return;
{
XTS_PARSER (parser)->within_reparse = false;
return;
}
TSParser *treesit_parser = XTS_PARSER (parser)->parser;
TSTree *tree = XTS_PARSER (parser)->tree;
@ -1091,14 +1188,10 @@ treesit_ensure_parsed (Lisp_Object parser)
XTS_PARSER (parser)->need_reparse = false;
XTS_PARSER (parser)->timestamp++;
/* After-change functions should run at the very end, most crucially
after need_reparse is set to false, this way if the function
calls some tree-sitter function which invokes
treesit_ensure_parsed again, it returns early and do not
recursively call the after change functions again.
(ref:notifier-inside-ensure-parsed) */
treesit_call_after_change_functions (tree, new_tree, parser);
ts_tree_delete (tree);
XTS_PARSER (parser)->within_reparse = false;
}
/* 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,
beg = NULL;
len = 0;
}
/* Normal case, read a character. */
/* Normal case, read until the gap or visible end. */
else
{
beg = (char *) BUF_BYTE_ADDRESS (buffer, byte_pos);
len = BYTES_BY_CHAR_HEAD ((int) *beg);
ptrdiff_t gap_bytepos = BUF_GPT_BYTE (buffer);
len = (byte_pos < gap_bytepos)
? gap_bytepos - byte_pos : visible_end - byte_pos;
}
/* We never let tree-sitter to parse buffers that large so this
assertion should never hit. */
@ -1182,6 +1277,7 @@ make_treesit_parser (Lisp_Object buffer, TSParser *parser,
lisp_parser->timestamp = 0;
lisp_parser->deleted = false;
lisp_parser->need_to_gc_buffer = false;
lisp_parser->within_reparse = false;
eassert (lisp_parser->visible_beg <= lisp_parser->visible_end);
return make_lisp_ptr (lisp_parser, Lisp_Vectorlike);
}
@ -1671,14 +1767,14 @@ treesit_check_range_argument (Lisp_Object ranges)
convert between tree-sitter buffer offset and buffer position. */
static Lisp_Object
treesit_make_ranges (const TSRange *ranges, uint32_t len,
struct buffer *buffer)
Lisp_Object parser, struct buffer *buffer)
{
Lisp_Object list = Qnil;
for (int idx = 0; idx < len; idx++)
{
TSRange range = ranges[idx];
uint32_t beg_byte = range.start_byte + BUF_BEGV_BYTE (buffer);
uint32_t end_byte = range.end_byte + BUF_BEGV_BYTE (buffer);
uint32_t beg_byte = range.start_byte + XTS_PARSER (parser)->visible_beg;
uint32_t end_byte = range.end_byte + XTS_PARSER (parser)->visible_beg;
eassert (BUF_BEGV_BYTE (buffer) <= beg_byte);
eassert (beg_byte <= end_byte);
eassert (end_byte <= BUF_ZV_BYTE (buffer));
@ -1724,11 +1820,9 @@ buffer. */)
if (NILP (ranges))
{
/* If RANGES is nil, make parser to parse the whole document.
To do that we give tree-sitter a 0 length, the range is a
dummy. */
TSRange treesit_range = {{0, 0}, {0, 0}, 0, 0};
To do that we give tree-sitter a 0 length. */
success = ts_parser_set_included_ranges (XTS_PARSER (parser)->parser,
&treesit_range , 0);
NULL , 0);
}
else
{
@ -1741,7 +1835,6 @@ buffer. */)
/* We can use XFIXNUM, XCAR, XCDR freely because we have checked
the input by treesit_check_range_argument. */
for (int idx = 0; !NILP (ranges); idx++, ranges = XCDR (ranges))
{
Lisp_Object range = XCAR (ranges);
@ -1786,6 +1879,10 @@ See also `treesit-parser-set-included-ranges'. */)
treesit_check_parser (parser);
treesit_initialize ();
/* Our return value depends on the buffer state (BUF_BEGV_BYTE,
etc), so we need to sync up. */
treesit_check_buffer_size (XBUFFER (XTS_PARSER (parser)->buffer));
treesit_sync_visible_region (parser);
/* When the parser doesn't have a range set and we call
ts_parser_included_ranges on it, it doesn't return an empty list,
but rather return DEFAULT_RANGE. (A single range where start_byte
@ -1798,13 +1895,10 @@ See also `treesit-parser-set-included-ranges'. */)
const TSRange *ranges
= ts_parser_included_ranges (XTS_PARSER (parser)->parser, &len);
/* Our return value depends on the buffer state (BUF_BEGV_BYTE,
etc), so we need to sync up. */
treesit_check_buffer_size (XBUFFER (XTS_PARSER (parser)->buffer));
treesit_sync_visible_region (parser);
struct buffer *buffer = XBUFFER (XTS_PARSER (parser)->buffer);
return treesit_make_ranges (ranges, len, buffer);
return treesit_make_ranges (ranges, len, parser, buffer);
}
DEFUN ("treesit-parser-notifiers", Ftreesit_parser_notifiers,

View file

@ -45,9 +45,12 @@ struct Lisp_TS_Parser
same tag. A tag is primarily used to differentiate between
parsers for the same language. */
Lisp_Object tag;
/* The Lisp ranges last set. This is use to compare to the new
ranges the users wants to set, and avoid reparse if the new
ranges is the same as the last set one. */
/* The Lisp ranges last set. This is use to compare to the new ranges
the users wants to set, and avoid reparse if the new ranges is the
same as the last set one. This might go out of sync with the
ranges we return from Ftreesit_parser_included_ranges, if we did a
ranges fix in treesit_sync_visible_region, but I don't think
that'll cause any harm. */
Lisp_Object last_set_ranges;
/* The buffer associated with this parser. */
Lisp_Object buffer;

View file

@ -1573,9 +1573,9 @@ syms_of_w32uniscribe_for_pdumper (void)
pfnScriptGetGlyphABCWidth = &ScriptGetGlyphABCWidth;
pfnScriptFreeCache = &ScriptFreeCache;
pfnScriptGetCMap = &ScriptGetCMap;
#endif /* Cygwin */
uniscribe_available = 1;
#endif /* Cygwin */
register_font_driver (&uniscribe_font_driver, NULL);

View file

@ -11869,7 +11869,7 @@ window_text_pixel_size (Lisp_Object window, Lisp_Object from, Lisp_Object to,
}
DEFUN ("window-text-pixel-size", Fwindow_text_pixel_size, Swindow_text_pixel_size, 0, 7, 0,
doc: /* Return the size of the text of WINDOW's buffer in pixels.
doc: /* Return the dimensions of the text of WINDOW's buffer in pixels.
WINDOW must be a live window and defaults to the selected one. The
return value is a cons of the maximum pixel-width of any text line and
the 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. */)
}
DEFUN ("buffer-text-pixel-size", Fbuffer_text_pixel_size, Sbuffer_text_pixel_size, 0, 4, 0,
doc: /* Return size of whole text of BUFFER-OR-NAME in WINDOW.
doc: /* Return the dimensions of whole text of BUFFER-OR-NAME in WINDOW.
BUFFER-OR-NAME must specify a live buffer or the name of a live buffer
and defaults to the current buffer. WINDOW must be a live window and
defaults to the selected one. The return value is a cons of the maximum
@ -22182,7 +22182,8 @@ try_window_id (struct window *w)
/* Window must either use window-based redisplay or be full width. */
if (!FRAME_WINDOW_P (f)
&& (!FRAME_LINE_INS_DEL_OK (f)
&& (FRAME_INITIAL_P (f)
|| !FRAME_LINE_INS_DEL_OK (f)
|| !WINDOW_FULL_WIDTH_P (w)))
GIVE_UP (4);

View file

@ -136,9 +136,11 @@ directory hierarchy."
(jsonrpc-events-buffer server)))))
(cond (noninteractive
(dolist (buffer buffers)
(eglot--test-message "contents of `%s':" (buffer-name buffer))
(princ (with-current-buffer buffer (buffer-string))
'external-debugging-output)))
(eglot--test-message "contents of `%s' %S:" (buffer-name buffer) buffer)
(if (buffer-live-p buffer)
(princ (with-current-buffer buffer (buffer-string))
'external-debugging-output)
(princ "Killed\n" #'external-debugging-output))))
(t
(eglot--test-message "Preserved for inspection: %s"
(mapconcat #'buffer-name buffers ", "))))))))
@ -724,7 +726,7 @@ directory hierarchy."
(minibuffer-choose-completion t))
(should
(equal
"fn test() -> i32 { let v: usize = 1; v.count_ones().1234567890;"
"fn test() -> i32 { let v: usize = 1; v.count_ones.1234567890;"
(buffer-string))))))
(ert-deftest eglot-test-basic-xref ()

View file

@ -36,7 +36,7 @@
(json
"[null,false,true,0,123,-456,3.75,\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\"]")
(json-bytes (encode-coding-string json 'utf-8)))
(should (equal (json-serialize lisp) json)) ; or `json-bytes'?
(should (equal (json-serialize lisp) json-bytes))
(with-temp-buffer
;; multibyte buffer
(json-insert lisp)
@ -82,28 +82,29 @@
"\"abc\uFFFFαβγ𝔸𝐁𝖢\\\"\\\\\"")))
(cl-destructuring-bind (lisp json) case
(ert-info ((format "%S ↔ %S" lisp json))
(should (equal (json-serialize lisp) json))
(with-temp-buffer
(json-insert lisp)
(should (equal (buffer-string) json))
(should (eobp)))
(with-temp-buffer
(set-buffer-multibyte nil)
(json-insert lisp)
(should (equal (buffer-string) (encode-coding-string json 'utf-8)))
(should (eobp)))
(should (equal (json-parse-string json) lisp))
(with-temp-buffer
(insert json)
(goto-char 1)
(should (equal (json-parse-buffer) lisp))
(should (eobp)))
(with-temp-buffer
(set-buffer-multibyte nil)
(insert (encode-coding-string json 'utf-8))
(goto-char 1)
(should (equal (json-parse-buffer) lisp))
(should (eobp)))))))
(let ((json-bytes (encode-coding-string json 'utf-8)))
(should (equal (json-serialize lisp) json-bytes))
(with-temp-buffer
(json-insert lisp)
(should (equal (buffer-string) json))
(should (eobp)))
(with-temp-buffer
(set-buffer-multibyte nil)
(json-insert lisp)
(should (equal (buffer-string) (encode-coding-string json 'utf-8)))
(should (eobp)))
(should (equal (json-parse-string json) lisp))
(with-temp-buffer
(insert json)
(goto-char 1)
(should (equal (json-parse-buffer) lisp))
(should (eobp)))
(with-temp-buffer
(set-buffer-multibyte nil)
(insert (encode-coding-string json 'utf-8))
(goto-char 1)
(should (equal (json-parse-buffer) lisp))
(should (eobp))))))))
(ert-deftest json-serialize/object ()
(let ((table (make-hash-table :test #'equal)))
@ -226,7 +227,8 @@
(should (equal (json-serialize ["foo"]) "[\"foo\"]"))
(should (equal (json-serialize ["a\n\fb"]) "[\"a\\n\\fb\"]"))
(should (equal (json-serialize ["\nasdфыв\u001f\u007ffgh\t"])
"[\"\\nasdфыв\\u001F\u007ffgh\\t\"]"))
(encode-coding-string "[\"\\nasdфыв\\u001F\u007ffgh\\t\"]"
'utf-8)))
(should (equal (json-serialize ["a\0b"]) "[\"a\\u0000b\"]"))
(should-error (json-serialize ["\xC3\x84"]))
(should-error (json-serialize ["\u00C4\xC3\x84"])))