Extract lua language support into an extension (#10437)

Release Notes:

- Extracted lua language support into an extension, and improved Lua
highlighting and completion label styling.

---------

Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
Max Brunsfeld
2024-04-11 11:32:10 -07:00
committed by GitHub
co-authored by Marshall
parent c6028f6651
commit 176f440158
16 changed files with 265 additions and 225 deletions
-3
View File
@@ -18,7 +18,6 @@ mod deno;
mod elixir;
mod go;
mod json;
mod lua;
mod nu;
mod ocaml;
mod python;
@@ -69,7 +68,6 @@ pub fn init(
("heex", tree_sitter_heex::language()),
("jsdoc", tree_sitter_jsdoc::language()),
("json", tree_sitter_json::language()),
("lua", tree_sitter_lua::language()),
("markdown", tree_sitter_markdown::language()),
("nix", tree_sitter_nix::language()),
("nu", tree_sitter_nu::language()),
@@ -280,7 +278,6 @@ pub fn init(
language!("scheme");
language!("racket");
language!("regex");
language!("lua", vec![Arc::new(lua::LuaLspAdapter)]);
language!(
"yaml",
vec![Arc::new(yaml::YamlLspAdapter::new(node_runtime.clone()))]
-146
View File
@@ -1,146 +0,0 @@
use anyhow::{anyhow, bail, Result};
use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use async_trait::async_trait;
use futures::{io::BufReader, StreamExt};
use language::{LanguageServerName, LspAdapterDelegate};
use lsp::LanguageServerBinary;
use smol::fs;
use std::{any::Any, env::consts, path::PathBuf};
use util::{
github::{latest_github_release, GitHubLspBinaryVersion},
maybe, ResultExt,
};
#[derive(Copy, Clone)]
pub struct LuaLspAdapter;
#[async_trait(?Send)]
impl super::LspAdapter for LuaLspAdapter {
fn name(&self) -> LanguageServerName {
LanguageServerName("lua-language-server".into())
}
async fn fetch_latest_server_version(
&self,
delegate: &dyn LspAdapterDelegate,
) -> Result<Box<dyn 'static + Send + Any>> {
let os = match consts::OS {
"macos" => "darwin",
"linux" => "linux",
"windows" => "win32",
other => bail!("Running on unsupported os: {other}"),
};
let platform = match consts::ARCH {
"x86_64" => "x64",
"aarch64" => "arm64",
other => bail!("Running on unsupported platform: {other}"),
};
let release = latest_github_release(
"LuaLS/lua-language-server",
true,
false,
delegate.http_client(),
)
.await?;
let version = &release.tag_name;
let asset_name = format!("lua-language-server-{version}-{os}-{platform}.tar.gz");
let asset = release
.assets
.iter()
.find(|asset| asset.name == asset_name)
.ok_or_else(|| anyhow!("no asset found matching {:?}", asset_name))?;
let version = GitHubLspBinaryVersion {
name: release.tag_name,
url: asset.browser_download_url.clone(),
};
Ok(Box::new(version) as Box<_>)
}
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("bin/lua-language-server");
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?;
}
// todo("windows")
#[cfg(not(windows))]
{
fs::set_permissions(
&binary_path,
<fs::Permissions as fs::unix::PermissionsExt>::from_mode(0o755),
)
.await?;
}
Ok(LanguageServerBinary {
path: binary_path,
env: None,
arguments: Vec::new(),
})
}
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> {
maybe!(async {
let mut last_binary_path = 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_file()
&& entry
.file_name()
.to_str()
.map_or(false, |name| name == "lua-language-server")
{
last_binary_path = Some(entry.path());
}
}
if let Some(path) = last_binary_path {
Ok(LanguageServerBinary {
path,
env: None,
arguments: Vec::new(),
})
} else {
Err(anyhow!("no cached binary"))
}
})
.await
.log_err()
}
-3
View File
@@ -1,3 +0,0 @@
("[" @open "]" @close)
("{" @open "}" @close)
("(" @open ")" @close)
-13
View File
@@ -1,13 +0,0 @@
name = "Lua"
grammar = "lua"
path_suffixes = ["lua"]
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"] },
{ start = "'", end = "'", close = false, newline = false, not_in = ["string"] },
]
collapsed_placeholder = "--[ ... ]--"
-10
View File
@@ -1,10 +0,0 @@
(
(comment)* @context
.
(function_declaration
"function" @name
name: (_) @name
(comment)* @collapse
body: (block) @collapse
) @item
)
-198
View File
@@ -1,198 +0,0 @@
;; Keywords
"return" @keyword
[
"goto"
"in"
"local"
] @keyword
(break_statement) @keyword
(do_statement
[
"do"
"end"
] @keyword)
(while_statement
[
"while"
"do"
"end"
] @keyword)
(repeat_statement
[
"repeat"
"until"
] @keyword)
(if_statement
[
"if"
"elseif"
"else"
"then"
"end"
] @keyword)
(elseif_statement
[
"elseif"
"then"
"end"
] @keyword)
(else_statement
[
"else"
"end"
] @keyword)
(for_statement
[
"for"
"do"
"end"
] @keyword)
(function_declaration
[
"function"
"end"
] @keyword)
(function_definition
[
"function"
"end"
] @keyword)
;; Operators
[
"and"
"not"
"or"
] @operator
[
"+"
"-"
"*"
"/"
"%"
"^"
"#"
"=="
"~="
"<="
">="
"<"
">"
"="
"&"
"~"
"|"
"<<"
">>"
"//"
".."
] @operator
;; Punctuations
[
";"
":"
","
"."
] @punctuation.delimiter
;; Brackets
[
"("
")"
"["
"]"
"{"
"}"
] @punctuation.bracket
;; Variables
(identifier) @variable
((identifier) @variable.special
(#eq? @variable.special "self"))
(variable_list
attribute: (attribute
(["<" ">"] @punctuation.bracket
(identifier) @attribute)))
;; Constants
((identifier) @constant
(#match? @constant "^[A-Z][A-Z_0-9]*$"))
(vararg_expression) @constant
(nil) @constant.builtin
[
(false)
(true)
] @boolean
;; Tables
(field name: (identifier) @field)
(dot_index_expression field: (identifier) @field)
(table_constructor
[
"{"
"}"
] @constructor)
;; Functions
(parameters (identifier) @parameter)
(function_call
name: [
(identifier) @function
(dot_index_expression field: (identifier) @function)
])
(function_declaration
name: [
(identifier) @function.definition
(dot_index_expression field: (identifier) @function.definition)
])
(method_index_expression method: (identifier) @method)
(function_call
(identifier) @function.builtin
(#any-of? @function.builtin
;; built-in functions in Lua 5.1
"assert" "collectgarbage" "dofile" "error" "getfenv" "getmetatable" "ipairs"
"load" "loadfile" "loadstring" "module" "next" "pairs" "pcall" "print"
"rawequal" "rawget" "rawset" "require" "select" "setfenv" "setmetatable"
"tonumber" "tostring" "type" "unpack" "xpcall"))
;; Others
(comment) @comment
(hash_bang_line) @preproc
(number) @number
(string) @string
-10
View File
@@ -1,10 +0,0 @@
(if_statement "end" @end) @indent
(do_statement "end" @end) @indent
(while_statement "end" @end) @indent
(for_statement "end" @end) @indent
(repeat_statement "until" @end) @indent
(function_declaration "end" @end) @indent
(_ "[" "]" @end) @indent
(_ "{" "}" @end) @indent
(_ "(" ")" @end) @indent
-3
View File
@@ -1,3 +0,0 @@
(function_declaration
"function" @context
name: (_) @name) @item