Merge branch 'main' into reconnections-2
This commit is contained in:
commit
969c314315
78 changed files with 2759 additions and 1281 deletions
|
@ -12,6 +12,7 @@ mod installation;
|
|||
mod json;
|
||||
mod language_plugin;
|
||||
mod python;
|
||||
mod ruby;
|
||||
mod rust;
|
||||
mod typescript;
|
||||
|
||||
|
@ -116,7 +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),
|
||||
(
|
||||
"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));
|
||||
}
|
||||
|
|
8
crates/zed/src/languages/erb/config.toml
Normal file
8
crates/zed/src/languages/erb/config.toml
Normal file
|
@ -0,0 +1,8 @@
|
|||
name = "ERB"
|
||||
path_suffixes = ["erb"]
|
||||
autoclose_before = ">})"
|
||||
brackets = [
|
||||
{ start = "<", end = ">", close = true, newline = true },
|
||||
]
|
||||
|
||||
block_comment = ["<%#", "%>"]
|
12
crates/zed/src/languages/erb/highlights.scm
Normal file
12
crates/zed/src/languages/erb/highlights.scm
Normal file
|
@ -0,0 +1,12 @@
|
|||
(comment_directive) @comment
|
||||
|
||||
[
|
||||
"<%#"
|
||||
"<%"
|
||||
"<%="
|
||||
"<%_"
|
||||
"<%-"
|
||||
"%>"
|
||||
"-%>"
|
||||
"_%>"
|
||||
] @keyword
|
7
crates/zed/src/languages/erb/injections.scm
Normal file
7
crates/zed/src/languages/erb/injections.scm
Normal file
|
@ -0,0 +1,7 @@
|
|||
((code) @content
|
||||
(#set! "language" "ruby")
|
||||
(#set! "combined"))
|
||||
|
||||
((content) @content
|
||||
(#set! "language" "html")
|
||||
(#set! "combined"))
|
|
@ -87,6 +87,25 @@ impl LspAdapter for PythonLspAdapter {
|
|||
.log_err()
|
||||
}
|
||||
|
||||
async fn process_completion(&self, item: &mut lsp::CompletionItem) {
|
||||
// Pyright assigns each completion item a `sortText` of the form `XX.YYYY.name`.
|
||||
// Where `XX` is the sorting category, `YYYY` is based on most recent usage,
|
||||
// and `name` is the symbol name itself.
|
||||
//
|
||||
// Because the the symbol name is included, there generally are not ties when
|
||||
// sorting by the `sortText`, so the symbol's fuzzy match score is not taken
|
||||
// into account. Here, we remove the symbol name from the sortText in order
|
||||
// to allow our own fuzzy score to be used to break ties.
|
||||
//
|
||||
// see https://github.com/microsoft/pyright/blob/95ef4e103b9b2f129c9320427e51b73ea7cf78bd/packages/pyright-internal/src/languageService/completionProvider.ts#LL2873
|
||||
let Some(sort_text) = &mut item.sort_text else { return };
|
||||
let mut parts = sort_text.split('.');
|
||||
let Some(first) = parts.next() else { return };
|
||||
let Some(second) = parts.next() else { return };
|
||||
let Some(_) = parts.next() else { return };
|
||||
sort_text.replace_range(first.len() + second.len() + 1.., "");
|
||||
}
|
||||
|
||||
async fn label_for_completion(
|
||||
&self,
|
||||
item: &lsp::CompletionItem,
|
||||
|
|
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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -211,21 +211,6 @@ fn init_paths() {
|
|||
std::fs::create_dir_all(&*zed::paths::LANGUAGES_DIR).expect("could not create languages path");
|
||||
std::fs::create_dir_all(&*zed::paths::DB_DIR).expect("could not create database path");
|
||||
std::fs::create_dir_all(&*zed::paths::LOGS_DIR).expect("could not create logs path");
|
||||
|
||||
// Copy setting files from legacy locations. TODO: remove this after a few releases.
|
||||
thread::spawn(|| {
|
||||
if std::fs::metadata(&*zed::paths::legacy::SETTINGS).is_ok()
|
||||
&& std::fs::metadata(&*zed::paths::SETTINGS).is_err()
|
||||
{
|
||||
std::fs::copy(&*zed::paths::legacy::SETTINGS, &*zed::paths::SETTINGS).log_err();
|
||||
}
|
||||
|
||||
if std::fs::metadata(&*zed::paths::legacy::KEYMAP).is_ok()
|
||||
&& std::fs::metadata(&*zed::paths::KEYMAP).is_err()
|
||||
{
|
||||
std::fs::copy(&*zed::paths::legacy::KEYMAP, &*zed::paths::KEYMAP).log_err();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn init_logger() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue