-
Notifications
You must be signed in to change notification settings - Fork 5
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
Add auto-completion #7
Conversation
So we can have a first-class CompletionHandler
Few things to note after spending some time on this:
Let me know if you have any thoughts. I'll make a commit for feedback once I have a bare minimum prototype that I'm happy with. |
Nope, I'm game to provide the tools for people to craft their own command, but then we should put a complete example in the README.
It's been a while since I was looking at this, but I came to the conclusion that it's better to disable the path completion and do it all within Go since that's pretty easy to implement and then users can easily add filters like "only accept accept directory".
I struggled with this too. I think doing middle-line completion correctly will involve a larger refactor to argument parsing. I think it makes sense, for MVP, to just prune args to cursor.
Yeah, we don't need to optimize for composition in the MVP. Bear in mind that |
@ammario |
command.go
Outdated
// When invoked `WithOS`, this includes argv[0], otherwise it is the same as Args. | ||
AllArgs []string | ||
// CurWord is the word the terminal cursor is currently in | ||
CurWord string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can CurWord
be an index into AllArgs
? This provides future compatibility with mid-line completions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To get auto-complete for equals flags (--flag=
) I'm currently just setting this to empty string before we call any handlers. If we don't do this then anyone writing a flag completion handler would sometimes see --flag=<arg>
as the current word, and other times just <arg>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, what use-case for mid-line completions isn't handled by just truncating the line at the cursor? Everything I tried just works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, ok. If we're truncating the line at the cursor then CurWord's only purpose is to distinguish the true flag value? That makes sense, I think it warrants a comment.
completion/handlers.go
Outdated
} | ||
|
||
func ListFiles(word string, filter func(info os.FileInfo) bool) []string { | ||
out := make([]string, 0, 32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
32 initial cap seems arbitrary?
if there's a good reason it should become a comment, otherwise make this var out []string
to reduce cognitive overhead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's arbitrary, I just wanted to avoid allocing the array 5 times for 16 files. Assuming var out []string
gives us a zero capacity: 0->1->2->4->8->16.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too minor to hold up the PR, but what leads you to optimize around that number of files?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just naively based off the fact that a 0 capacity slice grows 'slowly' for the first 32 elements. Though I also could have just set the capacity to the length of the slice returned by Readdir
. I'll go with just a var out []string
since it's not hugely important.
unfortunately GitHub doesn't let me be a "reviewer" on my own PR. On future hand-offs we should probably recreate the PR. In this one, just tag me via comment when ready for additional review. |
Yeah I'm happy with these changes, pls review 🙏 @ammario |
command.go
Outdated
// When invoked `WithOS`, this includes argv[0], otherwise it is the same as Args. | ||
AllArgs []string | ||
// CurWord is the word the terminal cursor is currently in | ||
CurWord string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, ok. If we're truncating the line at the cursor then CurWord's only purpose is to distinguish the true flag value? That makes sense, I think it warrants a comment.
completion/handlers.go
Outdated
} | ||
|
||
func ListFiles(word string, filter func(info os.FileInfo) bool) []string { | ||
out := make([]string, 0, 32) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is too minor to hold up the PR, but what leads you to optimize around that number of files?
Hey Ethan, sorry for the late review. I just skimmed the changes so we can get this in. I assume you're going to be integrating this into coder/coder next? |
Yep, when my backlog clears up that'll be next, serpent version bump + interactive install. |
TODO:
completion
command should have an interactive install by defaultCloses #3