-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Request: a way to show tab completions #3
Comments
When I wrote xterm-readline I based it off rustyline (a readline library for rust), and rustyline does have completion support implemented here: https://github.com/kkawakam/rustyline/blob/master/src/completion.rs I can't remember why I never implemented it. I think there's probably different ways to implement completion and I'm not sure which way is best for xterm-readline. I think what you've proposed seems sane. I wonder if the handler should choose which completion choose be the best candidate instead of returning the array? |
I like the behavior of the Python REPL, which appears to be the same as bash on my computer. (Maybe because both use readline?) Suppose I start
Then if I press tab one time, it prints out the possible completions and completes as many characters as possible, resulting in
So maybe the handler should return the current completion (like |
One more comment: now that I think of it, providing the current best completion and array of possible completions isn't a great option. It pushes complexity down to the user of xterm-readline, but it doesn't provide any benefit -- if the user types |
Yeah, I like showing the possible completion candidates to the user too but it's a bit trickier to implement because it requires rendering the list and then re-rendering the prompt on new lines and setting up the new cursor position. I've noticed the python one will both auto complete and show the list depending on how much ambiguity there is. For example, if you type "ha" and press tab python will auto complete automatically to "has" without showing candidates because the only two candidates are ["hasattr(", "hash("]. But then a second tab press (actually third? oddly the second one just sent a bell) shows the completion candidates. |
Interesting: that's not how it works for me. Pressing tab a single time both completes to It looks like the behavior is controlled by an option, I personally don't have strong feelings either way, but I'd slightly prefer showing the candidates on the first tab press. |
Interesting! Thanks for the investigation on show-all-if-ambiguous :) I also prefer showing candidates on first tab press. It's intuitively what I expect to happen. |
I was playing around with implementing this and it brought a lot of questions up. I think the primary question I have is what input the readline library provides the callback function. Does it provide the entire buffer? GNU Readline seems to actually separate the "last word" of the buffer given separator characters, and then provides only the last word to the callback. I'm not sure I like this, partly because my use case for xterm-readline can tokenize and parse out the string to "complete" by itself. Does it make sense that the callback should return both the parsed partial prefix being completed, and then list of candidates? For example, in the 'ha' example above the response from the callback would be: {
"prefix": "ha"
"completions": ["hasattr(", "hash("]
} This gives the readline l library enough information to actually auto-complete given any arbitrary grammar. |
I agree, I played around a little with this myself the other day and encountered the same issue. I am glad that you are looking at it, though! From the perspective of the typical user of this code, it would be nice if xterm-readline did the following:
For most use cases, requiring the user to tokenize the entire current string would be a bit inconvenient, and would require extra thought about tokenizing, just to produce code that's essentially the same for most languages. All that said, I get where you're coming from, and can imagine cases where it's useful to provide the entire string. In that case, the returned object you suggested makes sense to me. So maybe: last token vs. whole string could be an option, and the callback would be expected to return the data structure with Or maybe, instead of last token vs. whole string, the user could provide a tokenizer function. What does rustyline do? One other thing I ran into: In my use case, I'm connecting this to Pyodide (Python in wasm) running in a web worker, so all of the communication is asynchronous. In my local copy, the case InputType.Tab:
this.completionHandler(text).then((completions: string[]) => {
this.term?.write("\r\n" + completions.join(" ") + "\r\n");
this.state.refresh();
});
break; But I'm not sure that it's safe to do this async stuff this way. At any rate, I hope that what you come up with works safely with an async completion callback. BTW, if you're curious, this is what I'm using xterm-readline for: https://shinylive.io/py/examples/ |
Hello, it's some time since this Request, but I want to add my Question ;) I solved this by attachCustomKeyEventHandler which detects “tab” key up. Now my question, is there any interest in a PR to have this simple tabCompletionHandler in this lib ? If there is any chance to get this in Lib, I would try to create a PR for this ? Update: |
Hey guys, I'm trying to implement this in the forked repo: 6d99d86. Everything seems to be working fine (possibly), Update: It has now been better printed (following the example of mongosh): However, I have not done a comprehensive code testing yet, and the code implementation may not be optimal. Any suggestions are welcome! |
First off, thanks for creating this package.
I'm using it create a REPL using Pyodide (Python compiled to wasm), and I would like to add support for tab completions. The idea is that when you press tab, it does one of the following (which is similar to the normal
python
REPL):I don't see a good way to do this with the existing API. One way to go would be to provide a way register a completion handler; this handler would be a function which takes a string (the text typed on the command line so far) and returns an array of strings (the list of possible completions).
So the usage would be something like this:
The text was updated successfully, but these errors were encountered: