mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.0.0976: cannot send lines to a terminal job
Problem: Cannot send lines to a terminal job. Solution: Make [range]terminal send selected lines to the job. Use ++rows and ++cols for the terminal size.
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.
|
||||
|
@@ -1484,8 +1484,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),
|
||||
|
@@ -5238,6 +5238,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)
|
||||
|
||||
@@ -5247,7 +5248,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? */
|
||||
@@ -5263,7 +5267,11 @@ 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)
|
||||
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)
|
||||
|
@@ -38,7 +38,7 @@
|
||||
* in tl_scrollback are no longer used.
|
||||
*
|
||||
* TODO:
|
||||
* - make [range]terminal pipe [range] lines to the terminal
|
||||
* - test writing lines to terminal job when implemented for MS-Windows
|
||||
* - implement term_setsize()
|
||||
* - add test for giving error for invalid 'termsize' value.
|
||||
* - support minimal size when 'termsize' is "rows*cols".
|
||||
@@ -447,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)
|
||||
@@ -459,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)
|
||||
@@ -472,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;
|
||||
@@ -1077,6 +1092,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.
|
||||
@@ -1148,7 +1186,7 @@ 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,
|
||||
channel_send(term->tl_job->jv_channel, get_tty_part(term),
|
||||
(char_u *)msg, (int)len, NULL);
|
||||
|
||||
return OK;
|
||||
@@ -1332,7 +1370,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))
|
||||
{
|
||||
@@ -2823,7 +2862,12 @@ 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;
|
||||
channel_T *channel = NULL;
|
||||
@@ -3020,7 +3064,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);
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -769,6 +769,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
976,
|
||||
/**/
|
||||
975,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user