To: vim_dev@googlegroups.com Subject: Patch 8.0.0976 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0976 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. Files: src/ex_cmds.h, src/terminal.c, src/os_unix.c, src/testdir/test_terminal.vim, runtime/doc/terminal.txt *** ../vim-8.0.0975/src/ex_cmds.h 2017-08-11 22:27:44.513127603 +0200 --- src/ex_cmds.h 2017-08-20 17:44:32.652567654 +0200 *************** *** 1484,1491 **** NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN, ADDR_LINES), EX(CMD_terminal, "terminal", ex_terminal, ! RANGE|NOTADR|BANG|FILES|TRLBAR|CMDWIN, ! ADDR_OTHER), EX(CMD_tfirst, "tfirst", ex_tag, RANGE|NOTADR|BANG|TRLBAR|ZEROR, ADDR_LINES), --- 1484,1491 ---- NEEDARG|EXTRA|TRLBAR|NOTRLCOM|CMDWIN, ADDR_LINES), EX(CMD_terminal, "terminal", ex_terminal, ! RANGE|BANG|FILES|TRLBAR|CMDWIN, ! ADDR_LINES), EX(CMD_tfirst, "tfirst", ex_tag, RANGE|NOTADR|BANG|TRLBAR|ZEROR, ADDR_LINES), *** ../vim-8.0.0975/src/terminal.c 2017-08-20 15:05:11.620196302 +0200 --- src/terminal.c 2017-08-20 18:05:20.488715301 +0200 *************** *** 38,44 **** * in tl_scrollback are no longer used. * * TODO: ! * - make [range]terminal pipe [range] lines to the terminal * - implement term_setsize() * - add test for giving error for invalid 'termsize' value. * - support minimal size when 'termsize' is "rows*cols". --- 38,44 ---- * in tl_scrollback are no longer used. * * TODO: ! * - 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,456 **** cmd = eap->arg; while (*cmd && *cmd == '+' && *(cmd + 1) == '+') { ! char_u *p; cmd += 2; p = skiptowhite(cmd); 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) --- 447,460 ---- cmd = eap->arg; while (*cmd && *cmd == '+' && *(cmd + 1) == '+') { ! 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,464 **** --- 463,482 ---- 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,488 **** /* Make a copy, an autocommand may set 'shell'. */ tofree = cmd = vim_strsave(p_sh); ! if (eap->addr_count == 2) { ! 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; } argvar.v_type = VAR_STRING; --- 490,503 ---- /* Make a copy, an autocommand may set 'shell'. */ tofree = cmd = vim_strsave(p_sh); ! if (eap->addr_count > 0) { ! /* 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; *************** *** 1078,1083 **** --- 1093,1121 ---- } /* + * 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. * Return OK when the key was dropped or sent to the terminal. *************** *** 1148,1155 **** 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); return OK; } --- 1186,1193 ---- len = term_convert_key(term, c, msg); if (len > 0) /* TODO: if FAIL is returned, stop? */ ! channel_send(term->tl_job->jv_channel, get_tty_part(term), ! (char_u *)msg, (int)len, NULL); return OK; } *************** *** 1332,1338 **** #ifdef UNIX { ! int fd = curbuf->b_term->tl_job->jv_channel->ch_part[PART_IN].ch_fd; if (isatty(fd)) { --- 1370,1377 ---- #ifdef UNIX { ! 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,2829 **** * Return OK or FAIL. */ static int ! term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt) { WCHAR *p = NULL; channel_T *channel = NULL; --- 2862,2873 ---- * Return OK or FAIL. */ static int ! 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,3026 **** * Return OK or FAIL. */ static int ! term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt) { create_vterm(term, rows, cols); --- 3064,3075 ---- * Return OK or FAIL. */ static int ! term_and_job_init( ! term_T *term, ! int rows, ! int cols, ! typval_T *argvar, ! jobopt_T *opt) { create_vterm(term, rows, cols); *** ../vim-8.0.0975/src/os_unix.c 2017-08-13 20:06:14.963846989 +0200 --- src/os_unix.c 2017-08-20 17:50:14.902409545 +0200 *************** *** 5238,5243 **** --- 5238,5244 ---- 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,5253 **** /* default is to fail */ job->jv_status = JOB_FAILED; ! if (options->jo_pty) open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_name); /* TODO: without the channel feature connect the child to /dev/null? */ --- 5248,5257 ---- /* default is to fail */ job->jv_status = JOB_FAILED; ! 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,5270 **** goto failed; } } ! else if (!use_null_for_in && pty_master_fd < 0 && pipe(fd_in) < 0) ! goto failed; if (use_file_for_out) { --- 5267,5278 ---- 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) { *** ../vim-8.0.0975/src/testdir/test_terminal.vim 2017-08-19 15:39:56.011220406 +0200 --- src/testdir/test_terminal.vim 2017-08-20 17:55:00.468611020 +0200 *************** *** 251,257 **** func Test_terminal_size() let cmd = Get_cat_123_cmd() ! exe '5terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal(5, size[0]) --- 251,257 ---- func Test_terminal_size() let cmd = Get_cat_123_cmd() ! exe 'terminal ++rows=5 ' . cmd let size = term_getsize('') bwipe! call assert_equal(5, size[0]) *************** *** 262,268 **** call assert_equal(6, size[0]) vsplit ! exe '5,33terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal([5, 33], size) --- 262,268 ---- call assert_equal(6, size[0]) vsplit ! exe 'terminal ++rows=5 ++cols=33 ' . cmd let size = term_getsize('') bwipe! call assert_equal([5, 33], size) *************** *** 272,278 **** bwipe! call assert_equal([6, 36], size) ! exe 'vertical 20terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal(20, size[1]) --- 272,278 ---- bwipe! call assert_equal([6, 36], size) ! exe 'vertical terminal ++cols=20 ' . cmd let size = term_getsize('') bwipe! call assert_equal(20, size[1]) *************** *** 283,289 **** call assert_equal(26, size[1]) split ! exe 'vertical 6,20terminal ' . cmd let size = term_getsize('') bwipe! call assert_equal([6, 20], size) --- 283,289 ---- call assert_equal(26, size[1]) split ! exe 'vertical terminal ++rows=6 ++cols=20 ' . cmd let size = term_getsize('') bwipe! call assert_equal([6, 20], size) *** ../vim-8.0.0975/runtime/doc/terminal.txt 2017-08-18 22:57:02.325403165 +0200 --- runtime/doc/terminal.txt 2017-08-20 16:46:18.230557870 +0200 *************** *** 1,4 **** ! *terminal.txt* For Vim version 8.0. Last change: 2017 Aug 12 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *terminal.txt* For Vim version 8.0. Last change: 2017 Aug 20 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 102,111 **** 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. Two comma separated numbers are used as "rows,cols". E.g. `:24,80gdb` opens a terminal with 24 rows and 80 --- 102,110 ---- parentheses. E.g. if "gdb" exists the second terminal buffer will use "!gdb (1)". ! 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,130 **** --- 124,133 ---- 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. *** ../vim-8.0.0975/src/version.c 2017-08-20 16:11:45.223461107 +0200 --- src/version.c 2017-08-20 16:53:24.191885016 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 976, /**/ -- You can test a person's importance in the organization by asking how much RAM his computer has. Anybody who knows the answer to that question is not a decision-maker. (Scott Adams - The Dilbert principle) /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///