@@ -355,57 +355,57 @@ static void freeCompletions(linenoiseCompletions *lc) {
355
355
* the input was consumed by the completeLine() function to navigate the
356
356
* possible completions, and the caller should read for the next characters
357
357
* from stdin. */
358
- static int completeLine (struct linenoiseState * ls ) {
358
+ static int completeLine (struct linenoiseState * ls , int keypressed ) {
359
359
linenoiseCompletions lc = { 0 , NULL };
360
- int nread , nwritten ;
361
- char c = 0 ;
360
+ int nwritten ;
361
+ char c = keypressed ;
362
362
363
363
completionCallback (ls -> buf ,& lc );
364
364
if (lc .len == 0 ) {
365
365
linenoiseBeep ();
366
+ ls -> in_completion = 0 ;
366
367
} else {
367
- size_t stop = 0 , i = 0 ;
368
-
369
- while (!stop ) {
370
- /* Show completion or original buffer */
371
- if (i < lc .len ) {
372
- struct linenoiseState saved = * ls ;
373
-
374
- ls -> len = ls -> pos = strlen (lc .cvec [i ]);
375
- ls -> buf = lc .cvec [i ];
376
- refreshLine (ls );
377
- ls -> len = saved .len ;
378
- ls -> pos = saved .pos ;
379
- ls -> buf = saved .buf ;
380
- } else {
381
- refreshLine (ls );
382
- }
368
+ switch (c ) {
369
+ case 9 : /* tab */
370
+ if (ls -> in_completion == 0 ) {
371
+ ls -> in_completion = 1 ;
372
+ ls -> completion_idx = 0 ;
373
+ } else {
374
+ ls -> completion_idx = (ls -> completion_idx + 1 ) % (lc .len + 1 );
375
+ if (ls -> completion_idx == lc .len ) linenoiseBeep ();
376
+ }
377
+ c = 0 ;
378
+ break ;
379
+ case 27 : /* escape */
380
+ /* Re-show original buffer */
381
+ if (ls -> completion_idx < lc .len ) refreshLine (ls );
382
+ ls -> in_completion = 0 ;
383
+ c = 0 ;
384
+ break ;
385
+ default :
386
+ /* Update buffer and return */
387
+ if (ls -> completion_idx < lc .len ) {
388
+ nwritten = snprintf (ls -> buf ,ls -> buflen ,"%s" ,
389
+ lc .cvec [ls -> completion_idx ]);
390
+ ls -> len = ls -> pos = nwritten ;
391
+ c = 0 ;
392
+ }
393
+ ls -> in_completion = 0 ;
394
+ break ;
395
+ }
383
396
384
- nread = read (ls -> ifd ,& c ,1 );
385
- if (nread <= 0 ) {
386
- freeCompletions (& lc );
387
- return -1 ;
388
- }
397
+ /* Show completion or original buffer */
398
+ if (ls -> in_completion && ls -> completion_idx < lc .len ) {
399
+ struct linenoiseState saved = * ls ;
389
400
390
- switch (c ) {
391
- case 9 : /* tab */
392
- i = (i + 1 ) % (lc .len + 1 );
393
- if (i == lc .len ) linenoiseBeep ();
394
- break ;
395
- case 27 : /* escape */
396
- /* Re-show original buffer */
397
- if (i < lc .len ) refreshLine (ls );
398
- stop = 1 ;
399
- break ;
400
- default :
401
- /* Update buffer and return */
402
- if (i < lc .len ) {
403
- nwritten = snprintf (ls -> buf ,ls -> buflen ,"%s" ,lc .cvec [i ]);
404
- ls -> len = ls -> pos = nwritten ;
405
- }
406
- stop = 1 ;
407
- break ;
408
- }
401
+ ls -> len = ls -> pos = strlen (lc .cvec [ls -> completion_idx ]);
402
+ ls -> buf = lc .cvec [ls -> completion_idx ];
403
+ refreshLine (ls );
404
+ ls -> len = saved .len ;
405
+ ls -> pos = saved .pos ;
406
+ ls -> buf = saved .buf ;
407
+ } else {
408
+ refreshLine (ls );
409
409
}
410
410
}
411
411
@@ -841,6 +841,7 @@ void linenoiseEditDeletePrevWord(struct linenoiseState *l) {
841
841
int linenoiseEditStart (struct linenoiseState * l , int stdin_fd , int stdout_fd , char * buf , size_t buflen , const char * prompt ) {
842
842
/* Populate the linenoise state that we pass to functions implementing
843
843
* specific editing functionalities. */
844
+ l -> in_completion = 0 ;
844
845
l -> ifd = stdin_fd != -1 ? stdin_fd : STDIN_FILENO ;
845
846
l -> ofd = stdout_fd != -1 ? stdout_fd : STDOUT_FILENO ;
846
847
l -> buf = buf ;
@@ -908,8 +909,8 @@ char *linenoiseEditFeed(struct linenoiseState *l) {
908
909
/* Only autocomplete when the callback is set. It returns < 0 when
909
910
* there was an error reading from fd. Otherwise it will return the
910
911
* character that should be handled next. */
911
- if (c == 9 && completionCallback != NULL ) {
912
- c = completeLine (l );
912
+ if (( l -> in_completion || c == 9 ) && completionCallback != NULL ) {
913
+ c = completeLine (l , c );
913
914
/* Return on errors */
914
915
if (c < 0 ) return NULL ;
915
916
/* Read next character when 0 */
0 commit comments