chainWebpack: (config) => {config.plugin("monaco-editor").use(MonacoWebpackPlugin, [{// Languages are loaded on demand at runtimelanguages: ["json", "javascript", "html", "xml"],},]);},
monaco 静态方法
export namespace editor
monaco.editor.create
export function create(domElement: HTMLElement, options?: IStandaloneEditorConstructionOptions, override?: IEditorOverrideServices): IStandaloneCodeEditor;export interface IStandaloneEditorConstructionOptions extends IEditorConstructionOptions, IGlobalEditorOptions {model?: ITextModel | null;value?: string;language?: string;theme?: string;autoDetectHighContrast?: boolean;accessibilityHelpUrl?: string;ariaContainerElement?: HTMLElement;acceptSuggestionOnCommitCharacter: true, // 接受关于提交字符的建议acceptSuggestionOnEnter: 'on', // 接受输入建议 "on" | "off" | "smart"accessibilityPageSize: 10, // 辅助功能页面大小 Number 说明:控制编辑器中可由屏幕阅读器读出的行数。警告:这对大于默认值的数字具有性能含义。accessibilitySupport: 'on', // 辅助功能支持 控制编辑器是否应在为屏幕阅读器优化的模式下运行。autoClosingBrackets: 'always', // 是否自动添加结束括号(包括中括号) "always" | "languageDefined" | "beforeWhitespace" | "never"autoClosingDelete: 'always', // 是否自动删除结束括号(包括中括号) "always" | "never" | "auto"autoClosingOvertype: 'always', // 是否关闭改写 即使用insert模式时是覆盖后面的文字还是不覆盖后面的文字 "always" | "never" | "auto"autoClosingQuotes: 'always', // 是否自动添加结束的单引号 双引号 "always" | "languageDefined" | "beforeWhitespace" | "never"autoIndent: 'None', // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进automaticLayout: true, // 自动布局codeLens: false, // 是否显示codeLens 通过 CodeLens,你可以在专注于工作的同时了解代码所发生的情况 – 而无需离开编辑器。 可以查找代码引用、代码更改、关联的 Bug、工作项、代码评审和单元测试。codeLensFontFamily: '', // codeLens的字体样式codeLensFontSize: 14, // codeLens的字体大小colorDecorators: false, // 呈现内联色彩装饰器和颜色选择器comments: {ignoreEmptyLines: true, // 插入行注释时忽略空行。默认为真。insertSpace: true // 在行注释标记之后和块注释标记内插入一个空格。默认为真。}, // 注释配置contextmenu?: true, // 启用右键菜单columnSelection: false, // 启用列编辑 按下shift键位然后按↑↓键位可以实现列选择 然后实现列编辑autoSurround: 'never', // 是否应自动环绕选择copyWithSyntaxHighlighting: true, // 是否应将语法突出显示复制到剪贴板中 即 当你复制到word中是否保持文字高亮颜色cursorBlinking: 'Solid', // 光标动画样式cursorSmoothCaretAnimation: true, // 是否启用光标平滑插入动画 当你在快速输入文字的时候 光标是直接平滑的移动还是直接"闪现"到当前文字所处位置cursorStyle: 'UnderlineThin', // "Block"|"BlockOutline"|"Line"|"LineThin"|"Underline"|"UnderlineThin" 光标样式cursorSurroundingLines: 0, // 光标环绕行数 当文字输入超过屏幕时 可以看见右侧滚动条中光标所处位置是在滚动条中间还是顶部还是底部 即光标环绕行数 环绕行数越大 光标在滚动条中位置越居中cursorSurroundingLinesStyle: 'all', // "default" | "all" 光标环绕样式cursorWidth: 2, // <=25 光标宽度minimap: {enabled: false // 是否启用预览图}, // 预览图设置folding: true, // 是否启用代码折叠links: true, // 是否点击链接overviewRulerBorder: false, // 是否应围绕概览标尺绘制边框renderLineHighlight: 'gutter', // 当前行突出显示方式roundedSelection: false, // 选区是否有圆角scrollBeyondLastLine: false, // 设置编辑器是否可以滚动到最后一行之后readOnly: false, // 是否为只读模式theme: 'vs'// vs, hc-black, or vs-dark}
monaco.editor.createModel
Model是一个保存编辑状态的对象,里面含有语言信息,当前的编辑文本信息,标注信息等。所以我们可以缓存一下Model对象,在需要的时候直接调用setModel即可随时切换到之前的状态。或者也可以在初始化实例的时候设置一个Model。
/*** Create a new editor model.* You can specify the language that should be set for this model or let the language be inferred from the `uri`.*/export function createModel(value: string, language?: string, uri?: Uri): ITextModel;
const model=monaco.editor.createModel("hahahaha","javascript");monacoInstance = monaco.editor.create(this.monacoDom.current, {model:model})
TextModel的ts定义
export interface ITextModel {/*** Gets the resource associated with this editor model.*/readonly uri: Uri;/*** A unique identifier associated with this model.*/readonly id: string;/*** Get the resolved options for this model.*/getOptions(): TextModelResolvedOptions;/*** Get the current version id of the model.* Anytime a change happens to the model (even undo/redo),* the version id is incremented.*/getVersionId(): number;/*** Get the alternative version id of the model.* This alternative version id is not always incremented,* it will return the same values in the case of undo-redo.*/getAlternativeVersionId(): number;/*** Replace the entire text buffer value contained in this model.*/setValue(newValue: string): void;/*** Get the text stored in this model.* @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`.* @param preserverBOM Preserve a BOM character if it was detected when the model was constructed.* @return The text.*/getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string;/*** Get the length of the text stored in this model.*/getValueLength(eol?: EndOfLinePreference, preserveBOM?: boolean): number;/*** Get the text in a certain range.* @param range The range describing what text to get.* @param eol The end of line character preference. This will only be used for multiline ranges. Defaults to `EndOfLinePreference.TextDefined`.* @return The text.*/getValueInRange(range: IRange, eol?: EndOfLinePreference): string;/*** Get the length of text in a certain range.* @param range The range describing what text length to get.* @return The text length.*/getValueLengthInRange(range: IRange): number;/*** Get the character count of text in a certain range.* @param range The range describing what text length to get.*/getCharacterCountInRange(range: IRange): number;/*** Get the number of lines in the model.*/getLineCount(): number;/*** Get the text for a certain line.*/getLineContent(lineNumber: number): string;/*** Get the text length for a certain line.*/getLineLength(lineNumber: number): number;/*** Get the text for all lines.*/getLinesContent(): string[];/*** Get the end of line sequence predominantly used in the text buffer.* @return EOL char sequence (e.g.: '\n' or '\r\n').*/getEOL(): string;/*** Get the end of line sequence predominantly used in the text buffer.*/getEndOfLineSequence(): EndOfLineSequence;/*** Get the minimum legal column for line at `lineNumber`*/getLineMinColumn(lineNumber: number): number;/*** Get the maximum legal column for line at `lineNumber`*/getLineMaxColumn(lineNumber: number): number;/*** Returns the column before the first non whitespace character for line at `lineNumber`.* Returns 0 if line is empty or contains only whitespace.*/getLineFirstNonWhitespaceColumn(lineNumber: number): number;/*** Returns the column after the last non whitespace character for line at `lineNumber`.* Returns 0 if line is empty or contains only whitespace.*/getLineLastNonWhitespaceColumn(lineNumber: number): number;/*** Create a valid position,*/validatePosition(position: IPosition): Position;/*** Advances the given position by the given offset (negative offsets are also accepted)* and returns it as a new valid position.** If the offset and position are such that their combination goes beyond the beginning or* end of the model, throws an exception.** If the offset is such that the new position would be in the middle of a multi-byte* line terminator, throws an exception.*/modifyPosition(position: IPosition, offset: number): Position;/*** Create a valid range.*/validateRange(range: IRange): Range;/*** Converts the position to a zero-based offset.** The position will be [adjusted](#TextDocument.validatePosition).** @param position A position.* @return A valid zero-based offset.*/getOffsetAt(position: IPosition): number;/*** Converts a zero-based offset to a position.** @param offset A zero-based offset.* @return A valid [position](#Position).*/getPositionAt(offset: number): Position;/*** Get a range covering the entire model*/getFullModelRange(): Range;/*** Returns if the model was disposed or not.*/isDisposed(): boolean;/*** Search the model.* @param searchString The string used to search. If it is a regular expression, set `isRegex` to true.* @param searchOnlyEditableRange Limit the searching to only search inside the editable range of the model.* @param isRegex Used to indicate that `searchString` is a regular expression.* @param matchCase Force the matching to match lower/upper case exactly.* @param wordSeparators Force the matching to match entire words only. Pass null otherwise.* @param captureMatches The result will contain the captured groups.* @param limitResultCount Limit the number of results* @return The ranges where the matches are. It is empty if not matches have been found.*/findMatches(searchString: string,searchOnlyEditableRange: boolean,isRegex: boolean,matchCase: boolean,wordSeparators: string | null,captureMatches: boolean,limitResultCount?: number): FindMatch[];/*** Search the model.* @param searchString The string used to search. If it is a regular expression, set `isRegex` to true.* @param searchScope Limit the searching to only search inside these ranges.* @param isRegex Used to indicate that `searchString` is a regular expression.* @param matchCase Force the matching to match lower/upper case exactly.* @param wordSeparators Force the matching to match entire words only. Pass null otherwise.* @param captureMatches The result will contain the captured groups.* @param limitResultCount Limit the number of results* @return The ranges where the matches are. It is empty if no matches have been found.*/findMatches(searchString: string,searchScope: IRange | IRange[],isRegex: boolean,matchCase: boolean,wordSeparators: string | null,captureMatches: boolean,limitResultCount?: number): FindMatch[];/*** Search the model for the next match. Loops to the beginning of the model if needed.* @param searchString The string used to search. If it is a regular expression, set `isRegex` to true.* @param searchStart Start the searching at the specified position.* @param isRegex Used to indicate that `searchString` is a regular expression.* @param matchCase Force the matching to match lower/upper case exactly.* @param wordSeparators Force the matching to match entire words only. Pass null otherwise.* @param captureMatches The result will contain the captured groups.* @return The range where the next match is. It is null if no next match has been found.*/findNextMatch(searchString: string,searchStart: IPosition,isRegex: boolean,matchCase: boolean,wordSeparators: string | null,captureMatches: boolean): FindMatch | null;/*** Search the model for the previous match. Loops to the end of the model if needed.* @param searchString The string used to search. If it is a regular expression, set `isRegex` to true.* @param searchStart Start the searching at the specified position.* @param isRegex Used to indicate that `searchString` is a regular expression.* @param matchCase Force the matching to match lower/upper case exactly.* @param wordSeparators Force the matching to match entire words only. Pass null otherwise.* @param captureMatches The result will contain the captured groups.* @return The range where the previous match is. It is null if no previous match has been found.*/findPreviousMatch(searchString: string,searchStart: IPosition,isRegex: boolean,matchCase: boolean,wordSeparators: string | null,captureMatches: boolean): FindMatch | null;/*** Get the language associated with this model.*/getModeId(): string;/*** Get the word under or besides `position`.* @param position The position to look for a word.* @return The word under or besides `position`. Might be null.*/getWordAtPosition(position: IPosition): IWordAtPosition | null;/*** Get the word under or besides `position` trimmed to `position`.column* @param position The position to look for a word.* @return The word under or besides `position`. Will never be null.*/getWordUntilPosition(position: IPosition): IWordAtPosition;/*** Perform a minimum amount of operations, in order to transform the decorations* identified by `oldDecorations` to the decorations described by `newDecorations`* and returns the new identifiers associated with the resulting decorations.** @param oldDecorations Array containing previous decorations identifiers.* @param newDecorations Array describing what decorations should result after the call.* @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model.* @return An array containing the new decorations identifiers.*/deltaDecorations(oldDecorations: string[],newDecorations: IModelDeltaDecoration[],ownerId?: number): string[];/*** Get the options associated with a decoration.* @param id The decoration id.* @return The decoration options or null if the decoration was not found.*/getDecorationOptions(id: string): IModelDecorationOptions | null;/*** Get the range associated with a decoration.* @param id The decoration id.* @return The decoration range or null if the decoration was not found.*/getDecorationRange(id: string): Range | null;/*** Gets all the decorations for the line `lineNumber` as an array.* @param lineNumber The line number* @param ownerId If set, it will ignore decorations belonging to other owners.* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).* @return An array with the decorations*/getLineDecorations(lineNumber: number,ownerId?: number,filterOutValidation?: boolean): IModelDecoration[];/*** Gets all the decorations for the lines between `startLineNumber` and `endLineNumber` as an array.* @param startLineNumber The start line number* @param endLineNumber The end line number* @param ownerId If set, it will ignore decorations belonging to other owners.* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).* @return An array with the decorations*/getLinesDecorations(startLineNumber: number,endLineNumber: number,ownerId?: number,filterOutValidation?: boolean): IModelDecoration[];/*** Gets all the decorations in a range as an array. Only `startLineNumber` and `endLineNumber` from `range` are used for filtering.* So for now it returns all the decorations on the same line as `range`.* @param range The range to search in* @param ownerId If set, it will ignore decorations belonging to other owners.* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).* @return An array with the decorations*/getDecorationsInRange(range: IRange,ownerId?: number,filterOutValidation?: boolean): IModelDecoration[];/*** Gets all the decorations as an array.* @param ownerId If set, it will ignore decorations belonging to other owners.* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).*/getAllDecorations(ownerId?: number,filterOutValidation?: boolean): IModelDecoration[];/*** Gets all the decorations that should be rendered in the overview ruler as an array.* @param ownerId If set, it will ignore decorations belonging to other owners.* @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors).*/getOverviewRulerDecorations(ownerId?: number,filterOutValidation?: boolean): IModelDecoration[];/*** Gets all the decorations that contain injected text.* @param ownerId If set, it will ignore decorations belonging to other owners.*/getInjectedTextDecorations(ownerId?: number): IModelDecoration[];/*** Normalize a string containing whitespace according to indentation rules (converts to spaces or to tabs).*/normalizeIndentation(str: string): string;/*** Change the options of this model.*/updateOptions(newOpts: ITextModelUpdateOptions): void;/*** Detect the indentation options for this model from its content.*/detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void;/*** Close the current undo-redo element.* This offers a way to create an undo/redo stop point.*/pushStackElement(): void;/*** Open the current undo-redo element.* This offers a way to remove the current undo/redo stop point.*/popStackElement(): void;/*** Push edit operations, basically editing the model. This is the preferred way* of editing the model. The edit operations will land on the undo stack.* @param beforeCursorState The cursor state before the edit operations. This cursor state will be returned when `undo` or `redo` are invoked.* @param editOperations The edit operations.* @param cursorStateComputer A callback that can compute the resulting cursors state after the edit operations have been executed.* @return The cursor state returned by the `cursorStateComputer`.*/pushEditOperations(beforeCursorState: Selection[] | null,editOperations: IIdentifiedSingleEditOperation[],cursorStateComputer: ICursorStateComputer): Selection[] | null;/*** Change the end of line sequence. This is the preferred way of* changing the eol sequence. This will land on the undo stack.*/pushEOL(eol: EndOfLineSequence): void;/*** Edit the model without adding the edits to the undo stack.* This can have dire consequences on the undo stack! See @pushEditOperations for the preferred way.* @param operations The edit operations.* @return If desired, the inverse edit operations, that, when applied, will bring the model back to the previous state.*/applyEdits(operations: IIdentifiedSingleEditOperation[]): void;applyEdits(operations: IIdentifiedSingleEditOperation[],computeUndoEdits: false): void;applyEdits(operations: IIdentifiedSingleEditOperation[],computeUndoEdits: true): IValidEditOperation[];/*** Change the end of line sequence without recording in the undo stack.* This can have dire consequences on the undo stack! See @pushEOL for the preferred way.*/setEOL(eol: EndOfLineSequence): void;/*** An event emitted when the contents of the model have changed.* @event*/onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable;/*** An event emitted when decorations of the model have changed.* @event*/onDidChangeDecorations(listener: (e: IModelDecorationsChangedEvent) => void): IDisposable;/*** An event emitted when the model options have changed.* @event*/onDidChangeOptions(listener: (e: IModelOptionsChangedEvent) => void): IDisposable;/*** An event emitted when the language associated with the model has changed.* @event*/onDidChangeLanguage(listener: (e: IModelLanguageChangedEvent) => void): IDisposable;/*** An event emitted when the language configuration associated with the model has changed.* @event*/onDidChangeLanguageConfiguration(listener: (e: IModelLanguageConfigurationChangedEvent) => void): IDisposable;/*** An event emitted when the model has been attached to the first editor or detached from the last editor.* @event*/onDidChangeAttached(listener: () => void): IDisposable;/*** An event emitted right before disposing the model.* @event*/onWillDispose(listener: () => void): IDisposable;/*** Destroy this model. This will unbind the model from the mode* and make all necessary clean-up to release this object to the GC.*/dispose(): void;/*** Returns if this model is attached to an editor or not.*/isAttachedToEditor(): boolean;}

可以直接在model上绑定事件
model.onDidChangeContent((event)=>{...})// 相当于editor.onDidChangeModelContent(() => {const value = editor.getValue()})
Model最后也需要我们销毁,这里分两种情况,假如是通过createModel创建的Model,那么我们需要手动销毁,但是如果是monaco默认创建的,则不需要,在调用实例的销毁方法时,会顺带销毁默认创建的Model。
model.dispose();
在简单的场景下,Model的存在可能使得我们使用起来比较繁琐,但是,在复杂场景下,model可以极大的简化代码复杂性。
设想一下我们有5个tab,每个tab都是一个编辑器,每个编辑器都有各自的语言,内容和标注信息,如果没有Model,我们需要保存每个tab的语言,内容等信息,在切换到对应tab时再将这些信息初始化到编辑器上,但是利用Model,我们不需要额外去保存每个tab的编辑信息,只需要保存每个tab的Model,然后将Model传给编辑器进行初始化即可。
setModelLanguage
monaco.editor.setModelMarkers()
在编辑器中用波浪线标出错误提示。
monaco.editor.setModelMarkers(editor.getModel(), 'owner', [{startLineNumber,startColumn,endLineNumber,endColumn,message, // 提示文案severity: monaco.MarkerSeverity.Error, // marker 底部波浪线的信息等级 Hint,Info,Warning,Error},])
export namespace languages
monaco.languages.registerCompletionItemProvider
配置代码自动补全
monaco.languages.registerCompletionItemProvider('javascript', {provideCompletionItems:function(model, position){.......return {suggestions: [{label: '$:', // 显示的提示内容kind: monaco.languages.CompletionItemKind['Function'], // 用来显示提示内容后的不同的图标insertText: '$:', // 选择后粘贴到编辑器中的文字detail: '', // 提示内容后的说明range: range}]}}})
monacoCompletionProvide = monaco.languages.registerCompletionItemProvider('lua',{provideCompletionItems: function (model, position): any {// 获取当前行数const line = position.lineNumber// 获取当前列数const column = position.column// 获取当前输入行的内容const content = model.getLineContent(line)console.log('🚀 ~ 当前行 content', content)// 获取起始位置到当前位置的文本内容let textUntilPosition = model.getValueInRange({startLineNumber: 1, // position.lineNumberstartColumn: 1,endLineNumber: position.lineNumber,endColumn: position.column})console.log('🚀 ~ line 94 textUntilPosition', textUntilPosition)// 通过下标来获取当前光标后一个内容,即为刚输入的内容const sym = content[column - 2]// console.log('🚀 ~ file: Index.vue ~ line 84 ~ init ~ sym', sym)// 获取当前位置的 单词let word = model.getWordUntilPosition(position)// console.log('🚀 ~ file: Index.vue ~ line 88 ~ init ~ word', word)// 插入内容覆盖当前位置的单词let range = {startLineNumber: position.lineNumber,endLineNumber: position.lineNumber,startColumn: word.startColumn,endColumn: word.endColumn}// console.log('🚀 ~ file: Index.vue ~ line 112 ~ init ~ range', range)let suggestions = createCompleters(range, sym)// console.log('🚀 ~ suggestions', suggestions)return {suggestions: suggestions}},triggerCharacters: ['.']})
monaco 实例方法
export interface IEditor 编辑器实例方法
editor.dispose() 销毁实例
editor.getValue()
获取编辑器中的所有文本,并生成一个字符串返回,会保留所有信息(换行、缩进、注释等等)。
editor.setValue()
editor.updateOptions()
editor.getSelection()
获取编辑器中被选中文案的 range ,返回一个对象,如下:
{startLineNumber: 0,startColumnNumber: 0,endLineNumber: 0,endColumnNumber: 0,}
editor.getModel()
获取编辑器当前的 textmodel,一般不会直接使用,通过 textmodel 可以对文本各种操作。
editor.executeEdits()
在指定位置插入代码,跟 editor.setValue() 不同的地方是,可以用 “⌘ + Z” 撤销输入。
/*** Execute edits on the editor.* The edits will land on the undo-redo stack, but no "undo stop" will be pushed.* @param source The source of the call.* @param edits The edits to execute.* @param endCursorState Cursor state after the edits were applied.*/executeEdits(source: string | null | undefined, edits: IIdentifiedSingleEditOperation[], endCursorState?: ICursorStateComputer | Selection[]): boolean;/*** A single edit operation, that has an identifier.*/export interface IIdentifiedSingleEditOperation {/*** The range to replace. This can be empty to emulate a simple insert.*/range: IRange;/*** The text to replace with. This can be null to emulate a simple delete.*/text: string | null;/*** This indicates that this operation has "insert" semantics.* i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved.*/forceMoveMarkers?: boolean;}
editor.executeEdits('insert-code', [{range: {startLineNumber: 1,startColumn: 1,endLineNumber: 1,endColumn: 1,},text: 'text',},])
editor.addAction()
在右键菜单里增加一栏自定义的操作。
editor.addAction({id: '', // 菜单项 idlabel: '', // 菜单项名称keybindings: [this.monaco.KeyMod.CtrlCmd | this.monaco.KeyCode.KEY_J], // 绑定快捷键contextMenuGroupId: '9_cutcopypaste', // 所属菜单的分组run: () => {}, // 点击后执行的操作})
editor.getAction(‘actions.xxx’).run()
手动调用monaco方法。
//实现查找效果const model = editor.getModel();const range = model.findMatches('匹配的字符串或者正则表达式')[0].range;editor.setSelection(range);editor.getAction('actions.find').run();//实现拷贝效果editor.getAction('editor.action.clipboardCopyAction').run();//实现复制效果var selection = editor.getSelection();var content = localStorage.getItem('your-content');editor.executeEdits("", [{range: new monaco.Range(selection.endLineNumber, selection.endColumn, selection.endLineNumber, selection.endColumn),text: content}])
