editline icon indicating copy to clipboard operation
editline copied to clipboard

Prompt not redisplayed after displaying completion possibilities

Open minfrin opened this issue 4 years ago • 3 comments

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.

minfrin avatar Apr 20 '21 12:04 minfrin

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.

minfrin avatar Apr 20 '21 12:04 minfrin

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).

troglobit avatar Apr 20 '21 13:04 troglobit

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.

minfrin avatar Apr 20 '21 13:04 minfrin