bistromathic: properly compute the lcp, as expected by readline

Currently completion on "at" proposes only "atan", but does not
actually complete "at" into "atan".

* examples/c/bistromathic/parse.y (completion): Install the lcp in
matches[0].
* examples/c/bistromathic/bistromathic.test: Check that case.
This commit is contained in:
Akim Demaille
2020-03-02 05:29:31 +01:00
parent f334775dbf
commit 67793793e8
2 changed files with 23 additions and 2 deletions

View File

@@ -85,6 +85,7 @@ run 0 '> 1 / 0
## Completion. ##
## ------------ ##
# Check completion after an operator.
sed -e 's/\\t/ /g' >input <<EOF
(1+\t\t
EOF
@@ -94,3 +95,10 @@ run 0 '> (1+
atan exp sqrt
> (1+
> err: 1.4: syntax error: expected - or ( or double precision number or function or variable before end of file'
# Check the completion of a word.
sed -e 's/\\t/ /g' >input <<EOF
(at\t\t
EOF
run 0 '> (atan ( ''
> err: 1.9: syntax error: expected - or ( or double precision number or function or variable before end of file'

View File

@@ -384,8 +384,7 @@ completion (const char *text, int start, int end)
const int len = strlen (text);
// Need initial prefix and final NULL.
char **matches = calloc (ntokens + symbol_count () + 2, sizeof *matches);
int match = 0;
matches[match++] = strdup (text);
int match = 1;
for (int i = 0; i < ntokens; ++i)
if (tokens[i] == YYTRANSLATE (TOK_VAR))
{
@@ -406,6 +405,20 @@ completion (const char *text, int start, int end)
matches[match++] = strdup (token);
}
// Find the longest common prefix, and install it in matches[0], as
// required by readline.
if (match == 1)
matches[0] = strdup (text);
else
{
int lcplen = strlen (matches[1]);
for (int i = 2; i < match && lcplen; ++i)
for (int j = 0; j < lcplen; ++j)
if (matches[1][j] != matches[i][j])
lcplen = j;
matches[0] = strndup (matches[1], lcplen);
}
if (yydebug)
{
fprintf (stderr, "completion(\"%.*s[%.*s]%s\") = ",