diff --git a/docs/clice.toml b/docs/clice.toml index c7581f0d..dd020c26 100644 --- a/docs/clice.toml +++ b/docs/clice.toml @@ -5,14 +5,10 @@ # Supported variables: # - `${version}`: The version of clice. -# - `${binary}`: The path of the clice binary. # - `${llvm_version}`: The LLVM version used by clice. # - `${workspace}`: The workspace directory provided by the client. -[server] - # Compile commands directories to search for compile_commands.json files. - compile_commands_dirs = ["${workspace}/build"] - +[project] # Enable experimental clang-tidy diagnostics. # This feature is tracked in https://github.com/clice-project/clice/issues/90. clang_tidy = false @@ -22,22 +18,17 @@ # The default value is 8. Whatever the number you set, the minimum is 1, the maximum is 512. max_active_file = 8 -# Cache configuration for storing precompiled headers and modules. -[cache] # Directory for storing PCH and PCM files. - dir = "${workspace}/.clice/cache" + cache_dir = "${workspace}/.clice/cache" - # Maximum number of cache files to keep. If the total exceeds this limit, clice - # deletes the oldest files automatically. Set to 0 to disable the limit. - limit = 0 - -# Index configuration for symbol and feature indexing. -[index] # Directory for storing index files. - dir = "${workspace}/.clice/index" + index_dir = "${workspace}/.clice/index" + + logging_dir = "${workspace}/.clice/logging" + + # Compile commands directories to search for compile_commands.json files. + compile_commands_dirs = ["${workspace}/build"] - # Whether to index entities in implicit template instantiations. - implicitInstantiation = true # Control the behavior for specific files. Note that Clice matches rules # in order. If you want to add your own rules, either delete this rule @@ -55,42 +46,10 @@ # (e.g., `example.[0-9]` matches `example.0`, `example.1`, etc.). # - `[!...]`: Negates a range of characters to match in a path segment # (e.g., `example.[!0-9]` matches `example.a`, `example.b`, but not `example.0`). - pattern = "**/*" + patterns = ["**/*"] # Commands to append to the original command list (e.g., ["-std=c++17"]). append = [] # Commands to remove from the original command list. remove = [] - - # Controls whether the file is treated as readonly. - # Possible values: ["auto", "always", "never"] - # - # - "auto": Treats the file as readonly until you edit it. - # - "always": Always treats the file as readonly. - # - "never": Always treats the file as non-readonly. - # - # Readonly means the file is not editable, and LSP requests such as - # code actions or completions will not be sent to the server. This avoids - # dynamic computation and allows pre-indexed results to be loaded directly, - # improving performance. - readonly = "auto" - - # Controls how header files are treated. - # Possible values: ["auto", "always", "never"] - # - # - "auto": Attempts to infer the header context first. If no header context - # is found, the file will be treated as a normal source file. - # - "always": Always treats the file as a header file. If no header context - # is found, errors will be reported. - # - "never": Always treats the file as a source file. - # - # Header context refers to the related source files or additional metadata - # linked to the header file. - header = "auto" - - # Specifies extra header contexts (file paths) for the file. - # Normally, header contexts are inferred automatically once the file is indexed. - # However, if you need immediate context before indexing completes, you can - # provide it manually using this field. - contexts = [] diff --git a/docs/en/guide/configuration.md b/docs/en/guide/configuration.md index 8fb1d71b..08213d09 100644 --- a/docs/en/guide/configuration.md +++ b/docs/en/guide/configuration.md @@ -2,7 +2,21 @@ This is the documentation for `clice.toml`. -## Server +## Project + +| Name | Type | Default | +| ------------------- | -------- | ----------------------------- | +| `project.cache_dir` | `string` | `"${workspace}/.clice/cache"` | + +Folder for storing PCH and PCM caches. +
+ +| Name | Type | Default | +| ------------------- | -------- | ----------------------------- | +| `project.index_dir` | `string` | `"${workspace}/.clice/index"` | + +Folder for storing index files. +
## Rule @@ -11,7 +25,7 @@ This is the documentation for `clice.toml`. | Name | Type | | ------------------ | ------------------- | -| `[rules].pattern` | `array` of `string` | +| `[rules].patterns` | `array` of `string` | Glob patterns for matching file paths, following LSP's [standard](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentFilter). @@ -23,70 +37,16 @@ Glob patterns for matching file paths, following LSP's [standard](https://micros - `[!...]`: Excludes a character range to match in a path segment (e.g., `example.[!0-9]` matches `example.a`, `example.b`, but not `example.0`).
-| Name | Type | Default | -| ----------------- | ------------------- | ------- | -| `[rules].append` | `array` of `string` | `[]` | +| Name | Type | Default | +| ---------------- | ------------------- | ------- | +| `[rules].append` | `array` of `string` | `[]` | Commands to append to the original command list. For example, `append = ["-std=c++17"]`.
-| Name | Type | Default | -| ----------------- | ------------------- | ------- | -| `[rules].remove` | `array` of `string` | `[]` | +| Name | Type | Default | +| ---------------- | ------------------- | ------- | +| `[rules].remove` | `array` of `string` | `[]` | Commands to remove from the original command list. For example, `remove = ["-std=c++11"]`.
- -| Name | Type | Default | -| ------------------- | -------- | ------- | -| `[rules].readonly` | `string` | `"auto"` | - -Controls whether the file is treated as read-only. Values can be one of `"auto"`, `"always"`, and `"never"`. - -- `"auto"`: The file is treated as read-only before you edit it. -- `"always"`: Always treat the file as read-only. -- `"never"`: Always treat the file as non-read-only. - -Read-only means the file is not editable, and LSP requests like code actions or completions won't be triggered on it. This avoids dynamic computation and allows direct loading of pre-indexed results, improving performance. -
- -| Name | Type | Default | -| ----------------- | -------- | ------- | -| `[rules].header` | `string` | `"auto"` | - -Controls how to handle header files. Values can be one of `"auto"`, `"always"`, and `"never"`. - -- `"auto"`: First try to infer header file context. If no header file context is found, the file will be treated as a regular source file. -- `"always"`: Always treat the file as a header file. If no header file context is found, an error will be reported. -- `"never"`: Always treat the file as a source file. - -Header file context refers to the source files or other metadata associated with that header file. -
- -| Name | Type | Default | -| -------------------- | ------------------- | ------- | -| `[rules].contexts` | `array` of `string` | `[]` | - -Specify additional header file contexts (file paths) for the file. - -Usually, once a file is indexed, header file context is automatically inferred. However, if you need immediate context before indexing is complete, you can manually provide it using this field. - -## Cache - -| Name | Type | Default | -| ----------- | -------- | ------------------------------ | -| `cache.dir` | `string` | `"${workspace}/.clice/cache"` | - -Folder for storing PCH and PCM caches. -
- -## Index - -| Name | Type | Default | -| ----------- | -------- | ------------------------------ | -| `index.dir` | `string` | `"${workspace}/.clice/index"` | - -Folder for storing index files. -
- -## Feature diff --git a/docs/zh/guide/configuration.md b/docs/zh/guide/configuration.md index 4e53a831..02d53af7 100644 --- a/docs/zh/guide/configuration.md +++ b/docs/zh/guide/configuration.md @@ -2,16 +2,30 @@ 这是 `clice.toml` 的文档。 -## Server +## Project + +| 名称 | 类型 | 默认值 | +| ------------------- | -------- | ----------------------------- | +| `project.cache_dir` | `string` | `"${workspace}/.clice/cache"` | + +用于储存 PCH 和 PCM 缓存的文件夹。 +
+ +| 名称 | 类型 | 默认值 | +| ------------------- | -------- | ----------------------------- | +| `project.index_dir` | `string` | `"${workspace}/.clice/index"` | + +用于储存索引文件的文件夹。 +
## Rule `[[rules]]` 表示一个对象数组,其中每个对象都拥有下面这些属性
-| 名称              | 类型                | -| ----------------- | ------------------- | -| `[rules].pattern` | `array` of `string` | +| 名称 | 类型 | +| ------------------ | ------------------- | +| `[rules].patterns` | `array` of `string` | 用于匹配文件路径的 glob patterns,遵循 LSP 的 [标准](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#documentFilter)。 @@ -23,70 +37,16 @@ - `[!...]`: 排除要匹配的路径段中的字符范围 (例如,`example.[!0-9]` 匹配 `example.a`, `example.b`,但不匹配 `example.0`)。
-| 名称             | 类型                | 默认值 | -| ---------------- | ------------------- | ------- | -| `[rules].append` | `array` of `string` | `[]`    | +| 名称 | 类型 | 默认值 | +| ---------------- | ------------------- | ------ | +| `[rules].append` | `array` of `string` | `[]` | 追加到原始命令列表中的命令。例如,`append = ["-std=c++17"]`。
-| 名称             | 类型                | 默认值 | -| ---------------- | ------------------- | ------- | -| `[rules].remove` | `array` of `string` | `[]`    | +| 名称 | 类型 | 默认值 | +| ---------------- | ------------------- | ------ | +| `[rules].remove` | `array` of `string` | `[]` | 从原始命令列表中移除的命令。例如,`remove = ["-std=c++11"]`。
- -| 名称               | 类型     | 默认值  | -| ------------------ | -------- | -------- | -| `[rules].readonly` | `string` | `"auto"` | - -控制文件是否被视为只读。值可以是 `"auto"`、`"always"` 和 `"never"` 中的一个。 - -- `"auto"`: 在你编辑文件之前,文件被视为只读。 -- `"always"`: 始终将文件视为只读。 -- `"never"`: 始终将文件视为非只读。 - -只读意味着文件不可编辑,并且像代码操作 (code actions) 或补全 (completions) 这样的 LSP 请求不会在其上触发。这避免了动态计算,并允许直接加载预先索引的结果,从而提高性能。 -
- -| 名称             | 类型     | 默认值  | -| ---------------- | -------- | -------- | -| `[rules].header` | `string` | `"auto"` | - -控制如何处理头文件。值可以是 `"auto"`、`"always"` 和 `"never"` 中的一个。 - -- `"auto"`: 首先尝试推断头文件上下文。如果未找到头文件上下文,文件将被视为普通的源文件。 -- `"always"`: 始终将文件视为头文件。如果未找到头文件上下文,将会报告错误。 -- `"never"`: 始终将文件视为源文件。 - -头文件上下文指的是与该头文件相关联的源文件或其他元数据。 -
- -| 名称               | 类型                | 默认值 | -| ------------------ | ------------------- | ------- | -| `[rules].contexts` | `array` of `string` | `[]`    | - -为文件指定额外的头文件上下文 (文件路径)。 - -通常,一旦文件被索引,头文件上下文会自动推断。但是,如果你需要在索引完成前获得即时上下文,可以使用此字段手动提供。 - -## Cache - -| 名称        | 类型     | 默认值                       | -| ----------- | -------- | ----------------------------- | -| `cache.dir` | `string` | `"${workspace}/.clice/cache"` | - -用于储存 PCH 和 PCM 缓存的文件夹。 -
- -## Index - -| 名称        | 类型     | 默认值                       | -| ----------- | -------- | ----------------------------- | -| `index.dir` | `string` | `"${workspace}/.clice/index"` | - -用于储存索引文件的文件夹。 -
- -## Feature diff --git a/include/Server/Config.h b/include/Server/Config.h index e8522b50..d88919dc 100644 --- a/include/Server/Config.h +++ b/include/Server/Config.h @@ -8,45 +8,44 @@ namespace clice::config { -/// Read the config file, call when the program starts. -std::expected load(llvm::StringRef execute, llvm::StringRef filename); +struct ProjectOptions { + bool root = true; -/// Initialize the config, replace all predefined variables in the config file. -/// called in `Server::initialize`. -void init(std::string_view workplace); - -struct ServerOptions { - std::vector compile_commands_dirs = {"${workspace}/build"}; bool clang_tidy = false; - size_t max_active_file = 8; -}; -struct CacheOptions { - std::string dir = "${workspace}/.clice/cache"; - uint32_t limit = 0; -}; + std::size_t max_active_file = 8; -struct IndexOptions { - std::string dir = "${workspace}/.clice/index"; + std::string cache_dir = "${workspace}/.clice/cache"; + + std::string index_dir = "${workspace}/.clice/index"; + + std::string logging_dir = "${workspace}/.clice/logging"; + + std::vector compile_commands_dirs = {"${workspace}/build"}; }; struct Rule { - std::string pattern; - std::vector append; - std::vector remove; - std::string readonly; - std::string header; - std::vector context; + /// All patterns of the rule. + llvm::SmallVector patterns; + + /// The commands that you want to remove from original command. + llvm::SmallVector remove; + + /// The commands that you want to append from original command. + llvm::SmallVector append; }; -extern llvm::StringRef version; -extern llvm::StringRef binary; -extern llvm::StringRef llvm_version; -extern llvm::StringRef workspace; +struct Config { + /// The workspace of this config file. + std::string workspace; -extern const ServerOptions& server; -extern const CacheOptions& cache; -extern const IndexOptions& index; -extern llvm::ArrayRef rules; + /// Project level configs. + ProjectOptions project; + + /// All rules used for specific files. + llvm::SmallVector rules; + + auto parse(llvm::StringRef workspace) -> std::expected; +}; }; // namespace clice::config diff --git a/include/Server/Server.h b/include/Server/Server.h index 16baa26d..1d9c6e59 100644 --- a/include/Server/Server.h +++ b/include/Server/Server.h @@ -235,6 +235,8 @@ private: ActiveFileManager opening_files; PathMapping mapping; + + config::Config config; }; } // namespace clice diff --git a/include/Server/Version.h b/include/Server/Version.h new file mode 100644 index 00000000..5fe4f0e7 --- /dev/null +++ b/include/Server/Version.h @@ -0,0 +1,10 @@ +#pragma once + +#include + +namespace clice::config { + +constexpr inline std::string_view version = "0.0.1"; +constexpr inline std::string_view llvm_version = "20.1.5"; + +} // namespace clice::config diff --git a/src/Driver/clice.cc b/src/Driver/clice.cc index fb3636a7..636bbb83 100644 --- a/src/Driver/clice.cc +++ b/src/Driver/clice.cc @@ -1,3 +1,4 @@ +#include "Server/Version.h" #include "Server/Server.h" #include "Support/Logging.h" #include "Support/Format.h" @@ -47,14 +48,6 @@ cl::opt port{ cl::desc("The port to connect to"), }; -cl::opt config_path{ - "config", - cl::cat(category), - cl::value_desc("path"), - cl::desc( - "The path of the clice config file, if not specified, the default config will be used"), -}; - cl::opt resource_dir{ "resource-dir", cl::cat(category), @@ -119,22 +112,6 @@ bool check_arguments(int argc, const char** argv) { logging::info("argv[{}] = {}", i, argv[i]); } - // Handle configuration file loading - if(config_path.empty()) { - logging::info("No configuration file specified, using default settings"); - } else { - llvm::StringRef path = config_path; - // Try to load the configuration file and check the result - if(auto result = config::load(argv[0], path); result) { - logging::info("Configuration file loaded successfully from: {}", path); - } else { - logging::warn("Failed to load configuration file from: {} because {}", - path, - result.error()); - return false; - } - } - // Initialize resource directory if(resource_dir.empty()) { logging::info("No resource directory specified, using default resource directory"); diff --git a/src/Server/Config.cpp b/src/Server/Config.cpp index 1f050d84..dbbc7a6a 100644 --- a/src/Server/Config.cpp +++ b/src/Server/Config.cpp @@ -2,94 +2,16 @@ #include "toml++/toml.hpp" #include "Server/Config.h" +#include "Server/Version.h" #include "Support/Logging.h" +#include "Support/Ranges.h" #include "Support/FileSystem.h" #include "llvm/ADT/StringMap.h" namespace clice::config { -static llvm::StringMap predefined = { - /// the directory of the workplace. - {"workplace", "" }, - /// the directory of the executable. - {"binary", "" }, - /// the version of the clice. - {"version", "0.0.1"}, - /// the version of dependent llvm. - {"llvm_version", "20" }, -}; - -/// predefined variables. -llvm::StringRef version = predefined["version"]; -llvm::StringRef binary = predefined["binary"]; -llvm::StringRef llvm_version = predefined["llvm_version"]; -llvm::StringRef workspace = predefined["workplace"]; - -struct Config { - ServerOptions server; - CacheOptions cache; - IndexOptions index; - std::vector rules; -}; - -/// global config instance. -static Config config = {}; - -const ServerOptions& server = config.server; -const CacheOptions& cache = config.cache; -const IndexOptions& index = config.index; -llvm::ArrayRef rules = config.rules; - -template -static void parse(Object& object, auto&& value) { - if constexpr(std::is_same_v) { - if(auto v = value.as_boolean()) { - object = v->get(); - } - } else if constexpr(clice::integral) { - if(auto v = value.as_integer()) { - object = v->get(); - } - } else if constexpr(std::is_same_v) { - if(auto v = value.as_string()) { - object = v->get(); - } - } else if constexpr(clice::is_specialization_of) { - if(auto v = value.as_array()) { - for(auto& item: *v) { - object.emplace_back(); - parse(object.back(), item); - } - } - } else if constexpr(refl::reflectable_struct) { - if(auto table = value.as_table()) { - refl::foreach(object, [&](std::string_view key, auto& member) { - if(auto v = (*table)[key]) { - parse(member, v); - } - }); - } - } else { - static_assert(dependent_false, "Unsupported type"); - } -} - -std::expected load(llvm::StringRef execute, llvm::StringRef filename) { - predefined["version"] = "0.0.1"; - predefined["binary"] = execute; - predefined["llvm_version"] = "20"; - - auto toml = toml::parse_file(filename); - if(toml.failed()) { - return std::unexpected(toml.error().description()); - } - - parse(config, toml.table()); - return {}; -} - /// replace all predefined variables in the text. -static void resolve(std::string& input) { +static void resolve(std::string& input, Config& config) { std::string_view text = input; llvm::SmallString<128> path; std::size_t pos = 0; @@ -104,8 +26,12 @@ static void resolve(std::string& input) { auto variable = text.substr(pos + 2, end - (pos + 2)); - if(auto iter = predefined.find(variable); iter != predefined.end()) { - path.append(iter->second); + if(variable == "workspace") { + path.append(config.workspace); + } else if(variable == "version") { + path.append(config::version); + } else if(variable == "llvm_version") { + path.append(config::llvm_version); } else { path.append(text.substr(pos, end - pos + 1)); } @@ -120,25 +46,75 @@ static void resolve(std::string& input) { } template -static void replace(Object& object) { +static void replace(Object& object, Config& config) { if constexpr(std::is_same_v) { - resolve(object); - } else if constexpr(clice::is_specialization_of) { + resolve(object, config); + } else if constexpr(sequence_range) { for(auto& item: object) { - replace(item); + replace(item, config); } } else if constexpr(refl::reflectable_struct) { - refl::foreach(object, [&](auto, auto& member) { replace(member); }); + refl::foreach(object, [&](auto, auto& member) { replace(member, config); }); } } -void init(std::string_view workplace) { - predefined["workspace"] = workplace; +template +static void parse_toml(Object& object, auto&& value, Config& config) { + if constexpr(std::is_same_v) { + if(auto v = value.as_boolean()) { + object = v->get(); + } + } else if constexpr(clice::integral) { + if(auto v = value.as_integer()) { + object = v->get(); + } + } else if constexpr(std::is_same_v) { + if(auto v = value.as_string()) { + object = v->get(); + } + } else if constexpr(sequence_range) { + if(auto v = value.as_array()) { + for(auto& item: *v) { + object.emplace_back(); + parse_toml(object.back(), item, config); + } + } + } else if constexpr(refl::reflectable_struct) { + if(auto table = value.as_table()) { + refl::foreach(object, [&](std::string_view key, auto& member) { + if(auto v = (*table)[key]) { + parse_toml(member, v, config); + } + }); + } + } else { + static_assert(dependent_false, "Unsupported type"); + } +} - replace(config); +auto Config::parse(llvm::StringRef workspace) -> std::expected { + this->workspace = workspace; - logging::info("Config initialized successfully: {0}", json::serialize(config)); - return; + auto path = path::join(workspace, "clice.toml"); + + std::string error_message; + if(fs::exists(path)) { + if(auto toml = toml::parse_file(path)) { + parse_toml(*this, toml.table(), *this); + } else { + error_message = toml.error().description(); + } + } else { + error_message = "Config file doesn't exist!"; + } + + replace(*this, *this); + + if(!error_message.empty()) { + return std::unexpected(std::move(error_message)); + } + + return {}; } } // namespace clice::config diff --git a/src/Server/Document.cpp b/src/Server/Document.cpp index 20b2260e..2129f012 100644 --- a/src/Server/Document.cpp +++ b/src/Server/Document.cpp @@ -9,7 +9,7 @@ namespace clice { void Server::load_cache_info() { - auto path = path::join(config::cache.dir, "cache.json"); + auto path = path::join(config.project.cache_dir, "cache.json"); auto file = llvm::MemoryBuffer::getFile(path); if(!file) { logging::warn("Fail to load cache info, because: {}", file.getError()); @@ -101,7 +101,7 @@ void Server::save_cache_info() { json["pchs"].getAsArray()->emplace_back(std::move(object)); } - auto final_path = path::join(config::cache.dir, "cache.json"); + auto final_path = path::join(config.project.cache_dir, "cache.json"); llvm::SmallString<128> temp_path; if(auto error = llvm::sys::fs::createTemporaryFile("cache", "json", temp_path)) { @@ -171,15 +171,16 @@ bool check_pch_update(llvm::StringRef content, /// The actual PCH build task. async::Task build_pch_task(CompilationDatabase::LookupInfo& info, + std::string cache_dir, std::shared_ptr open_file, std::string path, std::uint32_t bound, std::string content, std::shared_ptr> diagnostics) { - if(!fs::exists(config::cache.dir)) { - auto error = fs::create_directories(config::cache.dir); + if(!fs::exists(cache_dir)) { + auto error = fs::create_directories(cache_dir); if(error) { - logging::warn("Fail to create directory for PCH building: {}", config::cache.dir); + logging::warn("Fail to create directory for PCH building: {}", cache_dir); co_return false; } } @@ -189,7 +190,7 @@ async::Task build_pch_task(CompilationDatabase::LookupInfo& info, CompilationParams params; params.kind = CompilationUnit::Preamble; - params.output_file = path::join(config::cache.dir, path::filename(path) + ".pch"); + params.output_file = path::join(cache_dir, path::filename(path) + ".pch"); params.arguments = std::move(info.arguments); params.diagnostics = diagnostics; params.add_remapped_file(path, content, bound); @@ -273,7 +274,13 @@ async::Task Server::build_pch(std::string file, std::string content) { } /// Schedule the new building task. - task = build_pch_task(info, open_file, file, bound, std::move(content), open_file->diagnostics); + task = build_pch_task(info, + config.project.cache_dir, + open_file, + file, + bound, + std::move(content), + open_file->diagnostics); if(co_await task) { /// FIXME: At this point, task has already been finished, destroy it directly. task.release().destroy(); @@ -326,7 +333,7 @@ async::Task<> Server::build_ast(std::string path, std::string content) { } /// Run Clang-Tidy - if(config::server.clang_tidy) { + if(config.project.clang_tidy) { logging::warn( "clang-tidy is not fully supported yet. Tracked in https://github.com/clice-project/clice/issues/90."); } diff --git a/src/Server/Lifecycle.cpp b/src/Server/Lifecycle.cpp index cbf851f2..07b82178 100644 --- a/src/Server/Lifecycle.cpp +++ b/src/Server/Lifecycle.cpp @@ -21,13 +21,18 @@ async::Task Server::on_initialize(proto::InitializeParams params) { })()); /// Initialize configuration. - config::init(workspace); + if(auto result = config.parse(workspace)) { + logging::info("Config initialized successfully: {0}", json::serialize(config)); + } else { + logging::warn("Fail to load config, because: {0}", result.error()); + logging::info("Use default config: {0}", json::serialize(config)); + } /// Set server options. - opening_files.set_capability(config::server.max_active_file); + opening_files.set_capability(config.project.max_active_file); /// Load compile commands.json - database.load_compile_database(config::server.compile_commands_dirs, workspace); + database.load_compile_database(config.project.compile_commands_dirs, workspace); /// Load cache info. load_cache_info(); diff --git a/tests/conftest.py b/tests/conftest.py index c763bce4..0d669b92 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -88,12 +88,6 @@ async def client( if resource_dir: cmd.append(f"--resource-dir={resource_dir}") - if hasattr(request, "param") and request.param: - if "config_project" in request.param: - project_name = request.param["config_project"] - config_path = test_data_dir / project_name / "clice.toml" - cmd.append(f"--config={config_path}") - client = LSPClient( cmd, mode, diff --git a/tests/data/clang_tidy/clice.toml b/tests/data/clang_tidy/clice.toml index bbb49939..70c93aa4 100644 --- a/tests/data/clang_tidy/clice.toml +++ b/tests/data/clang_tidy/clice.toml @@ -1,6 +1,6 @@ ### clice configuration -[server] +[project] # Enable clang-tidy diagnostics. clang_tidy = true diff --git a/tests/fixtures/client.py b/tests/fixtures/client.py index 506dcd4a..63824afa 100644 --- a/tests/fixtures/client.py +++ b/tests/fixtures/client.py @@ -28,6 +28,7 @@ class LSPClient(LSPTransport): async def exit(self): await self.send_notification("exit") + await self.stop() def get_abs_path(self, relative_path: str): return Path(self.workspace, relative_path) diff --git a/tests/integration/test_file_operation.py b/tests/integration/test_file_operation.py index 9b287379..fb0016a3 100644 --- a/tests/integration/test_file_operation.py +++ b/tests/integration/test_file_operation.py @@ -1,16 +1,17 @@ import pytest import asyncio +from tests.fixtures.client import LSPClient @pytest.mark.asyncio -async def test_did_open(client, test_data_dir): +async def test_did_open(client: LSPClient, test_data_dir): await client.initialize(test_data_dir / "hello_world") await client.did_open("main.cpp") await asyncio.sleep(5) @pytest.mark.asyncio -async def test_did_change(client, test_data_dir): +async def test_did_change(client: LSPClient, test_data_dir): await client.initialize(test_data_dir / "hello_world") await client.did_open("main.cpp") @@ -25,9 +26,8 @@ async def test_did_change(client, test_data_dir): await asyncio.sleep(5) -@pytest.mark.parametrize("client", [{"config_project": "clang_tidy"}], indirect=True) @pytest.mark.asyncio -async def test_clang_tidy(client, test_data_dir): +async def test_clang_tidy(client: LSPClient, test_data_dir): await client.initialize(test_data_dir / "clang_tidy") await client.did_open("main.cpp") await asyncio.sleep(5) diff --git a/tests/integration/test_lifecycle.py b/tests/integration/test_lifecycle.py index 7a2d3952..73b87e56 100644 --- a/tests/integration/test_lifecycle.py +++ b/tests/integration/test_lifecycle.py @@ -1,8 +1,9 @@ import pytest +from tests.fixtures.client import LSPClient @pytest.mark.asyncio -async def test_initialize(client, test_data_dir): +async def test_initialize(client: LSPClient, test_data_dir): result = await client.initialize(test_data_dir) assert "serverInfo" in result assert result["serverInfo"]["name"] == "clice"