• R/O
  • SSH

vim: 提交

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

修订版f2bfee4ac356b42aa8ca0dfed1440cc43c6cc0d3 (tree)
时间2020-10-25 06:15:04
作者Bram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.1900: Vim9: command modifiers do not work

Commit: https://github.com/vim/vim/commit/02194d2bd54eacd0b7b9a017a3fe1702ecb80971
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Oct 24 23:08:38 2020 +0200

patch 8.2.1900: Vim9: command modifiers do not work
Problem: Vim9: command modifiers do not work.
Solution: Make most command modifiers work.

更改概述

差异

diff -r 81d7d3860786 -r f2bfee4ac356 src/proto/usercmd.pro
--- a/src/proto/usercmd.pro Sat Oct 24 21:00:06 2020 +0200
+++ b/src/proto/usercmd.pro Sat Oct 24 23:15:04 2020 +0200
@@ -14,6 +14,7 @@
1414 void ex_comclear(exarg_T *eap);
1515 void uc_clear(garray_T *gap);
1616 void ex_delcommand(exarg_T *eap);
17-size_t add_win_cmd_modifers(char_u *buf, int *multi_mods);
17+size_t add_win_cmd_modifers(char_u *buf, cmdmod_T *cmod, int *multi_mods);
18+int produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote);
1819 void do_ucmd(exarg_T *eap);
1920 /* vim: set ft=c : */
diff -r 81d7d3860786 -r f2bfee4ac356 src/scriptfile.c
--- a/src/scriptfile.c Sat Oct 24 21:00:06 2020 +0200
+++ b/src/scriptfile.c Sat Oct 24 23:15:04 2020 +0200
@@ -1009,7 +1009,7 @@
10091009 int multi_mods = 0;
10101010
10111011 buf[0] = NUL;
1012- (void)add_win_cmd_modifers(buf, &multi_mods);
1012+ (void)add_win_cmd_modifers(buf, &cmdmod, &multi_mods);
10131013
10141014 vim_setenv((char_u *)"OPTWIN_CMD", buf);
10151015 cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
diff -r 81d7d3860786 -r f2bfee4ac356 src/testdir/test_vim9_disassemble.vim
--- a/src/testdir/test_vim9_disassemble.vim Sat Oct 24 21:00:06 2020 +0200
+++ b/src/testdir/test_vim9_disassemble.vim Sat Oct 24 23:15:04 2020 +0200
@@ -1627,15 +1627,15 @@
16271627 var res = execute('disass s:SilentMessage')
16281628 assert_match('<SNR>\d*_SilentMessage\_s*' ..
16291629 'silent echomsg "text"\_s*' ..
1630- '\d SILENT\_s*' ..
1630+ '\d CMDMOD silent\_s*' ..
16311631 '\d PUSHS "text"\_s*' ..
16321632 '\d ECHOMSG 1\_s*' ..
1633- '\d UNSILENT\_s*' ..
1633+ '\d CMDMOD_REV\_s*' ..
16341634 'silent! echoerr "error"\_s*' ..
1635- '\d SILENT!\_s*' ..
1635+ '\d CMDMOD silent!\_s*' ..
16361636 '\d PUSHS "error"\_s*' ..
16371637 '\d ECHOERR 1\_s*' ..
1638- '\d UNSILENT!\_s*' ..
1638+ '\d CMDMOD_REV\_s*' ..
16391639 '\d PUSHNR 0\_s*' ..
16401640 '\d RETURN',
16411641 res)
diff -r 81d7d3860786 -r f2bfee4ac356 src/usercmd.c
--- a/src/usercmd.c Sat Oct 24 21:00:06 2020 +0200
+++ b/src/usercmd.c Sat Oct 24 23:15:04 2020 +0200
@@ -1235,37 +1235,104 @@
12351235 }
12361236
12371237 /*
1238- * Add modifiers from "cmdmod.cmod_split" to "buf". Set "multi_mods" when one
1238+ * Add modifiers from "cmod->cmod_split" to "buf". Set "multi_mods" when one
12391239 * was added. Return the number of bytes added.
12401240 */
12411241 size_t
1242-add_win_cmd_modifers(char_u *buf, int *multi_mods)
1242+add_win_cmd_modifers(char_u *buf, cmdmod_T *cmod, int *multi_mods)
12431243 {
12441244 size_t result = 0;
12451245
12461246 // :aboveleft and :leftabove
1247- if (cmdmod.cmod_split & WSP_ABOVE)
1247+ if (cmod->cmod_split & WSP_ABOVE)
12481248 result += add_cmd_modifier(buf, "aboveleft", multi_mods);
12491249 // :belowright and :rightbelow
1250- if (cmdmod.cmod_split & WSP_BELOW)
1250+ if (cmod->cmod_split & WSP_BELOW)
12511251 result += add_cmd_modifier(buf, "belowright", multi_mods);
12521252 // :botright
1253- if (cmdmod.cmod_split & WSP_BOT)
1253+ if (cmod->cmod_split & WSP_BOT)
12541254 result += add_cmd_modifier(buf, "botright", multi_mods);
12551255
12561256 // :tab
1257- if (cmdmod.cmod_tab > 0)
1257+ if (cmod->cmod_tab > 0)
12581258 result += add_cmd_modifier(buf, "tab", multi_mods);
12591259 // :topleft
1260- if (cmdmod.cmod_split & WSP_TOP)
1260+ if (cmod->cmod_split & WSP_TOP)
12611261 result += add_cmd_modifier(buf, "topleft", multi_mods);
12621262 // :vertical
1263- if (cmdmod.cmod_split & WSP_VERT)
1263+ if (cmod->cmod_split & WSP_VERT)
12641264 result += add_cmd_modifier(buf, "vertical", multi_mods);
12651265 return result;
12661266 }
12671267
12681268 /*
1269+ * Generate text for the "cmod" command modifiers.
1270+ * If "buf" is NULL just return the length.
1271+ */
1272+ int
1273+produce_cmdmods(char_u *buf, cmdmod_T *cmod, int quote)
1274+{
1275+ int result = 0;
1276+ int multi_mods = 0;
1277+ int i;
1278+ typedef struct {
1279+ int flag;
1280+ char *name;
1281+ } mod_entry_T;
1282+ static mod_entry_T mod_entries[] = {
1283+#ifdef FEAT_BROWSE_CMD
1284+ {CMOD_BROWSE, "browse"},
1285+#endif
1286+#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1287+ {CMOD_CONFIRM, "confirm"},
1288+#endif
1289+ {CMOD_HIDE, "hide"},
1290+ {CMOD_KEEPALT, "keepalt"},
1291+ {CMOD_KEEPJUMPS, "keepjumps"},
1292+ {CMOD_KEEPMARKS, "keepmarks"},
1293+ {CMOD_KEEPPATTERNS, "keeppatterns"},
1294+ {CMOD_LOCKMARKS, "lockmarks"},
1295+ {CMOD_NOSWAPFILE, "noswapfile"},
1296+ {CMOD_UNSILENT, "unsilent"},
1297+ {CMOD_NOAUTOCMD, "noautocmd"},
1298+#ifdef HAVE_SANDBOX
1299+ {CMOD_SANDBOX, "sandbox"},
1300+#endif
1301+ {0, NULL}
1302+ };
1303+
1304+ result = quote ? 2 : 0;
1305+ if (buf != NULL)
1306+ {
1307+ if (quote)
1308+ *buf++ = '"';
1309+ *buf = '\0';
1310+ }
1311+
1312+ // the modifiers that are simple flags
1313+ for (i = 0; mod_entries[i].name != NULL; ++i)
1314+ if (cmod->cmod_flags & mod_entries[i].flag)
1315+ result += add_cmd_modifier(buf, mod_entries[i].name, &multi_mods);
1316+
1317+ // :silent
1318+ if (cmod->cmod_flags & CMOD_SILENT)
1319+ result += add_cmd_modifier(buf,
1320+ (cmod->cmod_flags & CMOD_ERRSILENT) ? "silent!"
1321+ : "silent", &multi_mods);
1322+ // :verbose
1323+ if (p_verbose > 0)
1324+ result += add_cmd_modifier(buf, "verbose", &multi_mods);
1325+ // flags from cmod->cmod_split
1326+ result += add_win_cmd_modifers(buf, cmod, &multi_mods);
1327+ if (quote && buf != NULL)
1328+ {
1329+ buf += result - 2;
1330+ *buf = '"';
1331+ }
1332+ return result;
1333+}
1334+
1335+/*
12691336 * Check for a <> code in a user command.
12701337 * "code" points to the '<'. "len" the length of the <> (inclusive).
12711338 * "buf" is where the result is to be added.
@@ -1452,62 +1519,7 @@
14521519
14531520 case ct_MODS:
14541521 {
1455- int multi_mods = 0;
1456- typedef struct {
1457- int flag;
1458- char *name;
1459- } mod_entry_T;
1460- static mod_entry_T mod_entries[] = {
1461-#ifdef FEAT_BROWSE_CMD
1462- {CMOD_BROWSE, "browse"},
1463-#endif
1464-#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
1465- {CMOD_CONFIRM, "confirm"},
1466-#endif
1467- {CMOD_HIDE, "hide"},
1468- {CMOD_KEEPALT, "keepalt"},
1469- {CMOD_KEEPJUMPS, "keepjumps"},
1470- {CMOD_KEEPMARKS, "keepmarks"},
1471- {CMOD_KEEPPATTERNS, "keeppatterns"},
1472- {CMOD_LOCKMARKS, "lockmarks"},
1473- {CMOD_NOSWAPFILE, "noswapfile"},
1474- {0, NULL}
1475- };
1476- int i;
1477-
1478- result = quote ? 2 : 0;
1479- if (buf != NULL)
1480- {
1481- if (quote)
1482- *buf++ = '"';
1483- *buf = '\0';
1484- }
1485-
1486- // the modifiers that are simple flags
1487- for (i = 0; mod_entries[i].name != NULL; ++i)
1488- if (cmdmod.cmod_flags & mod_entries[i].flag)
1489- result += add_cmd_modifier(buf, mod_entries[i].name,
1490- &multi_mods);
1491-
1492- // TODO: How to support :noautocmd?
1493-#ifdef HAVE_SANDBOX
1494- // TODO: How to support :sandbox?
1495-#endif
1496- // :silent
1497- if (msg_silent > 0)
1498- result += add_cmd_modifier(buf,
1499- emsg_silent > 0 ? "silent!" : "silent", &multi_mods);
1500- // TODO: How to support :unsilent?
1501- // :verbose
1502- if (p_verbose > 0)
1503- result += add_cmd_modifier(buf, "verbose", &multi_mods);
1504- // flags from cmdmod.cmod_split
1505- result += add_win_cmd_modifers(buf, &multi_mods);
1506- if (quote && buf != NULL)
1507- {
1508- buf += result - 2;
1509- *buf = '"';
1510- }
1522+ result = produce_cmdmods(buf, &cmdmod, quote);
15111523 break;
15121524 }
15131525
diff -r 81d7d3860786 -r f2bfee4ac356 src/version.c
--- a/src/version.c Sat Oct 24 21:00:06 2020 +0200
+++ b/src/version.c Sat Oct 24 23:15:04 2020 +0200
@@ -751,6 +751,8 @@
751751 static int included_patches[] =
752752 { /* Add new patch number below this line */
753753 /**/
754+ 1900,
755+/**/
754756 1899,
755757 /**/
756758 1898,
diff -r 81d7d3860786 -r f2bfee4ac356 src/vim9.h
--- a/src/vim9.h Sat Oct 24 21:00:06 2020 +0200
+++ b/src/vim9.h Sat Oct 24 23:15:04 2020 +0200
@@ -142,8 +142,8 @@
142142
143143 ISN_PUT, // ":put", uses isn_arg.put
144144
145- ISN_SILENT, // set msg_silent or emsg_silent if arg_number is non-zero
146- ISN_UNSILENT, // undo ISN_SILENT
145+ ISN_CMDMOD, // set cmdmod
146+ ISN_CMDMOD_REV, // undo ISN_CMDMOD
147147
148148 ISN_SHUFFLE, // move item on stack up or down
149149 ISN_DROP // pop stack and discard value
@@ -278,6 +278,11 @@
278278 linenr_T put_lnum; // line number to put below
279279 } put_T;
280280
281+// arguments to ISN_CMDMOD
282+typedef struct {
283+ cmdmod_T *cf_cmdmod; // allocated
284+} cmod_T;
285+
281286 /*
282287 * Instruction
283288 */
@@ -314,6 +319,7 @@
314319 checklen_T checklen;
315320 shuffle_T shuffle;
316321 put_T put;
322+ cmod_T cmdmod;
317323 } isn_arg;
318324 };
319325
diff -r 81d7d3860786 -r f2bfee4ac356 src/vim9compile.c
--- a/src/vim9compile.c Sat Oct 24 21:00:06 2020 +0200
+++ b/src/vim9compile.c Sat Oct 24 23:15:04 2020 +0200
@@ -142,7 +142,7 @@
142142 garray_T ctx_type_stack; // type of each item on the stack
143143 garray_T *ctx_type_list; // list of pointers to allocated types
144144
145- int ctx_silent; // set when ISN_SILENT was generated
145+ int ctx_has_cmdmod; // ISN_CMDMOD was generated
146146 };
147147
148148 static void delete_def_function_contents(dfunc_T *dfunc);
@@ -1823,36 +1823,45 @@
18231823 }
18241824
18251825 /*
1826- * Generate any instructions for side effects of "cmdmod".
1826+ * Generate an instruction for any command modifiers.
18271827 */
18281828 static int
18291829 generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod)
18301830 {
18311831 isn_T *isn;
18321832
1833- // TODO: use more modifiers in the command
1834- if (cmod->cmod_flags & (CMOD_SILENT | CMOD_ERRSILENT))
1835- {
1836- if ((isn = generate_instr(cctx, ISN_SILENT)) == NULL)
1833+ if (cmod->cmod_flags != 0
1834+ || cmod->cmod_split != 0
1835+ || cmod->cmod_verbose != 0
1836+ || cmod->cmod_tab != 0
1837+ || cmod->cmod_filter_regmatch.regprog != NULL)
1838+ {
1839+ cctx->ctx_has_cmdmod = TRUE;
1840+
1841+ if ((isn = generate_instr(cctx, ISN_CMDMOD)) == NULL)
18371842 return FAIL;
1838- isn->isn_arg.number = (cmod->cmod_flags & CMOD_ERRSILENT) != 0;
1839- cctx->ctx_silent = (cmod->cmod_flags & CMOD_ERRSILENT) ? 2 : 1;
1840- }
1843+ isn->isn_arg.cmdmod.cf_cmdmod = ALLOC_ONE(cmdmod_T);
1844+ if (isn->isn_arg.cmdmod.cf_cmdmod == NULL)
1845+ return FAIL;
1846+ mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T));
1847+ // filter progam now belongs to the instruction
1848+ cmod->cmod_filter_regmatch.regprog = NULL;
1849+ }
1850+
18411851 return OK;
18421852 }
18431853
18441854 static int
1845-generate_restore_cmdmods(cctx_T *cctx)
1855+generate_undo_cmdmods(cctx_T *cctx)
18461856 {
18471857 isn_T *isn;
18481858
1849- if (cctx->ctx_silent > 0)
1850- {
1851- if ((isn = generate_instr(cctx, ISN_UNSILENT)) == NULL)
1859+ if (cctx->ctx_has_cmdmod)
1860+ {
1861+ if ((isn = generate_instr(cctx, ISN_CMDMOD_REV)) == NULL)
18521862 return FAIL;
1853- isn->isn_arg.number = cctx->ctx_silent == 2;
1854- cctx->ctx_silent = 0;
1855- }
1863+ }
1864+
18561865 return OK;
18571866 }
18581867
@@ -7092,9 +7101,9 @@
70927101 for (;;)
70937102 {
70947103 exarg_T ea;
7095- cmdmod_T local_cmdmod;
70967104 int starts_with_colon = FALSE;
70977105 char_u *cmd;
7106+ cmdmod_T local_cmdmod;
70987107
70997108 // Bail out on the first error to avoid a flood of errors and report
71007109 // the right line number when inside try/catch.
@@ -7175,7 +7184,7 @@
71757184 /*
71767185 * COMMAND MODIFIERS
71777186 */
7178- CLEAR_FIELD(local_cmdmod);
7187+ cctx.ctx_has_cmdmod = FALSE;
71797188 if (parse_command_modifiers(&ea, &errormsg, &local_cmdmod, FALSE)
71807189 == FAIL)
71817190 {
@@ -7497,7 +7506,7 @@
74977506 line = skipwhite(line);
74987507
74997508 // Undo any command modifiers.
7500- generate_restore_cmdmods(&cctx);
7509+ generate_undo_cmdmods(&cctx);
75017510
75027511 if (cctx.ctx_type_stack.ga_len < 0)
75037512 {
@@ -7742,6 +7751,12 @@
77427751 free_type(isn->isn_arg.type.ct_type);
77437752 break;
77447753
7754+ case ISN_CMDMOD:
7755+ vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
7756+ ->cmod_filter_regmatch.regprog);
7757+ vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
7758+ break;
7759+
77457760 case ISN_2BOOL:
77467761 case ISN_2STRING:
77477762 case ISN_2STRING_ANY:
@@ -7754,6 +7769,7 @@
77547769 case ISN_CATCH:
77557770 case ISN_CHECKLEN:
77567771 case ISN_CHECKNR:
7772+ case ISN_CMDMOD_REV:
77577773 case ISN_COMPAREANY:
77587774 case ISN_COMPAREBLOB:
77597775 case ISN_COMPAREBOOL:
@@ -7805,7 +7821,6 @@
78057821 case ISN_PUT:
78067822 case ISN_RETURN:
78077823 case ISN_SHUFFLE:
7808- case ISN_SILENT:
78097824 case ISN_SLICE:
78107825 case ISN_STORE:
78117826 case ISN_STOREDICT:
@@ -7819,7 +7834,6 @@
78197834 case ISN_STRSLICE:
78207835 case ISN_THROW:
78217836 case ISN_TRY:
7822- case ISN_UNSILENT:
78237837 // nothing allocated
78247838 break;
78257839 }
diff -r 81d7d3860786 -r f2bfee4ac356 src/vim9execute.c
--- a/src/vim9execute.c Sat Oct 24 21:00:06 2020 +0200
+++ b/src/vim9execute.c Sat Oct 24 23:15:04 2020 +0200
@@ -832,8 +832,8 @@
832832 int save_suppress_errthrow = suppress_errthrow;
833833 msglist_T **saved_msg_list = NULL;
834834 msglist_T *private_msg_list = NULL;
835- int save_msg_silent = -1;
836- int save_emsg_silent = -1;
835+ cmdmod_T save_cmdmod;
836+ int restore_cmdmod = FALSE;
837837
838838 // Get pointer to item in the stack.
839839 #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
@@ -2816,22 +2816,19 @@
28162816 }
28172817 break;
28182818
2819- case ISN_SILENT:
2820- if (save_msg_silent == -1)
2821- save_msg_silent = msg_silent;
2822- ++msg_silent;
2823- if (iptr->isn_arg.number)
2824- {
2825- if (save_emsg_silent == -1)
2826- save_emsg_silent = emsg_silent;
2827- ++emsg_silent;
2828- }
2819+ case ISN_CMDMOD:
2820+ save_cmdmod = cmdmod;
2821+ restore_cmdmod = TRUE;
2822+ cmdmod = *iptr->isn_arg.cmdmod.cf_cmdmod;
2823+ apply_cmdmod(&cmdmod);
28292824 break;
28302825
2831- case ISN_UNSILENT:
2832- --msg_silent;
2833- if (iptr->isn_arg.number)
2834- --emsg_silent;
2826+ case ISN_CMDMOD_REV:
2827+ // filter regprog is owned by the instruction, don't free it
2828+ cmdmod.cmod_filter_regmatch.regprog = NULL;
2829+ undo_cmdmod(&cmdmod);
2830+ cmdmod = save_cmdmod;
2831+ restore_cmdmod = FALSE;
28352832 break;
28362833
28372834 case ISN_SHUFFLE:
@@ -2905,10 +2902,12 @@
29052902 }
29062903 msg_list = saved_msg_list;
29072904
2908- if (save_msg_silent != -1)
2909- msg_silent = save_msg_silent;
2910- if (save_emsg_silent != -1)
2911- emsg_silent = save_emsg_silent;
2905+ if (restore_cmdmod)
2906+ {
2907+ cmdmod.cmod_filter_regmatch.regprog = NULL;
2908+ undo_cmdmod(&cmdmod);
2909+ cmdmod = save_cmdmod;
2910+ }
29122911
29132912 failed_early:
29142913 // Free all local variables, but not arguments.
@@ -3527,10 +3526,24 @@
35273526 (long)iptr->isn_arg.put.put_lnum);
35283527 break;
35293528
3530- case ISN_SILENT: smsg("%4d SILENT%s", current,
3531- iptr->isn_arg.number ? "!" : ""); break;
3532- case ISN_UNSILENT: smsg("%4d UNSILENT%s", current,
3533- iptr->isn_arg.number ? "!" : ""); break;
3529+ // TODO: summarize modifiers
3530+ case ISN_CMDMOD:
3531+ {
3532+ char_u *buf;
3533+ int len = produce_cmdmods(
3534+ NULL, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);
3535+
3536+ buf = alloc(len + 1);
3537+ if (buf != NULL)
3538+ {
3539+ (void)produce_cmdmods(
3540+ buf, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);
3541+ smsg("%4d CMDMOD %s", current, buf);
3542+ vim_free(buf);
3543+ }
3544+ break;
3545+ }
3546+ case ISN_CMDMOD_REV: smsg("%4d CMDMOD_REV", current); break;
35343547
35353548 case ISN_SHUFFLE: smsg("%4d SHUFFLE %d up %d", current,
35363549 iptr->isn_arg.shuffle.shfl_item,
Show on old repository browser