mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-08 15:27:06 +03:00
Merge pull request #1895 from zed-industries/ruby-solargraph
Add ruby LSP support via SolarGraph
This commit is contained in:
commit
0dfacd7ffa
@ -12,6 +12,7 @@ mod installation;
|
||||
mod json;
|
||||
mod language_plugin;
|
||||
mod python;
|
||||
mod ruby;
|
||||
mod rust;
|
||||
mod typescript;
|
||||
|
||||
@ -116,8 +117,16 @@ pub async fn init(languages: Arc<LanguageRegistry>, _executor: Arc<Background>)
|
||||
tree_sitter_html::language(),
|
||||
Some(CachedLspAdapter::new(html::HtmlLspAdapter).await),
|
||||
),
|
||||
("ruby", tree_sitter_ruby::language(), None),
|
||||
("erb", tree_sitter_embedded_template::language(), None),
|
||||
(
|
||||
"ruby",
|
||||
tree_sitter_ruby::language(),
|
||||
Some(CachedLspAdapter::new(ruby::RubyLanguageServer).await),
|
||||
),
|
||||
(
|
||||
"erb",
|
||||
tree_sitter_embedded_template::language(),
|
||||
Some(CachedLspAdapter::new(ruby::RubyLanguageServer).await),
|
||||
),
|
||||
] {
|
||||
languages.add(language(name, grammar, lsp_adapter));
|
||||
}
|
||||
|
145
crates/zed/src/languages/ruby.rs
Normal file
145
crates/zed/src/languages/ruby.rs
Normal file
@ -0,0 +1,145 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use client::http::HttpClient;
|
||||
use language::{LanguageServerName, LspAdapter};
|
||||
use std::{any::Any, path::PathBuf, sync::Arc};
|
||||
|
||||
pub struct RubyLanguageServer;
|
||||
|
||||
#[async_trait]
|
||||
impl LspAdapter for RubyLanguageServer {
|
||||
async fn name(&self) -> LanguageServerName {
|
||||
LanguageServerName("solargraph".into())
|
||||
}
|
||||
|
||||
async fn server_args(&self) -> Vec<String> {
|
||||
vec!["stdio".into()]
|
||||
}
|
||||
|
||||
async fn fetch_latest_server_version(
|
||||
&self,
|
||||
_: Arc<dyn HttpClient>,
|
||||
) -> Result<Box<dyn 'static + Any + Send>> {
|
||||
Ok(Box::new(()))
|
||||
}
|
||||
|
||||
async fn fetch_server_binary(
|
||||
&self,
|
||||
_version: Box<dyn 'static + Send + Any>,
|
||||
_: Arc<dyn HttpClient>,
|
||||
_container_dir: PathBuf,
|
||||
) -> Result<PathBuf> {
|
||||
Err(anyhow!("solargraph must be installed manually"))
|
||||
}
|
||||
|
||||
async fn cached_server_binary(&self, _container_dir: PathBuf) -> Option<PathBuf> {
|
||||
Some("solargraph".into())
|
||||
}
|
||||
|
||||
async fn label_for_completion(
|
||||
&self,
|
||||
item: &lsp::CompletionItem,
|
||||
language: &Arc<language::Language>,
|
||||
) -> Option<language::CodeLabel> {
|
||||
let label = &item.label;
|
||||
let grammar = language.grammar()?;
|
||||
let highlight_id = match item.kind? {
|
||||
lsp::CompletionItemKind::METHOD => grammar.highlight_id_for_name("function.method")?,
|
||||
lsp::CompletionItemKind::CONSTANT => grammar.highlight_id_for_name("constant")?,
|
||||
lsp::CompletionItemKind::CLASS | lsp::CompletionItemKind::MODULE => {
|
||||
grammar.highlight_id_for_name("type")?
|
||||
}
|
||||
lsp::CompletionItemKind::KEYWORD => {
|
||||
if label.starts_with(":") {
|
||||
grammar.highlight_id_for_name("string.special.symbol")?
|
||||
} else {
|
||||
grammar.highlight_id_for_name("keyword")?
|
||||
}
|
||||
}
|
||||
lsp::CompletionItemKind::VARIABLE => {
|
||||
if label.starts_with("@") {
|
||||
grammar.highlight_id_for_name("property")?
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
};
|
||||
Some(language::CodeLabel {
|
||||
text: label.clone(),
|
||||
runs: vec![(0..label.len(), highlight_id)],
|
||||
filter_range: 0..label.len(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn label_for_symbol(
|
||||
&self,
|
||||
label: &str,
|
||||
kind: lsp::SymbolKind,
|
||||
language: &Arc<language::Language>,
|
||||
) -> Option<language::CodeLabel> {
|
||||
let grammar = language.grammar()?;
|
||||
match kind {
|
||||
lsp::SymbolKind::METHOD => {
|
||||
let mut parts = label.split('#');
|
||||
let classes = parts.next()?;
|
||||
let method = parts.next()?;
|
||||
if parts.next().is_some() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let class_id = grammar.highlight_id_for_name("type")?;
|
||||
let method_id = grammar.highlight_id_for_name("function.method")?;
|
||||
|
||||
let mut ix = 0;
|
||||
let mut runs = Vec::new();
|
||||
for (i, class) in classes.split("::").enumerate() {
|
||||
if i > 0 {
|
||||
ix += 2;
|
||||
}
|
||||
let end_ix = ix + class.len();
|
||||
runs.push((ix..end_ix, class_id));
|
||||
ix = end_ix;
|
||||
}
|
||||
|
||||
ix += 1;
|
||||
let end_ix = ix + method.len();
|
||||
runs.push((ix..end_ix, method_id));
|
||||
Some(language::CodeLabel {
|
||||
text: label.to_string(),
|
||||
runs,
|
||||
filter_range: 0..label.len(),
|
||||
})
|
||||
}
|
||||
lsp::SymbolKind::CONSTANT => {
|
||||
let constant_id = grammar.highlight_id_for_name("constant")?;
|
||||
Some(language::CodeLabel {
|
||||
text: label.to_string(),
|
||||
runs: vec![(0..label.len(), constant_id)],
|
||||
filter_range: 0..label.len(),
|
||||
})
|
||||
}
|
||||
lsp::SymbolKind::CLASS | lsp::SymbolKind::MODULE => {
|
||||
let class_id = grammar.highlight_id_for_name("type")?;
|
||||
|
||||
let mut ix = 0;
|
||||
let mut runs = Vec::new();
|
||||
for (i, class) in label.split("::").enumerate() {
|
||||
if i > 0 {
|
||||
ix += "::".len();
|
||||
}
|
||||
let end_ix = ix + class.len();
|
||||
runs.push((ix..end_ix, class_id));
|
||||
ix = end_ix;
|
||||
}
|
||||
|
||||
Some(language::CodeLabel {
|
||||
text: label.to_string(),
|
||||
runs,
|
||||
filter_range: 0..label.len(),
|
||||
})
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user