Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2018-06-12 20:28:23 -07:00
32 changed files with 390 additions and 175 deletions
+1
View File
@@ -376,6 +376,7 @@ Environment variables are used to pass information to the running job:
COLUMNS number of columns in the terminal initially
COLORS number of colors, 't_Co' (256*256*256 in the GUI)
VIM_SERVERNAME v:servername
VIM_TERMINAL v:version
MS-Windows ~
+6 -2
View File
@@ -5567,7 +5567,11 @@ job_check_ended(void)
* Returns NULL when out of memory.
*/
job_T *
job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
job_start(
typval_T *argvars,
char **argv_arg,
jobopt_T *opt_arg,
int is_terminal UNUSED)
{
job_T *job;
char_u *cmd = NULL;
@@ -5721,7 +5725,7 @@ job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg)
ch_log(NULL, "Starting job: %s", (char *)ga.ga_data);
ga_clear(&ga);
}
mch_job_start(argv, job, &opt);
mch_job_start(argv, job, &opt, is_terminal);
#else
ch_log(NULL, "Starting job: %s", (char *)cmd);
mch_job_start((char *)cmd, job, &opt);
+9 -6
View File
@@ -1928,8 +1928,8 @@ vim_str2nr(
while ('0' <= *ptr && *ptr <= '1')
{
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 2)
un = 2 * un + (unsigned long)(*ptr - '0');
if (un <= UVARNUM_MAX / 2)
un = 2 * un + (uvarnumber_T)(*ptr - '0');
else
un = UVARNUM_MAX;
++ptr;
@@ -1943,7 +1943,7 @@ vim_str2nr(
while ('0' <= *ptr && *ptr <= '7')
{
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 8)
if (un <= UVARNUM_MAX / 8)
un = 8 * un + (uvarnumber_T)(*ptr - '0');
else
un = UVARNUM_MAX;
@@ -1960,7 +1960,7 @@ vim_str2nr(
while (vim_isxdigit(*ptr))
{
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 16)
if (un <= UVARNUM_MAX / 16)
un = 16 * un + (uvarnumber_T)hex2nr(*ptr);
else
un = UVARNUM_MAX;
@@ -1974,9 +1974,12 @@ vim_str2nr(
/* decimal */
while (VIM_ISDIGIT(*ptr))
{
uvarnumber_T digit = (uvarnumber_T)(*ptr - '0');
/* avoid ubsan error for overflow */
if (un < UVARNUM_MAX / 10)
un = 10 * un + (uvarnumber_T)(*ptr - '0');
if (un < UVARNUM_MAX / 10
|| (un == UVARNUM_MAX / 10 && digit <= UVARNUM_MAX % 10))
un = 10 * un + digit;
else
un = UVARNUM_MAX;
++ptr;
+15 -9
View File
@@ -1903,7 +1903,7 @@ init_prompt(int cmdchar_todo)
|| Insstart_orig.col != (int)STRLEN(prompt))
{
Insstart.lnum = curwin->w_cursor.lnum;
Insstart.col = STRLEN(prompt);
Insstart.col = (int)STRLEN(prompt);
Insstart_orig = Insstart;
Insstart_textlen = Insstart.col;
Insstart_blank_vcol = MAXCOL;
@@ -1913,7 +1913,7 @@ init_prompt(int cmdchar_todo)
if (cmdchar_todo == 'A')
coladvance((colnr_T)MAXCOL);
if (cmdchar_todo == 'I' || curwin->w_cursor.col <= (int)STRLEN(prompt))
curwin->w_cursor.col = STRLEN(prompt);
curwin->w_cursor.col = (int)STRLEN(prompt);
/* Make sure the cursor is in a valid position. */
check_cursor();
}
@@ -4215,7 +4215,7 @@ expand_by_function(
{
list_T *matchlist = NULL;
dict_T *matchdict = NULL;
char_u *args[2];
typval_T args[3];
char_u *funcname;
pos_T pos;
win_T *curwin_save;
@@ -4227,15 +4227,18 @@ expand_by_function(
return;
/* Call 'completefunc' to obtain the list of matches. */
args[0] = (char_u *)"0";
args[1] = base;
args[0].v_type = VAR_NUMBER;
args[0].vval.v_number = 0;
args[1].v_type = VAR_STRING;
args[1].vval.v_string = base != NULL ? base : (char_u *)"";
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
/* Call a function, which returns a list or dict. */
if (call_vim_function(funcname, 2, args, FALSE, FALSE, &rettv) == OK)
if (call_vim_function(funcname, 2, args, &rettv, FALSE) == OK)
{
switch (rettv.v_type)
{
@@ -5542,7 +5545,7 @@ ins_complete(int c, int enable_pum)
* Call user defined function 'completefunc' with "a:findstart"
* set to 1 to obtain the length of text to use for completion.
*/
char_u *args[2];
typval_T args[3];
int col;
char_u *funcname;
pos_T pos;
@@ -5562,8 +5565,11 @@ ins_complete(int c, int enable_pum)
return FAIL;
}
args[0] = (char_u *)"1";
args[1] = NULL;
args[0].v_type = VAR_NUMBER;
args[0].vval.v_number = 1;
args[1].v_type = VAR_STRING;
args[1].vval.v_string = (char_u *)"";
args[2].v_type = VAR_UNKNOWN;
pos = curwin->w_cursor;
curwin_save = curwin;
curbuf_save = curbuf;
+18 -60
View File
@@ -1011,63 +1011,22 @@ eval_expr(char_u *arg, char_u **nextcmd)
/*
* Call some Vim script function and return the result in "*rettv".
* Uses argv[argc] for the function arguments. Only Number and String
* arguments are currently supported.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc]
* should have type VAR_UNKNOWN.
* Returns OK or FAIL.
*/
int
call_vim_function(
char_u *func,
int argc,
char_u **argv,
int safe, /* use the sandbox */
int str_arg_only, /* all arguments are strings */
typval_T *rettv)
typval_T *argv,
typval_T *rettv,
int safe) /* use the sandbox */
{
typval_T *argvars;
varnumber_T n;
int len;
int i;
int doesrange;
void *save_funccalp = NULL;
int ret;
argvars = (typval_T *)alloc((unsigned)((argc + 1) * sizeof(typval_T)));
if (argvars == NULL)
return FAIL;
for (i = 0; i < argc; i++)
{
/* Pass a NULL or empty argument as an empty string */
if (argv[i] == NULL || *argv[i] == NUL)
{
argvars[i].v_type = VAR_STRING;
argvars[i].vval.v_string = (char_u *)"";
continue;
}
if (str_arg_only)
len = 0;
else
{
/* Recognize a number argument, the others must be strings. A dash
* is a string too. */
vim_str2nr(argv[i], NULL, &len, STR2NR_ALL, &n, NULL, 0);
if (len == 1 && *argv[i] == '-')
len = 0;
}
if (len != 0 && len == (int)STRLEN(argv[i]))
{
argvars[i].v_type = VAR_NUMBER;
argvars[i].vval.v_number = n;
}
else
{
argvars[i].v_type = VAR_STRING;
argvars[i].vval.v_string = argv[i];
}
}
if (safe)
{
save_funccalp = save_funccal();
@@ -1075,7 +1034,7 @@ call_vim_function(
}
rettv->v_type = VAR_UNKNOWN; /* clear_tv() uses this */
ret = call_func(func, (int)STRLEN(func), rettv, argc, argvars, NULL,
ret = call_func(func, (int)STRLEN(func), rettv, argc, argv, NULL,
curwin->w_cursor.lnum, curwin->w_cursor.lnum,
&doesrange, TRUE, NULL, NULL);
if (safe)
@@ -1083,7 +1042,6 @@ call_vim_function(
--sandbox;
restore_funccal(save_funccalp);
}
vim_free(argvars);
if (ret == FAIL)
clear_tv(rettv);
@@ -1094,20 +1052,20 @@ call_vim_function(
/*
* Call Vim script function "func" and return the result as a number.
* Returns -1 when calling the function fails.
* Uses argv[argc] for the function arguments.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
* have type VAR_UNKNOWN.
*/
varnumber_T
call_func_retnr(
char_u *func,
int argc,
char_u **argv,
typval_T *argv,
int safe) /* use the sandbox */
{
typval_T rettv;
varnumber_T retval;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
return -1;
retval = get_tv_number_chk(&rettv, NULL);
@@ -1122,20 +1080,20 @@ call_func_retnr(
/*
* Call Vim script function "func" and return the result as a string.
* Returns NULL when calling the function fails.
* Uses argv[argc] for the function arguments.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
* have type VAR_UNKNOWN.
*/
void *
call_func_retstr(
char_u *func,
int argc,
char_u **argv,
typval_T *argv,
int safe) /* use the sandbox */
{
typval_T rettv;
char_u *retval;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
return NULL;
retval = vim_strsave(get_tv_string(&rettv));
@@ -1146,20 +1104,20 @@ call_func_retstr(
/*
* Call Vim script function "func" and return the result as a List.
* Uses argv[argc] for the function arguments.
* Uses argv[0] to argv[argc - 1] for the function arguments. argv[argc] should
* have type VAR_UNKNOWN.
* Returns NULL when there is something wrong.
*/
void *
call_func_retlist(
char_u *func,
int argc,
char_u **argv,
typval_T *argv,
int safe) /* use the sandbox */
{
typval_T rettv;
/* All arguments are passed as strings, no conversion to number. */
if (call_vim_function(func, argc, argv, safe, TRUE, &rettv) == FAIL)
if (call_vim_function(func, argc, argv, &rettv, safe) == FAIL)
return NULL;
if (rettv.v_type != VAR_LIST)
+1 -1
View File
@@ -7273,7 +7273,7 @@ f_job_start(typval_T *argvars, typval_T *rettv)
rettv->v_type = VAR_JOB;
if (check_restricted() || check_secure())
return;
rettv->vval.v_job = job_start(argvars, NULL, NULL);
rettv->vval.v_job = job_start(argvars, NULL, NULL, FALSE);
}
/*
+15 -2
View File
@@ -4063,8 +4063,16 @@ set_one_cmd_context(
case CMD_unlet:
while ((xp->xp_pattern = vim_strchr(arg, ' ')) != NULL)
arg = xp->xp_pattern + 1;
xp->xp_context = EXPAND_USER_VARS;
xp->xp_pattern = arg;
if (*xp->xp_pattern == '$')
{
xp->xp_context = EXPAND_ENV_VARS;
++xp->xp_pattern;
}
break;
case CMD_function:
@@ -5334,7 +5342,9 @@ get_bad_opt(char_u *p, exarg_T *eap)
eap->bad_char = BAD_DROP;
else if (MB_BYTE2LEN(*p) == 1 && p[1] == NUL)
eap->bad_char = *p;
return FAIL;
else
return FAIL;
return OK;
}
#endif
@@ -11310,7 +11320,10 @@ makeopens(
* winminheight and winminwidth need to be set to avoid an error if the
* user has set winheight or winwidth.
*/
if (put_line(fd, "set winminheight=1 winheight=1 winminwidth=1 winwidth=1") == FAIL)
if (put_line(fd, "set winminheight=0") == FAIL
|| put_line(fd, "set winheight=1") == FAIL
|| put_line(fd, "set winminwidth=0") == FAIL
|| put_line(fd, "set winwidth=1") == FAIL)
return FAIL;
if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL)
return FAIL;
+14 -9
View File
@@ -5280,7 +5280,7 @@ expand_shellcmd(
# if defined(FEAT_USR_CMDS) && defined(FEAT_EVAL)
static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, char_u **, int), expand_T *xp, int *num_file, char_u ***file);
static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, typval_T *, int), expand_T *xp, int *num_file, char_u ***file);
/*
* Call "user_expand_func()" to invoke a user defined Vim script function and
@@ -5288,15 +5288,15 @@ static void * call_user_expand_func(void *(*user_expand_func)(char_u *, int, cha
*/
static void *
call_user_expand_func(
void *(*user_expand_func)(char_u *, int, char_u **, int),
void *(*user_expand_func)(char_u *, int, typval_T *, int),
expand_T *xp,
int *num_file,
char_u ***file)
{
int keep = 0;
char_u num[50];
char_u *args[3];
typval_T args[4];
int save_current_SID = current_SID;
char_u *pat = NULL;
void *ret;
struct cmdline_info save_ccline;
@@ -5311,10 +5311,15 @@ call_user_expand_func(
ccline.cmdbuff[ccline.cmdlen] = 0;
}
args[0] = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
args[1] = xp->xp_line;
sprintf((char *)num, "%d", xp->xp_col);
args[2] = num;
pat = vim_strnsave(xp->xp_pattern, xp->xp_pattern_len);
args[0].v_type = VAR_STRING;
args[0].vval.v_string = pat;
args[1].v_type = VAR_STRING;
args[1].vval.v_string = xp->xp_line;
args[2].v_type = VAR_NUMBER;
args[2].vval.v_number = xp->xp_col;
args[3].v_type = VAR_UNKNOWN;
/* Save the cmdline, we don't know what the function may do. */
save_ccline = ccline;
@@ -5329,7 +5334,7 @@ call_user_expand_func(
if (ccline.cmdbuff != NULL)
ccline.cmdbuff[ccline.cmdlen] = keep;
vim_free(args[0]);
vim_free(pat);
return ret;
}
+5
View File
@@ -2856,6 +2856,11 @@ vgetorpeek(int advance)
/*
* get a character: 3. from the user - get it
*/
if (typebuf.tb_len == 0)
// timedout may have been set while waiting for a mapping
// that has a <Nop> RHS.
timedout = FALSE;
wait_tb_len = typebuf.tb_len;
c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
+13 -2
View File
@@ -3836,9 +3836,20 @@ get_firstwin(TabPageObject *tabObject)
else
return firstwin;
}
// Use the same order as in the WindowAttr() function.
static char *WindowAttrs[] = {
"buffer", "cursor", "height", "vars", "options", "number", "row", "col",
"tabpage", "valid",
"buffer",
"cursor",
"height",
"row",
"width",
"col",
"vars",
"options",
"number",
"tabpage",
"valid",
NULL
};
+4 -5
View File
@@ -4799,12 +4799,11 @@ iconv_end(void)
# endif
call_imactivatefunc(int active)
{
char_u *argv[1];
typval_T argv[2];
if (active)
argv[0] = (char_u *)"1";
else
argv[0] = (char_u *)"0";
argv[0].v_type = VAR_NUMBER;
argv[0].vval.v_number = active ? 1 : 0;
argv[1].v_type = VAR_NUMBER;
(void)call_func_retnr(p_imaf, 1, argv, FALSE);
}
+6 -4
View File
@@ -2219,7 +2219,7 @@ op_colon(oparg_T *oap)
op_function(oparg_T *oap UNUSED)
{
#ifdef FEAT_EVAL
char_u *(argv[1]);
typval_T argv[2];
# ifdef FEAT_VIRTUALEDIT
int save_virtual_op = virtual_op;
# endif
@@ -2235,12 +2235,14 @@ op_function(oparg_T *oap UNUSED)
/* Exclude the end position. */
decl(&curbuf->b_op_end);
argv[0].v_type = VAR_STRING;
if (oap->block_mode)
argv[0] = (char_u *)"block";
argv[0].vval.v_string = (char_u *)"block";
else if (oap->motion_type == MLINE)
argv[0] = (char_u *)"line";
argv[0].vval.v_string = (char_u *)"line";
else
argv[0] = (char_u *)"char";
argv[0].vval.v_string = (char_u *)"char";
argv[1].v_type = VAR_UNKNOWN;
# ifdef FEAT_VIRTUALEDIT
/* Reset virtual_op so that 'virtualedit' can be changed in the
+5 -5
View File
@@ -8967,6 +8967,7 @@ set_num_option(
*/
if (pp == &p_wh || pp == &p_hh)
{
// 'winheight' and 'helpheight'
if (p_wh < 1)
{
errmsg = e_positive;
@@ -8992,10 +8993,9 @@ set_num_option(
win_setheight((int)p_hh);
}
}
/* 'winminheight' */
else if (pp == &p_wmh)
{
// 'winminheight'
if (p_wmh < 0)
{
errmsg = e_positive;
@@ -9010,6 +9010,7 @@ set_num_option(
}
else if (pp == &p_wiw)
{
// 'winwidth'
if (p_wiw < 1)
{
errmsg = e_positive;
@@ -9025,10 +9026,9 @@ set_num_option(
if (!ONE_WINDOW && curwin->w_width < p_wiw)
win_setwidth((int)p_wiw);
}
/* 'winminwidth' */
else if (pp == &p_wmw)
{
// 'winminwidth'
if (p_wmw < 0)
{
errmsg = e_positive;
@@ -9039,7 +9039,7 @@ set_num_option(
errmsg = e_winwidth;
p_wmw = p_wiw;
}
win_setminheight();
win_setminwidth();
}
/* (re)set last window status line */
+30 -7
View File
@@ -4165,7 +4165,11 @@ wait4pid(pid_t child, waitstatus *status)
* Set the environment for a child process.
*/
static void
set_child_environment(long rows, long columns, char *term)
set_child_environment(
long rows,
long columns,
char *term,
int is_terminal UNUSED)
{
# ifdef HAVE_SETENV
char envbuf[50];
@@ -4175,6 +4179,9 @@ set_child_environment(long rows, long columns, char *term)
static char envbuf_Lines[20];
static char envbuf_Columns[20];
static char envbuf_Colors[20];
# ifdef FEAT_TERMINAL
static char envbuf_Version[20];
# endif
# ifdef FEAT_CLIENTSERVER
static char envbuf_Servername[60];
# endif
@@ -4195,6 +4202,13 @@ set_child_environment(long rows, long columns, char *term)
setenv("COLUMNS", (char *)envbuf, 1);
sprintf((char *)envbuf, "%ld", colors);
setenv("COLORS", (char *)envbuf, 1);
# ifdef FEAT_TERMINAL
if (is_terminal)
{
sprintf((char *)envbuf, "%ld", get_vim_var_nr(VV_VERSION));
setenv("VIM_TERMINAL", (char *)envbuf, 1);
}
# endif
# ifdef FEAT_CLIENTSERVER
setenv("VIM_SERVERNAME", serverName == NULL ? "" : (char *)serverName, 1);
# endif
@@ -4215,6 +4229,14 @@ set_child_environment(long rows, long columns, char *term)
putenv(envbuf_Columns);
vim_snprintf(envbuf_Colors, sizeof(envbuf_Colors), "COLORS=%ld", colors);
putenv(envbuf_Colors);
# ifdef FEAT_TERMINAL
if (is_terminal)
{
vim_snprintf(envbuf_Version, sizeof(envbuf_Version),
"VIM_TERMINAL=%ld", get_vim_var_nr(VV_VERSION));
putenv(envbuf_Version);
}
# endif
# ifdef FEAT_CLIENTSERVER
vim_snprintf(envbuf_Servername, sizeof(envbuf_Servername),
"VIM_SERVERNAME=%s", serverName == NULL ? "" : (char *)serverName);
@@ -4224,9 +4246,9 @@ set_child_environment(long rows, long columns, char *term)
}
static void
set_default_child_environment(void)
set_default_child_environment(int is_terminal)
{
set_child_environment(Rows, Columns, "dumb");
set_child_environment(Rows, Columns, "dumb", is_terminal);
}
#endif
@@ -4701,7 +4723,7 @@ mch_call_shell_fork(
# endif
}
# endif
set_default_child_environment();
set_default_child_environment(FALSE);
/*
* stderr is only redirected when using the GUI, so that a
@@ -5383,7 +5405,7 @@ mch_call_shell(
#if defined(FEAT_JOB_CHANNEL) || defined(PROTO)
void
mch_job_start(char **argv, job_T *job, jobopt_T *options)
mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal)
{
pid_t pid;
int fd_in[2] = {-1, -1}; /* for stdin */
@@ -5531,11 +5553,12 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
set_child_environment(
(long)options->jo_term_rows,
(long)options->jo_term_cols,
term);
term,
is_terminal);
}
else
# endif
set_default_child_environment();
set_default_child_environment(is_terminal);
if (options->jo_env != NULL)
{
+35 -6
View File
@@ -5275,22 +5275,51 @@ win32_build_env(dict_T *env, garray_T *gap, int is_terminal)
}
}
# ifdef FEAT_CLIENTSERVER
if (is_terminal)
# if defined(FEAT_CLIENTSERVER) || defined(FEAT_TERMINAL)
{
# ifdef FEAT_CLIENTSERVER
char_u *servername = get_vim_var_str(VV_SEND_SERVER);
size_t lval = STRLEN(servername);
size_t n;
size_t servername_len = STRLEN(servername);
# endif
# ifdef FEAT_TERMINAL
char_u *version = get_vim_var_str(VV_VERSION);
size_t version_len = STRLEN(version);
# endif
// size of "VIM_SERVERNAME=" and value,
// plus "VIM_TERMINAL=" and value,
// plus two terminating NULs
size_t n = 0
# ifdef FEAT_CLIENTSERVER
+ 15 + servername_len
# endif
# ifdef FEAT_TERMINAL
+ 13 + version_len + 2
# endif
;
if (ga_grow(gap, (int)(14 + lval + 2)) == OK)
if (ga_grow(gap, (int)n) == OK)
{
# ifdef FEAT_CLIENTSERVER
for (n = 0; n < 15; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)"VIM_SERVERNAME="[n];
for (n = 0; n < lval; n++)
for (n = 0; n < servername_len; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)servername[n];
*((WCHAR*)gap->ga_data + gap->ga_len++) = L'\0';
# endif
# ifdef FEAT_TERMINAL
if (is_terminal)
{
for (n = 0; n < 13; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)"VIM_TERMINAL="[n];
for (n = 0; n < version_len; n++)
*((WCHAR*)gap->ga_data + gap->ga_len++) =
(WCHAR)version[n];
*((WCHAR*)gap->ga_data + gap->ga_len++) = L'\0';
}
# endif
}
}
# endif
+1 -1
View File
@@ -67,7 +67,7 @@ void job_set_options(job_T *job, jobopt_T *opt);
void job_stop_on_exit(void);
int has_pending_job(void);
void job_check_ended(void);
job_T *job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg);
job_T *job_start(typval_T *argvars, char **argv_arg, jobopt_T *opt_arg, int is_terminal);
char *job_status(job_T *job);
void job_info(job_T *job, dict_T *dict);
void job_info_all(list_T *l);
+4 -4
View File
@@ -19,10 +19,10 @@ varnumber_T eval_to_number(char_u *expr);
list_T *eval_spell_expr(char_u *badword, char_u *expr);
int get_spellword(list_T *list, char_u **pp);
typval_T *eval_expr(char_u *arg, char_u **nextcmd);
int call_vim_function(char_u *func, int argc, char_u **argv, int safe, int str_arg_only, typval_T *rettv);
varnumber_T call_func_retnr(char_u *func, int argc, char_u **argv, int safe);
void *call_func_retstr(char_u *func, int argc, char_u **argv, int safe);
void *call_func_retlist(char_u *func, int argc, char_u **argv, int safe);
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv, int safe);
varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv, int safe);
void *call_func_retstr(char_u *func, int argc, typval_T *argv, int safe);
void *call_func_retlist(char_u *func, int argc, typval_T *argv, int safe);
int eval_foldexpr(char_u *arg, int *cp);
void ex_let(exarg_T *eap);
void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first);
+1 -1
View File
@@ -62,7 +62,7 @@ void mch_set_shellsize(void);
void mch_new_shellsize(void);
void may_send_sigint(int c, pid_t pid, pid_t wpid);
int mch_call_shell(char_u *cmd, int options);
void mch_job_start(char **argv, job_T *job, jobopt_T *options);
void mch_job_start(char **argv, job_T *job, jobopt_T *options, int is_terminal);
char *mch_job_status(job_T *job);
job_T *mch_detect_ended_job(job_T *job_list);
int mch_signal_job(job_T *job, char_u *how);
+1
View File
@@ -54,6 +54,7 @@ void win_setheight_win(int height, win_T *win);
void win_setwidth(int width);
void win_setwidth_win(int width, win_T *wp);
void win_setminheight(void);
void win_setminwidth(void);
void win_drag_status_line(win_T *dragwin, int offset);
void win_drag_vsep_line(win_T *dragwin, int offset);
void set_fraction(win_T *wp);
+1 -1
View File
@@ -5774,7 +5774,7 @@ term_and_job_init(
#endif
/* This may change a string in "argvar". */
term->tl_job = job_start(argvar, argv, opt);
term->tl_job = job_start(argvar, argv, opt, TRUE);
if (term->tl_job != NULL)
++term->tl_job->jv_refcount;
+12
View File
@@ -124,7 +124,10 @@ func RunTheTest(test)
exe 'call ' . a:test
else
try
let s:test = a:test
au VimLeavePre * call EarlyExit(s:test)
exe 'call ' . a:test
au! VimLeavePre
catch /^\cskipped/
call add(s:messages, ' Skipped')
call add(s:skipped, 'SKIPPED ' . a:test . ': ' . substitute(v:exception, '^\S*\s\+', '', ''))
@@ -174,6 +177,15 @@ func AfterTheTest()
endif
endfunc
func EarlyExit(test)
" It's OK for the test we use to test the quit detection.
if a:test != 'Test_zz_quit_detected()'
call add(v:errors, 'Test caused Vim to exit: ' . a:test)
endif
call FinishTesting()
endfunc
" This function can be called by a test if it wants to abort testing.
func FinishTesting()
call AfterTheTest()
+1 -1
View File
@@ -443,7 +443,7 @@ vim.current.window:Window:True
vim.current.tabpage:TabPage:True
current:__dir__,__members__,buffer,line,range,tabpage,window
buffer:__dir__,__members__,append,mark,name,number,options,range,valid,vars
window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
window:__dir__,__members__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
tabpage:__dir__,__members__,number,valid,vars,window,windows
range:__dir__,__members__,append,end,start
dictionary:__dir__,__members__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
+1 -1
View File
@@ -443,7 +443,7 @@ vim.current.window:Window:True
vim.current.tabpage:TabPage:True
current:__dir__,buffer,line,range,tabpage,window
buffer:__dir__,append,mark,name,number,options,range,valid,vars
window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars
window:__dir__,buffer,col,cursor,height,number,options,row,tabpage,valid,vars,width
tabpage:__dir__,number,valid,vars,window,windows
range:__dir__,append,end,start
dictionary:__dir__,get,has_key,items,keys,locked,pop,popitem,scope,update,values
+6
View File
@@ -198,3 +198,9 @@ func Test_user_is_happy()
smile
sleep 300m
endfunc
" Must be last.
func Test_zz_quit_detected()
" Verify that if a test function ends Vim the test script detects this.
quit
endfunc
+25
View File
@@ -117,6 +117,31 @@ func Test_omni_dash()
set omnifunc=
endfunc
func Test_completefunc_args()
let s:args = []
func! CompleteFunc(findstart, base)
let s:args += [[a:findstart, empty(a:base)]]
endfunc
new
set completefunc=CompleteFunc
call feedkeys("i\<C-X>\<C-U>\<Esc>", 'x')
call assert_equal(s:args[0], [1, 1])
call assert_equal(s:args[1][0], 0)
set completefunc=
let s:args = []
set omnifunc=CompleteFunc
call feedkeys("i\<C-X>\<C-O>\<Esc>", 'x')
call assert_equal(s:args[0], [1, 1])
call assert_equal(s:args[1][0], 0)
set omnifunc=
bwipe!
unlet s:args
delfunc CompleteFunc
endfunc
function! s:CompleteDone_CompleteFuncDict( findstart, base )
if a:findstart
return 0
+10 -1
View File
@@ -106,13 +106,22 @@ endfunc
func Test_mksession_winheight()
new
set winheight=10 winminheight=2
set winheight=10
set winminheight=2
mksession! Xtest_mks.out
source Xtest_mks.out
call delete('Xtest_mks.out')
endfunc
func Test_mksession_large_winheight()
set winheight=999
mksession! Xtest_mks_winheight.out
set winheight&
source Xtest_mks_winheight.out
call delete('Xtest_mks_winheight.out')
endfunc
func Test_mksession_arglist()
argdel *
next file1 file2 file3 file4
+30 -2
View File
@@ -1,10 +1,38 @@
" Tests for complicated + argument to :edit command
function Test_edit()
call writefile(["foo|bar"], "Xfile1")
call writefile(["foo/bar"], "Xfile2")
call writefile(["foo|bar"], "Xfile1")
call writefile(["foo/bar"], "Xfile2")
edit +1|s/|/PIPE/|w Xfile1| e Xfile2|1 | s/\//SLASH/|w
call assert_equal(["fooPIPEbar"], readfile("Xfile1"))
call assert_equal(["fooSLASHbar"], readfile("Xfile2"))
call delete('Xfile1')
call delete('Xfile2')
endfunction
func Test_edit_bad()
if !has('multi_byte')
finish
endif
" Test loading a utf8 file with bad utf8 sequences.
call writefile(["[\xff][\xc0][\xe2\x89\xf0][\xc2\xc2]"], "Xfile")
new
" Without ++bad=..., the default behavior is like ++bad=?
e! ++enc=utf8 Xfile
call assert_equal('[?][?][???][??]', getline(1))
e! ++enc=utf8 ++bad=_ Xfile
call assert_equal('[_][_][___][__]', getline(1))
e! ++enc=utf8 ++bad=drop Xfile
call assert_equal('[][][][]', getline(1))
e! ++enc=utf8 ++bad=keep Xfile
call assert_equal("[\xff][\xc0][\xe2\x89\xf0][\xc2\xc2]", getline(1))
call assert_fails('e! ++enc=utf8 ++bad=foo Xfile', 'E474:')
bw!
call delete('Xfile')
endfunc
+25 -29
View File
@@ -6,7 +6,7 @@ source screendump.vim
let g:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
let g:setting = ''
func! ListMonths()
func ListMonths()
if g:setting != ''
exe ":set" g:setting
endif
@@ -19,7 +19,7 @@ func! ListMonths()
return ''
endfunc
func! Test_popup_complete2()
func Test_popup_complete2()
" Although the popupmenu is not visible, this does not mean completion mode
" has ended. After pressing <f5> to complete the currently typed char, Vim
" still stays in the first state of the completion (:h ins-completion-menu),
@@ -34,9 +34,9 @@ func! Test_popup_complete2()
call assert_equal(["Dece", "", "December2015"], getline(1,3))
%d
bw!
endfu
endfunc
func! Test_popup_complete()
func Test_popup_complete()
new
inoremap <f5> <c-r>=ListMonths()<cr>
@@ -215,10 +215,10 @@ func! Test_popup_complete()
call feedkeys("aM\<f5>\<enter>\<esc>", 'tx')
call assert_equal(["March", "M", "March"], getline(1,4))
%d
endfu
endfunc
func! Test_popup_completion_insertmode()
func Test_popup_completion_insertmode()
new
inoremap <F5> <C-R>=ListMonths()<CR>
@@ -247,20 +247,16 @@ func! Test_popup_completion_insertmode()
iunmap <F5>
endfunc
" TODO: Fix what breaks after this line.
" - Do not use "q!", it may exit Vim if there is an error
finish
func Test_noinsert_complete()
function! s:complTest1() abort
func! s:complTest1() abort
call complete(1, ['source', 'soundfold'])
return ''
endfunction
endfunc
function! s:complTest2() abort
func! s:complTest2() abort
call complete(1, ['source', 'soundfold'])
return ''
endfunction
endfunc
new
set completeopt+=noinsert
@@ -281,9 +277,9 @@ func Test_noinsert_complete()
endfunc
func Test_compl_vim_cmds_after_register_expr()
function! s:test_func()
func! s:test_func()
return 'autocmd '
endfunction
endfunc
augroup AAAAA_Group
au!
augroup END
@@ -330,7 +326,7 @@ func DummyCompleteTwo(findstart, base)
else
return ['twodef', 'twoDEF']
endif
endfunction
endfunc
" Test that nothing happens if the 'completefunc' opens
" a new window (no completion, no crash)
@@ -407,7 +403,7 @@ func Test_omnifunc_with_check()
q!
endfunc
function UndoComplete()
func UndoComplete()
call complete(1, ['January', 'February', 'March',
\ 'April', 'May', 'June', 'July', 'August', 'September',
\ 'October', 'November', 'December'])
@@ -444,7 +440,7 @@ func Test_complete_no_undo()
q!
endfunc
function! DummyCompleteFive(findstart, base)
func DummyCompleteFive(findstart, base)
if a:findstart
return 0
else
@@ -489,7 +485,7 @@ func Test_completion_ctrl_e_without_autowrap()
q!
endfunc
function! DummyCompleteSix()
func DummyCompleteSix()
call complete(1, ['Hello', 'World'])
return ''
endfunction
@@ -577,7 +573,7 @@ func Test_completion_comment_formatting()
bwipe!
endfunc
fun MessCompleteMonths()
func MessCompleteMonths()
for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep")
call complete_add(m)
if complete_check()
@@ -585,14 +581,14 @@ fun MessCompleteMonths()
endif
endfor
return []
endfun
endfunc
fun MessCompleteMore()
func MessCompleteMore()
call complete(1, split("Oct Nov Dec"))
return []
endfun
endfunc
fun MessComplete(findstart, base)
func MessComplete(findstart, base)
if a:findstart
let line = getline('.')
let start = col('.') - 1
@@ -605,7 +601,7 @@ fun MessComplete(findstart, base)
call MessCompleteMore()
return []
endif
endf
endfunc
func Test_complete_func_mess()
" Calling complete() after complete_add() in 'completefunc' is wrong, but it
@@ -835,7 +831,7 @@ func Test_popup_complete_backwards_ctrl_p()
bwipe!
endfunc
fun! Test_complete_o_tab()
func Test_complete_o_tab()
let s:o_char_pressed = 0
fun! s:act_on_text_changed()
@@ -843,7 +839,7 @@ fun! Test_complete_o_tab()
let s:o_char_pressed = 0
call feedkeys("\<c-x>\<c-n>", 'i')
endif
endf
endfunc
set completeopt=menu,noselect
new
@@ -862,7 +858,7 @@ fun! Test_complete_o_tab()
bwipe!
set completeopt&
delfunc s:act_on_text_changed
endf
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+11 -4
View File
@@ -482,18 +482,25 @@ func Test_terminal_servername()
if !has('clientserver')
return
endif
call s:test_environment("VIM_SERVERNAME", v:servername)
endfunc
func Test_terminal_version()
call s:test_environment("VIM_TERMINAL", string(v:version))
endfunc
func s:test_environment(name, value)
let buf = Run_shell_in_terminal({})
" Wait for the shell to display a prompt
call WaitForAssert({-> assert_notequal('', term_getline(buf, 1))})
if has('win32')
call term_sendkeys(buf, "echo %VIM_SERVERNAME%\r")
call term_sendkeys(buf, "echo %" . a:name . "%\r")
else
call term_sendkeys(buf, "echo $VIM_SERVERNAME\r")
call term_sendkeys(buf, "echo $" . a:name . "\r")
endif
call term_wait(buf)
call Stop_shell_in_terminal(buf)
call WaitFor('getline(2) == v:servername')
call assert_equal(v:servername, getline(2))
call WaitForAssert({-> assert_equal(a:value, getline(2))})
exe buf . 'bwipe'
unlet buf
+10
View File
@@ -45,3 +45,13 @@ func Test_unlet_env()
unlet $MUST_NOT_BE_AN_ERROR
endfunc
func Test_unlet_complete()
let g:FOOBAR = 1
call feedkeys(":unlet g:FOO\t\n", 'tx')
call assert_true(!exists('g:FOOBAR'))
let $FOOBAR = 1
call feedkeys(":unlet $FOO\t\n", 'tx')
call assert_true(!exists('$FOOBAR') || empty($FOOBAR))
endfunc
+28
View File
@@ -776,6 +776,34 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
53,
/**/
52,
/**/
51,
/**/
50,
/**/
49,
/**/
48,
/**/
47,
/**/
46,
/**/
45,
/**/
44,
/**/
43,
/**/
42,
/**/
41,
/**/
40,
/**/
39,
/**/
+46 -12
View File
@@ -2112,17 +2112,22 @@ win_equal_rec(
static void
leaving_window(win_T *win)
{
// Only matters for a prompt window.
if (!bt_prompt(win->w_buffer))
return;
// When leaving a prompt window stop Insert mode and perhaps restart
// it when entering that window again.
win->w_buffer->b_prompt_insert = restart_edit;
restart_edit = NUL;
// When leaving the window (or closing the window) was done from a
// callback we need to break out of the Insert mode loop.
// callback we need to break out of the Insert mode loop and restart Insert
// mode when entering the window again.
if (State & INSERT)
{
stop_insert_mode = TRUE;
if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert == NUL)
if (win->w_buffer->b_prompt_insert == NUL)
win->w_buffer->b_prompt_insert = 'A';
}
}
@@ -2130,12 +2135,17 @@ leaving_window(win_T *win)
static void
entering_window(win_T *win)
{
// Only matters for a prompt window.
if (!bt_prompt(win->w_buffer))
return;
// When switching to a prompt buffer that was in Insert mode, don't stop
// Insert mode, it may have been set in leaving_window().
if (bt_prompt(win->w_buffer) && win->w_buffer->b_prompt_insert != NUL)
if (win->w_buffer->b_prompt_insert != NUL)
stop_insert_mode = FALSE;
// When entering the prompt window may restart Insert mode.
// When entering the prompt window restart Insert mode if we were in Insert
// mode when we left it.
restart_edit = win->w_buffer->b_prompt_insert;
}
#endif
@@ -5425,23 +5435,21 @@ frame_setwidth(frame_T *curfrp, int width)
}
/*
* Check 'winminheight' for a valid value.
* Check 'winminheight' for a valid value and reduce it if needed.
*/
void
win_setminheight(void)
{
int room;
int needed;
int first = TRUE;
win_T *wp;
/* loop until there is a 'winminheight' that is possible */
// loop until there is a 'winminheight' that is possible
while (p_wmh > 0)
{
/* TODO: handle vertical splits */
room = -p_wh;
FOR_ALL_WINDOWS(wp)
room += VISIBLE_HEIGHT(wp) - p_wmh;
if (room >= 0)
room = Rows - p_ch;
needed = frame_minheight(topframe, NULL);
if (room >= needed)
break;
--p_wmh;
if (first)
@@ -5452,6 +5460,32 @@ win_setminheight(void)
}
}
/*
* Check 'winminwidth' for a valid value and reduce it if needed.
*/
void
win_setminwidth(void)
{
int room;
int needed;
int first = TRUE;
// loop until there is a 'winminheight' that is possible
while (p_wmw > 0)
{
room = Columns;
needed = frame_minwidth(topframe, NULL);
if (room >= needed)
break;
--p_wmw;
if (first)
{
EMSG(_(e_noroom));
first = FALSE;
}
}
}
#if defined(FEAT_MOUSE) || defined(PROTO)
/*