vue-shiki-monaco
Version:
一个封shiki和monaco-editor的Vue组件
198 lines (197 loc) • 5.57 kB
JavaScript
import { shikiToMonaco } from "@shikijs/monaco";
import * as monaco from "monaco-editor-core";
import { createHighlighter } from "shiki";
function useMonacoEdit(options) {
let editInstance = null;
let highlighter = null;
const loadedThemes = /* @__PURE__ */ new Set();
const loadedLanguages = /* @__PURE__ */ new Set();
let resizeObserver = null;
let autoResizeEnabled = false;
let contextMenuCallback = null;
let minimapContextMenuCallback = null;
async function initMonacoEdit() {
const {
target,
languages,
themes,
defaultTheme = "vitesse-light",
defaultLanguage = "javascript"
} = options;
try {
languages.forEach((lang) => {
monaco.languages.register({ id: lang });
loadedLanguages.add(lang);
});
highlighter = await createShikiHighlighter(themes, languages);
themes.forEach((theme) => loadedThemes.add(theme));
shikiToMonaco(highlighter, monaco);
editInstance = monaco.editor.create(target, {
value: options.codeValue,
language: defaultLanguage,
theme: defaultTheme,
contextmenu: !options.contextMenu,
// 禁用默认右键菜单
automaticLayout: true,
// 启用自动布局
minimap: { enabled: true },
fontSize: 16,
...options
});
if (options.contextMenu?.enabled !== false) {
setupCustomContextMenu();
}
return editInstance;
} catch (error) {
throw error;
}
}
async function createShikiHighlighter(themes, langs) {
return await createHighlighter({
themes,
langs
});
}
function registerLanguage(language) {
monaco.languages.register({ id: language });
}
async function setLanguage(language) {
if (!editInstance) {
throw new Error("Editor instance not initialized");
}
try {
if (!loadedLanguages.has(language)) {
monaco.languages.register({ id: language });
loadedLanguages.add(language);
const newLanguages = Array.from(loadedLanguages);
options.languages = newLanguages;
if (highlighter) {
highlighter = await createShikiHighlighter(
Array.from(loadedThemes),
newLanguages
);
shikiToMonaco(highlighter, monaco);
}
}
const model = editInstance.getModel();
if (model) {
monaco.editor.setModelLanguage(model, language);
}
} catch (error) {
throw error;
}
}
async function setTheme(theme) {
if (!editInstance) {
throw new Error("Editor instance not initialized");
}
try {
if (!loadedThemes.has(theme)) {
loadedThemes.add(theme);
const newThemes = Array.from(loadedThemes);
options.themes = newThemes;
if (highlighter) {
highlighter = await createShikiHighlighter(
newThemes,
Array.from(loadedLanguages)
);
shikiToMonaco(highlighter, monaco);
}
}
monaco.editor.setTheme(theme);
} catch (error) {
throw error;
}
}
function destroy() {
if (editInstance) {
const domNode = editInstance.getDomNode();
if (domNode) {
domNode.removeEventListener("contextmenu", handleContextMenu);
}
editInstance.dispose();
}
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
contextMenuCallback = null;
minimapContextMenuCallback = null;
}
function layout() {
if (editInstance) {
editInstance.layout();
}
}
function enableAutoResize() {
if (!editInstance || autoResizeEnabled) return;
try {
resizeObserver = new ResizeObserver(() => {
if (editInstance) {
requestAnimationFrame(() => {
editInstance?.layout();
});
}
});
resizeObserver.observe(options.target);
autoResizeEnabled = true;
} catch (error) {
}
}
function disableAutoResize() {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
autoResizeEnabled = false;
}
}
function setupCustomContextMenu() {
if (!editInstance) return;
const domNode = editInstance.getDomNode();
if (domNode) {
domNode.addEventListener("contextmenu", handleContextMenu);
}
}
function handleContextMenu(event) {
event.preventDefault();
event.stopPropagation();
const target = event.target;
const isMinimapClick = target && (target.closest(".minimap") || target.closest(".minimap-slider") || target.closest(".minimap-decorations-layer") || target.closest(".minimap-shadow-visible") || target.classList.contains("minimap"));
if (isMinimapClick && minimapContextMenuCallback) {
minimapContextMenuCallback(event);
} else if (contextMenuCallback) {
contextMenuCallback(event);
}
}
function onContextMenu(callback) {
contextMenuCallback = callback;
}
function onMinimapContextMenu(callback) {
minimapContextMenuCallback = callback;
}
function offContextMenu() {
contextMenuCallback = null;
}
function offMinimapContextMenu() {
minimapContextMenuCallback = null;
}
return {
initMonacoEdit,
destroy,
registerLanguage,
setTheme,
setLanguage,
layout,
enableAutoResize,
disableAutoResize,
editInstance,
onContextMenu,
offContextMenu,
onMinimapContextMenu,
offMinimapContextMenu
};
}
export {
useMonacoEdit as u
};
//# sourceMappingURL=index-Bl0GB3kH.js.map