From 06b350bc822acac5543b17083d0358e30fbd748f Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Fri, 26 Aug 2016 22:43:55 -0400 Subject: [PATCH] Fixes issues with ^ in a sha Dynamically pads uri index based on need --- src/codeLensProvider.ts | 76 ++++++++++++++++++++++------------------- src/contentProvider.ts | 2 +- src/git.ts | 14 ++++---- src/gitBlameUri.ts | 5 +-- 4 files changed, 52 insertions(+), 45 deletions(-) diff --git a/src/codeLensProvider.ts b/src/codeLensProvider.ts index 4845928..bd4706a 100644 --- a/src/codeLensProvider.ts +++ b/src/codeLensProvider.ts @@ -14,8 +14,8 @@ export class GitBlameCodeLens extends CodeLens { return this.blame.then(allLines => allLines.slice(this.blameRange.start.line, this.blameRange.end.line + 1)); } - static toUri(lens: GitBlameCodeLens, index: number, line: IGitBlameLine, lines: IGitBlameLine[]): Uri { - return toGitBlameUri(Object.assign({ repoPath: lens.repoPath, index: index, range: lens.blameRange, lines: lines }, line)); + static toUri(lens: GitBlameCodeLens, index: number, line: IGitBlameLine, lines: IGitBlameLine[], commits: string[]): Uri { + return toGitBlameUri(Object.assign({ repoPath: lens.repoPath, index: index, range: lens.blameRange, lines: lines, commits: commits }, line)); } } @@ -78,46 +78,50 @@ export default class GitCodeLensProvider implements CodeLensProvider { } _resolveGitBlameCodeLens(lens: GitBlameCodeLens, token: CancellationToken): Thenable { - return lens.getBlameLines().then(lines => { - if (!lines.length) { - console.error('No blame lines found', lens); - throw new Error('No blame lines found'); - } + return new Promise((resolve, reject) => { + lens.getBlameLines().then(lines => { + if (!lines.length) { + console.error('No blame lines found', lens); + reject(null); + return; + } - let recentLine = lines[0]; + let recentLine = lines[0]; - let locations: Location[] = []; - if (lines.length > 1) { - let sorted = lines.sort((a, b) => b.date.getTime() - a.date.getTime()); - recentLine = sorted[0]; + let locations: Location[] = []; + if (lines.length > 1) { + let sorted = lines.sort((a, b) => b.date.getTime() - a.date.getTime()); + recentLine = sorted[0]; - // console.log(lens.fileName, 'Blame lines:', sorted); + // console.log(lens.fileName, 'Blame lines:', sorted); - let map: Map = new Map(); - sorted.forEach(l => { - let item = map.get(l.sha); - if (item) { - item.push(l); - } else { - map.set(l.sha, [l]); - } - }); + let map: Map = new Map(); + sorted.forEach(l => { + let item = map.get(l.sha); + if (item) { + item.push(l); + } else { + map.set(l.sha, [l]); + } + }); - Array.from(map.values()).forEach((lines, i) => { - const uri = GitBlameCodeLens.toUri(lens, i + 1, lines[0], lines); - lines.forEach(l => locations.push(new Location(uri, new Position(l.originalLine, 0)))); - }); - } else { - locations = [new Location(GitBlameCodeLens.toUri(lens, 1, recentLine, lines), lens.range.start)]; - } + const commits = Array.from(map.keys()); + Array.from(map.values()).forEach((lines, i) => { + const uri = GitBlameCodeLens.toUri(lens, i + 1, lines[0], lines, commits); + lines.forEach(l => locations.push(new Location(uri, new Position(l.originalLine, 0)))); + }); + } else { + locations = [new Location(GitBlameCodeLens.toUri(lens, 1, recentLine, lines, [recentLine.sha]), lens.range.start)]; + } - lens.command = { - title: `${recentLine.author}, ${moment(recentLine.date).fromNow()}`, - command: Commands.ShowBlameHistory, - arguments: [Uri.file(lens.fileName), lens.range.start, locations] - }; - return lens; - }).catch(ex => Promise.reject(ex)); // TODO: Figure out a better way to stop the codelens from appearing + lens.command = { + title: `${recentLine.author}, ${moment(recentLine.date).fromNow()}`, + command: Commands.ShowBlameHistory, + arguments: [Uri.file(lens.fileName), lens.range.start, locations] + }; + resolve(lens); + }); + });//.catch(ex => Promise.reject(ex)); // TODO: Figure out a better way to stop the codelens from appearing } _resolveGitHistoryCodeLens(lens: GitHistoryCodeLens, token: CancellationToken): Thenable { diff --git a/src/contentProvider.ts b/src/contentProvider.ts index b5ef73b..e7445d2 100644 --- a/src/contentProvider.ts +++ b/src/contentProvider.ts @@ -89,7 +89,7 @@ export default class GitBlameContentProvider implements TextDocumentContentProvi private _findEditor(uri: Uri): TextEditor { let uriString = uri.toString(); // TODO: This is a big hack :) - const matcher = (e: any) => (e._documentData && e._documentData._uri && e._documentData._uri.toString()) === uriString; + const matcher = (e: any) => (e && e._documentData && e._documentData._uri && e._documentData._uri.toString()) === uriString; if (matcher(window.activeTextEditor)) { return window.activeTextEditor; } diff --git a/src/git.ts b/src/git.ts index ace42be..3061d95 100644 --- a/src/git.ts +++ b/src/git.ts @@ -11,17 +11,18 @@ export declare interface IGitBlameLine { author: string; date: Date; line: number; - code: string; + //code: string; } export function gitRepoPath(cwd) { return gitCommand(cwd, 'rev-parse', '--show-toplevel').then(data => data.replace(/\r?\n|\r/g, '')); } -const blameMatcher = /^([0-9a-fA-F]{8})\s([\S]*)\s+([0-9\S]+)\s\((.*)\s([0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[-|+][0-9]{4})\s+([0-9]+)\)(.*)$/gm; +const blameMatcher = /^([\^0-9a-fA-F]{8})\s([\S]*)\s+([0-9\S]+)\s\((.*)\s([0-9]{4}-[0-9]{2}-[0-9]{2}\s[0-9]{2}:[0-9]{2}:[0-9]{2}\s[-|+][0-9]{4})\s+([0-9]+)\)(.*)$/gm; export function gitBlame(fileName: string) { - return gitCommand(dirname(fileName), 'blame', '-fnw', '--', fileName).then(data => { + console.log('git', 'blame', '-fnw', '--root', '--', fileName); + return gitCommand(dirname(fileName), 'blame', '-fnw', '--root', '--', fileName).then(data => { let lines: Array = []; let m: Array; while ((m = blameMatcher.exec(data)) != null) { @@ -31,8 +32,8 @@ export function gitBlame(fileName: string) { originalLine: parseInt(m[3], 10) - 1, author: m[4].trim(), date: new Date(m[5]), - line: parseInt(m[6], 10) - 1, - code: m[7] + line: parseInt(m[6], 10) - 1 + //code: m[7] }); } return lines; @@ -41,7 +42,7 @@ export function gitBlame(fileName: string) { export function gitGetVersionFile(repoPath: string, sha: string, source: string): Promise { return new Promise((resolve, reject) => { - gitCommand(repoPath, 'show', `${sha}:${source.replace(/\\/g, '/')}`).then(data => { + gitCommand(repoPath, 'show', `${sha.replace('^', '')}:${source.replace(/\\/g, '/')}`).then(data => { let ext = extname(source); tmp.file({ prefix: `${basename(source, ext)}-${sha}_`, postfix: ext }, (err, destination, fd, cleanupCallback) => { if (err) { @@ -65,6 +66,7 @@ export function gitGetVersionFile(repoPath: string, sha: string, source: string) } export function gitGetVersionText(repoPath: string, sha: string, source: string) { + console.log('git', 'show', `${sha}:${source.replace(/\\/g, '/')}`); return gitCommand(repoPath, 'show', `${sha}:${source.replace(/\\/g, '/')}`); } diff --git a/src/gitBlameUri.ts b/src/gitBlameUri.ts index 4504acf..1bd5f60 100644 --- a/src/gitBlameUri.ts +++ b/src/gitBlameUri.ts @@ -8,11 +8,12 @@ export interface IGitBlameUriData extends IGitBlameLine { repoPath: string, range: Range, index: number, - lines: IGitBlameLine[] + lines: IGitBlameLine[], + commits: string[] } export function toGitBlameUri(data: IGitBlameUriData) { - const pad = n => ("000" + n).slice(-3); + const pad = n => ("0000000" + n).slice(-("" + data.commits.length).length); let ext = extname(data.file); let path = `${dirname(data.file)}/${data.sha}: ${basename(data.file, ext)}${ext}`;