Skip to content

Commit 1ba2b20

Browse files
committed
Represent certain keywords in both bare and snippet form
1 parent e6e328b commit 1ba2b20

File tree

1 file changed

+74
-61
lines changed
  • crates/ark/src/lsp/completions/sources/composite

1 file changed

+74
-61
lines changed

crates/ark/src/lsp/completions/sources/composite/keyword.rs

Lines changed: 74 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -44,65 +44,71 @@ pub fn completions_from_keywords() -> anyhow::Result<Option<Vec<CompletionItem>>
4444
}
4545

4646
const BARE_KEYWORDS: &[&str] = &[
47-
"NULL",
48-
"NA",
4947
"TRUE",
5048
"FALSE",
49+
"NULL",
5150
"Inf",
5251
"NaN",
52+
"NA",
5353
"NA_integer_",
5454
"NA_real_",
55-
"NA_character_",
5655
"NA_complex_",
56+
"NA_character_",
57+
"if",
58+
"else",
59+
"repeat",
60+
"while",
61+
"function",
62+
"for",
5763
"in",
5864
"next",
5965
"break",
60-
"repeat",
61-
"function",
6266
];
6367

64-
// Snippet data is a tuple of:
65-
// - keyword: The reserved word
66-
// - label: The label for the completion item, displayed on the left in the UI
67-
// - snippet: The snippet to be inserted
68-
// - label_detail.description: The description displayed on the right in the
69-
// completion UI
70-
71-
// The only case where `keyword != label` is `fun` for `function`.
72-
// But in the name of preserving original behaviour, this is my opening
73-
// move.
74-
const KEYWORD_SNIPPETS: &[(&str, &str, &str, &str)] = &[
75-
// (keyword, label, snippet, label_detail.description)
76-
(
77-
"for",
78-
"for",
79-
"for (${1:variable} in ${2:vector}) {\n\t${0}\n}",
80-
"Define a loop",
81-
),
82-
(
83-
"if",
84-
"if",
85-
"if (${1:condition}) {\n\t${0}\n}",
86-
"Conditional expression",
87-
),
88-
(
89-
"while",
90-
"while",
91-
"while (${1:condition}) {\n\t${0}\n}",
92-
"Define a loop",
93-
),
94-
(
95-
"else",
96-
"else",
97-
"else {\n\t${0}\n}",
98-
"Conditional expression",
99-
),
100-
(
101-
"function",
102-
"fun",
103-
"${1:name} <- function(${2:variables}) {\n\t${0}\n}",
104-
"Function skeleton",
105-
),
68+
struct KeywordSnippet {
69+
keyword: &'static str,
70+
label: &'static str,
71+
snippet: &'static str,
72+
label_details_description: &'static str,
73+
}
74+
75+
const KEYWORD_SNIPPETS: &[KeywordSnippet] = &[
76+
KeywordSnippet {
77+
keyword: "if",
78+
label: "if",
79+
snippet: "if (${1:condition}) {\n\t${0}\n}",
80+
label_details_description: "An if statement",
81+
},
82+
KeywordSnippet {
83+
keyword: "else",
84+
label: "else",
85+
snippet: "else {\n\t${0}\n}",
86+
label_details_description: "An else statement",
87+
},
88+
KeywordSnippet {
89+
keyword: "repeat",
90+
label: "repeat",
91+
snippet: "repeat {\n\t${0}\n}",
92+
label_details_description: "A repeat loop",
93+
},
94+
KeywordSnippet {
95+
keyword: "while",
96+
label: "while",
97+
snippet: "while (${1:condition}) {\n\t${0}\n}",
98+
label_details_description: "A while loop",
99+
},
100+
KeywordSnippet {
101+
keyword: "function",
102+
label: "fun",
103+
snippet: "${1:name} <- function(${2:variables}) {\n\t${0}\n}",
104+
label_details_description: "Define a function",
105+
},
106+
KeywordSnippet {
107+
keyword: "for",
108+
label: "for",
109+
snippet: "for (${1:variable} in ${2:vector}) {\n\t${0}\n}",
110+
label_details_description: "A for loop",
111+
},
106112
];
107113

108114
fn add_bare_keywords(completions: &mut Vec<CompletionItem>) {
@@ -127,7 +133,13 @@ fn add_bare_keywords(completions: &mut Vec<CompletionItem>) {
127133
}
128134

129135
fn add_keyword_snippets(completions: &mut Vec<CompletionItem>) {
130-
for (keyword, label, snippet, label_details_description) in KEYWORD_SNIPPETS {
136+
for KeywordSnippet {
137+
keyword,
138+
label,
139+
snippet,
140+
label_details_description,
141+
} in KEYWORD_SNIPPETS
142+
{
131143
let item = completion_item(label.to_string(), CompletionData::Snippet {
132144
text: snippet.to_string(),
133145
});
@@ -168,9 +180,15 @@ mod tests {
168180
#[test]
169181
fn test_presence_bare_keywords() {
170182
let completions = super::completions_from_keywords().unwrap().unwrap();
183+
let keyword_completions: Vec<_> = completions
184+
.iter()
185+
.filter(|item| item.kind == Some(tower_lsp::lsp_types::CompletionItemKind::KEYWORD))
186+
.collect();
171187

172188
for keyword in super::BARE_KEYWORDS {
173-
let item = completions.iter().find(|item| item.label == *keyword);
189+
let item = keyword_completions
190+
.iter()
191+
.find(|item| item.label == *keyword);
174192
assert!(
175193
item.is_some(),
176194
"Expected keyword '{keyword}' not found in completions"
@@ -183,32 +201,27 @@ mod tests {
183201
description: Some("[keyword]".to_string()),
184202
})
185203
);
186-
assert_eq!(
187-
item.kind,
188-
Some(tower_lsp::lsp_types::CompletionItemKind::KEYWORD)
189-
);
190204
}
191205
}
192206

193207
#[test]
194208
fn test_presence_keyword_snippets() {
195209
let completions = super::completions_from_keywords().unwrap().unwrap();
210+
let snippet_completions: Vec<_> = completions
211+
.iter()
212+
.filter(|item| item.kind == Some(tower_lsp::lsp_types::CompletionItemKind::SNIPPET))
213+
.collect();
196214

197215
let snippet_labels: Vec<&str> = super::KEYWORD_SNIPPETS
198216
.iter()
199-
.map(|(_, label, _, _)| *label)
217+
.map(|snippet| snippet.label)
200218
.collect();
201219

202220
for label in snippet_labels {
203-
let item = completions.iter().find(|item| item.label == label);
221+
let item = snippet_completions.iter().find(|item| item.label == label);
204222
assert!(
205223
item.is_some(),
206-
"Expected snippet '{label}' not found in completions"
207-
);
208-
let item = item.unwrap();
209-
assert_eq!(
210-
item.kind,
211-
Some(tower_lsp::lsp_types::CompletionItemKind::SNIPPET)
224+
"Expected snippet '{label}' with SNIPPET kind not found in completions"
212225
);
213226
}
214227
}

0 commit comments

Comments
 (0)