如何在ACE编辑器中实现差异和合并工具

本文概述

  • 要求
  • 实现
【如何在ACE编辑器中实现差异和合并工具】差异工具用于比较两个文本文件之间的文本差异。如果你是开发人员(如果不是, 那么你是如何来到这里的?), 你可能已经在NetBeans和Sublime等著名的IDE中看到了这种工具。在本文中, 我们将展示如何为著名的Java ACE编辑器实现一个非常有用且易于使用的diff工具实现。
要求要为ACE编辑器实现差异/合并控件, 我们将依赖于@benkeen编写的Ace-diff插件。该插件是Ace Editor的包装器, 提供了2个面板的差异和合并工具, 可直观显示两个文档中的差异, 并允许你将更改从一个复制到另一个。它建立在google-diff-match-patch库的顶部。
为了在你的项目中实现此工具, 请在Github中项目的/ dist文件夹中获得ace-diff.js或ace-diff.min.js文件的副本。以及Github中项目的/ libs文件夹中的diff_match_patch.js文件。然后继续在文档中添加一个脚本标签, 其中包括所需的插件(在ACE编辑器之后):
< !-- Add ace editor from the CDN or a local copy --> < script src="http://img.readke.com/220524/123TR217-0.jpg" type="text/javascript" charset="utf-8"> < /script> < !-- Add the diff plugin --> < script src="http://www.srcmini.com/ace-diff.js"> < /script> < !-- Add the diff_match_patch plugin --> < script src="http://www.srcmini.com/diff_match_patch.js"> < /script>

如果需要更多信息, 请访问Github中的ace-diff官方存储库。此后, 你将可以在文档中实例化AceDiff类。但是, 要可视化编辑器, 你还没有准备好!继续添加一些CSS以正确可视化编辑器。
注意:根据你要在控件中找到控件的位置, 你需要更改一些属性。你可以按照需要的方式更改类的名称, 但不要忘记在Javascript中使用classes属性初始化时也要更改它们。
通过将.css文件链接到文档或在样式标签中添加以下CSS:
#flex-container {display: flex; display: -webkit-flex; flex-direction: row; position: absolute; bottom: 0; width: 100%; top: 0px !important; left: 0px; /* these 3 lines are to prevents an unsightly scrolling bounce affect on Safari */height: 100%; width: 100%; overflow: auto; }#flex-container> div {flex-grow: 1; -webkit-flex-grow: 1; position: relative; }#flex-container> div#acediff-gutter {flex: 0 0 60px; -webkit-flex: 0 0 60px; border-left: 1px solid #999999; border-right: 1px solid #999999; background-color: #efefef; overflow: hidden; }#acediff-gutter svg {background-color: #efefef; }.acediff-class {position: absolute !important; top: 0; bottom: 0; width: 100%; }.acediff-diff {background-color: #d8f2ff; border-top: 1px solid #a2d7f2; border-bottom: 1px solid #a2d7f2; position: absolute; z-index: 4; }.acediff-diff.targetOnly {height: 0px !important; border-top: 1px solid #a2d7f2; border-bottom: 0px; position: absolute; }.acediff-connector {fill: #d8f2ff; stroke: #a2d7f2; }.acediff-copy-left {float: right; }.acediff-copy-right, .acediff-copy-left {position: relative; }.acediff-copy-right div {color: #000000; text-shadow: 1px 1px #ffffff; position: absolute; margin: 2px 3px; cursor: pointer; }.acediff-copy-right div:hover {color: #004ea0; }.acediff-copy-left div {color: #000000; text-shadow: 1px 1px #ffffff; position: absolute; right: 0px; margin: 2px 3px; cursor: pointer; }.acediff-copy-left div:hover {color: #c98100; }

你就可以开始了。
实现diff控件需要具有以下标记:
< div id="flex-container"> < div> < div class="acediff-class" id="editor-left"> < /div> < /div> < div id="acediff-gutter"> < /div> < div> < div class="acediff-class" id="editor-right"> < /div> < /div> < /div>

你可以使用以下JS进行初始化:
< script> var aceDiffer = new AceDiff({left:{id:"editor-left"}, right:{id:"editor-right"}}); < /script>

请注意, 插件提供了以下所有选项, 你可以根据需要更改这些选项来操作该工具:
{mode: null, theme: null, diffGranularity: 'broad', showDiffs: true, showConnectors: true, maxDiffs: 5000, left: {id: 'acediff-left-editor', content: null, mode: null, theme: null, editable: true, copyLinkEnabled: true}, right: {id: 'acediff-right-editor', content: null, mode: null, theme: null, editable: true, copyLinkEnabled: true}, classes: {gutterID: 'acediff-gutter', diff: 'acediff-diff', connector: 'acediff-connector', newCodeConnectorLink: 'acediff-new-code-connector-copy', newCodeConnectorLinkContent: '& #8594; ', deletedCodeConnectorLink: 'acediff-deleted-code-connector-copy', deletedCodeConnectorLinkContent: '& #8592; ', copyRightContainer: 'acediff-copy-right', copyLeftContainer: 'acediff-copy-left'}}

此外, 你仍然可以使用有用的API来访问ACE编辑器的常规属性:
  • aceInstance.getEditors():此方法返回一个具有左右属性的对象。每个文件都包含对原始Ace编辑器的引用, 以防你需要对它们进行任何操作。
  • aceInstance.setOptions():这使你可以动态设置前面提到的许多选项。请注意, 在编辑器构造期间使用的某些内容(例如, 类)不能被覆盖。
  • aceInstance.getNumDiffs():返回当前显示的差异数。
  • aceInstance.diff():更新差异。永远都不需要这样做, 因为AceDiff会自动识别关键事件, 例如对编辑器的更改和窗口大小的调整。
  • aceInstance.destroy():销毁AceDiff实例, 销毁两个编辑器并清除装订线。
如你所见, 使用AceDiff确实很容易且实用。请参阅以下典型用法示例:
含开始内容
你可以设置以纯HTML开头的diff控件, 即:
< div id="flex-container"> < div> < div class="acediff-class" id="editor-left"> {propertyA: 12, propertyB: 123, propertyC: 321, }< /div> < /div> < div id="acediff-gutter"> < /div> < div> < div class="acediff-class" id="editor-right"> {propertyA: 12, propertyZ: 123, propertyC: 321, }< /div> < /div> < /div> < script> var aceDiffer = new AceDiff({left:{id:"editor-left"}, right:{id:"editor-right"}}); < /script>

动态内容
如果要以二维方式(使用jQuery或Angular)启动diff控件, 则可能需要(或想要)以动态方式将内容添加到编辑器中, 要实现此目的, 请使用aceDiffer实例的getEditors方法检索ACE编辑器实例并使用setValue方法对其进行动态更改。
< div id="flex-container"> < div> < div class="acediff-class" id="editor-left"> < /div> < /div> < div id="acediff-gutter"> < /div> < div> < div class="acediff-class" id="editor-right"> < /div> < /div> < /div> < script> var aceDiffer = new AceDiff({// Add a modemode:"ace/mode/javascript", left:{id:"editor-left"}, right:{id:"editor-right"}}); var editors = aceDiffer.getEditors(); var leftString = "var a = {\n propertyA: 12, \n propertyB: 123, \n propertyC: 321, \n}"; var rightString = "var a = {\n propertyA: 12, \n propertyZ: 123, \n propertyC: 321, \n}"; // Set Value to the editorseditors.left.setValue(leftString, 1); editors.right.setValue(rightString, 1); // Optional to prevent CTRL-Z and remove original content as the content was dinamically addededitors.left.getSession().setUndoManager(new ace.UndoManager()); editors.right.getSession().setUndoManager(new ace.UndoManager()); < /script>

编码愉快!

    推荐阅读