diff --git a/generated/rust-analyzer.nix b/generated/rust-analyzer.nix index e9322bbf..129ce7b0 100644 --- a/generated/rust-analyzer.nix +++ b/generated/rust-analyzer.nix @@ -172,7 +172,7 @@ targets and features, with the following base command line: ```bash - cargo check --quiet --workspace --message-format=json --all-targets + cargo check --quiet --workspace --message-format=json --all-targets --keep-going ``` . ''; @@ -1323,7 +1323,7 @@ description = '' Whether to show const generic parameter name inlay hints. ''; - pluginDefault = false; + pluginDefault = true; type = { kind = "boolean"; }; @@ -1332,7 +1332,7 @@ description = '' Whether to show generic lifetime parameter name inlay hints. ''; - pluginDefault = true; + pluginDefault = false; type = { kind = "boolean"; }; @@ -1649,7 +1649,7 @@ pluginDefault = null; type = { kind = "integer"; - maximum = null; + maximum = 65535; minimum = 0; }; }; @@ -1985,6 +1985,130 @@ kind = "boolean"; }; }; + "rust-analyzer.workspace.discoverConfig" = { + description = '' + Enables automatic discovery of projects using [`DiscoverWorkspaceConfig::command`]. + + [`DiscoverWorkspaceConfig`] also requires setting `progress_label` and `files_to_watch`. + `progress_label` is used for the title in progress indicators, whereas `files_to_watch` + is used to determine which build system-specific files should be watched in order to + reload rust-analyzer. + + Below is an example of a valid configuration: + ```json + "rust-analyzer.workspace.discoverConfig": { + "command": [ + "rust-project", + "develop-json", + {arg} + ], + "progressLabel": "rust-analyzer", + "filesToWatch": [ + "BUCK", + ], + } + ``` + + ## On `DiscoverWorkspaceConfig::command` + + **Warning**: This format is provisional and subject to change. + + [`DiscoverWorkspaceConfig::command`] *must* return a JSON object + corresponding to `DiscoverProjectData::Finished`: + + ```norun + #[derive(Debug, Clone, Deserialize, Serialize)] + #[serde(tag = "kind")] + #[serde(rename_all = "snake_case")] + enum DiscoverProjectData { + Finished { buildfile: Utf8PathBuf, project: ProjectJsonData }, + Error { error: String, source: Option }, + Progress { message: String }, + } + ``` + + As JSON, `DiscoverProjectData::Finished` is: + + ```json + { + // the internally-tagged representation of the enum. + "kind": "finished", + // the file used by a non-Cargo build system to define + // a package or target. + "buildfile": "rust-analyzer/BUILD", + // the contents of a rust-project.json, elided for brevity + "project": { + "sysroot": "foo", + "crates": [] + } + } + ``` + + It is encouraged, but not required, to use the other variants on + `DiscoverProjectData` to provide a more polished end-user experience. + + `DiscoverWorkspaceConfig::command` may *optionally* include an `{arg}`, + which will be substituted with the JSON-serialized form of the following + enum: + + ```norun + #[derive(PartialEq, Clone, Debug, Serialize)] + #[serde(rename_all = "camelCase")] + pub enum DiscoverArgument { + Path(AbsPathBuf), + Buildfile(AbsPathBuf), + } + ``` + + The JSON representation of `DiscoverArgument::Path` is: + + ```json + { + "path": "src/main.rs" + } + ``` + + Similarly, the JSON representation of `DiscoverArgument::Buildfile` is: + + ``` + { + "buildfile": "BUILD" + } + ``` + + `DiscoverArgument::Path` is used to find and generate a `rust-project.json`, + and therefore, a workspace, whereas `DiscoverArgument::buildfile` is used to + to update an existing workspace. As a reference for implementors, + buck2's `rust-project` will likely be useful: + https://github.com/facebook/buck2/tree/main/integrations/rust-project. + ''; + pluginDefault = null; + type = { + kind = "oneOf"; + subTypes = [ + { + kind = "submodule"; + options = { + command = { + item = { + kind = "string"; + }; + kind = "list"; + }; + filesToWatch = { + item = { + kind = "string"; + }; + kind = "list"; + }; + progressLabel = { + kind = "string"; + }; + }; + } + ]; + }; + }; "rust-analyzer.workspace.symbol.search.kind" = { description = '' Workspace symbol search kind. diff --git a/plugins/lsp/language-servers/rust-analyzer-config.nix b/plugins/lsp/language-servers/rust-analyzer-config.nix index 17362cc4..dc478d02 100644 --- a/plugins/lsp/language-servers/rust-analyzer-config.nix +++ b/plugins/lsp/language-servers/rust-analyzer-config.nix @@ -37,6 +37,16 @@ let lib.types.int else if kind == "object" then lib.types.attrsOf lib.types.anything + else if kind == "submodule" then + lib.types.submodule { + options = lib.mapAttrs ( + _: ty: + lib.mkOption { + type = mkRustAnalyzerType ty; + description = ""; + } + ) typeInfo.options; + } else if kind == "string" then lib.types.str else if kind == "boolean" then diff --git a/update-scripts/rust-analyzer.nix b/update-scripts/rust-analyzer.nix index fcad2fbd..181ad852 100644 --- a/update-scripts/rust-analyzer.nix +++ b/update-scripts/rust-analyzer.nix @@ -43,6 +43,7 @@ let maximum ? null, items ? null, anyOf ? null, + properties ? null, # Not used in the function, but anyOf values contain it enumDescriptions ? null, }@property: @@ -96,6 +97,13 @@ let kind = type; inherit minimum maximum; } + else if type == "object" && properties != null then + { + kind = "submodule"; + options = lib.mapAttrs ( + name: value: mkRustAnalyzerOptionType false "${property_name}.${name}" value + ) properties; + } else if lib.elem type [ "object"