使用微软Monaco Editor 编写代码比对工具

前言

微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VS Code,而Monaco Editor就是从这个项目中成长出来的一个web编辑器,所以Monaco Editor和VS Code在编辑代码,交互以及UI上几乎是一摸一样的,有点不同的是,两者的平台不一样,Monaco Editor基于浏览器,而VS Code基于electron,所以功能上VSCode更加健全,并且性能比较强大。本文主要介绍ng-zorro 框架集成Monaco Editor实现文本比对。Monaco Editor 不仅能做文本比对,同样可以做代码编辑器,可以查阅《使用微软Monaco Editor 编写在线调试工具》

环境及组件

Monaco Editor 微软 Monaco Editor 编辑器
Ant Design of Angular NG-ZORRO
ngx-monaco-editor monaco-editor angular npm 包

实现

根据 ngx-monaco-editor 文档按angular版本安装指定版本的npm包
注意:版本对应不上会导致资源404错误

  • Angular <= 4: v3.x.x
  • Angular 5: v5.x.x
  • Angular 6: v6.x.x
  • Angular 7: v7.x.x
  • Angular 8: v8.x.x
  • Angular 9: v9.x.x

npm install ngx-monaco-editor@6.0.0 --save

接下来配置全局静态资源
Angular 6 之前版本 添加到.angular-cli.json文件中

{
  "options": {
    {
      "assets": [
        { "glob": "**/*", "input": "node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/" }
      ],
      ...
    }
    ...
  },
  ...
}

Angular 6 之后版本 添加到.angular.json文件中

{
  "apps": [
    {
      "assets": [
        { "glob": "**/*", "input": "../node_modules/ngx-monaco-editor/assets/monaco", "output": "./assets/monaco/" }
      ],
      ...
    }
    ...
  ],
  ...
}

Angular 模块文件中配置 DiffEditorModule

import { NgModule } from '@angular/core';
import { DiffEditorRoutingModule } from './diff-editor-routing.module';
import { DiffEditorComponent } from './diff-editor.component';
import { NgZorroAntdModule } from 'ng-zorro-antd';
import { CommonModule } from '@angular/common';
import { ClipboardModule } from 'ngx-clipboard';
import { FormsModule } from '@angular/forms';
import { MonacoEditorModule } from 'ngx-monaco-editor';

@NgModule({
  imports: [
    CommonModule,
    DiffEditorRoutingModule,
    NgZorroAntdModule,
    ClipboardModule,
    FormsModule,
    MonacoEditorModule.forRoot(),
  ],
  declarations: [DiffEditorComponent],
  exports: [DiffEditorComponent]
})
export class DiffEditorModule { }

Monaco Editor 支持选择文本语言、编辑器主题等等配置,我们同样在页面上也支持这些配置项动态配置,结合阿里的NG-ZORRO框架,完整代码如下:

<div nz-row [nzGutter]="16">
  <div nz-col class="gutter-row" [nzSpan]="24" *ngIf="isCompared">
    <nz-select [(ngModel)]="selectedLang" class="lang-select ditor-config" (ngModelChange)="onChangeLanguage($event)">
      <nz-option *ngFor="let option of languages" [nzValue]="option" [nzLabel]="option"></nz-option>
    </nz-select>
    <nz-select [(ngModel)]="selectedTheme" class="lang-select ditor-config" (ngModelChange)="onChangeTheme($event)">
      <nz-option *ngFor="let option of themes" [nzValue]="option.value" [nzLabel]="option.name"></nz-option>
    </nz-select>
    <nz-switch class="ditor-config" [(ngModel)]="switchValue" [nzControl]="true" (click)="onChangeInline()" nzCheckedChildren="开启内联差异"
      nzUnCheckedChildren="关闭内联差异"></nz-switch>
    <button class="ditor-config" nz-button nzType="primary" (click)="onClear()">返回</button>
  </div>
  <div nz-col class="gutter-row diff-editor-row" [nzSpan]="24" *ngIf="isCompared">
    <ngx-monaco-diff-editor style="height: 100%" [options]="options" [originalModel]="originalModel" [modifiedModel]="modifiedModel">
    </ngx-monaco-diff-editor>
  </div>
  <div nz-col class="gutter-row" [nzSpan]="24" *ngIf="!isCompared">
    <button class="ditor-config" nz-button nzType="primary" (click)="onCompare()">比对文本</button>
  </div>

  <div nz-col class="gutter-row" [nzSpan]="12" *ngIf="!isCompared">
    <textarea nz-input placeholder="请输入比对文本" [nzAutosize]="{ minRows: 10, maxRows: 29 }" [(ngModel)]="text1"></textarea>
  </div>
  <div nz-col class="gutter-row" [nzSpan]="12" *ngIf="!isCompared">
    <textarea nz-input placeholder="请输入比对文本" [nzAutosize]="{ minRows: 10, maxRows: 29 }" [(ngModel)]="text2"></textarea>
  </div>
</div>
import { Component, Input, OnInit, Output } from '@angular/core';
import { DiffEditorModel } from "ngx-monaco-editor";
import { Title } from '@angular/platform-browser';

@Component({
  selector: 'app-diff-editor',
  templateUrl: './diff-editor.component.html',
  styleUrls: ['./diff-editor.component.less']
})
export class DiffEditorComponent implements OnInit {

  constructor(private titleService: Title) {
  }

  text1 = "";
  text2 = "";
  selectedLang = "plaintext";
  selectedTheme = "vs";
  languages = [
    "bat",
    "c",
    "coffeescript",
    "cpp",
    "csharp",
    "csp",
    "css",
    "dockerfile",
    "fsharp",
    "go",
    "handlebars",
    "html",
    "ini",
    "java",
    "javascript",
    "json",
    "less",
    "lua",
    "markdown",
    "msdax",
    "mysql",
    "objective-c",
    "pgsql",
    "php",
    "plaintext",
    "postiats",
    "powershell",
    "pug",
    "python",
    "r",
    "razor",
    "redis",
    "redshift",
    "ruby",
    "rust",
    "sb",
    "scss",
    "sol",
    "sql",
    "st",
    "swift",
    "typescript",
    "vb",
    "xml",
    "yaml"
  ];
  themes = [
    {
      value: "vs",
      name: "Visual Studio"
    },
    {
      value: "vs-dark",
      name: "Visual Studio Dark"
    },
    {
      value: "hc-black",
      name: "High Contrast Dark"
    }
  ];

  options = {
    theme: "vs",
    language: "plaintext",
    readOnly: true,
    renderSideBySide: true
  };
  originalModel: DiffEditorModel = {
    code: "",
    language: "plaintext"
  };

  modifiedModel: DiffEditorModel = {
    code: "",
    language: "plaintext"
  };

  switchValue = false;
  isCompared = false;

  public ngOnInit() {
    this.titleService.setTitle('码加在线工具 - 文本比对');
  }

  onChangeLanguage(language) {
    this.options = Object.assign({}, this.options, {
      language: language
    });
    this.originalModel = Object.assign({}, this.originalModel, {
      language: language
    });
    this.modifiedModel = Object.assign({}, this.modifiedModel, {
      language: language
    });
  }
  onChangeTheme(theme) {
    this.options = Object.assign({}, this.options, { theme: theme });
  }

  onChangeInline() {
    this.options = Object.assign({}, this.options, {
      renderSideBySide: this.switchValue
    });
    this.switchValue = !this.switchValue;
  }

  onCompare() {
    this.originalModel = Object.assign({}, this.originalModel, {
      code: this.text1
    });
    this.modifiedModel = Object.assign({}, this.modifiedModel, {
      code: this.text2
    });
    this.isCompared = true;
  }
  onClear() {
    this.isCompared = false;
  }
}

运行结果如下:
在这里插入图片描述

完美运行

最后推荐一个比较干净实用的在线工具 https://tool.leadingcode.cn/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

V-BOX

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值