Skip to content

Commit 1c5f18a

Browse files
committed
add module/type description when completion
1 parent 9ee149a commit 1c5f18a

File tree

5 files changed

+48
-43
lines changed

5 files changed

+48
-43
lines changed

crates/emmylua_ls/src/handlers/completion/providers/auto_require_provider.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use crate::{
77
util::module_name_convert,
88
};
99

10+
use super::module_path_provider::get_module_description;
11+
1012
pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
1113
if builder.is_cancelled() {
1214
return None;
@@ -74,6 +76,7 @@ fn add_module_completion_item(
7476
return None;
7577
}
7678

79+
let db = builder.semantic_model.get_db();
7780
let completion_item = CompletionItem {
7881
label: completion_name,
7982
kind: Some(lsp_types::CompletionItemKind::MODULE),
@@ -87,6 +90,7 @@ fn add_module_completion_item(
8790
module_info.file_id,
8891
position,
8992
)),
93+
documentation: get_module_description(db, module_info.file_id),
9094
..Default::default()
9195
};
9296

crates/emmylua_ls/src/handlers/completion/providers/doc_type_provider.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use emmylua_code_analysis::LuaTypeDeclId;
22
use emmylua_parser::{LuaAstNode, LuaDocNameType, LuaSyntaxKind, LuaTokenKind};
3-
use lsp_types::CompletionItem;
3+
use lsp_types::{CompletionItem, Documentation, MarkupContent};
44

55
use crate::handlers::completion::completion_builder::CompletionBuilder;
66

@@ -91,8 +91,26 @@ fn add_type_completion_item(
9191
let completion_item = CompletionItem {
9292
label: name.to_string(),
9393
kind: Some(kind),
94+
documentation: get_documentation(builder, type_decl),
9495
..CompletionItem::default()
9596
};
9697

9798
builder.add_completion_item(completion_item)
9899
}
100+
101+
fn get_documentation(
102+
builder: &CompletionBuilder,
103+
type_decl: Option<LuaTypeDeclId>,
104+
) -> Option<Documentation> {
105+
let db = builder.semantic_model.get_db();
106+
let semantic_id = type_decl?.into();
107+
let property = db.get_property_index().get_property(&semantic_id)?;
108+
if let Some(description) = &property.description {
109+
return Some(Documentation::MarkupContent(MarkupContent {
110+
kind: lsp_types::MarkupKind::Markdown,
111+
value: description.to_string(),
112+
}));
113+
}
114+
115+
None
116+
}

crates/emmylua_ls/src/handlers/completion/providers/module_path_provider.rs

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
use emmylua_code_analysis::Emmyrc;
1+
use emmylua_code_analysis::{DbIndex, FileId};
22
use emmylua_parser::{
3-
LuaAstNode, LuaAstToken, LuaCallArgList, LuaCallExpr, LuaExpr, LuaLiteralExpr, LuaStringToken,
3+
LuaAstNode, LuaAstToken, LuaCallArgList, LuaCallExpr, LuaLiteralExpr, LuaStringToken,
44
};
5-
use lsp_types::{CompletionItem, CompletionTextEdit, TextEdit};
5+
use lsp_types::{CompletionItem, CompletionTextEdit, Documentation, MarkupContent, TextEdit};
66

77
use crate::handlers::completion::completion_builder::CompletionBuilder;
88

@@ -14,21 +14,14 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
1414
}
1515

1616
let string_token = LuaStringToken::cast(builder.trigger_token.clone())?;
17-
let call_expr_prefix = string_token
17+
let call_expr = string_token
1818
.get_parent::<LuaLiteralExpr>()?
1919
.get_parent::<LuaCallArgList>()?
20-
.get_parent::<LuaCallExpr>()?
21-
.get_prefix_expr()?;
20+
.get_parent::<LuaCallExpr>()?;
2221

2322
let emmyrc = builder.semantic_model.get_emmyrc();
24-
match call_expr_prefix {
25-
LuaExpr::NameExpr(name_expr) => {
26-
let name = name_expr.get_name_text()?;
27-
if !is_require_call(emmyrc, &name) {
28-
return None;
29-
}
30-
}
31-
_ => return None,
23+
if !call_expr.is_require() {
24+
return None;
3225
}
3326

3427
let version_number = emmyrc.runtime.version.to_lua_version_number();
@@ -72,6 +65,7 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
7265
filter_text: Some(filter_text.clone()),
7366
text_edit: Some(CompletionTextEdit::Edit(text_edit)),
7467
detail: Some(uri.to_string()),
68+
documentation: get_module_description(db, *child_file_id),
7569
..Default::default()
7670
};
7771
module_completions.push(completion_item);
@@ -98,12 +92,16 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
9892
Some(())
9993
}
10094

101-
fn is_require_call(emmyrc: &Emmyrc, name: &str) -> bool {
102-
for fun in &emmyrc.runtime.require_like_function {
103-
if name == fun {
104-
return true;
105-
}
95+
pub fn get_module_description(db: &DbIndex, file_id: FileId) -> Option<Documentation> {
96+
let module_info = db.get_module_index().get_module(file_id)?;
97+
let semantic_id = module_info.property_owner_id.clone()?;
98+
let property = db.get_property_index().get_property(&semantic_id)?;
99+
if let Some(description) = &property.description {
100+
return Some(Documentation::MarkupContent(MarkupContent {
101+
kind: lsp_types::MarkupKind::Markdown,
102+
value: description.to_string(),
103+
}));
106104
}
107105

108-
name == "require"
106+
None
109107
}

crates/emmylua_ls/src/handlers/definition/goto_module_file.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ pub fn goto_module_file(
88
semantic_model: &SemanticModel,
99
string_token: LuaStringToken,
1010
) -> Option<GotoDefinitionResponse> {
11-
let emmyrc = semantic_model.get_emmyrc();
12-
if !is_require_path(string_token.clone(), &emmyrc).unwrap_or(false) {
11+
if !is_require_path(string_token.clone()).unwrap_or(false) {
1312
return None;
1413
}
1514

crates/emmylua_ls/src/handlers/document_link/build_link.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::path::PathBuf;
22

33
use emmylua_code_analysis::{file_path_to_uri, DbIndex, Emmyrc, LuaDocument};
44
use emmylua_parser::{
5-
LuaAstNode, LuaAstToken, LuaCallArgList, LuaCallExpr, LuaExpr, LuaLiteralExpr, LuaStringToken,
5+
LuaAstNode, LuaAstToken, LuaCallArgList, LuaCallExpr, LuaLiteralExpr, LuaStringToken,
66
LuaSyntaxNode,
77
};
88
use lsp_types::DocumentLink;
@@ -33,7 +33,7 @@ fn try_build_file_link(
3333
result: &mut Vec<DocumentLink>,
3434
emmyrc: &Emmyrc,
3535
) -> Option<()> {
36-
if is_require_path(token.clone(), emmyrc).unwrap_or(false) {
36+
if is_require_path(token.clone()).unwrap_or(false) {
3737
try_build_module_link(db, token, document, result);
3838
return Some(());
3939
}
@@ -103,25 +103,11 @@ fn try_build_module_link(
103103
Some(())
104104
}
105105

106-
pub fn is_require_path(token: LuaStringToken, emmyrc: &Emmyrc) -> Option<bool> {
107-
let call_expr_prefix = token
106+
pub fn is_require_path(token: LuaStringToken) -> Option<bool> {
107+
let call_expr = token
108108
.get_parent::<LuaLiteralExpr>()?
109109
.get_parent::<LuaCallArgList>()?
110-
.get_parent::<LuaCallExpr>()?
111-
.get_prefix_expr()?;
110+
.get_parent::<LuaCallExpr>()?;
112111

113-
if let LuaExpr::NameExpr(name_expr) = call_expr_prefix {
114-
let name = name_expr.get_name_text()?;
115-
if name == "require" {
116-
return Some(true);
117-
}
118-
119-
for require_like_function in &emmyrc.runtime.require_like_function {
120-
if name == *require_like_function {
121-
return Some(true);
122-
}
123-
}
124-
}
125-
126-
Some(false)
112+
Some(call_expr.is_require())
127113
}

0 commit comments

Comments
 (0)