From 53fd3657ccf50046f095e90f44ef4c34e2e2f6d5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 16 Dec 2025 08:07:47 +0800 Subject: [PATCH 1/3] vim-patch:9.0.1758: vim9 no class identifiers in stack dumps Problem: vim9 no class identifiers in stack dumps Solution: Prefix class members in stack traces with the class name followed by a dot. closes: vim/vim#12866 closes: vim/vim#12078 https://github.com/vim/vim/commit/0ffc17aa479867f6f3ee14a46cf71352f126b5ba Co-authored-by: LemonBoy --- src/nvim/runtime.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 9cbf140f11..3127a36bde 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -195,7 +195,6 @@ char *estack_sfile(estack_arg_T which) for (int idx = 0; idx < exestack.ga_len; idx++) { entry = ((estack_T *)exestack.ga_data) + idx; if (entry->es_name != NULL) { - size_t len = strlen(entry->es_name) + 15; char *type_name = ""; if (entry->es_type != last_type) { switch (entry->es_type) { @@ -208,26 +207,26 @@ char *estack_sfile(estack_arg_T which) } last_type = entry->es_type; } - len += strlen(type_name); - ga_grow(&ga, (int)len); linenr_T lnum = idx == exestack.ga_len - 1 ? which == ESTACK_STACK ? SOURCING_LNUM : 0 : entry->es_lnum; - char *dots = idx == exestack.ga_len - 1 ? "" : ".."; - if (lnum == 0) { - // For the bottom entry of : do not add the line number, - // it is used in . Also leave it out when the number is - // not set. - vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s%s", - type_name, entry->es_name, dots); - } else { - vim_snprintf((char *)ga.ga_data + ga.ga_len, len, "%s%s[%" PRIdLINENR "]%s", - type_name, entry->es_name, lnum, dots); + size_t len = strlen(entry->es_name) + strlen(type_name) + 26; + ga_grow(&ga, (int)len); + ga_concat(&ga, type_name); + ga_concat(&ga, entry->es_name); + // For the bottom entry of : do not add the line number, it is used in + // . Also leave it out when the number is not set. + if (lnum != 0) { + ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23, + "[%" PRIdLINENR "]", lnum); + } + if (idx != exestack.ga_len - 1) { + ga_concat(&ga, ".."); } - ga.ga_len += (int)strlen((char *)ga.ga_data + ga.ga_len); } } + ga_append(&ga, '\0'); return (char *)ga.ga_data; } From 6061169183c02e6e6cabae09a56dd68989afe257 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 16 Dec 2025 08:13:18 +0800 Subject: [PATCH 2/3] vim-patch:9.1.1983: Vim9: class_name definition can be improved Problem: Vim9: class_name definition can be improved Solution: Use string_T to store class_name, avoid using STRLEN() calls, simplify code, remove unused definition of struct oc_newmember_S (John Marriott) Use struct string_T to store the field class_name in struct class_T, which means we can just use the .length field in struct string_T instead of measuring it. In addition: 1. In eval.c use string_T to store class_name and s in function class_tv2string(). 2. In vim9type.c change some calls from ga_concat() to ga_concat_len() where the length is known. 3. In vim9class.c remove unused struct definition oc_newmember_S. Change some calls from ga_concat() to ga_concat_len() where the length is known. 4. In scriptfile.c use string_T to store type_name, class_name and es_name in function estack_sfile(). 5. In function estack_sfile() simplify construction of the grow array ga and change some calls from ga_concat() to ga_concat_len() when the length is known. closes: vim/vim#18925 https://github.com/vim/vim/commit/2019321e0be320183afa47b7ea979dc4fc3984a0 Co-authored-by: John Marriott --- src/nvim/runtime.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 3127a36bde..90f48333b2 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -195,38 +195,41 @@ char *estack_sfile(estack_arg_T which) for (int idx = 0; idx < exestack.ga_len; idx++) { entry = ((estack_T *)exestack.ga_data) + idx; if (entry->es_name != NULL) { - char *type_name = ""; + String type_name = STATIC_CSTR_AS_STRING(""); + String es_name = cstr_as_string(entry->es_name); if (entry->es_type != last_type) { switch (entry->es_type) { case ETYPE_SCRIPT: - type_name = "script "; break; + type_name = STATIC_CSTR_AS_STRING("script "); break; case ETYPE_UFUNC: - type_name = "function "; break; + type_name = STATIC_CSTR_AS_STRING("function "); break; default: - type_name = ""; break; + break; } last_type = entry->es_type; } linenr_T lnum = idx == exestack.ga_len - 1 ? which == ESTACK_STACK ? SOURCING_LNUM : 0 : entry->es_lnum; - size_t len = strlen(entry->es_name) + strlen(type_name) + 26; + + size_t len = es_name.size + type_name.size + 26; ga_grow(&ga, (int)len); - ga_concat(&ga, type_name); - ga_concat(&ga, entry->es_name); + ga_concat_len(&ga, type_name.data, type_name.size); + ga_concat_len(&ga, es_name.data, es_name.size); // For the bottom entry of : do not add the line number, it is used in // . Also leave it out when the number is not set. if (lnum != 0) { - ga.ga_len += vim_snprintf((char *)ga.ga_data + ga.ga_len, 23, - "[%" PRIdLINENR "]", lnum); + ga.ga_len += (int)vim_snprintf_safelen((char *)ga.ga_data + ga.ga_len, + len - (size_t)ga.ga_len, + "[%" PRIdLINENR "]", lnum); } if (idx != exestack.ga_len - 1) { - ga_concat(&ga, ".."); + ga_concat_len(&ga, S_LEN("..")); } } } - ga_append(&ga, '\0'); + ga_append(&ga, NUL); return (char *)ga.ga_data; } From 544bde3accf33370d1ac1b3306abb23bdbb2d01a Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 17 Dec 2025 06:46:22 +0800 Subject: [PATCH 3/3] vim-patch:9.1.1987: assert_equal() prepends unnecessary ':' when typed Problem: assert_equal() prepends unnecessary ':' when typed (after 9.0.1758). Solution: Don't change a NULL stacktrace to an empty string (zeertzjq). closes: vim/vim#18936 https://github.com/vim/vim/commit/c4b3aefd0d5f81693e7098f224d3e4bfe24a7aa7 --- src/nvim/runtime.c | 5 ++++- test/old/testdir/test_assert.vim | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/nvim/runtime.c b/src/nvim/runtime.c index 90f48333b2..9152f132ce 100644 --- a/src/nvim/runtime.c +++ b/src/nvim/runtime.c @@ -229,7 +229,10 @@ char *estack_sfile(estack_arg_T which) } } - ga_append(&ga, NUL); + // Only NUL-terminate when not returning NULL. + if (ga.ga_data != NULL) { + ga_append(&ga, NUL); + } return (char *)ga.ga_data; } diff --git a/test/old/testdir/test_assert.vim b/test/old/testdir/test_assert.vim index fa63af687d..03d3cab771 100644 --- a/test/old/testdir/test_assert.vim +++ b/test/old/testdir/test_assert.vim @@ -386,6 +386,19 @@ func Test_assert_fails_in_timer() call StopVimInTerminal(buf) endfunc +" Check that a typed assert_equal() doesn't prepend an unnecessary ':'. +func Test_assert_equal_typed() + let after =<< trim END + call feedkeys(":call assert_equal(0, 1)\", 't') + call feedkeys(":call writefile(v:errors, 'Xerrors')\", 't') + call feedkeys(":qa!\", 't') + END + call assert_equal(1, RunVim([], after, '')) + call assert_equal(['Expected 0 but got 1'], readfile('Xerrors')) + + call delete('Xerrors') +endfunc + func Test_assert_beeps() new call assert_equal(0, assert_beeps('normal h'))