Skip to content

Commit 12dfc9e

Browse files
committed
patch 8.1.0840: getchar(0) never returns a character in the terminal
Problem: getchar(0) never returns a character in the terminal. Solution: Call wait_func() at least once.
1 parent f58d81a commit 12dfc9e

7 files changed

Lines changed: 36 additions & 13 deletions

File tree

src/gui_gtk_x11.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6317,10 +6317,11 @@ gui_mch_wait_for_chars(long wtime)
63176317

63186318
timed_out = FALSE;
63196319

6320-
/* this timeout makes sure that we will return if no characters arrived in
6321-
* time */
6322-
if (wtime > 0)
6323-
timer = timeout_add(wtime, input_timer_cb, &timed_out);
6320+
// This timeout makes sure that we will return if no characters arrived in
6321+
// time. If "wtime" is zero just use one.
6322+
if (wtime >= 0)
6323+
timer = timeout_add(wtime <= 0 ? 1L : wtime,
6324+
input_timer_cb, &timed_out);
63246325
else
63256326
timer = 0;
63266327

src/gui_photon.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,8 +1344,9 @@ gui_mch_wait_for_chars(int wtime)
13441344
{
13451345
is_timeout = FALSE;
13461346

1347-
if (wtime > 0)
1348-
PtSetResource(gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL, wtime, 0);
1347+
if (wtime >= 0)
1348+
PtSetResource(gui_ph_timer_timeout, Pt_ARG_TIMER_INITIAL,
1349+
wtime == 0 ? 1 : wtime, 0);
13491350

13501351
while (1)
13511352
{

src/gui_w32.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2097,12 +2097,14 @@ gui_mch_wait_for_chars(int wtime)
20972097

20982098
s_timed_out = FALSE;
20992099

2100-
if (wtime > 0)
2100+
if (wtime >= 0)
21012101
{
2102-
/* Don't do anything while processing a (scroll) message. */
2102+
// Don't do anything while processing a (scroll) message.
21032103
if (s_busy_processing)
21042104
return FAIL;
2105-
s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)wtime,
2105+
2106+
// When called with "wtime" zero, just want one msec.
2107+
s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)(wtime == 0 ? 1 : wtime),
21062108
(TIMERPROC)_OnTimer);
21072109
}
21082110

src/gui_x11.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2683,9 +2683,10 @@ gui_mch_wait_for_chars(long wtime)
26832683

26842684
timed_out = FALSE;
26852685

2686-
if (wtime > 0)
2687-
timer = XtAppAddTimeOut(app_context, (long_u)wtime, gui_x11_timer_cb,
2688-
&timed_out);
2686+
if (wtime >= 0)
2687+
timer = XtAppAddTimeOut(app_context,
2688+
(long_u)(wtime == 0 ? 1L : wtime),
2689+
gui_x11_timer_cb, &timed_out);
26892690
#ifdef FEAT_JOB_CHANNEL
26902691
/* If there is a channel with the keep_open flag we need to poll for input
26912692
* on them. */

src/testdir/test_timers.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,16 @@ func Test_peek_and_get_char()
250250
call timer_stop(intr)
251251
endfunc
252252

253+
func Test_getchar_zero()
254+
call timer_start(20, {id -> feedkeys('x', 'L')})
255+
let c = 0
256+
while c == 0
257+
let c = getchar(0)
258+
sleep 10m
259+
endwhile
260+
call assert_equal('x', nr2char(c))
261+
endfunc
262+
253263
func Test_ex_mode()
254264
" Function with an empty line.
255265
func Foo(...)

src/ui.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ inchar_loop(
272272
{
273273
int len;
274274
int interrupted = FALSE;
275+
int did_call_wait_func = FALSE;
275276
int did_start_blocking = FALSE;
276277
long wait_time;
277278
long elapsed_time = 0;
@@ -313,7 +314,11 @@ inchar_loop(
313314
elapsed_time = ELAPSED_FUNC(start_tv);
314315
#endif
315316
wait_time -= elapsed_time;
316-
if (wait_time <= 0)
317+
318+
// If the waiting time is now zero or less, we timed out. However,
319+
// loop at least once to check for characters and events. Matters
320+
// when "wtime" is zero.
321+
if (wait_time <= 0 && did_call_wait_func)
317322
{
318323
if (wtime >= 0)
319324
// no character available within "wtime"
@@ -374,6 +379,7 @@ inchar_loop(
374379

375380
// Wait for a character to be typed or another event, such as the winch
376381
// signal or an event on the monitored file descriptors.
382+
did_call_wait_func = TRUE;
377383
if (wait_func(wait_time, &interrupted, FALSE))
378384
{
379385
// If input was put directly in typeahead buffer bail out here.

src/version.c

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

784784
static int included_patches[] =
785785
{ /* Add new patch number below this line */
786+
/**/
787+
840,
786788
/**/
787789
839,
788790
/**/

0 commit comments

Comments
 (0)