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." (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.")))))) 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): 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 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 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 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. 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 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: @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 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 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: 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. ** 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 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 dnl along with GNU Emacs. If not, see . 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. 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." (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 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 @@ (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) 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 @@ (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) 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 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. 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) 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, 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'. 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 (); diff --git a/src/treesit.c b/src/treesit.c index 5aedca44489..0ba6c733d64 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -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, 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 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; 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) pfnScriptGetGlyphABCWidth = &ScriptGetGlyphABCWidth; pfnScriptFreeCache = &ScriptFreeCache; pfnScriptGetCMap = &ScriptGetCMap; +#endif /* Cygwin */ uniscribe_available = 1; -#endif /* Cygwin */ register_font_driver (&uniscribe_font_driver, NULL); 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, } 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); 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." (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 () 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 @@ (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"])))