in src/client/common/editor.ts [86:160]
export function getWorkspaceEditsFromPatch(
filePatches: string[],
workspaceRoot: string | undefined,
fs: IFileSystem,
): WorkspaceEdit {
const workspaceEdit = new WorkspaceEdit();
filePatches.forEach((patch) => {
const indexOfAtAt = patch.indexOf('@@');
if (indexOfAtAt === -1) {
return;
}
const fileNameLines = patch
.substring(0, indexOfAtAt)
.split(/\r?\n/g)
.map((line) => line.trim())
.filter((line) => line.length > 0 && line.toLowerCase().endsWith('.py') && line.indexOf(' a') > 0);
if (patch.startsWith('---')) {
// Strip the first two lines
patch = patch.substring(indexOfAtAt);
}
if (patch.length === 0) {
return;
}
// We can't find the find name
if (fileNameLines.length === 0) {
return;
}
let fileName = fileNameLines[0].substring(fileNameLines[0].indexOf(' a') + 3).trim();
fileName = workspaceRoot && !path.isAbsolute(fileName) ? path.resolve(workspaceRoot, fileName) : fileName;
if (!fs.fileExistsSync(fileName)) {
return;
}
// Remove the text added by unified_diff
// # Work around missing newline (http://bugs.python.org/issue2142).
patch = patch.replace(/\\ No newline at end of file[\r\n]/, '');
const dmp = require('diff-match-patch') as typeof import('diff-match-patch');
const d = new dmp.diff_match_patch();
const patches = patch_fromText.call(d, patch);
if (!Array.isArray(patches) || patches.length === 0) {
throw new Error('Unable to parse Patch string');
}
const fileSource = fs.readFileSync(fileName);
const fileUri = Uri.file(fileName);
// Add line feeds and build the text edits
patches.forEach((p) => {
p.diffs.forEach((diff) => {
diff[1] += EOL;
});
getTextEditsInternal(fileSource, p.diffs, p.start1).forEach((edit) => {
switch (edit.action) {
case EditAction.Delete:
workspaceEdit.delete(fileUri, new Range(edit.start, edit.end));
break;
case EditAction.Insert:
workspaceEdit.insert(fileUri, edit.start, edit.text);
break;
case EditAction.Replace:
workspaceEdit.replace(fileUri, new Range(edit.start, edit.end), edit.text);
break;
default:
break;
}
});
});
});
return workspaceEdit;
}