Mercurial > vim
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) |