mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-02-12 02:58:32 -05:00
74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
'use strict';
|
|
import { Iterables, Strings } from '../../system';
|
|
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;
|
|
|
|
let chunk: string;
|
|
let currentStart: number;
|
|
let previousStart: number;
|
|
|
|
do {
|
|
match = unifiedDiffRegex.exec(`${data}\n@@`);
|
|
if (match == null) break;
|
|
|
|
// Stops excessive memory usage
|
|
// https://bugs.chromium.org/p/v8/issues/detail?id=2869
|
|
chunk = (' ' + match[5]).substr(1);
|
|
currentStart = parseInt(match[3], 10);
|
|
previousStart = parseInt(match[1], 10);
|
|
|
|
chunks.push(new GitDiffChunk(chunk, { start: currentStart, end: currentStart + parseInt(match[4], 10) }, { start: previousStart, end: previousStart + parseInt(match[2], 10) }));
|
|
} while (match != null);
|
|
|
|
if (!chunks.length) return undefined;
|
|
|
|
const diff = {
|
|
diff: debug ? data : undefined,
|
|
chunks: chunks
|
|
} as GitDiff;
|
|
return diff;
|
|
}
|
|
|
|
static parseChunk(chunk: string): [(GitDiffLine | undefined)[], (GitDiffLine | undefined)[]] {
|
|
const lines = Iterables.skip(Strings.lines(chunk), 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;
|
|
}
|
|
}
|
|
|
|
return [current, previous];
|
|
}
|
|
} |