Permalink
Browse files

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.
  • Loading branch information...
brammool committed Aug 20, 2017
1 parent edbc0d4 commit b241208a13d3e9def36d749b1e824ae694aa85f8
Showing with 93 additions and 31 deletions.
  1. +8 −5 runtime/doc/terminal.txt
  2. +2 −2 src/ex_cmds.h
  3. +11 −3 src/os_unix.c
  4. +66 −17 src/terminal.c
  5. +4 −4 src/testdir/test_terminal.vim
  6. +2 −0 src/version.c
View
@@ -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.
View
@@ -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),
View
@@ -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,8 +5267,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)
{
View
@@ -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,8 +1186,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;
}
@@ -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)
View
@@ -769,6 +769,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
976,
/**/
975,
/**/

0 comments on commit b241208

Please sign in to comment.