-
Notifications
You must be signed in to change notification settings - Fork 28
/
provideCompletion.ts
98 lines (98 loc) · 3.14 KB
/
provideCompletion.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import {
CompletionItem,
CompletionItemKind,
Position,
Range,
TextEdit
} from "vscode-languageserver";
import { IArgument, IEquivalenceClass, IArgdownResponse } from "@argdown/core";
const statementPattern = /\[([^\[]+?)\]$/;
const argumentPattern = /<([^<]+?)>$/;
export const provideCompletion = (
response: IArgdownResponse,
char: string,
position: Position,
text: string,
offset: number
) => {
const range = Range.create(
position.line,
position.character - 1,
position.line,
position.character + 1
);
if (!response.statements || !response.arguments) {
return [];
}
if (char === "[") {
return Object.keys(response.statements!).map((k: any) => {
const eqClass = response.statements![k];
const title = eqClass.title;
const item = CompletionItem.create(`[${title}]`);
item.textEdit = TextEdit.replace(range, `[${title}]`);
item.kind = CompletionItemKind.Variable;
item.detail = IEquivalenceClass.getCanonicalMemberText(eqClass);
return item;
});
} else if (char === "<") {
return Object.keys(response.arguments!).map((k: any) => {
const argument = response.arguments![k];
const title = argument.title;
const item = CompletionItem.create(`<${title}>`);
item.textEdit = TextEdit.replace(range, `<${title}>`);
item.kind = CompletionItemKind.Variable;
const desc = IArgument.getCanonicalMemberText(argument);
if (desc) {
item.detail = desc;
}
return item;
});
} else if (char === ":") {
const textBefore = text.slice(0, offset - 1);
const statementMatch = textBefore.match(statementPattern);
if (statementMatch && statementMatch.length > 1) {
const title = statementMatch[1];
const eqClass = response.statements![title];
if (!eqClass.members) {
return [];
}
return eqClass.members
.filter(member => !member.isReference)
.map(member => {
const item = CompletionItem.create(member.text!);
item.kind = CompletionItemKind.Value;
item.detail = `[${title}]: ${member.text}`;
item.insertText = ` ${member.text}
`;
return item;
});
} else {
const argumentMatch = textBefore.match(argumentPattern);
if (argumentMatch && argumentMatch.length > 1) {
const title = argumentMatch[1];
const argument = response.arguments![title];
if (argument.members) {
return argument.members
.filter(member => !member.isReference)
.map(member => {
const item = CompletionItem.create(member.text!);
item.kind = CompletionItemKind.Value;
item.detail = `<${title}>: ${member.text}`;
item.insertText = ` ${member.text}
`;
item.kind = CompletionItemKind.Value;
return item;
});
}
}
}
} else if (char === "#" && response.tags) {
return Object.keys(response.tags).map((t: any) => {
const item = CompletionItem.create(`#(${t})`);
item.insertText = `(${t})`;
item.kind = CompletionItemKind.Keyword;
return item;
});
}
return [];
};