comparison src/terminal.c @ 12064:407a475c67fd v8.0.0912

patch 8.0.0912: cannot run a job in a hidden terminal commit https://github.com/vim/vim/commit/8cad930a259a05a95c7d0c527a5881d5f9a59057 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 12 14:32:32 2017 +0200 patch 8.0.0912: cannot run a job in a hidden terminal Problem: Cannot run a job in a hidden terminal. Solution: Add option "hidden" and ++hidden.
author Christian Brabandt <cb@256bit.org>
date Sat, 12 Aug 2017 14:45:04 +0200
parents a879814b8a37
children 8ad282dee649
comparison
equal deleted inserted replaced
12063:2372e456e821 12064:407a475c67fd
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 * - add option values to the command:
40 * :term ++24x80 ++close vim notes.txt
41 * - When using term_finish "open" have a way to specify how the window is to 39 * - 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". 40 * be opened. E.g. term_opencmd "10split buffer %d".
43 * - support different cursor shapes, colors and attributes 41 * - support different cursor shapes, colors and attributes
44 * - make term_getcursor() return type (none/block/bar/underline) and 42 * - make term_getcursor() return type (none/block/bar/underline) and
45 * attributes (color, blink, etc.) 43 * attributes (color, blink, etc.)
247 term_start(char_u *cmd, jobopt_T *opt, int forceit) 245 term_start(char_u *cmd, jobopt_T *opt, int forceit)
248 { 246 {
249 exarg_T split_ea; 247 exarg_T split_ea;
250 win_T *old_curwin = curwin; 248 win_T *old_curwin = curwin;
251 term_T *term; 249 term_T *term;
250 buf_T *old_curbuf = NULL;
252 251
253 if (check_restricted() || check_secure()) 252 if (check_restricted() || check_secure())
254 return; 253 return;
255 254
256 term = (term_T *)alloc_clear(sizeof(term_T)); 255 term = (term_T *)alloc_clear(sizeof(term_T));
266 { 265 {
267 /* Create a new buffer in the current window. */ 266 /* Create a new buffer in the current window. */
268 if (!can_abandon(curbuf, forceit)) 267 if (!can_abandon(curbuf, forceit))
269 { 268 {
270 EMSG(_(e_nowrtmsg)); 269 EMSG(_(e_nowrtmsg));
270 vim_free(term);
271 return; 271 return;
272 } 272 }
273 if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE, 273 if (do_ecmd(0, NULL, NULL, &split_ea, ECMD_ONE,
274 ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL) 274 ECMD_HIDE + (forceit ? ECMD_FORCEIT : 0), curwin) == FAIL)
275 {
276 vim_free(term);
275 return; 277 return;
278 }
279 }
280 else if (opt->jo_hidden)
281 {
282 buf_T *buf;
283
284 /* Create a new buffer without a window. Make it the current buffer for
285 * a moment to be able to do the initialisations. */
286 buf = buflist_new((char_u *)"", NULL, (linenr_T)0,
287 BLN_NEW | BLN_LISTED);
288 if (buf == NULL || ml_open(buf) == FAIL)
289 {
290 vim_free(term);
291 return;
292 }
293 old_curbuf = curbuf;
294 --curbuf->b_nwindows;
295 curbuf = buf;
296 curwin->w_buffer = buf;
297 ++curbuf->b_nwindows;
276 } 298 }
277 else 299 else
278 { 300 {
279 /* Open a new window or tab. */ 301 /* Open a new window or tab. */
280 split_ea.cmdidx = CMD_new; 302 split_ea.cmdidx = CMD_new;
300 } 322 }
301 } 323 }
302 term->tl_buffer = curbuf; 324 term->tl_buffer = curbuf;
303 curbuf->b_term = term; 325 curbuf->b_term = term;
304 326
305 /* only one size was taken care of with :new, do the other one */ 327 if (!opt->jo_hidden)
306 if (opt->jo_term_rows > 0 && (cmdmod.split & WSP_VERT)) 328 {
307 win_setheight(opt->jo_term_rows); 329 /* only one size was taken care of with :new, do the other one */
308 if (opt->jo_term_cols > 0 && !(cmdmod.split & WSP_VERT)) 330 if (opt->jo_term_rows > 0 && (cmdmod.split & WSP_VERT))
309 win_setwidth(opt->jo_term_cols); 331 win_setheight(opt->jo_term_rows);
332 if (opt->jo_term_cols > 0 && !(cmdmod.split & WSP_VERT))
333 win_setwidth(opt->jo_term_cols);
334 }
310 335
311 /* Link the new terminal in the list of active terminals. */ 336 /* Link the new terminal in the list of active terminals. */
312 term->tl_next = first_term; 337 term->tl_next = first_term;
313 first_term = term; 338 first_term = term;
314 339
358 if (term_and_job_init(term, term->tl_rows, term->tl_cols, cmd, opt) == OK) 383 if (term_and_job_init(term, term->tl_rows, term->tl_cols, cmd, opt) == OK)
359 { 384 {
360 /* Get and remember the size we ended up with. Update the pty. */ 385 /* Get and remember the size we ended up with. Update the pty. */
361 vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols); 386 vterm_get_size(term->tl_vterm, &term->tl_rows, &term->tl_cols);
362 term_report_winsize(term, term->tl_rows, term->tl_cols); 387 term_report_winsize(term, term->tl_rows, term->tl_cols);
388
389 if (old_curbuf != NULL)
390 {
391 --curbuf->b_nwindows;
392 curbuf = old_curbuf;
393 curwin->w_buffer = curbuf;
394 ++curbuf->b_nwindows;
395 }
363 } 396 }
364 else 397 else
365 { 398 {
399 buf_T *buf = curbuf;
400
366 free_terminal(curbuf); 401 free_terminal(curbuf);
402 if (old_curbuf != NULL)
403 {
404 --curbuf->b_nwindows;
405 curbuf = old_curbuf;
406 curwin->w_buffer = curbuf;
407 ++curbuf->b_nwindows;
408 }
367 409
368 /* Wiping out the buffer will also close the window and call 410 /* Wiping out the buffer will also close the window and call
369 * free_terminal(). */ 411 * free_terminal(). */
370 do_buffer(DOBUF_WIPE, DOBUF_CURRENT, FORWARD, 0, TRUE); 412 do_buffer(DOBUF_WIPE, DOBUF_FIRST, FORWARD, buf->b_fnum, TRUE);
371 } 413 }
372 } 414 }
373 415
374 /* 416 /*
375 * ":terminal": open a terminal window and execute a job in it. 417 * ":terminal": open a terminal window and execute a job in it.
393 opt.jo_term_finish = 'c'; 435 opt.jo_term_finish = 'c';
394 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0) 436 else if ((int)(p - cmd) == 4 && STRNICMP(cmd, "open", 4) == 0)
395 opt.jo_term_finish = 'o'; 437 opt.jo_term_finish = 'o';
396 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "curwin", 6) == 0) 438 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "curwin", 6) == 0)
397 opt.jo_curwin = 1; 439 opt.jo_curwin = 1;
440 else if ((int)(p - cmd) == 6 && STRNICMP(cmd, "hidden", 6) == 0)
441 opt.jo_hidden = 1;
398 else 442 else
399 { 443 {
400 if (*p) 444 if (*p)
401 *p = NUL; 445 *p = NUL;
402 EMSG2(_("E181: Invalid attribute: %s"), cmd); 446 EMSG2(_("E181: Invalid attribute: %s"), cmd);
884 * Move the vterm contents into the scrollback buffer and free the vterm. 928 * Move the vterm contents into the scrollback buffer and free the vterm.
885 */ 929 */
886 static void 930 static void
887 cleanup_vterm(term_T *term) 931 cleanup_vterm(term_T *term)
888 { 932 {
889 if (term->tl_finish == 0) 933 if (term->tl_finish != 'c')
890 move_terminal_to_buffer(term); 934 move_terminal_to_buffer(term);
891 term_free_vterm(term); 935 term_free_vterm(term);
892 set_terminal_mode(term, FALSE); 936 set_terminal_mode(term, FALSE);
893 } 937 }
894 938
1220 return FAIL; 1264 return FAIL;
1221 } 1265 }
1222 1266
1223 /* 1267 /*
1224 * Called when a job has finished. 1268 * Called when a job has finished.
1225 * This updates the title and status, but does not close the vter, because 1269 * This updates the title and status, but does not close the vterm, because
1226 * there might still be pending output in the channel. 1270 * there might still be pending output in the channel.
1227 */ 1271 */
1228 void 1272 void
1229 term_job_ended(job_T *job) 1273 term_job_ended(job_T *job)
1230 { 1274 {
1476 cleanup_vterm(term); 1520 cleanup_vterm(term);
1477 1521
1478 if (term->tl_finish == 'c') 1522 if (term->tl_finish == 'c')
1479 { 1523 {
1480 /* ++close or term_finish == "close" */ 1524 /* ++close or term_finish == "close" */
1525 ch_log(NULL, "terminal job finished, closing window");
1481 curbuf = term->tl_buffer; 1526 curbuf = term->tl_buffer;
1482 do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE); 1527 do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
1483 break; 1528 break;
1484 } 1529 }
1485 if (term->tl_finish == 'o' && term->tl_buffer->b_nwindows == 0) 1530 if (term->tl_finish == 'o' && term->tl_buffer->b_nwindows == 0)
1486 { 1531 {
1487 char buf[50]; 1532 char buf[50];
1488 1533
1489 /* TODO: use term_opencmd */ 1534 /* TODO: use term_opencmd */
1535 ch_log(NULL, "terminal job finished, opening window");
1490 vim_snprintf(buf, sizeof(buf), "botright sbuf %d", fnum); 1536 vim_snprintf(buf, sizeof(buf), "botright sbuf %d", fnum);
1491 do_cmdline_cmd((char_u *)buf); 1537 do_cmdline_cmd((char_u *)buf);
1492 } 1538 }
1539 else
1540 ch_log(NULL, "terminal job finished");
1493 } 1541 }
1494 1542
1495 redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); 1543 redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
1496 } 1544 }
1497 if (did_one) 1545 if (did_one)
2378 /* TODO: allow more job options */ 2426 /* TODO: allow more job options */
2379 if (argvars[1].v_type != VAR_UNKNOWN 2427 if (argvars[1].v_type != VAR_UNKNOWN
2380 && get_job_options(&argvars[1], &opt, 2428 && get_job_options(&argvars[1], &opt,
2381 JO_TIMEOUT_ALL + JO_STOPONEXIT 2429 JO_TIMEOUT_ALL + JO_STOPONEXIT
2382 + JO_EXIT_CB + JO_CLOSE_CALLBACK, 2430 + JO_EXIT_CB + JO_CLOSE_CALLBACK,
2383 JO2_TERM_NAME + JO2_TERM_FINISH 2431 JO2_TERM_NAME + JO2_TERM_FINISH + JO2_HIDDEN
2384 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN 2432 + JO2_TERM_COLS + JO2_TERM_ROWS + JO2_VERTICAL + JO2_CURWIN
2385 + JO2_CWD + JO2_ENV) == FAIL) 2433 + JO2_CWD + JO2_ENV) == FAIL)
2386 return; 2434 return;
2387 2435
2388 if (opt.jo_vertical) 2436 if (opt.jo_vertical)