0

Asked already there https://softwarerecs.stackexchange.com/questions/81811/visual-diff-patch-editor, but there are no snippets... Is there something like this, but interactive ? With some possibility to edit patch or left/right and see updated results or patch back ? Thinking about something like Github pull requests with similar edit option for all files in PR at once.

var tas = document.getElementsByTagName("TEXTAREA");

function show(diffString) {
  var targetElement = document.getElementById('myDiffElement');
  var configuration = {
    drawFileList: false,
    fileListToggle: false,
    fileListStartVisible: false,
    fileContentToggle: false,
    matching: 'lines',
    outputFormat: 'side-by-side',
    synchronisedScroll: true,
    highlight: true,
    renderNothingWhenEmpty: false,
  };
  var diff2htmlUi = new Diff2HtmlUI(targetElement, diffString, configuration);
  diff2htmlUi.draw();
  diff2htmlUi.highlightCode();
  var tabs = document.getElementsByTagName("TABLE");
  tas[1].value = printTab(tabs[0]);
  tas[2].value = printTab(tabs[1]);
}

function printTab(t) {
  var o = "";
  for (var r = 1; r < t.rows.length; r++) {
    var cs = [];
    for (var c = 1; c < t.rows[r].cells.length; c++) {
      cs.push(t.rows[r].cells[c].innerText);
    }
    o += cs.join('\t') + '\n';
  }
  return o;
}

function demo() {
  show(tas[0].value);
}
setTimeout(demo, 2000)
<head>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.1/styles/github.min.css" />
  <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/diff2html/bundles/css/diff2html.min.css" />
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/diff2html/bundles/js/diff2html-ui.min.js"></script>
</head>
<script>
</script>

<body onload="">
  <textarea onchange="show(this.value)" rows="4" cols="20">diff --git a/https://codepen.io/HatScripts/full/QvWVgP b/https://codepen.io/HatScripts/full/QvWVgP
@@ -1,3 +1,3 @@ function example()
--- a/https://codepen.io/HatScripts/full/QvWVgP
+++ b/https://codepen.io/HatScripts/full/QvWVgP
      function example() {
-        return "pizza";
+        return "pasta";
      }</textarea>
  <textarea rows="4" cols="25"></textarea>
  <textarea rows="4" cols="25"></textarea>
  <div id="myDiffElement"></div>
</body>

Made something to do simple transformations on patch and filter results. In this case unify and reduce whitespaces and force lowercase before compare (using simple transformLeft vs transformRight functions), but not sure if it is perfect and if it can process any patch file.

var ta;
function transformLeft(i)
{
    return i.toLocaleLowerCase().replace(/\s+/g, ' ');
}
function transformRight(i)
{
    return i.toLocaleLowerCase().replace(/\s+/g, ' ');
}
function process(t)
{
    var res = [], head = { prev:[], now:[], tl:[], tr:[], tempRows:[] }, processed = [];
    var lastDiff = null;
    var r = t.split('\n');
    if (!r[r.length]) r.pop();
    var counts = null;
    for(var i of r)
    {
        var type = null;
        if (i.substr(0,5) == 'diff ') {
            head = { prev:[], now:[], tl:[], tr:[], tempRows:[] };
            counts = null;
            type = 'diff';
        }
        else if (i.substr(0,6) == 'index ') type = 'index';
        else if (i.substr(0,4) == '--- ') type = '---';
        else if (i.substr(0,4) == '+++ ') type = '+++';
        else if (i.substr(0,3) == '@@ ') {
            type = '@@';
            counts = i.substr(3, i.length - 6).split(' ');
            if (!head.lines || head['@@'] != i) {
                head.lines = {
                    prev: parseInt(counts[0].replace(/.+,/, '').replace(/[+-]/, '')),
                    now: parseInt(counts[1].replace(/.+,/, '').replace(/[+-]/, ''))
                };
            }
            counts = i;
            continue;
        }
        if (type && !head[type]) {
            head[type] = i;
            continue;
        }
        if (type == null && !head.lines)
        {
            var ignored = {
                "copy from ":2,
                "copy to ":2,
                "new mode ":2,
                "old mode ":2,
                "rename from ":2,
                "rename to ":2,
                "similarity index ":2,
                "dissimilarity index ":3,
                "deleted file mode ":3,
                "new file mode ":3
            };
            var space = i.indexOf(' ');
            if (space > 0)
            {
                space++;
                if (ignored[i.substr(0, space)] == 1)
                {
                    continue;
                }
                space = i.indexOf(' ', space);
                space++;
                if (ignored[i.substr(0, space)] == 2)
                {
                    continue;
                }
                space = i.indexOf(' ', space);
                space++;
                if (ignored[i.substr(0, space)] == 3)
                {
                    continue;
                }
            }
            alert("Unexpected content " + i + " !");
        }
        head.tempRows.push(i);
        var diff = 0;
        if (i[0] == '-')
        {
            diff--;
            head.lines.prev--;
            head.prev.push(i);
            head.tl.push(transformLeft(i.substr(1)));
        }
        else if (i[0] == '+')
        {
            diff++;
            head.lines.now--;
            head.now.push(i);
            head.tr.push(transformRight(i.substr(1)));
        }
        else
        {
            head.lines.prev--;
            head.prev.push(i);
            head.lines.now--;
            head.now.push(i);
        }
        if (diff != 0 & i.substr(1, 11) == "Subproject ")
        {
            continue;
        }
        if (head.lines.prev == 0 && head.lines.now == 0) {
            if (head.tl.join('\n') != head.tr.join('\n'))
            {
                if (!lastDiff || lastDiff != head.diff)
                {
                    lastDiff = head.diff;
                    res.push(head.diff);
                    res.push(head.index);
                    res.push(head['---']);
                    res.push(head['+++']);
                }
                res.push(counts);
                res.push(head.tempRows.join('\n'));
                processed.push({
                    diff:head.diff,
                    index:head.index,
                    "---":head['---'],
                    "+++":head['+++'],
                    cnts: head.counts,
                    rows: head.tempRows
                });
            }
            head.tl = [];
            head.tr = [];
            head.prev = [];
            head.now = [];
            head.tempRows = [];
            counts = null;
        }
    }
    ta[0].value = JSON.stringify(processed,null,2);
    ta[1].value = res.join('\n');
}
function init()
{
    ta = document.getElementsByTagName("TEXTAREA");
}
function droppper(e) {
    e.stopPropagation();
    e.preventDefault();
    var files = e.dataTransfer.files; // Array of all files

    for (var i=0, file; file=files[i]; i++) {
        var reader = new FileReader();

        reader.onload = function(e2) {
            ta[0].value = e2.target.result;
            process(ta[0].value);
        }

        reader.readAsText(file);
    }
}
<body onload="init()">
<textarea ondrop="droppper(event)" rows=60 cols=120 onchange="process(this.value)"></textarea>
<textarea rows=60 cols=120></textarea>
</body>
Jan
  • 2,178
  • 3
  • 14
  • 26
  • For example when I update tens of #include to have proper case when porting to linux, it would be nice to for example change case on left & right to lower or upper and update (recreate patch) to be able to check only remaining changes (if there are any at all), etc. Sure there are options like splitdiff -d, but do we have to work first in cmd in windows too ;-) Complicated and very slow way here https://stackoverflow.com/questions/17380029/how-to-perform-case-insensitive-diff-in-git/70564226#70564226 – Jan Jan 10 '22 at 07:52
  • https://meldmerge.org/ or https://github.com/timbrel/GitSavvy looks interesting... – Jan Jan 24 '22 at 11:12

0 Answers0