vue-use-monaco
Version:
A Vue library for integrating Monaco Editor with Shiki syntax highlighting, supporting real-time updates.
195 lines (193 loc) • 12.6 kB
TypeScript
import * as monaco_editor0 from "monaco-editor";
import * as monaco$1 from "monaco-editor";
import * as monaco from "monaco-editor";
import { SpecialTheme, ThemeInput } from "shiki";
//#region src/type.d.ts
type MonacoEditorInstance = monaco$1.editor.IStandaloneCodeEditor;
type MonacoDiffEditorInstance = monaco$1.editor.IStandaloneDiffEditor;
type MonacoTheme = 'andromeeda' | 'aurora-x' | 'ayu-dark' | 'catppuccin-frappe' | 'catppuccin-latte' | 'catppuccin-macchiato' | 'catppuccin-mocha' | 'dark-plus' | 'dracula' | 'dracula-soft' | 'everforest-dark' | 'everforest-light' | 'github-dark' | 'github-dark-default' | 'github-dark-dimmed' | 'github-dark-high-contrast' | 'github-light' | 'github-light-default' | 'github-light-high-contrast' | 'gruvbox-dark-hard' | 'gruvbox-dark-medium' | 'gruvbox-dark-soft' | 'gruvbox-light-hard' | 'gruvbox-light-medium' | 'gruvbox-light-soft' | 'houston' | 'kanagawa-dragon' | 'kanagawa-lotus' | 'kanagawa-wave' | 'laserwave' | 'light-plus' | 'material-theme' | 'material-theme-darker' | 'material-theme-lighter' | 'material-theme-ocean' | 'material-theme-palenight' | 'min-dark' | 'min-light' | 'monokai' | 'night-owl' | 'nord' | 'one-dark-pro' | 'one-light' | 'plastic' | 'poimandres' | 'red' | 'rose-pine' | 'rose-pine-dawn' | 'rose-pine-moon' | 'slack-dark' | 'slack-ochin' | 'snazzy-light' | 'solarized-dark' | 'solarized-light' | 'synthwave-84' | 'tokyo-night' | 'vesper' | 'vitesse-black' | 'vitesse-dark' | 'vitesse-light' | ThemeInput | string | SpecialTheme;
type MonacoLanguage = 'abap' | 'actionscript-3' | 'ada' | 'angular-html' | 'angular-ts' | 'apache' | 'apex' | 'apl' | 'applescript' | 'ara' | 'asciidoc' | 'asm' | 'astro' | 'awk' | 'ballerina' | 'bat' | 'beancount' | 'berry' | 'bibtex' | 'bicep' | 'blade' | 'bsl' | 'c' | 'cadence' | 'cairo' | 'clarity' | 'clojure' | 'cmake' | 'cobol' | 'codeowners' | 'codeql' | 'coffee' | 'common-lisp' | 'coq' | 'cpp' | 'crystal' | 'csharp' | 'css' | 'csv' | 'cue' | 'cypher' | 'd' | 'dart' | 'dax' | 'desktop' | 'diff' | 'docker' | 'dotenv' | 'dream-maker' | 'edge' | 'elixir' | 'elm' | 'emacs-lisp' | 'erb' | 'erlang' | 'fennel' | 'fish' | 'fluent' | 'fortran-fixed-form' | 'fortran-free-form' | 'fsharp' | 'gdresource' | 'gdscript' | 'gdshader' | 'genie' | 'gherkin' | 'git-commit' | 'git-rebase' | 'gleam' | 'glimmer-js' | 'glimmer-ts' | 'glsl' | 'gnuplot' | 'go' | 'graphql' | 'groovy' | 'hack' | 'haml' | 'handlebars' | 'haskell' | 'haxe' | 'hcl' | 'hjson' | 'hlsl' | 'html' | 'html-derivative' | 'http' | 'hxml' | 'hy' | 'imba' | 'ini' | 'java' | 'javascript' | 'jinja' | 'jison' | 'json' | 'json5' | 'jsonc' | 'jsonl' | 'jsonnet' | 'jssm' | 'jsx' | 'julia' | 'kotlin' | 'kusto' | 'latex' | 'lean' | 'less' | 'liquid' | 'llvm' | 'log' | 'logo' | 'lua' | 'luau' | 'make' | 'markdown' | 'marko' | 'matlab' | 'mdc' | 'mdx' | 'mermaid' | 'mipsasm' | 'mojo' | 'move' | 'narrat' | 'nextflow' | 'nginx' | 'nim' | 'nix' | 'nushell' | 'objective-c' | 'objective-cpp' | 'ocaml' | 'pascal' | 'perl' | 'php' | 'plsql' | 'po' | 'polar' | 'postcss' | 'powerquery' | 'powershell' | 'prisma' | 'prolog' | 'proto' | 'pug' | 'puppet' | 'purescript' | 'python' | 'qml' | 'qmldir' | 'qss' | 'r' | 'racket' | 'raku' | 'razor' | 'reg' | 'regexp' | 'rel' | 'riscv' | 'rst' | 'ruby' | 'rust' | 'sas' | 'sass' | 'scala' | 'scheme' | 'scss' | 'sdbl' | 'shaderlab' | 'shellscript' | 'shellsession' | 'smalltalk' | 'solidity' | 'soy' | 'sparql' | 'splunk' | 'sql' | 'ssh-config' | 'stata' | 'stylus' | 'svelte' | 'swift' | 'system-verilog' | 'systemd' | 'talonscript' | 'tasl' | 'tcl' | 'templ' | 'terraform' | 'tex' | 'toml' | 'ts-tags' | 'tsv' | 'tsx' | 'turtle' | 'twig' | 'typescript' | 'typespec' | 'typst' | 'v' | 'vala' | 'vb' | 'verilog' | 'vhdl' | 'viml' | 'vue' | 'vue-html' | 'vyper' | 'wasm' | 'wenyan' | 'wgsl' | 'wikitext' | 'wit' | 'wolfram' | 'xml' | 'xsl' | 'yaml' | 'zenscript' | 'zig' | string;
interface MonacoOptions extends monaco$1.editor.IStandaloneEditorConstructionOptions {
MAX_HEIGHT?: number | string;
readOnly?: boolean;
themes?: MonacoTheme[];
languages?: MonacoLanguage[];
theme?: string;
isCleanOnBeforeCreate?: boolean;
/**
* 控制更新时的自动滚动行为:当为 true 时,如果当前接近底部则在新增内容后自动滚动到底部;
* 当为 false 时,将完全禁用自动滚动。
* 默认 true。
*/
autoScrollOnUpdate?: boolean;
/**
* 编辑器创建时是否默认启用自动滚动。用户一旦滚离底部将自动暂停,回到底部附近再恢复。
* 默认 true(保持原有行为)。
*/
autoScrollInitial?: boolean;
/**
* 触发“接近底部”的绝对像素阈值。如果设置,将与 autoScrollThresholdLines 共同取最大值。
* 默认 32。
*/
autoScrollThresholdPx?: number;
/**
* 触发“接近底部”的相对行数阈值(以当前行高计算)。如果设置,将与 autoScrollThresholdPx 共同取最大值。
* 默认 2 行。
*/
autoScrollThresholdLines?: number;
/**
* 是否启用 Diff 编辑器 modified 侧的自动滚动逻辑。
* 当为 false 时,updateDiff/appendModified 等不会触发自动滚动。
* 默认 true(与单编辑器体验保持一致)。
*/
diffAutoScroll?: boolean;
onBeforeCreate?: (monaco: typeof monaco_editor0) => monaco$1.IDisposable[];
}
//#endregion
//#region src/code.detect.d.ts
/**
* @module detect
* (Language detector)
*/
/**
* Supported language identifiers
*/
type CodeLanguage = 'bash' | 'html' | 'http' | 'js' | 'ts' | 'py' | 'sql' | 'pl' | 'lua' | 'make' | 'uri' | 'css' | 'diff' | 'md' | 'docker' | 'xml' | 'c' | 'rs' | 'go' | 'java' | 'asm' | 'json' | 'yaml' | 'toml' | 'mermaid' | 'plain';
/**
* Language detection feature with pattern and score
*/
type LanguageFeature = [RegExp, number];
/**
* Language definition with identifier and detection features
*/
type LanguageDefinition = [CodeLanguage, ...LanguageFeature[]];
/**
* Language detection definitions
*/
/**
* Try to find the language the given code belongs to
*
* @param {string} code The code to analyze
* @param {LanguageDefinition[]} [additionalLanguages] Additional language definitions to supplement the built-in ones
* @returns {CodeLanguage} The detected language of the code
*/
declare function detectLanguage(code: string, additionalLanguages?: LanguageDefinition[]): CodeLanguage;
//#endregion
//#region src/preloadMonacoWorkers.d.ts
declare function preloadMonacoWorkers(options?: {
/**
* If true, also fetch each worker URL to warm the HTTP cache (best-effort).
*/
fetch?: boolean;
}): Promise<void>;
//#endregion
//#region src/index.d.ts
/**
* useMonaco 组合式函数
*
* 提供 Monaco 编辑器的创建、销毁、内容/主题/语言更新等能力。
* 支持主题自动切换、语言高亮、代码更新等功能。
*
* @param {MonacoOptions} [monacoOptions] - 编辑器初始化配置,支持 Monaco 原生配置及扩展项
* @param {number | string} [monacoOptions.MAX_HEIGHT] - 编辑器最大高度,可以是数字(像素)或 CSS 字符串(如 '100%', 'calc(100vh - 100px)')
* @param {boolean} [monacoOptions.readOnly] - 是否为只读模式
* @param {MonacoTheme[]} [monacoOptions.themes] - 主题数组,至少包含两个主题:[暗色主题, 亮色主题]
* @param {MonacoLanguage[]} [monacoOptions.languages] - 支持的编程语言数组
* @param {string} [monacoOptions.theme] - 初始主题名称
* @param {boolean} [monacoOptions.isCleanOnBeforeCreate] - 是否在创建前清理之前注册的资源, 默认为 true
* @param {(monaco: typeof import('monaco-editor')) => monaco.IDisposable[]} [monacoOptions.onBeforeCreate] - 编辑器创建前的钩子函数
*
* @returns {{
* createEditor: (container: HTMLElement, code: string, language: string) => Promise<monaco.editor.IStandaloneCodeEditor>,
* createDiffEditor: (
* container: HTMLElement,
* originalCode: string,
* modifiedCode: string,
* language: string,
* ) => Promise<monaco.editor.IStandaloneDiffEditor>,
* cleanupEditor: () => void,
* updateCode: (newCode: string, codeLanguage: string) => void,
* appendCode: (appendText: string, codeLanguage?: string) => void,
* updateDiff: (
* originalCode: string,
* modifiedCode: string,
* codeLanguage?: string,
* ) => void,
* updateOriginal: (newCode: string, codeLanguage?: string) => void,
* updateModified: (newCode: string, codeLanguage?: string) => void,
* appendOriginal: (appendText: string, codeLanguage?: string) => void,
* appendModified: (appendText: string, codeLanguage?: string) => void,
* setTheme: (theme: MonacoTheme) => void,
* setLanguage: (language: MonacoLanguage) => void,
* getCurrentTheme: () => string,
* getEditor: () => typeof monaco.editor,
* getEditorView: () => monaco.editor.IStandaloneCodeEditor | null,
* getDiffEditorView: () => monaco.editor.IStandaloneDiffEditor | null,
* getDiffModels: () => { original: monaco.editor.ITextModel | null, modified: monaco.editor.ITextModel | null },
* }} 返回对象包含以下方法和属性:
*
* @property {Function} createEditor - 创建并挂载 Monaco 编辑器到指定容器
* @property {Function} cleanupEditor - 销毁编辑器并清理容器
* @property {Function} updateCode - 更新编辑器内容和语言,必要时滚动到底部
* @property {Function} appendCode - 在编辑器末尾追加文本,必要时滚动到底部
* @property {Function} createDiffEditor - 创建并挂载 Diff 编辑器
* @property {Function} updateDiff - 更新 Diff 编辑器的 original/modified 内容(RAF 合并、增量更新)
* @property {Function} updateOriginal - 仅更新 Diff 的 original 内容(增量更新)
* @property {Function} updateModified - 仅更新 Diff 的 modified 内容(增量更新)
* @property {Function} appendOriginal - 在 Diff 的 original 末尾追加(显式流式场景)
* @property {Function} appendModified - 在 Diff 的 modified 末尾追加(显式流式场景)
* @property {Function} setTheme - 切换编辑器主题
* @property {Function} setLanguage - 切换编辑器语言
* @property {Function} getCurrentTheme - 获取当前主题名称
* @property {Function} getEditor - 获取 Monaco 的静态 editor 对象(用于静态方法调用)
* @property {Function} getEditorView - 获取当前编辑器实例
* @property {Function} getDiffEditorView - 获取当前 Diff 编辑器实例
* @property {Function} getDiffModels - 获取 Diff 的 original/modified 两个模型
*
* @throws {Error} 当主题数组不是数组或长度小于2时抛出错误
*
* @example
* ```typescript
* import { useMonaco } from 'vue-use-monaco'
*
* const { createEditor, updateCode, setTheme } = useMonaco({
* themes: ['vitesse-dark', 'vitesse-light'],
* languages: ['javascript', 'typescript'],
* readOnly: false
* })
*
* // 创建编辑器
* const editor = await createEditor(containerRef.value, 'console.log("hello")', 'javascript')
*
* // 更新代码
* updateCode('console.log("world")', 'javascript')
*
* // 切换主题
* setTheme('vitesse-light')
* ```
*/
declare function useMonaco(monacoOptions?: MonacoOptions): {
createEditor: (container: HTMLElement, code: string, language: string) => Promise<monaco.editor.IStandaloneCodeEditor>;
createDiffEditor: (container: HTMLElement, originalCode: string, modifiedCode: string, language: string) => Promise<monaco.editor.IStandaloneDiffEditor>;
cleanupEditor: () => void;
safeClean(): void;
updateCode: (newCode: string, codeLanguage: string) => void;
appendCode: (appendText: string, codeLanguage?: string) => void;
updateDiff: (originalCode: string, modifiedCode: string, codeLanguage?: string) => void;
updateOriginal: (newCode: string, codeLanguage?: string) => void;
updateModified: (newCode: string, codeLanguage?: string) => void;
appendOriginal: (appendText: string, codeLanguage?: string) => void;
appendModified: (appendText: string, codeLanguage?: string) => void;
setTheme(theme: MonacoTheme): void;
setLanguage(language: MonacoLanguage): void;
getCurrentTheme(): string;
getEditor(): typeof monaco.editor;
getEditorView(): monaco.editor.IStandaloneCodeEditor | null;
getDiffEditorView(): monaco.editor.IStandaloneDiffEditor | null;
getDiffModels(): {
original: monaco.editor.ITextModel | null;
modified: monaco.editor.ITextModel | null;
};
};
//#endregion
export { MonacoDiffEditorInstance, MonacoEditorInstance, MonacoLanguage, MonacoOptions, MonacoTheme, detectLanguage, preloadMonacoWorkers, useMonaco };