diff options
Diffstat (limited to 'src/shared/lsp/completion.h')
-rw-r--r-- | src/shared/lsp/completion.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/shared/lsp/completion.h b/src/shared/lsp/completion.h new file mode 100644 index 000000000..665b5a5ae --- /dev/null +++ b/src/shared/lsp/completion.h @@ -0,0 +1,269 @@ +// Copyright (C) 2018 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "jsonrpcmessages.h" +#include "languagefeatures.h" + +namespace lsp { + +class LANGUAGESERVERPROTOCOL_EXPORT CompletionParams : public TextDocumentPositionParams +{ +public: + using TextDocumentPositionParams::TextDocumentPositionParams; + + enum CompletionTriggerKind { + /** + * Completion was triggered by typing an identifier (24x7 code + * complete), manual invocation (e.g Ctrl+Space) or via API. + */ + Invoked = 1, + /** + * Completion was triggered by a trigger character specified by + * the `triggerCharacters` properties of the `CompletionRegistrationOptions`. + */ + TriggerCharacter = 2, + /// Completion was re-triggered as the current completion list is incomplete. + TriggerForIncompleteCompletions = 3 + }; + + class CompletionContext : public JsonObject + { + public: + using JsonObject::JsonObject; + + /// How the completion was triggered. + CompletionTriggerKind triggerKind() const + { return CompletionTriggerKind(typedValue<int>(triggerKindKey)); } + void setTriggerKind(CompletionTriggerKind triggerKind) + { insert(triggerKindKey, triggerKind); } + + /** + * The trigger character (a single character) that has trigger code complete. + * Is undefined if `triggerKind !== CompletionTriggerKind.TriggerCharacter` + */ + std::optional<QString> triggerCharacter() const + { return optionalValue<QString>(triggerCharacterKey); } + void setTriggerCharacter(const QString &triggerCharacter) + { insert(triggerCharacterKey, triggerCharacter); } + void clearTriggerCharacter() { remove(triggerCharacterKey); } + + bool isValid() const override { return contains(triggerKindKey); } + }; + + /** + * The completion context. This is only available it the client specifies + * to send this using `ClientCapabilities.textDocument.completion.contextSupport === true` + */ + std::optional<CompletionContext> context() const + { return optionalValue<CompletionContext>(contextKey); } + void setContext(const CompletionContext &context) + { insert(contextKey, context); } + void clearContext() { remove(contextKey); } + + // clangd extension + void setLimit(int limit) { insert(limitKey, limit); } +}; + +class LANGUAGESERVERPROTOCOL_EXPORT CompletionItem : public JsonObject +{ +public: + using JsonObject::JsonObject; + + /** + * The label of this completion item. By default also the text that is inserted when selecting + * this completion. + */ + QString label() const { return typedValue<QString>(labelKey); } + void setLabel(const QString &label) { insert(labelKey, label); } + + /// The kind of this completion item. Based of the kind an icon is chosen by the editor. + std::optional<int> kind() const { return optionalValue<int>(kindKey); } + void setKind(int kind) { insert(kindKey, kind); } + void clearKind() { remove(kindKey); } + + /// A human-readable string with additional information about this item, like type information. + std::optional<QString> detail() const { return optionalValue<QString>(detailKey); } + void setDetail(const QString &detail) { insert(detailKey, detail); } + void clearDetail() { remove(detailKey); } + + /// A human-readable string that represents a doc-comment. + std::optional<MarkupOrString> documentation() const; + void setDocumentation(const MarkupOrString &documentation) + { insert(documentationKey, documentation.toJson()); } + void cleatDocumentation() { remove(documentationKey); } + + /// A string that should be used when comparing this item + /// with other items. When `falsy` the label is used. + std::optional<QString> sortText() const { return optionalValue<QString>(sortTextKey); } + void setSortText(const QString &sortText) { insert(sortTextKey, sortText); } + void clearSortText() { remove(sortTextKey); } + + /// A string that should be used when filtering a set of + /// completion items. When `falsy` the label is used. + std::optional<QString> filterText() const { return optionalValue<QString>(filterTextKey); } + void setFilterText(const QString &filterText) { insert(filterTextKey, filterText); } + void clearFilterText() { remove(filterTextKey); } + + /** + * A string that should be inserted into a document when selecting + * this completion. When `falsy` the label is used. + * + * The `insertText` is subject to interpretation by the client side. + * Some tools might not take the string literally. For example + * VS Code when code complete is requested in this example `con<cursor position>` + * and a completion item with an `insertText` of `console` is provided it + * will only insert `sole`. Therefore it is recommended to use `textEdit` instead + * since it avoids additional client side interpretation. + * + * @deprecated Use textEdit instead. + */ + std::optional<QString> insertText() const { return optionalValue<QString>(insertTextKey); } + void setInsertText(const QString &insertText) { insert(insertTextKey, insertText); } + void clearInsertText() { remove(insertTextKey); } + + enum InsertTextFormat { + /// The primary text to be inserted is treated as a plain string. + PlainText = 1, + + /** + * The primary text to be inserted is treated as a snippet. + * + * A snippet can define tab stops and placeholders with `$1`, `$2` + * and `${3:foo}`. `$0` defines the final tab stop, it defaults to + * the end of the snippet. Placeholders with equal identifiers are linked, + * that is typing in one will update others too. + */ + Snippet = 2 + }; + + /// The format of the insert text. The format applies to both the `insertText` property + /// and the `newText` property of a provided `textEdit`. + std::optional<InsertTextFormat> insertTextFormat() const; + void setInsertTextFormat(const InsertTextFormat &insertTextFormat) + { insert(insertTextFormatKey, insertTextFormat); } + void clearInsertTextFormat() { remove(insertTextFormatKey); } + + /** + * An edit which is applied to a document when selecting this completion. When an edit is provided the value of + * `insertText` is ignored. + * + * *Note:* The range of the edit must be a single line range and it must contain the position at which completion + * has been requested. + */ + std::optional<TextEdit> textEdit() const { return optionalValue<TextEdit>(textEditKey); } + void setTextEdit(const TextEdit &textEdit) { insert(textEditKey, textEdit); } + void clearTextEdit() { remove(textEditKey); } + + /** + * An optional array of additional text edits that are applied when + * selecting this completion. Edits must not overlap with the main edit + * nor with themselves. + */ + std::optional<QList<TextEdit>> additionalTextEdits() const + { return optionalArray<TextEdit>(additionalTextEditsKey); } + void setAdditionalTextEdits(const QList<TextEdit> &additionalTextEdits) + { insertArray(additionalTextEditsKey, additionalTextEdits); } + void clearAdditionalTextEdits() { remove(additionalTextEditsKey); } + + /** + * An optional set of characters that when pressed while this completion is active will accept it first and + * then type that character. *Note* that all commit characters should have `length=1` and that superfluous + * characters will be ignored. + */ + std::optional<QList<QString>> commitCharacters() const + { return optionalArray<QString>(commitCharactersKey); } + void setCommitCharacters(const QList<QString> &commitCharacters) + { insertArray(commitCharactersKey, commitCharacters); } + void clearCommitCharacters() { remove(commitCharactersKey); } + + /** + * An optional command that is executed *after* inserting this completion. *Note* that + * additional modifications to the current document should be described with the + * additionalTextEdits-property. + */ + std::optional<Command> command() const { return optionalValue<Command>(commandKey); } + void setCommand(const Command &command) { insert(commandKey, command); } + void clearCommand() { remove(commandKey); } + + /** + * An data entry field that is preserved on a completion item between + * a completion and a completion resolve request. + */ + std::optional<QJsonValue> data() const { return optionalValue<QJsonValue>(dataKey); } + void setData(const QJsonValue &data) { insert(dataKey, data); } + void clearData() { remove(dataKey); } + + /** + * Completion item tags are extra annotations that tweak the rendering of a + * completion item. + * @since 3.15.0 + */ + enum CompletionItemTag { + Deprecated = 1, + }; + + /** + * Tags for this completion item. + * @since 3.15.0 + */ + std::optional<QList<CompletionItemTag>> tags() const; + + /** + * Indicates if this item is deprecated. + * @deprecated Use `tags` instead if supported. + */ + std::optional<bool> deprecated() const { return optionalValue<bool>(deprecatedKey); } + + bool isValid() const override { return contains(labelKey); } +}; + +class LANGUAGESERVERPROTOCOL_EXPORT CompletionList : public JsonObject +{ +public: + using JsonObject::JsonObject; + + /** + * This list it not complete. Further typing should result in recomputing + * this list. + */ + bool isIncomplete() const { return typedValue<bool>(isIncompleteKey); } + void setIsIncomplete(bool isIncomplete) { insert(isIncompleteKey, isIncomplete); } + + /// The completion items. + std::optional<QList<CompletionItem>> items() const { return array<CompletionItem>(itemsKey); } + void setItems(const QList<CompletionItem> &items) { insertArray(itemsKey, items); } + void clearItems() { remove(itemsKey); } + + bool isValid() const override { return contains(isIncompleteKey); } +}; + +/// The result of a completion is CompletionItem[] | CompletionList | null +class LANGUAGESERVERPROTOCOL_EXPORT CompletionResult + : public std::variant<QList<CompletionItem>, CompletionList, std::nullptr_t> +{ +public: + using variant::variant; + explicit CompletionResult(const QJsonValue &value); +}; + +class LANGUAGESERVERPROTOCOL_EXPORT CompletionRequest : public Request< + CompletionResult, std::nullptr_t, CompletionParams> +{ +public: + explicit CompletionRequest(const CompletionParams ¶ms); + using Request::Request; + constexpr static const char methodName[] = "textDocument/completion"; +}; + +class LANGUAGESERVERPROTOCOL_EXPORT CompletionItemResolveRequest : public Request< + CompletionItem, std::nullptr_t, CompletionItem> +{ +public: + explicit CompletionItemResolveRequest(const CompletionItem ¶ms); + using Request::Request; + constexpr static const char methodName[] = "completionItem/resolve"; +}; + +} // namespace LanguageClient |