Skip to content

Commit 714dbf5

Browse files
committed
Improve command-start detection
Now we know we're in command position after `blah <=` and `blah |[2] `.
1 parent 254046c commit 714dbf5

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

input.c

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -529,27 +529,70 @@ static char *list_completion_function(const char *text, int state) {
529529
return result;
530530
}
531531

532-
/* detect if we're currently at the start of a line. works ~80% well */
532+
enum st {
533+
NORMAL,
534+
START, /* start of a command */
535+
PIPESTART, /* just after a '|' */
536+
PIPESTARTBRACKET, /* the '|[' in 'a |[2] b' */
537+
LT /* the '<' in '<=word' */
538+
};
539+
540+
/* detect if we're currently at the start of a line. works ~90% well */
533541
static Boolean cmdstart(int point) {
534542
int i;
535-
Boolean quote = FALSE, start = TRUE;
543+
Boolean quote = FALSE;
544+
enum st state = START;
536545
for (i = 0; i < point; i++) {
537546
char c = rl_line_buffer[i];
538-
switch (c) {
539-
case '\'':
547+
if (c == '\'') {
540548
quote = !quote;
549+
continue;
550+
}
551+
if (quote) continue;
552+
553+
switch (state) {
554+
case PIPESTARTBRACKET:
555+
if (c == ']')
556+
state = START;
541557
break;
542-
case '&': case '|': case '{': case '`':
543-
if (!quote) start = TRUE;
558+
case LT:
559+
if (c == '=')
560+
state = START;
561+
else
562+
state = NORMAL;
544563
break;
545-
/* \n doesn't work right :( */
546-
case ' ': case '\t': case '\n': case '!':
564+
case PIPESTART:
565+
if (c == '[') {
566+
state = PIPESTARTBRACKET;
567+
break;
568+
}
569+
state = START; /* || correct? */
570+
/* fallthrough */
571+
case START:
572+
switch (c) {
573+
case ' ': case '\t': case '\n': case '!':
574+
break;
575+
default:
576+
state = NORMAL;
577+
}
547578
break;
548-
default:
549-
if (!quote) start = FALSE;
579+
case NORMAL:
580+
switch (c) {
581+
case '&': case '{': case '`':
582+
state = START;
583+
break;
584+
case '|':
585+
state = PIPESTART;
586+
break;
587+
case '<':
588+
state = LT;
589+
break;
590+
default:
591+
break; /* nothing to do */
592+
}
550593
}
551594
}
552-
return start;
595+
return state == START || state == PIPESTART;
553596
}
554597

555598
/* first-position completion. includes

0 commit comments

Comments
 (0)