Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function diffLine (theme, actual, expected) {
const outcome = fastDiff(actual, expected)
// TODO: Compute when line is mostly unequal (80%? 90%?) and treat it as being
// completely unequal.
const isPartiallyEqual = !(
(outcome.length === 2 && outcome[0][1] === actual && outcome[1][1] === expected) ||
// Discount line ending control pictures, which will be equal even when the
// rest of the line isn't.
(
outcome.length === 3 &&
outcome[2][0] === fastDiff.EQUAL &&
MATCH_CONTROL_PICTURES.test(outcome[2][1]) &&
outcome[0][1] + outcome[2][1] === actual &&
outcome[1][1] + outcome[2][1] === expected
)
)
let stringActual = ''
let stringExpected = ''
const noopWrap = { open: '', close: '' }
const deleteWrap = isPartiallyEqual ? theme.string.diff.delete : noopWrap
const insertWrap = isPartiallyEqual ? theme.string.diff.insert : noopWrap
const equalWrap = isPartiallyEqual ? theme.string.diff.equal : noopWrap
for (const diff of outcome) {
if (diff[0] === fastDiff.DELETE) {
stringActual += formatUtils.wrap(deleteWrap, diff[1])
private async applyComposedEdit(original: string, edit: TextEdit): Promise {
// check complex edit
let { range, newText } = edit
let { nvim, ranges } = this
let doc = TextDocument.create('file:///1', '', 0, original)
let edits: TextEdit[] = []
let diffs = fastDiff(original, newText)
let offset = 0
for (let i = 0; i < diffs.length; i++) {
let diff = diffs[i]
let pos = adjustPosition(range.start, doc.positionAt(offset))
if (diff[0] == fastDiff.EQUAL) {
offset = offset + diff[1].length
} else if (diff[0] == fastDiff.DELETE) {
let end = adjustPosition(range.start, doc.positionAt(offset + diff[1].length))
if (diffs[i + 1] && diffs[i + 1][0] == fastDiff.INSERT) {
// change
edits.push({ range: Range.create(pos, end), newText: diffs[i + 1][1] })
i = i + 1
} else {
// delete
edits.push({ range: Range.create(pos, end), newText: '' })
}
offset = offset + diff[1].length
} else if (diff[0] == fastDiff.INSERT) {
edits.push({ range: Range.create(pos, pos), newText: diff[1] })
}
}
if (change.range.end.line < 2) return
doc.buffer.setOption('modified', true, true)
let { range, text } = change
let lines = text.split('\n')
let lineChange = lines.length - (range.end.line - range.start.line) - 1
if (lineChange == 0) return
let lineChanges: LineChange[] = []
if (text.indexOf('\u3000') !== -1) {
let startLine = range.start.line
let diffs = fastDiff(original, text)
let offset = 0
let orig = TextDocument.create('file:///1', '', 0, original)
for (let i = 0; i < diffs.length; i++) {
let diff = diffs[i]
let pos = orig.positionAt(offset)
if (diff[0] == fastDiff.EQUAL) {
offset = offset + diff[1].length
} else if (diff[0] == fastDiff.DELETE) {
let end = orig.positionAt(offset + diff[1].length)
if (diffs[i + 1] && diffs[i + 1][0] == fastDiff.INSERT) {
let delta = diffs[i + 1][1].split('\n').length - (end.line - pos.line) - 1
if (delta != 0) lineChanges.push({ delta, lnum: pos.line + startLine })
i = i + 1
} else {
let delta = - (end.line - pos.line)
if (delta != 0) lineChanges.push({ delta, lnum: pos.line + startLine })
}
offset = offset + diff[1].length
} else if (diff[0] == fastDiff.INSERT) {
let delta = diff[1].split('\n').length - 1
if (delta != 0) lineChanges.push({ delta, lnum: pos.line + startLine })
}
diffResult.forEach(function (component) {
var length = component[1].length;
while (length > 0) {
var opLength = 0;
switch (component[0]) {
case diff.INSERT:
opLength = Math.min(otherIter.peekLength(), length);
delta.push(otherIter.next(opLength));
break;
case diff.DELETE:
opLength = Math.min(length, thisIter.peekLength());
thisIter.next(opLength);
delta['delete'](opLength);
break;
case diff.EQUAL:
opLength = Math.min(thisIter.peekLength(), otherIter.peekLength(), length);
var thisOp = thisIter.next(opLength);
var otherOp = otherIter.next(opLength);
if (equal(thisOp.insert, otherOp.insert)) {
delta.retain(opLength, op.attributes.diff(thisOp.attributes, otherOp.attributes));
} else {
delta.push(otherOp)['delete'](opLength);
}
break;
}
length -= opLength;
}
});
return delta.chop();
diffResult.forEach(function (component) {
var length = component[1].length;
while (length > 0) {
var opLength = 0;
switch (component[0]) {
case diff.INSERT:
opLength = Math.min(otherIter.peekLength(), length);
delta.push(otherIter.next(opLength));
break;
case diff.DELETE:
opLength = Math.min(length, thisIter.peekLength());
thisIter.next(opLength);
delta['delete'](opLength);
break;
case diff.EQUAL:
opLength = Math.min(thisIter.peekLength(), otherIter.peekLength(), length);
var thisOp = thisIter.next(opLength);
var otherOp = otherIter.next(opLength);
if (equal(thisOp.insert, otherOp.insert)) {
delta.retain(opLength, op.attributes.diff(thisOp.attributes, otherOp.attributes));
} else {
delta.push(otherOp)['delete'](opLength);
}
break;
}
length -= opLength;
}
});
return delta.chop();
for (const result of results) {
const start = offset;
const op = result[0];
const text = result[1];
switch (op) {
case diff.INSERT:
edits.push(TextEdit.insert(document.positionAt(start), text));
break;
case diff.DELETE:
offset += text.length;
edits.push(
TextEdit.del(Range.create(document.positionAt(start), document.positionAt(offset))),
);
break;
case diff.EQUAL:
offset += text.length;
break;
}
}
return edits;
}