export function getWorkspaceEditsFromPatch()

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;
}