diff --git a/crates/languages/src/yaml.rs b/crates/languages/src/yaml.rs index 01b071d79c..0dcee3416a 100644 --- a/crates/languages/src/yaml.rs +++ b/crates/languages/src/yaml.rs @@ -7,6 +7,7 @@ use language::{ }; use lsp::LanguageServerBinary; use node_runtime::NodeRuntime; +use project::project_settings::ProjectSettings; use serde_json::Value; use settings::{Settings, SettingsLocation}; use smol::fs; @@ -16,7 +17,7 @@ use std::{ path::{Path, PathBuf}, sync::Arc, }; -use util::{maybe, ResultExt}; +use util::{maybe, merge_json_value_into, ResultExt}; const SERVER_PATH: &str = "node_modules/yaml-language-server/bin/yaml-language-server"; @@ -29,6 +30,7 @@ pub struct YamlLspAdapter { } impl YamlLspAdapter { + const SERVER_NAME: &'static str = "yaml-language-server"; pub fn new(node: Arc) -> Self { YamlLspAdapter { node } } @@ -37,7 +39,40 @@ impl YamlLspAdapter { #[async_trait(?Send)] impl LspAdapter for YamlLspAdapter { fn name(&self) -> LanguageServerName { - LanguageServerName("yaml-language-server".into()) + LanguageServerName(Self::SERVER_NAME.into()) + } + + async fn check_if_user_installed( + &self, + _delegate: &dyn LspAdapterDelegate, + cx: &AsyncAppContext, + ) -> Option { + let configured_binary = cx + .update(|cx| { + ProjectSettings::get_global(cx) + .lsp + .get(Self::SERVER_NAME) + .and_then(|s| s.binary.clone()) + }) + .ok()??; + + let path = if let Some(configured_path) = configured_binary.path.map(PathBuf::from) { + configured_path + } else { + self.node.binary_path().await.ok()? + }; + + let arguments = configured_binary + .arguments + .unwrap_or_default() + .iter() + .map(|arg| arg.into()) + .collect(); + Some(LanguageServerBinary { + path, + arguments, + env: None, + }) } async fn fetch_latest_server_version( @@ -109,15 +144,18 @@ impl LspAdapter for YamlLspAdapter { .language(Some("YAML")) .tab_size })?; + let mut options = serde_json::json!({"[yaml]": {"editor.tabSize": tab_size}}); - Ok(serde_json::json!({ - "yaml": { - "keyOrdering": false - }, - "[yaml]": { - "editor.tabSize": tab_size - } - })) + let project_options = cx.update(|cx| { + ProjectSettings::get_global(cx) + .lsp + .get(Self::SERVER_NAME) + .and_then(|s| s.initialization_options.clone()) + })?; + if let Some(override_options) = project_options { + merge_json_value_into(override_options, &mut options); + } + Ok(options) } } diff --git a/docs/src/languages/yaml.md b/docs/src/languages/yaml.md index 36895a94c1..5ef614394c 100644 --- a/docs/src/languages/yaml.md +++ b/docs/src/languages/yaml.md @@ -4,3 +4,58 @@ YAML support is available natively in Zed. - Tree Sitter: [zed-industries/tree-sitter-yaml](https://github.com/zed-industries/tree-sitter-yaml) - Language Server: [redhat-developer/yaml-language-server](https://github.com/redhat-developer/yaml-language-server) + +## Configuration + +You can configure various [yaml-language-server settings](https://github.com/redhat-developer/yaml-language-server?tab=readme-ov-file#language-server-settings) by adding them to your Zed settings.json in a `yaml-language-server` block under the `lsp` key. For example: + +```json + "lsp": { + "yaml-language-server": { + "initialization_options": { + "yaml": { + "keyOrdering": true, + "format": { + "singleQuote": true + }, + "schemas": { + "http://json.schemastore.org/composer": ["/*"], + "../relative/path/schema.json": ["/config*.yaml"] + } + } + } + } + } +``` + +Note, settings keys must be nested, so `yaml.keyOrdering` becomes `{"yaml": { "keyOrdering": true }}`. + +## Schemas + +By default yaml-language-server will attempt to determine the correct schema for a given yaml file and retrieve the appropriate JSON Schema from [Json Schema Store]. + +You can override this by [using an inlined schema] reference via a modeline comment at the top of your yaml file: + +```yaml +# yaml-language-server: $schema=https://json.schemastore.org/github-action.json +name: Issue Assignment +on: + issues: + types: [oppened] +``` + +You can disable this functionality entirely if desired: + +```json + "lsp": { + "yaml-language-server": { + "initialization_options": { + "yaml": { + "schemaStore": { + "enable": false + } + } + } + } + } +```