-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Clojure language support with tree-sitter and LSP (#6988)
Current limitations: * Not able to navigate into JAR files Release Notes: - Added Clojure language support --------- Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
- Loading branch information
Showing
14 changed files
with
300 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
use anyhow::{anyhow, bail, Context, Result}; | ||
use async_trait::async_trait; | ||
pub use language::*; | ||
use lsp::LanguageServerBinary; | ||
use smol::fs::{self, File}; | ||
use std::{any::Any, env::consts, path::PathBuf}; | ||
use util::{ | ||
fs::remove_matching, | ||
github::{latest_github_release, GitHubLspBinaryVersion}, | ||
}; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct ClojureLspAdapter; | ||
|
||
#[async_trait] | ||
impl super::LspAdapter for ClojureLspAdapter { | ||
fn name(&self) -> LanguageServerName { | ||
LanguageServerName("clojure-lsp".into()) | ||
} | ||
|
||
fn short_name(&self) -> &'static str { | ||
"clojure" | ||
} | ||
|
||
async fn fetch_latest_server_version( | ||
&self, | ||
delegate: &dyn LspAdapterDelegate, | ||
) -> Result<Box<dyn 'static + Send + Any>> { | ||
let release = latest_github_release( | ||
"clojure-lsp/clojure-lsp", | ||
true, | ||
false, | ||
delegate.http_client(), | ||
) | ||
.await?; | ||
let platform = match consts::ARCH { | ||
"x86_64" => "amd64", | ||
"aarch64" => "aarch64", | ||
other => bail!("Running on unsupported platform: {other}"), | ||
}; | ||
let asset_name = format!("clojure-lsp-native-macos-{platform}.zip"); | ||
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.clone(), | ||
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 zip_path = container_dir.join(format!("clojure-lsp_{}.zip", version.name)); | ||
let folder_path = container_dir.join("bin"); | ||
let binary_path = folder_path.join("clojure-lsp"); | ||
|
||
if fs::metadata(&binary_path).await.is_err() { | ||
let mut response = delegate | ||
.http_client() | ||
.get(&version.url, Default::default(), true) | ||
.await | ||
.context("error downloading release")?; | ||
let mut file = File::create(&zip_path) | ||
.await | ||
.with_context(|| format!("failed to create file {}", zip_path.display()))?; | ||
if !response.status().is_success() { | ||
return Err(anyhow!( | ||
"download failed with status {}", | ||
response.status().to_string() | ||
))?; | ||
} | ||
futures::io::copy(response.body_mut(), &mut file).await?; | ||
|
||
fs::create_dir_all(&folder_path) | ||
.await | ||
.with_context(|| format!("failed to create directory {}", folder_path.display()))?; | ||
|
||
let unzip_status = smol::process::Command::new("unzip") | ||
.arg(&zip_path) | ||
.arg("-d") | ||
.arg(&folder_path) | ||
.output() | ||
.await? | ||
.status; | ||
if !unzip_status.success() { | ||
return Err(anyhow!("failed to unzip elixir-ls archive"))?; | ||
} | ||
|
||
remove_matching(&container_dir, |entry| entry != folder_path).await; | ||
} | ||
|
||
Ok(LanguageServerBinary { | ||
path: binary_path, | ||
arguments: vec![], | ||
}) | ||
} | ||
|
||
async fn cached_server_binary( | ||
&self, | ||
container_dir: PathBuf, | ||
_: &dyn LspAdapterDelegate, | ||
) -> Option<LanguageServerBinary> { | ||
let binary_path = container_dir.join("bin").join("clojure-lsp"); | ||
if binary_path.exists() { | ||
Some(LanguageServerBinary { | ||
path: binary_path, | ||
arguments: vec![], | ||
}) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
async fn installation_test_binary( | ||
&self, | ||
container_dir: PathBuf, | ||
) -> Option<LanguageServerBinary> { | ||
let binary_path = container_dir.join("bin").join("clojure-lsp"); | ||
if binary_path.exists() { | ||
Some(LanguageServerBinary { | ||
path: binary_path, | ||
arguments: vec!["--version".into()], | ||
}) | ||
} else { | ||
None | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
("(" @open ")" @close) | ||
("[" @open "]" @close) | ||
("{" @open "}" @close) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name = "Clojure" | ||
grammar = "clojure" | ||
path_suffixes = ["clj", "cljs"] | ||
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"] }, | ||
] | ||
word_characters = ["-"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
;; Literals | ||
|
||
(num_lit) @number | ||
|
||
[ | ||
(char_lit) | ||
(str_lit) | ||
] @string | ||
|
||
[ | ||
(bool_lit) | ||
(nil_lit) | ||
] @constant.builtin | ||
|
||
(kwd_lit) @constant | ||
|
||
;; Comments | ||
|
||
(comment) @comment | ||
|
||
;; Treat quasiquotation as operators for the purpose of highlighting. | ||
|
||
[ | ||
"'" | ||
"`" | ||
"~" | ||
"@" | ||
"~@" | ||
] @operator | ||
|
||
|
||
(list_lit | ||
. | ||
(sym_lit) @function) | ||
|
||
(list_lit | ||
. | ||
(sym_lit) @keyword | ||
(#match? @keyword | ||
"^(do|if|let|var|fn|fn*|loop*|recur|throw|try|catch|finally|set!|new|quote|->|->>)$" | ||
)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
(_ "[" "]") @indent | ||
(_ "{" "}") @indent | ||
(_ "(" ")") @indent |
Oops, something went wrong.