|
1 | | -import { loader, type Monaco } from "@monaco-editor/react"; |
2 | 1 | import * as monaco from 'monaco-editor'; |
3 | | -import type { IRange, languages } from "monaco-editor"; |
4 | | -import { functionsParser, getFunctionInlineSignature, getFunctionObjectSignature } from "@nlighten/json-transform-core"; |
5 | | -import {formatSchemaType} from "@nlighten/json-schema-utils"; |
6 | | -import jsonVariablesTokensProvider from "./jsonVariablesTokensProvider"; |
7 | | -import registerHoverProvider from "./jsonHoverProvider"; |
8 | | -import {getSuggestions, resolveSuggestions} from "./suggestionsProvider"; |
| 2 | +import { loader, type Monaco } from "@monaco-editor/react"; |
| 3 | +import {getSuggestions} from "./suggestionsProvider"; |
| 4 | + |
| 5 | +import { |
| 6 | + registerJsonTransformItemCompletionProvider, |
| 7 | + registerJsonTransformDSTProvider, |
| 8 | + registerJsonTransformHoverProvider, |
| 9 | + defineThemeVsDarkCustom |
| 10 | +} from "@nlighten/monaco-json-transform" |
9 | 11 |
|
10 | 12 | const glob = window as unknown as { monaco: Monaco }; |
11 | 13 |
|
@@ -34,116 +36,29 @@ export const getModel = (value: string, uri: string, language = "json", path?: s |
34 | 36 | }; |
35 | 37 |
|
36 | 38 | const initMonaco = (monaco: Monaco) => { |
37 | | - jsonVariablesTokensProvider(monaco); |
38 | | - |
39 | | - // add suggestions |
40 | | - const jsonVariableMapper = (v: any, paths: any, range: IRange, inline: boolean): languages.CompletionItem => { |
41 | | - let label = v[0] === "<" ? v.replace(/^<[^>]*>/, "") : v; |
42 | | - let insertText: string = label.replace(/"/g, '\\"'); |
43 | | - let insertTextRules: any = undefined; |
44 | | - let documentation: string | undefined = undefined; |
45 | | - let detail = paths?.[v] |
46 | | - ? `(${paths[v].type}${paths[v].format ? ":" + paths[v].format : ""})${ |
47 | | - paths[v].description ? " " + paths[v].description : "" |
48 | | - }` |
49 | | - : undefined; |
50 | | - let kind = monaco.languages.CompletionItemKind.Field; |
51 | | - let tags: any = undefined; |
52 | | - if (inline && v[0] === "$" && v[1] === "$") { |
53 | | - const inlineFunction = functionsParser.get(v.substring(2)); |
54 | | - if (inlineFunction) { |
55 | | - if (inlineFunction.deprecated) { |
56 | | - tags = [monaco.languages.CompletionItemTag.Deprecated]; |
57 | | - } |
58 | | - let counter = 1; |
59 | | - label = v + " (inline)"; |
60 | | - |
61 | | - insertText = getFunctionInlineSignature(v.substring(2), inlineFunction, true).replace("$$", "\\$\\$"); // escape the first $$ |
62 | | - if (insertText.includes("{")) { |
63 | | - insertText = insertText.replace(/{/g, () => `$\{${counter++}:`); |
64 | | - } |
65 | | - insertText += `:$\{${counter}:input}`; |
66 | | - insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet; |
67 | | - kind = monaco.languages.CompletionItemKind.Function; |
68 | | - documentation = inlineFunction.description; |
69 | | - } |
70 | | - } else if (!inline && v[0] === "$" && v[1] === "$") { |
71 | | - const objectFunction = functionsParser.get(v.substring(2)); |
72 | | - if (objectFunction) { |
73 | | - let counter = 1; |
74 | | - label = v + " (object)"; |
75 | | - insertText = getFunctionObjectSignature(v.substring(2), objectFunction); |
76 | | - insertText = insertText.replace(/\{\w+}/g, m => `$\{${counter++}:"${m.substring(1)}"`); |
77 | | - insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet; |
78 | | - kind = monaco.languages.CompletionItemKind.Module; |
79 | | - detail = objectFunction.outputSchema |
80 | | - ? formatSchemaType(objectFunction.outputSchema) |
81 | | - : objectFunction.description; |
82 | | - documentation = objectFunction.description; |
83 | | - } |
84 | | - } |
85 | | - return { |
86 | | - label, |
87 | | - kind, |
88 | | - insertText, |
89 | | - insertTextRules, |
90 | | - range, |
91 | | - detail, |
92 | | - documentation, |
93 | | - tags, |
94 | | - }; |
95 | | - }; |
96 | | - const functionSuggestions = functionsParser.getNames() |
97 | | - .filter(x => !functionsParser.get(x).deprecated) |
98 | | - .map(x => `$$${x}`); |
| 39 | + registerJsonTransformDSTProvider(monaco); |
99 | 40 |
|
100 | | - monaco.languages.registerCompletionItemProvider("json", { |
101 | | - provideCompletionItems: (model, position) => { |
| 41 | + registerJsonTransformItemCompletionProvider(monaco, { |
| 42 | + getTypeMap: (model) => { |
102 | 43 | const path = model.uri.path.replace(/\.\w+$/, ""); |
103 | | - const [suggestions, paths] = getSuggestions(path); |
104 | | - const word = model.getWordUntilPosition(position); |
105 | | - const range = { |
106 | | - startLineNumber: position.lineNumber, |
107 | | - endLineNumber: position.lineNumber, |
108 | | - startColumn: word.startColumn, |
109 | | - endColumn: word.endColumn, |
110 | | - }; |
111 | | - // find out if we are inside a string or after a key inside an object |
112 | | - // we count (") before position on same line |
113 | | - // if even number then we are not in a string, otherwise a string (this is not precise, could have been escaped) |
114 | | - const quotesCount = |
115 | | - model |
116 | | - .getLineContent(position.lineNumber) |
117 | | - .substring(0, position.column - 1) |
118 | | - .match(/^"|[^\\]"/g)?.length ?? 0; // ignore escaped double quotes |
119 | | - const inline = quotesCount % 2 !== 0; // if inside a string, suggest inline functions otherwise object functions |
120 | | - return { |
121 | | - suggestions: suggestions.concat(functionSuggestions).map(s => jsonVariableMapper(s, paths, range, inline)), |
122 | | - }; |
| 44 | + const [, paths] = getSuggestions(path); |
| 45 | + return paths; |
123 | 46 | }, |
| 47 | + getSuggestions: (model) => { |
| 48 | + const path = model.uri.path.replace(/\.\w+$/, ""); |
| 49 | + return getSuggestions(path)[0]; |
| 50 | + } |
124 | 51 | }); |
125 | 52 |
|
126 | | - monaco.editor.registerCommand("docs", function (accessor: any, arg: any) { |
127 | | - window.open(functionsParser.resolveDocsUrl(arg.func, arg.type), "_blank"); |
| 53 | + registerJsonTransformHoverProvider(monaco, { |
| 54 | + getTypeMap: (model) => { |
| 55 | + const path = model.uri.path.replace(/\.\w+$/, ""); |
| 56 | + console.log('looking for: ' + path); |
| 57 | + return getSuggestions(path, true)[1]; |
| 58 | + } |
128 | 59 | }); |
129 | 60 |
|
130 | | - registerHoverProvider(monaco, { resolveSuggestions }); |
131 | | - |
132 | | - monaco.editor.defineTheme("vs-dark-custom", { |
133 | | - base: "vs-dark", |
134 | | - colors: {}, |
135 | | - inherit: true, |
136 | | - rules: [ |
137 | | - { token: "variable", foreground: "#80ff80".substring(1) }, |
138 | | - { token: "variable_deprecated", foreground: "#80ff80".substring(1), fontStyle: "strikethrough" }, |
139 | | - { token: "member", foreground: "#30ffee".substring(1) }, |
140 | | - { token: "context", foreground: "#d7a6ff".substring(1) }, |
141 | | - { token: "annotation", foreground: "#ff8080".substring(1) }, |
142 | | - { token: "function", foreground: "#ffff80".substring(1) }, |
143 | | - { token: "function_context", foreground: "#7d7df3".substring(1) }, |
144 | | - { token: "function_deprecated", foreground: "#ffff80".substring(1), fontStyle: "strikethrough" }, |
145 | | - ], |
146 | | - }); |
| 61 | + defineThemeVsDarkCustom(monaco); |
147 | 62 | }; |
148 | 63 |
|
149 | 64 | loader.config({ monaco }) |
|
0 commit comments