elixir: Improve ElixirLS LSP autocomplete to show labelDetails information (#21666)
Closes https://github.com/zed-industries/zed/issues/19688 Release Notes: - Improved ElixirLS LSP autocomplete to show module, function and struct field details   
This commit is contained in:
parent
6a37307302
commit
74d7ce2d2b
3 changed files with 75 additions and 15 deletions
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -16139,7 +16139,7 @@ dependencies = [
|
||||||
name = "zed_elixir"
|
name = "zed_elixir"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zed_extension_api 0.1.0",
|
"zed_extension_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -16183,6 +16183,17 @@ dependencies = [
|
||||||
"wit-bindgen",
|
"wit-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zed_extension_api"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9fd16b8b30a9dc920fc1678ff852f696b5bdf5b5843bc745a128be0aac29859e"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"wit-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zed_glsl"
|
name = "zed_glsl"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -13,4 +13,4 @@ path = "src/elixir.rs"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
zed_extension_api = "0.1.0"
|
zed_extension_api = "0.2.0"
|
||||||
|
|
|
@ -107,36 +107,85 @@ impl ElixirLs {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn label_for_completion(&self, completion: Completion) -> Option<CodeLabel> {
|
pub fn label_for_completion(&self, completion: Completion) -> Option<CodeLabel> {
|
||||||
|
let name = &completion.label;
|
||||||
|
let detail = completion
|
||||||
|
.detail
|
||||||
|
.filter(|detail| detail != "alias")
|
||||||
|
.map(|detail| format!(": {detail}"))
|
||||||
|
.unwrap_or("".to_string());
|
||||||
|
|
||||||
|
let detail_span = CodeLabelSpan::literal(detail, Some("comment.unused".to_string()));
|
||||||
|
|
||||||
match completion.kind? {
|
match completion.kind? {
|
||||||
CompletionKind::Module
|
CompletionKind::Module | CompletionKind::Class | CompletionKind::Struct => {
|
||||||
| CompletionKind::Class
|
|
||||||
| CompletionKind::Interface
|
|
||||||
| CompletionKind::Struct => {
|
|
||||||
let name = completion.label;
|
|
||||||
let defmodule = "defmodule ";
|
let defmodule = "defmodule ";
|
||||||
let code = format!("{defmodule}{name}");
|
let alias = completion
|
||||||
|
.label_details
|
||||||
|
.and_then(|details| details.description)
|
||||||
|
.filter(|description| description.starts_with("alias"))
|
||||||
|
.map(|description| format!(" ({description})"))
|
||||||
|
.unwrap_or("".to_string());
|
||||||
|
|
||||||
|
let code = format!("{defmodule}{name}{alias}");
|
||||||
|
let name_start = defmodule.len();
|
||||||
|
let name_end = name_start + name.len();
|
||||||
|
|
||||||
Some(CodeLabel {
|
Some(CodeLabel {
|
||||||
code,
|
code,
|
||||||
spans: vec![CodeLabelSpan::code_range(
|
spans: vec![
|
||||||
defmodule.len()..defmodule.len() + name.len(),
|
CodeLabelSpan::code_range(name_start..name_end),
|
||||||
)],
|
detail_span,
|
||||||
|
CodeLabelSpan::code_range(name_end..(name_end + alias.len())),
|
||||||
|
],
|
||||||
filter_range: (0..name.len()).into(),
|
filter_range: (0..name.len()).into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
CompletionKind::Interface => Some(CodeLabel {
|
||||||
|
code: name.to_string(),
|
||||||
|
spans: vec![CodeLabelSpan::code_range(0..name.len()), detail_span],
|
||||||
|
filter_range: (0..name.len()).into(),
|
||||||
|
}),
|
||||||
|
CompletionKind::Field => Some(CodeLabel {
|
||||||
|
code: name.to_string(),
|
||||||
|
spans: vec![
|
||||||
|
CodeLabelSpan::literal(name, Some("function".to_string())),
|
||||||
|
detail_span,
|
||||||
|
],
|
||||||
|
filter_range: (0..name.len()).into(),
|
||||||
|
}),
|
||||||
CompletionKind::Function | CompletionKind::Constant => {
|
CompletionKind::Function | CompletionKind::Constant => {
|
||||||
let name = completion.label;
|
let detail = completion
|
||||||
|
.label_details
|
||||||
|
.clone()
|
||||||
|
.and_then(|details| details.detail)
|
||||||
|
.unwrap_or("".to_string());
|
||||||
|
|
||||||
|
let description = completion
|
||||||
|
.label_details
|
||||||
|
.clone()
|
||||||
|
.and_then(|details| details.description)
|
||||||
|
.map(|description| format!(" ({description})"))
|
||||||
|
.unwrap_or("".to_string());
|
||||||
|
|
||||||
let def = "def ";
|
let def = "def ";
|
||||||
let code = format!("{def}{name}");
|
let code = format!("{def}{name}{detail}{description}");
|
||||||
|
|
||||||
|
let name_start = def.len();
|
||||||
|
let name_end = name_start + name.len();
|
||||||
|
let detail_end = name_end + detail.len();
|
||||||
|
let description_end = detail_end + description.len();
|
||||||
|
|
||||||
Some(CodeLabel {
|
Some(CodeLabel {
|
||||||
code,
|
code,
|
||||||
spans: vec![CodeLabelSpan::code_range(def.len()..def.len() + name.len())],
|
spans: vec![
|
||||||
|
CodeLabelSpan::code_range(name_start..name_end),
|
||||||
|
CodeLabelSpan::code_range(name_end..detail_end),
|
||||||
|
CodeLabelSpan::code_range(detail_end..description_end),
|
||||||
|
],
|
||||||
filter_range: (0..name.len()).into(),
|
filter_range: (0..name.len()).into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
CompletionKind::Operator => {
|
CompletionKind::Operator => {
|
||||||
let name = completion.label;
|
|
||||||
let def_a = "def a ";
|
let def_a = "def a ";
|
||||||
let code = format!("{def_a}{name} b");
|
let code = format!("{def_a}{name} b");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue