forked from frappe/builder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpythonCustomCompletion.ts
More file actions
83 lines (77 loc) · 2.57 KB
/
pythonCustomCompletion.ts
File metadata and controls
83 lines (77 loc) · 2.57 KB
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
import { syntaxTree } from "@codemirror/language";
const completePropertyAfter = ["PropertyName", ".", "?."];
const dontCompleteIn = [
"TemplateString",
"LineComment",
"BlockComment",
"VariableDefinition",
"PropertyDefinition",
];
// Create completion source for custom objects
// Currently only two levels of nesting is supported, eg: frappe.session.user
export default function customPythonCompletions(context: any, customCompletions: any) {
let nodeBefore = syntaxTree(context.state).resolveInner(context.pos, -1);
if (completePropertyAfter.includes(nodeBefore.name) && nodeBefore.parent?.name == "MemberExpression") {
let object = nodeBefore.parent.getChild("Expression");
if (object?.name == "VariableName") {
let from = /\./.test(nodeBefore.name) ? nodeBefore.to : nodeBefore.from;
let variableName = context.state.sliceDoc(object.from, object.to);
if (Object.keys(customCompletions).includes(variableName)) {
return completeProperties(from, customCompletions[variableName as keyof typeof customCompletions]);
}
}
if (object?.name == "MemberExpression") {
let from = /\./.test(nodeBefore.name) ? nodeBefore.to : nodeBefore.from;
let prevName = context.state.sliceDoc(object.from, object.to).split(".")[0];
let variableName = context.state.sliceDoc(object.from, object.to).split(".")[1];
if (
Object.keys(customCompletions).includes(prevName) &&
variableName in customCompletions[prevName] &&
typeof customCompletions[prevName][
variableName as keyof (typeof customCompletions)[typeof prevName]
] == "object"
)
return completeProperties(
from,
customCompletions[prevName][variableName as keyof (typeof customCompletions)[typeof prevName]],
);
}
} else if (nodeBefore.name == "VariableName") {
return {
from: nodeBefore.from,
options: [
{ label: "data", type: "class" },
...Object.keys(customCompletions).map((item) => {
return { label: item, type: "class" };
}),
],
validFor: /^[\w$]*$/,
};
} else if (context.explicit && !dontCompleteIn.includes(nodeBefore.name)) {
return {
from: nodeBefore.from,
options: [
{ label: "data", type: "class" },
...Object.keys(customCompletions).map((item) => {
return { label: item, type: "class" };
}),
],
validFor: /^[\w$]*$/,
};
}
return null;
}
function completeProperties(from: any, object: any) {
let options = [];
for (let name of Object.keys(object)) {
options.push({
label: name,
type: object[name]["type"] ? object[name]["type"] : "variable",
});
}
return {
from,
options,
validFor: /^[\w$]*$/,
};
}