diff --git a/src/client/RPCClient.ts b/src/client/RPCClient.ts index 363ffc3..38cbc2a 100644 --- a/src/client/RPCClient.ts +++ b/src/client/RPCClient.ts @@ -13,7 +13,7 @@ export default class RPCClient implements Disposable { public config = workspace.getConfiguration('discord'); - public git!: API; + public git?: API; private _rpc: any; diff --git a/src/extension.ts b/src/extension.ts index ed33067..34ba302 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -4,7 +4,6 @@ import Logger from './structures/Logger'; import { GitExtension } from './git'; const { register } = require('discord-rpc'); // eslint-disable-line -const sleep = (wait: number) => new Promise(resolve => setTimeout(resolve, wait)); let loginTimeout: NodeJS.Timer; const statusBarIcon: StatusBarItem = window.createStatusBarItem(StatusBarAlignment.Left); @@ -15,18 +14,6 @@ register(config.get('clientID')!); const rpc = new RPCClient(config.get('clientID')!, statusBarIcon); export async function activate(context: ExtensionContext) { - try { - const ext = extensions.getExtension('vscode.git')!; - await ext.activate(); - rpc.git = ext.exports.getAPI(1); - } catch { - // We loaded before the git extension, give it a bit to load - // In a perfect world this shouldn't happen - await sleep(2000); - const ext = extensions.getExtension('vscode.git')!; - await ext.activate(); - rpc.git = ext.exports.getAPI(1); - } Logger.log('Discord Presence activated!'); let isWorkspaceExcluded = false; @@ -105,6 +92,17 @@ export async function activate(context: ExtensionContext) { disableJoinRequests, ); + const gitExtension = extensions.getExtension('vscode.git'); + if (gitExtension) { + if (!gitExtension.exports.enabled) { + gitExtension.exports.onDidChangeEnablement(e => { + if (e) { + rpc.git = gitExtension.exports.getAPI(1); + } + }); + } + } + if (!isWorkspaceExcluded && config.get('enabled')) { statusBarIcon.show(); try { diff --git a/src/git.d.ts b/src/git.d.ts index ce263da..bc46dde 100644 --- a/src/git.d.ts +++ b/src/git.d.ts @@ -1,9 +1,10 @@ /* - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { Uri, Event } from 'vscode'; +// eslint-disable-next-line +import { Uri, SourceControlInputBox, Event, CancellationToken } from 'vscode'; export interface Git { readonly path: string; @@ -41,6 +42,7 @@ export interface Commit { readonly hash: string; readonly message: string; readonly parents: string[]; + readonly authorEmail?: string | undefined; } export interface Submodule { @@ -67,6 +69,7 @@ export const enum Status { DELETED, UNTRACKED, IGNORED, + INTENT_TO_ADD, ADDED_BY_US, ADDED_BY_THEM, @@ -108,6 +111,14 @@ export interface RepositoryUIState { readonly onDidChange: Event; } +/** + * Log options. + */ +export interface LogOptions { + /** Max number of log entries to retrieve. If not specified, the default is 32. */ + readonly maxEntries?: number; +} + export interface Repository { readonly rootUri: Uri; readonly inputBox: InputBox; @@ -117,6 +128,7 @@ export interface Repository { getConfigs(): Promise<{ key: string; value: string }[]>; getConfig(key: string): Promise; setConfig(key: string, value: string): Promise; + getGlobalConfig(key: string): Promise; getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number }>; detectObjectType(object: string): Promise<{ mimetype: string; encoding?: string }>; @@ -128,11 +140,16 @@ export interface Repository { apply(patch: string, reverse?: boolean): Promise; diff(cached?: boolean): Promise; + diffWithHEAD(): Promise; diffWithHEAD(path: string): Promise; + diffWith(ref: string): Promise; diffWith(ref: string, path: string): Promise; + diffIndexWithHEAD(): Promise; diffIndexWithHEAD(path: string): Promise; + diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffBlobs(object1: string, object2: string): Promise; + diffBetween(ref1: string, ref2: string): Promise; diffBetween(ref1: string, ref2: string, path: string): Promise; hashObject(data: string): Promise; @@ -150,12 +167,19 @@ export interface Repository { addRemote(name: string, url: string): Promise; removeRemote(name: string): Promise; - fetch(remote?: string, ref?: string): Promise; - pull(): Promise; + fetch(remote?: string, ref?: string, depth?: number): Promise; + pull(unshallow?: boolean): Promise; push(remoteName?: string, branchName?: string, setUpstream?: boolean): Promise; + + blame(path: string): Promise; + log(options?: LogOptions): Promise; } +export type APIState = 'uninitialized' | 'initialized'; + export interface API { + readonly state: APIState; + readonly onDidChangeState: Event; readonly git: Git; readonly repositories: Repository[]; readonly onDidOpenRepository: Event; @@ -211,4 +235,7 @@ export const enum GitErrorCodes { WrongCase = 'WrongCase', CantLockRef = 'CantLockRef', CantRebaseMultipleBranches = 'CantRebaseMultipleBranches', + PatchDoesNotApply = 'PatchDoesNotApply', + NoPathFound = 'NoPathFound', + UnknownPath = 'UnknownPath', } diff --git a/src/structures/Activity.ts b/src/structures/Activity.ts index 7ff6d2a..daec1ce 100644 --- a/src/structures/Activity.ts +++ b/src/structures/Activity.ts @@ -337,7 +337,7 @@ export default class Activity implements Disposable { } if (str.includes('{gitbranch}')) { - if (this.client.git.repositories.length) { + if (this.client.git?.repositories.length) { fileDetail.gitbranch = this.client.git.repositories.find(repo => repo.ui.selected)!.state.HEAD!.name; } else { fileDetail.gitbranch = 'Unknown'; @@ -345,7 +345,7 @@ export default class Activity implements Disposable { } if (str.includes('{gitreponame}')) { - if (this.client.git.repositories.length) { + if (this.client.git?.repositories.length) { fileDetail.gitreponame = this.client.git.repositories .find(repo => repo.ui.selected)! .state.remotes[0].fetchUrl!.split('/')[1]