comparison src/terminal.c @ 12192:6947d5bcf57f v8.0.0976

patch 8.0.0976: cannot send lines to a terminal job commit https://github.com/vim/vim/commit/b241208a13d3e9def36d749b1e824ae694aa85f8 Author: Bram Moolenaar <Bram@vim.org> Date: Sun Aug 20 18:09:14 2017 +0200 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.
author Christian Brabandt <cb@256bit.org>
date Sun, 20 Aug 2017 18:15:04 +0200
parents 36456f237c59
children 53987de2115d
comparison
equal deleted inserted replaced
12191:fee055edaaef 12192:6947d5bcf57f
36 * that buffer, attributes come from the scrollback buffer tl_scrollback. 36 * that buffer, attributes come from the scrollback buffer tl_scrollback.
37 * When the buffer is changed it is turned into a normal buffer, the attributes 37 * When the buffer is changed it is turned into a normal buffer, the attributes
38 * in tl_scrollback are no longer used. 38 * in tl_scrollback are no longer used.
39 * 39 *
40 * TODO: 40 * TODO:
41 * - make [range]terminal pipe [range] lines to the terminal 41 * - test writing lines to terminal job when implemented for MS-Windows
42 * - implement term_setsize() 42 * - implement term_setsize()
43 * - add test for giving error for invalid 'termsize' value. 43 * - add test for giving error for invalid 'termsize' value.
44 * - support minimal size when 'termsize' is "rows*cols". 44 * - support minimal size when 'termsize' is "rows*cols".
45 * - support minimal size when 'termsize' is empty? 45 * - support minimal size when 'termsize' is empty?
46 * - implement job options when starting a terminal. Allow: 46 * - implement job options when starting a terminal. Allow:
445 init_job_options(&opt); 445 init_job_options(&opt);
446 446
447 cmd = eap->arg; 447 cmd = eap->arg;
448 while (*cmd && *cmd == '+' && *(cmd + 1) == '+') 448 while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
449 { 449 {
450 char_u *p; 450 char_u *p, *ep;
451 451
452 cmd += 2; 452 cmd += 2;
453 p = skiptowhite(cmd); 453 p = skiptowhite(cmd);
454 ep = vim_strchr(cmd, '=');
455 if (ep != NULL && ep < p)
456 p = ep;
457
454 if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0) 458 if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0)
455 opt.jo_term_finish = 'c'; 459 opt.jo_term_finish = 'c';
456 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0) 460 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
457 opt.jo_term_finish = 'o'; 461 opt.jo_term_finish = 'o';
458 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "curwin", 6) == 0) 462 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "curwin", 6) == 0)
459 opt.jo_curwin = 1; 463 opt.jo_curwin = 1;
460 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0) 464 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0)
461 opt.jo_hidden = 1; 465 opt.jo_hidden = 1;
466 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "rows", 4) == 0
467 && ep != NULL && isdigit(ep[1]))
468 {
469 opt.jo_set2 |= JO2_TERM_ROWS;
470 opt.jo_term_rows = atoi((char *)ep + 1);
471 p = skiptowhite(cmd);
472 }
473 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "cols", 4) == 0
474 && ep != NULL && isdigit(ep[1]))
475 {
476 opt.jo_set2 |= JO2_TERM_COLS;
477 opt.jo_term_cols = atoi((char *)ep + 1);
478 p = skiptowhite(cmd);
479 }
462 else 480 else
463 { 481 {
464 if (*p) 482 if (*p)
465 *p = NUL; 483 *p = NUL;
466 EMSG2(_("E181: Invalid attribute: %s"), cmd); 484 EMSG2(_("E181: Invalid attribute: %s"), cmd);
470 } 488 }
471 if (cmd == NULL || *cmd == NUL) 489 if (cmd == NULL || *cmd == NUL)
472 /* Make a copy, an autocommand may set 'shell'. */ 490 /* Make a copy, an autocommand may set 'shell'. */
473 tofree = cmd = vim_strsave(p_sh); 491 tofree = cmd = vim_strsave(p_sh);
474 492
475 if (eap->addr_count == 2) 493 if (eap->addr_count > 0)
476 { 494 {
477 opt.jo_term_rows = eap->line1; 495 /* Write lines from current buffer to the job. */
478 opt.jo_term_cols = eap->line2; 496 opt.jo_set |= JO_IN_IO | JO_IN_BUF | JO_IN_TOP | JO_IN_BOT;
479 } 497 opt.jo_io[PART_IN] = JIO_BUFFER;
480 else if (eap->addr_count == 1) 498 opt.jo_io_buf[PART_IN] = curbuf->b_fnum;
481 { 499 opt.jo_in_top = eap->line1;
482 if (cmdmod.split & WSP_VERT) 500 opt.jo_in_bot = eap->line2;
483 opt.jo_term_cols = eap->line2;
484 else
485 opt.jo_term_rows = eap->line2;
486 } 501 }
487 502
488 argvar.v_type = VAR_STRING; 503 argvar.v_type = VAR_STRING;
489 argvar.vval.v_string = cmd; 504 argvar.vval.v_string = cmd;
490 term_start(&argvar, &opt, eap->forceit); 505 term_start(&argvar, &opt, eap->forceit);
1076 --allow_keys; 1091 --allow_keys;
1077 return c; 1092 return c;
1078 } 1093 }
1079 1094
1080 /* 1095 /*
1096 * Get the part that is connected to the tty. Normally this is PART_IN, but
1097 * when writing buffer lines to the job it can be another. This makes it
1098 * possible to do "1,5term vim -".
1099 */
1100 static ch_part_T
1101 get_tty_part(term_T *term)
1102 {
1103 #ifdef UNIX
1104 ch_part_T parts[3] = {PART_IN, PART_OUT, PART_ERR};
1105 int i;
1106
1107 for (i = 0; i < 3; ++i)
1108 {
1109 int fd = term->tl_job->jv_channel->ch_part[parts[i]].ch_fd;
1110
1111 if (isatty(fd))
1112 return parts[i];
1113 }
1114 #endif
1115 return PART_IN;
1116 }
1117
1118 /*
1081 * Send keys to terminal. 1119 * Send keys to terminal.
1082 * Return FAIL when the key needs to be handled in Normal mode. 1120 * Return FAIL when the key needs to be handled in Normal mode.
1083 * Return OK when the key was dropped or sent to the terminal. 1121 * Return OK when the key was dropped or sent to the terminal.
1084 */ 1122 */
1085 int 1123 int
1146 1184
1147 /* Convert the typed key to a sequence of bytes for the job. */ 1185 /* Convert the typed key to a sequence of bytes for the job. */
1148 len = term_convert_key(term, c, msg); 1186 len = term_convert_key(term, c, msg);
1149 if (len > 0) 1187 if (len > 0)
1150 /* TODO: if FAIL is returned, stop? */ 1188 /* TODO: if FAIL is returned, stop? */
1151 channel_send(term->tl_job->jv_channel, PART_IN, 1189 channel_send(term->tl_job->jv_channel, get_tty_part(term),
1152 (char_u *)msg, (int)len, NULL); 1190 (char_u *)msg, (int)len, NULL);
1153 1191
1154 return OK; 1192 return OK;
1155 } 1193 }
1156 1194
1157 static void 1195 static void
1330 position_cursor(curwin, &curbuf->b_term->tl_cursor_pos); 1368 position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
1331 may_set_cursor_props(curbuf->b_term); 1369 may_set_cursor_props(curbuf->b_term);
1332 1370
1333 #ifdef UNIX 1371 #ifdef UNIX
1334 { 1372 {
1335 int fd = curbuf->b_term->tl_job->jv_channel->ch_part[PART_IN].ch_fd; 1373 int part = get_tty_part(curbuf->b_term);
1374 int fd = curbuf->b_term->tl_job->jv_channel->ch_part[part].ch_fd;
1336 1375
1337 if (isatty(fd)) 1376 if (isatty(fd))
1338 { 1377 {
1339 ttyinfo_T info; 1378 ttyinfo_T info;
1340 1379
2821 * Create a new terminal of "rows" by "cols" cells. 2860 * Create a new terminal of "rows" by "cols" cells.
2822 * Store a reference in "term". 2861 * Store a reference in "term".
2823 * Return OK or FAIL. 2862 * Return OK or FAIL.
2824 */ 2863 */
2825 static int 2864 static int
2826 term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt) 2865 term_and_job_init(
2866 term_T *term,
2867 int rows,
2868 int cols,
2869 typval_T *argvar,
2870 jobopt_T *opt)
2827 { 2871 {
2828 WCHAR *p = NULL; 2872 WCHAR *p = NULL;
2829 channel_T *channel = NULL; 2873 channel_T *channel = NULL;
2830 job_T *job = NULL; 2874 job_T *job = NULL;
2831 DWORD error; 2875 DWORD error;
3018 * Start job for "cmd". 3062 * Start job for "cmd".
3019 * Store the pointers in "term". 3063 * Store the pointers in "term".
3020 * Return OK or FAIL. 3064 * Return OK or FAIL.
3021 */ 3065 */
3022 static int 3066 static int
3023 term_and_job_init(term_T *term, int rows, int cols, typval_T *argvar, jobopt_T *opt) 3067 term_and_job_init(
3068 term_T *term,
3069 int rows,
3070 int cols,
3071 typval_T *argvar,
3072 jobopt_T *opt)
3024 { 3073 {
3025 create_vterm(term, rows, cols); 3074 create_vterm(term, rows, cols);
3026 3075
3027 /* TODO: if the command is "NONE" only create a pty. */ 3076 /* TODO: if the command is "NONE" only create a pty. */
3028 term->tl_job = job_start(argvar, opt); 3077 term->tl_job = job_start(argvar, opt);