diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 5d37c219dd25..c7a3e1ccba6e 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -95,6 +95,7 @@ pub struct LanguageServerConfiguration { #[serde(default)] #[serde(skip_serializing_if = "Vec::is_empty")] pub args: Vec, + pub language_id: Option, } #[derive(Debug, Serialize, Deserialize)] diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs index c7202febadb0..c376aefaa5af 100644 --- a/helix-term/src/application.rs +++ b/helix-term/src/application.rs @@ -358,12 +358,8 @@ impl Application { // trigger textDocument/didOpen for docs that are already open for doc in docs { - // TODO: extract and share with editor.open - let language_id = doc - .language() - .and_then(|s| s.split('.').last()) // source.rust - .map(ToOwned::to_owned) - .unwrap_or_default(); + let language_id = + doc.language_id().map(ToOwned::to_owned).unwrap_or_default(); tokio::spawn(language_server.text_document_did_open( doc.url().unwrap(), diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs index 9652d7b3cd51..579349ee5d69 100644 --- a/helix-view/src/document.rs +++ b/helix-view/src/document.rs @@ -844,6 +844,24 @@ impl Document { .map(|language| language.scope.as_str()) } + /// Language ID for the document. Either the `language-id` from the + /// `language-server` configuration, or the document language if no + /// `language-id` has been specified. + pub fn language_id(&self) -> Option<&str> { + self.language + .as_ref() + .and_then(|config| config.language_server.as_ref()) + .and_then(|lsp_config| lsp_config.language_id.as_ref()) + .map_or_else( + || { + self.language() + .and_then(|s| s.rsplit_once('.')) + .map(|(_, language_id)| language_id) + }, + |language_id| Some(language_id.as_str()), + ) + } + /// Corresponding [`LanguageConfiguration`]. pub fn language_config(&self) -> Option<&LanguageConfiguration> { self.language.as_deref() diff --git a/helix-view/src/editor.rs b/helix-view/src/editor.rs index f4b0f73e72a8..7406b4758499 100644 --- a/helix-view/src/editor.rs +++ b/helix-view/src/editor.rs @@ -307,11 +307,8 @@ impl Editor { if let Some(language_server) = doc.language_server() { tokio::spawn(language_server.text_document_did_close(doc.identifier())); } - let language_id = doc - .language() - .and_then(|s| s.split('.').last()) // source.rust - .map(ToOwned::to_owned) - .unwrap_or_default(); + + let language_id = doc.language_id().map(ToOwned::to_owned).unwrap_or_default(); // TODO: this now races with on_init code if the init happens too quickly tokio::spawn(language_server.text_document_did_open( diff --git a/languages.toml b/languages.toml index 2c870ab24c0d..78447578668e 100644 --- a/languages.toml +++ b/languages.toml @@ -128,7 +128,7 @@ roots = [] comment-token = "//" # TODO: highlights-jsx, highlights-params -language-server = { command = "typescript-language-server", args = ["--stdio"] } +language-server = { command = "typescript-language-server", args = ["--stdio"], language-id = "javascript" } indent = { tab-width = 2, unit = " " } [[language]] @@ -140,7 +140,7 @@ shebangs = [] roots = [] # TODO: highlights-jsx, highlights-params -language-server = { command = "typescript-language-server", args = ["--stdio"] } +language-server = { command = "typescript-language-server", args = ["--stdio"], language-id = "typescript"} indent = { tab-width = 2, unit = " " } [[language]] @@ -151,7 +151,7 @@ file-types = ["tsx"] roots = [] # TODO: highlights-jsx, highlights-params -language-server = { command = "typescript-language-server", args = ["--stdio"] } +language-server = { command = "typescript-language-server", args = ["--stdio"], language-id = "typescriptreact" } indent = { tab-width = 2, unit = " " } [[language]]