@nlighten/monaco-json-transform
Version:
JSON Transform language tokenizer (and syntax highlight), hover provider and more
103 lines • 5.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerJsonTransformItemCompletionProvider = exports.jsonTransformerItemCompletionProvider = void 0;
const json_transform_core_1 = require("@nlighten/json-transform-core");
const json_schema_utils_1 = require("@nlighten/json-schema-utils");
const jsonTransformerItemCompletionProvider = ({ getTypeMap, getSuggestions } = {}) => {
const jsonVariableMapper = (name, typeMap, range, inline) => {
let label = name[0] === "<" ? name.replace(/^<[^>]*>/, "") : name;
let insertText = label.replace(/"/g, '\\"');
let insertTextRules = undefined;
let documentation = undefined;
let detail = typeMap?.[name]
? `(${typeMap[name].type}${typeMap[name].format ? ":" + typeMap[name].format : ""})${typeMap[name].description ? " " + typeMap[name].description : ""}`
: undefined;
let kind = 3; /* monaco.languages.CompletionItemKind.Field */
let tags = undefined;
if (inline && name[0] === "$" && name[1] === "$") {
const inlineFunction = json_transform_core_1.functionsParser.get(name.substring(2));
if (inlineFunction) {
if (inlineFunction.deprecatedInFavorOf) {
tags = [1 /* monaco.languages.CompletionItemTag.Deprecated */];
}
let counter = 1;
label = name + " (inline)";
insertText = (0, json_transform_core_1.getFunctionInlineSignature)(name.substring(2), inlineFunction, true).replace("$$", "\\$\\$"); // escape the first $$
if (insertText.includes("{")) {
insertText = insertText.replace(/{/g, () => `$\{${counter++}:`);
}
insertText += `:$\{${counter}:input}`;
insertTextRules = 4 /* monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet */;
kind = 1 /* monaco.languages.CompletionItemKind.Function */;
detail = (0, json_schema_utils_1.formatSchemaType)(inlineFunction.outputSchema);
documentation = inlineFunction.description;
}
}
else if (!inline && name[0] === "$" && name[1] === "$") {
const objectFunction = json_transform_core_1.functionsParser.get(name.substring(2));
if (objectFunction) {
let counter = 1;
label = name + " (object)";
insertText = (0, json_transform_core_1.getFunctionObjectSignature)(name.substring(2), objectFunction);
insertText = insertText.replace(/\{\w+}/g, m => `$\{${counter++}:"${m.substring(1)}"`);
insertTextRules = 4 /* monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet */;
kind = 8 /* monaco.languages.CompletionItemKind.Module */;
detail = objectFunction.outputSchema
? (0, json_schema_utils_1.formatSchemaType)(objectFunction.outputSchema)
: objectFunction.description;
documentation = objectFunction.description;
}
}
return {
label,
kind,
insertText,
insertTextRules,
range,
detail,
documentation,
tags,
};
};
const functionSuggestions = Array.from(json_transform_core_1.functionsParser.getNames()).map(x => `$$${x}`);
const contextSuggestions = Object.keys(json_transform_core_1.ContextVariablesSchemas);
return {
provideCompletionItems: (model, position) => {
//const path = model.uri.path.replace(/\.\w+$/, "");
const typeMap = getTypeMap ? getTypeMap(model) : undefined;
const suggestions = getSuggestions ? getSuggestions(model) : undefined;
const word = model.getWordUntilPosition(position);
const range = {
startLineNumber: position.lineNumber,
endLineNumber: position.lineNumber,
startColumn: word.startColumn,
endColumn: word.endColumn,
};
// find out if we are inside a string or after a key inside an object
// we count (") before position on same line
// if even number then we are not in a string, otherwise a string (this is not precise, could have been escaped)
const quotesCount = model
.getLineContent(position.lineNumber)
.substring(0, position.column - 1)
.match(/^"|[^\\]"/g)?.length ?? 0; // ignore escaped double quotes
const inline = quotesCount % 2 !== 0; // if inside a string, suggest inline functions otherwise object functions
return {
suggestions: (suggestions ?? [])
.concat(functionSuggestions, contextSuggestions)
.map(s => jsonVariableMapper(s, typeMap, range, inline)),
};
},
};
};
exports.jsonTransformerItemCompletionProvider = jsonTransformerItemCompletionProvider;
/**
* Add item completion for JSON transformers
* Additional suggestions and type mapping can be provided in options
* @param monaco
* @param options
*/
const registerJsonTransformItemCompletionProvider = (monaco, options) => {
monaco.languages.registerCompletionItemProvider("json", (0, exports.jsonTransformerItemCompletionProvider)(options));
};
exports.registerJsonTransformItemCompletionProvider = registerJsonTransformItemCompletionProvider;
//# sourceMappingURL=jsonCompletionItemProvider.js.map