To: vim_dev@googlegroups.com Subject: Patch 8.2.0563 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0563 Problem: Vim9: cannot split a function line. Solution: Continue in next line so long as the function isn't done. Files: runtime/doc/vim9.txt, src/userfunc.c, src/proto/userfunc.pro, src/vim9compile.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.0562/runtime/doc/vim9.txt 2020-04-12 20:55:16.994819669 +0200 --- runtime/doc/vim9.txt 2020-04-12 21:50:35.156437618 +0200 *************** *** 210,215 **** --- 210,222 ---- Note that "enddef" cannot be used at the start of a continuation line, it ends the current function. + It is also possible to split a function header over multiple lines, in between + arguments: > + def MyFunc( + text: string, + separator = '-' + ): string + No curly braces expansion ~ *** ../vim-8.2.0562/src/userfunc.c 2020-04-12 19:37:13.526297236 +0200 --- src/userfunc.c 2020-04-12 21:42:51.725957343 +0200 *************** *** 144,150 **** garray_T *argtypes, // NULL unless using :def int *varargs, garray_T *default_args, ! int skip) { int mustend = FALSE; char_u *arg = *argp; --- 144,152 ---- garray_T *argtypes, // NULL unless using :def int *varargs, garray_T *default_args, ! int skip, ! exarg_T *eap, ! char_u **line_to_free) { int mustend = FALSE; char_u *arg = *argp; *************** *** 168,173 **** --- 170,197 ---- */ while (*p != endchar) { + if (eap != NULL && *p == NUL && eap->getline != NULL) + { + char_u *theline; + + // End of the line, get the next one. + theline = eap->getline(':', eap->cookie, 0, TRUE); + if (theline == NULL) + break; + vim_free(*line_to_free); + *line_to_free = theline; + p = skipwhite(theline); + } + + if (mustend && *p != endchar) + { + if (!skip) + semsg(_(e_invarg2), *argp); + break; + } + if (*p == endchar) + break; + if (p[0] == '.' && p[1] == '.' && p[2] == '.') { if (varargs != NULL) *************** *** 241,253 **** mustend = TRUE; } p = skipwhite(p); - if (mustend && *p != endchar) - { - if (!skip) - semsg(_(e_invarg2), *argp); - break; - } } if (*p != endchar) goto err_ret; ++p; // skip "endchar" --- 265,272 ---- mustend = TRUE; } p = skipwhite(p); } + if (*p != endchar) goto err_ret; ++p; // skip "endchar" *************** *** 323,329 **** ga_init(&newlines); // First, check if this is a lambda expression. "->" must exist. ! ret = get_function_args(&start, '-', NULL, NULL, NULL, NULL, TRUE); if (ret == FAIL || *start != '>') return NOTDONE; --- 342,349 ---- ga_init(&newlines); // First, check if this is a lambda expression. "->" must exist. ! ret = get_function_args(&start, '-', NULL, NULL, NULL, NULL, TRUE, ! NULL, NULL); if (ret == FAIL || *start != '>') return NOTDONE; *************** *** 334,340 **** pnewargs = NULL; *arg = skipwhite(*arg + 1); // TODO: argument types ! ret = get_function_args(arg, '-', pnewargs, NULL, &varargs, NULL, FALSE); if (ret == FAIL || **arg != '>') goto errret; --- 354,361 ---- pnewargs = NULL; *arg = skipwhite(*arg + 1); // TODO: argument types ! ret = get_function_args(arg, '-', pnewargs, NULL, &varargs, NULL, FALSE, ! NULL, NULL); if (ret == FAIL || **arg != '>') goto errret; *************** *** 2508,2516 **** emsg(_("E862: Cannot use g: here")); } if (get_function_args(&p, ')', &newargs, eap->cmdidx == CMD_def ? &argtypes : NULL, ! &varargs, &default_args, eap->skip) == FAIL) goto errret_2; if (eap->cmdidx == CMD_def) --- 2529,2540 ---- emsg(_("E862: Cannot use g: here")); } + // This may get more lines and make the pointers into the first line + // invalid. if (get_function_args(&p, ')', &newargs, eap->cmdidx == CMD_def ? &argtypes : NULL, ! &varargs, &default_args, eap->skip, ! eap, &line_to_free) == FAIL) goto errret_2; if (eap->cmdidx == CMD_def) *************** *** 2521,2529 **** --- 2545,2559 ---- ret_type = skipwhite(p + 1); p = skip_type(ret_type); if (p > ret_type) + { + ret_type = vim_strnsave(ret_type, (int)(p - ret_type)); p = skipwhite(p); + } else + { + ret_type = NULL; semsg(_("E1056: expected a type: %s"), ret_type); + } } } else *************** *** 3134,3139 **** --- 3164,3170 ---- vim_free(line_to_free); vim_free(fudi.fd_newkey); vim_free(name); + vim_free(ret_type); did_emsg |= saved_did_emsg; need_wait_return |= saved_wait_return; } *** ../vim-8.2.0562/src/proto/userfunc.pro 2020-02-06 19:25:02.624298180 +0100 --- src/proto/userfunc.pro 2020-04-12 21:19:17.527075121 +0200 *************** *** 1,7 **** /* userfunc.c */ void func_init(void); hashtab_T *func_tbl_get(void); ! int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, garray_T *argtypes, int *varargs, garray_T *default_args, int skip); int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload); void emsg_funcname(char *ermsg, char_u *name); --- 1,7 ---- /* userfunc.c */ void func_init(void); hashtab_T *func_tbl_get(void); ! int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, garray_T *argtypes, int *varargs, garray_T *default_args, int skip, exarg_T *eap, char_u **line_to_free); int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload); void emsg_funcname(char *ermsg, char_u *name); *** ../vim-8.2.0562/src/vim9compile.c 2020-04-12 20:55:16.994819669 +0200 --- src/vim9compile.c 2020-04-12 21:20:23.910907286 +0200 *************** *** 3275,3282 **** char_u *start = skipwhite(*arg + 1); // Find out what comes after the arguments. ret = get_function_args(&start, '-', NULL, ! NULL, NULL, NULL, TRUE); if (ret != FAIL && *start == '>') ret = compile_lambda(arg, cctx); else --- 3275,3283 ---- char_u *start = skipwhite(*arg + 1); // Find out what comes after the arguments. + // TODO: pass getline function ret = get_function_args(&start, '-', NULL, ! NULL, NULL, NULL, TRUE, NULL, NULL); if (ret != FAIL && *start == '>') ret = compile_lambda(arg, cctx); else *** ../vim-8.2.0562/src/testdir/test_vim9_func.vim 2020-04-12 14:39:49.134760416 +0200 --- src/testdir/test_vim9_func.vim 2020-04-12 21:05:04.713252683 +0200 *************** *** 561,566 **** --- 561,582 ---- CheckDefFailure(['let str: string', 'str = FuncNoArgRetNumber()'], 'E1013: type mismatch, expected string but got number') enddef + def MultiLine( + arg1: string, + arg2 = 1234, + ...rest: list + ): string + return arg1 .. arg2 .. join(rest, '-') + enddef + + def Test_multiline() + assert_equal('text1234', MultiLine('text')) + assert_equal('text777', MultiLine('text', 777)) + assert_equal('text777one', MultiLine('text', 777, 'one')) + assert_equal('text777one-two', MultiLine('text', 777, 'one', 'two')) + enddef + + " When using CheckScriptFailure() for the below test, E1010 is generated instead " of E1056. func Test_E1056_1059() *** ../vim-8.2.0562/src/version.c 2020-04-12 20:55:16.998819659 +0200 --- src/version.c 2020-04-12 21:06:26.157041834 +0200 *************** *** 740,741 **** --- 740,743 ---- { /* Add new patch number below this line */ + /**/ + 563, /**/ -- How come wrong numbers are never busy? /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///