Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2017-08-21 20:39:26 -07:00
12 changed files with 330 additions and 135 deletions
+8 -5
View File
@@ -1,4 +1,4 @@
*terminal.txt* For Vim version 8.0. Last change: 2017 Aug 12
*terminal.txt* For Vim version 8.0. Last change: 2017 Aug 20
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -102,10 +102,9 @@ Syntax ~
parentheses. E.g. if "gdb" exists the second terminal
buffer will use "!gdb (1)".
If [range] is given it is used for the terminal size.
One number specifies the number of rows. Unless the
"vertical" modifier is used, then it is the number of
columns.
If [range] is given the specified lines are used as
input for the job. It will not be possible to type
keys in the terminal window.
Two comma separated numbers are used as "rows,cols".
E.g. `:24,80gdb` opens a terminal with 24 rows and 80
@@ -125,6 +124,10 @@ Syntax ~
cannot be |abandon|ed.
++hidden Open the terminal in a hidden buffer,
no window will be used.
++rows={height} Use {height} for the terminal window
height.
++cols={width} Use {width} for the terminal window
width.
If you want to use more options use the |term_start()|
function.
+2 -2
View File
@@ -1490,8 +1490,8 @@ EX(CMD_tearoff, "tearoff", ex_tearoff,
NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN,
ADDR_LINES),
EX(CMD_terminal, "terminal", ex_terminal,
RANGE|NOTADR|BANG|FILES|TRLBAR|CMDWIN,
ADDR_OTHER),
RANGE|BANG|FILES|TRLBAR|CMDWIN,
ADDR_LINES),
EX(CMD_tfirst, "tfirst", ex_tag,
RANGE|NOTADR|BANG|TRLBAR|ZEROR,
ADDR_LINES),
+1 -3
View File
@@ -2051,9 +2051,7 @@ dialog_changed(
else
{
#endif
dialog_msg(buff, _("Save changes to \"%s\"?"),
(buf->b_fname != NULL) ?
buf->b_fname : (char_u *)_("Untitled"));
dialog_msg(buff, _("Save changes to \"%s\"?"), buf->b_fname);
if (checkall)
ret = vim_dialog_yesnoallcancel(VIM_QUESTION, NULL, buff, 1);
else
+45 -41
View File
@@ -3254,6 +3254,8 @@ static struct vimoption options[] =
p_term("t_AL", T_CAL)
p_term("t_al", T_AL)
p_term("t_bc", T_BC)
p_term("t_BE", T_BE)
p_term("t_BD", T_BD)
p_term("t_cd", T_CD)
p_term("t_ce", T_CE)
p_term("t_cl", T_CL)
@@ -3270,13 +3272,11 @@ static struct vimoption options[] =
p_term("t_db", T_DB)
p_term("t_DL", T_CDL)
p_term("t_dl", T_DL)
p_term("t_EC", T_CEC)
p_term("t_EI", T_CEI)
p_term("t_fs", T_FS)
p_term("t_GP", T_CGP)
p_term("t_IE", T_CIE)
p_term("t_SC", T_CSC)
p_term("t_EC", T_CEC)
p_term("t_SH", T_CSH)
p_term("t_RS", T_CRS)
p_term("t_IS", T_CIS)
p_term("t_ke", T_KE)
p_term("t_ks", T_KS)
@@ -3290,10 +3290,13 @@ static struct vimoption options[] =
p_term("t_op", T_OP)
p_term("t_RB", T_RBG)
p_term("t_RI", T_CRI)
p_term("t_RS", T_CRS)
p_term("t_RV", T_CRV)
p_term("t_Sb", T_CSB)
p_term("t_SC", T_CSC)
p_term("t_se", T_SE)
p_term("t_Sf", T_CSF)
p_term("t_SH", T_CSH)
p_term("t_SI", T_CSI)
p_term("t_so", T_SO)
p_term("t_SR", T_CSR)
@@ -3308,9 +3311,9 @@ static struct vimoption options[] =
p_term("t_vb", T_VB)
p_term("t_ve", T_VE)
p_term("t_vi", T_VI)
p_term("t_VS", T_CVS)
p_term("t_vs", T_VS)
p_term("t_WP", T_CWP)
p_term("t_GP", T_CGP)
p_term("t_WS", T_CWS)
p_term("t_xn", T_XN)
p_term("t_xs", T_XS)
@@ -3318,8 +3321,6 @@ static struct vimoption options[] =
p_term("t_ZR", T_CZR)
p_term("t_8f", T_8F)
p_term("t_8b", T_8B)
p_term("t_BE", T_BE)
p_term("t_BD", T_BD)
/* terminal key codes are not in here */
@@ -4468,8 +4469,6 @@ trigger_optionsset_string(
(char_u *)options[opt_idx].fullname, NULL, FALSE, NULL);
reset_v_option_vars();
}
vim_free(oldval);
vim_free(newval);
}
#endif
@@ -4935,19 +4934,19 @@ do_set(
}
else if (opt_idx >= 0) /* string */
{
char_u *save_arg = NULL;
char_u *s = NULL;
char_u *oldval = NULL; /* previous value if *varp */
char_u *newval;
char_u *origval = NULL;
char_u *save_arg = NULL;
char_u *s = NULL;
char_u *oldval = NULL; /* previous value if *varp */
char_u *newval;
char_u *origval = NULL;
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
char_u *saved_origval = NULL;
char_u *saved_newval = NULL;
char_u *saved_origval = NULL;
char_u *saved_newval = NULL;
#endif
unsigned newlen;
int comma;
int bs;
int new_value_alloced; /* new string option
unsigned newlen;
int comma;
int bs;
int new_value_alloced; /* new string option
was allocated */
/* When using ":set opt=val" for a global option
@@ -4960,6 +4959,16 @@ do_set(
/* The old value is kept until we are sure that the
* new value is valid. */
oldval = *(char_u **)varp;
/* When setting the local value of a global
* option, the old value may be the global value. */
if (((int)options[opt_idx].indir & PV_BOTH)
&& (opt_flags & OPT_LOCAL))
origval = *(char_u **)get_varp(
&options[opt_idx]);
else
origval = oldval;
if (nextchar == '&') /* set to default val */
{
newval = options[opt_idx].def_val[
@@ -5036,6 +5045,8 @@ do_set(
break;
}
vim_free(oldval);
if (origval == oldval)
origval = *(char_u **)varp;
oldval = *(char_u **)varp;
}
/*
@@ -5074,15 +5085,6 @@ do_set(
++arg;
}
/* When setting the local value of a global
* option, the old value may be the global value. */
if (((int)options[opt_idx].indir & PV_BOTH)
&& (opt_flags & OPT_LOCAL))
origval = *(char_u **)get_varp(
&options[opt_idx]);
else
origval = oldval;
/*
* Copy the new string into allocated memory.
* Can't use set_string_option_direct(), because
@@ -5286,7 +5288,9 @@ do_set(
new_value_alloced = TRUE;
}
/* Set the new value. */
/*
* Set the new value.
*/
*(char_u **)(varp) = newval;
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
@@ -5312,19 +5316,16 @@ do_set(
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval, errbuf, opt_flags);
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
if (errmsg == NULL)
trigger_optionsset_string(opt_idx, opt_flags,
saved_origval, saved_newval);
vim_free(saved_origval);
vim_free(saved_newval);
#endif
/* If error detected, print the error message. */
if (errmsg != NULL)
{
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
vim_free(saved_origval);
vim_free(saved_newval);
#endif
goto skip;
}
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
trigger_optionsset_string(opt_idx, opt_flags,
saved_origval, saved_newval);
#endif
}
else /* key code option */
{
@@ -6135,8 +6136,11 @@ set_string_option(
#if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL)
/* call autocommand after handling side effects */
trigger_optionsset_string(opt_idx, opt_flags,
if (r == NULL)
trigger_optionsset_string(opt_idx, opt_flags,
saved_oldval, saved_newval);
vim_free(saved_oldval);
vim_free(saved_newval);
#endif
}
return r;
+19 -3
View File
@@ -4352,6 +4352,7 @@ mch_call_shell(
# define EXEC_FAILED 122 /* Exit code when shell didn't execute. Don't use
127, some shells use that already */
# define OPEN_NULL_FAILED 123 /* Exit code if /dev/null can't be opened */
char_u *newcmd;
pid_t pid;
@@ -5260,6 +5261,7 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
int use_file_for_in = options->jo_io[PART_IN] == JIO_FILE;
int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE;
int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE;
int use_buffer_for_in = options->jo_io[PART_IN] == JIO_BUFFER;
int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT;
SIGSET_DECL(curset)
@@ -5269,7 +5271,10 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
/* default is to fail */
job->jv_status = JOB_FAILED;
if (options->jo_pty)
if (options->jo_pty
&& (!(use_file_for_in || use_null_for_in)
|| !(use_file_for_in || use_null_for_out)
|| !(use_out_for_err || use_file_for_err || use_null_for_err)))
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_name);
/* TODO: without the channel feature connect the child to /dev/null? */
@@ -5285,8 +5290,12 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
goto failed;
}
}
else if (!use_null_for_in && pty_master_fd < 0 && pipe(fd_in) < 0)
goto failed;
else
/* When writing buffer lines to the input don't use the pty, so that
* the pipe can be closed when all lines were written. */
if (!use_null_for_in && (pty_master_fd < 0 || use_buffer_for_in)
&& pipe(fd_in) < 0)
goto failed;
if (use_file_for_out)
{
@@ -5383,7 +5392,14 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options)
}
if (use_null_for_in || use_null_for_out || use_null_for_err)
{
null_fd = open("/dev/null", O_RDWR | O_EXTRA, 0);
if (null_fd < 0)
{
perror("opening /dev/null failed");
_exit(OPEN_NULL_FAILED);
}
}
if (pty_slave_fd >= 0)
{
-1
View File
@@ -53,7 +53,6 @@ void cursor_on(void);
void cursor_off(void);
void term_cursor_mode(int forced);
void term_cursor_color(char_u *color);
void term_cursor_blink(int blink);
void term_cursor_shape(int shape, int blink);
void scroll_region_set(win_T *wp, int off);
void scroll_region_reset(void);
+23 -24
View File
@@ -828,17 +828,13 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_LE, "\b"},
{(int)KS_VI, IF_EB("\033[?25l", ESC_STR "[?25l")},
{(int)KS_VE, IF_EB("\033[?25h", ESC_STR "[?25h")},
#if 0
/* This is currently disabled, because we cannot reliably restore the
* cursor style because of what appears to be an xterm bug. */
{(int)KS_VE, IF_EB("\033[?25h\033[?12l", ESC_STR "[?25h" ESC_STR "[?12l")},
{(int)KS_VS, IF_EB("\033[?12h", ESC_STR "[?12h")},
{(int)KS_CVS, IF_EB("\033[?12l", ESC_STR "[?12l")},
# ifdef TERMINFO
{(int)KS_CSH, IF_EB("\033[%p1%d q", ESC_STR "[%p1%d q")},
# else
{(int)KS_CSH, IF_EB("\033[%d q", ESC_STR "[%d q")},
# endif
#endif
{(int)KS_CRS, IF_EB("\033P$q q\033\\", ESC_STR "P$q q" ESC_STR "\\")},
# ifdef TERMINFO
{(int)KS_CM, IF_EB("\033[%i%p1%d;%p2%dH",
@@ -1591,7 +1587,7 @@ set_termname(char_u *term)
{KS_DL, "dl"}, {KS_CDL,"DL"}, {KS_CS, "cs"},
{KS_CL, "cl"}, {KS_CD, "cd"},
{KS_VI, "vi"}, {KS_VE, "ve"}, {KS_MB, "mb"},
{KS_VS, "vs"}, {KS_ME, "me"}, {KS_MR, "mr"},
{KS_ME, "me"}, {KS_MR, "mr"},
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
@@ -1601,6 +1597,7 @@ set_termname(char_u *term)
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
{KS_VS, "vs"}, {KS_CVS, "VS"},
{KS_CIS, "IS"}, {KS_CIE, "IE"},
{KS_CSC, "SC"}, {KS_CEC, "EC"},
{KS_TS, "ts"}, {KS_FS, "fs"},
@@ -3671,11 +3668,11 @@ mouse_model_popup(void)
void
scroll_start(void)
{
if (*T_VS != NUL)
if (*T_VS != NUL && *T_CVS != NUL)
{
out_str(T_VS);
out_str(T_VE);
screen_start(); /* don't know where cursor is now */
out_str(T_CVS);
screen_start(); /* don't know where cursor is now */
}
}
@@ -3700,10 +3697,9 @@ cursor_on(void)
void
cursor_off(void)
{
if (full_screen)
if (full_screen && !cursor_is_off)
{
if (!cursor_is_off)
out_str(T_VI); /* disable cursor */
out_str(T_VI); /* disable cursor */
cursor_is_off = TRUE;
}
}
@@ -3772,20 +3768,10 @@ term_cursor_color(char_u *color)
out_flush();
}
}
void
term_cursor_blink(int blink)
{
if (blink)
out_str(T_VS);
else
out_str(T_VE);
out_flush();
}
# endif
/*
* "shape" == 1: block, "shape" == 2: underline, "shape" == 3: vertical bar
* "shape": 1 = block, 2 = underline, 3 = vertical bar
*/
void
term_cursor_shape(int shape, int blink)
@@ -3795,6 +3781,17 @@ term_cursor_shape(int shape, int blink)
OUT_STR(tgoto((char *)T_CSH, 0, shape * 2 - blink));
out_flush();
}
/* When t_SH is not set try setting just the blink state. */
else if (blink && *T_VS != NUL)
{
out_str(T_VS);
out_flush();
}
else if (!blink && *T_CVS != NUL)
{
out_str(T_CVS);
out_flush();
}
}
#endif
@@ -4699,7 +4696,9 @@ check_termcode(
* 5 = vertical bar blink, 6 = vertical bar */
number = number == 0 ? 1 : number;
initial_cursor_shape = (number + 1) / 2;
initial_cursor_blink = (number & 1) ? TRUE : FALSE;
/* The blink flag is actually inverted, compared to
* the value set with T_SH. */
initial_cursor_blink = (number & 1) ? FALSE : TRUE;
rcm_status = STATUS_GOT;
LOG_TR("Received cursor shape response");
+4 -2
View File
@@ -39,7 +39,8 @@ enum SpecialKey
KS_DB, /* text may be scrolled up from down */
KS_VI, /* cursor invisible */
KS_VE, /* cursor visible */
KS_VS, /* cursor very visible */
KS_VS, /* cursor very visible (blink) */
KS_CVS, /* cursor normally visible (no blink) */
KS_CSH, /* cursor shape */
KS_CRS, /* request cursor shape */
KS_ME, /* normal mode */
@@ -131,7 +132,8 @@ extern char_u *(term_strings[]); /* current terminal strings */
#define T_DB (TERM_STR(KS_DB)) /* text may be scrolled up from down */
#define T_VI (TERM_STR(KS_VI)) /* cursor invisible */
#define T_VE (TERM_STR(KS_VE)) /* cursor visible */
#define T_VS (TERM_STR(KS_VS)) /* cursor very visible */
#define T_VS (TERM_STR(KS_VS)) /* cursor very visible (blink) */
#define T_CVS (TERM_STR(KS_CVS)) /* cursor normally visible (no blink) */
#define T_CSH (TERM_STR(KS_CSH)) /* cursor shape */
#define T_CRS (TERM_STR(KS_CRS)) /* request cursor shape */
#define T_ME (TERM_STR(KS_ME)) /* normal mode */
+157 -48
View File
@@ -38,8 +38,7 @@
* in tl_scrollback are no longer used.
*
* TODO:
* - help index for winptydll, optwin entry for winptydll
* - make [range]terminal pipe [range] lines to the terminal
* - test for writing lines to terminal job does not work on MS-Windows
* - implement term_setsize()
* - add test for giving error for invalid 'termsize' value.
* - support minimal size when 'termsize' is "rows*cols".
@@ -50,8 +49,8 @@
"err_io", "err_name", "err_buf", "err_modifiable", "err_msg"
* Check that something is connected to the terminal.
* Test: "cat" reading from a file or buffer
* "ls" writing stdout to a file or buffer
* shell writing stderr to a file or buffer
* "ls" writing stdout to a file or buffer
* shell writing stderr to a file or buffer
* - For the GUI fill termios with default values, perhaps like pangoterm:
* http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
* - support ":term NONE" to open a terminal with a pty but not running a job
@@ -448,10 +447,14 @@ ex_terminal(exarg_T *eap)
cmd = eap->arg;
while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
{
char_u *p;
char_u *p, *ep;
cmd += 2;
p = skiptowhite(cmd);
ep = vim_strchr(cmd, '=');
if (ep != NULL && ep < p)
p = ep;
if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0)
opt.jo_term_finish = 'c';
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
@@ -460,6 +463,20 @@ ex_terminal(exarg_T *eap)
opt.jo_curwin = 1;
else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0)
opt.jo_hidden = 1;
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "rows", 4) == 0
&& ep != NULL && isdigit(ep[1]))
{
opt.jo_set2 |= JO2_TERM_ROWS;
opt.jo_term_rows = atoi((char *)ep + 1);
p = skiptowhite(cmd);
}
else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "cols", 4) == 0
&& ep != NULL && isdigit(ep[1]))
{
opt.jo_set2 |= JO2_TERM_COLS;
opt.jo_term_cols = atoi((char *)ep + 1);
p = skiptowhite(cmd);
}
else
{
if (*p)
@@ -473,17 +490,14 @@ ex_terminal(exarg_T *eap)
/* Make a copy, an autocommand may set 'shell'. */
tofree = cmd = vim_strsave(p_sh);
if (eap->addr_count == 2)
if (eap->addr_count > 0)
{
opt.jo_term_rows = eap->line1;
opt.jo_term_cols = eap->line2;
}
else if (eap->addr_count == 1)
{
if (cmdmod.split & WSP_VERT)
opt.jo_term_cols = eap->line2;
else
opt.jo_term_rows = eap->line2;
/* Write lines from current buffer to the job. */
opt.jo_set |= JO_IN_IO | JO_IN_BUF | JO_IN_TOP | JO_IN_BOT;
opt.jo_io[PART_IN] = JIO_BUFFER;
opt.jo_io_buf[PART_IN] = curbuf->b_fnum;
opt.jo_in_top = eap->line1;
opt.jo_in_bot = eap->line2;
}
argvar.v_type = VAR_STRING;
@@ -836,7 +850,26 @@ add_scrollback_line_to_buffer(term_T *term, char_u *text, int len)
int empty = (buf->b_ml.ml_flags & ML_EMPTY);
linenr_T lnum = buf->b_ml.ml_line_count;
ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE);
#ifdef _WIN32
if (!enc_utf8 && enc_codepage > 0)
{
WCHAR *ret = NULL;
int length = 0;
MultiByteToWideChar_alloc(CP_UTF8, 0, (char*)text, len + 1,
&ret, &length);
if (ret != NULL)
{
WideCharToMultiByte_alloc(enc_codepage, 0,
ret, length, (char **)&text, &len, 0, 0);
vim_free(ret);
ml_append_buf(term->tl_buffer, lnum, text, len, FALSE);
vim_free(text);
}
}
else
#endif
ml_append_buf(term->tl_buffer, lnum, text, len + 1, FALSE);
if (empty)
{
/* Delete the empty line that was in the empty buffer. */
@@ -927,7 +960,7 @@ move_terminal_to_buffer(term_T *term)
int c;
for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i)
ga.ga_len += mb_char2bytes(c == NUL ? ' ' : c,
ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c,
(char_u *)ga.ga_data + ga.ga_len);
}
}
@@ -1083,6 +1116,29 @@ term_vgetc()
return c;
}
/*
* Get the part that is connected to the tty. Normally this is PART_IN, but
* when writing buffer lines to the job it can be another. This makes it
* possible to do "1,5term vim -".
*/
static ch_part_T
get_tty_part(term_T *term)
{
#ifdef UNIX
ch_part_T parts[3] = {PART_IN, PART_OUT, PART_ERR};
int i;
for (i = 0; i < 3; ++i)
{
int fd = term->tl_job->jv_channel->ch_part[parts[i]].ch_fd;
if (isatty(fd))
return parts[i];
}
#endif
return PART_IN;
}
/*
* Send keys to terminal.
* Return FAIL when the key needs to be handled in Normal mode.
@@ -1154,8 +1210,8 @@ send_keys_to_term(term_T *term, int c, int typed)
len = term_convert_key(term, c, msg);
if (len > 0)
/* TODO: if FAIL is returned, stop? */
channel_send(term->tl_job->jv_channel, PART_IN,
(char_u *)msg, (int)len, NULL);
channel_send(term->tl_job->jv_channel, get_tty_part(term),
(char_u *)msg, (int)len, NULL);
return OK;
}
@@ -1276,8 +1332,6 @@ may_set_cursor_props(term_T *term)
term_cursor_color(term->tl_cursor_color);
else
term_cursor_color((char_u *)"");
/* do both blink and shape+blink, in case setting shape does not work */
term_cursor_blink(term->tl_cursor_blink);
term_cursor_shape(term->tl_cursor_shape, term->tl_cursor_blink);
}
}
@@ -1293,7 +1347,6 @@ may_restore_cursor_props(void)
{
did_change_cursor = FALSE;
term_cursor_color((char_u *)"");
term_cursor_blink(FALSE);
/* this will restore the initial cursor style, if possible */
ui_cursor_shape_forced(TRUE);
}
@@ -1341,7 +1394,8 @@ terminal_loop(void)
#ifdef UNIX
{
int fd = curbuf->b_term->tl_job->jv_channel->ch_part[PART_IN].ch_fd;
int part = get_tty_part(curbuf->b_term);
int fd = curbuf->b_term->tl_job->jv_channel->ch_part[part].ch_fd;
if (isatty(fd))
{
@@ -1438,6 +1492,18 @@ terminal_loop(void)
goto theend;
}
}
# ifdef _WIN32
if (!enc_utf8 && has_mbyte && c >= 0x80)
{
WCHAR wc;
char_u mb[3];
mb[0] = (unsigned)c >> 8;
mb[1] = c;
if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
c = wc;
}
# endif
if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
{
ret = OK;
@@ -1597,7 +1663,7 @@ color2index(VTermColor *color, int fg, int *boldp)
/* 216-color cube */
return 17 + ((red + 25) / 0x33) * 36
+ ((green + 25) / 0x33) * 6
+ ((green + 25) / 0x33) * 6
+ (blue + 25) / 0x33;
}
return 0;
@@ -2046,20 +2112,39 @@ term_update_window(win_T *wp)
else
{
#if defined(FEAT_MBYTE)
if (enc_utf8 && c >= 0x80)
if (enc_utf8)
{
ScreenLines[off] = ' ';
ScreenLinesUC[off] = c;
}
else
{
ScreenLines[off] = c;
if (enc_utf8)
if (c >= 0x80)
{
ScreenLines[off] = ' ';
ScreenLinesUC[off] = c;
}
else
{
ScreenLines[off] = c;
ScreenLinesUC[off] = NUL;
}
}
#else
ScreenLines[off] = c;
# ifdef _WIN32
else if (has_mbyte && c >= 0x80)
{
char_u mb[MB_MAXBYTES+1];
WCHAR wc = c;
if (WideCharToMultiByte(GetACP(), 0, &wc, 1,
(char*)mb, 2, 0, 0) > 1)
{
ScreenLines[off] = mb[0];
ScreenLines[off+1] = mb[1];
cell.width = mb_ptr2cells(mb);
}
else
ScreenLines[off] = c;
}
# endif
else
#endif
ScreenLines[off] = c;
}
ScreenAttrs[off] = cell2attr(cell.attrs, cell.fg, cell.bg);
@@ -2067,11 +2152,12 @@ term_update_window(win_T *wp)
++off;
if (cell.width == 2)
{
ScreenLines[off] = NUL;
#if defined(FEAT_MBYTE)
if (enc_utf8)
ScreenLinesUC[off] = NUL;
else if (!has_mbyte)
#endif
ScreenLines[off] = NUL;
++pos.col;
++off;
}
@@ -2156,6 +2242,7 @@ create_vterm(term_T *term, int rows, int cols)
{
VTerm *vterm;
VTermScreen *screen;
VTermValue value;
vterm = vterm_new(rows, cols);
term->tl_vterm = vterm;
@@ -2180,6 +2267,11 @@ create_vterm(term_T *term, int rows, int cols)
/* Allow using alternate screen. */
vterm_screen_enable_altscreen(screen, 1);
/* We do not want a blinking cursor by default. */
value.boolean = 0;
vterm_state_set_termprop(vterm_obtain_state(vterm),
VTERM_PROP_CURSORBLINK, &value);
}
/*
@@ -2832,13 +2924,20 @@ dyn_winpty_init(int verbose)
* Return OK or FAIL.
*/
static int
term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt)
term_and_job_init(
term_T *term,
int rows,
int cols,
typval_T *argvar,
jobopt_T *opt)
{
WCHAR *p = NULL;
WCHAR *cmd_wchar = NULL;
channel_T *channel = NULL;
job_T *job = NULL;
DWORD error;
HANDLE jo = NULL, child_process_handle, child_thread_handle;
HANDLE jo = NULL;
HANDLE child_process_handle;
HANDLE child_thread_handle;
void *winpty_err;
void *spawn_config = NULL;
char buf[MAX_PATH];
@@ -2858,8 +2957,8 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
cmd = ga.ga_data;
}
p = enc_to_utf16(cmd, NULL);
if (p == NULL)
cmd_wchar = enc_to_utf16(cmd, NULL);
if (cmd_wchar == NULL)
return FAIL;
job = job_alloc();
@@ -2884,7 +2983,7 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN |
WINPTY_SPAWN_FLAG_EXIT_AFTER_SHUTDOWN,
NULL,
p,
cmd_wchar,
NULL,
NULL,
&winpty_err);
@@ -2899,20 +2998,25 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
if (job == NULL)
goto failed;
/* TODO: when all lines are written and the fd is closed, the command
* doesn't get EOF and hangs. */
if (opt->jo_set & JO_IN_BUF)
job->jv_in_buf = buflist_findnr(opt->jo_io_buf[PART_IN]);
if (!winpty_spawn(term->tl_winpty, spawn_config, &child_process_handle,
&child_thread_handle, &error, &winpty_err))
goto failed;
channel_set_pipes(channel,
(sock_T) CreateFileW(
(sock_T)CreateFileW(
winpty_conin_name(term->tl_winpty),
GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL),
(sock_T) CreateFileW(
(sock_T)CreateFileW(
winpty_conout_name(term->tl_winpty),
GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL),
(sock_T) CreateFileW(
(sock_T)CreateFileW(
winpty_conerr_name(term->tl_winpty),
GENERIC_READ, 0, NULL,
OPEN_EXISTING, 0, NULL));
@@ -2929,7 +3033,7 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
}
winpty_spawn_config_free(spawn_config);
vim_free(p);
vim_free(cmd_wchar);
create_vterm(term, rows, cols);
@@ -2952,8 +3056,8 @@ term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *
failed:
if (argvar->v_type == VAR_LIST)
vim_free(ga.ga_data);
if (p != NULL)
vim_free(p);
if (cmd_wchar != NULL)
vim_free(cmd_wchar);
if (spawn_config != NULL)
winpty_spawn_config_free(spawn_config);
if (channel != NULL)
@@ -3029,7 +3133,12 @@ terminal_enabled(void)
* Return OK or FAIL.
*/
static int
term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt)
term_and_job_init(
term_T *term,
int rows,
int cols,
typval_T *argvar,
jobopt_T *opt)
{
create_vterm(term, rows, cols);
+13
View File
@@ -548,6 +548,19 @@ func Test_OptionSet()
call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 18: Setting string option"
let oldval = &tags
let g:options=[['tags', oldval, 'tagpath', 'global']]
set tags=tagpath
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" 1l: Resetting string option"
let g:options=[['tags', 'tagpath', oldval, 'global']]
set tags&
call assert_equal([], g:options)
call assert_equal(g:opt[0], g:opt[1])
" Cleanup
au! OptionSet
for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
+36 -6
View File
@@ -251,7 +251,7 @@ endfunc
func Test_terminal_size()
let cmd = Get_cat_123_cmd()
exe '5terminal ' . cmd
exe 'terminal ++rows=5 ' . cmd
let size = term_getsize('')
bwipe!
call assert_equal(5, size[0])
@@ -262,7 +262,7 @@ func Test_terminal_size()
call assert_equal(6, size[0])
vsplit
exe '5,33terminal ' . cmd
exe 'terminal ++rows=5 ++cols=33 ' . cmd
let size = term_getsize('')
bwipe!
call assert_equal([5, 33], size)
@@ -272,7 +272,7 @@ func Test_terminal_size()
bwipe!
call assert_equal([6, 36], size)
exe 'vertical 20terminal ' . cmd
exe 'vertical terminal ++cols=20 ' . cmd
let size = term_getsize('')
bwipe!
call assert_equal(20, size[1])
@@ -283,7 +283,7 @@ func Test_terminal_size()
call assert_equal(26, size[1])
split
exe 'vertical 6,20terminal ' . cmd
exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd
let size = term_getsize('')
bwipe!
call assert_equal([6, 20], size)
@@ -458,9 +458,16 @@ func Test_terminal_noblock()
call term_sendkeys(g:buf, 'echo ' . repeat(c, 5000) . "\<cr>")
endfor
call term_sendkeys(g:buf, "echo done\<cr>")
" On MS-Windows there is an extra empty line below "done". Find "done" in
" the last-but-one or the last-but-two line.
let g:lnum = term_getsize(g:buf)[0] - 1
call WaitFor('term_getline(g:buf, g:lnum) =~ "done"', 3000)
call assert_match('done', term_getline(g:buf, g:lnum))
call WaitFor('term_getline(g:buf, g:lnum) =~ "done" || term_getline(g:buf, g:lnum - 1) =~ "done"', 3000)
let line = term_getline(g:buf, g:lnum)
if line !~ 'done'
let line = term_getline(g:buf, g:lnum - 1)
endif
call assert_match('done', line)
let g:job = term_getjob(g:buf)
call Stop_shell_in_terminal(g:buf)
@@ -470,3 +477,26 @@ func Test_terminal_noblock()
unlet g:lnum
bwipe
endfunc
func Test_terminal_write_stdin()
" Todo: make this work on all systems.
if !has('unix')
return
endif
new
call setline(1, ['one', 'two', 'three'])
%term wc
call WaitFor('getline(1) != ""')
let nrs = split(getline(1))
call assert_equal(['3', '3', '14'], nrs)
bwipe
call setline(1, ['one', 'two', 'three', 'four'])
2,3term wc
call WaitFor('getline(1) != ""')
let nrs = split(getline(1))
call assert_equal(['2', '2', '10'], nrs)
bwipe
bwipe!
endfunc
+22
View File
@@ -784,6 +784,28 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
983,
/**/
982,
/**/
981,
/**/
980,
/**/
979,
/**/
978,
/**/
977,
/**/
976,
/**/
975,
/**/
974,
/**/
973,
/**/
972,
/**/