kkawakam / rustyline

Readline Implementation in Rust
https://crates.io/crates/rustyline/
MIT License
1.5k stars 173 forks source link

CompletionType::List does not support completion candidates that are shorter than the input #748

Closed sharkdp closed 7 months ago

sharkdp commented 7 months ago

Thank you for maintaining this crate — we use it in Numbat and it works great.

We want to implement a feature where a user could type something like \hbar in the REPL, press Tab and it would be replaced by . This seems to work fine when using CompletionType::Circular, but it does not work for CompletionType::List. Words will only be replaced if they are longer than the input. This is probably due to this check:

https://github.com/kkawakam/rustyline/blob/fafa0b9ba7cc6fbd21c055ea06ed42be6504ae62/src/lib.rs#L154

Would it be possible to support this use case?

Remark: that check above should probably use lcp.unicode_width() instead of lcp.len() (?).

gwenn commented 7 months ago

Not strictly related to the issue but to your remark:

that check above should probably use lcp.unicode_width() instead of lcp.len() (?).

s.line.pos() and start are byte offsets so the difference between them is a number of bytes. So lcp.len() seems right. But maybe we should compare s.line[start..s.line.pos()].width() and lcp.width() instead. I will try to do some tests...

gwenn commented 7 months ago

Ok, If I remember correctly, I used replxx (or linenoise-ng) as a reference implementation. But then I didn't backported this change:

if ( ( longestCommonPrefix > itemLength ) || ( completionsCount == 1 ) ) {

And the associated comment perfectly matches your issue:

Support replacement completions, e.g. substitute symbolic names (\alpha) with proper symbols (α).

gwenn commented 7 months ago

Could you please give #750 a try ?

gwenn commented 7 months ago

Version 13.0.0 released.

sharkdp commented 7 months ago

Thank you!