jsdiff icon indicating copy to clipboard operation
jsdiff copied to clipboard

No function to apply diffs from `diffChars`, `diffWords`, etc.

Open sirbrillig opened this issue 9 years ago • 2 comments

While you can create a unified diff with createPatch and then apply that to another string using applyPatch, there doesn't seem to be a way to apply Change Objects.

I think this would be helpful to apply diffs to data where line-context is not sufficient to match the diff.

e.g., something like:

const str1 = 'Greetings,\nhello world'
const str2 = 'Greetings\nhello my friend'
const diffs = diffWords( str1, str2 )
const result = applyDiffs( 'hello world', diffs )
expect( result ).to.equal( 'hello my friend' )

sirbrillig avatar Dec 30 '15 01:12 sirbrillig

+1

I created a very crude solution with a basic test. If the owner approves I can make a pull request for this functionality:

var oldStr = "please authenticate";
var newStr =  "now you may authenticate";
var delta = [ { count: 3, added: undefined, removed: true, value: 'ple' },
  { count: 9, added: true, removed: undefined, value: 'now you m' },
  { count: 1, value: 'a' },
  { count: 2, added: undefined, removed: true, value: 'se' },
  { count: 1, added: true, removed: undefined, value: 'y' },
  { count: 13, value: ' authenticate' } ];

function insertAt(str, index, add) {
  return [str.slice(0, index), add, str.slice(index)].join('');
}

function removeAt(str, index, count){
    return str.slice(0, index) + str.slice(index+count);
};

function applyPatch(delta, str){
    var result = str;
    var pos = 0;
    for(var i =0; i<delta.length; i++){
        if(delta[i].added){
            result = insertAt(result,pos,delta[i].value);
            pos+=delta[i].count;
        }
        else if(delta[i].removed){
            result = removeAt(result,pos,delta[i].count);
        }else{
            pos += delta[i].count;
        }
    }
    return result;
}

console.log("Does it work?",newStr === applyPatch(delta, oldStr));

Output: Does it work? true

Further tests are needed but I think this is the basic solution, it may not be the best performance wise though.

pedro93 avatar May 11 '16 11:05 pedro93

+1 This would be a great addition and is exactly what I'm trying to use this library for.

jbgarr avatar Jun 03 '16 16:06 jbgarr