Adds diff info to active line hover always

This commit is contained in:
Eric Amodio
2017-05-27 02:39:10 -04:00
parent 2036c8abaf
commit e99febb52d
4 changed files with 78 additions and 42 deletions

View File

@@ -298,30 +298,25 @@ export class BlameActiveLineController extends Disposable {
if (!commit.isUncommitted && (!possibleDuplicate || !this.annotationController.isAnnotating(editor))) { if (!commit.isUncommitted && (!possibleDuplicate || !this.annotationController.isAnnotating(editor))) {
hoverMessage = BlameAnnotationFormatter.getAnnotationHover(cfg, blameLine, logCommit || commit); hoverMessage = BlameAnnotationFormatter.getAnnotationHover(cfg, blameLine, logCommit || commit);
// if (commit.previousSha !== undefined) { if (commit.previousSha !== undefined) {
// const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset, commit.previousSha); const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset, commit.previousSha);
// if (changes !== undefined) { if (changes !== undefined) {
// const previous = changes[0]; let previous = changes[0];
// if (previous !== undefined) { if (previous !== undefined) {
// hoverMessage += `\n\n\`Before ${commit.shortSha}\`\n\`\`\`\n${previous.trim().replace(/\n/g, '\`\n>\n> \`')}\n\`\`\``; previous = previous.replace(/\n/g, '\`\n>\n> \`').trim();
// } hoverMessage += `\n\n---\n\`\`\`\n${previous}\n\`\`\``;
// else { }
// hoverMessage += `\n\n\`Added in ${commit.shortSha}\``; }
// } }
// }
// }
} }
else if (commit.isUncommitted) { else if (commit.isUncommitted) {
const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset); const changes = await this.git.getDiffForLine(this._uri, blameLine.line + offset);
if (changes !== undefined) { if (changes !== undefined) {
let original = changes[0]; let previous = changes[0];
if (original !== undefined) { if (previous !== undefined) {
original = original.replace(/\n/g, '\`\n>\n> \`').trim(); previous = previous.replace(/\n/g, '\`\n>\n> \`').trim();
hoverMessage = `\`${'0'.repeat(8)}\`   __Uncommitted change__\n\n\---\n\`\`\`\n${original}\n\`\`\``; hoverMessage = `\`${'0'.repeat(8)}\`   __Uncommitted change__\n\n---\n\`\`\`\n${previous}\n\`\`\``;
} }
// else {
// hoverMessage = `\`${'0'.repeat(8)}\`   __Uncommitted change__\n\n\`Added\``;
// }
} }
} }
} }

View File

@@ -1,18 +1,19 @@
'use strict'; 'use strict';
export interface IGitDiffChunk { export interface IGitDiffChunk {
current: (string | undefined)[];
currentStart: number;
currentEnd: number;
previous: (string | undefined)[];
previousStart: number;
previousEnd: number;
chunk?: string; chunk?: string;
original: (string | undefined)[];
originalStart: number;
originalEnd: number;
changes: (string | undefined)[];
changesStart: number;
changesEnd: number;
} }
export interface IGitDiff { export interface IGitDiff {
diff?: string;
chunks: IGitDiffChunk[]; chunks: IGitDiffChunk[];
diff?: string;
} }

View File

@@ -15,22 +15,41 @@ export class GitDiffParser {
match = unifiedDiffRegex.exec(`${data}\n@@`); match = unifiedDiffRegex.exec(`${data}\n@@`);
if (match == null) break; if (match == null) break;
const originalStart = +match[1]; const previousStart = +match[1];
const changedStart = +match[3]; const currentStart = +match[3];
const chunk = match[5]; const chunk = match[5];
const lines = chunk.split('\n').slice(1); const lines = chunk.split('\n').slice(1);
const original = lines.filter(l => l[0] !== '+').map(l => (l[0] === '-') ? l.substring(1) : undefined);
const changed = lines.filter(l => l[0] !== '-').map(l => (l[0] === '+') ? l.substring(1) : undefined); const current = [];
const previous = [];
for (const l of lines) {
switch (l[0]) {
case '+':
current.push(` ${l.substring(1)}`);
previous.push(undefined);
break;
case '-':
current.push(undefined);
previous.push(` ${l.substring(1)}`);
break;
default:
current.push(l);
previous.push(l);
break;
}
}
chunks.push({ chunks.push({
chunk: debug ? chunk : undefined, chunk: debug ? chunk : undefined,
original: original, current: current,
originalStart: originalStart, currentStart: currentStart,
originalEnd: originalStart + +match[2], currentEnd: currentStart + +match[4],
changes: changed, previous: previous,
changesStart: changedStart, previousStart: previousStart,
changesEnd: changedStart + +match[4] previousEnd: previousStart + +match[2]
}); });
} while (match != null); } while (match != null);

View File

@@ -570,6 +570,10 @@ export class GitService extends Disposable {
} }
async getDiffForFile(uri: GitUri, sha1?: string, sha2?: string): Promise<IGitDiff | undefined> { async getDiffForFile(uri: GitUri, sha1?: string, sha2?: string): Promise<IGitDiff | undefined> {
if (sha1 !== undefined && sha2 === undefined && uri.sha !== undefined) {
sha2 = uri.sha;
}
let key = 'diff'; let key = 'diff';
if (sha1 !== undefined) { if (sha1 !== undefined) {
key += `:${sha1}`; key += `:${sha1}`;
@@ -620,7 +624,7 @@ export class GitService extends Disposable {
try { try {
const data = await Git.diff(root, file, sha1, sha2); const data = await Git.diff(root, file, sha1, sha2);
return GitDiffParser.parse(data, this.config.debug); return GitDiffParser.parse(data);
} }
catch (ex) { catch (ex) {
// Trap and cache expected diff errors // Trap and cache expected diff errors
@@ -645,12 +649,29 @@ export class GitService extends Disposable {
const diff = await this.getDiffForFile(uri, sha1, sha2); const diff = await this.getDiffForFile(uri, sha1, sha2);
if (diff === undefined) return undefined; if (diff === undefined) return undefined;
const chunk = diff.chunks.find(_ => Math.min(_.originalStart, _.changesStart) <= line && Math.max(_.originalEnd, _.changesEnd) >= line); const chunk = diff.chunks.find(_ => _.currentStart <= line && _.currentEnd >= line);
if (chunk === undefined) return undefined; if (chunk === undefined) return undefined;
// Search for the line (skipping deleted lines -- since they don't currently exist in the editor)
// Keep track of the deleted lines for the original version
line = line - chunk.currentStart + 1;
let count = 0;
let deleted = 0;
for (const l of chunk.current) {
if (l === undefined) {
deleted++;
if (count === line) break;
continue;
}
if (count === line) break;
count++;
}
return [ return [
chunk.original[line - chunk.originalStart + 1], chunk.previous[line + deleted - 1],
chunk.changes[line - chunk.changesStart + 1] chunk.current[line + deleted]
]; ];
} }
catch (ex) { catch (ex) {