comparison src/terminal.c @ 12031:9897241c08b5 v8.0.0896

patch 8.0.0896: cannot close a terminal window when the job ends commit https://github.com/vim/vim/commit/dd693ce28b158ff573129ee30fe5b886544a03c2 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Aug 10 23:15:19 2017 +0200 patch 8.0.0896: cannot close a terminal window when the job ends Problem: Cannot automaticlaly close a terminal window when the job ends. Solution: Add the ++close argument to :term. Add the term_finish option to term_start(). (Yasuhiro Matsumoto, closes #1950) Also add ++open.
author Christian Brabandt <cb@256bit.org>
date Thu, 10 Aug 2017 23:30:05 +0200
parents c0ee48f48a2b
children a3ed3d236839
comparison
equal deleted inserted replaced
12030:4d0860530243 12031:9897241c08b5
34 * 34 *
35 * When the job ends the text is put in a buffer. Redrawing then happens from 35 * When the job ends the text is put in a buffer. Redrawing then happens from
36 * that buffer, attributes come from the scrollback buffer tl_scrollback. 36 * that buffer, attributes come from the scrollback buffer tl_scrollback.
37 * 37 *
38 * TODO: 38 * TODO:
39 * - When the job ends:
40 * - Need an option or argument to drop the window+buffer right away, to be
41 * used for a shell or Vim. 'termfinish'; "close", "open" (open window when
42 * job finishes).
43 * patch by Yasuhiro: #1950
44 * - add option values to the command: 39 * - add option values to the command:
45 * :term <24x80> <close> vim notes.txt
46 * or use:
47 * :term ++24x80 ++close vim notes.txt 40 * :term ++24x80 ++close vim notes.txt
41 * - When using term_finish "open" have a way to specify how the window is to
42 * be opened. E.g. term_opencmd "10split buffer %d".
48 * - support different cursor shapes, colors and attributes 43 * - support different cursor shapes, colors and attributes
49 * - make term_getcursor() return type (none/block/bar/underline) and 44 * - make term_getcursor() return type (none/block/bar/underline) and
50 * attributes (color, blink, etc.) 45 * attributes (color, blink, etc.)
46 * - Make argument list work on MS-Windows. #1954
51 * - MS-Windows: no redraw for 'updatetime' #1915 47 * - MS-Windows: no redraw for 'updatetime' #1915
52 * - To set BS correctly, check get_stty(); Pass the fd of the pty. 48 * - To set BS correctly, check get_stty(); Pass the fd of the pty.
53 * For the GUI fill termios with default values, perhaps like pangoterm: 49 * For the GUI fill termios with default values, perhaps like pangoterm:
54 * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134 50 * http://bazaar.launchpad.net/~leonerd/pangoterm/trunk/view/head:/main.c#L134
55 * Also get the NL behavior from there. 51 * Also get the NL behavior from there.
122 int tl_tty_fd; 118 int tl_tty_fd;
123 char_u *tl_tty_name; 119 char_u *tl_tty_name;
124 120
125 int tl_normal_mode; /* TRUE: Terminal-Normal mode */ 121 int tl_normal_mode; /* TRUE: Terminal-Normal mode */
126 int tl_channel_closed; 122 int tl_channel_closed;
123 int tl_finish; /* 'c' for ++close, 'o' for ++open */
127 124
128 #ifdef WIN3264 125 #ifdef WIN3264
129 void *tl_winpty_config; 126 void *tl_winpty_config;
130 void *tl_winpty; 127 void *tl_winpty;
131 #endif 128 #endif
255 term = (term_T *)alloc_clear(sizeof(term_T)); 252 term = (term_T *)alloc_clear(sizeof(term_T));
256 if (term == NULL) 253 if (term == NULL)
257 return; 254 return;
258 term->tl_dirty_row_end = MAX_ROW; 255 term->tl_dirty_row_end = MAX_ROW;
259 term->tl_cursor_visible = TRUE; 256 term->tl_cursor_visible = TRUE;
257 term->tl_finish = opt->jo_term_finish;
260 ga_init2(&term->tl_scrollback, sizeof(sb_line_T), 300); 258 ga_init2(&term->tl_scrollback, sizeof(sb_line_T), 300);
261 259
262 /* Open a new window or tab. */ 260 /* Open a new window or tab. */
263 vim_memset(&split_ea, 0, sizeof(split_ea)); 261 vim_memset(&split_ea, 0, sizeof(split_ea));
264 split_ea.cmdidx = CMD_new; 262 split_ea.cmdidx = CMD_new;
358 * ":terminal": open a terminal window and execute a job in it. 356 * ":terminal": open a terminal window and execute a job in it.
359 */ 357 */
360 void 358 void
361 ex_terminal(exarg_T *eap) 359 ex_terminal(exarg_T *eap)
362 { 360 {
363 jobopt_T opt; 361 jobopt_T opt;
362 char_u *cmd;
364 363
365 init_job_options(&opt); 364 init_job_options(&opt);
365
366 cmd = eap->arg;
367 while (*cmd && *cmd == '+' && *(cmd + 1) == '+')
368 {
369 char_u *p;
370
371 cmd += 2;
372 p = skiptowhite(cmd);
373 if ((int)(p - cmd) == 5 && STRNICMP(cmd, "close", 5) == 0)
374 opt.jo_term_finish = 'c';
375 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
376 opt.jo_term_finish = 'o';
377 else
378 {
379 if (*p)
380 *p = NUL;
381 EMSG2(_("E181: Invalid attribute: %s"), cmd);
382 return;
383 }
384 cmd = skipwhite(p);
385 }
366 386
367 if (eap->addr_count == 2) 387 if (eap->addr_count == 2)
368 { 388 {
369 opt.jo_term_rows = eap->line1; 389 opt.jo_term_rows = eap->line1;
370 opt.jo_term_cols = eap->line2; 390 opt.jo_term_cols = eap->line2;
376 else 396 else
377 opt.jo_term_rows = eap->line2; 397 opt.jo_term_rows = eap->line2;
378 } 398 }
379 /* TODO: get more options from before the command */ 399 /* TODO: get more options from before the command */
380 400
381 term_start(eap->arg, &opt); 401 term_start(cmd, &opt);
382 } 402 }
383 403
384 /* 404 /*
385 * Free the scrollback buffer for "term". 405 * Free the scrollback buffer for "term".
386 */ 406 */
844 * Move the vterm contents into the scrollback buffer and free the vterm. 864 * Move the vterm contents into the scrollback buffer and free the vterm.
845 */ 865 */
846 static void 866 static void
847 cleanup_vterm(term_T *term) 867 cleanup_vterm(term_T *term)
848 { 868 {
849 move_terminal_to_buffer(term); 869 if (term->tl_finish == 0)
870 move_terminal_to_buffer(term);
850 term_free_vterm(term); 871 term_free_vterm(term);
851 set_terminal_mode(term, FALSE); 872 set_terminal_mode(term, FALSE);
852 } 873 }
853 874
854 /* 875 /*
1413 1434
1414 for (term = first_term; term != NULL; term = term->tl_next) 1435 for (term = first_term; term != NULL; term = term->tl_next)
1415 if (term->tl_job == ch->ch_job) 1436 if (term->tl_job == ch->ch_job)
1416 { 1437 {
1417 term->tl_channel_closed = TRUE; 1438 term->tl_channel_closed = TRUE;
1439 did_one = TRUE;
1418 1440
1419 vim_free(term->tl_title); 1441 vim_free(term->tl_title);
1420 term->tl_title = NULL; 1442 term->tl_title = NULL;
1421 vim_free(term->tl_status_text); 1443 vim_free(term->tl_status_text);
1422 term->tl_status_text = NULL; 1444 term->tl_status_text = NULL;
1423 1445
1424 /* Unless in Terminal-Normal mode: clear the vterm. */ 1446 /* Unless in Terminal-Normal mode: clear the vterm. */
1425 if (!term->tl_normal_mode) 1447 if (!term->tl_normal_mode)
1448 {
1449 int fnum = term->tl_buffer->b_fnum;
1450
1426 cleanup_vterm(term); 1451 cleanup_vterm(term);
1427 1452
1453 if (term->tl_finish == 'c')
1454 {
1455 /* ++close or term_finish == "close" */
1456 curbuf = term->tl_buffer;
1457 do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
1458 break;
1459 }
1460 if (term->tl_finish == 'o' && term->tl_buffer->b_nwindows == 0)
1461 {
1462 char buf[50];
1463
1464 /* TODO: use term_opencmd */
1465 vim_snprintf(buf, sizeof(buf), "botright sbuf %d", fnum);
1466 do_cmdline_cmd((char_u *)buf);
1467 }
1468 }
1469
1428 redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); 1470 redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
1429 did_one = TRUE;
1430 } 1471 }
1431 if (did_one) 1472 if (did_one)
1432 { 1473 {
1433 redraw_statuslines(); 1474 redraw_statuslines();
1434 1475
2296 /* TODO: allow more job options */ 2337 /* TODO: allow more job options */
2297 if (argvars[1].v_type != VAR_UNKNOWN 2338 if (argvars[1].v_type != VAR_UNKNOWN
2298 && get_job_options(&argvars[1], &opt, 2339 && get_job_options(&argvars[1], &opt,
2299 JO_TIMEOUT_ALL + JO_STOPONEXIT 2340 JO_TIMEOUT_ALL + JO_STOPONEXIT
2300 + JO_EXIT_CB + JO_CLOSE_CALLBACK 2341 + JO_EXIT_CB + JO_CLOSE_CALLBACK
2301 + JO2_TERM_NAME) == FAIL) 2342 + JO2_TERM_NAME + JO2_TERM_FINISH) == FAIL)
2302 return; 2343 return;
2303 2344
2304 term_start(cmd, &opt); 2345 term_start(cmd, &opt);
2305 2346
2306 if (curbuf->b_term != NULL) 2347 if (curbuf->b_term != NULL)