Merge #8866 from janlazo/vim-8.0.0878

This commit is contained in:
Justin M. Keyes 2018-08-20 23:09:10 +02:00 committed by GitHub
commit 0839c44257
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 365 additions and 164 deletions

View File

@ -163,12 +163,14 @@ CTRL-R CTRL-F *c_CTRL-R_CTRL-F* *c_<C-R>_<C-F>*
CTRL-R CTRL-P *c_CTRL-R_CTRL-P* *c_<C-R>_<C-P>*
CTRL-R CTRL-W *c_CTRL-R_CTRL-W* *c_<C-R>_<C-W>*
CTRL-R CTRL-A *c_CTRL-R_CTRL-A* *c_<C-R>_<C-A>*
CTRL-R CTRL-L *c_CTRL-R_CTRL-L* *c_<C-R>_<C-L>*
Insert the object under the cursor:
CTRL-F the Filename under the cursor
CTRL-P the Filename under the cursor, expanded with
'path' as in |gf|
CTRL-W the Word under the cursor
CTRL-A the WORD under the cursor; see |WORD|
CTRL-L the line under the cursor
When 'incsearch' is set the cursor position at the end of the
currently displayed match is used. With CTRL-W the part of
@ -176,8 +178,8 @@ CTRL-R CTRL-A *c_CTRL-R_CTRL-A* *c_<C-R>_<C-A>*
*c_CTRL-R_CTRL-R* *c_<C-R>_<C-R>*
*c_CTRL-R_CTRL-O* *c_<C-R>_<C-O>*
CTRL-R CTRL-R {0-9a-z"%#:-=. CTRL-F CTRL-P CTRL-W CTRL-A}
CTRL-R CTRL-O {0-9a-z"%#:-=. CTRL-F CTRL-P CTRL-W CTRL-A}
CTRL-R CTRL-R {0-9a-z"%#:-=. CTRL-F CTRL-P CTRL-W CTRL-A CTRL-L}
CTRL-R CTRL-O {0-9a-z"%#:-=. CTRL-F CTRL-P CTRL-W CTRL-A CTRL-L}
Insert register or object under the cursor. Works like
|c_CTRL-R| but inserts the text literally. For example, if
register a contains "xy^Hz" (where ^H is a backspace),
@ -786,6 +788,11 @@ Also see |`=|.
Note: these are typed literally, they are not special keys!
<cword> is replaced with the word under the cursor (like |star|)
<cWORD> is replaced with the WORD under the cursor (see |WORD|)
<cexpr> is replaced with the word under the cursor, including more
to form a C expression. E.g., when the cursor is on "arg"
of "ptr->arg" then the result is "ptr->arg"; when the
cursor is on "]" of "list[idx]" then the result is
"list[idx]". This is used for |v:beval_text|.
<cfile> is replaced with the path name under the cursor (like what
|gf| uses)
<afile> When executing autocommands, is replaced with the file name

View File

@ -4079,6 +4079,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
specifies what for. The following completion types are
supported:
arglist file names in argument list
augroup autocmd groups
buffer buffer names
behave :behave suboptions
@ -4099,6 +4100,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
highlight highlight groups
history :history suboptions
locale locale names (as output of locale -a)
mapclear buffer argument
mapping mapping name
menu menus
messages |:messages| suboptions

View File

@ -1208,6 +1208,7 @@ By default, the arguments of user defined commands do not undergo completion.
However, by specifying one or the other of the following attributes, argument
completion can be enabled:
-complete=arglist file names in argument list
-complete=augroup autocmd groups
-complete=buffer buffer names
-complete=behave :behave suboptions
@ -1227,6 +1228,7 @@ completion can be enabled:
-complete=highlight highlight groups
-complete=history :history suboptions
-complete=locale locale names (as output of locale -a)
-complete=mapclear buffer argument
-complete=mapping mapping name
-complete=menu menus
-complete=messages |:messages| suboptions

View File

@ -2659,9 +2659,8 @@ buf_T *setaltfname(char_u *ffname, char_u *sfname, linenr_T lnum)
* Get alternate file name for current window.
* Return NULL if there isn't any, and give error message if requested.
*/
char_u *
getaltfname (
int errmsg /* give error message */
char_u * getaltfname(
bool errmsg // give error message
)
{
char_u *fname;

View File

@ -2254,6 +2254,15 @@ static int alist_add_list(int count, char_u **files, int after)
}
}
// Function given to ExpandGeneric() to obtain the possible arguments of the
// argedit and argdelete commands.
char_u *get_arglist_name(expand_T *xp FUNC_ATTR_UNUSED, int idx)
{
if (idx >= ARGCOUNT) {
return NULL;
}
return alist_name(&ARGLIST[idx]);
}
/// ":compiler[!] {name}"
void ex_compiler(exarg_T *eap)

View File

@ -2665,8 +2665,8 @@ const char * set_one_cmd_context(
size_t len = 0;
exarg_T ea;
int context = EXPAND_NOTHING;
int forceit = false;
int usefilter = false; // Filter instead of file name.
bool forceit = false;
bool usefilter = false; // Filter instead of file name.
ExpandInit(xp);
xp->xp_pattern = (char_u *)buff;
@ -2786,9 +2786,9 @@ const char * set_one_cmd_context(
xp->xp_context = EXPAND_NOTHING; /* Default now that we're past command */
if (*p == '!') { /* forced commands */
forceit = TRUE;
++p;
if (*p == '!') { // forced commands
forceit = true;
p++;
}
/*
@ -2813,10 +2813,10 @@ const char * set_one_cmd_context(
}
if (ea.cmdidx == CMD_read) {
usefilter = forceit; /* :r! filter if forced */
if (*arg == '!') { /* :r !filter */
++arg;
usefilter = TRUE;
usefilter = forceit; // :r! filter if forced
if (*arg == '!') { // :r !filter
arg++;
usefilter = true;
}
}
@ -2978,7 +2978,7 @@ const char * set_one_cmd_context(
// A full match ~user<Tab> will be replaced by user's home
// directory i.e. something like ~user<Tab> -> /home/user/
if (*p == NUL && p > (const char *)xp->xp_pattern + 1
&& match_user(xp->xp_pattern + 1) == 1) {
&& match_user(xp->xp_pattern + 1) >= 1) {
xp->xp_context = EXPAND_USER;
++xp->xp_pattern;
}
@ -3350,6 +3350,19 @@ const char * set_one_cmd_context(
case CMD_xunmap:
return (const char *)set_context_in_map_cmd(
xp, (char_u *)cmd, (char_u *)arg, forceit, false, true, ea.cmdidx);
case CMD_mapclear:
case CMD_nmapclear:
case CMD_vmapclear:
case CMD_omapclear:
case CMD_imapclear:
case CMD_cmapclear:
case CMD_lmapclear:
case CMD_smapclear:
case CMD_xmapclear:
xp->xp_context = EXPAND_MAPCLEAR;
xp->xp_pattern = (char_u *)arg;
break;
case CMD_abbreviate: case CMD_noreabbrev:
case CMD_cabbrev: case CMD_cnoreabbrev:
case CMD_iabbrev: case CMD_inoreabbrev:
@ -3441,6 +3454,13 @@ const char * set_one_cmd_context(
xp->xp_pattern = (char_u *)arg;
break;
case CMD_argdelete:
while ((xp->xp_pattern = vim_strchr((const char_u *)arg, ' ')) != NULL) {
arg = (const char *)(xp->xp_pattern + 1);
}
xp->xp_context = EXPAND_ARGLIST;
xp->xp_pattern = (char_u *)arg;
break;
default:
break;
@ -4846,6 +4866,7 @@ static struct {
*/
static const char *command_complete[] =
{
[EXPAND_ARGLIST] = "arglist",
[EXPAND_AUGROUP] = "augroup",
[EXPAND_BEHAVE] = "behave",
[EXPAND_BUFFERS] = "buffer",
@ -4870,6 +4891,7 @@ static const char *command_complete[] =
#ifdef HAVE_WORKING_LIBINTL
[EXPAND_LOCALES] = "locale",
#endif
[EXPAND_MAPCLEAR] = "mapclear",
[EXPAND_MAPPINGS] = "mapping",
[EXPAND_MENUS] = "menu",
[EXPAND_MESSAGES] = "messages",
@ -8370,23 +8392,25 @@ ssize_t find_cmdline_var(const char_u *src, size_t *usedlen)
"%",
#define SPEC_PERC 0
"#",
#define SPEC_HASH 1
"<cword>", /* cursor word */
#define SPEC_CWORD 2
"<cWORD>", /* cursor WORD */
#define SPEC_CCWORD 3
"<cfile>", /* cursor path name */
#define SPEC_CFILE 4
"<sfile>", /* ":so" file name */
#define SPEC_SFILE 5
"<slnum>", /* ":so" file line number */
#define SPEC_SLNUM 6
"<afile>", /* autocommand file name */
# define SPEC_AFILE 7
"<abuf>", /* autocommand buffer number */
# define SPEC_ABUF 8
"<amatch>", /* autocommand match name */
# define SPEC_AMATCH 9
#define SPEC_HASH (SPEC_PERC + 1)
"<cword>", // cursor word
#define SPEC_CWORD (SPEC_HASH + 1)
"<cWORD>", // cursor WORD
#define SPEC_CCWORD (SPEC_CWORD + 1)
"<cexpr>", // expr under cursor
#define SPEC_CEXPR (SPEC_CCWORD + 1)
"<cfile>", // cursor path name
#define SPEC_CFILE (SPEC_CEXPR + 1)
"<sfile>", // ":so" file name
#define SPEC_SFILE (SPEC_CFILE + 1)
"<slnum>", // ":so" file line number
#define SPEC_SLNUM (SPEC_SFILE + 1)
"<afile>", // autocommand file name
#define SPEC_AFILE (SPEC_SLNUM + 1)
"<abuf>", // autocommand buffer number
#define SPEC_ABUF (SPEC_AFILE + 1)
"<amatch>", // autocommand match name
#define SPEC_AMATCH (SPEC_ABUF + 1)
};
for (size_t i = 0; i < ARRAY_SIZE(spec_str); ++i) {
@ -8467,10 +8491,16 @@ eval_vars (
/*
* word or WORD under cursor
*/
if (spec_idx == SPEC_CWORD || spec_idx == SPEC_CCWORD) {
resultlen = find_ident_under_cursor(&result, (spec_idx == SPEC_CWORD
? (FIND_IDENT|FIND_STRING)
: FIND_STRING));
if (spec_idx == SPEC_CWORD
|| spec_idx == SPEC_CCWORD
|| spec_idx == SPEC_CEXPR) {
resultlen = find_ident_under_cursor(
&result,
spec_idx == SPEC_CWORD
? (FIND_IDENT | FIND_STRING)
: (spec_idx == SPEC_CEXPR
? (FIND_IDENT | FIND_STRING | FIND_EVAL)
: FIND_STRING));
if (resultlen == 0) {
*errormsg = (char_u *)"";
return NULL;
@ -8507,9 +8537,13 @@ eval_vars (
if (*s == '<') /* "#<99" uses v:oldfiles */
++s;
i = getdigits_int(&s);
*usedlen = (size_t)(s - src); /* length of what we expand */
if (s == src + 2 && src[1] == '-') {
// just a minus sign, don't skip over it
s--;
}
*usedlen = (size_t)(s - src); // length of what we expand
if (src[1] == '<') {
if (src[1] == '<' && i != 0) {
if (*usedlen < 2) {
/* Should we give an error message for #<text? */
*usedlen = 1;
@ -8522,6 +8556,9 @@ eval_vars (
return NULL;
}
} else {
if (i == 0 && src[1] == '<' && *usedlen > 1) {
*usedlen = 1;
}
buf = buflist_findnr(i);
if (buf == NULL) {
*errormsg = (char_u *)_(
@ -9655,6 +9692,14 @@ char_u *get_messages_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
return NULL;
}
char_u *get_mapclear_arg(expand_T *xp FUNC_ATTR_UNUSED, int idx)
{
if (idx == 0) {
return (char_u *)"<buffer>";
}
return NULL;
}
static TriState filetype_detect = kNone;
static TriState filetype_plugin = kNone;
static TriState filetype_indent = kNone;

View File

@ -3290,17 +3290,18 @@ void restore_cmdline_alloc(char_u *p)
/// @returns FAIL for failure, OK otherwise
static bool cmdline_paste(int regname, bool literally, bool remcr)
{
long i;
char_u *arg;
char_u *p;
int allocated;
bool allocated;
struct cmdline_info save_ccline;
/* check for valid regname; also accept special characters for CTRL-R in
* the command line */
if (regname != Ctrl_F && regname != Ctrl_P && regname != Ctrl_W
&& regname != Ctrl_A && !valid_yank_reg(regname, false))
&& regname != Ctrl_A && regname != Ctrl_L
&& !valid_yank_reg(regname, false)) {
return FAIL;
}
/* A register containing CTRL-R can cause an endless loop. Allow using
* CTRL-C to break the loop. */
@ -3312,9 +3313,9 @@ static bool cmdline_paste(int regname, bool literally, bool remcr)
/* Need to save and restore ccline. And set "textlock" to avoid nasty
* things like going to another buffer when evaluating an expression. */
save_cmdline(&save_ccline);
++textlock;
i = get_spec_reg(regname, &arg, &allocated, TRUE);
--textlock;
textlock++;
const bool i = get_spec_reg(regname, &arg, &allocated, true);
textlock--;
restore_cmdline(&save_ccline);
if (i) {
@ -4760,6 +4761,7 @@ ExpandFromContext (
} tab[] = {
{ EXPAND_COMMANDS, get_command_name, false, true },
{ EXPAND_BEHAVE, get_behave_arg, true, true },
{ EXPAND_MAPCLEAR, get_mapclear_arg, true, true },
{ EXPAND_MESSAGES, get_messages_arg, true, true },
{ EXPAND_HISTORY, get_history_arg, true, true },
{ EXPAND_USER_COMMANDS, get_user_commands, false, true },
@ -4787,6 +4789,7 @@ ExpandFromContext (
#endif
{ EXPAND_ENV_VARS, get_env_name, true, true },
{ EXPAND_USER, get_users, true, false },
{ EXPAND_ARGLIST, get_arglist_name, true, false },
};
int i;

View File

@ -2990,6 +2990,43 @@ void reset_VIsual(void)
}
}
// Check for a balloon-eval special item to include when searching for an
// identifier. When "dir" is BACKWARD "ptr[-1]" must be valid!
// Returns true if the character at "*ptr" should be included.
// "dir" is FORWARD or BACKWARD, the direction of searching.
// "*colp" is in/decremented if "ptr[-dir]" should also be included.
// "bnp" points to a counter for square brackets.
static bool find_is_eval_item(
const char_u *const ptr,
int *const colp,
int *const bnp,
const int dir)
{
// Accept everything inside [].
if ((*ptr == ']' && dir == BACKWARD) || (*ptr == '[' && dir == FORWARD)) {
*bnp += 1;
}
if (*bnp > 0) {
if ((*ptr == '[' && dir == BACKWARD) || (*ptr == ']' && dir == FORWARD)) {
*bnp -= 1;
}
return true;
}
// skip over "s.var"
if (*ptr == '.') {
return true;
}
// two-character item: s->var
if (ptr[dir == BACKWARD ? 0 : 1] == '>'
&& ptr[dir == BACKWARD ? -1 : 0] == '-') {
*colp += dir;
return true;
}
return false;
}
/*
* Find the identifier under or to the right of the cursor.
* "find_type" can have one of three values:
@ -3030,6 +3067,7 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
int this_class = 0;
int prev_class;
int prevcol;
int bn = 0; // bracket nesting
/*
* if i == 0: try to find an identifier
@ -3041,71 +3079,62 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
* 1. skip to start of identifier/string
*/
col = startcol;
if (has_mbyte) {
while (ptr[col] != NUL) {
this_class = mb_get_class(ptr + col);
if (this_class != 0 && (i == 1 || this_class != 1))
break;
col += (*mb_ptr2len)(ptr + col);
while (ptr[col] != NUL) {
// Stop at a ']' to evaluate "a[x]".
if ((find_type & FIND_EVAL) && ptr[col] == ']') {
break;
}
} else
while (ptr[col] != NUL
&& (i == 0 ? !vim_iswordc(ptr[col]) : ascii_iswhite(ptr[col]))
)
++col;
this_class = mb_get_class(ptr + col);
if (this_class != 0 && (i == 1 || this_class != 1)) {
break;
}
col += utfc_ptr2len(ptr + col);
}
// When starting on a ']' count it, so that we include the '['.
bn = ptr[col] == ']';
/*
* 2. Back up to start of identifier/string.
*/
if (has_mbyte) {
/* Remember class of character under cursor. */
this_class = mb_get_class(ptr + col);
while (col > 0 && this_class != 0) {
prevcol = col - 1 - (*mb_head_off)(ptr, ptr + col - 1);
prev_class = mb_get_class(ptr + prevcol);
if (this_class != prev_class
&& (i == 0
|| prev_class == 0
|| (find_type & FIND_IDENT))
)
break;
col = prevcol;
}
/* If we don't want just any old string, or we've found an
* identifier, stop searching. */
if (this_class > 2)
this_class = 2;
if (!(find_type & FIND_STRING) || this_class == 2)
break;
// Remember class of character under cursor.
if ((find_type & FIND_EVAL) && ptr[col] == ']') {
this_class = mb_get_class((char_u *)"a");
} else {
while (col > 0
&& ((i == 0
? vim_iswordc(ptr[col - 1])
: (!ascii_iswhite(ptr[col - 1])
&& (!(find_type & FIND_IDENT)
|| !vim_iswordc(ptr[col - 1]))))
))
--col;
/* If we don't want just any old string, or we've found an
* identifier, stop searching. */
if (!(find_type & FIND_STRING) || vim_iswordc(ptr[col]))
this_class = mb_get_class(ptr + col);
}
while (col > 0 && this_class != 0) {
prevcol = col - 1 - utf_head_off(ptr, ptr + col - 1);
prev_class = mb_get_class(ptr + prevcol);
if (this_class != prev_class
&& (i == 0
|| prev_class == 0
|| (find_type & FIND_IDENT))
&& (!(find_type & FIND_EVAL)
|| prevcol == 0
|| !find_is_eval_item(ptr + prevcol, &prevcol, &bn, BACKWARD))) {
break;
}
col = prevcol;
}
// If we don't want just any old string, or we've found an
// identifier, stop searching.
if (this_class > 2) {
this_class = 2;
}
if (!(find_type & FIND_STRING) || this_class == 2) {
break;
}
}
if (ptr[col] == NUL || (i == 0 && (
has_mbyte ? this_class != 2 :
!vim_iswordc(ptr[col])))) {
/*
* didn't find an identifier or string
*/
if (find_type & FIND_STRING)
if (ptr[col] == NUL || (i == 0 && this_class != 2)) {
// didn't find an identifier or string
if (find_type & FIND_STRING) {
EMSG(_("E348: No string under cursor"));
else
} else {
EMSG(_(e_noident));
}
return 0;
}
ptr += col;
@ -3114,21 +3143,20 @@ size_t find_ident_at_pos(win_T *wp, linenr_T lnum, colnr_T startcol,
/*
* 3. Find the end if the identifier/string.
*/
bn = 0;
startcol -= col;
col = 0;
if (has_mbyte) {
/* Search for point of changing multibyte character class. */
this_class = mb_get_class(ptr);
while (ptr[col] != NUL
&& ((i == 0 ? mb_get_class(ptr + col) == this_class
: mb_get_class(ptr + col) != 0)
))
col += (*mb_ptr2len)(ptr + col);
} else
while ((i == 0 ? vim_iswordc(ptr[col])
: (ptr[col] != NUL && !ascii_iswhite(ptr[col])))
) {
++col;
}
// Search for point of changing multibyte character class.
this_class = mb_get_class(ptr);
while (ptr[col] != NUL
&& ((i == 0
? mb_get_class(ptr + col) == this_class
: mb_get_class(ptr + col) != 0)
|| ((find_type & FIND_EVAL)
&& col <= (int)startcol
&& find_is_eval_item(ptr + col, &col, &bn, FORWARD)))) {
col += utfc_ptr2len(ptr + col);
}
assert(col >= 0);
return (size_t)col;

View File

@ -1110,7 +1110,7 @@ int insert_reg(
)
{
int retval = OK;
int allocated;
bool allocated;
/*
* It is possible to get into an endless loop by having CTRL-R a in
@ -1187,82 +1187,92 @@ static void stuffescaped(const char *arg, int literally)
}
}
/*
* If "regname" is a special register, return TRUE and store a pointer to its
* value in "argp".
*/
int get_spec_reg(
// If "regname" is a special register, return true and store a pointer to its
// value in "argp".
bool get_spec_reg(
int regname,
char_u **argp,
int *allocated, /* return: TRUE when value was allocated */
int errmsg /* give error message when failing */
bool *allocated, // return: true when value was allocated
bool errmsg // give error message when failing
)
{
size_t cnt;
*argp = NULL;
*allocated = FALSE;
*allocated = false;
switch (regname) {
case '%': /* file name */
if (errmsg)
check_fname(); /* will give emsg if not set */
*argp = curbuf->b_fname;
return TRUE;
return true;
case '#': /* alternate file name */
*argp = getaltfname(errmsg); /* may give emsg if not set */
return TRUE;
case '#': // alternate file name
*argp = getaltfname(errmsg); // may give emsg if not set
return true;
case '=': /* result of expression */
*argp = get_expr_line();
*allocated = TRUE;
return TRUE;
*allocated = true;
return true;
case ':': /* last command line */
if (last_cmdline == NULL && errmsg)
EMSG(_(e_nolastcmd));
*argp = last_cmdline;
return TRUE;
return true;
case '/': /* last search-pattern */
if (last_search_pat() == NULL && errmsg)
EMSG(_(e_noprevre));
*argp = last_search_pat();
return TRUE;
return true;
case '.': /* last inserted text */
*argp = get_last_insert_save();
*allocated = TRUE;
if (*argp == NULL && errmsg)
*allocated = true;
if (*argp == NULL && errmsg) {
EMSG(_(e_noinstext));
return TRUE;
}
return true;
case Ctrl_F: /* Filename under cursor */
case Ctrl_P: /* Path under cursor, expand via "path" */
if (!errmsg)
return FALSE;
*argp = file_name_at_cursor(FNAME_MESS | FNAME_HYP
| (regname == Ctrl_P ? FNAME_EXP : 0), 1L, NULL);
*allocated = TRUE;
return TRUE;
case Ctrl_F: // Filename under cursor
case Ctrl_P: // Path under cursor, expand via "path"
if (!errmsg) {
return false;
}
*argp = file_name_at_cursor(
FNAME_MESS | FNAME_HYP | (regname == Ctrl_P ? FNAME_EXP : 0),
1L, NULL);
*allocated = true;
return true;
case Ctrl_W: /* word under cursor */
case Ctrl_A: /* WORD (mnemonic All) under cursor */
if (!errmsg)
return FALSE;
case Ctrl_W: // word under cursor
case Ctrl_A: // WORD (mnemonic All) under cursor
if (!errmsg) {
return false;
}
cnt = find_ident_under_cursor(argp, (regname == Ctrl_W
? (FIND_IDENT|FIND_STRING)
: FIND_STRING));
*argp = cnt ? vim_strnsave(*argp, cnt) : NULL;
*allocated = TRUE;
return TRUE;
*allocated = true;
return true;
case Ctrl_L: // Line under cursor
if (!errmsg) {
return false;
}
*argp = ml_get_buf(curwin->w_buffer, curwin->w_cursor.lnum, false);
return true;
case '_': /* black hole: always empty */
*argp = (char_u *)"";
return TRUE;
return true;
}
return FALSE;
return false;
}
/// Paste a yank register into the command line.
@ -2652,7 +2662,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
int lendiff = 0;
pos_T old_pos;
char_u *insert_string = NULL;
int allocated = FALSE;
bool allocated = false;
long cnt;
if (flags & PUT_FIXINDENT)
@ -2748,9 +2758,10 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
* For special registers '%' (file name), '#' (alternate file name) and
* ':' (last command line), etc. we have to create a fake yank register.
*/
if (get_spec_reg(regname, &insert_string, &allocated, TRUE)) {
if (insert_string == NULL)
if (get_spec_reg(regname, &insert_string, &allocated, true)) {
if (insert_string == NULL) {
return;
}
}
if (!curbuf->terminal) {
@ -4907,10 +4918,11 @@ void *get_reg_contents(int regname, int flags)
return NULL;
char_u *retval;
int allocated;
if (get_spec_reg(regname, &retval, &allocated, FALSE)) {
if (retval == NULL)
bool allocated;
if (get_spec_reg(regname, &retval, &allocated, false)) {
if (retval == NULL) {
return NULL;
}
if (allocated) {
return get_reg_wrap_one_line(retval, flags);
}

View File

@ -137,6 +137,11 @@ func Test_getcompletion()
let l = getcompletion('v:notexists', 'var')
call assert_equal([], l)
args a.c b.c
let l = getcompletion('', 'arglist')
call assert_equal(['a.c', 'b.c'], l)
%argdelete
let l = getcompletion('', 'augroup')
call assert_true(index(l, 'END') >= 0)
let l = getcompletion('blahblah', 'augroup')
@ -222,6 +227,11 @@ func Test_getcompletion()
let l = getcompletion('not', 'messages')
call assert_equal([], l)
let l = getcompletion('', 'mapclear')
call assert_true(index(l, '<buffer>') >= 0)
let l = getcompletion('not', 'mapclear')
call assert_equal([], l)
if has('cscope')
let l = getcompletion('', 'cscope')
let cmds = ['add', 'find', 'help', 'kill', 'reset', 'show']
@ -311,6 +321,9 @@ func Test_paste_in_cmdline()
call feedkeys("ft:aaa \<C-R>\<C-F> bbb\<C-B>\"\<CR>", 'tx')
call assert_equal('"aaa /tmp/some bbb', @:)
call feedkeys(":aaa \<C-R>\<C-L> bbb\<C-B>\"\<CR>", 'tx')
call assert_equal('"aaa '.getline(1).' bbb', @:)
set incsearch
call feedkeys("fy:aaa veryl\<C-R>\<C-W> bbb\<C-B>\"\<CR>", 'tx')
call assert_equal('"aaa verylongword bbb', @:)
@ -375,6 +388,27 @@ func Test_cmdline_complete_user_cmd()
delcommand Foo
endfunc
func Test_cmdline_write_alternatefile()
new
call setline('.', ['one', 'two'])
f foo.txt
new
f #-A
call assert_equal('foo.txt-A', expand('%'))
f #<-B.txt
call assert_equal('foo-B.txt', expand('%'))
f %<
call assert_equal('foo-B', expand('%'))
new
call assert_fails('f #<', 'E95')
bw!
f foo-B.txt
f %<-A
call assert_equal('foo-B-A', expand('%'))
bw!
bw!
endfunc
" using a leading backslash here
set cpo+=C
@ -430,6 +464,22 @@ func Test_getcmdtype()
cunmap <F6>
endfunc
func Test_getcmdwintype()
call feedkeys("q/:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
call assert_equal('/', a)
call feedkeys("q?:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
call assert_equal('?', a)
call feedkeys("q::let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
call assert_equal(':', a)
call feedkeys(":\<C-F>:let a = getcmdwintype()\<CR>:q\<CR>", 'x!')
call assert_equal(':', a)
call assert_equal('', getcmdwintype())
endfunc
func Test_verbosefile()
set verbosefile=Xlog
echomsg 'foo'
@ -440,4 +490,25 @@ func Test_verbosefile()
call delete('Xlog')
endfunc
func Test_setcmdpos()
func InsertTextAtPos(text, pos)
call assert_equal(0, setcmdpos(a:pos))
return a:text
endfunc
" setcmdpos() with position in the middle of the command line.
call feedkeys(":\"12\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
call assert_equal('"1ab2', @:)
call feedkeys(":\"12\<C-R>\<C-R>=InsertTextAtPos('a', 3)\<CR>b\<CR>", 'xt')
call assert_equal('"1b2a', @:)
" setcmdpos() with position beyond the end of the command line.
call feedkeys(":\"12\<C-B>\<C-R>=InsertTextAtPos('a', 10)\<CR>b\<CR>", 'xt')
call assert_equal('"12ab', @:)
" setcmdpos() returns 1 when not editing the command line.
call assert_equal(1, setcmdpos(3))
endfunc
set cpo&

View File

@ -392,10 +392,31 @@ func! Test_normal10_expand()
call setline(1, ['1', 'ifooar,,cbar'])
2
norm! $
let a=expand('<cword>')
let b=expand('<cWORD>')
call assert_equal('cbar', a)
call assert_equal('ifooar,,cbar', b)
call assert_equal('cbar', expand('<cword>'))
call assert_equal('ifooar,,cbar', expand('<cWORD>'))
call setline(1, ['prx = list[idx];'])
1
let expected = ['', 'prx', 'prx', 'prx',
\ 'list', 'list', 'list', 'list', 'list', 'list', 'list',
\ 'idx', 'idx', 'idx', 'idx',
\ 'list[idx]',
\ '];',
\ ]
for i in range(1, 16)
exe 'norm ' . i . '|'
call assert_equal(expected[i], expand('<cexpr>'), 'i == ' . i)
endfor
if executable('echo')
" Test expand(`...`) i.e. backticks command expansion.
" MS-Windows has a trailing space.
call assert_match('^abcde *$', expand('`echo abcde`'))
endif
" Test expand(`=...`) i.e. backticks expression expansion
call assert_equal('5', expand('`=2+3`'))
" clean up
bw!
endfunc
@ -1536,12 +1557,12 @@ fun! Test_normal29_brace()
\ 'the ''{'' flag is in ''cpoptions'' then ''{'' in the first column is used as a',
\ 'paragraph boundary |posix|.',
\ '{',
\ 'This is no paragaraph',
\ 'This is no paragraph',
\ 'unless the ''{'' is set',
\ 'in ''cpoptions''',
\ '}',
\ '.IP',
\ 'The nroff macros IP seperates a paragraph',
\ 'The nroff macros IP separates a paragraph',
\ 'That means, it must be a ''.''',
\ 'followed by IP',
\ '.LPIt does not matter, if afterwards some',
@ -1556,7 +1577,7 @@ fun! Test_normal29_brace()
1
norm! 0d2}
call assert_equal(['.IP',
\ 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
\ 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''', 'followed by IP',
\ '.LPIt does not matter, if afterwards some', 'more characters follow.', '.SHAlso section boundaries from the nroff',
\ 'macros terminate a paragraph. That means', 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
norm! 0d}
@ -1576,21 +1597,21 @@ fun! Test_normal29_brace()
" set cpo+={
" 1
" norm! 0d2}
" call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
" \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
" call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
" \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
" \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
" \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
" \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
" $
" norm! d}
" call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
" \ '.IP', 'The nroff macros IP seperates a paragraph', 'That means, it must be a ''.''',
" call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}',
" \ '.IP', 'The nroff macros IP separates a paragraph', 'That means, it must be a ''.''',
" \ 'followed by IP', '.LPIt does not matter, if afterwards some', 'more characters follow.',
" \ '.SHAlso section boundaries from the nroff', 'macros terminate a paragraph. That means',
" \ 'a character like this:', '.NH', 'End of text here', ''], getline(1,'$'))
" norm! gg}
" norm! d5}
" call assert_equal(['{', 'This is no paragaraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
" call assert_equal(['{', 'This is no paragraph', 'unless the ''{'' is set', 'in ''cpoptions''', '}', ''], getline(1,'$'))
" clean up
set cpo-={

View File

@ -155,6 +155,8 @@ enum {
EXPAND_USER_ADDR_TYPE,
EXPAND_PACKADD,
EXPAND_MESSAGES,
EXPAND_MAPCLEAR,
EXPAND_ARGLIST,
EXPAND_CHECKHEALTH,
};