Skip to content

Commit 7569a35

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents 292d598 + 0cb8ac7 commit 7569a35

6 files changed

Lines changed: 121 additions & 48 deletions

File tree

src/proto/screen.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ void redraw_buf_and_status_later(buf_T *buf, int type);
99
int redraw_asap(int type);
1010
void redraw_after_callback(int call_update_screen);
1111
void redrawWinline(linenr_T lnum, int invalid);
12+
void reset_updating_screen(int may_resize_shell);
1213
void update_curbuf(int type);
1314
int update_screen(int type_arg);
1415
int conceal_cursor_line(win_T *wp);

src/proto/terminal.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ void term_win_entered(void);
2020
int terminal_loop(int blocking);
2121
void term_job_ended(job_T *job);
2222
void term_channel_closed(channel_T *ch);
23+
void term_check_channel_closed_recently(void);
2324
int term_do_update_window(win_T *wp);
2425
void term_update_window(win_T *wp);
2526
int term_is_finished(buf_T *buf);

src/screen.c

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,19 @@ redrawWinline(
512512
curwin->w_lines[i].wl_valid = FALSE;
513513
}
514514
#endif
515+
}
516+
517+
void
518+
reset_updating_screen(int may_resize_shell UNUSED)
519+
{
520+
updating_screen = FALSE;
521+
#ifdef FEAT_GUI
522+
if (may_resize_shell)
523+
gui_may_resize_shell();
524+
#endif
525+
#ifdef FEAT_TERMINAL
526+
term_check_channel_closed_recently();
527+
#endif
515528
}
516529

517530
/*
@@ -778,10 +791,7 @@ update_screen(int type_arg)
778791
FOR_ALL_WINDOWS(wp)
779792
wp->w_buffer->b_mod_set = FALSE;
780793

781-
updating_screen = FALSE;
782-
#ifdef FEAT_GUI
783-
gui_may_resize_shell();
784-
#endif
794+
reset_updating_screen(TRUE);
785795

786796
/* Clear or redraw the command line. Done last, because scrolling may
787797
* mess up the command line. */
@@ -861,11 +871,9 @@ update_finish(void)
861871
end_search_hl();
862872
# endif
863873

864-
updating_screen = FALSE;
874+
reset_updating_screen(TRUE);
865875

866876
# ifdef FEAT_GUI
867-
gui_may_resize_shell();
868-
869877
/* Redraw the cursor and update the scrollbars when all screen updating is
870878
* done. */
871879
if (gui.in_use)

src/terminal.c

Lines changed: 96 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
* in tl_scrollback are no longer used.
3939
*
4040
* TODO:
41+
* - Win32: Termdebug doesn't work, because gdb does not support mi2. This
42+
* plugin: https://github.com/cpiger/NeoDebug runs gdb as a job, redirecting
43+
* input and output. Command I/O is in gdb window.
4144
* - Win32: Redirecting input does not work, half of Test_terminal_redir_file()
4245
* is disabled.
4346
* - Win32: Redirecting output works but includes escape sequences.
@@ -100,6 +103,8 @@ struct terminal_S {
100103

101104
int tl_normal_mode; /* TRUE: Terminal-Normal mode */
102105
int tl_channel_closed;
106+
int tl_channel_recently_closed; // still need to handle tl_finish
107+
103108
int tl_finish;
104109
#define TL_FINISH_UNSET NUL
105110
#define TL_FINISH_CLOSE 'c' /* ++close or :terminal without argument */
@@ -971,12 +976,10 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
971976
if (buffer == curbuf)
972977
{
973978
update_screen(0);
974-
update_cursor(term, TRUE);
975-
#ifdef FEAT_GUI_MACVIM
976-
/* Force a flush now for better experience of interactive shell. */
977-
if (gui.in_use)
978-
gui_macvim_force_flush();
979-
#endif
979+
/* update_screen() can be slow, check the terminal wasn't closed
980+
* already */
981+
if (buffer == curbuf && curbuf->b_term != NULL)
982+
update_cursor(curbuf->b_term, TRUE);
980983
}
981984
else
982985
redraw_after_callback(TRUE);
@@ -2105,6 +2108,10 @@ terminal_loop(int blocking)
21052108
while (must_redraw != 0)
21062109
if (update_screen(0) == FAIL)
21072110
break;
2111+
if (!term_use_loop_check(TRUE))
2112+
/* job finished while redrawing */
2113+
break;
2114+
21082115
update_cursor(curbuf->b_term, FALSE);
21092116
restore_cursor = TRUE;
21102117

@@ -2774,6 +2781,53 @@ static VTermScreenCallbacks screen_callbacks = {
27742781
NULL /* sb_popline */
27752782
};
27762783

2784+
/*
2785+
* Do the work after the channel of a terminal was closed.
2786+
* Must be called only when updating_screen is FALSE.
2787+
* Returns TRUE when a buffer was closed (list of terminals may have changed).
2788+
*/
2789+
static int
2790+
term_after_channel_closed(term_T *term)
2791+
{
2792+
/* Unless in Terminal-Normal mode: clear the vterm. */
2793+
if (!term->tl_normal_mode)
2794+
{
2795+
int fnum = term->tl_buffer->b_fnum;
2796+
2797+
cleanup_vterm(term);
2798+
2799+
if (term->tl_finish == TL_FINISH_CLOSE)
2800+
{
2801+
aco_save_T aco;
2802+
2803+
/* ++close or term_finish == "close" */
2804+
ch_log(NULL, "terminal job finished, closing window");
2805+
aucmd_prepbuf(&aco, term->tl_buffer);
2806+
do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
2807+
aucmd_restbuf(&aco);
2808+
return TRUE;
2809+
}
2810+
if (term->tl_finish == TL_FINISH_OPEN
2811+
&& term->tl_buffer->b_nwindows == 0)
2812+
{
2813+
char buf[50];
2814+
2815+
/* TODO: use term_opencmd */
2816+
ch_log(NULL, "terminal job finished, opening window");
2817+
vim_snprintf(buf, sizeof(buf),
2818+
term->tl_opencmd == NULL
2819+
? "botright sbuf %d"
2820+
: (char *)term->tl_opencmd, fnum);
2821+
do_cmdline_cmd((char_u *)buf);
2822+
}
2823+
else
2824+
ch_log(NULL, "terminal job finished");
2825+
}
2826+
2827+
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
2828+
return FALSE;
2829+
}
2830+
27772831
/*
27782832
* Called when a channel has been closed.
27792833
* If this was a channel for a terminal window then finish it up.
@@ -2782,9 +2836,12 @@ static VTermScreenCallbacks screen_callbacks = {
27822836
term_channel_closed(channel_T *ch)
27832837
{
27842838
term_T *term;
2839+
term_T *next_term;
27852840
int did_one = FALSE;
27862841

2787-
for (term = first_term; term != NULL; term = term->tl_next)
2842+
for (term = first_term; term != NULL; term = next_term)
2843+
{
2844+
next_term = term->tl_next;
27882845
if (term->tl_job == ch->ch_job)
27892846
{
27902847
term->tl_channel_closed = TRUE;
@@ -2800,43 +2857,19 @@ term_channel_closed(channel_T *ch)
28002857
}
28012858
#endif
28022859

2803-
/* Unless in Terminal-Normal mode: clear the vterm. */
2804-
if (!term->tl_normal_mode)
2860+
if (updating_screen)
28052861
{
2806-
int fnum = term->tl_buffer->b_fnum;
2807-
2808-
cleanup_vterm(term);
2809-
2810-
if (term->tl_finish == TL_FINISH_CLOSE)
2811-
{
2812-
aco_save_T aco;
2813-
2814-
/* ++close or term_finish == "close" */
2815-
ch_log(NULL, "terminal job finished, closing window");
2816-
aucmd_prepbuf(&aco, term->tl_buffer);
2817-
do_bufdel(DOBUF_WIPE, (char_u *)"", 1, fnum, fnum, FALSE);
2818-
aucmd_restbuf(&aco);
2819-
break;
2820-
}
2821-
if (term->tl_finish == TL_FINISH_OPEN
2822-
&& term->tl_buffer->b_nwindows == 0)
2823-
{
2824-
char buf[50];
2825-
2826-
/* TODO: use term_opencmd */
2827-
ch_log(NULL, "terminal job finished, opening window");
2828-
vim_snprintf(buf, sizeof(buf),
2829-
term->tl_opencmd == NULL
2830-
? "botright sbuf %d"
2831-
: (char *)term->tl_opencmd, fnum);
2832-
do_cmdline_cmd((char_u *)buf);
2833-
}
2834-
else
2835-
ch_log(NULL, "terminal job finished");
2862+
/* Cannot open or close windows now. Can happen when
2863+
* 'lazyredraw' is set. */
2864+
term->tl_channel_recently_closed = TRUE;
2865+
continue;
28362866
}
28372867

2838-
redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
2868+
if (term_after_channel_closed(term))
2869+
next_term = first_term;
28392870
}
2871+
}
2872+
28402873
if (did_one)
28412874
{
28422875
redraw_statuslines();
@@ -2855,6 +2888,29 @@ term_channel_closed(channel_T *ch)
28552888
}
28562889
}
28572890

2891+
/*
2892+
* To be called after resetting updating_screen: handle any terminal where the
2893+
* channel was closed.
2894+
*/
2895+
void
2896+
term_check_channel_closed_recently()
2897+
{
2898+
term_T *term;
2899+
term_T *next_term;
2900+
2901+
for (term = first_term; term != NULL; term = next_term)
2902+
{
2903+
next_term = term->tl_next;
2904+
if (term->tl_channel_recently_closed)
2905+
{
2906+
term->tl_channel_recently_closed = FALSE;
2907+
if (term_after_channel_closed(term))
2908+
// start over, the list may have changed
2909+
next_term = first_term;
2910+
}
2911+
}
2912+
}
2913+
28582914
/*
28592915
* Fill one screen line from a line of the terminal.
28602916
* Advances "pos" to past the last column.

src/ui.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,10 @@ ui_breakcheck_force(int force)
431431
#endif
432432
mch_breakcheck(force);
433433

434-
updating_screen = save_us;
434+
if (save_us)
435+
updating_screen = save_us;
436+
else
437+
reset_updating_screen(FALSE);
435438
}
436439

437440
/*****************************************************************************

src/version.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,10 @@ static char *(features[]) =
776776

777777
static int included_patches[] =
778778
{ /* Add new patch number below this line */
779+
/**/
780+
1815,
781+
/**/
782+
1814,
779783
/**/
780784
1813,
781785
/**/

0 commit comments

Comments
 (0)