Files
vscode-gitlens/src/git/parsers/diffParser.ts
2017-06-09 18:00:54 -04:00

70 lines
2.2 KiB
TypeScript

'use strict';
import { GitDiff, GitDiffChunk, GitDiffLine } from './../git';
const unifiedDiffRegex = /^@@ -([\d]+),([\d]+) [+]([\d]+),([\d]+) @@([\s\S]*?)(?=^@@)/gm;
export class GitDiffParser {
static parse(data: string, debug: boolean = false): GitDiff | undefined {
if (!data) return undefined;
const chunks: GitDiffChunk[] = [];
let match: RegExpExecArray | null = null;
do {
match = unifiedDiffRegex.exec(`${data}\n@@`);
if (match == null) break;
const previousStart = +match[1];
const currentStart = +match[3];
const chunk = match[5];
const lines = chunk.split('\n').slice(1);
const current: (GitDiffLine | undefined)[] = [];
const previous: (GitDiffLine | undefined)[] = [];
for (const l of lines) {
switch (l[0]) {
case '+':
current.push({
line: ` ${l.substring(1)}`,
state: 'added'
});
previous.push(undefined);
break;
case '-':
current.push(undefined);
previous.push({
line: ` ${l.substring(1)}`,
state: 'removed'
});
break;
default:
current.push({ line: l, state: 'unchanged' });
previous.push({ line: l, state: 'unchanged' });
break;
}
}
chunks.push({
chunk: debug ? chunk : undefined,
current: current,
currentStart: currentStart,
currentEnd: currentStart + +match[4],
previous: previous,
previousStart: previousStart,
previousEnd: previousStart + +match[2]
});
} while (match != null);
if (!chunks.length) return undefined;
const diff = {
diff: debug ? data : undefined,
chunks: chunks
} as GitDiff;
return diff;
}
}