From 0ba48e8c2741bd65d547fe6bf1d9873f411b25b4 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 17 Nov 2020 18:23:19 +0100 Subject: [PATCH 01/13] patch 8.2.2001: Vim9: :def function does not apply 'maxfuncdepth' Problem: Vim9: :def function does not apply 'maxfuncdepth'. Solution: Use 'maxfuncdepth'. (issue #7313) --- src/proto/userfunc.pro | 4 +++ src/testdir/test_vim9_func.vim | 30 ++++++++++++++++++ src/userfunc.c | 56 +++++++++++++++++++++++++++++----- src/version.c | 2 ++ src/vim9execute.c | 15 +++++++++ 5 files changed, 99 insertions(+), 8 deletions(-) diff --git a/src/proto/userfunc.pro b/src/proto/userfunc.pro index 5bc7a4b90f..7ee36dbc18 100644 --- a/src/proto/userfunc.pro +++ b/src/proto/userfunc.pro @@ -14,6 +14,10 @@ ufunc_T *find_func(char_u *name, int is_global, cctx_T *cctx); int func_is_global(ufunc_T *ufunc); int func_name_refcount(char_u *name); void copy_func(char_u *lambda, char_u *global); +int funcdepth_increment(void); +void funcdepth_decrement(void); +int funcdepth_get(void); +void funcdepth_restore(int depth); int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict); void save_funccal(funccal_entry_T *entry); void restore_funccal(void); diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index a3f21491f2..bbfce23c4a 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -49,6 +49,36 @@ def TestCompilingError() call delete('XTest_compile_error') enddef +def CallRecursive(n: number): number + return CallRecursive(n + 1) +enddef + +def CallMapRecursive(l: list): number + return map(l, {_, v -> CallMapRecursive([v])})[0] +enddef + +def Test_funcdepth_error() + set maxfuncdepth=10 + + var caught = false + try + CallRecursive(1) + catch /E132:/ + caught = true + endtry + assert_true(caught) + + caught = false + try + CallMapRecursive([1]) + catch /E132:/ + caught = true + endtry + assert_true(caught) + + set maxfuncdepth& +enddef + def ReturnString(): string return 'string' enddef diff --git a/src/userfunc.c b/src/userfunc.c index 6e780ea011..7a306b1b7f 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1373,6 +1373,50 @@ failed: func_clear_free(fp, TRUE); } +static int funcdepth = 0; + +/* + * Increment the function call depth count. + * Return FAIL when going over 'maxfuncdepth'. + * Otherwise return OK, must call funcdepth_decrement() later! + */ + int +funcdepth_increment(void) +{ + if (funcdepth >= p_mfd) + { + emsg(_("E132: Function call depth is higher than 'maxfuncdepth'")); + return FAIL; + } + ++funcdepth; + return OK; +} + + void +funcdepth_decrement(void) +{ + --funcdepth; +} + +/* + * Get the current function call depth. + */ + int +funcdepth_get(void) +{ + return funcdepth; +} + +/* + * Restore the function call depth. This is for cases where there is no + * garantee funcdepth_decrement() can be called exactly the same number of + * times as funcdepth_increment(). + */ + void +funcdepth_restore(int depth) +{ + funcdepth = depth; +} /* * Call a user function. @@ -1391,7 +1435,6 @@ call_user_func( funccall_T *fc; int save_did_emsg; int default_arg_err = FALSE; - static int depth = 0; dictitem_T *v; int fixvar_idx = 0; // index in fixvar[] int i; @@ -1406,15 +1449,13 @@ call_user_func( #endif ESTACK_CHECK_DECLARATION - // If depth of calling is getting too high, don't execute the function - if (depth >= p_mfd) + // If depth of calling is getting too high, don't execute the function. + if (funcdepth_increment() == FAIL) { - emsg(_("E132: Function call depth is higher than 'maxfuncdepth'")); rettv->v_type = VAR_NUMBER; rettv->vval.v_number = -1; return; } - ++depth; line_breakcheck(); // check for CTRL-C hit @@ -1437,7 +1478,7 @@ call_user_func( { // Execute the function, possibly compiling it first. call_def_function(fp, argcount, argvars, funcexe->partial, rettv); - --depth; + funcdepth_decrement(); current_funccal = fc->caller; free_funccal(fc); return; @@ -1783,8 +1824,7 @@ call_user_func( } did_emsg |= save_did_emsg; - --depth; - + funcdepth_decrement(); cleanup_function_call(fc); } diff --git a/src/version.c b/src/version.c index a988b21dc1..4b91cf1ca1 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2001, /**/ 2000, /**/ diff --git a/src/vim9execute.c b/src/vim9execute.c index d8f9cfe02d..a7d83b47a7 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -227,6 +227,10 @@ call_dfunc(int cdf_idx, int argcount_arg, ectx_T *ectx) == FAIL) return FAIL; + // If depth of calling is getting too high, don't execute the function. + if (funcdepth_increment() == FAIL) + return FAIL; + // Move the vararg-list to below the missing optional arguments. if (vararg_count > 0 && arg_to_add > 0) *STACK_TV_BOT(arg_to_add - 1) = *STACK_TV_BOT(-1); @@ -503,6 +507,7 @@ func_return(ectx_T *ectx) ectx->ec_stack.ga_len = top + 1; *STACK_TV_BOT(-1) = *STACK_TV(idx); + funcdepth_decrement(); return OK; } @@ -835,6 +840,7 @@ call_def_function( cmdmod_T save_cmdmod; int restore_cmdmod = FALSE; int trylevel_at_start = trylevel; + int orig_funcdepth; // Get pointer to item in the stack. #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx) @@ -870,11 +876,19 @@ call_def_function( } } + // If depth of calling is getting too high, don't execute the function. + orig_funcdepth = funcdepth_get(); + if (funcdepth_increment() == FAIL) + return FAIL; + CLEAR_FIELD(ectx); ectx.ec_dfunc_idx = ufunc->uf_dfunc_idx; ga_init2(&ectx.ec_stack, sizeof(typval_T), 500); if (ga_grow(&ectx.ec_stack, 20) == FAIL) + { + funcdepth_decrement(); return FAIL; + } ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10); ga_init2(&ectx.ec_funcrefs, sizeof(partial_T *), 10); @@ -2941,6 +2955,7 @@ failed_early: if (ret != OK && did_emsg == did_emsg_before) semsg(_(e_unknown_error_while_executing_str), printable_func_name(ufunc)); + funcdepth_restore(orig_funcdepth); return ret; } From 52bf81c2d5f0d57443a29525b68b88707f5ad87c Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 17 Nov 2020 18:50:44 +0100 Subject: [PATCH 02/13] patch 8.2.2002: Vim9: lambda argument shadowed by function name Problem: Vim9: lambda argument shadowed by function name. Solution: Let function name be shadowed by lambda argument. (closes #7313) --- src/testdir/test_vim9_func.vim | 9 +++++++++ src/version.c | 2 ++ src/vim9compile.c | 18 ++++++++++++------ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index bbfce23c4a..e11564f083 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1456,6 +1456,15 @@ def Test_nested_lambda() CheckScriptSuccess(lines) enddef +def Shadowed(): list + var FuncList: list = [{ -> 42}] + return FuncList->map({_, Shadowed -> Shadowed()}) +enddef + +def Test_lambda_arg_shadows_func() + assert_equal([42], Shadowed()) +enddef + def Line_continuation_in_def(dir: string = ''): string var path: string = empty(dir) \ ? 'empty' diff --git a/src/version.c b/src/version.c index 4b91cf1ca1..7f4996761f 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2002, /**/ 2001, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index 6b2b766bea..ebe48548e2 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2712,13 +2712,19 @@ compile_call( goto theend; } - // If we can find the function by name generate the right call. - // Skip global functions here, a local funcref takes precedence. - ufunc = find_func(name, FALSE, cctx); - if (ufunc != NULL && !func_is_global(ufunc)) + // An argument or local variable can be a function reference, this + // overrules a function name. + if (lookup_local(namebuf, varlen, cctx) == NULL + && arg_exists(namebuf, varlen, NULL, NULL, NULL, cctx) != OK) { - res = generate_CALL(cctx, ufunc, argcount); - goto theend; + // If we can find the function by name generate the right call. + // Skip global functions here, a local funcref takes precedence. + ufunc = find_func(name, FALSE, cctx); + if (ufunc != NULL && !func_is_global(ufunc)) + { + res = generate_CALL(cctx, ufunc, argcount); + goto theend; + } } // If the name is a variable, load it and use PCALL. From 1efefda623283d941705d8f6ad0e9cfe0ac76079 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 17 Nov 2020 19:22:06 +0100 Subject: [PATCH 03/13] patch 8.2.2003: build error with +conceal but without +popupwin Problem: Build error with +conceal but without +popupwin. Solution: Add #ifdef. (Tom Ryder, closes #7316) --- src/drawline.c | 6 ++++-- src/version.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/drawline.c b/src/drawline.c index fcca38a2e9..0b99742163 100644 --- a/src/drawline.c +++ b/src/drawline.c @@ -2446,16 +2446,18 @@ win_line( && conceal_cursor_line(wp) && (int)wp->w_virtcol <= vcol + n_skip) { -# ifdef FEAT_RIGHTLEFT +# ifdef FEAT_RIGHTLEFT if (wp->w_p_rl) wp->w_wcol = wp->w_width - col + boguscols - 1; else -# endif +# endif wp->w_wcol = col - boguscols; wp->w_wrow = row; did_wcol = TRUE; curwin->w_valid |= VALID_WCOL|VALID_WROW|VALID_VIRTCOL; +# ifdef FEAT_PROP_POPUP curwin->w_flags &= ~(WFLAG_WCOL_OFF_ADDED | WFLAG_WROW_OFF_ADDED); +# endif } #endif diff --git a/src/version.c b/src/version.c index 7f4996761f..a34e9bfa81 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2003, /**/ 2002, /**/ From b3a01946b30f33e7be0358b3ff2736b94973a659 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Tue, 17 Nov 2020 19:56:09 +0100 Subject: [PATCH 04/13] patch 8.2.2004: compiler warning for uninitialized variable Problem: Compiler warning for uninitialized variable. Solution: Initialize "ufunc". (John Marriott) --- src/version.c | 2 ++ src/vim9compile.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/version.c b/src/version.c index a34e9bfa81..dafd15bf94 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2004, /**/ 2003, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index ebe48548e2..c8fb95ec41 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2626,7 +2626,7 @@ compile_call( char_u fname_buf[FLEN_FIXED + 1]; char_u *tofree = NULL; int error = FCERR_NONE; - ufunc_T *ufunc; + ufunc_T *ufunc = NULL; int res = FAIL; int is_autoload; From c77534c303721df4024fd6cfd51098d593b7d4da Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 11:34:37 +0100 Subject: [PATCH 05/13] patch 8.2.2005: redoing a mapping with doesn't work properly Problem: Redoing a mapping with doesn't work properly. Solution: Fill the redo buffer. Use "" instead of a key code. (closes #7282) --- src/getchar.c | 6 +----- src/ops.c | 7 ++++--- src/testdir/test_mapping.vim | 36 ++++++++++++++++++++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/getchar.c b/src/getchar.c index 165a6a3ad7..ad21cba7f2 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -3691,11 +3691,7 @@ getcmdkeycmd( else if (IS_SPECIAL(c1)) { if (c1 == K_SNR) - { - ga_append(&line_ga, (char)K_SPECIAL); - ga_append(&line_ga, (char)KS_EXTRA); - ga_append(&line_ga, (char)KE_SNR); - } + ga_concat(&line_ga, (char_u *)""); else { semsg(e_cmd_maping_must_not_include_str_key, diff --git a/src/ops.c b/src/ops.c index cc25683072..417bb1621d 100644 --- a/src/ops.c +++ b/src/ops.c @@ -3465,8 +3465,9 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) if ((redo_yank || oap->op_type != OP_YANK) && ((!VIsual_active || oap->motion_force) // Also redo Operator-pending Visual mode mappings - || (VIsual_active && cap->cmdchar == ':' - && oap->op_type != OP_COLON)) + || (VIsual_active + && (cap->cmdchar == ':' || cap->cmdchar == K_COMMAND) + && oap->op_type != OP_COLON)) && cap->cmdchar != 'D' #ifdef FEAT_FOLDING && oap->op_type != OP_FOLD @@ -3688,7 +3689,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); - else if (cap->cmdchar != ':') + else if (cap->cmdchar != ':' && cap->cmdchar != K_COMMAND) { int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL; diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim index dbd0a7e320..66edaa80a6 100644 --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -1324,4 +1324,40 @@ func Test_map_cmdkey_cmdline_mode() %bw! endfunc +func Test_map_cmdkey_redo() + func SelectDash() + call search('^---\n\zs', 'bcW') + norm! V + call search('\n\ze---$', 'W') + endfunc + + let text =<< trim END + --- + aaa + --- + bbb + bbb + --- + ccc + ccc + ccc + --- + END + new Xcmdtext + call setline(1, text) + + onoremap i- call SelectDash() + call feedkeys('2Gdi-', 'xt') + call assert_equal(['---', '---'], getline(1, 2)) + call feedkeys('j.', 'xt') + call assert_equal(['---', '---', '---'], getline(1, 3)) + call feedkeys('j.', 'xt') + call assert_equal(['---', '---', '---', '---'], getline(1, 4)) + + bwipe! + call delete('Xcmdtext') + delfunc SelectDash + ounmap i- +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index dafd15bf94..2191c34060 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2005, /**/ 2004, /**/ From 88774a30c0b1957a6177cdb69d2becedae610299 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 12:12:39 +0100 Subject: [PATCH 06/13] patch 8.2.2006: .pbtxt files are not recognized Problem: .pbtxt files are not recognized. Solution: Recognize .pbtxt as protobuf text buffers. (closes #7326) --- runtime/filetype.vim | 1 + src/testdir/test_filetype.vim | 1 + src/version.c | 2 ++ 3 files changed, 4 insertions(+) diff --git a/runtime/filetype.vim b/runtime/filetype.vim index a16a28d7af..9381402031 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1305,6 +1305,7 @@ au BufNewFile,BufRead *.pml setf promela " Google protocol buffers au BufNewFile,BufRead *.proto setf proto +au BufNewFile,BufRead *.pbtxt setf pbtxt " Protocols au BufNewFile,BufRead */etc/protocols setf protocols diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index 0e5a0cd04c..90e2ca080f 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -345,6 +345,7 @@ let s:filename_checks = { \ 'papp': ['file.papp', 'file.pxml', 'file.pxsl'], \ 'pascal': ['file.pas', 'file.pp', 'file.dpr', 'file.lpr'], \ 'passwd': ['any/etc/passwd', 'any/etc/passwd-', 'any/etc/passwd.edit', 'any/etc/shadow', 'any/etc/shadow-', 'any/etc/shadow.edit', 'any/var/backups/passwd.bak', 'any/var/backups/shadow.bak', '/etc/passwd', '/etc/passwd-', '/etc/passwd.edit', '/etc/shadow', '/etc/shadow-', '/etc/shadow.edit', '/var/backups/passwd.bak', '/var/backups/shadow.bak'], + \ 'pbtxt': ['file.pbtxt'], \ 'pccts': ['file.g'], \ 'pdf': ['file.pdf'], \ 'perl': ['file.plx', 'file.al', 'file.psgi', 'gitolite.rc', '.gitolite.rc', 'example.gitolite.rc'], diff --git a/src/version.c b/src/version.c index 2191c34060..4b91ba453c 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2006, /**/ 2005, /**/ From 17ab28daa060c3c263841329e74befb9c6e8b588 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 12:24:01 +0100 Subject: [PATCH 07/13] patch 8.2.2007: test for insert mode in popup is not reliable Problem: Test for insert mode in popup is not reliable. Solution: Wait for the popup to disappear. (Ozaki Kiichi, closes #7321) --- src/testdir/test_terminal.vim | 2 +- src/version.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim index ee0e743440..cef379a575 100644 --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -1266,7 +1266,7 @@ func Test_terminal_popup_insert_cmd() call assert_equal('n', mode()) call feedkeys("\", 'xt') - sleep 50m + call WaitFor({-> popup_list() == []}) delfunc StartTermInPopup iunmap endfunc diff --git a/src/version.c b/src/version.c index 4b91ba453c..cc296f5d69 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2007, /**/ 2006, /**/ From 032f40afb88b24043f96655aa248267a4f54faa8 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 15:21:50 +0100 Subject: [PATCH 08/13] patch 8.2.2008: MS-Windows GUI: handling channel messages lags Problem: MS-Windows GUI: handling channel messages lags. Solution: Reduce the wait time from 100 to 10 msec. (closes #7097) --- src/gui_w32.c | 9 ++++++--- src/version.c | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/gui_w32.c b/src/gui_w32.c index b296861440..80a70e25ce 100644 --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -2134,7 +2134,10 @@ gui_mch_wait_for_chars(int wtime) break; } else if (input_available() - || MsgWaitForMultipleObjects(0, NULL, FALSE, 100, + // TODO: The 10 msec is a compromise between laggy response + // and consuming more CPU time. Better would be to handle + // channel messages when they arrive. + || MsgWaitForMultipleObjects(0, NULL, FALSE, 10, QS_ALLINPUT) != WAIT_TIMEOUT) break; } @@ -8458,7 +8461,7 @@ make_tooltip(BalloonEval *beval, char *text, POINT pt) TOOLINFOW *pti; int ToolInfoSize; - if (multiline_balloon_available() == TRUE) + if (multiline_balloon_available()) ToolInfoSize = sizeof(TOOLINFOW_NEW); else ToolInfoSize = sizeof(TOOLINFOW); @@ -8481,7 +8484,7 @@ make_tooltip(BalloonEval *beval, char *text, POINT pt) pti->hinst = 0; // Don't use string resources pti->uId = ID_BEVAL_TOOLTIP; - if (multiline_balloon_available() == TRUE) + if (multiline_balloon_available()) { RECT rect; TOOLINFOW_NEW *ptin = (TOOLINFOW_NEW *)pti; diff --git a/src/version.c b/src/version.c index cc296f5d69..a96756de07 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2008, /**/ 2007, /**/ From 382319211a96adce089673c80eda982cc5259d0d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 15:30:09 +0100 Subject: [PATCH 09/13] patch 8.2.2009: MS-Windows: setting $LANG in gvimext only causes problems Problem: MS-Windows: setting $LANG in gvimext only causes problems. Solution: Do not set $LANG. (Ken Takata, closes #7325) --- src/GvimExt/gvimext.cpp | 79 ++++++----------------------------------- src/version.c | 2 ++ 2 files changed, 13 insertions(+), 68 deletions(-) diff --git a/src/GvimExt/gvimext.cpp b/src/GvimExt/gvimext.cpp index 53d96df8bf..24ad9412fe 100644 --- a/src/GvimExt/gvimext.cpp +++ b/src/GvimExt/gvimext.cpp @@ -161,7 +161,6 @@ static char *null_libintl_bindtextdomain(const char *, const char *); static int dyn_libintl_init(char *dir); static void dyn_libintl_end(void); -static wchar_t *oldenv = NULL; static HINSTANCE hLibintlDLL = 0; static char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext; static char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain; @@ -205,17 +204,17 @@ dyn_libintl_init(char *dir) if (buf != NULL && buf2 != NULL) { GetEnvironmentVariableW(L"PATH", buf, len); -#ifdef _WIN64 +# ifdef _WIN64 _snwprintf(buf2, len2, L"%S\\GvimExt64;%s", dir, buf); -#else +# else _snwprintf(buf2, len2, L"%S\\GvimExt32;%s", dir, buf); -#endif +# endif SetEnvironmentVariableW(L"PATH", buf2); hLibintlDLL = LoadLibrary(GETTEXT_DLL); -#ifdef GETTEXT_DLL_ALT +# ifdef GETTEXT_DLL_ALT if (!hLibintlDLL) hLibintlDLL = LoadLibrary(GETTEXT_DLL_ALT); -#endif +# endif SetEnvironmentVariableW(L"PATH", buf); } free(buf); @@ -273,56 +272,7 @@ null_libintl_textdomain(const char* /* domainname */) dyn_gettext_load(void) { char szBuff[BUFSIZE]; - char szLang[BUFSIZE]; DWORD len; - HKEY keyhandle; - int gotlang = 0; - - strcpy(szLang, "LANG="); - - // First try getting the language from the registry, this can be - // used to overrule the system language. - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0, - KEY_READ, &keyhandle) == ERROR_SUCCESS) - { - len = BUFSIZE; - if (RegQueryValueEx(keyhandle, "lang", 0, NULL, (BYTE*)szBuff, &len) - == ERROR_SUCCESS) - { - szBuff[len] = 0; - strcat(szLang, szBuff); - gotlang = 1; - } - RegCloseKey(keyhandle); - } - - if (!gotlang && getenv("LANG") == NULL) - { - // Get the language from the system. - // Could use LOCALE_SISO639LANGNAME, but it's not in Win95. - // LOCALE_SABBREVLANGNAME gives us three letters, like "enu", we use - // only the first two. - len = GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, - (LPTSTR)szBuff, BUFSIZE); - if (len >= 2 && _strnicmp(szBuff, "en", 2) != 0) - { - // There are a few exceptions (probably more) - if (_strnicmp(szBuff, "cht", 3) == 0 - || _strnicmp(szBuff, "zht", 3) == 0) - strcpy(szBuff, "zh_TW"); - else if (_strnicmp(szBuff, "chs", 3) == 0 - || _strnicmp(szBuff, "zhc", 3) == 0) - strcpy(szBuff, "zh_CN"); - else if (_strnicmp(szBuff, "jp", 2) == 0) - strcpy(szBuff, "ja"); - else - szBuff[2] = 0; // truncate to two-letter code - strcat(szLang, szBuff); - gotlang = 1; - } - } - if (gotlang) - putenv(szLang); // Try to locate the runtime files. The path is used to find libintl.dll // and the vim.mo files. @@ -378,10 +328,8 @@ DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /* lpReserved */) inc_cRefThisDLL() { #ifdef FEAT_GETTEXT - if (g_cRefThisDll == 0) { + if (g_cRefThisDll == 0) dyn_gettext_load(); - oldenv = GetEnvironmentStringsW(); - } #endif InterlockedIncrement((LPLONG)&g_cRefThisDll); } @@ -390,13 +338,8 @@ inc_cRefThisDLL() dec_cRefThisDLL() { #ifdef FEAT_GETTEXT - if (InterlockedDecrement((LPLONG)&g_cRefThisDll) == 0) { + if (InterlockedDecrement((LPLONG)&g_cRefThisDll) == 0) dyn_gettext_free(); - if (oldenv != NULL) { - FreeEnvironmentStringsW(oldenv); - oldenv = NULL; - } - } #else InterlockedDecrement((LPLONG)&g_cRefThisDll); #endif @@ -967,8 +910,8 @@ STDMETHODIMP CShellExt::InvokeGvim(HWND hParent, NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. - oldenv == NULL ? 0 : CREATE_UNICODE_ENVIRONMENT, - oldenv, // Use unmodified environment block. + 0, // No creation flags. + NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi) // Pointer to PROCESS_INFORMATION structure. @@ -1057,8 +1000,8 @@ STDMETHODIMP CShellExt::InvokeSingleGvim(HWND hParent, NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. - oldenv == NULL ? 0 : CREATE_UNICODE_ENVIRONMENT, - oldenv, // Use unmodified environment block. + 0, // No creation flags. + NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi) // Pointer to PROCESS_INFORMATION structure. diff --git a/src/version.c b/src/version.c index a96756de07..7c8a3706aa 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2009, /**/ 2008, /**/ From 8e02faf4e903e33e41961ba042bb5146213813a5 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 16:35:02 +0100 Subject: [PATCH 10/13] patch 8.2.2010: Vim9: compiling fails for unreachable return statement Problem: Vim9: compiling fails for unreachable return statement. Solution: Fix it. (closes #7319) --- src/testdir/test_vim9_disassemble.vim | 6 ++++++ src/version.c | 2 ++ src/vim9compile.c | 30 ++++++++++++++------------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 37748a1d3f..06fb77b0b5 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -749,6 +749,9 @@ def Test_disassemble_const_expr() enddef def ReturnInIf(): string + if 1 < 0 + return "maybe" + endif if g:cond return "yes" else @@ -759,6 +762,9 @@ enddef def Test_disassemble_return_in_if() var instr = execute('disassemble ReturnInIf') assert_match('ReturnInIf\_s*' .. + 'if 1 < 0\_s*' .. + ' return "maybe"\_s*' .. + 'endif\_s*' .. 'if g:cond\_s*' .. '0 LOADG g:cond\_s*' .. '1 COND2BOOL\_s*' .. diff --git a/src/version.c b/src/version.c index 7c8a3706aa..c56640dcaa 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2010, /**/ 2009, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index c8fb95ec41..c5d92aa1b8 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -4694,21 +4694,24 @@ compile_return(char_u *arg, int set_return_type, cctx_T *cctx) if (compile_expr0(&p, cctx) == FAIL) return NULL; - stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; - if (set_return_type) - cctx->ctx_ufunc->uf_ret_type = stack_type; - else + if (cctx->ctx_skip != SKIP_YES) { - if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID - && stack_type->tt_type != VAR_VOID - && stack_type->tt_type != VAR_UNKNOWN) + stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1]; + if (set_return_type) + cctx->ctx_ufunc->uf_ret_type = stack_type; + else { - emsg(_(e_returning_value_in_function_without_return_type)); - return NULL; - } - if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, + if (cctx->ctx_ufunc->uf_ret_type->tt_type == VAR_VOID + && stack_type->tt_type != VAR_VOID + && stack_type->tt_type != VAR_UNKNOWN) + { + emsg(_(e_returning_value_in_function_without_return_type)); + return NULL; + } + if (need_type(stack_type, cctx->ctx_ufunc->uf_ret_type, -1, cctx, FALSE, FALSE) == FAIL) - return NULL; + return NULL; + } } } else @@ -4725,8 +4728,7 @@ compile_return(char_u *arg, int set_return_type, cctx_T *cctx) // No argument, return zero. generate_PUSHNR(cctx, 0); } - - if (generate_instr(cctx, ISN_RETURN) == NULL) + if (cctx->ctx_skip != SKIP_YES && generate_instr(cctx, ISN_RETURN) == NULL) return NULL; // "return val | endif" is possible From 9950280d377a5c0706d141017fcef9cad598b8b0 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 16:53:23 +0100 Subject: [PATCH 11/13] patch 8.2.2011: "syn sync" reports a very large number Problem: "syn sync" reports a very large number. Solution: Use "at the first line". --- src/syntax.c | 38 +++++++++++++++++++++++-------------- src/testdir/test_syntax.vim | 3 +++ src/version.c | 2 ++ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/syntax.c b/src/syntax.c index 6025889b20..2245dc6251 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -3869,9 +3869,14 @@ syn_cmd_list( msg_puts(_("no syncing")); else { - msg_puts(_("syncing starts ")); - msg_outnum(curwin->w_s->b_syn_sync_minlines); - msg_puts(_(" lines before top line")); + if (curwin->w_s->b_syn_sync_minlines == MAXLNUM) + msg_puts(_("syncing starts at the first line")); + else + { + msg_puts(_("syncing starts ")); + msg_outnum(curwin->w_s->b_syn_sync_minlines); + msg_puts(_(" lines before top line")); + } syn_match_msg(); } return; @@ -3935,19 +3940,24 @@ syn_lines_msg(void) || curwin->w_s->b_syn_sync_minlines > 0) { msg_puts("; "); - if (curwin->w_s->b_syn_sync_minlines > 0) + if (curwin->w_s->b_syn_sync_minlines == MAXLNUM) + msg_puts(_("from the first line")); + else { - msg_puts(_("minimal ")); - msg_outnum(curwin->w_s->b_syn_sync_minlines); - if (curwin->w_s->b_syn_sync_maxlines) - msg_puts(", "); + if (curwin->w_s->b_syn_sync_minlines > 0) + { + msg_puts(_("minimal ")); + msg_outnum(curwin->w_s->b_syn_sync_minlines); + if (curwin->w_s->b_syn_sync_maxlines) + msg_puts(", "); + } + if (curwin->w_s->b_syn_sync_maxlines > 0) + { + msg_puts(_("maximal ")); + msg_outnum(curwin->w_s->b_syn_sync_maxlines); + } + msg_puts(_(" lines before top line")); } - if (curwin->w_s->b_syn_sync_maxlines > 0) - { - msg_puts(_("maximal ")); - msg_outnum(curwin->w_s->b_syn_sync_maxlines); - } - msg_puts(_(" lines before top line")); } } diff --git a/src/testdir/test_syntax.vim b/src/testdir/test_syntax.vim index dc05355865..f668a50858 100644 --- a/src/testdir/test_syntax.vim +++ b/src/testdir/test_syntax.vim @@ -316,6 +316,8 @@ func Test_syntax_arg_skipped() syn sync ccomment endif call assert_notmatch('on C-style comments', execute('syntax sync')) + syn sync fromstart + call assert_match('syncing starts at the first line', execute('syntax sync')) syn clear endfunc @@ -735,6 +737,7 @@ func Test_syntax_foldlevel() redir END call assert_equal("\nsyntax foldlevel start", @c) syn sync fromstart + call assert_match('from the first line$', execute('syn sync')) let a = map(range(3,9), 'foldclosed(v:val)') call assert_equal([3,3,3,3,3,3,3], a) " attached cascade folds together let a = map(range(10,15), 'foldclosed(v:val)') diff --git a/src/version.c b/src/version.c index c56640dcaa..80d2af9db1 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2011, /**/ 2010, /**/ From d92cc130fbb1beacf6411ee5837545f46f9be90e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 17:17:15 +0100 Subject: [PATCH 12/13] patch 8.2.2012: Vim9: confusing error message when using bool wrongly Problem: Vim9: confusing error message when using bool wrongly. Solution: Mention "Bool" instead of "Special". (closes #7323) --- src/errors.h | 2 ++ src/testdir/test_vim9_expr.vim | 7 +++++++ src/typval.c | 5 ++++- src/version.c | 2 ++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/errors.h b/src/errors.h index 969301f9c4..5ba6d52be5 100644 --- a/src/errors.h +++ b/src/errors.h @@ -301,3 +301,5 @@ EXTERN char e_cmd_mapping_must_end_with_cr_before_second_cmd[] INIT(=N_("E1136: mapping must end with before second ")); EXTERN char e_cmd_maping_must_not_include_str_key[] INIT(= N_("E1137: mapping must not include %s key")); +EXTERN char e_using_bool_as_number[] + INIT(= N_("E1138: Using a Bool as a Number")); diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index 63bfdd8040..b7897fe7cb 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -1292,6 +1292,13 @@ func Test_expr5_fails() call CheckDefFailure(["var x = 'a' .. 0z32"], 'E1105:', 1) call CheckDefFailure(["var x = 'a' .. function('len')"], 'E1105:', 1) call CheckDefFailure(["var x = 'a' .. function('len', ['a'])"], 'E1105:', 1) + + call CheckScriptFailure(['vim9script', 'var x = 1 + v:none'], 'E611:', 2) + call CheckScriptFailure(['vim9script', 'var x = 1 + v:null'], 'E611:', 2) + call CheckScriptFailure(['vim9script', 'var x = 1 + v:true'], 'E1138:', 2) + call CheckScriptFailure(['vim9script', 'var x = 1 + v:false'], 'E1138:', 2) + call CheckScriptFailure(['vim9script', 'var x = 1 + true'], 'E1138:', 2) + call CheckScriptFailure(['vim9script', 'var x = 1 + false'], 'E1138:', 2) endfunc func Test_expr5_fails_channel() diff --git a/src/typval.c b/src/typval.c index 7c55d3a5e1..0e2513aee3 100644 --- a/src/typval.c +++ b/src/typval.c @@ -213,7 +213,10 @@ tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool) case VAR_SPECIAL: if (!want_bool && in_vim9script()) { - emsg(_("E611: Using a Special as a Number")); + if (varp->v_type == VAR_BOOL) + emsg(_(e_using_bool_as_number)); + else + emsg(_("E611: Using a Special as a Number")); break; } return varp->vval.v_number == VVAL_TRUE ? 1 : 0; diff --git a/src/version.c b/src/version.c index 80d2af9db1..0f0ccda25a 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2012, /**/ 2011, /**/ From 79cdf80bed3192add70882bc0aaeede91cc74300 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 18 Nov 2020 17:39:05 +0100 Subject: [PATCH 13/13] patch 8.2.2013: Vim9: not skipping white space after unary minus Problem: Vim9: not skipping white space after unary minus. Solution: Skip whitespace. (closes #7324) --- src/testdir/test_vim9_expr.vim | 21 +++++++++++++++++++-- src/version.c | 2 ++ src/vim9compile.c | 2 ++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim index b7897fe7cb..156d244629 100644 --- a/src/testdir/test_vim9_expr.vim +++ b/src/testdir/test_vim9_expr.vim @@ -2300,12 +2300,29 @@ def Test_expr7_parens_vim9script() CheckScriptSuccess(lines) enddef -def Test_expr7_negate() +def Test_expr7_negate_add() assert_equal(-99, -99) + assert_equal(-99, - 99) assert_equal(99, --99) + assert_equal(99, -- 99) + assert_equal(99, - - 99) + assert_equal(99, +99) + assert_equal(-99, -+99) + assert_equal(-99, -+ 99) + assert_equal(-99, - +99) + assert_equal(-99, - + 99) + assert_equal(-99, +-99) + assert_equal(-99, + -99) + assert_equal(-99, + - 99) + var nr = 88 assert_equal(-88, -nr) - assert_equal(88, --nr) + assert_equal(-88, - nr) + assert_equal(-88, - +nr) + assert_equal(88, -- nr) + assert_equal(88, + nr) + assert_equal(88, --+ nr) + assert_equal(88, - - nr) enddef def Echo(arg: any): string diff --git a/src/version.c b/src/version.c index 0f0ccda25a..3f5cd797cf 100644 --- a/src/version.c +++ b/src/version.c @@ -750,6 +750,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2013, /**/ 2012, /**/ diff --git a/src/vim9compile.c b/src/vim9compile.c index c5d92aa1b8..2c522809d9 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3362,6 +3362,8 @@ compile_leader(cctx_T *cctx, int numeric_only, char_u *start, char_u **end) while (p > start) { --p; + while (VIM_ISWHITE(*p)) + --p; if (*p == '-' || *p == '+') { int negate = *p == '-';