Skip to content

Commit e9c21ae

Browse files
committed
patch 8.0.0854: no redraw after terminal was closed
Problem: No redraw after terminal was closed. Solution: Set typebuf_was_filled. (Yasuhiro Matsumoto, closes #1925, closes #1924) Add function to check for messages even when input is available.
1 parent b4a6721 commit e9c21ae

7 files changed

Lines changed: 76 additions & 28 deletions

File tree

src/os_mswin.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,18 @@ mch_char_avail(void)
809809
/* never used */
810810
return TRUE;
811811
}
812+
813+
# if defined(FEAT_TERMINAL) || defined(PROTO)
814+
/*
815+
* Check for any pending input or messages.
816+
*/
817+
int
818+
mch_check_messages(void)
819+
{
820+
/* TODO: check for messages */
821+
return TRUE;
822+
}
823+
# endif
812824
#endif
813825

814826

src/os_unix.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,8 @@ typedef int waitstatus;
175175
#endif
176176
static pid_t wait4pid(pid_t, waitstatus *);
177177

178-
static int WaitForChar(long msec, int *interrupted);
179-
static int WaitForCharOrMouse(long msec, int *interrupted);
178+
static int WaitForChar(long msec, int *interrupted, int ignore_input);
179+
static int WaitForCharOrMouse(long msec, int *interrupted, int ignore_input);
180180
#if defined(__BEOS__) || defined(VMS)
181181
int RealWaitForChar(int, long, int *, int *interrupted);
182182
#else
@@ -481,7 +481,7 @@ mch_inchar(
481481
* We want to be interrupted by the winch signal
482482
* or by an event on the monitored file descriptors.
483483
*/
484-
if (WaitForChar(wait_time, &interrupted))
484+
if (WaitForChar(wait_time, &interrupted, FALSE))
485485
{
486486
/* If input was put directly in typeahead buffer bail out here. */
487487
if (typebuf_changed(tb_change_cnt))
@@ -536,9 +536,20 @@ handle_resize(void)
536536
int
537537
mch_char_avail(void)
538538
{
539-
return WaitForChar(0L, NULL);
539+
return WaitForChar(0L, NULL, FALSE);
540540
}
541541

542+
#if defined(FEAT_TERMINAL) || defined(PROTO)
543+
/*
544+
* Check for any pending input or messages.
545+
*/
546+
int
547+
mch_check_messages(void)
548+
{
549+
return WaitForChar(0L, NULL, TRUE);
550+
}
551+
#endif
552+
542553
#if defined(HAVE_TOTAL_MEM) || defined(PROTO)
543554
# ifdef HAVE_SYS_RESOURCE_H
544555
# include <sys/resource.h>
@@ -718,7 +729,7 @@ mch_delay(long msec, int ignoreinput)
718729
in_mch_delay = FALSE;
719730
}
720731
else
721-
WaitForChar(msec, NULL);
732+
WaitForChar(msec, NULL, FALSE);
722733
}
723734

724735
#if defined(HAVE_STACK_LIMIT) \
@@ -5616,13 +5627,15 @@ mch_breakcheck(int force)
56165627
* from inbuf[].
56175628
* "msec" == -1 will block forever.
56185629
* Invokes timer callbacks when needed.
5630+
* When "ignore_input" is TRUE even check for pending input when input is
5631+
* already available.
56195632
* "interrupted" (if not NULL) is set to TRUE when no character is available
56205633
* but something else needs to be done.
56215634
* Returns TRUE when a character is available.
56225635
* When a GUI is being used, this will never get called -- webb
56235636
*/
56245637
static int
5625-
WaitForChar(long msec, int *interrupted)
5638+
WaitForChar(long msec, int *interrupted, int ignore_input)
56265639
{
56275640
#ifdef FEAT_TIMERS
56285641
long due_time;
@@ -5631,7 +5644,7 @@ WaitForChar(long msec, int *interrupted)
56315644

56325645
/* When waiting very briefly don't trigger timers. */
56335646
if (msec >= 0 && msec < 10L)
5634-
return WaitForCharOrMouse(msec, NULL);
5647+
return WaitForCharOrMouse(msec, NULL, ignore_input);
56355648

56365649
while (msec < 0 || remaining > 0)
56375650
{
@@ -5645,7 +5658,7 @@ WaitForChar(long msec, int *interrupted)
56455658
}
56465659
if (due_time <= 0 || (msec > 0 && due_time > remaining))
56475660
due_time = remaining;
5648-
if (WaitForCharOrMouse(due_time, interrupted))
5661+
if (WaitForCharOrMouse(due_time, interrupted, ignore_input))
56495662
return TRUE;
56505663
if (interrupted != NULL && *interrupted)
56515664
/* Nothing available, but need to return so that side effects get
@@ -5656,20 +5669,21 @@ WaitForChar(long msec, int *interrupted)
56565669
}
56575670
return FALSE;
56585671
#else
5659-
return WaitForCharOrMouse(msec, interrupted);
5672+
return WaitForCharOrMouse(msec, interrupted, ignore_input);
56605673
#endif
56615674
}
56625675

56635676
/*
56645677
* Wait "msec" msec until a character is available from the mouse or keyboard
56655678
* or from inbuf[].
56665679
* "msec" == -1 will block forever.
5680+
* for "ignore_input" see WaitForCharOr().
56675681
* "interrupted" (if not NULL) is set to TRUE when no character is available
56685682
* but something else needs to be done.
56695683
* When a GUI is being used, this will never get called -- webb
56705684
*/
56715685
static int
5672-
WaitForCharOrMouse(long msec, int *interrupted)
5686+
WaitForCharOrMouse(long msec, int *interrupted, int ignore_input)
56735687
{
56745688
#ifdef FEAT_MOUSE_GPM
56755689
int gpm_process_wanted;
@@ -5679,7 +5693,7 @@ WaitForCharOrMouse(long msec, int *interrupted)
56795693
#endif
56805694
int avail;
56815695

5682-
if (input_available()) /* something in inbuf[] */
5696+
if (!ignore_input && input_available()) /* something in inbuf[] */
56835697
return 1;
56845698

56855699
#if defined(FEAT_MOUSE_DEC)
@@ -5722,7 +5736,7 @@ WaitForCharOrMouse(long msec, int *interrupted)
57225736
# endif
57235737
if (!avail)
57245738
{
5725-
if (input_available())
5739+
if (!ignore_input && input_available())
57265740
return 1;
57275741
# ifdef FEAT_XCLIPBOARD
57285742
if (rest == 0 || !do_xterm_trace())

src/os_win32.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,10 +1400,11 @@ handle_focus_event(INPUT_RECORD ir)
14001400
/*
14011401
* Wait until console input from keyboard or mouse is available,
14021402
* or the time is up.
1403+
* When "ignore_input" is TRUE even wait when input is available.
14031404
* Return TRUE if something is available FALSE if not.
14041405
*/
14051406
static int
1406-
WaitForChar(long msec)
1407+
WaitForChar(long msec, int ignore_input)
14071408
{
14081409
DWORD dwNow = 0, dwEndTime = 0;
14091410
INPUT_RECORD ir;
@@ -1440,7 +1441,7 @@ WaitForChar(long msec)
14401441
|| g_nMouseClick != -1
14411442
#endif
14421443
#ifdef FEAT_CLIENTSERVER
1443-
|| input_available()
1444+
|| (!ignore_input && input_available())
14441445
#endif
14451446
)
14461447
return TRUE;
@@ -1583,8 +1584,19 @@ WaitForChar(long msec)
15831584
int
15841585
mch_char_avail(void)
15851586
{
1586-
return WaitForChar(0L);
1587+
return WaitForChar(0L, FALSE);
15871588
}
1589+
1590+
# if defined(FEAT_TERMINAL) || defined(PROTO)
1591+
/*
1592+
* Check for any pending input or messages.
1593+
*/
1594+
int
1595+
mch_check_messages(void)
1596+
{
1597+
return WaitForChar(0L, TRUE);
1598+
}
1599+
# endif
15881600
#endif
15891601

15901602
/*
@@ -1614,7 +1626,7 @@ tgetch(int *pmodifiers, WCHAR *pch2)
16141626
DWORD cRecords = 0;
16151627

16161628
#ifdef FEAT_CLIENTSERVER
1617-
(void)WaitForChar(-1L);
1629+
(void)WaitForChar(-1L, FALSE);
16181630
if (input_available())
16191631
return 0;
16201632
# ifdef FEAT_MOUSE
@@ -1681,7 +1693,7 @@ mch_inchar(
16811693

16821694
if (time >= 0)
16831695
{
1684-
if (!WaitForChar(time)) /* no character available */
1696+
if (!WaitForChar(time, FALSE)) /* no character available */
16851697
return 0;
16861698
}
16871699
else /* time == -1, wait forever */
@@ -1693,7 +1705,7 @@ mch_inchar(
16931705
* write the autoscript file to disk. Or cause the CursorHold event
16941706
* to be triggered.
16951707
*/
1696-
if (!WaitForChar(p_ut))
1708+
if (!WaitForChar(p_ut, FALSE))
16971709
{
16981710
#ifdef FEAT_AUTOCMD
16991711
if (trigger_cursorhold() && maxlen >= 3)
@@ -1723,7 +1735,7 @@ mch_inchar(
17231735
/* Keep looping until there is something in the typeahead buffer and more
17241736
* to get and still room in the buffer (up to two bytes for a char and
17251737
* three bytes for a modifier). */
1726-
while ((typeaheadlen == 0 || WaitForChar(0L))
1738+
while ((typeaheadlen == 0 || WaitForChar(0L, FALSE))
17271739
&& typeaheadlen + 5 <= TYPEAHEADLEN)
17281740
{
17291741
if (typebuf_changed(tb_change_cnt))
@@ -5721,7 +5733,7 @@ cursor_visible(BOOL fVisible)
57215733

57225734

57235735
/*
5724-
* write `cbToWrite' bytes in `pchBuf' to the screen
5736+
* Write "cbToWrite" bytes in `pchBuf' to the screen.
57255737
* Returns the number of bytes actually written (at least one).
57265738
*/
57275739
static DWORD
@@ -5828,7 +5840,7 @@ mch_write(
58285840

58295841
if (p_wd)
58305842
{
5831-
WaitForChar(p_wd);
5843+
WaitForChar(p_wd, FALSE);
58325844
if (prefix != 0)
58335845
prefix = 1;
58345846
}
@@ -6120,7 +6132,7 @@ mch_delay(
61206132
# endif
61216133
Sleep((int)msec);
61226134
else
6123-
WaitForChar(msec);
6135+
WaitForChar(msec, FALSE);
61246136
#endif
61256137
}
61266138

src/proto/os_unix.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ int mch_chdir(char *path);
33
void mch_write(char_u *s, int len);
44
int mch_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
55
int mch_char_avail(void);
6+
int mch_check_messages(void);
67
long_u mch_total_mem(int special);
78
void mch_delay(long msec, int ignoreinput);
89
int mch_stackcheck(char *p);

src/proto/os_win32.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ void PlatformId(void);
88
void mch_setmouse(int on);
99
void mch_update_cursor(void);
1010
int mch_char_avail(void);
11+
int mch_check_messages(void);
1112
int mch_inchar(char_u *buf, int maxlen, long time, int tb_change_cnt);
1213
void mch_init(void);
1314
void mch_exit(int r);

src/terminal.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,7 @@ term_channel_closed(channel_T *ch)
13051305

13061306
/* Need to break out of vgetc(). */
13071307
ins_char_typebuf(K_IGNORE);
1308+
typebuf_was_filled = TRUE;
13081309

13091310
term = curbuf->b_term;
13101311
if (term != NULL)
@@ -2140,31 +2141,36 @@ f_term_wait(typval_T *argvars, typval_T *rettv UNUSED)
21402141
ch_log(NULL, "term_wait(): invalid argument");
21412142
return;
21422143
}
2144+
if (buf->b_term->tl_job == NULL)
2145+
{
2146+
ch_log(NULL, "term_wait(): no job to wait for");
2147+
return;
2148+
}
21432149

21442150
/* Get the job status, this will detect a job that finished. */
2145-
if (buf->b_term->tl_job == NULL
2146-
|| STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
2151+
if (STRCMP(job_status(buf->b_term->tl_job), "dead") == 0)
21472152
{
21482153
/* The job is dead, keep reading channel I/O until the channel is
21492154
* closed. */
2155+
ch_log(NULL, "term_wait(): waiting for channel to close");
21502156
while (buf->b_term != NULL && !buf->b_term->tl_channel_closed)
21512157
{
2152-
mch_char_avail();
2158+
mch_check_messages();
21532159
parse_queued_messages();
21542160
ui_delay(10L, FALSE);
21552161
}
2156-
mch_char_avail();
2162+
mch_check_messages();
21572163
parse_queued_messages();
21582164
}
21592165
else
21602166
{
2161-
mch_char_avail();
2167+
mch_check_messages();
21622168
parse_queued_messages();
21632169

21642170
/* Wait for 10 msec for any channel I/O. */
21652171
/* TODO: use delay from optional argument */
21662172
ui_delay(10L, TRUE);
2167-
mch_char_avail();
2173+
mch_check_messages();
21682174

21692175
/* Flushing messages on channels is hopefully sufficient.
21702176
* TODO: is there a better way? */

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ static char *(features[]) =
769769

770770
static int included_patches[] =
771771
{ /* Add new patch number below this line */
772+
/**/
773+
854,
772774
/**/
773775
853,
774776
/**/

0 commit comments

Comments
 (0)