个性化阅读
专注于IT技术分析

如何在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="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.5/ace.js" type="text/javascript" charset="utf-8"></script>
<!-- Add the diff plugin -->
<script src="ace-diff.js"></script>
<!-- Add the diff_match_patch plugin -->
<script src="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 mode
        mode:"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 editors
    editors.left.setValue(leftString, 1);
    editors.right.setValue(rightString, 1);

    // Optional to prevent CTRL-Z and remove original content as the content was dinamically added
    editors.left.getSession().setUndoManager(new ace.UndoManager());
    editors.right.getSession().setUndoManager(new ace.UndoManager());
</script>

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何在ACE编辑器中实现差异和合并工具

评论 抢沙发

评论前必须登录!