monaco-yaml
Version:
YAML plugin for the Monaco Editor
310 lines (309 loc) • 9.75 kB
JavaScript
// src/index.ts
import {
fromCodeActionTriggerType,
fromFormattingOptions,
fromPosition,
fromRange,
toCodeAction,
toCodeLens,
toCompletionList,
toDocumentSymbol,
toFoldingRange,
toHover,
toLink,
toLocationLink,
toMarkerData,
toRange,
toSelectionRanges,
toTextEdit,
toWorkspaceEdit
} from "monaco-languageserver-types";
import { registerMarkerDataProvider } from "monaco-marker-data-provider";
import { createWorkerManager } from "monaco-worker-manager";
function mergeOptions(newOptions, oldOptions) {
return {
...oldOptions,
...newOptions,
format: {
...oldOptions.format,
...newOptions.format
}
};
}
function togglable(create) {
let disposable;
return {
get() {
return disposable;
},
toggle(enabled) {
if (enabled) {
disposable ??= create();
} else {
disposable?.dispose();
disposable = void 0;
}
}
};
}
function configureMonacoYaml(monaco, options = {}) {
let createData = mergeOptions(options, {
codeLens: false,
completion: true,
customTags: [],
disableAdditionalProperties: false,
disableDefaultProperties: false,
enableSchemaRequest: false,
flowMapping: "allow",
flowSequence: "allow",
format: {
bracketSpacing: true,
enable: true,
printWidth: 80,
proseWrap: "preserve",
singleQuote: false,
trailingComma: true
},
hover: true,
hoverAnchor: true,
indentation: " ",
isKubernetes: false,
keyOrdering: false,
parentSkeletonSelectedFirst: false,
schemas: [],
validate: true,
yamlVersion: "1.2"
});
monaco.languages.register({
id: "yaml",
extensions: [".yaml", ".yml"],
aliases: ["YAML", "yaml", "YML", "yml"],
mimetypes: ["application/x-yaml"]
});
const workerManager = createWorkerManager(monaco, {
label: "yaml",
moduleId: "monaco-yaml/yaml.worker",
createData
});
const diagnosticMap = /* @__PURE__ */ new WeakMap();
const codeLensProvider = togglable(
() => monaco.languages.registerCodeLensProvider("yaml", {
async provideCodeLenses(model) {
const worker = await workerManager.getWorker(model.uri);
const lenses = await worker.getCodeLens(String(model.uri));
if (lenses) {
return {
lenses: lenses.map(toCodeLens),
dispose() {
}
};
}
}
})
);
const completionProvider = togglable(
() => monaco.languages.registerCompletionItemProvider("yaml", {
triggerCharacters: [" ", ":"],
async provideCompletionItems(model, position) {
const wordInfo = model.getWordUntilPosition(position);
const worker = await workerManager.getWorker(model.uri);
const info = await worker.doComplete(String(model.uri), fromPosition(position));
if (info) {
return toCompletionList(info, {
range: {
startLineNumber: position.lineNumber,
startColumn: wordInfo.startColumn,
endLineNumber: position.lineNumber,
endColumn: wordInfo.endColumn
}
});
}
}
})
);
const formatProvider = togglable(
() => monaco.languages.registerDocumentFormattingEditProvider("yaml", {
displayName: "yaml",
async provideDocumentFormattingEdits(model) {
const worker = await workerManager.getWorker(model.uri);
const edits = await worker.format(String(model.uri));
return edits?.map(toTextEdit);
}
})
);
const hoverProvider = togglable(
() => monaco.languages.registerHoverProvider("yaml", {
async provideHover(model, position) {
const worker = await workerManager.getWorker(model.uri);
const info = await worker.doHover(String(model.uri), fromPosition(position));
if (info) {
return toHover(info);
}
}
})
);
const validationProvider = togglable(
() => registerMarkerDataProvider(monaco, "yaml", {
owner: "yaml",
async provideMarkerData(model) {
const worker = await workerManager.getWorker(model.uri);
const diagnostics = await worker.doValidation(String(model.uri));
diagnosticMap.set(model, diagnostics);
return diagnostics?.map(toMarkerData);
},
async doReset(model) {
const worker = await workerManager.getWorker(model.uri);
await worker.resetSchema(String(model.uri));
}
})
);
function toggleAll() {
codeLensProvider.toggle(createData.codeLens);
completionProvider.toggle(createData.completion);
formatProvider.toggle(createData.format?.enable);
hoverProvider.toggle(createData.hover);
validationProvider.toggle(createData.validate);
}
toggleAll();
const disposables = [
workerManager,
monaco.languages.registerDefinitionProvider("yaml", {
async provideDefinition(model, position) {
const worker = await workerManager.getWorker(model.uri);
const locationLinks = await worker.doDefinition(String(model.uri), fromPosition(position));
return locationLinks?.map(toLocationLink);
}
}),
monaco.languages.registerDocumentSymbolProvider("yaml", {
displayName: "yaml",
async provideDocumentSymbols(model) {
const worker = await workerManager.getWorker(model.uri);
const items = await worker.findDocumentSymbols(String(model.uri));
return items?.map(toDocumentSymbol);
}
}),
monaco.languages.registerLinkProvider("yaml", {
async provideLinks(model) {
const worker = await workerManager.getWorker(model.uri);
const links = await worker.findLinks(String(model.uri));
if (links) {
return {
links: links.map(toLink)
};
}
}
}),
monaco.languages.registerCodeActionProvider("yaml", {
async provideCodeActions(model, range, context) {
const worker = await workerManager.getWorker(model.uri);
const codeActions = await worker.getCodeAction(String(model.uri), fromRange(range), {
diagnostics: diagnosticMap.get(model)?.filter((diagnostic) => range.intersectRanges(toRange(diagnostic.range))) || [],
only: context.only ? [context.only] : void 0,
triggerKind: fromCodeActionTriggerType(context.trigger)
});
if (codeActions) {
return {
actions: codeActions.map(toCodeAction),
dispose() {
}
};
}
}
}),
monaco.languages.registerFoldingRangeProvider("yaml", {
async provideFoldingRanges(model) {
const worker = await workerManager.getWorker(model.uri);
const foldingRanges = await worker.getFoldingRanges(String(model.uri));
return foldingRanges?.map(toFoldingRange);
}
}),
monaco.languages.setLanguageConfiguration("yaml", {
comments: {
lineComment: "#"
},
brackets: [
["{", "}"],
["[", "]"],
["(", ")"]
],
autoClosingPairs: [
{ open: "{", close: "}" },
{ open: "[", close: "]" },
{ open: "(", close: ")" },
{ open: '"', close: '"' },
{ open: "'", close: "'" }
],
surroundingPairs: [
{ open: "{", close: "}" },
{ open: "[", close: "]" },
{ open: "(", close: ")" },
{ open: '"', close: '"' },
{ open: "'", close: "'" }
]
}),
monaco.languages.registerOnTypeFormattingEditProvider("yaml", {
autoFormatTriggerCharacters: ["\n"],
async provideOnTypeFormattingEdits(model, position, ch, formattingOptions) {
const worker = await workerManager.getWorker(model.uri);
const edits = await worker.doDocumentOnTypeFormatting(
String(model.uri),
fromPosition(position),
ch,
fromFormattingOptions(formattingOptions)
);
return edits?.map(toTextEdit);
}
}),
monaco.languages.registerRenameProvider("yaml", {
async provideRenameEdits(model, position, newName) {
const worker = await workerManager.getWorker(model.uri);
const edit = await worker.doRename(String(model.uri), fromPosition(position), newName);
if (edit) {
return toWorkspaceEdit(edit);
}
},
async resolveRenameLocation(model, position) {
const worker = await workerManager.getWorker(model.uri);
const range = await worker.prepareRename(String(model.uri), fromPosition(position));
if (range) {
return { range: toRange(range), text: "" };
}
}
}),
monaco.languages.registerSelectionRangeProvider("yaml", {
async provideSelectionRanges(model, positions) {
const worker = await workerManager.getWorker(model.uri);
const selectionRanges = await worker.getSelectionRanges(
String(model.uri),
positions.map(fromPosition)
);
return selectionRanges?.map(toSelectionRanges);
}
})
];
return {
dispose() {
codeLensProvider.get()?.dispose();
completionProvider.get()?.dispose();
formatProvider.get()?.dispose();
hoverProvider.get()?.dispose();
validationProvider.get()?.dispose();
for (const disposable of disposables) {
disposable.dispose();
}
},
async update(newOptions) {
createData = mergeOptions(newOptions, createData);
workerManager.updateCreateData(createData);
toggleAll();
await validationProvider.get()?.revalidate();
},
getOptions() {
return createData;
}
};
}
export {
configureMonacoYaml
};
//# sourceMappingURL=index.js.map