#include #include "./completion_provider.hpp" #include "../../protocol/transform/facade.hpp" namespace lsp::providers::text_document { std::string CompletionProvider::ProvideResponse(const protocol::RequestMessage& request) { spdlog::debug("CompletionProvider: Providing response for method {}", request.method); try { // 验证请求是否包含参数 if (!request.params.has_value()) { spdlog::warn("{}: Missing params in request", GetProviderName()); return BuildErrorMessageResponse(protocol::ErrorCode::kInvalidParams, "Missing params"); } // 从 variant 中提取参数 protocol::CompletionParams completion_params = transform::As(request.params.value()); protocol::CompletionList completion_list = BuildCompletionResponse(completion_params); // 构建响应消息 protocol::ResponseMessage response; response.id = request.id; response.result = transform::LSPAny(completion_list); std::string json; auto ec = glz::write_json(response, json); if (ec) { spdlog::error("{}: Failed to serialize response: {}", GetProviderName(), glz::format_error(ec, json)); return BuildErrorMessageResponse(protocol::ErrorCode::kInternalError, "Failed to serialize response"); } return json; } catch (const transform::ConversionError& e) { spdlog::error("{}: Failed to convert params: {}", GetProviderName(), e.what()); return BuildErrorMessageResponse(protocol::ErrorCode::kInvalidParams, "Invalid completion params"); } catch (const std::exception& e) { spdlog::error("{}: Unexpected error: {}", GetProviderName(), e.what()); return BuildErrorMessageResponse(protocol::ErrorCode::kInternalError, "Internal error"); } } std::string CompletionProvider::GetMethod() const { return "textDocument/completion"; } std::string CompletionProvider::GetProviderName() const { return "CompletionProvider"; } protocol::CompletionList CompletionProvider::BuildCompletionResponse(const protocol::CompletionParams& params) { spdlog::trace("{}: Processing completion request for URI='{}', Position=({}, {})", GetProviderName(), params.textDocument.uri, params.position.line, params.position.character); // 获取补全前缀 std::string prefix = ExtractPrefix(params.textDocument, params.position); // 如果提供了 context,可以使用其中的信息 if (params.context.has_value()) { spdlog::trace("{}: Trigger kind: {}", GetProviderName(), static_cast(params.context->triggerKind)); if (params.context->triggerCharacter.has_value()) spdlog::trace("{}: Trigger character: '{}'", GetProviderName(), params.context->triggerCharacter.value()); } // 收集所有补全项 std::vector allItems; // 添加关键字补全 auto keywordItems = ProvideKeywordCompletions(prefix); allItems.insert(allItems.end(), keywordItems.begin(), keywordItems.end()); // 添加上下文相关补全 auto contextualItems = ProvideContextualCompletions(params.textDocument, params.position, prefix); allItems.insert(allItems.end(), contextualItems.begin(), contextualItems.end()); // 构建补全列表 protocol::CompletionList result; result.isIncomplete = false; // 表示这是完整的补全列表 result.items = std::move(allItems); spdlog::info("{}: Provided {} completion items", GetProviderName(), result.items.size()); return result; } std::string CompletionProvider::ExtractPrefix(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position) { // TODO: 实现从文档内容和位置计算前缀 // 这需要访问文档管理器来获取文档内容 // 现在返回空字符串 spdlog::trace("{}: ExtractPrefix not implemented, returning empty string", GetProviderName()); return ""; } std::vector CompletionProvider::ProvideKeywordCompletions(const std::string& prefix) { std::vector items; // 从 tsl_keywords_ 获取补全项 auto tslItems = tsl_keywords_.GetCompletionItems(prefix); for (const auto& tslItem : tslItems) { protocol::CompletionItem item; item.label = tslItem.label; item.kind = protocol::CompletionItemKind::kKeyword; item.detail = "TSL Keyword"; // 创建文档内容 protocol::MarkupContent documentation; documentation.kind = protocol::MarkupKindLiterals::PlainText; documentation.value = "TSL language keyword"; item.documentation = documentation; item.insertText = tslItem.label; items.push_back(item); } spdlog::debug("{}: Found {} keyword completions", GetProviderName(), items.size()); return items; } std::vector CompletionProvider::ProvideContextualCompletions(const protocol::TextDocumentIdentifier& textDocument, const protocol::Position& position, const std::string& prefix) { spdlog::debug("{}: Processing contextual completions for URI: {}", GetProviderName(), textDocument.uri); std::vector items; // TODO: 基于上下文提供补全 // 示例:添加一个变量补全 if (!prefix.empty() && prefix[0] == '$') { protocol::CompletionItem varItem; varItem.label = "$myVariable"; varItem.kind = protocol::CompletionItemKind::kVariable; varItem.detail = "Local variable"; varItem.insertText = "$myVariable"; protocol::MarkupContent doc; doc.kind = protocol::MarkupKindLiterals::Markdown; doc.value = "Example variable completion"; varItem.documentation = doc; items.push_back(varItem); } spdlog::debug("{}: Found {} contextual completions", GetProviderName(), items.size()); return items; } }