Skip to content

Commit 0104a3b

Browse files
committed
Represent certain keywords in both bare and snippet form
Deal with reserved words in the order in which they appear in their help topic and be consistent everywhere
1 parent e6e328b commit 0104a3b

File tree

2 files changed

+75
-62
lines changed

2 files changed

+75
-62
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
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ fn completions_from_search_path(
5353
let mut completions = vec![];
5454

5555
const KEYWORD_SOURCE: &[&str] = &[
56-
"if", "else", "for", "in", "while", "repeat", "break", "next", "function",
56+
"if", "else", "repeat", "while", "function", "for", "in", "next", "break",
5757
];
5858

5959
unsafe {

0 commit comments

Comments
 (0)