Mercurial > vim
comparison src/ex_docmd.c @ 9230:f7fb117883ba v7.4.1898
commit https://github.com/vim/vim/commit/63a60ded3fd584847a05dccf058026e682abad90
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 4 22:08:55 2016 +0200
patch 7.4.1898
Problem: User commands don't support modifiers.
Solution: Add the <mods> item. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/829)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sat, 04 Jun 2016 22:15:05 +0200 |
parents | ea504064c996 |
children | ac8180818504 |
comparison
equal
deleted
inserted
replaced
9229:a169b470d24d | 9230:f7fb117883ba |
---|---|
6411 | 6411 |
6412 *lenp = len; | 6412 *lenp = len; |
6413 return buf; | 6413 return buf; |
6414 } | 6414 } |
6415 | 6415 |
6416 static size_t | |
6417 add_cmd_modifier(char_u *buf, char *mod_str, int *multi_mods) | |
6418 { | |
6419 size_t result; | |
6420 | |
6421 result = STRLEN(mod_str); | |
6422 if (*multi_mods) | |
6423 result += 1; | |
6424 if (buf != NULL) | |
6425 { | |
6426 if (*multi_mods) | |
6427 STRCAT(buf, " "); | |
6428 STRCAT(buf, mod_str); | |
6429 } | |
6430 | |
6431 *multi_mods = 1; | |
6432 | |
6433 return result; | |
6434 } | |
6435 | |
6416 /* | 6436 /* |
6417 * Check for a <> code in a user command. | 6437 * Check for a <> code in a user command. |
6418 * "code" points to the '<'. "len" the length of the <> (inclusive). | 6438 * "code" points to the '<'. "len" the length of the <> (inclusive). |
6419 * "buf" is where the result is to be added. | 6439 * "buf" is where the result is to be added. |
6420 * "split_buf" points to a buffer used for splitting, caller should free it. | 6440 * "split_buf" points to a buffer used for splitting, caller should free it. |
6434 { | 6454 { |
6435 size_t result = 0; | 6455 size_t result = 0; |
6436 char_u *p = code + 1; | 6456 char_u *p = code + 1; |
6437 size_t l = len - 2; | 6457 size_t l = len - 2; |
6438 int quote = 0; | 6458 int quote = 0; |
6439 enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_REGISTER, | 6459 enum { ct_ARGS, ct_BANG, ct_COUNT, ct_LINE1, ct_LINE2, ct_MODS, |
6440 ct_LT, ct_NONE } type = ct_NONE; | 6460 ct_REGISTER, ct_LT, ct_NONE } type = ct_NONE; |
6441 | 6461 |
6442 if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') | 6462 if ((vim_strchr((char_u *)"qQfF", *p) != NULL) && p[1] == '-') |
6443 { | 6463 { |
6444 quote = (*p == 'q' || *p == 'Q') ? 1 : 2; | 6464 quote = (*p == 'q' || *p == 'Q') ? 1 : 2; |
6445 p += 2; | 6465 p += 2; |
6461 type = ct_LINE2; | 6481 type = ct_LINE2; |
6462 else if (STRNICMP(p, "lt>", l) == 0) | 6482 else if (STRNICMP(p, "lt>", l) == 0) |
6463 type = ct_LT; | 6483 type = ct_LT; |
6464 else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0) | 6484 else if (STRNICMP(p, "reg>", l) == 0 || STRNICMP(p, "register>", l) == 0) |
6465 type = ct_REGISTER; | 6485 type = ct_REGISTER; |
6486 else if (STRNICMP(p, "mods>", l) == 0) | |
6487 type = ct_MODS; | |
6466 | 6488 |
6467 switch (type) | 6489 switch (type) |
6468 { | 6490 { |
6469 case ct_ARGS: | 6491 case ct_ARGS: |
6470 /* Simple case first */ | 6492 /* Simple case first */ |
6581 buf += num_len; | 6603 buf += num_len; |
6582 if (quote) | 6604 if (quote) |
6583 *buf = '"'; | 6605 *buf = '"'; |
6584 } | 6606 } |
6585 | 6607 |
6608 break; | |
6609 } | |
6610 | |
6611 case ct_MODS: | |
6612 { | |
6613 int multi_mods = 0; | |
6614 typedef struct { | |
6615 int *varp; | |
6616 char *name; | |
6617 } mod_entry_T; | |
6618 static mod_entry_T mod_entries[] = { | |
6619 #ifdef FEAT_BROWSE_CMD | |
6620 {&cmdmod.browse, "browse"}, | |
6621 #endif | |
6622 #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) | |
6623 {&cmdmod.confirm, "confirm"}, | |
6624 #endif | |
6625 {&cmdmod.hide, "hide"}, | |
6626 {&cmdmod.keepalt, "keepalt"}, | |
6627 {&cmdmod.keepjumps, "keepjumps"}, | |
6628 {&cmdmod.keepmarks, "keepmarks"}, | |
6629 {&cmdmod.keeppatterns, "keeppatterns"}, | |
6630 {&cmdmod.lockmarks, "lockmarks"}, | |
6631 {&cmdmod.noswapfile, "noswapfile"}, | |
6632 {NULL, NULL} | |
6633 }; | |
6634 int i; | |
6635 | |
6636 result = quote ? 2 : 0; | |
6637 if (buf != NULL) | |
6638 { | |
6639 if (quote) | |
6640 *buf++ = '"'; | |
6641 *buf = '\0'; | |
6642 } | |
6643 | |
6644 #ifdef FEAT_WINDOWS | |
6645 /* :aboveleft and :leftabove */ | |
6646 if (cmdmod.split & WSP_ABOVE) | |
6647 result += add_cmd_modifier(buf, "aboveleft", &multi_mods); | |
6648 /* :belowright and :rightbelow */ | |
6649 if (cmdmod.split & WSP_BELOW) | |
6650 result += add_cmd_modifier(buf, "belowright", &multi_mods); | |
6651 /* :botright */ | |
6652 if (cmdmod.split & WSP_BOT) | |
6653 result += add_cmd_modifier(buf, "botright", &multi_mods); | |
6654 #endif | |
6655 | |
6656 /* the modifiers that are simple flags */ | |
6657 for (i = 0; mod_entries[i].varp != NULL; ++i) | |
6658 if (*mod_entries[i].varp) | |
6659 result += add_cmd_modifier(buf, mod_entries[i].name, | |
6660 &multi_mods); | |
6661 | |
6662 /* TODO: How to support :noautocmd? */ | |
6663 #ifdef HAVE_SANDBOX | |
6664 /* TODO: How to support :sandbox?*/ | |
6665 #endif | |
6666 /* :silent */ | |
6667 if (msg_silent > 0) | |
6668 result += add_cmd_modifier(buf, | |
6669 emsg_silent > 0 ? "silent!" : "silent", &multi_mods); | |
6670 #ifdef FEAT_WINDOWS | |
6671 /* :tab */ | |
6672 if (cmdmod.tab > 0) | |
6673 result += add_cmd_modifier(buf, "tab", &multi_mods); | |
6674 /* :topleft */ | |
6675 if (cmdmod.split & WSP_TOP) | |
6676 result += add_cmd_modifier(buf, "topleft", &multi_mods); | |
6677 #endif | |
6678 /* TODO: How to support :unsilent?*/ | |
6679 /* :verbose */ | |
6680 if (p_verbose > 0) | |
6681 result += add_cmd_modifier(buf, "verbose", &multi_mods); | |
6682 #ifdef FEAT_WINDOWS | |
6683 /* :vertical */ | |
6684 if (cmdmod.split & WSP_VERT) | |
6685 result += add_cmd_modifier(buf, "vertical", &multi_mods); | |
6686 #endif | |
6687 if (quote && buf != NULL) | |
6688 { | |
6689 buf += result - 2; | |
6690 *buf = '"'; | |
6691 } | |
6586 break; | 6692 break; |
6587 } | 6693 } |
6588 | 6694 |
6589 case ct_REGISTER: | 6695 case ct_REGISTER: |
6590 result = eap->regname ? 1 : 0; | 6696 result = eap->regname ? 1 : 0; |