mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user