// 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(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 triggerCharacter() const { return optionalValue(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 context() const { return optionalValue(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(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 kind() const { return optionalValue(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 detail() const { return optionalValue(detailKey); } void setDetail(const QString &detail) { insert(detailKey, detail); } void clearDetail() { remove(detailKey); } /// A human-readable string that represents a doc-comment. std::optional 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 sortText() const { return optionalValue(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 filterText() const { return optionalValue(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` * 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 insertText() const { return optionalValue(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() 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() const { return optionalValue(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> additionalTextEdits() const { return optionalArray(additionalTextEditsKey); } void setAdditionalTextEdits(const QList &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> commitCharacters() const { return optionalArray(commitCharactersKey); } void setCommitCharacters(const QList &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() const { return optionalValue(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 data() const { return optionalValue(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> tags() const; /** * Indicates if this item is deprecated. * @deprecated Use `tags` instead if supported. */ std::optional deprecated() const { return optionalValue(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(isIncompleteKey); } void setIsIncomplete(bool isIncomplete) { insert(isIncompleteKey, isIncomplete); } /// The completion items. std::optional> items() const { return array(itemsKey); } void setItems(const QList &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, 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