Skip to content

Commit 0c7f2df

Browse files
committed
refactor completion dispatch
1 parent 90cce65 commit 0c7f2df

17 files changed

Lines changed: 558 additions & 134 deletions

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

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ pub struct CompletionBuilder<'a> {
1515
pub env_duplicate_name: HashSet<String>,
1616
completion_items: Vec<CompletionItem>,
1717
cancel_token: CancellationToken,
18-
stopped: bool,
1918
pub trigger_kind: CompletionTriggerKind,
2019
/// 是否为空格字符触发的补全(非主动触发)
2120
pub is_space_trigger_character: bool,
@@ -44,7 +43,6 @@ impl<'a> CompletionBuilder<'a> {
4443
env_duplicate_name: HashSet::new(),
4544
completion_items: Vec::new(),
4645
cancel_token,
47-
stopped: false,
4846
trigger_kind,
4947
is_space_trigger_character,
5048
position_offset,
@@ -54,7 +52,7 @@ impl<'a> CompletionBuilder<'a> {
5452
}
5553

5654
pub fn is_cancelled(&self) -> bool {
57-
self.stopped || self.cancel_token.is_cancelled()
55+
self.cancel_token.is_cancelled()
5856
}
5957

6058
pub fn add_completion_item(&mut self, item: CompletionItem) -> Option<()> {
@@ -70,10 +68,6 @@ impl<'a> CompletionBuilder<'a> {
7068
&mut self.completion_items
7169
}
7270

73-
pub fn stop_here(&mut self) {
74-
self.stopped = true;
75-
}
76-
7771
pub fn get_trigger_text(&self) -> String {
7872
self.trigger_token.text().trim_end().to_string()
7973
}

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::{
22
completion_builder::CompletionBuilder,
33
providers::{
4-
desc_provider, doc_name_token_provider, doc_tag_provider, doc_type_provider,
5-
file_path_provider, module_path_provider, table_field_provider,
4+
CompletionProvider, DescProvider, DocNameTokenProvider, DocTagProvider, DocTypeProvider,
5+
FilePathProvider, ModulePathProvider, TableFieldProvider,
66
},
77
};
88

@@ -20,31 +20,31 @@ pub enum CompletionContext {
2020

2121
impl CompletionContext {
2222
pub fn analyze(builder: &CompletionBuilder) -> Self {
23-
if doc_tag_provider::can_add_completion(builder) {
23+
if DocTagProvider.supports(builder) {
2424
return Self::DocTag;
2525
}
2626

27-
if doc_name_token_provider::can_add_completion(builder) {
27+
if DocNameTokenProvider.supports(builder) {
2828
return Self::DocName;
2929
}
3030

31-
if doc_type_provider::get_completion_type(builder).is_some() {
31+
if DocTypeProvider.supports(builder) {
3232
return Self::DocType;
3333
}
3434

35-
if desc_provider::can_add_completion(builder) {
35+
if DescProvider.supports(builder) {
3636
return Self::DocDescription;
3737
}
3838

39-
if module_path_provider::can_add_completion(builder) {
39+
if ModulePathProvider.supports(builder) {
4040
return Self::ModulePath;
4141
}
4242

43-
if file_path_provider::can_add_completion(builder) {
43+
if FilePathProvider.supports(builder) {
4444
return Self::FilePath;
4545
}
4646

47-
if table_field_provider::has_exclusive_completion(builder) {
47+
if TableFieldProvider.supports(builder) {
4848
return Self::TableField;
4949
}
5050

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,34 @@ use crate::{
1515
util::{file_name_convert, module_name_convert},
1616
};
1717

18-
pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
18+
use super::{CompletionProvider, ProviderDecision};
19+
20+
pub struct AutoRequireProvider;
21+
22+
impl CompletionProvider for AutoRequireProvider {
23+
fn name(&self) -> &'static str {
24+
"auto_require"
25+
}
26+
27+
fn supports(&self, builder: &CompletionBuilder) -> bool {
28+
builder.semantic_model.get_emmyrc().completion.auto_require
29+
&& builder
30+
.trigger_token
31+
.parent()
32+
.and_then(LuaNameExpr::cast)
33+
.is_some()
34+
}
35+
36+
fn complete(&self, builder: &mut CompletionBuilder) -> ProviderDecision {
37+
if complete_provider(builder).is_some() {
38+
ProviderDecision::Continue
39+
} else {
40+
ProviderDecision::NoMatch
41+
}
42+
}
43+
}
44+
45+
fn complete_provider(builder: &mut CompletionBuilder) -> Option<()> {
1946
if builder.is_cancelled() {
2047
return None;
2148
}

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,33 @@ use emmylua_parser_desc::{LuaDescRefPathItem, parse_ref_target};
1111
use rowan::TextRange;
1212
use std::collections::HashSet;
1313

14-
pub fn can_add_completion(builder: &CompletionBuilder) -> bool {
14+
use super::{CompletionProvider, ProviderDecision};
15+
16+
pub struct DescProvider;
17+
18+
impl CompletionProvider for DescProvider {
19+
fn name(&self) -> &'static str {
20+
"doc_description"
21+
}
22+
23+
fn supports(&self, builder: &CompletionBuilder) -> bool {
24+
supports_provider(builder)
25+
}
26+
27+
fn complete(&self, builder: &mut CompletionBuilder) -> ProviderDecision {
28+
if complete_provider(builder).is_some() {
29+
ProviderDecision::Stop
30+
} else {
31+
ProviderDecision::NoMatch
32+
}
33+
}
34+
}
35+
36+
fn supports_provider(builder: &CompletionBuilder) -> bool {
1537
detect_path(builder).is_some()
1638
}
1739

18-
pub fn add_completions(builder: &mut CompletionBuilder) -> Option<()> {
40+
fn complete_provider(builder: &mut CompletionBuilder) -> Option<()> {
1941
if builder.is_cancelled() {
2042
return None;
2143
}
@@ -28,8 +50,6 @@ pub fn add_completions(builder: &mut CompletionBuilder) -> Option<()> {
2850
add_by_prefix(builder, &path);
2951
}
3052

31-
builder.stop_here();
32-
3353
Some(())
3454
}
3555

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,33 @@ use lsp_types::CompletionItem;
99

1010
use crate::handlers::completion::completion_builder::CompletionBuilder;
1111

12-
pub fn can_add_completion(builder: &CompletionBuilder) -> bool {
12+
use super::{CompletionProvider, ProviderDecision};
13+
14+
pub struct DocNameTokenProvider;
15+
16+
impl CompletionProvider for DocNameTokenProvider {
17+
fn name(&self) -> &'static str {
18+
"doc_name_token"
19+
}
20+
21+
fn supports(&self, builder: &CompletionBuilder) -> bool {
22+
supports_provider(builder)
23+
}
24+
25+
fn complete(&self, builder: &mut CompletionBuilder) -> ProviderDecision {
26+
if complete_provider(builder).is_some() {
27+
ProviderDecision::Stop
28+
} else {
29+
ProviderDecision::NoMatch
30+
}
31+
}
32+
}
33+
34+
fn supports_provider(builder: &CompletionBuilder) -> bool {
1335
get_doc_completion_expected(&builder.trigger_token).is_some()
1436
}
1537

16-
pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
38+
fn complete_provider(builder: &mut CompletionBuilder) -> Option<()> {
1739
if builder.is_cancelled() {
1840
return None;
1941
}
@@ -46,8 +68,6 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
4668
}
4769
}
4870

49-
builder.stop_here();
50-
5171
Some(())
5272
}
5373

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,42 @@ use emmylua_parser::{
55
};
66
use lsp_types::{CompletionItem, MarkupContent};
77

8-
pub fn can_add_completion(builder: &CompletionBuilder) -> bool {
8+
use super::{CompletionProvider, ProviderDecision};
9+
10+
pub struct DocTagProvider;
11+
12+
impl CompletionProvider for DocTagProvider {
13+
fn name(&self) -> &'static str {
14+
"doc_tag"
15+
}
16+
17+
fn supports(&self, builder: &CompletionBuilder) -> bool {
18+
supports_provider(builder)
19+
}
20+
21+
fn complete(&self, builder: &mut CompletionBuilder) -> ProviderDecision {
22+
if complete_provider(builder).is_some() {
23+
ProviderDecision::Stop
24+
} else {
25+
ProviderDecision::NoMatch
26+
}
27+
}
28+
}
29+
30+
fn supports_provider(builder: &CompletionBuilder) -> bool {
931
matches!(
1032
builder.trigger_token.kind().into(),
1133
LuaTokenKind::TkDocStart | LuaTokenKind::TkDocLongStart | LuaTokenKind::TkTagOther
1234
)
1335
}
1436

15-
pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
37+
fn complete_provider(builder: &mut CompletionBuilder) -> Option<()> {
1638
if builder.is_cancelled() {
1739
return None;
1840
}
1941

2042
let trigger_token_kind: LuaTokenKind = builder.trigger_token.kind().into();
21-
if !can_add_completion(builder) {
43+
if !supports_provider(builder) {
2244
return None;
2345
}
2446

@@ -37,7 +59,6 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
3759
add_tag_param_return_completion(builder, last_index);
3860
}
3961

40-
builder.stop_here();
4162
Some(())
4263
}
4364

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,34 @@ use crate::handlers::completion::{
77
completion_builder::CompletionBuilder, completion_data::CompletionData,
88
};
99

10-
pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
10+
use super::{CompletionProvider, ProviderDecision};
11+
12+
pub struct DocTypeProvider;
13+
14+
impl CompletionProvider for DocTypeProvider {
15+
fn name(&self) -> &'static str {
16+
"doc_type"
17+
}
18+
19+
fn supports(&self, builder: &CompletionBuilder) -> bool {
20+
completion_type_for(builder).is_some()
21+
}
22+
23+
fn complete(&self, builder: &mut CompletionBuilder) -> ProviderDecision {
24+
if complete_provider(builder).is_some() {
25+
ProviderDecision::Stop
26+
} else {
27+
ProviderDecision::NoMatch
28+
}
29+
}
30+
}
31+
32+
fn complete_provider(builder: &mut CompletionBuilder) -> Option<()> {
1133
if builder.is_cancelled() {
1234
return None;
1335
}
1436

15-
let completion_type = get_completion_type(builder)?;
37+
let completion_type = completion_type_for(builder)?;
1638

1739
let prefix_content = builder.trigger_token.text().to_string();
1840
let prefix = if let Some(last_sep) = prefix_content.rfind('.') {
@@ -22,7 +44,6 @@ pub fn add_completion(builder: &mut CompletionBuilder) -> Option<()> {
2244
""
2345
};
2446
complete_types_by_prefix(builder, prefix, None, Some(completion_type));
25-
builder.stop_here();
2647
Some(())
2748
}
2849

@@ -82,7 +103,7 @@ pub enum CompletionType {
82103
AttributeUse,
83104
}
84105

85-
pub fn get_completion_type(builder: &CompletionBuilder) -> Option<CompletionType> {
106+
fn completion_type_for(builder: &CompletionBuilder) -> Option<CompletionType> {
86107
match builder.trigger_token.kind().into() {
87108
LuaTokenKind::TkName => {
88109
let parent = builder.trigger_token.parent()?;

0 commit comments

Comments
 (0)