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:
Max Brunsfeld 2024-03-22 17:29:06 -07:00 committed by GitHub
parent 4459eacc98
commit 6ebe599c98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
70 changed files with 1278 additions and 1223 deletions

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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()
}

View file

@ -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"] },
]

View file

@ -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

View file

@ -1,3 +0,0 @@
(_ "[" "]" @end) @indent
(_ "{" "}" @end) @indent
(_ "(" ")" @end) @indent

View file

@ -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

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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"))]

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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()
}

View file

@ -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"]

View file

@ -1,9 +0,0 @@
[
(style_element)
(script_element)
(element)
(if_statement)
(else_statement)
(each_statement)
(await_statement)
] @fold

View file

@ -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

View file

@ -1,8 +0,0 @@
[
(element)
(if_statement)
(each_statement)
(await_statement)
(script_element)
(style_element)
] @indent

View file

@ -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"))

View file

@ -1,7 +0,0 @@
(comment) @comment
[
(raw_text)
(attribute_value)
(quoted_attribute_value)
] @string

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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"))??;

View 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 {

View file

@ -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 {

View file

@ -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 {