Fix issues with extension API that come up when moving Svelte into an extension (#9611)
We're doing it. Svelte support is moving into an extension. This PR fixes some issues that came up along the way. Notes * extensions need to be able to retrieve the path the `node` binary installed by Zed * previously we were silently swallowing any errors that occurred while loading a grammar * npm commands ran by extensions weren't run in the right directory * Tree-sitter's WASM stdlib didn't support a C function (`strncmp`) needed by the Svelte parser's external scanner * the way that LSP installation status was reported was unnecessarily complex Release Notes: - Removed built-in support for the Svelte and Gleam languages, because full support for those languages is now available via extensions. These extensions will be suggested for download when you open a `.svelte` or `.gleam` file. --------- Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
4459eacc98
commit
6ebe599c98
70 changed files with 1278 additions and 1223 deletions
|
@ -12,7 +12,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/@astrojs/language-server/bin/nodeServer.js";
|
||||
|
||||
|
@ -107,7 +107,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -7,10 +7,9 @@ use lsp::LanguageServerBinary;
|
|||
use smol::fs::{self, File};
|
||||
use std::{any::Any, env::consts, path::PathBuf, sync::Arc};
|
||||
use util::{
|
||||
async_maybe,
|
||||
fs::remove_matching,
|
||||
github::{latest_github_release, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
pub struct CLspAdapter;
|
||||
|
@ -264,7 +263,7 @@ impl super::LspAdapter for CLspAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_clangd_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -9,8 +9,7 @@ use smol::fs;
|
|||
use std::env::consts::ARCH;
|
||||
use std::ffi::OsString;
|
||||
use std::{any::Any, path::PathBuf};
|
||||
use util::async_maybe;
|
||||
use util::github::latest_github_release;
|
||||
use util::{github::latest_github_release, maybe};
|
||||
use util::{github::GitHubLspBinaryVersion, ResultExt};
|
||||
|
||||
pub struct OmniSharpAdapter;
|
||||
|
@ -115,7 +114,7 @@ impl super::LspAdapter for OmniSharpAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_binary_path = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str =
|
||||
"node_modules/vscode-langservers-extracted/bin/vscode-css-language-server";
|
||||
|
@ -105,7 +105,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -11,10 +11,9 @@ use settings::Settings;
|
|||
use smol::{fs, fs::File};
|
||||
use std::{any::Any, env::consts, ffi::OsString, path::PathBuf, sync::Arc};
|
||||
use util::{
|
||||
async_maybe,
|
||||
fs::remove_matching,
|
||||
github::{latest_github_release, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
|
||||
|
@ -207,7 +206,7 @@ impl LspAdapter for DenoLspAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/dockerfile-language-server-nodejs/bin/docker-langserver";
|
||||
|
||||
|
@ -94,7 +94,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -20,10 +20,9 @@ use std::{
|
|||
};
|
||||
use task::static_source::{Definition, TaskDefinitions};
|
||||
use util::{
|
||||
async_maybe,
|
||||
fs::remove_matching,
|
||||
github::{latest_github_release, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, JsonSchema)]
|
||||
|
@ -413,7 +412,7 @@ impl LspAdapter for NextLspAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary_next(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_binary_path = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_NAME: &str = "elm-language-server";
|
||||
const SERVER_PATH: &str = "node_modules/@elm-tooling/elm-language-server/out/node/index.js";
|
||||
|
@ -120,7 +120,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
use std::any::Any;
|
||||
use std::env::consts;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use async_compression::futures::bufread::GzipDecoder;
|
||||
use async_tar::Archive;
|
||||
use async_trait::async_trait;
|
||||
use futures::io::BufReader;
|
||||
use futures::StreamExt;
|
||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use smol::fs;
|
||||
use util::github::{latest_github_release, GitHubLspBinaryVersion};
|
||||
use util::{async_maybe, ResultExt};
|
||||
|
||||
fn server_binary_arguments() -> Vec<OsString> {
|
||||
vec!["lsp".into()]
|
||||
}
|
||||
|
||||
pub struct GleamLspAdapter;
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl LspAdapter for GleamLspAdapter {
|
||||
fn name(&self) -> LanguageServerName {
|
||||
LanguageServerName("gleam".into())
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
) -> Result<Box<dyn 'static + Send + Any>> {
|
||||
let release =
|
||||
latest_github_release("gleam-lang/gleam", true, false, delegate.http_client()).await?;
|
||||
let asset_name = format!(
|
||||
"gleam-{version}-{arch}-{os}.tar.gz",
|
||||
version = release.tag_name,
|
||||
arch = std::env::consts::ARCH,
|
||||
os = match consts::OS {
|
||||
"macos" => "apple-darwin",
|
||||
"linux" => "unknown-linux-musl",
|
||||
"windows" => "pc-windows-msvc",
|
||||
other => bail!("Running on unsupported os: {other}"),
|
||||
},
|
||||
);
|
||||
let asset = release
|
||||
.assets
|
||||
.iter()
|
||||
.find(|asset| asset.name == asset_name)
|
||||
.ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
|
||||
Ok(Box::new(GitHubLspBinaryVersion {
|
||||
name: release.tag_name,
|
||||
url: asset.browser_download_url.clone(),
|
||||
}))
|
||||
}
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
version: Box<dyn 'static + Send + Any>,
|
||||
container_dir: PathBuf,
|
||||
delegate: &dyn LspAdapterDelegate,
|
||||
) -> Result<LanguageServerBinary> {
|
||||
let version = version.downcast::<GitHubLspBinaryVersion>().unwrap();
|
||||
let binary_path = container_dir.join("gleam");
|
||||
|
||||
if fs::metadata(&binary_path).await.is_err() {
|
||||
let mut response = delegate
|
||||
.http_client()
|
||||
.get(&version.url, Default::default(), true)
|
||||
.await
|
||||
.map_err(|err| anyhow!("error downloading release: {}", err))?;
|
||||
let decompressed_bytes = GzipDecoder::new(BufReader::new(response.body_mut()));
|
||||
let archive = Archive::new(decompressed_bytes);
|
||||
archive.unpack(container_dir).await?;
|
||||
}
|
||||
|
||||
Ok(LanguageServerBinary {
|
||||
path: binary_path,
|
||||
env: None,
|
||||
arguments: server_binary_arguments(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn cached_server_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir)
|
||||
.await
|
||||
.map(|mut binary| {
|
||||
binary.arguments = vec!["--version".into()];
|
||||
binary
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
let mut last = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
last = Some(entry?.path());
|
||||
}
|
||||
|
||||
anyhow::Ok(LanguageServerBinary {
|
||||
path: last.ok_or_else(|| anyhow!("no cached binary"))?,
|
||||
env: None,
|
||||
arguments: server_binary_arguments(),
|
||||
})
|
||||
})
|
||||
.await
|
||||
.log_err()
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
name = "Gleam"
|
||||
grammar = "gleam"
|
||||
path_suffixes = ["gleam"]
|
||||
line_comments = ["// ", "/// "]
|
||||
autoclose_before = ";:.,=}])>"
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "\"", end = "\"", close = true, newline = false, not_in = ["string", "comment"] },
|
||||
]
|
|
@ -1,130 +0,0 @@
|
|||
; Comments
|
||||
(module_comment) @comment
|
||||
(statement_comment) @comment
|
||||
(comment) @comment
|
||||
|
||||
; Constants
|
||||
(constant
|
||||
name: (identifier) @constant)
|
||||
|
||||
; Modules
|
||||
(module) @module
|
||||
(import alias: (identifier) @module)
|
||||
(remote_type_identifier
|
||||
module: (identifier) @module)
|
||||
(remote_constructor_name
|
||||
module: (identifier) @module)
|
||||
((field_access
|
||||
record: (identifier) @module
|
||||
field: (label) @function)
|
||||
(#is-not? local))
|
||||
|
||||
; Functions
|
||||
(unqualified_import (identifier) @function)
|
||||
(unqualified_import "type" (type_identifier) @type)
|
||||
(unqualified_import (type_identifier) @constructor)
|
||||
(function
|
||||
name: (identifier) @function)
|
||||
(external_function
|
||||
name: (identifier) @function)
|
||||
(function_parameter
|
||||
name: (identifier) @variable.parameter)
|
||||
((function_call
|
||||
function: (identifier) @function)
|
||||
(#is-not? local))
|
||||
((binary_expression
|
||||
operator: "|>"
|
||||
right: (identifier) @function)
|
||||
(#is-not? local))
|
||||
|
||||
; "Properties"
|
||||
; Assumed to be intended to refer to a name for a field; something that comes
|
||||
; before ":" or after "."
|
||||
; e.g. record field names, tuple indices, names for named arguments, etc
|
||||
(label) @property
|
||||
(tuple_access
|
||||
index: (integer) @property)
|
||||
|
||||
; Attributes
|
||||
(attribute
|
||||
"@" @attribute
|
||||
name: (identifier) @attribute)
|
||||
|
||||
(attribute_value (identifier) @constant)
|
||||
|
||||
; Type names
|
||||
(remote_type_identifier) @type
|
||||
(type_identifier) @type
|
||||
|
||||
; Data constructors
|
||||
(constructor_name) @constructor
|
||||
|
||||
; Literals
|
||||
(string) @string
|
||||
((escape_sequence) @warning
|
||||
; Deprecated in v0.33.0-rc2:
|
||||
(#eq? @warning "\\e"))
|
||||
(escape_sequence) @string.escape
|
||||
(bit_string_segment_option) @function.builtin
|
||||
(integer) @number
|
||||
(float) @number
|
||||
|
||||
; Reserved identifiers
|
||||
; TODO: when tree-sitter supports `#any-of?` in the Rust bindings,
|
||||
; refactor this to use `#any-of?` rather than `#match?`
|
||||
((identifier) @warning
|
||||
(#match? @warning "^(auto|delegate|derive|else|implement|macro|test|echo)$"))
|
||||
|
||||
; Variables
|
||||
(identifier) @variable
|
||||
(discard) @comment.unused
|
||||
|
||||
; Keywords
|
||||
[
|
||||
(visibility_modifier) ; "pub"
|
||||
(opacity_modifier) ; "opaque"
|
||||
"as"
|
||||
"assert"
|
||||
"case"
|
||||
"const"
|
||||
; DEPRECATED: 'external' was removed in v0.30.
|
||||
"external"
|
||||
"fn"
|
||||
"if"
|
||||
"import"
|
||||
"let"
|
||||
"panic"
|
||||
"todo"
|
||||
"type"
|
||||
"use"
|
||||
] @keyword
|
||||
|
||||
; Operators
|
||||
(binary_expression
|
||||
operator: _ @operator)
|
||||
(boolean_negation "!" @operator)
|
||||
(integer_negation "-" @operator)
|
||||
|
||||
; Punctuation
|
||||
[
|
||||
"("
|
||||
")"
|
||||
"["
|
||||
"]"
|
||||
"{"
|
||||
"}"
|
||||
"<<"
|
||||
">>"
|
||||
] @punctuation.bracket
|
||||
[
|
||||
"."
|
||||
","
|
||||
;; Controversial -- maybe some are operators?
|
||||
":"
|
||||
"#"
|
||||
"="
|
||||
"->"
|
||||
".."
|
||||
"-"
|
||||
"<-"
|
||||
] @punctuation.delimiter
|
|
@ -1,3 +0,0 @@
|
|||
(_ "[" "]" @end) @indent
|
||||
(_ "{" "}" @end) @indent
|
||||
(_ "(" ")" @end) @indent
|
|
@ -1,31 +0,0 @@
|
|||
(external_type
|
||||
(visibility_modifier)? @context
|
||||
"type" @context
|
||||
(type_name) @name) @item
|
||||
|
||||
(type_definition
|
||||
(visibility_modifier)? @context
|
||||
(opacity_modifier)? @context
|
||||
"type" @context
|
||||
(type_name) @name) @item
|
||||
|
||||
(data_constructor
|
||||
(constructor_name) @name) @item
|
||||
|
||||
(data_constructor_argument
|
||||
(label) @name) @item
|
||||
|
||||
(type_alias
|
||||
(visibility_modifier)? @context
|
||||
"type" @context
|
||||
(type_name) @name) @item
|
||||
|
||||
(function
|
||||
(visibility_modifier)? @context
|
||||
"fn" @context
|
||||
name: (_) @name) @item
|
||||
|
||||
(constant
|
||||
(visibility_modifier)? @context
|
||||
"const" @context
|
||||
name: (_) @name) @item
|
|
@ -19,7 +19,7 @@ use std::{
|
|||
Arc,
|
||||
},
|
||||
};
|
||||
use util::{async_maybe, fs::remove_matching, github::latest_github_release, ResultExt};
|
||||
use util::{fs::remove_matching, github::latest_github_release, maybe, ResultExt};
|
||||
|
||||
fn server_binary_arguments() -> Vec<OsString> {
|
||||
vec!["-mode=stdio".into()]
|
||||
|
@ -368,7 +368,7 @@ impl super::LspAdapter for GoLspAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_binary_path = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str =
|
||||
"node_modules/vscode-langservers-extracted/bin/vscode-html-language-server";
|
||||
|
@ -105,7 +105,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -16,7 +16,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::{Arc, OnceLock},
|
||||
};
|
||||
use util::{async_maybe, paths, ResultExt};
|
||||
use util::{maybe, paths, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/vscode-json-languageserver/bin/vscode-json-languageserver";
|
||||
|
||||
|
@ -167,7 +167,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -22,7 +22,6 @@ mod dockerfile;
|
|||
mod elixir;
|
||||
mod elm;
|
||||
mod erlang;
|
||||
mod gleam;
|
||||
mod go;
|
||||
mod haskell;
|
||||
mod html;
|
||||
|
@ -36,7 +35,6 @@ mod purescript;
|
|||
mod python;
|
||||
mod ruby;
|
||||
mod rust;
|
||||
mod svelte;
|
||||
mod tailwind;
|
||||
mod terraform;
|
||||
mod toml;
|
||||
|
@ -83,7 +81,6 @@ pub fn init(
|
|||
tree_sitter_embedded_template::language(),
|
||||
),
|
||||
("erlang", tree_sitter_erlang::language()),
|
||||
("gleam", tree_sitter_gleam::language()),
|
||||
("glsl", tree_sitter_glsl::language()),
|
||||
("go", tree_sitter_go::language()),
|
||||
("gomod", tree_sitter_gomod::language()),
|
||||
|
@ -113,7 +110,6 @@ pub fn init(
|
|||
("ruby", tree_sitter_ruby::language()),
|
||||
("rust", tree_sitter_rust::language()),
|
||||
("scheme", tree_sitter_scheme::language()),
|
||||
("svelte", tree_sitter_svelte::language()),
|
||||
("toml", tree_sitter_toml::language()),
|
||||
("tsx", tree_sitter_typescript::language_tsx()),
|
||||
("typescript", tree_sitter_typescript::language_typescript()),
|
||||
|
@ -237,8 +233,6 @@ pub fn init(
|
|||
}
|
||||
}
|
||||
language!("erlang", vec![Arc::new(erlang::ErlangLspAdapter)]);
|
||||
|
||||
language!("gleam", vec![Arc::new(gleam::GleamLspAdapter)]);
|
||||
language!("go", vec![Arc::new(go::GoLspAdapter)]);
|
||||
language!("gomod");
|
||||
language!("gowork");
|
||||
|
@ -346,13 +340,6 @@ pub fn init(
|
|||
"yaml",
|
||||
vec![Arc::new(yaml::YamlLspAdapter::new(node_runtime.clone()))]
|
||||
);
|
||||
language!(
|
||||
"svelte",
|
||||
vec![
|
||||
Arc::new(svelte::SvelteLspAdapter::new(node_runtime.clone())),
|
||||
Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
|
||||
]
|
||||
);
|
||||
language!(
|
||||
"php",
|
||||
vec![
|
||||
|
@ -393,6 +380,11 @@ pub fn init(
|
|||
))]
|
||||
);
|
||||
language!("dart", vec![Arc::new(dart::DartLanguageServer {})]);
|
||||
|
||||
languages.register_secondary_lsp_adapter(
|
||||
"Svelte".into(),
|
||||
Arc::new(tailwind::TailwindLspAdapter::new(node_runtime.clone())),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
|
|
|
@ -8,9 +8,8 @@ use lsp::LanguageServerBinary;
|
|||
use smol::fs;
|
||||
use std::{any::Any, env::consts, path::PathBuf};
|
||||
use util::{
|
||||
async_maybe,
|
||||
github::{latest_github_release, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
@ -117,7 +116,7 @@ impl super::LspAdapter for LuaLspAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_binary_path = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -14,7 +14,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
fn intelephense_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
|
||||
vec![server_path.into(), "--stdio".into()]
|
||||
|
@ -106,7 +106,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -11,7 +11,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/.bin/prisma-language-server";
|
||||
|
||||
|
@ -94,7 +94,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -13,7 +13,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/.bin/purescript-language-server";
|
||||
|
||||
|
@ -115,7 +115,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -16,10 +16,9 @@ use task::{
|
|||
TaskVariables,
|
||||
};
|
||||
use util::{
|
||||
async_maybe,
|
||||
fs::remove_matching,
|
||||
github::{latest_github_release, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
pub struct RustLspAdapter;
|
||||
|
@ -397,7 +396,7 @@ impl ContextProvider for RustContextProvider {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -1,162 +0,0 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use futures::StreamExt;
|
||||
use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
||||
use lsp::LanguageServerBinary;
|
||||
use node_runtime::NodeRuntime;
|
||||
use serde_json::json;
|
||||
use smol::fs;
|
||||
use std::{
|
||||
any::Any,
|
||||
ffi::OsString,
|
||||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/svelte-language-server/bin/server.js";
|
||||
|
||||
fn server_binary_arguments(server_path: &Path) -> Vec<OsString> {
|
||||
vec![server_path.into(), "--stdio".into()]
|
||||
}
|
||||
|
||||
pub struct SvelteLspAdapter {
|
||||
node: Arc<dyn NodeRuntime>,
|
||||
}
|
||||
|
||||
impl SvelteLspAdapter {
|
||||
pub fn new(node: Arc<dyn NodeRuntime>) -> Self {
|
||||
SvelteLspAdapter { node }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl LspAdapter for SvelteLspAdapter {
|
||||
fn name(&self) -> LanguageServerName {
|
||||
LanguageServerName("svelte-language-server".into())
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Result<Box<dyn 'static + Any + Send>> {
|
||||
Ok(Box::new(
|
||||
self.node
|
||||
.npm_package_latest_version("svelte-language-server")
|
||||
.await?,
|
||||
) as Box<_>)
|
||||
}
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
latest_version: Box<dyn 'static + Send + Any>,
|
||||
container_dir: PathBuf,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Result<LanguageServerBinary> {
|
||||
let latest_version = latest_version.downcast::<String>().unwrap();
|
||||
let server_path = container_dir.join(SERVER_PATH);
|
||||
let package_name = "svelte-language-server";
|
||||
|
||||
let should_install_language_server = self
|
||||
.node
|
||||
.should_install_npm_package(package_name, &server_path, &container_dir, &latest_version)
|
||||
.await;
|
||||
|
||||
if should_install_language_server {
|
||||
self.node
|
||||
.npm_install_packages(&container_dir, &[(package_name, latest_version.as_str())])
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(LanguageServerBinary {
|
||||
path: self.node.binary_path().await?,
|
||||
env: None,
|
||||
arguments: server_binary_arguments(&server_path),
|
||||
})
|
||||
}
|
||||
|
||||
async fn cached_server_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
_: &dyn LspAdapterDelegate,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &*self.node).await
|
||||
}
|
||||
|
||||
async fn installation_test_binary(
|
||||
&self,
|
||||
container_dir: PathBuf,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
get_cached_server_binary(container_dir, &*self.node).await
|
||||
}
|
||||
|
||||
async fn initialization_options(
|
||||
self: Arc<Self>,
|
||||
_: &Arc<dyn LspAdapterDelegate>,
|
||||
) -> Result<Option<serde_json::Value>> {
|
||||
let config = json!({
|
||||
"inlayHints": {
|
||||
"parameterNames": {
|
||||
"enabled": "all",
|
||||
"suppressWhenArgumentMatchesName": false
|
||||
},
|
||||
"parameterTypes": {
|
||||
"enabled": true
|
||||
},
|
||||
"variableTypes": {
|
||||
"enabled": true,
|
||||
"suppressWhenTypeMatchesName": false
|
||||
},
|
||||
"propertyDeclarationTypes": {
|
||||
"enabled": true
|
||||
},
|
||||
"functionLikeReturnType": {
|
||||
"enabled": true
|
||||
},
|
||||
"enumMemberValues": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(Some(json!({
|
||||
"provideFormatter": true,
|
||||
"configuration": {
|
||||
"typescript": config,
|
||||
"javascript": config
|
||||
}
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_cached_server_binary(
|
||||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
let entry = entry?;
|
||||
if entry.file_type().await?.is_dir() {
|
||||
last_version_dir = Some(entry.path());
|
||||
}
|
||||
}
|
||||
let last_version_dir = last_version_dir.ok_or_else(|| anyhow!("no cached binary"))?;
|
||||
let server_path = last_version_dir.join(SERVER_PATH);
|
||||
if server_path.exists() {
|
||||
Ok(LanguageServerBinary {
|
||||
path: node.binary_path().await?,
|
||||
env: None,
|
||||
arguments: server_binary_arguments(&server_path),
|
||||
})
|
||||
} else {
|
||||
Err(anyhow!(
|
||||
"missing executable in directory {:?}",
|
||||
last_version_dir
|
||||
))
|
||||
}
|
||||
})
|
||||
.await
|
||||
.log_err()
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
name = "Svelte"
|
||||
grammar = "svelte"
|
||||
path_suffixes = ["svelte"]
|
||||
block_comment = ["<!-- ", " -->"]
|
||||
autoclose_before = ";:.,=}])>"
|
||||
brackets = [
|
||||
{ start = "{", end = "}", close = true, newline = true },
|
||||
{ start = "[", end = "]", close = true, newline = true },
|
||||
{ start = "(", end = ")", close = true, newline = true },
|
||||
{ start = "<", end = ">", close = false, newline = true, not_in = ["string", "comment"] },
|
||||
{ start = "\"", end = "\"", close = true, newline = false, not_in = ["string"] },
|
||||
{ start = "'", end = "'", close = true, newline = false, not_in = ["string", "comment"] },
|
||||
{ start = "`", end = "`", close = true, newline = false, not_in = ["string"] },
|
||||
{ start = "/*", end = " */", close = true, newline = false, not_in = ["string", "comment"] },
|
||||
]
|
||||
scope_opt_in_language_servers = ["tailwindcss-language-server"]
|
||||
prettier_parser_name = "svelte"
|
||||
prettier_plugins = ["prettier-plugin-svelte"]
|
||||
|
||||
[overrides.string]
|
||||
word_characters = ["-"]
|
||||
opt_into_language_servers = ["tailwindcss-language-server"]
|
|
@ -1,9 +0,0 @@
|
|||
[
|
||||
(style_element)
|
||||
(script_element)
|
||||
(element)
|
||||
(if_statement)
|
||||
(else_statement)
|
||||
(each_statement)
|
||||
(await_statement)
|
||||
] @fold
|
|
@ -1,42 +0,0 @@
|
|||
; Special identifiers
|
||||
;--------------------
|
||||
|
||||
; TODO:
|
||||
(tag_name) @tag
|
||||
(attribute_name) @property
|
||||
(erroneous_end_tag_name) @keyword
|
||||
(comment) @comment
|
||||
|
||||
[
|
||||
(attribute_value)
|
||||
(quoted_attribute_value)
|
||||
] @string
|
||||
|
||||
[
|
||||
(text)
|
||||
(raw_text_expr)
|
||||
] @none
|
||||
|
||||
[
|
||||
(special_block_keyword)
|
||||
(then)
|
||||
(as)
|
||||
] @keyword
|
||||
|
||||
[
|
||||
"{"
|
||||
"}"
|
||||
] @punctuation.bracket
|
||||
|
||||
"=" @operator
|
||||
|
||||
[
|
||||
"<"
|
||||
">"
|
||||
"</"
|
||||
"/>"
|
||||
"#"
|
||||
":"
|
||||
"/"
|
||||
"@"
|
||||
] @tag.delimiter
|
|
@ -1,8 +0,0 @@
|
|||
[
|
||||
(element)
|
||||
(if_statement)
|
||||
(each_statement)
|
||||
(await_statement)
|
||||
(script_element)
|
||||
(style_element)
|
||||
] @indent
|
|
@ -1,32 +0,0 @@
|
|||
; injections.scm
|
||||
; --------------
|
||||
((script_element
|
||||
(start_tag
|
||||
(attribute
|
||||
(quoted_attribute_value (attribute_value) @_language))?)
|
||||
(raw_text) @content)
|
||||
(#eq? @_language "")
|
||||
(#set! "language" "javascript"))
|
||||
|
||||
((script_element
|
||||
(start_tag
|
||||
(attribute
|
||||
(quoted_attribute_value (attribute_value) @_language)))
|
||||
(raw_text) @content)
|
||||
(#eq? @_language "ts")
|
||||
(#set! "language" "typescript"))
|
||||
|
||||
((script_element
|
||||
(start_tag
|
||||
(attribute
|
||||
(quoted_attribute_value (attribute_value) @_language)))
|
||||
(raw_text) @content)
|
||||
(#eq? @_language "typescript")
|
||||
(#set! "language" "typescript"))
|
||||
|
||||
(style_element
|
||||
(raw_text) @content
|
||||
(#set! "language" "css"))
|
||||
|
||||
((raw_text_expr) @content
|
||||
(#set! "language" "javascript"))
|
|
@ -1,7 +0,0 @@
|
|||
(comment) @comment
|
||||
|
||||
[
|
||||
(raw_text)
|
||||
(attribute_value)
|
||||
(quoted_attribute_value)
|
||||
] @string
|
|
@ -14,7 +14,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/.bin/tailwindcss-language-server";
|
||||
|
||||
|
@ -135,7 +135,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -7,10 +7,9 @@ use lsp::{CodeActionKind, LanguageServerBinary};
|
|||
use smol::fs::{self, File};
|
||||
use std::{any::Any, ffi::OsString, path::PathBuf};
|
||||
use util::{
|
||||
async_maybe,
|
||||
fs::remove_matching,
|
||||
github::{latest_github_release, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
fn terraform_ls_binary_arguments() -> Vec<OsString> {
|
||||
|
@ -154,7 +153,7 @@ fn build_download_url(version: String) -> Result<String> {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -6,8 +6,8 @@ use language::{LanguageServerName, LspAdapter, LspAdapterDelegate};
|
|||
use lsp::LanguageServerBinary;
|
||||
use smol::fs::{self, File};
|
||||
use std::{any::Any, path::PathBuf};
|
||||
use util::async_maybe;
|
||||
use util::github::latest_github_release;
|
||||
use util::maybe;
|
||||
use util::{github::GitHubLspBinaryVersion, ResultExt};
|
||||
|
||||
pub struct TaploLspAdapter;
|
||||
|
@ -108,7 +108,7 @@ impl LspAdapter for TaploLspAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -18,10 +18,9 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
use util::{
|
||||
async_maybe,
|
||||
fs::remove_matching,
|
||||
github::{build_tarball_url, GitHubLspBinaryVersion},
|
||||
ResultExt,
|
||||
maybe, ResultExt,
|
||||
};
|
||||
|
||||
fn typescript_server_binary_arguments(server_path: &Path) -> Vec<OsString> {
|
||||
|
@ -199,7 +198,7 @@ async fn get_cached_ts_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let old_server_path = container_dir.join(TypeScriptLspAdapter::OLD_SERVER_PATH);
|
||||
let new_server_path = container_dir.join(TypeScriptLspAdapter::NEW_SERVER_PATH);
|
||||
if new_server_path.exists() {
|
||||
|
@ -378,7 +377,7 @@ async fn get_cached_eslint_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
// This is unfortunate but we don't know what the version is to build a path directly
|
||||
let mut dir = fs::read_dir(&container_dir).await?;
|
||||
let first = dir.next().await.ok_or(anyhow!("missing first file"))??;
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
pub struct VueLspVersion {
|
||||
vue_version: String,
|
||||
|
@ -211,7 +211,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: Arc<dyn NodeRuntime>,
|
||||
) -> Option<(LanguageServerBinary, TypescriptPath)> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -15,7 +15,7 @@ use std::{
|
|||
path::{Path, PathBuf},
|
||||
sync::Arc,
|
||||
};
|
||||
use util::{async_maybe, ResultExt};
|
||||
use util::{maybe, ResultExt};
|
||||
|
||||
const SERVER_PATH: &str = "node_modules/yaml-language-server/bin/yaml-language-server";
|
||||
|
||||
|
@ -110,7 +110,7 @@ async fn get_cached_server_binary(
|
|||
container_dir: PathBuf,
|
||||
node: &dyn NodeRuntime,
|
||||
) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_version_dir = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
|
@ -9,8 +9,8 @@ use lsp::LanguageServerBinary;
|
|||
use smol::fs;
|
||||
use std::env::consts::{ARCH, OS};
|
||||
use std::{any::Any, path::PathBuf};
|
||||
use util::async_maybe;
|
||||
use util::github::latest_github_release;
|
||||
use util::maybe;
|
||||
use util::{github::GitHubLspBinaryVersion, ResultExt};
|
||||
|
||||
pub struct ZlsAdapter;
|
||||
|
@ -113,7 +113,7 @@ impl LspAdapter for ZlsAdapter {
|
|||
}
|
||||
|
||||
async fn get_cached_server_binary(container_dir: PathBuf) -> Option<LanguageServerBinary> {
|
||||
async_maybe!({
|
||||
maybe!(async {
|
||||
let mut last_binary_path = None;
|
||||
let mut entries = fs::read_dir(&container_dir).await?;
|
||||
while let Some(entry) = entries.next().await {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue