Skip to content

Commit 6db7c41

Browse files
committed
support callsnippet
1 parent 805f713 commit 6db7c41

File tree

4 files changed

+123
-13
lines changed

4 files changed

+123
-13
lines changed

crates/emmylua_ls/src/handlers/completion/add_completions/add_decl_completion.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ use emmylua_code_analysis::{DbIndex, LuaDeclId, LuaSemanticDeclId, LuaType};
22
use lsp_types::CompletionItem;
33

44
use crate::handlers::completion::{
5-
completion_builder::CompletionBuilder, completion_data::CompletionData,
5+
add_completions::get_function_snippet, completion_builder::CompletionBuilder,
6+
completion_data::CompletionData,
67
};
78

89
use super::{
@@ -19,6 +20,7 @@ pub fn add_decl_completion(
1920
check_visibility(builder, property_owner.clone())?;
2021

2122
let overload_count = count_function_overloads(builder.semantic_model.get_db(), typ);
23+
2224
let mut completion_item = CompletionItem {
2325
label: name.to_string(),
2426
kind: Some(get_completion_kind(typ)),
@@ -34,6 +36,13 @@ pub fn add_decl_completion(
3436
completion_item.deprecated = Some(true);
3537
}
3638

39+
if builder.support_snippets(typ) {
40+
if let Some(snippet) = get_function_snippet(builder, name, typ, CallDisplay::None) {
41+
completion_item.insert_text = Some(snippet);
42+
completion_item.insert_text_format = Some(lsp_types::InsertTextFormat::SNIPPET);
43+
}
44+
}
45+
3746
builder.add_completion_item(completion_item)?;
3847
Some(())
3948
}

crates/emmylua_ls/src/handlers/completion/add_completions/add_member_completion.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use emmylua_parser::{
99
use lsp_types::CompletionItem;
1010

1111
use crate::handlers::completion::{
12-
completion_builder::CompletionBuilder, completion_data::CompletionData,
13-
providers::get_function_remove_nil,
12+
add_completions::get_function_snippet, completion_builder::CompletionBuilder,
13+
completion_data::CompletionData, providers::get_function_remove_nil,
1414
};
1515

1616
use super::{
@@ -40,6 +40,7 @@ pub fn add_member_completion(
4040
}
4141

4242
let member_key = &member_info.key;
43+
let mut can_add_snippet = true;
4344
let label = match status {
4445
CompletionTriggerStatus::Dot => match member_key {
4546
LuaMemberKey::Name(name) => name.to_string(),
@@ -70,15 +71,21 @@ pub fn add_member_completion(
7071
LuaMemberKey::Name(name) => name.to_string(),
7172
_ => return None,
7273
},
73-
CompletionTriggerStatus::InString => match member_key {
74-
LuaMemberKey::Name(name) => name.to_string(),
75-
_ => return None,
76-
},
77-
CompletionTriggerStatus::LeftBracket => match member_key {
78-
LuaMemberKey::Name(name) => format!("\"{}\"", name),
79-
LuaMemberKey::Integer(index) => format!("{}", index),
80-
_ => return None,
81-
},
74+
CompletionTriggerStatus::InString => {
75+
can_add_snippet = false;
76+
match member_key {
77+
LuaMemberKey::Name(name) => name.to_string(),
78+
_ => return None,
79+
}
80+
}
81+
CompletionTriggerStatus::LeftBracket => {
82+
can_add_snippet = false;
83+
match member_key {
84+
LuaMemberKey::Name(name) => format!("\"{}\"", name),
85+
LuaMemberKey::Integer(index) => format!("{}", index),
86+
_ => return None,
87+
}
88+
}
8289
};
8390

8491
let typ = &member_info.typ;
@@ -149,6 +156,13 @@ pub fn add_member_completion(
149156
);
150157
}
151158

159+
if can_add_snippet && builder.support_snippets(typ) {
160+
if let Some(snippet) = get_function_snippet(builder, &label, typ, call_display) {
161+
completion_item.insert_text = Some(snippet);
162+
completion_item.insert_text_format = Some(lsp_types::InsertTextFormat::SNIPPET);
163+
}
164+
}
165+
152166
// 尝试添加别名补全项, 如果添加成功, 则不添加原来的 `[index]` 补全项
153167
if !try_add_alias_completion_item_new(builder, &member_info, &completion_item, &label)
154168
.unwrap_or(false)

crates/emmylua_ls/src/handlers/completion/add_completions/mod.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,83 @@ pub fn get_detail(
154154
}
155155
}
156156

157+
pub fn get_function_snippet(
158+
builder: &CompletionBuilder,
159+
label: &str,
160+
typ: &LuaType,
161+
display: CallDisplay,
162+
) -> Option<String> {
163+
match typ {
164+
LuaType::Signature(signature_id) => {
165+
let signature = builder
166+
.semantic_model
167+
.get_db()
168+
.get_signature_index()
169+
.get(signature_id)?;
170+
171+
let mut params_str = signature
172+
.get_type_params()
173+
.iter()
174+
.map(|param| param.0.clone())
175+
.collect::<Vec<_>>();
176+
177+
match display {
178+
CallDisplay::AddSelf => {
179+
params_str.insert(0, "self".to_string());
180+
}
181+
CallDisplay::RemoveFirst => {
182+
if !params_str.is_empty() {
183+
params_str.remove(0);
184+
}
185+
}
186+
_ => {}
187+
}
188+
189+
Some(format!(
190+
"{}({})",
191+
label,
192+
params_str
193+
.iter()
194+
.enumerate()
195+
.map(|(i, name)| format!("${{{}:{}}}", i + 1, name))
196+
.collect::<Vec<_>>()
197+
.join(", ")
198+
))
199+
}
200+
LuaType::DocFunction(f) => {
201+
let mut params_str = f
202+
.get_params()
203+
.iter()
204+
.map(|param| param.0.clone())
205+
.collect::<Vec<_>>();
206+
207+
match display {
208+
CallDisplay::AddSelf => {
209+
params_str.insert(0, "self".to_string());
210+
}
211+
CallDisplay::RemoveFirst => {
212+
if !params_str.is_empty() {
213+
params_str.remove(0);
214+
}
215+
}
216+
_ => {}
217+
}
218+
219+
Some(format!(
220+
"{}({})",
221+
label,
222+
params_str
223+
.iter()
224+
.enumerate()
225+
.map(|(i, name)| format!("${{{}:{}}}", i + 1, name))
226+
.collect::<Vec<_>>()
227+
.join(", ")
228+
))
229+
}
230+
_ => None,
231+
}
232+
}
233+
157234
#[allow(unused)]
158235
fn truncate_with_ellipsis(s: &str, max_len: usize) -> String {
159236
if s.chars().count() > max_len {

crates/emmylua_ls/src/handlers/completion/completion_builder.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::collections::HashSet;
22

3-
use emmylua_code_analysis::SemanticModel;
3+
use emmylua_code_analysis::{LuaType, SemanticModel};
44
use emmylua_parser::LuaSyntaxToken;
55
use lsp_types::{CompletionItem, CompletionTriggerKind};
66
use rowan::TextSize;
@@ -76,4 +76,14 @@ impl<'a> CompletionBuilder<'a> {
7676
pub fn is_invoked(&self) -> bool {
7777
self.trigger_kind == CompletionTriggerKind::INVOKED
7878
}
79+
80+
pub fn support_snippets(&self, ty: &LuaType) -> bool {
81+
ty.is_function()
82+
&& self
83+
.semantic_model
84+
.get_db()
85+
.get_emmyrc()
86+
.completion
87+
.call_snippet
88+
}
7989
}

0 commit comments

Comments
 (0)