-
Notifications
You must be signed in to change notification settings - Fork 124
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
RFC for an argument completer base class #269
base: master
Are you sure you want to change the base?
Conversation
/// </summary> | ||
/// <param name="text">The text to complete</param> | ||
/// <returns></returns> | ||
protected virtual string QuoteCompletionText(string text) => text.Contains(" ") ? $@"""{text}""" : text; |
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.
What if the user is using a single quote?
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.
Oh gosh, had some flashbacks of working on argument completion for PSWordCloud. There's a bit more you need to handle for this kind of thing as well, depending on the colorful variety of things you may be expecting to handle as the completion results themselves. Let me find some code I wrote a while back... here:
This one covers escaping things that need escaping, spaces, #
characters in the completion results (I happened to end up having fonts with that character on my computer and it breaks completions terribly 😀) and probably a few other things. I haven't managed to break it yet.
The only thing I don't think it bothers to handle is whether the user used single quotes, it currently replaces them with double quotes instead I think. So it could be expanded on to detect that and act accordingly (less things need escaping there, etc).
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.
I expect we have to turn this into a much more complete implementation. Maybe we can make use of the parser to determine what needs to be escaped?
I like the idea of a base class to remove the need to have common code for every completer as I've had to write it for my own completers. One consideration is whether it makes sense to have this as an independent nuget assembly so it can be used for different versions of PS rather than the one it gets checked into. |
@SteveL-MSFT I like the idea of that, but I think it would open up too many possible dependency conflicts. If you have two modules that each depend on a different version of that completion assembly, you can easily end up only being able to load one of them into a session at a time. Until there's a way to isolate dependencies like that properly I think it's best left in the core pwsh toolkit, and folks can simply declare a dependency on a minimum PS version as usual without much hassle. |
I see a point to put an end solution in separate nuget but it looks weird for base class. |
Co-authored-by: Steve Lee <slee@microsoft.com>
There already is an function in CompletionCompeters private static bool CompletionRequiresQuotes(string completion, bool escape)
{
// If the tokenizer sees the completion as more than two tokens, or if there is some error, then
// some form of quoting is necessary (if it's a variable, we'd need ${}, filenames would need [], etc.)
Language.Token[] tokens;
ParseError[] errors;
Language.Parser.ParseInput(completion, out tokens, out errors);
char[] charToCheck = escape ? new[] { '$', '[', ']', '`' } : new[] { '$', '`' };
// Expect no errors and 2 tokens (1 is for our completion, the other is eof)
// Or if the completion is a keyword, we ignore the errors
bool requireQuote = !(errors.Length == 0 && tokens.Length == 2);
if ((!requireQuote && tokens[0] is StringToken) ||
(tokens.Length == 2 && (tokens[0].TokenFlags & TokenFlags.Keyword) != 0))
{
requireQuote = false;
var value = tokens[0].Text;
if (value.IndexOfAny(charToCheck) != -1)
requireQuote = true;
}
return requireQuote;
} This could be reused. The second parameter is named somewhat unfortunate: |
I have updated the RFC with more robust quoting |
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.
I think making a base class available to deduplicate functionality is a good idea.
I suspect us trying to perfect the implementation in an RFC is going to miss the forest for the trees.
I wouldn't have necessarily said an RFC was needed for this, but given that we are discussing this in an RFC the parts I'd want us to agree on here are:
- The name
- The API and exposed members and what their contracts are
- Possible future needs or directions for the class and how it might fit into the greater completion framework
The DevEX working group briefly discussed this and we think that the implementation doesn't necessarily have to be a base class, which could lead to other problems like this: https://en.wikipedia.org/wiki/Fragile_base_class |
I'll tinker a bit with it and will get back with an update. |
No description provided.