[Mono-dev] csharp tab completion.
Miguel de Icaza
miguel at novell.com
Thu Mar 12 13:01:38 EDT 2009
Hello,
A follow up: this contains a cleaned up version of the patch, a few
old hacks have been removed, and the sample now actually builds.
> Hello,
>
> I cooked this patch on my last trip and just got it polished enough
> that it is worth posting to the mailing list.
>
> A feature frequently requested is for the `csharp' interactive shell
> is to provide bash-like tab completion so that you can quickly explore
> the API without having to look things up. The getline.cs library
> already provided a mechanism for doing tab completion, but the support
> was not implemented.
>
> The challenge was to reuse the current gmcs parser without having to
> dramatically modify it and still provide completions. The support
> works like this.
>
> The parser and tokenizer work together so that the tokenizer upon
> reaching the end of the input generates the following tokens:
> GENERATE_COMPLETION followed by as many COMPLETE_COMPLETION token and
> finally the EOF token.
>
> GENERATE_COMPLETION needs to be handled in every production where
> the user is likely to press the TAB key in the shell (or in the future
> the GUI, or an explicit request in an IDE). COMPLETE_COMPLETION must
> be handled throughout the grammar to provide a way of completing the
> parsed expression. See below for details.
>
> For the member access case, I have added productions that mirror the
> non-completing productions, for example:
>
> primary_expression DOT IDENTIFIER GENERATE_COMPLETION
> {
> LocatedToken lt = (LocatedToken) $3;
> $$ = new CompletionMemberAccess ((Expression) $1, lt.Value, lt.Location);
> }
>
> This mirrors:
>
> primary_expression DOT IDENTIFIER opt_type_argument_list
> {
> LocatedToken lt = (LocatedToken) $3;
> $$ = new MemberAccess ((Expression) $1, lt.Value, (TypeArguments) $4, lt.Location);
> }
>
> The CompletionMemberAccess is a new kind of Mono.CSharp.Expression
> that does the actual lookup. It internally mimics some of the
> MemberAccess code but has been tuned for this particular use.
>
> After this initial token is processed GENERATE_COMPLETION the
> tokenizer will emit COMPLETE_COMPLETION tokens. This is done to help
> the parser basically produce a valid result from the partial input it
> received. For example it is able to produce a valid AST from "(x"
> even if no parenthesis has been closed. This is achieved by sprinkling
> the grammar with productions that can cope with this "winding down"
> token, for example this is what parenthesized_expression looks like now:
>
> parenthesized_expression
> : OPEN_PARENS expression CLOSE_PARENS
> {
> $$ = new ParenthesizedExpression ((Expression) $2);
> }
> //
> // New production
> //
> | OPEN_PARENS expression COMPLETE_COMPLETION
> {
> $$ = new ParenthesizedExpression ((Expression) $2);
> }
> ;
>
> Once we have wrapped up everything we generate the last EOF token.
>
> When the AST is complete we actually trigger the regular semantic
> analysis process. The DoResolve method of each node in our abstract
> syntax tree will compute the result and communicate the possible
> completions by throwing an exception of type CompletionResult.
>
> This is the bit that I am not very comfortable with, I had to
> provide both the prefix string and the results to allow the completion
> engine to render things properly.
>
> So for example if the user type "T" and the completion is "ToString"
> we return "oString".
>
> Attached is the patch for review.
>
> Future Work:
>
> I have only implemented support for completion right now in two
> spots: declared variables and member access, so stuff like foo.<TAB>
> will produce the completions for foo properly and foo.T<TAB> will
> produce the completions for anything in foo that starts with a T.
>
> There are many other places missing (using declarations, type
> parameters for example, and I am sure there are many other opportunities
> missing), I might add those in the future if there is enough interest,
> or even better, you can get yourself started with compiler technology
> and email us patches ;-)
>
> GSharp:
>
> The GUI version perhaps needs to implement this in a GUI-ish way
> when the user presses a dot for example, or when the user presses a
> hotkey. The GUI version also has the benefit that it can distinguish
> the user pressing tab from the user pasting some text with a tab.
>
> Miguel
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: auto-complete-csharp-2
Type: text/x-patch
Size: 22409 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20090312/cc347160/attachment.bin
More information about the Mono-devel-list
mailing list