Browse Source

Removes Hovers namespace

main
Eric Amodio 1 year ago
parent
commit
2b96d98ee9
5 changed files with 353 additions and 370 deletions
  1. +3
    -3
      src/annotations/blameAnnotationProvider.ts
  2. +2
    -7
      src/annotations/gutterChangesAnnotationProvider.ts
  3. +343
    -350
      src/hovers/hovers.ts
  4. +3
    -8
      src/hovers/lineHoverController.ts
  5. +2
    -2
      src/statusbar/statusBarController.ts

+ 3
- 3
src/annotations/blameAnnotationProvider.ts View File

@ -6,7 +6,7 @@ import type { Container } from '../container';
import { GitUri } from '../git/gitUri';
import type { GitBlame } from '../git/models/blame';
import type { GitCommit } from '../git/models/commit';
import { Hovers } from '../hovers/hovers';
import { changesMessage, detailsMessage } from '../hovers/hovers';
import { log } from '../system/decorators/log';
import type { GitDocumentState, TrackedDocument } from '../trackers/gitDocumentTracker';
import { AnnotationProviderBase } from './annotationProvider';
@ -172,7 +172,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
await Promise.all([
providers.details ? this.getDetailsHoverMessage(commit, document) : undefined,
providers.changes
? Hovers.changesMessage(commit, await GitUri.fromUri(document.uri), position.line, document)
? changesMessage(commit, await GitUri.fromUri(document.uri), position.line, document)
: undefined,
])
).filter(<T>(m?: T): m is T => Boolean(m));
@ -190,7 +190,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase
editorLine = commitLine.originalLine - 1;
const cfg = configuration.get('hovers');
return Hovers.detailsMessage(
return detailsMessage(
commit,
await GitUri.fromUri(document.uri),
editorLine,

+ 2
- 7
src/annotations/gutterChangesAnnotationProvider.ts View File

@ -11,7 +11,7 @@ import { configuration, FileAnnotationType } from '../configuration';
import type { Container } from '../container';
import type { GitCommit } from '../git/models/commit';
import type { GitDiff } from '../git/models/diff';
import { Hovers } from '../hovers/hovers';
import { localChangesMessage } from '../hovers/hovers';
import { getLogScope, log } from '../system/decorators/log';
import { Stopwatch } from '../system/stopwatch';
import type { GitDocumentState, TrackedDocument } from '../trackers/gitDocumentTracker';
@ -306,12 +306,7 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase
position.line >= hunk.current.position.start - 1 &&
position.line <= hunk.current.position.end - (hasMoreDeletedLines ? 0 : 1)
) {
const markdown = await Hovers.localChangesMessage(
commit,
this.trackedDocument.uri,
position.line,
hunk,
);
const markdown = await localChangesMessage(commit, this.trackedDocument.uri, position.line, hunk);
if (markdown == null) return undefined;
return new Hover(

+ 343
- 350
src/hovers/hovers.ts View File

@ -18,412 +18,405 @@ import { count } from '../system/iterable';
import { getSettledValue, PromiseCancelledError } from '../system/promise';
import { getDurationMilliseconds } from '../system/string';
export namespace Hovers {
export async function changesMessage(
commit: GitCommit,
uri: GitUri,
editorLine: number, // 0-based, Git is 1-based
document: TextDocument,
): Promise<MarkdownString | undefined> {
const documentRef = uri.sha;
let previousSha = null;
async function getDiff() {
if (commit.file == null) return undefined;
// TODO: Figure out how to optimize this
let ref;
if (commit.isUncommitted) {
if (GitRevision.isUncommittedStaged(documentRef)) {
ref = documentRef;
}
} else {
previousSha = await commit.getPreviousSha();
ref = previousSha;
if (ref == null) {
return `\`\`\`diff\n+ ${document.lineAt(editorLine).text}\n\`\`\``;
}
}
export async function changesMessage(
commit: GitCommit,
uri: GitUri,
editorLine: number, // 0-based, Git is 1-based
document: TextDocument,
): Promise<MarkdownString | undefined> {
const documentRef = uri.sha;
const line = editorLine + 1;
const commitLine = commit.lines.find(l => l.line === line) ?? commit.lines[0];
let previousSha = null;
let originalPath = commit.file.originalPath;
if (originalPath == null) {
if (uri.fsPath !== commit.file.uri.fsPath) {
originalPath = commit.file.path;
}
}
async function getDiff() {
if (commit.file == null) return undefined;
editorLine = commitLine.line - 1;
// TODO: Doesn't work with dirty files -- pass in editor? or contents?
let hunkLine = await Container.instance.git.getDiffForLine(uri, editorLine, ref, documentRef);
// If we didn't find a diff & ref is undefined (meaning uncommitted), check for a staged diff
if (hunkLine == null && ref == null && documentRef !== GitRevision.uncommittedStaged) {
hunkLine = await Container.instance.git.getDiffForLine(
uri,
editorLine,
undefined,
GitRevision.uncommittedStaged,
);
// TODO: Figure out how to optimize this
let ref;
if (commit.isUncommitted) {
if (GitRevision.isUncommittedStaged(documentRef)) {
ref = documentRef;
}
} else {
previousSha = await commit.getPreviousSha();
ref = previousSha;
if (ref == null) {
return `\`\`\`diff\n+ ${document.lineAt(editorLine).text}\n\`\`\``;
}
return hunkLine != null ? getDiffFromHunkLine(hunkLine) : undefined;
}
const diff = await getDiff();
if (diff == null) return undefined;
let message;
let previous;
let current;
if (commit.isUncommitted) {
const compareUris = await commit.getPreviousComparisonUrisForLine(editorLine, documentRef);
if (compareUris?.previous == null) return undefined;
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs({
lhs: {
sha: compareUris.previous.sha ?? '',
uri: compareUris.previous.documentUri(),
},
rhs: {
sha: compareUris.current.sha ?? '',
uri: compareUris.current.documentUri(),
},
repoPath: commit.repoPath,
line: editorLine,
})} "Open Changes")`;
previous =
compareUris.previous.sha == null || compareUris.previous.isUncommitted
? ` &nbsp;_${GitRevision.shorten(compareUris.previous.sha, {
strings: { working: 'Working Tree' },
})}_ &nbsp;${GlyphChars.ArrowLeftRightLong}&nbsp; `
: ` &nbsp;[$(git-commit) ${GitRevision.shorten(
compareUris.previous.sha || '',
)}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
compareUris.previous.sha || '',
)} "Show Commit") &nbsp;${GlyphChars.ArrowLeftRightLong}&nbsp; `;
current =
compareUris.current.sha == null || compareUris.current.isUncommitted
? `_${GitRevision.shorten(compareUris.current.sha, {
strings: {
working: 'Working Tree',
},
})}_`
: `[$(git-commit) ${GitRevision.shorten(
compareUris.current.sha || '',
)}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
compareUris.current.sha || '',
)} "Show Commit")`;
} else {
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs(
commit,
editorLine,
)} "Open Changes")`;
const line = editorLine + 1;
const commitLine = commit.lines.find(l => l.line === line) ?? commit.lines[0];
if (previousSha === null) {
previousSha = await commit.getPreviousSha();
}
if (previousSha) {
previous = ` &nbsp;[$(git-commit) ${GitRevision.shorten(
previousSha,
)}](${ShowQuickCommitCommand.getMarkdownCommandArgs(previousSha)} "Show Commit") &nbsp;${
GlyphChars.ArrowLeftRightLong
}&nbsp;`;
let originalPath = commit.file.originalPath;
if (originalPath == null) {
if (uri.fsPath !== commit.file.uri.fsPath) {
originalPath = commit.file.path;
}
current = `[$(git-commit) ${commit.shortSha}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
commit.sha,
)} "Show Commit")`;
}
message = `${diff}\n---\n\nChanges${previous ?? ' added in '}${current} &nbsp;&nbsp;|&nbsp;&nbsp; ${message}`;
editorLine = commitLine.line - 1;
// TODO: Doesn't work with dirty files -- pass in editor? or contents?
let hunkLine = await Container.instance.git.getDiffForLine(uri, editorLine, ref, documentRef);
const markdown = new MarkdownString(message, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;
}
export async function localChangesMessage(
fromCommit: GitCommit | undefined,
uri: GitUri,
editorLine: number, // 0-based, Git is 1-based
hunk: GitDiffHunk,
): Promise<MarkdownString | undefined> {
const diff = getDiffFromHunk(hunk);
let message;
let previous;
let current;
if (fromCommit == null) {
previous = '_Working Tree_';
current = '_Unsaved_';
} else {
const file = await fromCommit.findFile(uri);
if (file == null) return undefined;
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs({
lhs: {
sha: fromCommit.sha,
uri: GitUri.fromFile(file, uri.repoPath!, undefined, true).toFileUri(),
},
rhs: {
sha: '',
uri: uri.toFileUri(),
},
repoPath: uri.repoPath!,
line: editorLine,
})} "Open Changes")`;
previous = `[$(git-commit) ${fromCommit.shortSha}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
fromCommit.sha,
)} "Show Commit")`;
current = '_Working Tree_';
// If we didn't find a diff & ref is undefined (meaning uncommitted), check for a staged diff
if (hunkLine == null && ref == null && documentRef !== GitRevision.uncommittedStaged) {
hunkLine = await Container.instance.git.getDiffForLine(
uri,
editorLine,
undefined,
GitRevision.uncommittedStaged,
);
}
message = `${diff}\n---\n\nLocal Changes &nbsp;${previous} &nbsp;${
GlyphChars.ArrowLeftRightLong
}&nbsp; ${current}${message == null ? '' : ` &nbsp;&nbsp;|&nbsp;&nbsp; ${message}`}`;
const markdown = new MarkdownString(message, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;
return hunkLine != null ? getDiffFromHunkLine(hunkLine) : undefined;
}
export async function detailsMessage(
commit: GitCommit,
uri: GitUri,
editorLine: number, // 0-based, Git is 1-based
format: string,
dateFormat: string | null,
options?: {
autolinks?: boolean;
cancellationToken?: CancellationToken;
pullRequests?: {
enabled: boolean;
pr?: PullRequest | PromiseCancelledError<Promise<PullRequest | undefined>>;
};
getBranchAndTagTips?: (
sha: string,
options?: { compact?: boolean | undefined; icons?: boolean | undefined },
) => string | undefined;
},
): Promise<MarkdownString> {
if (dateFormat === null) {
dateFormat = 'MMMM Do, YYYY h:mma';
}
const diff = await getDiff();
if (diff == null) return undefined;
let message = commit.message ?? commit.summary;
if (commit.message == null && !commit.isUncommitted) {
await commit.ensureFullDetails();
message = commit.message ?? commit.summary;
let message;
let previous;
let current;
if (commit.isUncommitted) {
const compareUris = await commit.getPreviousComparisonUrisForLine(editorLine, documentRef);
if (compareUris?.previous == null) return undefined;
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs({
lhs: {
sha: compareUris.previous.sha ?? '',
uri: compareUris.previous.documentUri(),
},
rhs: {
sha: compareUris.current.sha ?? '',
uri: compareUris.current.documentUri(),
},
repoPath: commit.repoPath,
line: editorLine,
})} "Open Changes")`;
previous =
compareUris.previous.sha == null || compareUris.previous.isUncommitted
? ` &nbsp;_${GitRevision.shorten(compareUris.previous.sha, {
strings: { working: 'Working Tree' },
})}_ &nbsp;${GlyphChars.ArrowLeftRightLong}&nbsp; `
: ` &nbsp;[$(git-commit) ${GitRevision.shorten(
compareUris.previous.sha || '',
)}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
compareUris.previous.sha || '',
)} "Show Commit") &nbsp;${GlyphChars.ArrowLeftRightLong}&nbsp; `;
current =
compareUris.current.sha == null || compareUris.current.isUncommitted
? `_${GitRevision.shorten(compareUris.current.sha, {
strings: {
working: 'Working Tree',
},
})}_`
: `[$(git-commit) ${GitRevision.shorten(
compareUris.current.sha || '',
)}](${ShowQuickCommitCommand.getMarkdownCommandArgs(compareUris.current.sha || '')} "Show Commit")`;
} else {
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs(commit, editorLine)} "Open Changes")`;
if (previousSha === null) {
previousSha = await commit.getPreviousSha();
}
if (previousSha) {
previous = ` &nbsp;[$(git-commit) ${GitRevision.shorten(
previousSha,
)}](${ShowQuickCommitCommand.getMarkdownCommandArgs(previousSha)} "Show Commit") &nbsp;${
GlyphChars.ArrowLeftRightLong
}&nbsp;`;
}
const remotes = await Container.instance.git.getRemotesWithProviders(commit.repoPath, { sort: true });
current = `[$(git-commit) ${commit.shortSha}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
commit.sha,
)} "Show Commit")`;
}
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
message = `${diff}\n---\n\nChanges${previous ?? ' added in '}${current} &nbsp;&nbsp;|&nbsp;&nbsp; ${message}`;
const [previousLineComparisonUrisResult, autolinkedIssuesOrPullRequestsResult, prResult, presenceResult] =
await Promise.allSettled([
commit.isUncommitted ? commit.getPreviousComparisonUrisForLine(editorLine, uri.sha) : undefined,
getAutoLinkedIssuesOrPullRequests(message, remotes),
options?.pullRequests?.pr ??
getPullRequestForCommit(commit.ref, remotes, {
pullRequests:
options?.pullRequests?.enabled !== false &&
CommitFormatter.has(
format,
'pullRequest',
'pullRequestAgo',
'pullRequestAgoOrDate',
'pullRequestDate',
'pullRequestState',
),
}),
Container.instance.vsls.maybeGetPresence(commit.author.email),
]);
const markdown = new MarkdownString(message, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;
}
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
export async function localChangesMessage(
fromCommit: GitCommit | undefined,
uri: GitUri,
editorLine: number, // 0-based, Git is 1-based
hunk: GitDiffHunk,
): Promise<MarkdownString | undefined> {
const diff = getDiffFromHunk(hunk);
let message;
let previous;
let current;
if (fromCommit == null) {
previous = '_Working Tree_';
current = '_Unsaved_';
} else {
const file = await fromCommit.findFile(uri);
if (file == null) return undefined;
message = `[$(compare-changes)](${DiffWithCommand.getMarkdownCommandArgs({
lhs: {
sha: fromCommit.sha,
uri: GitUri.fromFile(file, uri.repoPath!, undefined, true).toFileUri(),
},
rhs: {
sha: '',
uri: uri.toFileUri(),
},
repoPath: uri.repoPath!,
line: editorLine,
})} "Open Changes")`;
const previousLineComparisonUris = getSettledValue(previousLineComparisonUrisResult);
const autolinkedIssuesOrPullRequests = getSettledValue(autolinkedIssuesOrPullRequestsResult);
const pr = getSettledValue(prResult);
const presence = getSettledValue(presenceResult);
previous = `[$(git-commit) ${fromCommit.shortSha}](${ShowQuickCommitCommand.getMarkdownCommandArgs(
fromCommit.sha,
)} "Show Commit")`;
// Remove possible duplicate pull request
if (pr != null && !(pr instanceof PromiseCancelledError)) {
autolinkedIssuesOrPullRequests?.delete(pr.id);
}
current = '_Working Tree_';
}
message = `${diff}\n---\n\nLocal Changes &nbsp;${previous} &nbsp;${
GlyphChars.ArrowLeftRightLong
}&nbsp; ${current}${message == null ? '' : ` &nbsp;&nbsp;|&nbsp;&nbsp; ${message}`}`;
const markdown = new MarkdownString(message, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;
}
const details = await CommitFormatter.fromTemplateAsync(format, commit, {
autolinkedIssuesOrPullRequests: autolinkedIssuesOrPullRequests,
dateFormat: dateFormat,
editor: {
line: editorLine,
uri: uri,
},
getBranchAndTagTips: options?.getBranchAndTagTips,
messageAutolinks: options?.autolinks,
pullRequestOrRemote: pr,
presence: presence,
previousLineComparisonUris: previousLineComparisonUris,
outputFormat: 'markdown',
remotes: remotes,
});
export async function detailsMessage(
commit: GitCommit,
uri: GitUri,
editorLine: number, // 0-based, Git is 1-based
format: string,
dateFormat: string | null,
options?: {
autolinks?: boolean;
cancellationToken?: CancellationToken;
pullRequests?: {
enabled: boolean;
pr?: PullRequest | PromiseCancelledError<Promise<PullRequest | undefined>>;
};
getBranchAndTagTips?: (
sha: string,
options?: { compact?: boolean | undefined; icons?: boolean | undefined },
) => string | undefined;
},
): Promise<MarkdownString> {
if (dateFormat === null) {
dateFormat = 'MMMM Do, YYYY h:mma';
}
const markdown = new MarkdownString(details, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;
let message = commit.message ?? commit.summary;
if (commit.message == null && !commit.isUncommitted) {
await commit.ensureFullDetails();
message = commit.message ?? commit.summary;
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
}
function getDiffFromHunk(hunk: GitDiffHunk): string {
return `\`\`\`diff\n${hunk.diff.trim()}\n\`\`\``;
const remotes = await Container.instance.git.getRemotesWithProviders(commit.repoPath, { sort: true });
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
const [previousLineComparisonUrisResult, autolinkedIssuesOrPullRequestsResult, prResult, presenceResult] =
await Promise.allSettled([
commit.isUncommitted ? commit.getPreviousComparisonUrisForLine(editorLine, uri.sha) : undefined,
getAutoLinkedIssuesOrPullRequests(message, remotes),
options?.pullRequests?.pr ??
getPullRequestForCommit(commit.ref, remotes, {
pullRequests:
options?.pullRequests?.enabled !== false &&
CommitFormatter.has(
format,
'pullRequest',
'pullRequestAgo',
'pullRequestAgoOrDate',
'pullRequestDate',
'pullRequestState',
),
}),
Container.instance.vsls.maybeGetPresence(commit.author.email),
]);
if (options?.cancellationToken?.isCancellationRequested) return new MarkdownString();
const previousLineComparisonUris = getSettledValue(previousLineComparisonUrisResult);
const autolinkedIssuesOrPullRequests = getSettledValue(autolinkedIssuesOrPullRequestsResult);
const pr = getSettledValue(prResult);
const presence = getSettledValue(presenceResult);
// Remove possible duplicate pull request
if (pr != null && !(pr instanceof PromiseCancelledError)) {
autolinkedIssuesOrPullRequests?.delete(pr.id);
}
function getDiffFromHunkLine(hunkLine: GitDiffHunkLine, diffStyle?: 'line' | 'hunk'): string {
if (diffStyle === 'hunk' || (diffStyle == null && configuration.get('hovers.changesDiff') === 'hunk')) {
return getDiffFromHunk(hunkLine.hunk);
}
const details = await CommitFormatter.fromTemplateAsync(format, commit, {
autolinkedIssuesOrPullRequests: autolinkedIssuesOrPullRequests,
dateFormat: dateFormat,
editor: {
line: editorLine,
uri: uri,
},
getBranchAndTagTips: options?.getBranchAndTagTips,
messageAutolinks: options?.autolinks,
pullRequestOrRemote: pr,
presence: presence,
previousLineComparisonUris: previousLineComparisonUris,
outputFormat: 'markdown',
remotes: remotes,
});
const markdown = new MarkdownString(details, true);
markdown.supportHtml = true;
markdown.isTrusted = true;
return markdown;
}
return `\`\`\`diff${hunkLine.previous == null ? '' : `\n- ${hunkLine.previous.line.trim()}`}${
hunkLine.current == null ? '' : `\n+ ${hunkLine.current.line.trim()}`
}\n\`\`\``;
function getDiffFromHunk(hunk: GitDiffHunk): string {
return `\`\`\`diff\n${hunk.diff.trim()}\n\`\`\``;
}
function getDiffFromHunkLine(hunkLine: GitDiffHunkLine, diffStyle?: 'line' | 'hunk'): string {
if (diffStyle === 'hunk' || (diffStyle == null && configuration.get('hovers.changesDiff') === 'hunk')) {
return getDiffFromHunk(hunkLine.hunk);
}
async function getAutoLinkedIssuesOrPullRequests(message: string, remotes: GitRemote[]) {
const scope = getNewLogScope('Hovers.getAutoLinkedIssuesOrPullRequests');
Logger.debug(scope, `${GlyphChars.Dash} message=<message>`);
return `\`\`\`diff${hunkLine.previous == null ? '' : `\n- ${hunkLine.previous.line.trim()}`}${
hunkLine.current == null ? '' : `\n+ ${hunkLine.current.line.trim()}`
}\n\`\`\``;
}
const start = hrtime();
async function getAutoLinkedIssuesOrPullRequests(message: string, remotes: GitRemote[]) {
const scope = getNewLogScope('Hovers.getAutoLinkedIssuesOrPullRequests');
Logger.debug(scope, `${GlyphChars.Dash} message=<message>`);
const cfg = configuration.get('hovers');
if (
!cfg.autolinks.enabled ||
!cfg.autolinks.enhanced ||
!CommitFormatter.has(cfg.detailsMarkdownFormat, 'message')
) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
const start = hrtime();
return undefined;
}
const cfg = configuration.get('hovers');
if (
!cfg.autolinks.enabled ||
!cfg.autolinks.enhanced ||
!CommitFormatter.has(cfg.detailsMarkdownFormat, 'message')
) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
const remote = await Container.instance.git.getBestRemoteWithRichProvider(remotes);
if (remote?.provider == null) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return undefined;
}
return undefined;
}
const remote = await Container.instance.git.getBestRemoteWithRichProvider(remotes);
if (remote?.provider == null) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
// TODO: Make this configurable?
const timeout = 250;
try {
const autolinks = await Container.instance.autolinks.getLinkedIssuesAndPullRequests(message, remote, {
timeout: timeout,
});
if (autolinks != null && Logger.enabled(LogLevel.Debug)) {
// If there are any issues/PRs that timed out, log it
const prCount = count(autolinks.values(), pr => pr instanceof PromiseCancelledError);
if (prCount !== 0) {
Logger.debug(
scope,
`timed out ${
GlyphChars.Dash
} ${prCount} issue/pull request queries took too long (over ${timeout} ms) ${
GlyphChars.Dot
} ${getDurationMilliseconds(start)} ms`,
);
// const pending = [
// ...Iterables.map(autolinks.values(), issueOrPullRequest =>
// issueOrPullRequest instanceof CancelledPromiseError
// ? issueOrPullRequest.promise
// : undefined,
// ),
// ];
// void Promise.all(pending).then(() => {
// Logger.debug(
// scope,
// `${GlyphChars.Dot} ${count} issue/pull request queries completed; refreshing...`,
// );
// void executeCoreCommand(CoreCommands.EditorShowHover);
// });
return autolinks;
}
}
return undefined;
}
// TODO: Make this configurable?
const timeout = 250;
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
try {
const autolinks = await Container.instance.autolinks.getLinkedIssuesAndPullRequests(message, remote, {
timeout: timeout,
});
return autolinks;
} catch (ex) {
Logger.error(ex, scope, `failed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
if (autolinks != null && Logger.enabled(LogLevel.Debug)) {
// If there are any issues/PRs that timed out, log it
const prCount = count(autolinks.values(), pr => pr instanceof PromiseCancelledError);
if (prCount !== 0) {
Logger.debug(
scope,
`timed out ${
GlyphChars.Dash
} ${prCount} issue/pull request queries took too long (over ${timeout} ms) ${
GlyphChars.Dot
} ${getDurationMilliseconds(start)} ms`,
);
return undefined;
// const pending = [
// ...Iterables.map(autolinks.values(), issueOrPullRequest =>
// issueOrPullRequest instanceof CancelledPromiseError
// ? issueOrPullRequest.promise
// : undefined,
// ),
// ];
// void Promise.all(pending).then(() => {
// Logger.debug(
// scope,
// `${GlyphChars.Dot} ${count} issue/pull request queries completed; refreshing...`,
// );
// void executeCoreCommand(CoreCommands.EditorShowHover);
// });
return autolinks;
}
}
}
async function getPullRequestForCommit(
ref: string,
remotes: GitRemote[],
options?: {
pullRequests?: boolean;
},
) {
const scope = getNewLogScope('Hovers.getPullRequestForCommit');
Logger.debug(scope, `${GlyphChars.Dash} ref=${ref}`);
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
const start = hrtime();
return autolinks;
} catch (ex) {
Logger.error(ex, scope, `failed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
if (!options?.pullRequests) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return undefined;
}
}
return undefined;
}
async function getPullRequestForCommit(
ref: string,
remotes: GitRemote[],
options?: {
pullRequests?: boolean;
},
) {
const scope = getNewLogScope('Hovers.getPullRequestForCommit');
Logger.debug(scope, `${GlyphChars.Dash} ref=${ref}`);
const remote = await Container.instance.git.getBestRemoteWithRichProvider(remotes, {
includeDisconnected: true,
});
if (remote?.provider == null) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
const start = hrtime();
return undefined;
}
if (!options?.pullRequests) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
const { provider } = remote;
const connected = provider.maybeConnected ?? (await provider.isConnected());
if (!connected) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return undefined;
}
return remote;
}
const remote = await Container.instance.git.getBestRemoteWithRichProvider(remotes, {
includeDisconnected: true,
});
if (remote?.provider == null) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return undefined;
}
try {
const pr = await Container.instance.git.getPullRequestForCommit(ref, provider, { timeout: 250 });
const { provider } = remote;
const connected = provider.maybeConnected ?? (await provider.isConnected());
if (!connected) {
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return remote;
}
return pr;
} catch (ex) {
if (ex instanceof PromiseCancelledError) {
Logger.debug(scope, `timed out ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
try {
const pr = await Container.instance.git.getPullRequestForCommit(ref, provider, { timeout: 250 });
return ex;
}
Logger.debug(scope, `completed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
Logger.error(ex, scope, `failed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return pr;
} catch (ex) {
if (ex instanceof PromiseCancelledError) {
Logger.debug(scope, `timed out ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return undefined;
return ex;
}
Logger.error(ex, scope, `failed ${GlyphChars.Dot} ${getDurationMilliseconds(start)} ms`);
return undefined;
}
}

+ 3
- 8
src/hovers/lineHoverController.ts View File

@ -7,7 +7,7 @@ import { Logger } from '../logger';
import { debug } from '../system/decorators/log';
import { once } from '../system/event';
import type { LinesChangeEvent } from '../trackers/gitLineTracker';
import { Hovers } from './hovers';
import { changesMessage, detailsMessage } from './hovers';
const maxSmallIntegerV8 = 2 ** 30; // Max number that can be stored in V8's smis (small integers)
@ -123,7 +123,7 @@ export class LineHoverController implements Disposable {
const trackedDocument = await this.container.tracker.get(document);
if (trackedDocument == null) return undefined;
const message = await Hovers.detailsMessage(
const message = await detailsMessage(
commit,
trackedDocument.uri,
editorLine,
@ -182,12 +182,7 @@ export class LineHoverController implements Disposable {
const trackedDocument = await this.container.tracker.get(document);
if (trackedDocument == null) return undefined;
const message = await Hovers.changesMessage(
commit,
trackedDocument.uri,
position.line,
trackedDocument.document,
);
const message = await changesMessage(commit, trackedDocument.uri, position.line, trackedDocument.document);
if (message == null) return undefined;
return new Hover(message, range);

+ 2
- 2
src/statusbar/statusBarController.ts View File

@ -7,7 +7,7 @@ import type { Container } from '../container';
import { CommitFormatter } from '../git/formatters/commitFormatter';
import type { GitCommit } from '../git/models/commit';
import type { PullRequest } from '../git/models/pullRequest';
import { Hovers } from '../hovers/hovers';
import { detailsMessage } from '../hovers/hovers';
import type { LogScope } from '../logger';
import { Logger } from '../logger';
import { asCommand } from '../system/command';
@ -372,7 +372,7 @@ export class StatusBarController implements Disposable {
) {
if (cancellationToken.isCancellationRequested) return;
const tooltip = await Hovers.detailsMessage(
const tooltip = await detailsMessage(
commit,
commit.getGitUri(),
commit.lines[0].line,

Loading…
Cancel
Save