Open
Description
Background and motivation
In #68578 (comment), we have introduced a set of symbol types for building a parsable hierarchy.
In #84177 (comment) a set of parsing APIs that expose information required by completions.
In this issue, we want to propose a set of APIs for completions.
API Proposal
namespace System.CommandLine.Completions;
The types presented in the details below are complete, none of our other proposals is extending them.
namespace System.CommandLine.Completions;
/// <summary>
/// Provides details about a command line completion item.
/// </summary>
/// reference: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_completion
public class CompletionItem : IEquatable<CompletionItem>
{
/// <param name="label">The label value, which is the text displayed to users and, unless <paramref name="insertText"/> is set, is also used to populate the <see cref="InsertText"/> property.</param>
/// <param name="kind">The kind of completion item.</param>
/// <param name="sortText">The value used to sort the completion item in a list. If this is not provided, then <paramref name="label"/> is used.</param>
/// <param name="insertText">The text to be inserted by this completion item. If this is not provided, then <paramref name="label"/> is used.</param>
/// <param name="documentation">Documentation about the completion item.</param>
/// <param name="detail">Additional details regarding the completion item.</param>
public CompletionItem(string label, string kind = "Value", string? sortText = null, string? insertText = null,
string? documentation = null, string? detail = null);
/// <summary>
/// The label value, which is the text displayed to users.
/// </summary>
public string Label { get; }
/// <summary>
/// The kind of completion item.
/// </summary>
public string? Kind { get; }
/// <summary>
/// The value used to sort the completion item in a list.
/// </summary>
public string SortText { get; }
/// <summary>
/// The text to be inserted by this completion item.
/// </summary>
public string? InsertText { get; }
/// <summary>
/// Documentation about the completion item.
/// </summary>
public string? Documentation { get; set; }
/// <summary>
/// Additional details regarding the completion item.
/// </summary>
public string? Detail { get; }
}
/// <summary>
/// Supports command line completion operations.
/// </summary>
public class CompletionContext
{
/// The text of the word to be completed, if any.
public string WordToComplete { get; }
/// The parse result for which completions are being requested.
public ParseResult ParseResult { get; }
/// <summary>
/// Gets an empty CompletionContext.
/// </summary>
/// <remarks>Can be used for testing purposes.</remarks>
public static CompletionContext Empty { get; }
}
/// <summary>
/// Provides details for calculating completions in the context of complete, unsplit command line text.
/// </summary>
public class TextCompletionContext : CompletionContext
{
/// <summary>
/// The position of the cursor within the command line.
/// </summary>
public int CursorPosition { get; }
/// <summary>
/// The complete text of the command line prior to splitting, including any additional whitespace.
/// </summary>
public string CommandLineText { get; }
/// <summary>
/// Creates a new instance of <see cref="TextCompletionContext"/> at the specified cursor position.
/// </summary>
/// <param name="position">The cursor position at which completions are calculated.</param>
public TextCompletionContext AtCursorPosition(int position);
}
namespace System.CommandLine
namespace System.CommandLine;
public abstract class CliSymbol
{
/// <summary>
/// Gets completions for the symbol.
/// </summary>
public abstract IEnumerable<CompletionItem> GetCompletions(CompletionContext context);
}
public abstract class CliArgument : CliSymbol
{
/// <summary>
/// Gets the list of completion sources for the argument.
/// </summary>
public List<Func<CompletionContext, IEnumerable<CompletionItem>>> CompletionSources { get; }
}
public abstract class CliOption : CliSymbol
{
/// <summary>
/// Gets the list of completion sources for the option.
/// </summary>
public List<Func<CompletionContext, IEnumerable<CompletionItem>>> CompletionSources { get; }
}
public sealed class ParseResult
{
/// <summary>
/// Gets completions based on a given parse result.
/// </summary>
/// <param name="position">The position at which completions are requested.</param>
/// <returns>A set of completions for completion.</returns>
public IEnumerable<CompletionItem> GetCompletions(int? position = null);
}
API Usage
Defining completion sources:
CliOption<string> fruitOption = new("--fruit");
fruitOption.CompletionSources.Add("apple", "banana", "cherry");
CliOption<string> vegetableOption = new("--vegetable");
vegetableOption.CompletionSources.Add("asparagus", "broccoli", "carrot");
CliCommand eatCommand = new ("eat")
{
fruitOption,
vegetableOption
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment