Description
When using tab completion, if you press an arrow key to navigate, the current completion candidate is discarded, and the raw escape sequence characters (like [D, [C) are appended to the input buffer as literal text.
Steps to reproduce
// set completion callback
void CompletionTest(const char *, linenoiseCompletions *lc) {
linenoiseAddCompletion(lc, "Text1");
}
int main() {
linenoiseSetCompletionCallback(CompletionTest);
/* ... loop ... */
}
- Pressing
Tab to trigger completion, the prompt shows the candidate Text1.
- Pressing the Left Arrow key, the prompt becomes
[D.
- Inspecting the input line reveals that the underlying buffer data has also been replaced by
[D.
> Text1 <- Shows candidate after pressing Tab
> [D <- Becomes [D after pressing Left Arrow
Expected behavior
Arrow keys should be handled correctly during completion:
- The cursor should move in the specified direction.
- It should accept the current completion candidate.
Cause analysis
In linenoise.c, the completeLine function handles case 27 (ESC) by immediately setting ls->in_completion = 0 and returning c = 0.
|
case 27: /* escape */ |
|
/* Re-show original buffer */ |
|
if (ls->completion_idx < lc.len) refreshLine(ls); |
|
ls->in_completion = 0; |
|
c = 0; |
|
break; |
It fails to check if the ESC character is the start of a multi-byte escape sequence. Consequently, the subsequent bytes (e.g., [D) are interpreted as user input in linenoiseEditFeed.
Proposed fix
Modify completeLine to check for escape sequences: When an ESC is received, attempt to read the next 2 bytes to determine if it is an arrow key sequence (similar to linenoiseEditFeed).
I think this modification wouldn't be too complicated. I'd be happy to submit a PR for this if the approach sounds good.
Description
When using tab completion, if you press an arrow key to navigate, the current completion candidate is discarded, and the raw escape sequence characters (like
[D,[C) are appended to the input buffer as literal text.Steps to reproduce
Tabto trigger completion, the prompt shows the candidateText1.[D.[D.Expected behavior
Arrow keys should be handled correctly during completion:
Cause analysis
In
linenoise.c, thecompleteLinefunction handlescase 27(ESC) by immediately settingls->in_completion = 0and returningc = 0.linenoise/linenoise.c
Lines 739 to 744 in 452e379
It fails to check if the ESC character is the start of a multi-byte escape sequence. Consequently, the subsequent bytes (e.g.,
[D) are interpreted as user input inlinenoiseEditFeed.Proposed fix
Modify
completeLineto check for escape sequences: When anESCis received, attempt to read the next 2 bytes to determine if it is an arrow key sequence (similar tolinenoiseEditFeed).I think this modification wouldn't be too complicated. I'd be happy to submit a PR for this if the approach sounds good.