Skip to content

Commit e99febb

Browse files
committed
Adds diff info to active line hover always
1 parent 2036c8a commit e99febb

File tree

4 files changed

+77
-41
lines changed

4 files changed

+77
-41
lines changed

src/blameActiveLineController.ts

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -298,30 +298,25 @@ export class BlameActiveLineController extends Disposable {
298298
if (!commit.isUncommitted && (!possibleDuplicate || !this.annotationController.isAnnotating(editor))) {
299299
hoverMessage = BlameAnnotationFormatter.getAnnotationHover(cfg, blameLine, logCommit || commit);
300300

301-
// if (commit.previousSha !== undefined) {
302-
// const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset, commit.previousSha);
303-
// if (changes !== undefined) {
304-
// const previous = changes[0];
305-
// if (previous !== undefined) {
306-
// hoverMessage += `\n\n\`Before ${commit.shortSha}\`\n\`\`\`\n${previous.trim().replace(/\n/g, '\`\n>\n> \`')}\n\`\`\``;
307-
// }
308-
// else {
309-
// hoverMessage += `\n\n\`Added in ${commit.shortSha}\``;
310-
// }
311-
// }
312-
// }
301+
if (commit.previousSha !== undefined) {
302+
const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset, commit.previousSha);
303+
if (changes !== undefined) {
304+
let previous = changes[0];
305+
if (previous !== undefined) {
306+
previous = previous.replace(/\n/g, '\`\n>\n> \`').trim();
307+
hoverMessage += `\n\n---\n\`\`\`\n${previous}\n\`\`\``;
308+
}
309+
}
310+
}
313311
}
314312
else if (commit.isUncommitted) {
315313
const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset);
316314
if (changes !== undefined) {
317-
let original = changes[0];
318-
if (original !== undefined) {
319-
original = original.replace(/\n/g, '\`\n>\n> \`').trim();
320-
hoverMessage = `\`${'0'.repeat(8)}\`   __Uncommitted change__\n\n\---\n\`\`\`\n${original}\n\`\`\``;
315+
let previous = changes[0];
316+
if (previous !== undefined) {
317+
previous = previous.replace(/\n/g, '\`\n>\n> \`').trim();
318+
hoverMessage = `\`${'0'.repeat(8)}\`   __Uncommitted change__\n\n---\n\`\`\`\n${previous}\n\`\`\``;
321319
}
322-
// else {
323-
// hoverMessage = `\`${'0'.repeat(8)}\`   __Uncommitted change__\n\n\`Added\``;
324-
// }
325320
}
326321
}
327322
}

src/git/models/diff.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
'use strict';
22

33
export interface IGitDiffChunk {
4-
chunk?: string;
4+
current: (string | undefined)[];
5+
currentStart: number;
6+
currentEnd: number;
57

6-
original: (string | undefined)[];
7-
originalStart: number;
8-
originalEnd: number;
8+
previous: (string | undefined)[];
9+
previousStart: number;
10+
previousEnd: number;
911

10-
changes: (string | undefined)[];
11-
changesStart: number;
12-
changesEnd: number;
12+
chunk?: string;
1313
}
1414

1515
export interface IGitDiff {
16-
diff?: string;
1716
chunks: IGitDiffChunk[];
17+
18+
diff?: string;
1819
}

src/git/parsers/diffParser.ts

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,41 @@ export class GitDiffParser {
1515
match = unifiedDiffRegex.exec(`${data}\n@@`);
1616
if (match == null) break;
1717

18-
const originalStart = +match[1];
19-
const changedStart = +match[3];
18+
const previousStart = +match[1];
19+
const currentStart = +match[3];
2020

2121
const chunk = match[5];
2222
const lines = chunk.split('\n').slice(1);
23-
const original = lines.filter(l => l[0] !== '+').map(l => (l[0] === '-') ? l.substring(1) : undefined);
24-
const changed = lines.filter(l => l[0] !== '-').map(l => (l[0] === '+') ? l.substring(1) : undefined);
23+
24+
const current = [];
25+
const previous = [];
26+
for (const l of lines) {
27+
switch (l[0]) {
28+
case '+':
29+
current.push(` ${l.substring(1)}`);
30+
previous.push(undefined);
31+
break;
32+
33+
case '-':
34+
current.push(undefined);
35+
previous.push(` ${l.substring(1)}`);
36+
break;
37+
38+
default:
39+
current.push(l);
40+
previous.push(l);
41+
break;
42+
}
43+
}
2544

2645
chunks.push({
2746
chunk: debug ? chunk : undefined,
28-
original: original,
29-
originalStart: originalStart,
30-
originalEnd: originalStart + +match[2],
31-
changes: changed,
32-
changesStart: changedStart,
33-
changesEnd: changedStart + +match[4]
47+
current: current,
48+
currentStart: currentStart,
49+
currentEnd: currentStart + +match[4],
50+
previous: previous,
51+
previousStart: previousStart,
52+
previousEnd: previousStart + +match[2]
3453
});
3554
} while (match != null);
3655

src/gitService.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,10 @@ export class GitService extends Disposable {
570570
}
571571

572572
async getDiffForFile(uri: GitUri, sha1?: string, sha2?: string): Promise<IGitDiff | undefined> {
573+
if (sha1 !== undefined && sha2 === undefined && uri.sha !== undefined) {
574+
sha2 = uri.sha;
575+
}
576+
573577
let key = 'diff';
574578
if (sha1 !== undefined) {
575579
key += `:${sha1}`;
@@ -620,7 +624,7 @@ export class GitService extends Disposable {
620624

621625
try {
622626
const data = await Git.diff(root, file, sha1, sha2);
623-
return GitDiffParser.parse(data, this.config.debug);
627+
return GitDiffParser.parse(data);
624628
}
625629
catch (ex) {
626630
// Trap and cache expected diff errors
@@ -645,12 +649,29 @@ export class GitService extends Disposable {
645649
const diff = await this.getDiffForFile(uri, sha1, sha2);
646650
if (diff === undefined) return undefined;
647651

648-
const chunk = diff.chunks.find(_ => Math.min(_.originalStart, _.changesStart) <= line && Math.max(_.originalEnd, _.changesEnd) >= line);
652+
const chunk = diff.chunks.find(_ => _.currentStart <= line && _.currentEnd >= line);
649653
if (chunk === undefined) return undefined;
650654

655+
// Search for the line (skipping deleted lines -- since they don't currently exist in the editor)
656+
// Keep track of the deleted lines for the original version
657+
line = line - chunk.currentStart + 1;
658+
let count = 0;
659+
let deleted = 0;
660+
for (const l of chunk.current) {
661+
if (l === undefined) {
662+
deleted++;
663+
if (count === line) break;
664+
665+
continue;
666+
}
667+
668+
if (count === line) break;
669+
count++;
670+
}
671+
651672
return [
652-
chunk.original[line - chunk.originalStart + 1],
653-
chunk.changes[line - chunk.changesStart + 1]
673+
chunk.previous[line + deleted - 1],
674+
chunk.current[line + deleted]
654675
];
655676
}
656677
catch (ex) {

0 commit comments

Comments
 (0)