以前项目是用ace编辑器的,但是总有些不敬人意的地方。前端事件看见的VS Code编辑器Monaco Editor准备更换下,下面介绍一些使用中遇到的一点问题。代码提示

 1.项目引用

  1. import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';

项目中引用了editor.api.js,但是这个文件不包含一些默认的语言和插件,所以在使用的时候,还需要我们自己import

  1. import 'monaco-editor/esm/vs/basic-languages/mysql/mysql.contribution';
  2. import 'monaco-editor/esm/vs/editor/contrib/suggest/suggestController.js';
  3. import 'monaco-editor/esm/vs/editor/contrib/bracketMatching/bracketMatching.js';
  4. import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js';

如果嫌麻烦我们也可以使用editor.all.js

2.react组件封装

可以使用github项目,https://github.com/superRaytin/react-monaco-editor,也可以拿来项目里面改下,比较简单

其实在componentDidUpdate的方法中,使用这个方法this.editor.setValue,undo不能撤回上次的value,

如果项目中有别的需求可以使用

  1. var model = this.editor.getModel();
  2. model.pushEditOperations(
  3. [],
  4. [
  5. {
  6. range: model.getFullModelRange(),
  7. text: prevProps.value
  8. }
  9. ]
  10. );

onDidChangeModelContent,方法产生的监听需要在组件销毁的时候dispose下

3.编辑器参数配置

查看以下代码文件 monaco-editor/esm/vs/editor/common/config/commonEditorConfig.js

minimap,scrollBeyondLastLine,Suggestion,snippet相关的

4.在光标处插入文本

  跟ace使用差别比较大

  1. var position = editor.getPosition();
  2. editor.executeEdits('', [
  3. {
  4. range: {
  5. startLineNumber: position.lineNumber,
  6. startColumn: position.column,
  7. endLineNumber: position.lineNumber,
  8. endColumn: position.column
  9. },
  10. text: 'test'
  11. }
  12. ]);

5.代码自动完成

下面代码是引用了monaco-editor自带的mysql的语法高亮里面的定义,设置的代码提示

  1. import { language as mysqlLanguage } from 'monaco-editor/esm/vs/basic-languages/mysql/mysql.js';
  2. monaco.languages.registerCompletionItemProvider('mysql', {
  3. provideCompletionItems: function(model, position) {
  4. // get editor content before the pointer
  5. var textUntilPosition = model.getValueInRange({
  6. startLineNumber: position.lineNumber,
  7. startColumn: 1,
  8. endLineNumber: position.lineNumber,
  9. endColumn: position.column
  10. });
  11. var match = textUntilPosition.match(/(\S+)$/);
  12. if (!match) return [];
  13. match = match[0].toUpperCase();
  14. var suggestions = [];
  15. mysqlLanguage.keywords.forEach(item => {
  16. if (item.indexOf(match) !== -1) {
  17. suggestions.push({
  18. label: item,
  19. kind: monaco.languages.CompletionItemKind.Keyword,
  20. insertText: item
  21. });
  22. }
  23. });
  24. mysqlLanguage.operators.forEach(item => {
  25. if (item.indexOf(match) !== -1) {
  26. suggestions.push({
  27. label: item,
  28. kind: monaco.languages.CompletionItemKind.Operator,
  29. insertText: item
  30. });
  31. }
  32. });
  33. mysqlLanguage.builtinFunctions.forEach(item => {
  34. if (item.indexOf(match) !== -1) {
  35. suggestions.push({
  36. label: item,
  37. kind: monaco.languages.CompletionItemKind.Function,
  38. insertText: item
  39. });
  40. }
  41. });
  42. return {
  43. suggestions
  44. };
  45. }
  46. });

如果你想增加代码片段,也可以直接添加下面的信息

  1. {
  2. label: 'ifelse',
  3. kind: monaco.languages.CompletionItemKind.Snippet,
  4. insertText: ['if (${1:condition}) {', '\t$0', '} else {', '\t', '}'].join('\n'),
  5. insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
  6. documentation: 'If-Else Statement'
  7. }

使用中发现,编辑器自带的默认的变量提示,在提供了自定义的registerCompletionItemProvider后会失效,暂时没找到什么好方法

默认的变量提示 monaco-editor/esm/vs/editor/common/services/editorWorkerServiceImpl.js

  1. _this._register(modes.CompletionProviderRegistry.register('*', new WordBasedCompletionItemProvider(_this._workerManager, configurationService, _this._modelService)));

monaco-editor/esm/vs/editor/contrib/suggest/suggest.js

会根据注册的Provider的分组,语言默认的优先级不高,没有分到一组,找到了结果就不再会执行下面的组

6.语法高亮

官网的文档蛮详细的,和ace的差别不是很大,虽然我也没怎么看懂

  https://microsoft.github.io/monaco-editor/monarch.html

可以在项目中找个相似的语言抄抄改改,结合着看官方文档

monaco-editor/esm/vs/basic-languages

高亮的样式需要在定义主题来对应,不是完全通过css处理的

  1. monaco.editor.defineTheme('ace', {
  2. base: 'vs',
  3. inherit: true,
  4. rules: [
  5. { token: '', foreground: '5c6773' },
  6. { token: 'invalid', foreground: 'ff3333' },
  7. { token: 'emphasis', fontStyle: 'italic' },
  8. { token: 'strong', fontStyle: 'bold' },
  9. { token: 'variable', foreground: '5c6773' },
  10. { token: 'variable.predefined', foreground: '5c6773' },
  11. { token: 'constant', foreground: 'f08c36' },
  12. ]
  13. });

  7.语法检测

语法检测,就需要编写对应的语法编译逻辑,这个不同语言不同的写法,一些也有现成的。这边主要介绍下怎么和编辑器交互,显示错误信息

错误信息hover显示需要插件 import 'monaco-editor/esm/vs/editor/contrib/hover/hover.js';

  1. //清楚mark
  2. monaco.editor.setModelMarkers(model, 'eslint', []);
  3. //添加mark
  4. monaco.editor.setModelMarkers(model, 'eslint', [
  5. {
  6. startLineNumber: 2,
  7. endLineNumber: 2,
  8. startColumn: 2,
  9. endColumn: 4,
  10. message: 'Syntax error',
  11. severity: 3,
  12. source: 'ESLint',
  13. code: 'asdasdas'
  14. }
  15. ]);

对于上面的一些配置信息会对提示框有什么影响可以看下面的源码

monaco-editor/esm/vs/editor/common/services/modelServiceImpl.js  ModelMarkerHandler._createDecorationOption

  1. ModelMarkerHandler._createDecorationOption = function (marker) {
  2. var className;
  3. var color = undefined;
  4. var zIndex;
  5. var inlineClassName = undefined;
  6. switch (marker.severity) {
  7. case MarkerSeverity.Hint:
  8. if (marker.tags && marker.tags.indexOf(1 /* Unnecessary */) >= 0) {
  9. className = "squiggly-unnecessary" /* EditorUnnecessaryDecoration */;
  10. }
  11. else {
  12. className = "squiggly-hint" /* EditorHintDecoration */;
  13. }
  14. zIndex = 0;
  15. break;
  16. case MarkerSeverity.Warning:
  17. className = "squiggly-warning" /* EditorWarningDecoration */;
  18. color = themeColorFromId(overviewRulerWarning);
  19. zIndex = 20;
  20. break;
  21. case MarkerSeverity.Info:
  22. className = "squiggly-info" /* EditorInfoDecoration */;
  23. color = themeColorFromId(overviewRulerInfo);
  24. zIndex = 10;
  25. break;
  26. case MarkerSeverity.Error:
  27. default:
  28. className = "squiggly-error" /* EditorErrorDecoration */;
  29. color = themeColorFromId(overviewRulerError);
  30. zIndex = 30;
  31. break;
  32. }
  33. if (marker.tags) {
  34. if (marker.tags.indexOf(1 /* Unnecessary */) !== -1) {
  35. inlineClassName = "squiggly-inline-unnecessary" /* EditorUnnecessaryInlineDecoration */;
  36. }
  37. }
  38. var hoverMessage = null;
  39. var message = marker.message, source = marker.source, relatedInformation = marker.relatedInformation, code = marker.code;
  40. if (typeof message === 'string') {
  41. message = message.trim();
  42. if (source) {
  43. if (/\n/g.test(message)) {
  44. if (code) {
  45. message = nls.localize('diagAndSourceAndCodeMultiline', "[{0}]\n{1} [{2}]", source, message, code);
  46. }
  47. else {
  48. message = nls.localize('diagAndSourceMultiline', "[{0}]\n{1}", source, message);
  49. }
  50. }
  51. else {
  52. if (code) {
  53. message = nls.localize('diagAndSourceAndCode', "[{0}] {1} [{2}]", source, message, code);
  54. }
  55. else {
  56. message = nls.localize('diagAndSource', "[{0}] {1}", source, message);
  57. }
  58. }
  59. }
  60. hoverMessage = new MarkdownString().appendCodeblock('_', message);
  61. if (!isFalsyOrEmpty(relatedInformation)) {
  62. hoverMessage.appendMarkdown('\n');
  63. for (var _i = 0, _a = relatedInformation; _i < _a.length; _i++) {
  64. var _b = _a[_i], message_1 = _b.message, resource = _b.resource, startLineNumber = _b.startLineNumber, startColumn = _b.startColumn;
  65. hoverMessage.appendMarkdown("* [" + basename(resource.path) + "(" + startLineNumber + ", " + startColumn + ")](" + resource.toString(false) + "#" + startLineNumber + "," + startColumn + "): ");
  66. hoverMessage.appendText("" + message_1);
  67. hoverMessage.appendMarkdown('\n');
  68. }
  69. hoverMessage.appendMarkdown('\n');
  70. }
  71. }

Monaco Editor 使用入门的更多相关文章

  1. monaco editor + vue的配置

    monaco editor是vscode的御用编辑器. 功能非常强大,使用方便轻巧,对js\ts等等语言支持都良好,能方便的扩展以支持其他语言或者自定义的特性. 夸了这么多,这里只说它一个问题: 这货 ...

  2. react & monaco editor & vs code

    react & monaco editor & vs code monaco-editor https://microsoft.github.io/monaco-editor/inde ...

  3. monaco editor 实现自定义提示(sql为例)

    monaco editor :https://www.cnblogs.com/XHappyness/p/9414177.html 这里实现自己定义的提示: .vue <template> ...

  4. Vue cli2.0 项目中使用Monaco Editor编辑器

    monaco-editor 是微软出的一条开源web在线编辑器支持多种语言,代码高亮,代码提示等功能,与Visual Studio Code 功能几乎相同. 在项目中可能会用带代码编辑功能,或者展示代 ...

  5. 【软工】[技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE

    [技术博客] 用Monaco Editor打造接近vscode体验的浏览器IDE 官方文档与重要参考资料 官方demo 官方API调用样例 Playground 官方API Doc,但其搜索框不支持模 ...

  6. js 在浏览器中使用 monaco editor

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  7. 使用 TypeScript,React,ANTLR 和 Monaco Editor 创建一个自定义 Web 编辑器(二)

    译文来源 欢迎阅读如何使用 TypeScript, React, ANTLR4, Monaco Editor 创建一个自定义 Web 编辑器系列的第二章节, 在这之前建议您阅读使用 TypeScrip ...

  8. Asp.Net Core 使用Monaco Editor 实现代码编辑器

    在项目中经常有代码在线编辑的需求,比如修改基于Xml的配置文件,编辑Json格式的测试数据等.我们可以使用微软开源的在线代码编辑器Monaco Editor实现这些功能.Monaco Editor是著 ...

  9. 手把手教你实现在Monaco Editor中使用VSCode主题

    背景 笔者开源了一个小项目code-run,类似codepen的一个工具,其中代码编辑器使用的是微软的Monaco Editor,这个库是直接从VSCode的源码中生成的,只不过是做了一点修改让它支持 ...

随机推荐

  1. vue的全局指令

    vue有四个全局指令:directive.extent.set.component directive:自定义指令 //写一个改变颜色的指令 Vue.directive('amie',function ...

  2. Java基础-面向接口编程-JDBC详解

    Java基础-面向接口编程-JDBC详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.JDBC概念和数据库驱动程序 JDBC(Java Data Base Connectiv ...

  3. vue-router 实践

    1. vue-router2学习实践笔记 2. router.push() 3. 使用vue-router跳转页面

  4. PHP超级全局变量

    $_get:地址栏上获取值 $_post:post表单发送数据 $_request:即有get也有post的内容 如果post和get重名:那么由设置项决定,比如request_crder=" ...

  5. NCPC2016-E- Exponial

    题目描述 Illustration of exponial(3) (not to scale), Picture by C.M. de Talleyrand-Périgord via Wikimedi ...

  6. http协议POST请求头content-type主要的四种取值

    介绍: 在此之前对content-type理解很肤浅,因此必须记录下来现在的理解,以便回顾 Content-Type,从名字上可以理解为内容类型,但在互联网上专业术语叫“媒体类型”,即MediaTyp ...

  7. 逻辑控制之While循环控制器(While Controller)

    测试环境 apache-jmeter-3.0 1.   添加While Controller 右键线程组->添加->逻辑控制器->响应断言 2.   控制面板介绍 添加后,面板如下 ...

  8. [整理]C语言中字符常量与ASCII码

    所有的ASCII码都可以用“\”加数字(一般是8进制数字)来表示.而C中定义了一些字母前加"\"来表示常见的那些不能显示的ASCII字符,如\0,\t,\n等,就称为转义字符,因为 ...

  9. iframe中的历史记录问题汇总及解决方案[转]

    在做页面统计的时候遇到了两个问题: 1.包含iframe的页面,在IE下按后退按钮不能刷新主页面.隐藏Iframe的src是统计程序的url,每点一次后退,就会发出一次页面加载时间请求. 2.由js动 ...

  10. 【JAVA】配置JAVA环境变量,安装Eclipse

    Java程序依赖JDK,就像C#程序依赖.NetFrameWork一样. 所以在开发之前,必须在win7或者是linux上,安装jdk(JavaDevelopkit)里面包括java一些工具,还有JR ...