Prompt not redisplayed after displaying completion possibilities
I have a simple application that uses editline v1.17.1, and returns 4 possible completions on the empty string.
The 4 completions are displayed correctly, however the prompt is not re-displayed, ending up with this:
Run cli:
(device) [email protected] />
Press tab once, you get 4 completions as expected, but no redisplay of the prompt:
(device) [email protected] />
services system exit quit
Type 's' followed by tab, and you get 2 completions as expected, but no redisplay of prompt, and the 's' character appears twice:
(device) [email protected] />
services system exit quit
s
services system
ss
Type 'e' followed by tab, giving you the unique option 'services'. This is displayed, but the prompt is still missing, and we still have a stray s:
(device) [email protected] />
services system exit quit
s
services system
sservices
Press 'enter' despite the corrupt prompt, and the line is returned correctly and the prompt redisplayed:
(device) [email protected] />
services system exit quit
s
services system
sservices
(device) [email protected] /services>
The prompt is "(device) %s@%s /%s> " and contains no special characters.
Is this a known issue?
Apple Terminal on Big Sur, cli running on CentOS8.
Hmmm...
What made the problem go away was to set the prompt to a single unchanging string, and pass the string:
result = readline(prompt);
It seems that references to prompt are kept around internally after readline() returns. If an attempt is made to clean up the prompt or regenerate the prompt, chaos follows. I suspect somewhere inside the prompt needs to be strdup'ed.
In the original code there's no way to free stuff, so it's made to use a static string, or only change the contents of prompt between calls to readline().
Note: this is a very small an limited library. If you need anything more advanced I suggest looking at libedit (or readline) instead).
Alas in this case I'm only making changes to the contents of prompt in between calls to readline(), but it's not working in this case.
If I hack the code to not free prompt (ie leak), the problem disappears.
Ideally if editline needs to keep prompt past the readline() call, it should strdup it (and then free). Alternatively, store the prompt length only if that is all that's needed.
At this stage we support libedit, but this is not available where we want to run. Readline is not an option because of GPL.