diff --git a/src/annotations/annotations.ts b/src/annotations/annotations.ts index 20507fe..60fb8fa 100644 --- a/src/annotations/annotations.ts +++ b/src/annotations/annotations.ts @@ -63,14 +63,14 @@ export async function getHeatmapColors() { if (heatmapColors == null) { let colors; if ( - Container.config.heatmap.coldColor === defaultHeatmapColdColor && - Container.config.heatmap.hotColor === defaultHeatmapHotColor + Container.instance.config.heatmap.coldColor === defaultHeatmapColdColor && + Container.instance.config.heatmap.hotColor === defaultHeatmapHotColor ) { colors = defaultHeatmapColors; } else { const chroma = (await import(/* webpackChunkName: "heatmap-chroma" */ 'chroma-js')).default; colors = chroma - .scale([Container.config.heatmap.hotColor, Container.config.heatmap.coldColor]) + .scale([Container.instance.config.heatmap.hotColor, Container.instance.config.heatmap.coldColor]) .mode('lrgb') .classes(20) .colors(20); @@ -110,7 +110,7 @@ export class Annotations { ) { const [r, g, b, a] = this.getHeatmapColor(date, heatmap); - const { locations } = Container.config.heatmap; + const { locations } = Container.instance.config.heatmap; const gutter = locations.includes(HeatmapLocations.Gutter); const overview = locations.includes(HeatmapLocations.Overview); diff --git a/src/annotations/autolinks.ts b/src/annotations/autolinks.ts index 8fbf222..ea8e591 100644 --- a/src/annotations/autolinks.ts +++ b/src/annotations/autolinks.ts @@ -31,7 +31,7 @@ export class Autolinks implements Disposable { protected _disposable: Disposable | undefined; private _references: CacheableAutolinkReference[] = []; - constructor() { + constructor(private readonly container: Container) { this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); this.onConfigurationChanged(); @@ -43,7 +43,7 @@ export class Autolinks implements Disposable { private onConfigurationChanged(e?: ConfigurationChangeEvent) { if (configuration.changed(e, 'autolinks')) { - this._references = Container.config.autolinks ?? []; + this._references = this.container.config.autolinks ?? []; } } diff --git a/src/annotations/blameAnnotationProvider.ts b/src/annotations/blameAnnotationProvider.ts index 1679fb8..628ab82 100644 --- a/src/annotations/blameAnnotationProvider.ts +++ b/src/annotations/blameAnnotationProvider.ts @@ -18,12 +18,13 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase annotationType: FileAnnotationType, editor: TextEditor, trackedDocument: TrackedDocument, + protected readonly container: Container, ) { super(annotationType, editor, trackedDocument); this.blame = editor.document.isDirty - ? Container.git.getBlameForFileContents(this.trackedDocument.uri, editor.document.getText()) - : Container.git.getBlameForFile(this.trackedDocument.uri); + ? this.container.git.getBlameForFileContents(this.trackedDocument.uri, editor.document.getText()) + : this.container.git.getBlameForFile(this.trackedDocument.uri); if (editor.document.isDirty) { trackedDocument.setForceDirtyStateChangeOnNextDocumentChange(); @@ -69,7 +70,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase dates.sort((a, b) => a.getTime() - b.getTime()); const coldThresholdDate = new Date(); - coldThresholdDate.setDate(coldThresholdDate.getDate() - (Container.config.heatmap.ageThreshold || 90)); + coldThresholdDate.setDate(coldThresholdDate.getDate() - (this.container.config.heatmap.ageThreshold || 90)); const coldThresholdTimestamp = coldThresholdDate.getTime(); const hotDates: Date[] = []; @@ -122,8 +123,8 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase registerHoverProviders(providers: { details: boolean; changes: boolean }) { if ( - !Container.config.hovers.enabled || - !Container.config.hovers.annotations.enabled || + !this.container.config.hovers.enabled || + !this.container.config.hovers.annotations.enabled || (!providers.details && !providers.changes) ) { return; @@ -144,7 +145,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase position: Position, _token: CancellationToken, ): Promise { - if (Container.config.hovers.annotations.over !== 'line' && position.character !== 0) return undefined; + if (this.container.config.hovers.annotations.over !== 'line' && position.character !== 0) return undefined; if (this.document.uri.toString() !== document.uri.toString()) return undefined; @@ -175,7 +176,7 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase // Get the full commit message -- since blame only returns the summary let logCommit: GitCommit | undefined = undefined; if (!commit.isUncommitted) { - logCommit = await Container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, { + logCommit = await this.container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, { ref: commit.sha, }); if (logCommit != null) { @@ -194,12 +195,12 @@ export abstract class BlameAnnotationProviderBase extends AnnotationProviderBase logCommit ?? commit, await GitUri.fromUri(document.uri), editorLine, - Container.config.hovers.detailsMarkdownFormat, - Container.config.defaultDateFormat, + this.container.config.hovers.detailsMarkdownFormat, + this.container.config.defaultDateFormat, { - autolinks: Container.config.hovers.autolinks.enabled, + autolinks: this.container.config.hovers.autolinks.enabled, pullRequests: { - enabled: Container.config.hovers.pullRequests.enabled, + enabled: this.container.config.hovers.pullRequests.enabled, }, }, ); diff --git a/src/annotations/fileAnnotationController.ts b/src/annotations/fileAnnotationController.ts index 7e0b0ce..97b8f9b 100644 --- a/src/annotations/fileAnnotationController.ts +++ b/src/annotations/fileAnnotationController.ts @@ -79,11 +79,13 @@ export class FileAnnotationController implements Disposable { private readonly _toggleModes: Map; private _windowAnnotationType?: FileAnnotationType | undefined = undefined; - constructor() { - this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); + constructor(private readonly container: Container) { + this._disposable = Disposable.from( + container.onReady(this.onReady, this), + configuration.onDidChange(this.onConfigurationChanged, this), + ); this._toggleModes = new Map(); - this.onConfigurationChanged(); } dispose() { @@ -99,8 +101,12 @@ export class FileAnnotationController implements Disposable { this._disposable?.dispose(); } + private onReady(): void { + this.onConfigurationChanged(); + } + private onConfigurationChanged(e?: ConfigurationChangeEvent) { - const cfg = Container.config; + const cfg = this.container.config; if (configuration.changed(e, 'blame.highlight')) { Decorations.gutterBlameHighlight?.dispose(); @@ -274,7 +280,7 @@ export class FileAnnotationController implements Disposable { } private onTextDocumentClosed(document: TextDocument) { - if (!Container.git.isTrackable(document.uri)) return; + if (!this.container.git.isTrackable(document.uri)) return; for (const [key, p] of this._annotationProviders) { if (p.document !== document) continue; @@ -340,7 +346,7 @@ export class FileAnnotationController implements Disposable { const provider = this.getProvider(editor); if (provider == null) return undefined; - const trackedDocument = await Container.tracker.get(editor!.document); + const trackedDocument = await this.container.tracker.get(editor!.document); if (trackedDocument == null || !trackedDocument.isBlameable) return undefined; return provider.annotationType; @@ -385,7 +391,7 @@ export class FileAnnotationController implements Disposable { if (editor == null) return false; // || editor.viewColumn == null) return false; this._editor = editor; - const trackedDocument = await Container.tracker.getOrAdd(editor.document); + const trackedDocument = await this.container.tracker.getOrAdd(editor.document); if (!trackedDocument.isBlameable) return false; const currentProvider = this.getProvider(editor); @@ -433,7 +439,7 @@ export class FileAnnotationController implements Disposable { on?: boolean, ): Promise { if (editor != null) { - const trackedDocument = await Container.tracker.getOrAdd(editor.document); + const trackedDocument = await this.container.tracker.getOrAdd(editor.document); if ((type === FileAnnotationType.Changes && !trackedDocument.isTracked) || !trackedDocument.isBlameable) { return false; } @@ -459,7 +465,7 @@ export class FileAnnotationController implements Disposable { private async attachKeyboardHook() { // Allows pressing escape to exit the annotations if (this._keyboardScope == null) { - this._keyboardScope = await Container.keyboard.beginScope({ + this._keyboardScope = await this.container.keyboard.beginScope({ escape: { onDidPressKey: async () => { const e = this._editor; @@ -535,20 +541,20 @@ export class FileAnnotationController implements Disposable { // Allows pressing escape to exit the annotations await this.attachKeyboardHook(); - const trackedDocument = await Container.tracker.getOrAdd(editor.document); + const trackedDocument = await this.container.tracker.getOrAdd(editor.document); let provider: AnnotationProviderBase | undefined = undefined; switch (type) { case FileAnnotationType.Blame: - provider = new GutterBlameAnnotationProvider(editor, trackedDocument); + provider = new GutterBlameAnnotationProvider(editor, trackedDocument, this.container); break; case FileAnnotationType.Changes: - provider = new GutterChangesAnnotationProvider(editor, trackedDocument); + provider = new GutterChangesAnnotationProvider(editor, trackedDocument, this.container); break; case FileAnnotationType.Heatmap: - provider = new GutterHeatmapBlameAnnotationProvider(editor, trackedDocument); + provider = new GutterHeatmapBlameAnnotationProvider(editor, trackedDocument, this.container); break; } if (provider == null || !(await provider.validate())) return undefined; @@ -565,8 +571,8 @@ export class FileAnnotationController implements Disposable { window.onDidChangeTextEditorViewColumn(this.onTextEditorViewColumnChanged, this), window.onDidChangeVisibleTextEditors(Functions.debounce(this.onVisibleTextEditorsChanged, 50), this), workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this), - Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this), - Container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this), + this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this), + this.container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this), ); } diff --git a/src/annotations/gutterBlameAnnotationProvider.ts b/src/annotations/gutterBlameAnnotationProvider.ts index 177e8ea..65b4f58 100644 --- a/src/annotations/gutterBlameAnnotationProvider.ts +++ b/src/annotations/gutterBlameAnnotationProvider.ts @@ -14,8 +14,8 @@ import { BlameAnnotationProviderBase } from './blameAnnotationProvider'; import { Decorations } from './fileAnnotationController'; export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { - constructor(editor: TextEditor, trackedDocument: TrackedDocument) { - super(FileAnnotationType.Blame, editor, trackedDocument); + constructor(editor: TextEditor, trackedDocument: TrackedDocument, container: Container) { + super(FileAnnotationType.Blame, editor, trackedDocument, container); } override clear() { @@ -39,7 +39,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { let start = process.hrtime(); - const cfg = Container.config.blame; + const cfg = this.container.config.blame; // Precalculate the formatting options so we don't need to do it on each iteration const tokenOptions = Strings.getTokensFromTemplate(cfg.format).reduce<{ @@ -51,17 +51,17 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { let getBranchAndTagTips; if (CommitFormatter.has(cfg.format, 'tips')) { - getBranchAndTagTips = await Container.git.getBranchesAndTagsTipsFn(blame.repoPath); + getBranchAndTagTips = await this.container.git.getBranchesAndTagsTipsFn(blame.repoPath); } const options: CommitFormatOptions = { - dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat, + dateFormat: cfg.dateFormat === null ? this.container.config.defaultDateFormat : cfg.dateFormat, getBranchAndTagTips: getBranchAndTagTips, tokenOptions: tokenOptions, }; const avatars = cfg.avatars; - const gravatarDefault = Container.config.defaultGravatarsStyle; + const gravatarDefault = this.container.config.defaultGravatarsStyle; const separateLines = cfg.separateLines; const renderOptions = Annotations.gutterRenderOptions( separateLines, @@ -169,7 +169,7 @@ export class GutterBlameAnnotationProvider extends BlameAnnotationProviderBase { Logger.log(cc, `${Strings.getDurationMilliseconds(start)} ms to apply all gutter blame annotations`); } - this.registerHoverProviders(Container.config.hovers.annotations); + this.registerHoverProviders(this.container.config.hovers.annotations); return true; } diff --git a/src/annotations/gutterChangesAnnotationProvider.ts b/src/annotations/gutterChangesAnnotationProvider.ts index 3dd371a..048ba90 100644 --- a/src/annotations/gutterChangesAnnotationProvider.ts +++ b/src/annotations/gutterChangesAnnotationProvider.ts @@ -32,7 +32,11 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase) { + constructor( + editor: TextEditor, + trackedDocument: TrackedDocument, + private readonly container: Container, + ) { super(FileAnnotationType.Changes, editor, trackedDocument); } @@ -74,13 +78,13 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase(d?: T): d is T => Boolean(d)); if (!diffs?.length) return false; @@ -162,11 +166,11 @@ export class GutterChangesAnnotationProvider extends AnnotationProviderBase) { - super(FileAnnotationType.Heatmap, editor, trackedDocument); + constructor(editor: TextEditor, trackedDocument: TrackedDocument, container: Container) { + super(FileAnnotationType.Heatmap, editor, trackedDocument, container); } @log() @@ -58,7 +59,7 @@ export class GutterHeatmapBlameAnnotationProvider extends BlameAnnotationProvide Logger.log(cc, `${Strings.getDurationMilliseconds(start)} ms to apply recent changes annotations`); } - // this.registerHoverProviders(Container.config.hovers.annotations); + // this.registerHoverProviders(this.container.config.hovers.annotations); return true; } diff --git a/src/annotations/lineAnnotationController.ts b/src/annotations/lineAnnotationController.ts index c0c29b9..f7fa166 100644 --- a/src/annotations/lineAnnotationController.ts +++ b/src/annotations/lineAnnotationController.ts @@ -34,27 +34,31 @@ export class LineAnnotationController implements Disposable { private _editor: TextEditor | undefined; private _enabled: boolean = false; - constructor() { + constructor(private readonly container: Container) { this._disposable = Disposable.from( + container.onReady(this.onReady, this), configuration.onDidChange(this.onConfigurationChanged, this), - Container.fileAnnotations.onDidToggleAnnotations(this.onFileAnnotationsToggled, this), + container.fileAnnotations.onDidToggleAnnotations(this.onFileAnnotationsToggled, this), Authentication.onDidChange(() => void this.refresh(window.activeTextEditor)), ); - this.onConfigurationChanged(); } dispose() { this.clearAnnotations(this._editor); - Container.lineTracker.stop(this); + this.container.lineTracker.stop(this); this._disposable.dispose(); } + private onReady(): void { + this.onConfigurationChanged(); + } + private onConfigurationChanged(e?: ConfigurationChangeEvent) { if (!configuration.changed(e, 'currentLine')) return; if (configuration.changed(e, 'currentLine.enabled')) { - if (Container.config.currentLine.enabled) { + if (this.container.config.currentLine.enabled) { this._enabled = true; this.resume(); } else { @@ -152,7 +156,7 @@ export class LineAnnotationController implements Disposable { ) { if (lines.length === 0) return undefined; - const remote = await Container.git.getRichRemoteProvider(repoPath); + const remote = await this.container.git.getRichRemoteProvider(repoPath); if (remote?.provider == null) return undefined; const refs = new Set(); @@ -166,7 +170,7 @@ export class LineAnnotationController implements Disposable { const { provider } = remote; const prs = await Promises.raceAll( refs.values(), - ref => Container.git.getPullRequestForCommit(ref, provider), + ref => this.container.git.getPullRequestForCommit(ref, provider), timeout, ); if (prs.size === 0 || Iterables.every(prs.values(), pr => pr == null)) return undefined; @@ -180,7 +184,7 @@ export class LineAnnotationController implements Disposable { const cc = Logger.getCorrelationContext(); - const selections = Container.lineTracker.selections; + const selections = this.container.lineTracker.selections; if (editor == null || selections == null || !isTextEditor(editor)) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because there is no valid editor or no valid selections`; @@ -197,7 +201,7 @@ export class LineAnnotationController implements Disposable { this._editor = editor; } - const cfg = Container.config.currentLine; + const cfg = this.container.config.currentLine; if (this.suspended) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the controller is suspended`; @@ -207,7 +211,7 @@ export class LineAnnotationController implements Disposable { return; } - const trackedDocument = await Container.tracker.getOrAdd(editor.document); + const trackedDocument = await this.container.tracker.getOrAdd(editor.document); if (!trackedDocument.isBlameable && this.suspended) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${ @@ -222,7 +226,7 @@ export class LineAnnotationController implements Disposable { } // Make sure the editor hasn't died since the await above and that we are still on the same line(s) - if (editor.document == null || !Container.lineTracker.includes(selections)) { + if (editor.document == null || !this.container.lineTracker.includes(selections)) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} Skipped because the ${ editor.document == null @@ -243,7 +247,7 @@ export class LineAnnotationController implements Disposable { const commitLines = [ ...Iterables.filterMap(selections, selection => { - const state = Container.lineTracker.getState(selection.active); + const state = this.container.lineTracker.getState(selection.active); if (state?.commit == null) { Logger.debug(cc, `Line ${selection.active} returned no commit`); return undefined; @@ -258,7 +262,7 @@ export class LineAnnotationController implements Disposable { // TODO: Make this configurable? const timeout = 100; const [getBranchAndTagTips, prs] = await Promise.all([ - CommitFormatter.has(cfg.format, 'tips') ? Container.git.getBranchesAndTagsTipsFn(repoPath) : undefined, + CommitFormatter.has(cfg.format, 'tips') ? this.container.git.getBranchesAndTagsTipsFn(repoPath) : undefined, repoPath != null && cfg.pullRequests.enabled && CommitFormatter.has( @@ -293,7 +297,7 @@ export class LineAnnotationController implements Disposable { // l, cfg.format, { - dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat, + dateFormat: cfg.dateFormat === null ? this.container.config.defaultDateFormat : cfg.dateFormat, getBranchAndTagTips: getBranchAndTagTips, pullRequestOrRemote: prs?.get(commit.ref), pullRequestPendingMessage: `PR ${GlyphChars.Ellipsis}`, @@ -312,17 +316,17 @@ export class LineAnnotationController implements Disposable { private setLineTracker(enabled: boolean) { if (enabled) { - if (!Container.lineTracker.isSubscribed(this)) { - Container.lineTracker.start( + if (!this.container.lineTracker.isSubscribed(this)) { + this.container.lineTracker.start( this, - Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this), + this.container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this), ); } return; } - Container.lineTracker.stop(this); + this.container.lineTracker.stop(this); } private async waitForAnyPendingPullRequests( diff --git a/src/api/actionRunners.ts b/src/api/actionRunners.ts index 07d6512..ce1e1f2 100644 --- a/src/api/actionRunners.ts +++ b/src/api/actionRunners.ts @@ -1,7 +1,7 @@ 'use strict'; import { commands, Disposable, Event, EventEmitter, QuickPickItem, window } from 'vscode'; import { Commands } from '../commands/common'; -import { configuration } from '../configuration'; +import { Config, configuration } from '../configuration'; import { ContextKeys, setContext } from '../constants'; import { Container } from '../container'; import { getQuickPickIgnoreFocusOut } from '../quickpicks'; @@ -128,7 +128,7 @@ export class ActionRunners implements Disposable { private readonly _actionRunners = new Map[]>(); private readonly _disposable: Disposable; - constructor() { + constructor(private readonly container: Container) { const subscriptions: Disposable[] = [ configuration.onDidChange(e => { if (!configuration.changed(e, 'partners')) return; @@ -165,7 +165,7 @@ export class ActionRunners implements Disposable { } get(action: Actions): RegisteredActionRunner[] | undefined { - return filterOnlyEnabledRunners(this._actionRunners.get(action)); + return filterOnlyEnabledRunners(this.container.config, this._actionRunners.get(action)); } has(action: Actions): boolean { @@ -337,10 +337,10 @@ export class ActionRunners implements Disposable { } } -function filterOnlyEnabledRunners(runners: RegisteredActionRunner[] | undefined) { +function filterOnlyEnabledRunners(config: Config, runners: RegisteredActionRunner[] | undefined) { if (runners == null || runners.length === 0) return undefined; - const partners = Container.config.partners; + const partners = config.partners; if (partners == null) return runners; return runners.filter( diff --git a/src/api/api.ts b/src/api/api.ts index b0eab6f..dcc7c82 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -12,6 +12,11 @@ const emptyDisposable = Object.freeze({ }); export class Api implements GitLensApi { + readonly #container: Container; + constructor(container: Container) { + this.#container = container; + } + registerActionRunner(action: Action, runner: ActionRunner): Disposable { if (runner.name === builtInActionRunnerName) { throw new Error(`Cannot use the reserved name '${builtInActionRunnerName}'`); @@ -20,7 +25,7 @@ export class Api implements GitLensApi { if ((action as string) === 'hover.commandHelp') { action = 'hover.commands'; } - return Container.actionRunners.register(action, runner); + return this.#container.actionRunners.register(action, runner); } // registerAutolinkProvider(provider: RemoteProvider): Disposable; @@ -39,7 +44,7 @@ export function preview() { if (fn == null) throw new Error('Not supported'); descriptor.value = function (this: any, ...args: any[]) { - if (Container.insiders || Logger.isDebugging) return fn!.apply(this, args); + if (Container.instance.insiders || Logger.isDebugging) return fn!.apply(this, args); console.error('GitLens preview APIs are only available in the Insiders edition'); return emptyDisposable; diff --git a/src/avatars.ts b/src/avatars.ts index 3e7a615..024c7d9 100644 --- a/src/avatars.ts +++ b/src/avatars.ts @@ -27,7 +27,7 @@ _onDidFetchAvatar.event( ), ] : undefined; - void Container.context.globalState.update(GlobalState.Avatars, avatars); + void Container.instance.context.globalState.update(GlobalState.Avatars, avatars); }, 1000), ); @@ -139,7 +139,7 @@ function createOrUpdateAvatar( function ensureAvatarCache(cache: Map | undefined): asserts cache is Map { if (cache == null) { - const avatars: [string, Avatar][] | undefined = Container.context.globalState + const avatars: [string, Avatar][] | undefined = Container.instance.context.globalState .get<[string, SerializedAvatar][]>(GlobalState.Avatars) ?.map<[string, Avatar]>(([key, avatar]) => [ key, @@ -184,13 +184,13 @@ async function getAvatarUriFromRemoteProvider( try { let account; - if (Container.config.integrations.enabled) { + if (Container.instance.config.integrations.enabled) { // if (typeof repoPathOrCommit === 'string') { - // const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit); + // const remote = await Container.instance.git.getRichRemoteProvider(repoPathOrCommit); // account = await remote?.provider.getAccountForEmail(email, { avatarSize: size }); // } else { if (typeof repoPathOrCommit !== 'string') { - const remote = await Container.git.getRichRemoteProvider(repoPathOrCommit.repoPath); + const remote = await Container.instance.git.getRichRemoteProvider(repoPathOrCommit.repoPath); account = await remote?.provider.getAccountForCommit(repoPathOrCommit.ref, { avatarSize: size }); } } @@ -248,7 +248,7 @@ export function getPresenceDataUri(status: ContactPresenceStatus) { export function resetAvatarCache(reset: 'all' | 'failed' | 'fallback') { switch (reset) { case 'all': - void Container.context.globalState.update(GlobalState.Avatars, undefined); + void Container.instance.context.globalState.update(GlobalState.Avatars, undefined); avatarCache?.clear(); avatarQueue.clear(); break; diff --git a/src/codelens/codeLensController.ts b/src/codelens/codeLensController.ts index 339a4aa..2af49fd 100644 --- a/src/codelens/codeLensController.ts +++ b/src/codelens/codeLensController.ts @@ -17,9 +17,11 @@ export class GitCodeLensController implements Disposable { private _provider: GitCodeLensProvider | undefined; private _providerDisposable: Disposable | undefined; - constructor() { - this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); - this.onConfigurationChanged(); + constructor(private readonly container: Container) { + this._disposable = Disposable.from( + container.onReady(this.onReady, this), + configuration.onDidChange(this.onConfigurationChanged, this), + ); } dispose() { @@ -27,6 +29,10 @@ export class GitCodeLensController implements Disposable { this._disposable?.dispose(); } + private onReady(): void { + this.onConfigurationChanged(); + } + private onConfigurationChanged(e?: ConfigurationChangeEvent) { if ( configuration.changed(e, 'codeLens') || @@ -38,7 +44,7 @@ export class GitCodeLensController implements Disposable { Logger.log('CodeLens config changed; resetting CodeLens provider'); } - const cfg = Container.config.codeLens; + const cfg = this.container.config.codeLens; if (cfg.enabled && (cfg.recentChange.enabled || cfg.authors.enabled)) { this.ensureProvider(); } else { @@ -62,7 +68,7 @@ export class GitCodeLensController implements Disposable { private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent) { if (this._provider === undefined || !e.document.isBlameable) return; - const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit; + const maxLines = this.container.config.advanced.blame.sizeThresholdAfterEdit; if (maxLines > 0 && e.document.lineCount > maxLines) return; Logger.log('Dirty idle triggered; resetting CodeLens provider'); @@ -92,11 +98,11 @@ export class GitCodeLensController implements Disposable { this._providerDisposable?.dispose(); - this._provider = new GitCodeLensProvider(Container.context, Container.git, Container.tracker); + this._provider = new GitCodeLensProvider(this.container); this._providerDisposable = Disposable.from( languages.registerCodeLensProvider(GitCodeLensProvider.selector, this._provider), - Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this), - Container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this), + this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this), + this.container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this), ); } } diff --git a/src/codelens/codeLensProvider.ts b/src/codelens/codeLensProvider.ts index fe55aad..4e8aa9c 100644 --- a/src/codelens/codeLensProvider.ts +++ b/src/codelens/codeLensProvider.ts @@ -9,7 +9,6 @@ import { DocumentSymbol, Event, EventEmitter, - ExtensionContext, Location, Position, Range, @@ -40,11 +39,9 @@ import { import { BuiltInCommands, DocumentSchemes } from '../constants'; import { Container } from '../container'; import { GitBlame, GitBlameLines, GitCommit, RemoteResourceType } from '../git/git'; -import { GitService } from '../git/gitService'; import { GitUri } from '../git/gitUri'; import { Logger } from '../logger'; import { Functions, Iterables } from '../system'; -import { DocumentTracker, GitDocumentState } from '../trackers/gitDocumentTracker'; export class GitRecentChangeCodeLens extends CodeLens { constructor( @@ -86,11 +83,6 @@ export class GitAuthorsCodeLens extends CodeLens { } export class GitCodeLensProvider implements CodeLensProvider { - private _onDidChangeCodeLenses = new EventEmitter(); - get onDidChangeCodeLenses(): Event { - return this._onDidChangeCodeLenses.event; - } - static selector: DocumentSelector = [ { scheme: DocumentSchemes.File }, { scheme: DocumentSchemes.Git }, @@ -99,25 +91,26 @@ export class GitCodeLensProvider implements CodeLensProvider { { scheme: DocumentSchemes.Vsls }, ]; - constructor( - _context: ExtensionContext, - private readonly _git: GitService, - private readonly _tracker: DocumentTracker, - ) {} + private _onDidChangeCodeLenses = new EventEmitter(); + get onDidChangeCodeLenses(): Event { + return this._onDidChangeCodeLenses.event; + } + + constructor(private readonly container: Container) {} reset(_reason?: 'idle' | 'saved') { this._onDidChangeCodeLenses.fire(); } async provideCodeLenses(document: TextDocument, token: CancellationToken): Promise { - const trackedDocument = await this._tracker.getOrAdd(document); + const trackedDocument = await this.container.tracker.getOrAdd(document); if (!trackedDocument.isBlameable) return []; let dirty = false; if (document.isDirty) { // Only allow dirty blames if we are idle if (trackedDocument.isDirtyIdle) { - const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit; + const maxLines = this.container.config.advanced.blame.sizeThresholdAfterEdit; if (maxLines > 0 && document.lineCount > maxLines) { dirty = true; } @@ -157,13 +150,13 @@ export class GitCodeLensProvider implements CodeLensProvider { if (languageScope.scopes.length === 1 && languageScope.scopes.includes(CodeLensScopes.Document)) { blame = document.isDirty - ? await this._git.getBlameForFileContents(gitUri, document.getText()) - : await this._git.getBlameForFile(gitUri); + ? await this.container.git.getBlameForFileContents(gitUri, document.getText()) + : await this.container.git.getBlameForFile(gitUri); } else { [blame, symbols] = await Promise.all([ document.isDirty - ? this._git.getBlameForFileContents(gitUri, document.getText()) - : this._git.getBlameForFile(gitUri), + ? this.container.git.getBlameForFileContents(gitUri, document.getText()) + : this.container.git.getBlameForFile(gitUri), commands.executeCommand(BuiltInCommands.ExecuteDocumentSymbolProvider, document.uri) as Promise< SymbolInformation[] >, @@ -217,7 +210,7 @@ export class GitCodeLensProvider implements CodeLensProvider { if (dirty || cfg.recentChange.enabled) { if (!dirty) { blameForRangeFn = Functions.once(() => - this._git.getBlameForRangeSync(blame!, gitUri, blameRange), + this.container.git.getBlameForRangeSync(blame!, gitUri, blameRange), ); } @@ -244,7 +237,7 @@ export class GitCodeLensProvider implements CodeLensProvider { if (!dirty && cfg.authors.enabled) { if (blameForRangeFn === undefined) { blameForRangeFn = Functions.once(() => - this._git.getBlameForRangeSync(blame!, gitUri, blameRange), + this.container.git.getBlameForRangeSync(blame!, gitUri, blameRange), ); } @@ -404,7 +397,9 @@ export class GitCodeLensProvider implements CodeLensProvider { let blameForRangeFn: (() => GitBlameLines | undefined) | undefined; if (dirty || cfg.recentChange.enabled) { if (!dirty) { - blameForRangeFn = Functions.once(() => this._git.getBlameForRangeSync(blame!, gitUri!, blameRange)); + blameForRangeFn = Functions.once(() => + this.container.git.getBlameForRangeSync(blame!, gitUri!, blameRange), + ); } lenses.push( new GitRecentChangeCodeLens( @@ -446,7 +441,7 @@ export class GitCodeLensProvider implements CodeLensProvider { if (multiline && !dirty) { if (blameForRangeFn === undefined) { blameForRangeFn = Functions.once(() => - this._git.getBlameForRangeSync(blame!, gitUri!, blameRange), + this.container.git.getBlameForRangeSync(blame!, gitUri!, blameRange), ); } lenses.push( @@ -496,7 +491,7 @@ export class GitCodeLensProvider implements CodeLensProvider { const recentCommit: GitCommit = Iterables.first(blame.commits.values()); // TODO@eamodio This is FAR too expensive, but this accounts for commits that delete lines -- is there another way? // if (lens.uri != null) { - // const commit = await this._git.getCommitForFile(lens.uri.repoPath, lens.uri.fsPath, { + // const commit = await this.container.git.getCommitForFile(lens.uri.repoPath, lens.uri.fsPath, { // range: lens.blameRange, // }); // if ( @@ -509,7 +504,7 @@ export class GitCodeLensProvider implements CodeLensProvider { // } let title = `${recentCommit.author}, ${recentCommit.formattedDate}`; - if (Container.config.debug) { + if (this.container.config.debug) { title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${ lens.range.end.character }${ @@ -580,7 +575,7 @@ export class GitCodeLensProvider implements CodeLensProvider { const author = Iterables.first(blame.authors.values()).name; let title = `${count} ${count > 1 ? 'authors' : 'author'} (${author}${count > 1 ? ' and others' : ''})`; - if (Container.config.debug) { + if (this.container.config.debug) { title += ` [${lens.languageId}: ${SymbolKind[lens.symbol.kind]}(${lens.range.start.character}-${ lens.range.end.character }${ @@ -871,10 +866,10 @@ export class GitCodeLensProvider implements CodeLensProvider { private getDirtyTitle(cfg: CodeLensConfig) { if (cfg.recentChange.enabled && cfg.authors.enabled) { - return Container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors; + return this.container.config.strings.codeLens.unsavedChanges.recentChangeAndAuthors; } - if (cfg.recentChange.enabled) return Container.config.strings.codeLens.unsavedChanges.recentChangeOnly; - return Container.config.strings.codeLens.unsavedChanges.authorsOnly; + if (cfg.recentChange.enabled) return this.container.config.strings.codeLens.unsavedChanges.recentChangeOnly; + return this.container.config.strings.codeLens.unsavedChanges.authorsOnly; } } diff --git a/src/commands/addAuthors.ts b/src/commands/addAuthors.ts index 184b083..fa00112 100644 --- a/src/commands/addAuthors.ts +++ b/src/commands/addAuthors.ts @@ -13,7 +13,7 @@ export class AddAuthorsCommand extends Command { async execute(sourceControl: SourceControl) { let repo; if (sourceControl?.rootUri != null) { - repo = await Container.git.getRepository(sourceControl.rootUri); + repo = await Container.instance.git.getRepository(sourceControl.rootUri); } return executeGitCommand({ diff --git a/src/commands/browseRepoAtRevision.ts b/src/commands/browseRepoAtRevision.ts index f91814c..d11bd97 100644 --- a/src/commands/browseRepoAtRevision.ts +++ b/src/commands/browseRepoAtRevision.ts @@ -66,7 +66,7 @@ export class BrowseRepoAtRevisionCommand extends ActiveEditorCommand { if (gitUri.sha == null) return; const sha = args?.before - ? await Container.git.resolveReference(gitUri.repoPath!, `${gitUri.sha}^`) + ? await Container.instance.git.resolveReference(gitUri.repoPath!, `${gitUri.sha}^`) : gitUri.sha; uri = toGitLensFSUri(sha, gitUri.repoPath!); gitUri = GitUri.fromRevisionUri(uri); diff --git a/src/commands/closeUnchangedFiles.ts b/src/commands/closeUnchangedFiles.ts index 07cb40e..78baf28 100644 --- a/src/commands/closeUnchangedFiles.ts +++ b/src/commands/closeUnchangedFiles.ts @@ -28,7 +28,7 @@ export class CloseUnchangedFilesCommand extends Command { const repoPath = await getRepoPathOrPrompt('Close All Unchanged Files'); if (!repoPath) return; - const status = await Container.git.getStatusForRepo(repoPath); + const status = await Container.instance.git.getStatusForRepo(repoPath); if (status == null) { void window.showWarningMessage('Unable to close unchanged files'); diff --git a/src/commands/closeView.ts b/src/commands/closeView.ts index 25d3dec..fa7a0a9 100644 --- a/src/commands/closeView.ts +++ b/src/commands/closeView.ts @@ -16,7 +16,7 @@ export class CloseViewCommand extends Command { async execute(command: Commands) { switch (command) { case Commands.CloseWelcomeView: - await Container.context.globalState.update(SyncedState.WelcomeViewVisible, false); + await Container.instance.context.globalState.update(SyncedState.WelcomeViewVisible, false); await setContext(ContextKeys.ViewsWelcomeVisible, false); break; } diff --git a/src/commands/common.ts b/src/commands/common.ts index 010652b..bb194a7 100644 --- a/src/commands/common.ts +++ b/src/commands/common.ts @@ -230,7 +230,7 @@ export function getCommandUri(uri?: Uri, editor?: TextEditor): Uri | undefined { } export async function getRepoPathOrActiveOrPrompt(uri: Uri | undefined, editor: TextEditor | undefined, title: string) { - const repoPath = await Container.git.getRepoPathOrActive(uri, editor); + const repoPath = await Container.instance.git.getRepoPathOrActive(uri, editor); if (repoPath) return repoPath; const pick = await RepositoryPicker.show(title); @@ -243,7 +243,7 @@ export async function getRepoPathOrActiveOrPrompt(uri: Uri | undefined, editor: } export async function getRepoPathOrPrompt(title: string, uri?: Uri) { - const repoPath = await Container.git.getRepoPath(uri); + const repoPath = await Container.instance.git.getRepoPath(uri); if (repoPath) return repoPath; const pick = await RepositoryPicker.show(title); diff --git a/src/commands/compareWith.ts b/src/commands/compareWith.ts index 3d6f71c..a48e97f 100644 --- a/src/commands/compareWith.ts +++ b/src/commands/compareWith.ts @@ -76,9 +76,9 @@ export class CompareWithCommand extends ActiveEditorCommand { if (!repoPath) return; if (args.ref1 != null && args.ref2 != null) { - void (await Container.searchAndCompareView.compare(repoPath, args.ref1, args.ref2)); + void (await Container.instance.searchAndCompareView.compare(repoPath, args.ref1, args.ref2)); } else { - Container.searchAndCompareView.selectForCompare(repoPath, args.ref1, { prompt: true }); + Container.instance.searchAndCompareView.selectForCompare(repoPath, args.ref1, { prompt: true }); } } catch (ex) { Logger.error(ex, 'CompareWithCommmand'); diff --git a/src/commands/copyCurrentBranch.ts b/src/commands/copyCurrentBranch.ts index f564992..667e552 100644 --- a/src/commands/copyCurrentBranch.ts +++ b/src/commands/copyCurrentBranch.ts @@ -20,7 +20,7 @@ export class CopyCurrentBranchCommand extends ActiveEditorCommand { if (!repoPath) return; try { - const branch = await Container.git.getBranch(repoPath); + const branch = await Container.instance.git.getBranch(repoPath); if (branch?.name) { await env.clipboard.writeText(branch.name); } diff --git a/src/commands/copyMessageToClipboard.ts b/src/commands/copyMessageToClipboard.ts index 8c7cec2..41bd670 100644 --- a/src/commands/copyMessageToClipboard.ts +++ b/src/commands/copyMessageToClipboard.ts @@ -53,10 +53,10 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand { let repoPath; // If we don't have an editor then get the message of the last commit to the branch if (uri == null) { - repoPath = await Container.git.getActiveRepoPath(editor); + repoPath = await Container.instance.git.getActiveRepoPath(editor); if (!repoPath) return; - const log = await Container.git.getLog(repoPath, { limit: 1 }); + const log = await Container.instance.git.getLog(repoPath, { limit: 1 }); if (log == null) return; args.message = Iterables.first(log.commits.values()).message; @@ -70,8 +70,12 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand { try { const blame = editor?.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); + ? await Container.instance.git.getBlameForLineContents( + gitUri, + blameline, + editor.document.getText(), + ) + : await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) return; if (blame.commit.isUncommitted) return; @@ -89,7 +93,7 @@ export class CopyMessageToClipboardCommand extends ActiveEditorCommand { } // Get the full commit message -- since blame only returns the summary - const commit = await Container.git.getCommit(repoPath!, args.sha); + const commit = await Container.instance.git.getCommit(repoPath!, args.sha); if (commit == null) return; args.message = commit.message; diff --git a/src/commands/copyShaToClipboard.ts b/src/commands/copyShaToClipboard.ts index 8995e87..1d277c5 100644 --- a/src/commands/copyShaToClipboard.ts +++ b/src/commands/copyShaToClipboard.ts @@ -29,7 +29,7 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand { protected override preExecute(context: CommandContext, args?: CopyShaToClipboardCommandArgs) { if (isCommandContextViewNodeHasCommit(context)) { args = { ...args }; - args.sha = Container.config.advanced.abbreviateShaOnCopy + args.sha = Container.instance.config.advanced.abbreviateShaOnCopy ? context.node.commit.shortSha : context.node.commit.sha; return this.execute(context.editor, context.node.commit.uri, args); @@ -53,10 +53,10 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand { try { // If we don't have an editor then get the sha of the last commit to the branch if (uri == null) { - const repoPath = await Container.git.getActiveRepoPath(editor); + const repoPath = await Container.instance.git.getActiveRepoPath(editor); if (!repoPath) return; - const log = await Container.git.getLog(repoPath, { limit: 1 }); + const log = await Container.instance.git.getLog(repoPath, { limit: 1 }); if (log == null) return; args.sha = Iterables.first(log.commits.values()).sha; @@ -67,8 +67,12 @@ export class CopyShaToClipboardCommand extends ActiveEditorCommand { try { const gitUri = await GitUri.fromUri(uri); const blame = editor?.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); + ? await Container.instance.git.getBlameForLineContents( + gitUri, + blameline, + editor.document.getText(), + ) + : await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) return; args.sha = blame.commit.sha; diff --git a/src/commands/createPullRequestOnRemote.ts b/src/commands/createPullRequestOnRemote.ts index b499496..022ec19 100644 --- a/src/commands/createPullRequestOnRemote.ts +++ b/src/commands/createPullRequestOnRemote.ts @@ -22,7 +22,7 @@ export class CreatePullRequestOnRemoteCommand extends Command { async execute(args?: CreatePullRequestOnRemoteCommandArgs) { if (args?.repoPath == null) return; - const repo = await Container.git.getRepository(args.repoPath); + const repo = await Container.instance.git.getRepository(args.repoPath); if (repo == null) return; const compareRemote = await repo.getRemote(args.remote); diff --git a/src/commands/diffLineWithPrevious.ts b/src/commands/diffLineWithPrevious.ts index 61e5cf1..05c1da0 100644 --- a/src/commands/diffLineWithPrevious.ts +++ b/src/commands/diffLineWithPrevious.ts @@ -33,7 +33,7 @@ export class DiffLineWithPreviousCommand extends ActiveEditorCommand { const gitUri = args.commit != null ? GitUri.fromCommit(args.commit) : await GitUri.fromUri(uri); try { - const diffUris = await Container.git.getPreviousLineDiffUris( + const diffUris = await Container.instance.git.getPreviousLineDiffUris( gitUri.repoPath!, gitUri, args.line, diff --git a/src/commands/diffLineWithWorking.ts b/src/commands/diffLineWithWorking.ts index db825b4..d4814a8 100644 --- a/src/commands/diffLineWithWorking.ts +++ b/src/commands/diffLineWithWorking.ts @@ -38,8 +38,8 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand { try { const blame = editor?.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); + ? await Container.instance.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) + : await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) { void Messages.showFileNotUnderSourceControlWarningMessage('Unable to open compare'); @@ -50,7 +50,7 @@ export class DiffLineWithWorkingCommand extends ActiveEditorCommand { // If the line is uncommitted, change the previous commit if (args.commit.isUncommitted) { - const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath); + const status = await Container.instance.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath); args.commit = args.commit.with({ sha: status?.indexStatus != null ? GitRevision.uncommittedStaged : args.commit.previousSha!, fileName: args.commit.previousFileName!, diff --git a/src/commands/diffWith.ts b/src/commands/diffWith.ts index 174c67c..ac92781 100644 --- a/src/commands/diffWith.ts +++ b/src/commands/diffWith.ts @@ -88,8 +88,12 @@ export class DiffWithCommand extends Command { let rhsSha = args.rhs.sha; [args.lhs.sha, args.rhs.sha] = await Promise.all([ - await Container.git.resolveReference(args.repoPath, args.lhs.sha, args.lhs.uri, { timeout: 100 }), - await Container.git.resolveReference(args.repoPath, args.rhs.sha, args.rhs.uri, { timeout: 100 }), + await Container.instance.git.resolveReference(args.repoPath, args.lhs.sha, args.lhs.uri, { + timeout: 100, + }), + await Container.instance.git.resolveReference(args.repoPath, args.rhs.sha, args.rhs.uri, { + timeout: 100, + }), ]); if (args.lhs.sha !== GitRevision.deletedOrMissing) { @@ -98,7 +102,7 @@ export class DiffWithCommand extends Command { if (args.rhs.sha && args.rhs.sha !== GitRevision.deletedOrMissing) { // Ensure that the file still exists in this commit - const status = await Container.git.getFileStatusForCommit( + const status = await Container.instance.git.getFileStatusForCommit( args.repoPath, args.rhs.uri.fsPath, args.rhs.sha, @@ -115,8 +119,8 @@ export class DiffWithCommand extends Command { } const [lhs, rhs] = await Promise.all([ - Container.git.getVersionedUri(args.repoPath, args.lhs.uri.fsPath, args.lhs.sha), - Container.git.getVersionedUri(args.repoPath, args.rhs.uri.fsPath, args.rhs.sha), + Container.instance.git.getVersionedUri(args.repoPath, args.lhs.uri.fsPath, args.lhs.sha), + Container.instance.git.getVersionedUri(args.repoPath, args.rhs.uri.fsPath, args.rhs.sha), ]); let rhsSuffix = GitRevision.shorten(rhsSha, { strings: { uncommitted: 'Working Tree' } }); diff --git a/src/commands/diffWithNext.ts b/src/commands/diffWithNext.ts index b64c759..470cdb5 100644 --- a/src/commands/diffWithNext.ts +++ b/src/commands/diffWithNext.ts @@ -42,7 +42,7 @@ export class DiffWithNextCommand extends ActiveEditorCommand { const gitUri = args.commit != null ? GitUri.fromCommit(args.commit) : await GitUri.fromUri(uri); try { - const diffUris = await Container.git.getNextDiffUris( + const diffUris = await Container.instance.git.getNextDiffUris( gitUri.repoPath!, gitUri, gitUri.sha, diff --git a/src/commands/diffWithPrevious.ts b/src/commands/diffWithPrevious.ts index f301e83..818612b 100644 --- a/src/commands/diffWithPrevious.ts +++ b/src/commands/diffWithPrevious.ts @@ -83,7 +83,7 @@ export class DiffWithPreviousCommand extends ActiveEditorCommand { // } try { - const diffUris = await Container.git.getPreviousDiffUris( + const diffUris = await Container.instance.git.getPreviousDiffUris( gitUri.repoPath!, gitUri, gitUri.sha, diff --git a/src/commands/diffWithRevision.ts b/src/commands/diffWithRevision.ts index b7de79d..73dd01f 100644 --- a/src/commands/diffWithRevision.ts +++ b/src/commands/diffWithRevision.ts @@ -34,13 +34,13 @@ export class DiffWithRevisionCommand extends ActiveEditorCommand { } try { - const log = Container.git + const log = Container.instance.git .getLogForFile(gitUri.repoPath, gitUri.fsPath) .then( log => log ?? (gitUri.sha - ? Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha }) + ? Container.instance.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha }) : undefined), ); diff --git a/src/commands/diffWithRevisionFrom.ts b/src/commands/diffWithRevisionFrom.ts index 76eb552..8796cda 100644 --- a/src/commands/diffWithRevisionFrom.ts +++ b/src/commands/diffWithRevisionFrom.ts @@ -57,7 +57,7 @@ export class DiffWithRevisionFromCommand extends ActiveEditorCommand { let renamedTitle: string | undefined; // Check to see if this file has been renamed - const files = await Container.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filters: ['R', 'C'] }); + const files = await Container.instance.git.getDiffStatus(gitUri.repoPath, 'HEAD', ref, { filters: ['R', 'C'] }); if (files != null) { const fileName = Strings.normalizePath(paths.relative(gitUri.repoPath, gitUri.fsPath)); const rename = files.find(s => s.fileName === fileName); diff --git a/src/commands/diffWithWorking.ts b/src/commands/diffWithWorking.ts index d8e78c7..deb84e7 100644 --- a/src/commands/diffWithWorking.ts +++ b/src/commands/diffWithWorking.ts @@ -38,7 +38,12 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand { if (args.inDiffRightEditor) { try { - const diffUris = await Container.git.getPreviousDiffUris(gitUri.repoPath!, gitUri, gitUri.sha, 0); + const diffUris = await Container.instance.git.getPreviousDiffUris( + gitUri.repoPath!, + gitUri, + gitUri.sha, + 0, + ); gitUri = diffUris?.previous ?? gitUri; } catch (ex) { Logger.error( @@ -66,7 +71,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand { // If we are a fake "staged" sha, check the status if (gitUri.isUncommittedStaged) { - const status = await Container.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath); + const status = await Container.instance.git.getStatusForFile(gitUri.repoPath!, gitUri.fsPath); if (status?.indexStatus != null) { void (await executeCommand(Commands.DiffWith, { repoPath: gitUri.repoPath, @@ -88,7 +93,7 @@ export class DiffWithWorkingCommand extends ActiveEditorCommand { uri = gitUri.toFileUri(); - const workingUri = await Container.git.getWorkingUri(gitUri.repoPath!, uri); + const workingUri = await Container.instance.git.getWorkingUri(gitUri.repoPath!, uri); if (workingUri == null) { void window.showWarningMessage('Unable to open compare. File has been deleted from the working tree'); diff --git a/src/commands/externalDiff.ts b/src/commands/externalDiff.ts index 93e859a..c9dc911 100644 --- a/src/commands/externalDiff.ts +++ b/src/commands/externalDiff.ts @@ -122,7 +122,7 @@ export class ExternalDiffCommand extends Command { const repoPath = await getRepoPathOrPrompt('Open All Changes (difftool)'); if (!repoPath) return undefined; - const status = await Container.git.getStatusForRepo(repoPath); + const status = await Container.instance.git.getStatusForRepo(repoPath); if (status == null) { return window.showInformationMessage("The repository doesn't have any changes"); } @@ -158,11 +158,11 @@ export class ExternalDiffCommand extends Command { const editor = window.activeTextEditor; if (editor == null) return; - repoPath = await Container.git.getRepoPathOrActive(undefined, editor); + repoPath = await Container.instance.git.getRepoPathOrActive(undefined, editor); if (!repoPath) return; const uri = editor.document.uri; - const status = await Container.git.getStatusForFile(repoPath, uri.fsPath); + const status = await Container.instance.git.getStatusForFile(repoPath, uri.fsPath); if (status == null) { void window.showInformationMessage("The current file doesn't have any changes"); @@ -178,11 +178,13 @@ export class ExternalDiffCommand extends Command { args.files.push({ uri: status.uri, staged: false }); } } else { - repoPath = await Container.git.getRepoPath(args.files[0].uri.fsPath); + repoPath = await Container.instance.git.getRepoPath(args.files[0].uri.fsPath); if (!repoPath) return; } - const tool = Container.config.advanced.externalDiffTool || (await Container.git.getDiffTool(repoPath)); + const tool = + Container.instance.config.advanced.externalDiffTool || + (await Container.instance.git.getDiffTool(repoPath)); if (!tool) { const viewDocs = 'View Git Docs'; const result = await window.showWarningMessage( @@ -199,7 +201,7 @@ export class ExternalDiffCommand extends Command { } for (const file of args.files) { - void Container.git.openDiffTool(repoPath, file.uri, { + void Container.instance.git.openDiffTool(repoPath, file.uri, { ref1: file.ref1, ref2: file.ref2, staged: file.staged, diff --git a/src/commands/git/branch.ts b/src/commands/git/branch.ts index 81f39c1..a720ff6 100644 --- a/src/commands/git/branch.ts +++ b/src/commands/git/branch.ts @@ -148,7 +148,7 @@ export class BranchGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], showTags: false, title: this.title, }; diff --git a/src/commands/git/cherry-pick.ts b/src/commands/git/cherry-pick.ts index b2ff9be..54dfc23 100644 --- a/src/commands/git/cherry-pick.ts +++ b/src/commands/git/cherry-pick.ts @@ -80,7 +80,7 @@ export class CherryPickGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], cache: new Map>(), destination: undefined!, selectedBranchOrTag: undefined, @@ -162,7 +162,7 @@ export class CherryPickGitCommand extends QuickCommand { let log = context.cache.get(ref); if (log == null) { - log = Container.git.getLog(state.repo.path, { ref: ref, merges: false }); + log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false }); context.cache.set(ref, log); } diff --git a/src/commands/git/coauthors.ts b/src/commands/git/coauthors.ts index 1cacb3e..793fa75 100644 --- a/src/commands/git/coauthors.ts +++ b/src/commands/git/coauthors.ts @@ -93,7 +93,7 @@ export class CoAuthorsGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], activeRepo: undefined, title: this.title, }; @@ -106,7 +106,7 @@ export class CoAuthorsGitCommand extends QuickCommand { ); // Ensure that the active repo is known to the built-in git - context.activeRepo = await Container.git.getActiveRepository(); + context.activeRepo = await Container.instance.git.getActiveRepository(); if ( context.activeRepo != null && !gitApi.repositories.some(r => r.rootUri.fsPath === context.activeRepo!.path) diff --git a/src/commands/git/fetch.ts b/src/commands/git/fetch.ts index 9a4fb93..29a7c50 100644 --- a/src/commands/git/fetch.ts +++ b/src/commands/git/fetch.ts @@ -59,7 +59,7 @@ export class FetchGitCommand extends QuickCommand { return state.repos[0].fetch({ branch: state.reference }); } - return Container.git.fetchAll(state.repos, { + return Container.instance.git.fetchAll(state.repos, { all: state.flags.includes('--all'), prune: state.flags.includes('--prune'), }); @@ -67,7 +67,7 @@ export class FetchGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], title: this.title, }; diff --git a/src/commands/git/log.ts b/src/commands/git/log.ts index 73775be..289795b 100644 --- a/src/commands/git/log.ts +++ b/src/commands/git/log.ts @@ -76,7 +76,7 @@ export class LogGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], cache: new Map>(), selectedBranchOrTag: undefined, title: this.title, @@ -152,8 +152,8 @@ export class LogGitCommand extends QuickCommand { if (log == null) { log = state.fileName != null - ? Container.git.getLogForFile(state.repo.path, state.fileName, { ref: ref }) - : Container.git.getLog(state.repo.path, { ref: ref }); + ? Container.instance.git.getLogForFile(state.repo.path, state.fileName, { ref: ref }) + : Container.instance.git.getLog(state.repo.path, { ref: ref }); context.cache.set(ref, log); } @@ -175,7 +175,7 @@ export class LogGitCommand extends QuickCommand { } if (!(state.reference instanceof GitLogCommit) || state.reference.isFile) { - state.reference = await Container.git.getCommit(state.repo.path, state.reference.ref); + state.reference = await Container.instance.git.getCommit(state.repo.path, state.reference.ref); } const result = yield* GitCommandsCommand.getSteps( diff --git a/src/commands/git/merge.ts b/src/commands/git/merge.ts index 22d31f8..a8bd120 100644 --- a/src/commands/git/merge.ts +++ b/src/commands/git/merge.ts @@ -76,7 +76,7 @@ export class MergeGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], cache: new Map>(), destination: undefined!, pickCommit: false, @@ -159,7 +159,7 @@ export class MergeGitCommand extends QuickCommand { let log = context.cache.get(ref); if (log == null) { - log = Container.git.getLog(state.repo.path, { ref: ref, merges: false }); + log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false }); context.cache.set(ref, log); } @@ -195,7 +195,7 @@ export class MergeGitCommand extends QuickCommand { } private async *confirmStep(state: MergeStepState, context: Context): AsyncStepResultGenerator { - const aheadBehind = await Container.git.getAheadBehindCommitCount(state.repo.path, [ + const aheadBehind = await Container.instance.git.getAheadBehindCommitCount(state.repo.path, [ GitRevision.createRange(context.destination.name, state.reference.name), ]); const count = aheadBehind != null ? aheadBehind.ahead + aheadBehind.behind : 0; diff --git a/src/commands/git/pull.ts b/src/commands/git/pull.ts index 3d03884..19c3e16 100644 --- a/src/commands/git/pull.ts +++ b/src/commands/git/pull.ts @@ -68,12 +68,12 @@ export class PullGitCommand extends QuickCommand { } } - return Container.git.pullAll(state.repos, { rebase: state.flags.includes('--rebase') }); + return Container.instance.git.pullAll(state.repos, { rebase: state.flags.includes('--rebase') }); } protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], title: this.title, }; diff --git a/src/commands/git/push.ts b/src/commands/git/push.ts index 814b45a..ef39539 100644 --- a/src/commands/git/push.ts +++ b/src/commands/git/push.ts @@ -64,14 +64,14 @@ export class PushGitCommand extends QuickCommand { if (index !== -1) { if (!GitReference.isBranch(state.reference)) return Promise.resolve(); - return Container.git.pushAll(state.repos, { + return Container.instance.git.pushAll(state.repos, { force: false, publish: { remote: state.flags[index + 1] }, reference: state.reference, }); } - return Container.git.pushAll(state.repos, { + return Container.instance.git.pushAll(state.repos, { force: state.flags.includes('--force'), reference: state.reference, }); @@ -79,7 +79,7 @@ export class PushGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], title: this.title, }; diff --git a/src/commands/git/rebase.ts b/src/commands/git/rebase.ts index 1153c51..a6d6156 100644 --- a/src/commands/git/rebase.ts +++ b/src/commands/git/rebase.ts @@ -75,7 +75,7 @@ export class RebaseGitCommand extends QuickCommand { async execute(state: RebaseStepState) { let configs: string[] | undefined; if (state.flags.includes('--interactive')) { - await Container.rebaseEditor.enableForNextUse(); + await Container.instance.rebaseEditor.enableForNextUse(); let editor; switch (env.appName) { @@ -97,7 +97,7 @@ export class RebaseGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], cache: new Map>(), destination: undefined!, pickCommit: false, @@ -180,7 +180,7 @@ export class RebaseGitCommand extends QuickCommand { let log = context.cache.get(ref); if (log == null) { - log = Container.git.getLog(state.repo.path, { ref: ref, merges: false }); + log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false }); context.cache.set(ref, log); } @@ -216,7 +216,7 @@ export class RebaseGitCommand extends QuickCommand { } private async *confirmStep(state: RebaseStepState, context: Context): AsyncStepResultGenerator { - const aheadBehind = await Container.git.getAheadBehindCommitCount(state.repo.path, [ + const aheadBehind = await Container.instance.git.getAheadBehindCommitCount(state.repo.path, [ state.reference.refType === 'revision' ? GitRevision.createRange(state.reference.ref, context.destination.ref) : GitRevision.createRange(context.destination.name, state.reference.name), diff --git a/src/commands/git/reset.ts b/src/commands/git/reset.ts index a2e50cc..58a42f4 100644 --- a/src/commands/git/reset.ts +++ b/src/commands/git/reset.ts @@ -71,7 +71,7 @@ export class ResetGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], cache: new Map>(), destination: undefined!, title: this.title, @@ -118,7 +118,7 @@ export class ResetGitCommand extends QuickCommand { let log = context.cache.get(ref); if (log == null) { - log = Container.git.getLog(state.repo.path, { ref: ref, merges: false }); + log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false }); context.cache.set(ref, log); } diff --git a/src/commands/git/revert.ts b/src/commands/git/revert.ts index e458fda..e069c64 100644 --- a/src/commands/git/revert.ts +++ b/src/commands/git/revert.ts @@ -73,7 +73,7 @@ export class RevertGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], cache: new Map>(), destination: undefined!, title: this.title, @@ -122,7 +122,7 @@ export class RevertGitCommand extends QuickCommand { let log = context.cache.get(ref); if (log == null) { - log = Container.git.getLog(state.repo.path, { ref: ref, merges: false }); + log = Container.instance.git.getLog(state.repo.path, { ref: ref, merges: false }); context.cache.set(ref, log); } diff --git a/src/commands/git/search.ts b/src/commands/git/search.ts index 08110a7..9419f46 100644 --- a/src/commands/git/search.ts +++ b/src/commands/git/search.ts @@ -91,14 +91,14 @@ export class SearchGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], commit: undefined, resultsKey: undefined, resultsPromise: undefined, title: this.title, }; - const cfg = Container.config.gitCommands.search; + const cfg = Container.instance.config.gitCommands.search; if (state.matchAll == null) { state.matchAll = cfg.matchAll; } @@ -166,7 +166,7 @@ export class SearchGitCommand extends QuickCommand { // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (state.showResultsInSideBar) { - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( state.repo.path, search, { @@ -195,7 +195,7 @@ export class SearchGitCommand extends QuickCommand { showInSideBarCommand: new ActionQuickPickItem( '$(link-external) Show Results in Side Bar', () => - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( repoPath, search, { @@ -212,7 +212,7 @@ export class SearchGitCommand extends QuickCommand { showInSideBarButton: { button: QuickCommandButtons.ShowResultsInSideBar, onDidClick: () => - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( repoPath, search, { diff --git a/src/commands/git/show.ts b/src/commands/git/show.ts index 31c869a..39f3101 100644 --- a/src/commands/git/show.ts +++ b/src/commands/git/show.ts @@ -76,7 +76,7 @@ export class ShowGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], title: this.title, }; @@ -110,7 +110,10 @@ export class ShowGitCommand extends QuickCommand { state.reference.isFile ) { if (state.reference != null && (!GitLogCommit.is(state.reference) || state.reference.isFile)) { - state.reference = await Container.git.getCommit(state.reference.repoPath, state.reference.ref); + state.reference = await Container.instance.git.getCommit( + state.reference.repoPath, + state.reference.ref, + ); } if (state.counter < 2 || state.reference == null) { diff --git a/src/commands/git/stash.ts b/src/commands/git/stash.ts index c373bbb..6b4948c 100644 --- a/src/commands/git/stash.ts +++ b/src/commands/git/stash.ts @@ -144,7 +144,7 @@ export class StashGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], title: this.title, }; @@ -258,7 +258,7 @@ export class StashGitCommand extends QuickCommand { while (this.canStepsContinue(state)) { if (state.counter < 3 || state.reference == null) { const result: StepResult = yield* pickStashStep(state, context, { - stash: await Container.git.getStash(state.repo.path), + stash: await Container.instance.git.getStash(state.repo.path), placeholder: (context, stash) => stash == null ? `No stashes found in ${state.repo.formattedName}` @@ -374,7 +374,7 @@ export class StashGitCommand extends QuickCommand { while (this.canStepsContinue(state)) { if (state.counter < 3 || state.reference == null) { const result: StepResult = yield* pickStashStep(state, context, { - stash: await Container.git.getStash(state.repo.path), + stash: await Container.instance.git.getStash(state.repo.path), placeholder: (context, stash) => stash == null ? `No stashes found in ${state.repo.formattedName}` : 'Choose a stash to delete', picked: state.reference?.ref, @@ -435,7 +435,7 @@ export class StashGitCommand extends QuickCommand { while (this.canStepsContinue(state)) { if (state.counter < 3 || state.reference == null) { const result: StepResult = yield* pickStashStep(state, context, { - stash: await Container.git.getStash(state.repo.path), + stash: await Container.instance.git.getStash(state.repo.path), placeholder: (context, stash) => stash == null ? `No stashes found in ${state.repo.formattedName}` : 'Choose a stash', picked: state.reference?.ref, @@ -447,7 +447,7 @@ export class StashGitCommand extends QuickCommand { } // if (!(state.reference instanceof GitStashCommit)) { - // state.reference = await Container.git.getCommit(state.repo.path, state.reference.ref); + // state.reference = await Container.instance.git.getCommit(state.repo.path, state.reference.ref); // } const result = yield* GitCommandsCommand.getSteps( diff --git a/src/commands/git/status.ts b/src/commands/git/status.ts index bd1bb37..e2c195a 100644 --- a/src/commands/git/status.ts +++ b/src/commands/git/status.ts @@ -55,7 +55,7 @@ export class StatusGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], status: undefined!, title: this.title, }; diff --git a/src/commands/git/switch.ts b/src/commands/git/switch.ts index 418bacb..9c0c01b 100644 --- a/src/commands/git/switch.ts +++ b/src/commands/git/switch.ts @@ -88,7 +88,7 @@ export class SwitchGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], showTags: false, title: this.title, }; @@ -146,7 +146,7 @@ export class SwitchGitCommand extends QuickCommand { if (GitReference.isBranch(state.reference) && state.reference.remote) { context.title = `Create Branch and ${this.title}`; - const branches = await Container.git.getBranches(state.reference.repoPath, { + const branches = await Container.instance.git.getBranches(state.reference.repoPath, { filter: b => b.upstream?.name === state.reference!.name, sort: { orderBy: BranchSorting.DateDesc }, }); diff --git a/src/commands/git/tag.ts b/src/commands/git/tag.ts index eea55c5..7b7a26e 100644 --- a/src/commands/git/tag.ts +++ b/src/commands/git/tag.ts @@ -127,7 +127,7 @@ export class TagGitCommand extends QuickCommand { protected async *steps(state: PartialStepState): StepGenerator { const context: Context = { - repos: [...(await Container.git.getOrderedRepositories())], + repos: [...(await Container.instance.git.getOrderedRepositories())], showTags: false, title: this.title, }; diff --git a/src/commands/gitCommands.actions.ts b/src/commands/gitCommands.actions.ts index d1a9ff3..47b04aa 100644 --- a/src/commands/gitCommands.actions.ts +++ b/src/commands/gitCommands.actions.ts @@ -35,7 +35,7 @@ export async function executeGitCommand(args: GitCommandsCommandArgs): Promise { - return typeof repo === 'string' ? (await Container.git.getRepository(repo))! : repo; + return typeof repo === 'string' ? (await Container.instance.git.getRepository(repo))! : repo; } export namespace GitActions { @@ -152,17 +152,17 @@ export namespace GitActions { ) { if ( !configuration.get(`views.${branch.remote ? 'remotes' : 'branches'}.reveal` as const) || - (Container.repositoriesView.visible && - !(branch.remote ? Container.remotesView.visible : Container.branchesView.visible)) + (Container.instance.repositoriesView.visible && + !(branch.remote ? Container.instance.remotesView.visible : Container.instance.branchesView.visible)) ) { - return Container.repositoriesView.revealBranch(branch, options); + return Container.instance.repositoriesView.revealBranch(branch, options); } let node; if (branch.remote) { - node = await Container.remotesView.revealBranch(branch, options); + node = await Container.instance.remotesView.revealBranch(branch, options); } else { - node = await Container.branchesView.revealBranch(branch, options); + node = await Container.instance.branchesView.revealBranch(branch, options); } return node; @@ -177,7 +177,7 @@ export namespace GitActions { ) { // Open the working file to ensure undo will work void (await GitActions.Commit.openFile(file, ref1, { preserveFocus: true, preview: false })); - void (await Container.git.applyChangesToWorkingFile( + void (await Container.instance.git.applyChangesToWorkingFile( GitUri.fromFile(file, ref1.repoPath, ref1.ref), ref1.ref, ref2?.ref, @@ -193,7 +193,7 @@ export namespace GitActions { if (GitLogCommit.is(ref)) { message = ref.message; } else { - const commit = await Container.git.getCommit(ref.repoPath, ref.ref); + const commit = await Container.instance.git.getCommit(ref.repoPath, ref.ref); if (commit == null) return; message = commit.message; @@ -399,7 +399,7 @@ export namespace GitActions { file = f; } - return Container.git.openDiffTool( + return Container.instance.git.openDiffTool( commitOrRef.repoPath, GitUri.fromFile(file, file.repoPath ?? commitOrRef.repoPath), { @@ -461,7 +461,7 @@ export namespace GitActions { ref2: string | undefined, tool?: string, ): Promise { - return Container.git.openDirectoryCompare(repoPath, ref, ref2, tool); + return Container.instance.git.openDirectoryCompare(repoPath, ref, ref2, tool); } export async function openDirectoryCompareWithPrevious( @@ -558,7 +558,9 @@ export namespace GitActions { const editor = await findOrOpenEditor(uri, opts); if (annotationType != null && editor != null) { - void (await Container.fileAnnotations.show(editor, annotationType, { selection: { line: line } })); + void (await Container.instance.fileAnnotations.show(editor, annotationType, { + selection: { line: line }, + })); } } @@ -589,7 +591,9 @@ export namespace GitActions { const uris: Uri[] = ( await Promise.all( - files.map(file => Container.git.getWorkingUri(repoPath!, GitUri.fromFile(file, repoPath!, ref))), + files.map(file => + Container.instance.git.getWorkingUri(repoPath!, GitUri.fromFile(file, repoPath!, ref)), + ), ) ).filter((u?: T): u is T => Boolean(u)); findOrOpenEditors(uris); @@ -633,7 +637,7 @@ export namespace GitActions { } export async function restoreFile(file: string | GitFile, ref: GitRevisionReference) { - void (await Container.git.checkout(ref.repoPath, ref.ref, { + void (await Container.instance.git.checkout(ref.repoPath, ref.ref, { fileName: typeof file === 'string' ? file : file.fileName, })); } @@ -648,20 +652,20 @@ export namespace GitActions { ) { if ( !configuration.get('views.commits.reveal') || - (Container.repositoriesView.visible && !Container.commitsView.visible) + (Container.instance.repositoriesView.visible && !Container.instance.commitsView.visible) ) { - return Container.repositoriesView.revealCommit(commit, options); + return Container.instance.repositoriesView.revealCommit(commit, options); } // TODO@eamodio stop duplicate notifications - let node = await Container.commitsView.revealCommit(commit, options); + let node = await Container.instance.commitsView.revealCommit(commit, options); if (node != null) return node; - node = await Container.branchesView.revealCommit(commit, options); + node = await Container.instance.branchesView.revealCommit(commit, options); if (node != null) return node; - node = await Container.remotesView.revealCommit(commit, options); + node = await Container.instance.remotesView.revealCommit(commit, options); if (node != null) return node; return undefined; @@ -711,12 +715,12 @@ export namespace GitActions { ) { if ( !configuration.get('views.tags.reveal') || - (Container.repositoriesView.visible && !Container.tagsView.visible) + (Container.instance.repositoriesView.visible && !Container.instance.tagsView.visible) ) { - return Container.repositoriesView.revealTag(tag, options); + return Container.instance.repositoriesView.revealTag(tag, options); } - const node = await Container.tagsView.revealTag(tag, options); + const node = await Container.instance.tagsView.revealTag(tag, options); return node; } } @@ -724,7 +728,7 @@ export namespace GitActions { export namespace Remote { export async function add(repo?: string | Repository) { if (repo == null) { - repo = Container.git.getHighlanderRepoPath(); + repo = Container.instance.git.getHighlanderRepoPath(); if (repo == null) { const pick = await RepositoryPicker.show(undefined, 'Choose a repository to add a remote to'); @@ -750,7 +754,7 @@ export namespace GitActions { if (url == null || url.length === 0) return undefined; repo = await ensureRepo(repo); - void (await Container.git.addRemote(repo.path, name, url)); + void (await Container.instance.git.addRemote(repo.path, name, url)); void (await repo.fetch({ remote: name })); return name; @@ -758,7 +762,7 @@ export namespace GitActions { export async function fetch(repo: string | Repository, remote: string) { if (typeof repo === 'string') { - const r = await Container.git.getRepository(repo); + const r = await Container.instance.git.getRepository(repo); if (r == null) return; repo = r; @@ -768,7 +772,7 @@ export namespace GitActions { } export async function prune(repo: string | Repository, remote: string) { - void (await Container.git.pruneRemote(typeof repo === 'string' ? repo : repo.path, remote)); + void (await Container.instance.git.pruneRemote(typeof repo === 'string' ? repo : repo.path, remote)); } export async function reveal( @@ -781,12 +785,12 @@ export namespace GitActions { ) { // if ( // configuration.get('views.repositories.enabled') && - // (Container.repositoriesView.visible || !Container.remotesView.visible) + // (Container.instance.repositoriesView.visible || !Container.instance.remotesView.visible) // ) { - // return Container.repositoriesView.revealRemote(remote, options); + // return Container.instance.repositoriesView.revealRemote(remote, options); // } - const node = await Container.remotesView.revealRemote(remote, options); + const node = await Container.instance.remotesView.revealRemote(remote, options); return node; } } @@ -836,12 +840,12 @@ export namespace GitActions { ) { if ( !configuration.get('views.stashes.reveal') || - (Container.repositoriesView.visible && !Container.stashesView.visible) + (Container.instance.repositoriesView.visible && !Container.instance.stashesView.visible) ) { - return Container.repositoriesView.revealStash(stash, options); + return Container.instance.repositoriesView.revealStash(stash, options); } - const node = await Container.stashesView.revealStash(stash, options); + const node = await Container.instance.stashesView.revealStash(stash, options); return node; } } diff --git a/src/commands/gitCommands.ts b/src/commands/gitCommands.ts index 4ee8c62..8529d91 100644 --- a/src/commands/gitCommands.ts +++ b/src/commands/gitCommands.ts @@ -310,7 +310,7 @@ export class GitCommandsCommand extends Command { } } - const scope = Container.keyboard.createScope(mapping); + const scope = Container.instance.keyboard.createScope(mapping); void scope.start(); disposables.push( @@ -460,7 +460,7 @@ export class GitCommandsCommand extends Command { } } - const scope = Container.keyboard.createScope(mapping); + const scope = Container.instance.keyboard.createScope(mapping); void scope.start(); let overrideItems = false; @@ -767,8 +767,8 @@ class PickCommandStep implements QuickPickStep { new TagGitCommand(args?.command === 'tag' ? args : undefined), ]; - if (Container.config.gitCommands.sortBy === GitCommandSorting.Usage) { - const usage = Container.context.workspaceState.get(WorkspaceState.GitCommandPaletteUsage); + if (Container.instance.config.gitCommands.sortBy === GitCommandSorting.Usage) { + const usage = Container.instance.context.workspaceState.get(WorkspaceState.GitCommandPaletteUsage); if (usage != null) { this.items.sort((a, b) => (usage[b.key] ?? 0) - (usage[a.key] ?? 0)); } @@ -808,12 +808,12 @@ class PickCommandStep implements QuickPickStep { } private async updateCommandUsage(id: string, timestamp: number) { - let usage = Container.context.workspaceState.get(WorkspaceState.GitCommandPaletteUsage); + let usage = Container.instance.context.workspaceState.get(WorkspaceState.GitCommandPaletteUsage); if (usage === undefined) { usage = Object.create(null) as Usage; } usage[id] = timestamp; - await Container.context.workspaceState.update(WorkspaceState.GitCommandPaletteUsage, usage); + await Container.instance.context.workspaceState.update(WorkspaceState.GitCommandPaletteUsage, usage); } } diff --git a/src/commands/inviteToLiveShare.ts b/src/commands/inviteToLiveShare.ts index ee388ca..0fd8519 100644 --- a/src/commands/inviteToLiveShare.ts +++ b/src/commands/inviteToLiveShare.ts @@ -32,12 +32,12 @@ export class InviteToLiveShareCommand extends Command { async execute(args?: InviteToLiveShareCommandArgs) { if (args?.email) { - const contact = await Container.vsls.getContact(args.email); + const contact = await Container.instance.vsls.getContact(args.email); if (contact != null) { return contact.invite(); } } - return Container.vsls.startSession(); + return Container.instance.vsls.startSession(); } } diff --git a/src/commands/openAssociatedPullRequestOnRemote.ts b/src/commands/openAssociatedPullRequestOnRemote.ts index 5693412..1218a91 100644 --- a/src/commands/openAssociatedPullRequestOnRemote.ts +++ b/src/commands/openAssociatedPullRequestOnRemote.ts @@ -24,7 +24,7 @@ export class OpenAssociatedPullRequestOnRemoteCommand extends ActiveEditorComman if (blameline < 0) return; try { - const blame = await Container.git.getBlameForLine(gitUri, blameline); + const blame = await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) return; await executeCommand(Commands.OpenPullRequestOnRemote, { diff --git a/src/commands/openChangedFiles.ts b/src/commands/openChangedFiles.ts index dd51e74..ea26531 100644 --- a/src/commands/openChangedFiles.ts +++ b/src/commands/openChangedFiles.ts @@ -24,7 +24,7 @@ export class OpenChangedFilesCommand extends Command { const repoPath = await getRepoPathOrPrompt('Open All Changed Files'); if (!repoPath) return; - const status = await Container.git.getStatusForRepo(repoPath); + const status = await Container.instance.git.getStatusForRepo(repoPath); if (status == null) { void window.showWarningMessage('Unable to open changed files'); diff --git a/src/commands/openCommitOnRemote.ts b/src/commands/openCommitOnRemote.ts index 24e08a6..8b85ed9 100644 --- a/src/commands/openCommitOnRemote.ts +++ b/src/commands/openCommitOnRemote.ts @@ -72,8 +72,8 @@ export class OpenCommitOnRemoteCommand extends ActiveEditorCommand { if (blameline < 0) return; const blame = editor?.document.isDirty - ? await Container.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) - : await Container.git.getBlameForLine(gitUri, blameline); + ? await Container.instance.git.getBlameForLineContents(gitUri, blameline, editor.document.getText()) + : await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) { void Messages.showFileNotUnderSourceControlWarningMessage( 'Unable to open commit on remote provider', diff --git a/src/commands/openFileAtRevision.ts b/src/commands/openFileAtRevision.ts index 1210dfa..4d4b0e9 100644 --- a/src/commands/openFileAtRevision.ts +++ b/src/commands/openFileAtRevision.ts @@ -57,7 +57,7 @@ export class OpenFileAtRevisionCommand extends ActiveEditorCommand { if (blameline >= 0) { try { const gitUri = await GitUri.fromUri(context.editor.document.uri); - const blame = await Container.git.getBlameForLine(gitUri, blameline); + const blame = await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame != null && !blame.commit.isUncommitted && blame.commit.previousSha != null) { args.revisionUri = GitUri.toRevisionUri(GitUri.fromCommit(blame.commit, true)); } @@ -82,13 +82,15 @@ export class OpenFileAtRevisionCommand extends ActiveEditorCommand { try { if (args.revisionUri == null) { - const log = Container.git + const log = Container.instance.git .getLogForFile(gitUri.repoPath, gitUri.fsPath) .then( log => log ?? (gitUri.sha - ? Container.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { ref: gitUri.sha }) + ? Container.instance.git.getLogForFile(gitUri.repoPath, gitUri.fsPath, { + ref: gitUri.sha, + }) : undefined), ); diff --git a/src/commands/openFileFromRemote.ts b/src/commands/openFileFromRemote.ts index 49b9f05..1644e93 100644 --- a/src/commands/openFileFromRemote.ts +++ b/src/commands/openFileFromRemote.ts @@ -25,9 +25,9 @@ export class OpenFileFromRemoteCommand extends Command { }); if (url == null || url.length === 0) return; - let local = await Container.git.getLocalInfoFromRemoteUri(Uri.parse(url)); + let local = await Container.instance.git.getLocalInfoFromRemoteUri(Uri.parse(url)); if (local == null) { - local = await Container.git.getLocalInfoFromRemoteUri(Uri.parse(url), { validate: false }); + local = await Container.instance.git.getLocalInfoFromRemoteUri(Uri.parse(url), { validate: false }); if (local == null) { void window.showWarningMessage('Unable to parse the provided remote url.'); diff --git a/src/commands/openFileOnRemote.ts b/src/commands/openFileOnRemote.ts index 8ef8bfd..b15b8d6 100644 --- a/src/commands/openFileOnRemote.ts +++ b/src/commands/openFileOnRemote.ts @@ -83,9 +83,13 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand { const gitUri = await GitUri.fromUri(uri); if (gitUri.repoPath) { if (gitUri.sha == null) { - const commit = await Container.git.getCommitForFile(gitUri.repoPath, gitUri.fsPath, { - firstIfNotFound: true, - }); + const commit = await Container.instance.git.getCommitForFile( + gitUri.repoPath, + gitUri.fsPath, + { + firstIfNotFound: true, + }, + ); if (commit != null) { args.sha = commit.sha; @@ -115,7 +119,7 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand { args = { range: true, ...args }; try { - let remotes = await Container.git.getRemotes(gitUri.repoPath); + let remotes = await Container.instance.git.getRemotes(gitUri.repoPath); const range = args.range && editor != null && UriComparer.equals(editor.document.uri, uri) ? new Range( @@ -143,7 +147,7 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand { if ((args.sha == null && args.branchOrTag == null) || args.pickBranchOrTag) { let branch; if (!args.pickBranchOrTag) { - branch = await Container.git.getBranch(gitUri.repoPath); + branch = await Container.instance.git.getBranch(gitUri.repoPath); } if (branch?.upstream == null) { diff --git a/src/commands/openOnRemote.ts b/src/commands/openOnRemote.ts index 5a09a17..28c33e4 100644 --- a/src/commands/openOnRemote.ts +++ b/src/commands/openOnRemote.ts @@ -33,7 +33,7 @@ export class OpenOnRemoteCommand extends Command { async execute(args?: OpenOnRemoteCommandArgs) { if (args?.resource == null) return; - let remotes = 'remotes' in args ? args.remotes : await Container.git.getRemotes(args.repoPath); + let remotes = 'remotes' in args ? args.remotes : await Container.instance.git.getRemotes(args.repoPath); if (args.remote != null) { const filtered = remotes.filter(r => r.name === args.remote); @@ -60,7 +60,7 @@ export class OpenOnRemoteCommand extends Command { const file = commit?.files.find(f => f.fileName === fileName); if (file?.status === 'D') { // Resolve to the previous commit to that file - args.resource.sha = await Container.git.resolveReference( + args.resource.sha = await Container.instance.git.resolveReference( commit.repoPath, `${commit.sha}^`, fileName, diff --git a/src/commands/openPullRequestOnRemote.ts b/src/commands/openPullRequestOnRemote.ts index a42dbdd..87b0858 100644 --- a/src/commands/openPullRequestOnRemote.ts +++ b/src/commands/openPullRequestOnRemote.ts @@ -33,10 +33,10 @@ export class OpenPullRequestOnRemoteCommand extends Command { if (args?.pr == null) { if (args?.repoPath == null || args?.ref == null) return; - const remote = await Container.git.getRichRemoteProvider(args.repoPath); + const remote = await Container.instance.git.getRichRemoteProvider(args.repoPath); if (remote?.provider == null) return; - const pr = await Container.git.getPullRequestForCommit(args.ref, remote.provider); + const pr = await Container.instance.git.getPullRequestForCommit(args.ref, remote.provider); if (pr == null) return; args = { ...args }; diff --git a/src/commands/openRevisionFile.ts b/src/commands/openRevisionFile.ts index d6ef84e..5efb160 100644 --- a/src/commands/openRevisionFile.ts +++ b/src/commands/openRevisionFile.ts @@ -36,7 +36,7 @@ export class OpenRevisionFileCommand extends ActiveEditorCommand { try { if (args.revisionUri == null) { if (gitUri?.sha) { - const commit = await Container.git.getCommit(gitUri.repoPath!, gitUri.sha); + const commit = await Container.instance.git.getCommit(gitUri.repoPath!, gitUri.sha); args.revisionUri = commit != null && commit.status === 'D' diff --git a/src/commands/openWorkingFile.ts b/src/commands/openWorkingFile.ts index fe0f415..0c1576a 100644 --- a/src/commands/openWorkingFile.ts +++ b/src/commands/openWorkingFile.ts @@ -36,7 +36,7 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand { args.uri = await GitUri.fromUri(uri); if (GitUri.is(args.uri) && args.uri.sha) { - const workingUri = await Container.git.getWorkingUri(args.uri.repoPath!, args.uri); + const workingUri = await Container.instance.git.getWorkingUri(args.uri.repoPath!, args.uri); if (workingUri === undefined) { void window.showWarningMessage( 'Unable to open working file. File could not be found in the working tree', @@ -58,7 +58,9 @@ export class OpenWorkingFileCommand extends ActiveEditorCommand { const e = await findOrOpenEditor(args.uri, { ...args.showOptions, throwOnError: true }); if (args.annotationType === undefined) return; - void (await Container.fileAnnotations.show(e, args.annotationType, { selection: { line: args.line } })); + void (await Container.instance.fileAnnotations.show(e, args.annotationType, { + selection: { line: args.line }, + })); } catch (ex) { Logger.error(ex, 'OpenWorkingFileCommand'); void Messages.showGenericErrorMessage('Unable to open working file'); diff --git a/src/commands/quickCommand.buttons.ts b/src/commands/quickCommand.buttons.ts index 36abb06..a5e6fa2 100644 --- a/src/commands/quickCommand.buttons.ts +++ b/src/commands/quickCommand.buttons.ts @@ -20,8 +20,8 @@ export class ToggleQuickInputButton implements QuickInputButton { const icon = this.getToggledState().icon; return typeof icon === 'string' ? { - dark: Uri.file(Container.context.asAbsolutePath(`images/dark/${icon}.svg`)), - light: Uri.file(Container.context.asAbsolutePath(`images/light/${icon}.svg`)), + dark: Uri.file(Container.instance.context.asAbsolutePath(`images/dark/${icon}.svg`)), + light: Uri.file(Container.instance.context.asAbsolutePath(`images/light/${icon}.svg`)), } : icon; } @@ -133,15 +133,17 @@ export namespace QuickCommandButtons { on: { tooltip: 'Will confirm', icon: { - dark: Uri.file(Container.context.asAbsolutePath('images/dark/icon-check.svg')), - light: Uri.file(Container.context.asAbsolutePath('images/light/icon-check.svg')), + dark: Uri.file(Container.instance.context.asAbsolutePath('images/dark/icon-check.svg')), + light: Uri.file(Container.instance.context.asAbsolutePath('images/light/icon-check.svg')), }, }, off: { tooltip: 'Skips confirm', icon: { - dark: Uri.file(Container.context.asAbsolutePath('images/dark/icon-no-check.svg')), - light: Uri.file(Container.context.asAbsolutePath('images/light/icon-no-check.svg')), + dark: Uri.file(Container.instance.context.asAbsolutePath('images/dark/icon-no-check.svg')), + light: Uri.file( + Container.instance.context.asAbsolutePath('images/light/icon-no-check.svg'), + ), }, }, }), diff --git a/src/commands/quickCommand.steps.ts b/src/commands/quickCommand.steps.ts index f092a6d..61a4471 100644 --- a/src/commands/quickCommand.steps.ts +++ b/src/commands/quickCommand.steps.ts @@ -315,7 +315,7 @@ export function getValidateGitReferenceFn( return true; } - if (!(await Container.git.validateReference(repos.path, value))) { + if (!(await Container.instance.git.validateReference(repos.path, value))) { if (inRefMode) { quickpick.items = [ DirectiveQuickPickItem.create(Directive.Back, true, { @@ -330,7 +330,7 @@ export function getValidateGitReferenceFn( if (!inRefMode) { if ( - await Container.git.hasBranchesAndOrTags(repos.path, { + await Container.instance.git.hasBranchesAndOrTags(repos.path, { filter: { branches: b => b.name.includes(value), tags: t => t.name.includes(value) }, }) ) { @@ -338,7 +338,7 @@ export function getValidateGitReferenceFn( } } - const commit = await Container.git.getCommit(repos.path, value); + const commit = await Container.instance.git.getCommit(repos.path, value); quickpick.items = [ CommitQuickPickItem.create(commit!, true, { alwaysShow: true, @@ -370,8 +370,21 @@ export async function* inputBranchNameStep< value = value.trim(); if (value.length === 0) return [false, 'Please enter a valid branch name']; - const valid = await Container.git.validateBranchOrTagName(value); - return [valid, valid ? undefined : `'${value}' isn't a valid branch name`]; + if ('repo' in state) { + const valid = await Container.instance.git.validateBranchOrTagName(state.repo.path, value); + return [valid, valid ? undefined : `'${value}' isn't a valid branch name`]; + } + + let valid = true; + + for (const repo of state.repos) { + valid = await Container.instance.git.validateBranchOrTagName(repo.path, value); + if (!valid) { + return [false, `'${value}' isn't a valid branch name`]; + } + } + + return [true, undefined]; }, }); @@ -405,8 +418,21 @@ export async function* inputTagNameStep< value = value.trim(); if (value.length === 0) return [false, 'Please enter a valid tag name']; - const valid = await Container.git.validateBranchOrTagName(value); - return [valid, valid ? undefined : `'${value}' isn't a valid tag name`]; + if ('repo' in state) { + const valid = await Container.instance.git.validateBranchOrTagName(state.repo.path, value); + return [valid, valid ? undefined : `'${value}' isn't a valid tag name`]; + } + + let valid = true; + + for (const repo of state.repos) { + valid = await Container.instance.git.validateBranchOrTagName(repo.path, value); + if (!valid) { + return [false, `'${value}' isn't a valid branch name`]; + } + } + + return [true, undefined]; }, }); @@ -830,7 +856,7 @@ export async function* pickCommitStep< break; case QuickCommandButtons.SearchInSideBar: - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( state.repo.path, { pattern: SearchPattern.fromCommit(item.item.ref) }, { @@ -874,7 +900,7 @@ export async function* pickCommitStep< }); } else { const commit = items[0].item; - await Container.searchAndCompareView.search( + await Container.instance.searchAndCompareView.search( commit.repoPath, { pattern: SearchPattern.fromCommit(commit) }, { @@ -974,7 +1000,7 @@ export function* pickCommitsStep< break; case QuickCommandButtons.SearchInSideBar: - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( state.repo.path, { pattern: SearchPattern.fromCommit(item.ref) }, { @@ -1003,7 +1029,7 @@ export function* pickCommitsStep< }); } else { const commit = quickpick.activeItems[0].item; - await Container.searchAndCompareView.search( + await Container.instance.searchAndCompareView.search( commit.repoPath, { pattern: SearchPattern.fromCommit(commit) }, { @@ -1038,7 +1064,7 @@ export async function* pickContributorsStep< multiselect: true, placeholder: placeholder, matchOnDescription: true, - items: (await Container.git.getContributors(state.repo.path)).map(c => + items: (await Container.instance.git.getContributors(state.repo.path)).map(c => ContributorQuickPickItem.create(c, message?.includes(c.toCoauthor())), ), }); @@ -1051,10 +1077,10 @@ export async function* pickRepositoryStep< Context extends { repos: Repository[]; title: string }, >(state: State, context: Context, placeholder: string = 'Choose a repository'): AsyncStepResultGenerator { if (typeof state.repo === 'string') { - state.repo = await Container.git.getRepository(state.repo); + state.repo = await Container.instance.git.getRepository(state.repo); if (state.repo != null) return state.repo; } - const active = state.repo ?? (await Container.git.getActiveRepository()); + const active = state.repo ?? (await Container.instance.git.getActiveRepository()); const step = QuickCommand.createPickStep({ title: context.title, @@ -1074,7 +1100,7 @@ export async function* pickRepositoryStep< ), onDidClickItemButton: (quickpick, button, { item }) => { if (button === QuickCommandButtons.RevealInSideBar) { - void Container.repositoriesView.revealRepository(item.path, { + void Container.instance.repositoriesView.revealRepository(item.path, { select: true, expand: true, }); @@ -1084,7 +1110,7 @@ export async function* pickRepositoryStep< onDidPressKey: quickpick => { if (quickpick.activeItems.length === 0) return; - void Container.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, { + void Container.instance.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, { select: true, focus: false, expand: true, @@ -1116,7 +1142,7 @@ export async function* pickRepositoriesStep< actives = state.repos; } } else { - const active = await Container.git.getActiveRepository(); + const active = await Container.instance.git.getActiveRepository(); actives = active != null ? [active] : []; } @@ -1143,7 +1169,7 @@ export async function* pickRepositoriesStep< ), onDidClickItemButton: (quickpick, button, { item }) => { if (button === QuickCommandButtons.RevealInSideBar) { - void Container.repositoriesView.revealRepository(item.path, { + void Container.instance.repositoriesView.revealRepository(item.path, { select: true, expand: true, }); @@ -1153,7 +1179,7 @@ export async function* pickRepositoriesStep< onDidPressKey: quickpick => { if (quickpick.activeItems.length === 0) return; - void Container.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, { + void Container.instance.repositoriesView.revealRepository(quickpick.activeItems[0].item.path, { select: true, focus: false, expand: true, @@ -1312,7 +1338,7 @@ export async function* showCommitOrStashStep< : [QuickCommandButtons.RevealInSideBar, QuickCommandButtons.SearchInSideBar], onDidClickButton: (quickpick, button) => { if (button === QuickCommandButtons.SearchInSideBar) { - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( state.repo.path, { pattern: SearchPattern.fromCommit(state.reference.ref) }, { @@ -1360,7 +1386,7 @@ async function getShowCommitOrStashStepItems< >(state: State) { const items: CommandQuickPickItem[] = [new CommitFilesQuickPickItem(state.reference)]; - const branch = await Container.git.getBranch(state.repo.path); + const branch = await Container.instance.git.getBranch(state.repo.path); let remotes: GitRemote[] | undefined; let isStash = false; @@ -1389,7 +1415,7 @@ async function getShowCommitOrStashStepItems< }), ); } else { - remotes = await Container.git.getRemotes(state.repo.path, { sort: true }); + remotes = await Container.instance.git.getRemotes(state.repo.path, { sort: true }); items.push( new RevealInSideBarQuickPickItem(state.reference), @@ -1398,7 +1424,7 @@ async function getShowCommitOrStashStepItems< if ( branch != null && - (await Container.git.branchContainsCommit(state.repo.path, branch.name, state.reference.ref)) + (await Container.instance.git.branchContainsCommit(state.repo.path, branch.name, state.reference.ref)) ) { items.push( new GitCommandQuickPickItem('Revert Commit...', { @@ -1567,7 +1593,7 @@ export function* showCommitOrStashFilesStep< additionalButtons: [QuickCommandButtons.RevealInSideBar, QuickCommandButtons.SearchInSideBar], onDidClickButton: (quickpick, button) => { if (button === QuickCommandButtons.SearchInSideBar) { - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( state.repo.path, { pattern: SearchPattern.fromCommit(state.reference.ref) }, { @@ -1639,7 +1665,7 @@ export async function* showCommitOrStashFileStep< additionalButtons: [QuickCommandButtons.RevealInSideBar, QuickCommandButtons.SearchInSideBar], onDidClickButton: (quickpick, button) => { if (button === QuickCommandButtons.SearchInSideBar) { - void Container.searchAndCompareView.search( + void Container.instance.searchAndCompareView.search( state.repo.path, { pattern: SearchPattern.fromCommit(state.reference.ref) }, { @@ -1704,7 +1730,7 @@ async function getShowCommitOrStashFileStepItems< items.push(new RevealInSideBarQuickPickItem(state.reference)); } else { - remotes = await Container.git.getRemotes(state.repo.path, { sort: true }); + remotes = await Container.instance.git.getRemotes(state.repo.path, { sort: true }); items.push( new RevealInSideBarQuickPickItem(state.reference), diff --git a/src/commands/quickCommand.ts b/src/commands/quickCommand.ts index cf59da1..83b75ad 100644 --- a/src/commands/quickCommand.ts +++ b/src/commands/quickCommand.ts @@ -147,7 +147,7 @@ export abstract class QuickCommand implements QuickPickItem { return override != null ? override - : !Container.config.gitCommands.skipConfirmations.includes(this.skipConfirmKey); + : !Container.instance.config.gitCommands.skipConfirmations.includes(this.skipConfirmKey); } isMatch(key: string) { diff --git a/src/commands/rebaseEditor.ts b/src/commands/rebaseEditor.ts index a3bb1c2..a6c2497 100644 --- a/src/commands/rebaseEditor.ts +++ b/src/commands/rebaseEditor.ts @@ -9,7 +9,7 @@ export class DisableRebaseEditorCommand extends Command { } execute() { - return Container.rebaseEditor.setEnabled(false); + return Container.instance.rebaseEditor.setEnabled(false); } } @@ -20,6 +20,6 @@ export class EnableRebaseEditorCommand extends Command { } execute() { - return Container.rebaseEditor.setEnabled(true); + return Container.instance.rebaseEditor.setEnabled(true); } } diff --git a/src/commands/remoteProviders.ts b/src/commands/remoteProviders.ts index 864be0c..ec33fcd 100644 --- a/src/commands/remoteProviders.ts +++ b/src/commands/remoteProviders.ts @@ -47,7 +47,7 @@ export class ConnectRemoteProviderCommand extends Command { if (args?.repoPath == null) { const repos = new Map>(); - for (const repo of await Container.git.getOrderedRepositories()) { + for (const repo of await Container.instance.git.getOrderedRepositories()) { const remote = await repo.getRichRemote(); if (remote?.provider != null && !(await remote.provider.isConnected())) { repos.set(repo, remote); @@ -73,18 +73,18 @@ export class ConnectRemoteProviderCommand extends Command { } else if (args?.remote == null) { repoPath = args.repoPath; - remote = await Container.git.getRichRemoteProvider(repoPath, { includeDisconnected: true }); + remote = await Container.instance.git.getRichRemoteProvider(repoPath, { includeDisconnected: true }); if (remote == null) return false; } else { repoPath = args.repoPath; - remotes = await Container.git.getRemotes(repoPath); + remotes = await Container.instance.git.getRemotes(repoPath); remote = remotes.find(r => r.id === args.remote) as GitRemote | undefined; if (!remote?.provider.hasApi()) return false; } const connected = await remote.provider.connect(); - if (connected && !(remotes ?? (await Container.git.getRemotes(repoPath))).some(r => r.default)) { + if (connected && !(remotes ?? (await Container.instance.git.getRemotes(repoPath))).some(r => r.default)) { await remote.setAsDefault(true); } return connected; @@ -135,7 +135,7 @@ export class DisconnectRemoteProviderCommand extends Command { if (args?.repoPath == null) { const repos = new Map>(); - for (const repo of await Container.git.getOrderedRepositories()) { + for (const repo of await Container.instance.git.getOrderedRepositories()) { const remote = await repo.getRichRemote(true); if (remote != null) { repos.set(repo, remote); @@ -161,12 +161,12 @@ export class DisconnectRemoteProviderCommand extends Command { } else if (args?.remote == null) { repoPath = args.repoPath; - remote = await Container.git.getRichRemoteProvider(repoPath, { includeDisconnected: false }); + remote = await Container.instance.git.getRichRemoteProvider(repoPath, { includeDisconnected: false }); if (remote == null) return undefined; } else { repoPath = args.repoPath; - remote = (await Container.git.getRemotes(repoPath)).find(r => r.id === args.remote) as + remote = (await Container.instance.git.getRemotes(repoPath)).find(r => r.id === args.remote) as | GitRemote | undefined; if (!remote?.provider.hasApi()) return undefined; diff --git a/src/commands/repositories.ts b/src/commands/repositories.ts index 2269e1a..2465879 100644 --- a/src/commands/repositories.ts +++ b/src/commands/repositories.ts @@ -10,7 +10,10 @@ export class FetchRepositoriesCommand extends Command { } async execute() { - return executeGitCommand({ command: 'fetch', state: { repos: await Container.git.getOrderedRepositories() } }); + return executeGitCommand({ + command: 'fetch', + state: { repos: await Container.instance.git.getOrderedRepositories() }, + }); } } @@ -21,7 +24,10 @@ export class PullRepositoriesCommand extends Command { } async execute() { - return executeGitCommand({ command: 'pull', state: { repos: await Container.git.getOrderedRepositories() } }); + return executeGitCommand({ + command: 'pull', + state: { repos: await Container.instance.git.getOrderedRepositories() }, + }); } } @@ -32,6 +38,9 @@ export class PushRepositoriesCommand extends Command { } async execute() { - return executeGitCommand({ command: 'push', state: { repos: await Container.git.getOrderedRepositories() } }); + return executeGitCommand({ + command: 'push', + state: { repos: await Container.instance.git.getOrderedRepositories() }, + }); } } diff --git a/src/commands/searchCommits.ts b/src/commands/searchCommits.ts index 004ab5e..4232e4e 100644 --- a/src/commands/searchCommits.ts +++ b/src/commands/searchCommits.ts @@ -50,7 +50,7 @@ export class SearchCommitsCommand extends Command { repo: args?.repoPath, ...args?.search, showResultsInSideBar: - Container.config.gitCommands.search.showResultsInSideBar ?? args?.showResultsInSideBar, + Container.instance.config.gitCommands.search.showResultsInSideBar ?? args?.showResultsInSideBar, }, })); } diff --git a/src/commands/showCommitsInView.ts b/src/commands/showCommitsInView.ts index d525817..47c0235 100644 --- a/src/commands/showCommitsInView.ts +++ b/src/commands/showCommitsInView.ts @@ -35,12 +35,12 @@ export class ShowCommitsInViewCommand extends ActiveEditorCommand { try { // Check for any uncommitted changes in the range const blame = editor.document.isDirty - ? await Container.git.getBlameForRangeContents( + ? await Container.instance.git.getBlameForRangeContents( gitUri, editor.selection, editor.document.getText(), ) - : await Container.git.getBlameForRange(gitUri, editor.selection); + : await Container.instance.git.getBlameForRange(gitUri, editor.selection); if (blame === undefined) { return Messages.showFileNotUnderSourceControlWarningMessage('Unable to find commits'); } diff --git a/src/commands/showQuickBranchHistory.ts b/src/commands/showQuickBranchHistory.ts index d617443..c989ddf 100644 --- a/src/commands/showQuickBranchHistory.ts +++ b/src/commands/showQuickBranchHistory.ts @@ -32,7 +32,7 @@ export class ShowQuickBranchHistoryCommand extends ActiveEditorCachedCommand { const gitUri = uri != null ? await GitUri.fromUri(uri) : undefined; - const repoPath = args?.repoPath ?? gitUri?.repoPath ?? Container.git.getHighlanderRepoPath(); + const repoPath = args?.repoPath ?? gitUri?.repoPath ?? Container.instance.git.getHighlanderRepoPath(); let ref: GitReference | 'HEAD' | undefined; if (repoPath != null) { if (args?.branch != null) { diff --git a/src/commands/showQuickCommit.ts b/src/commands/showQuickCommit.ts index c2b4c3a..6680546 100644 --- a/src/commands/showQuickCommit.ts +++ b/src/commands/showQuickCommit.ts @@ -89,7 +89,7 @@ export class ShowQuickCommitCommand extends ActiveEditorCachedCommand { if (blameline < 0) return; try { - const blame = await Container.git.getBlameForLine(gitUri, blameline); + const blame = await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) { void Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit'); @@ -126,7 +126,7 @@ export class ShowQuickCommitCommand extends ActiveEditorCachedCommand { } if (args.repoLog == null) { - args.commit = await Container.git.getCommit(repoPath!, args.sha); + args.commit = await Container.instance.git.getCommit(repoPath!, args.sha); } } diff --git a/src/commands/showQuickCommitFile.ts b/src/commands/showQuickCommitFile.ts index 85e594d..e45aa37 100644 --- a/src/commands/showQuickCommitFile.ts +++ b/src/commands/showQuickCommitFile.ts @@ -78,7 +78,7 @@ export class ShowQuickCommitFileCommand extends ActiveEditorCachedCommand { if (blameline < 0) return; try { - const blame = await Container.git.getBlameForLine(gitUri, blameline); + const blame = await Container.instance.git.getBlameForLine(gitUri, blameline); if (blame == null) { void Messages.showFileNotUnderSourceControlWarningMessage('Unable to show commit file details'); @@ -115,7 +115,9 @@ export class ShowQuickCommitFileCommand extends ActiveEditorCachedCommand { if (args.fileLog === undefined) { const repoPath = args.commit === undefined ? gitUri.repoPath : args.commit.repoPath; - args.commit = await Container.git.getCommitForFile(repoPath, gitUri.fsPath, { ref: args.sha }); + args.commit = await Container.instance.git.getCommitForFile(repoPath, gitUri.fsPath, { + ref: args.sha, + }); if (args.commit === undefined) { void Messages.showCommitNotFoundWarningMessage('Unable to show commit file details'); @@ -134,7 +136,7 @@ export class ShowQuickCommitFileCommand extends ActiveEditorCachedCommand { const fileName = args.commit.fileName; if (args.commit instanceof GitBlameCommit) { - args.commit = (await Container.git.getCommit(args.commit.repoPath, args.commit.ref))!; + args.commit = (await Container.instance.git.getCommit(args.commit.repoPath, args.commit.ref))!; } void (await executeGitCommand({ diff --git a/src/commands/showQuickFileHistory.ts b/src/commands/showQuickFileHistory.ts index a49b051..9f5b4b6 100644 --- a/src/commands/showQuickFileHistory.ts +++ b/src/commands/showQuickFileHistory.ts @@ -50,7 +50,7 @@ export class ShowQuickFileHistoryCommand extends ActiveEditorCachedCommand { const gitUri = await GitUri.fromUri(uri); if (args?.showInSideBar) { - await Container.fileHistoryView.showHistoryForUri(gitUri); + await Container.instance.fileHistoryView.showHistoryForUri(gitUri); return; } diff --git a/src/commands/showView.ts b/src/commands/showView.ts index cd80914..661bf86 100644 --- a/src/commands/showView.ts +++ b/src/commands/showView.ts @@ -29,28 +29,28 @@ export class ShowViewCommand extends Command { async execute(command: Commands) { switch (command) { case Commands.ShowBranchesView: - return Container.branchesView.show(); + return Container.instance.branchesView.show(); case Commands.ShowCommitsView: - return Container.commitsView.show(); + return Container.instance.commitsView.show(); case Commands.ShowContributorsView: - return Container.contributorsView.show(); + return Container.instance.contributorsView.show(); case Commands.ShowFileHistoryView: - return Container.fileHistoryView.show(); + return Container.instance.fileHistoryView.show(); case Commands.ShowLineHistoryView: - return Container.lineHistoryView.show(); + return Container.instance.lineHistoryView.show(); case Commands.ShowRemotesView: - return Container.remotesView.show(); + return Container.instance.remotesView.show(); case Commands.ShowRepositoriesView: - return Container.repositoriesView.show(); + return Container.instance.repositoriesView.show(); case Commands.ShowSearchAndCompareView: - return Container.searchAndCompareView.show(); + return Container.instance.searchAndCompareView.show(); case Commands.ShowStashesView: - return Container.stashesView.show(); + return Container.instance.stashesView.show(); case Commands.ShowTagsView: - return Container.tagsView.show(); + return Container.instance.tagsView.show(); case Commands.ShowWelcomeView: await setContext(ContextKeys.ViewsWelcomeVisible, true); - void Container.context.globalState.update(SyncedState.WelcomeViewVisible, true); + void Container.instance.context.globalState.update(SyncedState.WelcomeViewVisible, true); void (await commands.executeCommand('gitlens.views.welcome.focus')); } diff --git a/src/commands/stashSave.ts b/src/commands/stashSave.ts index ac7d8dd..2e5e3a2 100644 --- a/src/commands/stashSave.ts +++ b/src/commands/stashSave.ts @@ -46,9 +46,9 @@ export class StashSaveCommand extends Command { } else if (context.type === 'scm-states') { args = { ...args }; args.uris = context.scmResourceStates.map(s => s.resourceUri); - args.repoPath = await Container.git.getRepoPath(args.uris[0].fsPath); + args.repoPath = await Container.instance.git.getRepoPath(args.uris[0].fsPath); - const status = await Container.git.getStatusForRepo(args.repoPath); + const status = await Container.instance.git.getStatusForRepo(args.repoPath); if (status?.computeWorkingTreeStatus().staged) { if (!context.scmResourceStates.some(s => (s as any).resourceGroupType === ResourceGroupType.Index)) { args.keepStaged = true; @@ -60,9 +60,9 @@ export class StashSaveCommand extends Command { (a, b) => a.concat(b.resourceStates.map(s => s.resourceUri)), [], ); - args.repoPath = await Container.git.getRepoPath(args.uris[0].fsPath); + args.repoPath = await Container.instance.git.getRepoPath(args.uris[0].fsPath); - const status = await Container.git.getStatusForRepo(args.repoPath); + const status = await Container.instance.git.getStatusForRepo(args.repoPath); if (status?.computeWorkingTreeStatus().staged) { if (!context.scmResourceGroups.some(g => g.id === 'index')) { args.keepStaged = true; diff --git a/src/commands/switchMode.ts b/src/commands/switchMode.ts index 3719875..f7d6f7f 100644 --- a/src/commands/switchMode.ts +++ b/src/commands/switchMode.ts @@ -24,16 +24,17 @@ export class SwitchModeCommand extends Command { cc.exitDetails = ` \u2014 mode=${pick.key ?? ''}`; } - const active = Container.config.mode.active; + const active = Container.instance.config.mode.active; if (active === pick.key) return; // Check if we have applied any annotations and clear them if we won't be applying them again if (active != null && active.length !== 0) { - const activeAnnotations = Container.config.modes?.[active].annotations; + const activeAnnotations = Container.instance.config.modes?.[active].annotations; if (activeAnnotations != null) { - const newAnnotations = pick.key != null ? Container.config.modes?.[pick.key].annotations : undefined; + const newAnnotations = + pick.key != null ? Container.instance.config.modes?.[pick.key].annotations : undefined; if (activeAnnotations !== newAnnotations) { - await Container.fileAnnotations.clearAll(); + await Container.instance.fileAnnotations.clearAll(); } } } @@ -50,9 +51,14 @@ export class ToggleReviewModeCommand extends Command { @log({ args: false, singleLine: true, timed: false }) async execute() { - if (Container.config.modes == null || !Object.keys(Container.config.modes).includes('review')) return; + if ( + Container.instance.config.modes == null || + !Object.keys(Container.instance.config.modes).includes('review') + ) { + return; + } - const mode = Container.config.mode.active === 'review' ? undefined : 'review'; + const mode = Container.instance.config.mode.active === 'review' ? undefined : 'review'; await configuration.update('mode.active', mode, ConfigurationTarget.Global); } } @@ -65,9 +71,11 @@ export class ToggleZenModeCommand extends Command { @log({ args: false, singleLine: true, timed: false }) async execute() { - if (Container.config.modes == null || !Object.keys(Container.config.modes).includes('zen')) return; + if (Container.instance.config.modes == null || !Object.keys(Container.instance.config.modes).includes('zen')) { + return; + } - const mode = Container.config.mode.active === 'zen' ? undefined : 'zen'; + const mode = Container.instance.config.mode.active === 'zen' ? undefined : 'zen'; await configuration.update('mode.active', mode, ConfigurationTarget.Global); } } diff --git a/src/commands/toggleCodeLens.ts b/src/commands/toggleCodeLens.ts index 5e6e774..a8f53b4 100644 --- a/src/commands/toggleCodeLens.ts +++ b/src/commands/toggleCodeLens.ts @@ -9,6 +9,6 @@ export class ToggleCodeLensCommand extends Command { } execute() { - return Container.codeLens.toggleCodeLens(); + return Container.instance.codeLens.toggleCodeLens(); } } diff --git a/src/commands/toggleFileAnnotations.ts b/src/commands/toggleFileAnnotations.ts index 11ac6f5..a5394d3 100644 --- a/src/commands/toggleFileAnnotations.ts +++ b/src/commands/toggleFileAnnotations.ts @@ -28,7 +28,7 @@ export class ClearFileAnnotationsCommand extends EditorCommand { } try { - void (await Container.fileAnnotations.clear(editor)); + void (await Container.instance.fileAnnotations.clear(editor)); } catch (ex) { Logger.error(ex, 'ClearFileAnnotationsCommand'); void Messages.showGenericErrorMessage('Unable to clear file annotations'); @@ -123,7 +123,7 @@ async function toggleFileAnnotations { try { - void (await Container.lineAnnotations.toggle(editor)); + void (await Container.instance.lineAnnotations.toggle(editor)); } catch (ex) { Logger.error(ex, 'ToggleLineBlameCommand'); void window.showErrorMessage( diff --git a/src/container.ts b/src/container.ts index 0b66723..7ad436c 100644 --- a/src/container.ts +++ b/src/container.ts @@ -1,5 +1,5 @@ 'use strict'; -import { commands, ConfigurationChangeEvent, ConfigurationScope, ExtensionContext } from 'vscode'; +import { commands, ConfigurationChangeEvent, ConfigurationScope, Event, EventEmitter, ExtensionContext } from 'vscode'; import { Autolinks } from './annotations/autolinks'; import { FileAnnotationController } from './annotations/fileAnnotationController'; import { LineAnnotationController } from './annotations/lineAnnotationController'; @@ -42,53 +42,81 @@ import { SettingsWebview } from './webviews/settingsWebview'; import { WelcomeWebview } from './webviews/welcomeWebview'; export class Container { - private static _configsAffectedByMode: string[] | undefined; - private static _applyModeConfigurationTransformBound: + static #instance: Container | undefined; + static #proxy = new Proxy({} as Container, { + get: function (target, prop) { + // In case anyone has cached this instance + if (Container.#instance != null) return (Container.#instance as any)[prop]; + + // Allow access to config before we are initialized + if (prop === 'config') return configuration.get(); + + // debugger; + throw new Error('Container is not initialized'); + }, + }); + + static create(context: ExtensionContext, cfg: Config) { + if (Container.#instance != null) throw new Error('Container is already initialized'); + + Container.#instance = new Container(context, cfg); + return Container.#instance; + } + + static get instance(): Container { + return Container.#instance ?? Container.#proxy; + } + + private _onReady: EventEmitter = new EventEmitter(); + get onReady(): Event { + return this._onReady.event; + } + + private _configsAffectedByMode: string[] | undefined; + private _applyModeConfigurationTransformBound: | ((e: ConfigurationChangeEvent) => ConfigurationChangeEvent) | undefined; - private static _terminalLinks: GitTerminalLinkProvider | undefined; + private _terminalLinks: GitTerminalLinkProvider | undefined; - static initialize(context: ExtensionContext, config: Config) { + private constructor(context: ExtensionContext, config: Config) { this._context = context; - this._config = Container.applyMode(config); + this._config = this.applyMode(config); + context.subscriptions.push(configuration.onWillChange(this.onConfigurationChanging, this)); - context.subscriptions.push((this._actionRunners = new ActionRunners())); - context.subscriptions.push((this._lineTracker = new GitLineTracker())); - context.subscriptions.push((this._tracker = new GitDocumentTracker())); - context.subscriptions.push((this._vsls = new VslsController())); + context.subscriptions.push((this._git = new GitService(this))); + context.subscriptions.push(new GitFileSystemProvider(this)); - context.subscriptions.push((this._git = new GitService())); + context.subscriptions.push((this._actionRunners = new ActionRunners(this))); + context.subscriptions.push((this._tracker = new GitDocumentTracker(this))); + context.subscriptions.push((this._lineTracker = new GitLineTracker(this))); + context.subscriptions.push((this._keyboard = new Keyboard())); + context.subscriptions.push((this._vsls = new VslsController(this))); - context.subscriptions.push(new ViewFileDecorationProvider()); + context.subscriptions.push((this._fileAnnotationController = new FileAnnotationController(this))); + context.subscriptions.push((this._lineAnnotationController = new LineAnnotationController(this))); + context.subscriptions.push((this._lineHoverController = new LineHoverController(this))); + context.subscriptions.push((this._statusBarController = new StatusBarController(this))); + context.subscriptions.push((this._codeLensController = new GitCodeLensController(this))); - // Since there is a bit of a chicken & egg problem with the DocumentTracker and the GitService, initialize the tracker once the GitService is loaded - this._tracker.initialize(); + context.subscriptions.push((this._settingsWebview = new SettingsWebview(this))); + context.subscriptions.push((this._welcomeWebview = new WelcomeWebview(this))); + context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider(this))); - context.subscriptions.push((this._fileAnnotationController = new FileAnnotationController())); - context.subscriptions.push((this._lineAnnotationController = new LineAnnotationController())); - context.subscriptions.push((this._lineHoverController = new LineHoverController())); - context.subscriptions.push((this._statusBarController = new StatusBarController())); - context.subscriptions.push((this._codeLensController = new GitCodeLensController())); - context.subscriptions.push((this._keyboard = new Keyboard())); - context.subscriptions.push((this._settingsWebview = new SettingsWebview())); - context.subscriptions.push((this._welcomeWebview = new WelcomeWebview())); - - context.subscriptions.push((this._repositoriesView = new RepositoriesView())); - context.subscriptions.push((this._commitsView = new CommitsView())); - context.subscriptions.push((this._fileHistoryView = new FileHistoryView())); - context.subscriptions.push((this._lineHistoryView = new LineHistoryView())); - context.subscriptions.push((this._branchesView = new BranchesView())); - context.subscriptions.push((this._remotesView = new RemotesView())); - context.subscriptions.push((this._stashesView = new StashesView())); - context.subscriptions.push((this._tagsView = new TagsView())); - context.subscriptions.push((this._contributorsView = new ContributorsView())); - context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView())); - - context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider())); + context.subscriptions.push(new ViewFileDecorationProvider()); + context.subscriptions.push((this._repositoriesView = new RepositoriesView(this))); + context.subscriptions.push((this._commitsView = new CommitsView(this))); + context.subscriptions.push((this._fileHistoryView = new FileHistoryView(this))); + context.subscriptions.push((this._lineHistoryView = new LineHistoryView(this))); + context.subscriptions.push((this._branchesView = new BranchesView(this))); + context.subscriptions.push((this._remotesView = new RemotesView(this))); + context.subscriptions.push((this._stashesView = new StashesView(this))); + context.subscriptions.push((this._tagsView = new TagsView(this))); + context.subscriptions.push((this._contributorsView = new ContributorsView(this))); + context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView(this))); if (config.terminalLinks.enabled) { - context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider())); + context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider(this))); } context.subscriptions.push( @@ -96,18 +124,22 @@ export class Container { if (!configuration.changed(e, 'terminalLinks.enabled')) return; this._terminalLinks?.dispose(); - if (Container.config.terminalLinks.enabled) { - context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider())); + if (this.config.terminalLinks.enabled) { + context.subscriptions.push((this._terminalLinks = new GitTerminalLinkProvider(this))); } }), ); + } - context.subscriptions.push(new GitFileSystemProvider()); + private _ready: boolean = false; + ready() { + if (this._ready) throw new Error('Container is already ready'); - context.subscriptions.push(configuration.onWillChange(this.onConfigurationChanging, this)); + this._ready = true; + this._onReady.fire(); } - private static onConfigurationChanging(e: ConfigurationWillChangeEvent) { + private onConfigurationChanging(e: ConfigurationWillChangeEvent) { this._config = undefined; if (configuration.changed(e.change, 'outputLevel')) { @@ -126,90 +158,90 @@ export class Container { } } - private static _actionRunners: ActionRunners; - static get actionRunners() { + private _actionRunners: ActionRunners; + get actionRunners() { if (this._actionRunners == null) { - this._context.subscriptions.push((this._actionRunners = new ActionRunners())); + this._context.subscriptions.push((this._actionRunners = new ActionRunners(this))); } return this._actionRunners; } - private static _autolinks: Autolinks; - static get autolinks() { + private _autolinks: Autolinks | undefined; + get autolinks() { if (this._autolinks == null) { - this._context.subscriptions.push((this._autolinks = new Autolinks())); + this._context.subscriptions.push((this._autolinks = new Autolinks(this))); } return this._autolinks; } - private static _codeLensController: GitCodeLensController; - static get codeLens() { + private _codeLensController: GitCodeLensController; + get codeLens() { return this._codeLensController; } - private static _branchesView: BranchesView | undefined; - static get branchesView() { + private _branchesView: BranchesView | undefined; + get branchesView() { if (this._branchesView == null) { - this._context.subscriptions.push((this._branchesView = new BranchesView())); + this._context.subscriptions.push((this._branchesView = new BranchesView(this))); } return this._branchesView; } - private static _commitsView: CommitsView | undefined; - static get commitsView() { + private _commitsView: CommitsView | undefined; + get commitsView() { if (this._commitsView == null) { - this._context.subscriptions.push((this._commitsView = new CommitsView())); + this._context.subscriptions.push((this._commitsView = new CommitsView(this))); } return this._commitsView; } - private static _config: Config | undefined; - static get config() { + private _config: Config | undefined; + get config() { if (this._config == null) { - this._config = Container.applyMode(configuration.get()); + this._config = this.applyMode(configuration.get()); } return this._config; } - private static _context: ExtensionContext; - static get context() { + private _context: ExtensionContext; + get context() { return this._context; } - private static _contributorsView: ContributorsView | undefined; - static get contributorsView() { + private _contributorsView: ContributorsView | undefined; + get contributorsView() { if (this._contributorsView == null) { - this._context.subscriptions.push((this._contributorsView = new ContributorsView())); + this._context.subscriptions.push((this._contributorsView = new ContributorsView(this))); } return this._contributorsView; } - private static _fileAnnotationController: FileAnnotationController; - static get fileAnnotations() { + private _fileAnnotationController: FileAnnotationController; + get fileAnnotations() { return this._fileAnnotationController; } - private static _fileHistoryView: FileHistoryView | undefined; - static get fileHistoryView() { + private _fileHistoryView: FileHistoryView | undefined; + get fileHistoryView() { if (this._fileHistoryView == null) { - this._context.subscriptions.push((this._fileHistoryView = new FileHistoryView())); + this._context.subscriptions.push((this._fileHistoryView = new FileHistoryView(this))); } return this._fileHistoryView; } - private static _git: GitService; - static get git() { + private _git: GitService; + get git() { return this._git; } - private static _github: Promise | undefined; - static get github() { + private _github: Promise | undefined; + get github() { if (this._github == null) { this._github = this._loadGitHubApi(); } @@ -217,7 +249,7 @@ export class Container { return this._github; } - private static async _loadGitHubApi() { + private async _loadGitHubApi() { try { return new (await import(/* webpackChunkName: "github" */ './github/github')).GitHubApi(); } catch (ex) { @@ -227,127 +259,132 @@ export class Container { } @memoize() - static get insiders() { + get insiders() { return this._context.extension.id.endsWith('-insiders'); } - private static _keyboard: Keyboard; - static get keyboard() { + private _keyboard: Keyboard; + get keyboard() { return this._keyboard; } - private static _lineAnnotationController: LineAnnotationController; - static get lineAnnotations() { + private _lineAnnotationController: LineAnnotationController; + get lineAnnotations() { return this._lineAnnotationController; } - private static _lineHistoryView: LineHistoryView | undefined; - static get lineHistoryView() { + private _lineHistoryView: LineHistoryView | undefined; + get lineHistoryView() { if (this._lineHistoryView == null) { - this._context.subscriptions.push((this._lineHistoryView = new LineHistoryView())); + this._context.subscriptions.push((this._lineHistoryView = new LineHistoryView(this))); } return this._lineHistoryView; } - private static _lineHoverController: LineHoverController; - static get lineHovers() { + private _lineHoverController: LineHoverController; + get lineHovers() { return this._lineHoverController; } - private static _lineTracker: GitLineTracker; - static get lineTracker() { + private _lineTracker: GitLineTracker; + get lineTracker() { return this._lineTracker; } - private static _rebaseEditor: RebaseEditorProvider | undefined; - static get rebaseEditor() { + private _rebaseEditor: RebaseEditorProvider | undefined; + get rebaseEditor() { if (this._rebaseEditor == null) { - this._context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider())); + this._context.subscriptions.push((this._rebaseEditor = new RebaseEditorProvider(this))); } return this._rebaseEditor; } - private static _remotesView: RemotesView | undefined; - static get remotesView() { + private _remotesView: RemotesView | undefined; + get remotesView() { if (this._remotesView == null) { - this._context.subscriptions.push((this._remotesView = new RemotesView())); + this._context.subscriptions.push((this._remotesView = new RemotesView(this))); } return this._remotesView; } - private static _repositoriesView: RepositoriesView | undefined; - static get repositoriesView(): RepositoriesView { + private _repositoriesView: RepositoriesView | undefined; + get repositoriesView(): RepositoriesView { if (this._repositoriesView == null) { - this._context.subscriptions.push((this._repositoriesView = new RepositoriesView())); + this._context.subscriptions.push((this._repositoriesView = new RepositoriesView(this))); } return this._repositoriesView; } - private static _searchAndCompareView: SearchAndCompareView | undefined; - static get searchAndCompareView() { + private _searchAndCompareView: SearchAndCompareView | undefined; + get searchAndCompareView() { if (this._searchAndCompareView == null) { - this._context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView())); + this._context.subscriptions.push((this._searchAndCompareView = new SearchAndCompareView(this))); } return this._searchAndCompareView; } - private static _settingsWebview: SettingsWebview; - static get settingsWebview() { + private _settingsWebview: SettingsWebview; + get settingsWebview() { return this._settingsWebview; } - private static _stashesView: StashesView | undefined; - static get stashesView() { + private _stashesView: StashesView | undefined; + get stashesView() { if (this._stashesView == null) { - this._context.subscriptions.push((this._stashesView = new StashesView())); + this._context.subscriptions.push((this._stashesView = new StashesView(this))); } return this._stashesView; } - private static _statusBarController: StatusBarController; - static get statusBar() { + private _statusBarController: StatusBarController; + get statusBar() { return this._statusBarController; } - private static _tagsView: TagsView | undefined; - static get tagsView() { + private _tagsView: TagsView | undefined; + get tagsView() { if (this._tagsView == null) { - this._context.subscriptions.push((this._tagsView = new TagsView())); + this._context.subscriptions.push((this._tagsView = new TagsView(this))); } return this._tagsView; } - private static _tracker: GitDocumentTracker; - static get tracker() { + private _tracker: GitDocumentTracker; + get tracker() { return this._tracker; } - private static _viewCommands: ViewCommands | undefined; - static get viewCommands() { + @memoize() + get version(): string { + return this.context.extension.packageJSON.version; + } + + private _viewCommands: ViewCommands | undefined; + get viewCommands() { if (this._viewCommands == null) { - this._viewCommands = new ViewCommands(); + this._viewCommands = new ViewCommands(this); } return this._viewCommands; } - private static _vsls: VslsController; - static get vsls() { + private _vsls: VslsController; + get vsls() { return this._vsls; } - private static _welcomeWebview: WelcomeWebview; - static get welcomeWebview() { + private _welcomeWebview: WelcomeWebview; + get welcomeWebview() { return this._welcomeWebview; } - private static applyMode(config: Config) { + private applyMode(config: Config) { if (!config.mode.active) return config; const mode = config.modes?.[config.mode.active]; @@ -399,7 +436,7 @@ export class Container { return config; } - private static applyModeConfigurationTransform(e: ConfigurationChangeEvent): ConfigurationChangeEvent { + private applyModeConfigurationTransform(e: ConfigurationChangeEvent): ConfigurationChangeEvent { if (this._configsAffectedByMode == null) { this._configsAffectedByMode = [ `gitlens.${configuration.name('mode')}`, diff --git a/src/extension.ts b/src/extension.ts index 29c3446..6b26445 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -17,13 +17,9 @@ import { registerPartnerActionRunners } from './partners'; import { Strings, Versions } from './system'; import { ViewNode } from './views/nodes'; -let _context: ExtensionContext | undefined; - export async function activate(context: ExtensionContext): Promise { const start = process.hrtime(); - _context = context; - if (context.extension.id === 'eamodio.gitlens-insiders') { // Ensure that stable isn't also installed const stable = extensions.getExtension('eamodio.gitlens'); @@ -47,7 +43,7 @@ export async function activate(context: ExtensionContext): Promise { if (GitUri.is(o)) { @@ -112,13 +108,13 @@ export async function activate(context: ExtensionContext): Promise('git.path')); } catch (ex) { Logger.error(ex, `GitLens (v${gitlensVersion}) activate`); void setEnabled(false); @@ -137,16 +133,16 @@ export async function activate(context: ExtensionContext): Promise { await Promise.all([setContext(ContextKeys.Enabled, enabled), setContext(ContextKeys.Disabled, !enabled)]); } -export function setKeysForSync(...keys: (SyncedState | string)[]) { - return _context?.globalState?.setKeysForSync([...keys, SyncedState.Version, SyncedState.WelcomeViewVisible]); +function setKeysForSync(context: ExtensionContext, ...keys: (SyncedState | string)[]) { + return context.globalState?.setKeysForSync([...keys, SyncedState.Version, SyncedState.WelcomeViewVisible]); } -export function notifyOnUnsupportedGitVersion(version: string) { +function notifyOnUnsupportedGitVersion(version: string) { if (GitService.compareGitVersion('2.7.2') !== -1) return; // If git is less than v2.7.2 void Messages.showGitVersionUnsupportedErrorMessage(version, '2.7.2'); } -function registerBuiltInActionRunners(context: ExtensionContext): void { - context.subscriptions.push( - Container.actionRunners.registerBuiltIn('createPullRequest', { +function registerBuiltInActionRunners(container: Container): void { + container.context.subscriptions.push( + container.actionRunners.registerBuiltIn('createPullRequest', { label: ctx => `Create Pull Request on ${ctx.remote?.provider?.name ?? 'Remote'}`, run: async ctx => { if (ctx.type !== 'createPullRequest') return; @@ -226,7 +222,7 @@ function registerBuiltInActionRunners(context: ExtensionContext): void { })); }, }), - Container.actionRunners.registerBuiltIn('openPullRequest', { + container.actionRunners.registerBuiltIn('openPullRequest', { label: ctx => `Open Pull Request on ${ctx.provider?.name ?? 'Remote'}`, run: async ctx => { if (ctx.type !== 'openPullRequest') return; @@ -239,31 +235,31 @@ function registerBuiltInActionRunners(context: ExtensionContext): void { ); } -async function showWelcomeOrWhatsNew(context: ExtensionContext, version: string, previousVersion: string | undefined) { +async function showWelcomeOrWhatsNew(container: Container, version: string, previousVersion: string | undefined) { if (previousVersion == null) { Logger.log(`GitLens first-time install; window.focused=${window.state.focused}`); - if (Container.config.showWelcomeOnInstall === false) return; + if (container.config.showWelcomeOnInstall === false) return; if (window.state.focused) { - await context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined); + await container.context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined); await commands.executeCommand(Commands.ShowWelcomePage); } else { // Save pending on window getting focus - await context.globalState.update(GlobalState.PendingWelcomeOnFocus, true); + await container.context.globalState.update(GlobalState.PendingWelcomeOnFocus, true); const disposable = window.onDidChangeWindowState(e => { if (!e.focused) return; disposable.dispose(); // If the window is now focused and we are pending the welcome, clear the pending state and show the welcome - if (context.globalState.get(GlobalState.PendingWelcomeOnFocus) === true) { - void context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined); - if (Container.config.showWelcomeOnInstall) { + if (container.context.globalState.get(GlobalState.PendingWelcomeOnFocus) === true) { + void container.context.globalState.update(GlobalState.PendingWelcomeOnFocus, undefined); + if (container.config.showWelcomeOnInstall) { void commands.executeCommand(Commands.ShowWelcomePage); } } }); - context.subscriptions.push(disposable); + container.context.subscriptions.push(disposable); } return; @@ -284,27 +280,27 @@ async function showWelcomeOrWhatsNew(context: ExtensionContext, version: string, return; } - if (major !== prevMajor && Container.config.showWhatsNewAfterUpgrades) { + if (major !== prevMajor && container.config.showWhatsNewAfterUpgrades) { if (window.state.focused) { - await context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined); + await container.context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined); await Messages.showWhatsNewMessage(version); } else { // Save pending on window getting focus - await context.globalState.update(GlobalState.PendingWhatsNewOnFocus, true); + await container.context.globalState.update(GlobalState.PendingWhatsNewOnFocus, true); const disposable = window.onDidChangeWindowState(e => { if (!e.focused) return; disposable.dispose(); // If the window is now focused and we are pending the what's new, clear the pending state and show the what's new - if (context.globalState.get(GlobalState.PendingWhatsNewOnFocus) === true) { - void context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined); - if (Container.config.showWhatsNewAfterUpgrades) { + if (container.context.globalState.get(GlobalState.PendingWhatsNewOnFocus) === true) { + void container.context.globalState.update(GlobalState.PendingWhatsNewOnFocus, undefined); + if (container.config.showWhatsNewAfterUpgrades) { void Messages.showWhatsNewMessage(version); } } }); - context.subscriptions.push(disposable); + container.context.subscriptions.push(disposable); } } } diff --git a/src/git/formatters/commitFormatter.ts b/src/git/formatters/commitFormatter.ts index 693bad9..8617b08 100644 --- a/src/git/formatters/commitFormatter.ts +++ b/src/git/formatters/commitFormatter.ts @@ -136,7 +136,8 @@ export class CommitFormatter extends Formatter { } private get _pullRequestDateOrAgo() { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return dateStyle === DateStyle.Absolute ? this._pullRequestDate : this._pullRequestDateAgo; } @@ -145,7 +146,8 @@ export class CommitFormatter extends Formatter { } get agoOrDate(): string { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return this._padOrTruncate( dateStyle === DateStyle.Absolute ? this._date : this._dateAgo, this._options.tokenOptions.agoOrDate, @@ -153,7 +155,8 @@ export class CommitFormatter extends Formatter { } get agoOrDateShort(): string { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return this._padOrTruncate( dateStyle === DateStyle.Absolute ? this._date : this._dateAgoShort, this._options.tokenOptions.agoOrDateShort, @@ -174,7 +177,8 @@ export class CommitFormatter extends Formatter { } get authorAgoOrDate(): string { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return this._padOrTruncate( dateStyle === DateStyle.Absolute ? this._authorDate : this._authorDateAgo, this._options.tokenOptions.authorAgoOrDate, @@ -182,7 +186,8 @@ export class CommitFormatter extends Formatter { } get authorAgoOrDateShort(): string { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return this._padOrTruncate( dateStyle === DateStyle.Absolute ? this._authorDate : this._authorDateAgoShort, this._options.tokenOptions.authorAgoOrDateShort, @@ -205,7 +210,7 @@ export class CommitFormatter extends Formatter { } get avatar(): string | Promise { - if (!this._options.markdown || !Container.config.hovers.avatars) { + if (!this._options.markdown || !Container.instance.config.hovers.avatars) { return this._padOrTruncate(emptyStr, this._options.tokenOptions.avatar); } @@ -228,9 +233,9 @@ export class CommitFormatter extends Formatter { } private async _getAvatarMarkdown(title: string, size?: number) { - size = size ?? Container.config.hovers.avatarSize; + size = size ?? Container.instance.config.hovers.avatarSize; const avatarPromise = this._item.getAvatarUri({ - defaultStyle: Container.config.defaultGravatarsStyle, + defaultStyle: Container.instance.config.defaultGravatarsStyle, size: size, }); return this._padOrTruncate( @@ -350,13 +355,13 @@ export class CommitFormatter extends Formatter { provider: { id: pr.provider.id, name: pr.provider.name, domain: pr.provider.domain }, pullRequest: { id: pr.id, url: pr.url }, })} "Open Pull Request \\#${pr.id}${ - Container.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...' + Container.instance.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...' }\n${GlyphChars.Dash.repeat(2)}\n${Strings.escapeMarkdown(pr.title).replace(/"/g, '\\"')}\n${ pr.state }, ${pr.formatDateFromNow()}")`; } else if (pr instanceof Promises.CancellationError) { commands += `${separator}[$(git-pull-request) PR $(loading~spin)](command:${Commands.RefreshHover} "Searching for a Pull Request (if any) that introduced this commit...")`; - } else if (pr.provider != null && Container.config.integrations.enabled) { + } else if (pr.provider != null && Container.instance.config.integrations.enabled) { commands += `${separator}[$(plug) Connect to ${pr.provider.name}${ GlyphChars.Ellipsis }](${ConnectRemoteProviderCommand.getMarkdownCommandArgs(pr)} "Connect to ${ @@ -365,7 +370,7 @@ export class CommitFormatter extends Formatter { } } - if (Container.actionRunners.count('hover.commands') > 0) { + if (Container.instance.actionRunners.count('hover.commands') > 0) { commands += `${separator}[$(organization) Team${GlyphChars.SpaceThinnest}${ GlyphChars.Ellipsis }](${getMarkdownActionCommand('hover.commands', { @@ -400,7 +405,8 @@ export class CommitFormatter extends Formatter { } get committerAgoOrDate(): string { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return this._padOrTruncate( dateStyle === DateStyle.Absolute ? this._committerDate : this._committerDateAgo, this._options.tokenOptions.committerAgoOrDate, @@ -408,7 +414,8 @@ export class CommitFormatter extends Formatter { } get committerAgoOrDateShort(): string { - const dateStyle = this._options.dateStyle != null ? this._options.dateStyle : Container.config.defaultDateStyle; + const dateStyle = + this._options.dateStyle != null ? this._options.dateStyle : Container.instance.config.defaultDateStyle; return this._padOrTruncate( dateStyle === DateStyle.Absolute ? this._committerDate : this._committerDateAgoShort, this._options.tokenOptions.committerAgoOrDateShort, @@ -477,7 +484,7 @@ export class CommitFormatter extends Formatter { message = this._padOrTruncate(message, this._options.tokenOptions.message); if (this._options.messageAutolinks) { - message = Container.autolinks.linkify( + message = Container.instance.autolinks.linkify( this._options.markdown ? Strings.escapeMarkdown(message, { quoted: true }) : message, this._options.markdown ?? false, this._options.remotes, @@ -507,7 +514,7 @@ export class CommitFormatter extends Formatter { provider: { id: pr.provider.id, name: pr.provider.name, domain: pr.provider.domain }, pullRequest: { id: pr.id, url: pr.url }, })} "Open Pull Request \\#${pr.id}${ - Container.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...' + Container.instance.actionRunners.count('openPullRequest') == 1 ? ` on ${pr.provider.name}` : '...' }\n${GlyphChars.Dash.repeat(2)}\n${Strings.escapeMarkdown(pr.title).replace(/"/g, '\\"')}\n${ pr.state }, ${pr.formatDateFromNow()}")`; diff --git a/src/git/fsProvider.ts b/src/git/fsProvider.ts index 114d735..8fcfa64 100644 --- a/src/git/fsProvider.ts +++ b/src/git/fsProvider.ts @@ -33,7 +33,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable { private readonly _disposable: Disposable; private readonly _searchTreeMap = new Map>>(); - constructor() { + constructor(private readonly container: Container) { this._disposable = Disposable.from( workspace.registerFileSystemProvider(DocumentSchemes.GitLens, this, { isCaseSensitive: true, @@ -83,7 +83,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable { if (ref === GitRevision.deletedOrMissing) return emptyArray; - const buffer = await Container.git.getVersionedFileBuffer(repoPath, path, ref); + const buffer = await this.container.git.getVersionedFileBuffer(repoPath, path, ref); if (buffer === undefined) return emptyArray; return buffer; @@ -125,7 +125,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable { }; } - treeItem = await Container.git.getTreeFileForRevision(repoPath, path, ref); + treeItem = await this.container.git.getTreeFileForRevision(repoPath, path, ref); } if (treeItem === undefined) { @@ -154,7 +154,7 @@ export class GitFileSystemProvider implements FileSystemProvider, Disposable { private async createSearchTree(ref: string, repoPath: string) { const searchTree = TernarySearchTree.forPaths(); - const trees = await Container.git.getTreeForRevision(repoPath, ref); + const trees = await this.container.git.getTreeForRevision(repoPath, ref); // Add a fake root folder so that searches will work searchTree.set('~', { commitSha: '', path: '~', size: 0, type: 'tree' }); diff --git a/src/git/git.ts b/src/git/git.ts index 36c19b9..55a9f97 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -75,9 +75,9 @@ export interface GitCommandOptions extends RunOptions>(); export async function git(options: GitCommandOptions, ...args: any[]): Promise { - if (Container.vsls.isMaybeGuest) { + if (Container.instance.vsls.isMaybeGuest) { if (options.local !== true) { - const guest = await Container.vsls.guest(); + const guest = await Container.instance.vsls.guest(); if (guest !== undefined) { return guest.git(options, ...args); } @@ -1396,7 +1396,11 @@ export namespace Git { return git({ cwd: repoPath, errors: GitErrorHandling.Ignore }, 'show-ref', '--tags'); } - export function stash__apply(repoPath: string, stashName: string, deleteAfter: boolean) { + export function stash__apply( + repoPath: string, + stashName: string, + deleteAfter: boolean, + ): Promise { if (!stashName) return Promise.resolve(undefined); return git({ cwd: repoPath }, 'stash', deleteAfter ? 'pop' : 'apply', stashName); } diff --git a/src/git/gitService.ts b/src/git/gitService.ts index fd270dd..34d71fb 100644 --- a/src/git/gitService.ts +++ b/src/git/gitService.ts @@ -137,6 +137,7 @@ export class GitService implements Disposable { private readonly _disposable: Disposable; private readonly _repositoryTree: TernarySearchTree; private _repositoriesLoadingPromise: Promise | undefined; + private _repositoriesLoadingPromiseResolver: (() => void) | undefined; private readonly _branchesCache = new Map>(); private readonly _contributorsCache = new Map>(); @@ -148,10 +149,11 @@ export class GitService implements Disposable { private readonly _trackedCache = new Map>(); private readonly _userMapCache = new Map(); - constructor() { + constructor(private readonly container: Container) { this._repositoryTree = TernarySearchTree.forPaths(); this._disposable = Disposable.from( + container.onReady(this.onReady, this), window.onDidChangeWindowState(this.onWindowStateChanged, this), workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this), configuration.onDidChange(this.onConfigurationChanged, this), @@ -163,9 +165,10 @@ export class GitService implements Disposable { void this.updateContext(this._repositoryTree); }), ); - this.onConfigurationChanged(); - this._repositoriesLoadingPromise = this.onWorkspaceFoldersChanged(); + this._repositoriesLoadingPromise = new Promise(resolve => (this._repositoriesLoadingPromiseResolver = resolve)); + + this.onConfigurationChanged(); } dispose() { @@ -174,24 +177,16 @@ export class GitService implements Disposable { this._disposable.dispose(); } - @log() - static async initialize(): Promise { - // Try to use the same git as the built-in vscode git extension - let gitPath; - const gitApi = await GitService.getBuiltInGitApi(); - if (gitApi != null) { - gitPath = gitApi.git.path; - } - - await Git.setOrFindGitPath(gitPath ?? configuration.getAny('git.path')); + private onReady() { + this.onWorkspaceFoldersChanged().finally(() => this._repositoriesLoadingPromiseResolver!()); } get readonly() { - return Container.vsls.readonly; + return this.container.vsls.readonly; } get useCaching() { - return Container.config.advanced.caching.enabled; + return this.container.config.advanced.caching.enabled; } private onAnyRepositoryChanged(repo: Repository, e: RepositoryChangeEvent) { @@ -287,8 +282,8 @@ export class GitService implements Disposable { if (scheme !== DocumentSchemes.File && scheme !== DocumentSchemes.Vsls) continue; if (scheme === DocumentSchemes.Vsls) { - if (Container.vsls.isMaybeGuest) { - const guest = await Container.vsls.guest(); + if (this.container.vsls.isMaybeGuest) { + const guest = await this.container.vsls.guest(); if (guest != null) { const repositories = await guest.getRepositoriesInFolder( f, @@ -859,7 +854,7 @@ export class GitService implements Disposable { let repoPath; if (editor != null) { - const doc = await Container.tracker.getOrAdd(editor.document.uri); + const doc = await this.container.tracker.getOrAdd(editor.document.uri); if (doc != null) { repoPath = doc.uri.repoPath; } @@ -888,7 +883,7 @@ export class GitService implements Disposable { key += `:${uri.sha}`; } - const doc = await Container.tracker.getOrAdd(uri); + const doc = await this.container.tracker.getOrAdd(uri); if (this.useCaching) { if (doc.state != null) { const cachedBlame = doc.state.get(key); @@ -934,8 +929,8 @@ export class GitService implements Disposable { try { const data = await Git.blame(root, file, uri.sha, { - args: Container.config.advanced.blame.customArguments, - ignoreWhitespace: Container.config.blame.ignoreWhitespace, + args: this.container.config.advanced.blame.customArguments, + ignoreWhitespace: this.container.config.blame.ignoreWhitespace, }); const blame = GitBlameParser.parse(data, root, file, await this.getCurrentUser(root)); return blame; @@ -970,7 +965,7 @@ export class GitService implements Disposable { const key = `blame:${Strings.sha1(contents)}`; - const doc = await Container.tracker.getOrAdd(uri); + const doc = await this.container.tracker.getOrAdd(uri); if (this.useCaching) { if (doc.state != null) { const cachedBlame = doc.state.get(key); @@ -1017,9 +1012,9 @@ export class GitService implements Disposable { try { const data = await Git.blame__contents(root, file, contents, { - args: Container.config.advanced.blame.customArguments, + args: this.container.config.advanced.blame.customArguments, correlationKey: `:${key}`, - ignoreWhitespace: Container.config.blame.ignoreWhitespace, + ignoreWhitespace: this.container.config.blame.ignoreWhitespace, }); const blame = GitBlameParser.parse(data, root, file, await this.getCurrentUser(root)); return blame; @@ -1075,8 +1070,8 @@ export class GitService implements Disposable { try { const data = await Git.blame(uri.repoPath, fileName, uri.sha, { - args: Container.config.advanced.blame.customArguments, - ignoreWhitespace: Container.config.blame.ignoreWhitespace, + args: this.container.config.advanced.blame.customArguments, + ignoreWhitespace: this.container.config.blame.ignoreWhitespace, startLine: lineToBlame, endLine: lineToBlame, }); @@ -1130,8 +1125,8 @@ export class GitService implements Disposable { try { const data = await Git.blame__contents(uri.repoPath, fileName, contents, { - args: Container.config.advanced.blame.customArguments, - ignoreWhitespace: Container.config.blame.ignoreWhitespace, + args: this.container.config.advanced.blame.customArguments, + ignoreWhitespace: this.container.config.blame.ignoreWhitespace, startLine: lineToBlame, endLine: lineToBlame, }); @@ -1227,14 +1222,14 @@ export class GitService implements Disposable { let [branch] = await this.getBranches(repoPath, { filter: b => b.current }); if (branch != null) return branch; - const data = await Git.rev_parse__currentBranch(repoPath, Container.config.advanced.commitOrdering); + const data = await Git.rev_parse__currentBranch(repoPath, this.container.config.advanced.commitOrdering); if (data == null) return undefined; const [name, upstream] = data[0].split('\n'); if (GitBranch.isDetached(name)) { const [rebaseStatus, committerDate] = await Promise.all([ this.getRebaseStatus(repoPath), - Git.log__recent_committerdate(repoPath, Container.config.advanced.commitOrdering), + Git.log__recent_committerdate(repoPath, this.container.config.advanced.commitOrdering), ]); branch = new GitBranch( @@ -1316,13 +1311,13 @@ export class GitService implements Disposable { const data = await Git.rev_parse__currentBranch( repoPath!, - Container.config.advanced.commitOrdering, + this.container.config.advanced.commitOrdering, ); if (data != null) { const [name, upstream] = data[0].split('\n'); const [rebaseStatus, committerDate] = await Promise.all([ GitBranch.isDetached(name) ? this.getRebaseStatus(repoPath!) : undefined, - Git.log__recent_committerdate(repoPath!, Container.config.advanced.commitOrdering), + Git.log__recent_committerdate(repoPath!, this.container.config.advanced.commitOrdering), ]); current = new GitBranch( @@ -1537,7 +1532,7 @@ export class GitService implements Disposable { async getOldestUnpushedRefForFile(repoPath: string, fileName: string): Promise { const data = await Git.log__file(repoPath, fileName, '@{push}..', { format: 'refs', - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, renames: true, }); if (data == null || data.length === 0) return undefined; @@ -1690,7 +1685,7 @@ export class GitService implements Disposable { key += `:${ref2}`; } - const doc = await Container.tracker.getOrAdd(uri); + const doc = await this.container.tracker.getOrAdd(uri); if (this.useCaching) { if (doc.state != null) { const cachedDiff = doc.state.get(key); @@ -1748,7 +1743,7 @@ export class GitService implements Disposable { // let data; // if (ref2 == null && ref1 != null && !GitRevision.isUncommittedStaged(ref1)) { // data = await Git.show__diff(root, file, ref1, originalFileName, { - // similarityThreshold: Container.config.advanced.similarityThreshold, + // similarityThreshold: this.container.config.advanced.similarityThreshold, // }); // } else { const data = await Git.diff(root, file, ref1, ref2, { @@ -1756,7 +1751,7 @@ export class GitService implements Disposable { filters: ['M'], linesOfContext: 0, renames: true, - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); // } @@ -1796,7 +1791,7 @@ export class GitService implements Disposable { const key = `diff:${Strings.sha1(contents)}`; - const doc = await Container.tracker.getOrAdd(uri); + const doc = await this.container.tracker.getOrAdd(uri); if (this.useCaching) { if (doc.state != null) { const cachedDiff = doc.state.get(key); @@ -1854,7 +1849,7 @@ export class GitService implements Disposable { const data = await Git.diff__contents(root, file, ref, contents, { ...options, filters: ['M'], - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); const diff = GitDiffParser.parse(data); @@ -1909,7 +1904,7 @@ export class GitService implements Disposable { ): Promise { try { const data = await Git.diff__name_status(repoPath, ref1, ref2, { - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, ...options, }); const files = GitDiffParser.parseNameStatus(data, repoPath); @@ -1949,15 +1944,15 @@ export class GitService implements Disposable { since?: string; } = {}, ): Promise { - const limit = options.limit ?? Container.config.advanced.maxListItems ?? 0; + const limit = options.limit ?? this.container.config.advanced.maxListItems ?? 0; try { const data = await Git.log(repoPath, ref, { ...options, limit: limit, merges: options.merges == null ? true : options.merges, - ordering: options.ordering ?? Container.config.advanced.commitOrdering, - similarityThreshold: Container.config.advanced.similarityThreshold, + ordering: options.ordering ?? this.container.config.advanced.commitOrdering, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); const log = GitLogParser.parse( data, @@ -2001,7 +1996,7 @@ export class GitService implements Disposable { since?: string; } = {}, ): Promise | undefined> { - const limit = options.limit ?? Container.config.advanced.maxListItems ?? 0; + const limit = options.limit ?? this.container.config.advanced.maxListItems ?? 0; try { const data = await Git.log(repoPath, ref, { @@ -2010,9 +2005,9 @@ export class GitService implements Disposable { limit: limit, merges: options.merges == null ? true : options.merges, reverse: options.reverse, - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, since: options.since, - ordering: options.ordering ?? Container.config.advanced.commitOrdering, + ordering: options.ordering ?? this.container.config.advanced.commitOrdering, }); const commits = GitLogParser.parseRefsOnly(data); return new Set(commits); @@ -2040,7 +2035,7 @@ export class GitService implements Disposable { return log; } - moreLimit = moreLimit ?? Container.config.advanced.maxSearchItems ?? 0; + moreLimit = moreLimit ?? this.container.config.advanced.maxSearchItems ?? 0; // If the log is for a range, then just get everything prior + more if (GitRevision.isRange(log.sha)) { @@ -2102,8 +2097,8 @@ export class GitService implements Disposable { search = { matchAll: false, matchCase: false, matchRegex: true, ...search }; try { - const limit = options.limit ?? Container.config.advanced.maxSearchItems ?? 0; - const similarityThreshold = Container.config.advanced.similarityThreshold; + const limit = options.limit ?? this.container.config.advanced.maxSearchItems ?? 0; + const similarityThreshold = this.container.config.advanced.similarityThreshold; const operations = SearchPattern.parseSearchOperations(search.pattern); @@ -2175,7 +2170,7 @@ export class GitService implements Disposable { } const data = await Git.log__search(repoPath, args, { - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, ...options, limit: limit, useShow: useShow, @@ -2212,7 +2207,7 @@ export class GitService implements Disposable { options: { limit?: number; ordering?: string | null }, ): (limit: number | undefined) => Promise { return async (limit: number | undefined) => { - limit = limit ?? Container.config.advanced.maxSearchItems ?? 0; + limit = limit ?? this.container.config.advanced.maxSearchItems ?? 0; const moreLog = await this.getLogForSearch(log.repoPath, search, { ...options, @@ -2279,7 +2274,7 @@ export class GitService implements Disposable { options = { reverse: false, ...options }; if (options.renames == null) { - options.renames = Container.config.advanced.fileHistoryFollowsRenames; + options.renames = this.container.config.advanced.fileHistoryFollowsRenames; } let key = 'log'; @@ -2288,13 +2283,13 @@ export class GitService implements Disposable { } if (options.all == null) { - options.all = Container.config.advanced.fileHistoryShowAllBranches; + options.all = this.container.config.advanced.fileHistoryShowAllBranches; } if (options.all) { key += ':all'; } - options.limit = options.limit == null ? Container.config.advanced.maxListItems || 0 : options.limit; + options.limit = options.limit == null ? this.container.config.advanced.maxListItems || 0 : options.limit; if (options.limit) { key += `:n${options.limit}`; } @@ -2315,7 +2310,7 @@ export class GitService implements Disposable { key += `:skip${options.skip}`; } - const doc = await Container.tracker.getOrAdd(GitUri.fromFile(fileName, repoPath!, options.ref)); + const doc = await this.container.tracker.getOrAdd(GitUri.fromFile(fileName, repoPath!, options.ref)); if (this.useCaching && options.range == null) { if (doc.state != null) { const cachedLog = doc.state.get(key); @@ -2437,7 +2432,7 @@ export class GitService implements Disposable { } const data = await Git.log__file(root, file, ref, { - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, ...options, firstParent: options.renames, startLine: range == null ? undefined : range.start.line + 1, @@ -2506,7 +2501,7 @@ export class GitService implements Disposable { return log; } - moreLimit = moreLimit ?? Container.config.advanced.maxSearchItems ?? 0; + moreLimit = moreLimit ?? this.container.config.advanced.maxSearchItems ?? 0; const ref = Iterables.last(log.commits.values())?.ref; const moreLog = await this.getLogForFile(log.repoPath, fileName, { @@ -2768,7 +2763,7 @@ export class GitService implements Disposable { filters: filters, format: 'simple', limit: skip + 1, - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, reverse: true, // startLine: editorLine != null ? editorLine + 1 : undefined, }); @@ -2781,7 +2776,7 @@ export class GitService implements Disposable { filters: ['R', 'C'], format: 'simple', limit: 1, - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, // startLine: editorLine != null ? editorLine + 1 : undefined }); if (data == null || data.length === 0) { @@ -3020,7 +3015,7 @@ export class GitService implements Disposable { firstParent: firstParent, format: 'simple', limit: skip + 2, - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, startLine: editorLine != null ? editorLine + 1 : undefined, }); } catch (ex) { @@ -3035,7 +3030,7 @@ export class GitService implements Disposable { } ref = await Git.log__file_recent(repoPath, fileName, { - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, }); return GitUri.fromFile(fileName, repoPath, ref ?? GitRevision.deletedOrMissing); } @@ -3175,11 +3170,11 @@ export class GitService implements Disposable { ): Promise { const cc = Logger.getCorrelationContext(); - limit = limit ?? Container.config.advanced.maxListItems ?? 0; + limit = limit ?? this.container.config.advanced.maxListItems ?? 0; try { // Pass a much larger limit to reflog, because we aggregate the data and we won't know how many lines we'll need const data = await Git.reflog(repoPath, { - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, ...options, limit: limit * 100, }); @@ -3202,7 +3197,7 @@ export class GitService implements Disposable { options: { all?: boolean; branch?: string; limit?: number; ordering?: string | null; skip?: number }, ): (limit: number) => Promise { return async (limit: number | undefined) => { - limit = limit ?? Container.config.advanced.maxSearchItems ?? 0; + limit = limit ?? this.container.config.advanced.maxSearchItems ?? 0; const moreLog = await this.getIncomingActivity(reflog.repoPath, { ...options, @@ -3512,7 +3507,7 @@ export class GitService implements Disposable { @gate(() => '') private async ensureProperWorkspaceCasing(repoPath: string, filePath: string) { - if (Container.config.advanced.messages.suppressImproperWorkspaceCasingWarning) return; + if (this.container.config.advanced.messages.suppressImproperWorkspaceCasingWarning) return; filePath = filePath.replace(/\\/g, '/'); @@ -3633,7 +3628,7 @@ export class GitService implements Disposable { ): Repository | undefined { let repo = repositoryTree.findSubstr(path); // If we can't find the repo and we are a guest, check if we are a "root" workspace - if (repo == null && isVslsScheme !== false && Container.vsls.isMaybeGuest) { + if (repo == null && isVslsScheme !== false && this.container.vsls.isMaybeGuest) { if (!vslsUriPrefixRegex.test(path)) { path = Strings.normalizePath(path); const vslsPath = `/~0${path.startsWith(slash) ? path : `/${path}`}`; @@ -3670,7 +3665,7 @@ export class GitService implements Disposable { let stash = this.useCaching ? this._stashesCache.get(repoPath) : undefined; if (stash === undefined) { const data = await Git.stash__list(repoPath, { - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); stash = GitStashParser.parse(data, repoPath); @@ -3691,7 +3686,7 @@ export class GitService implements Disposable { const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1; const data = await Git.status__file(repoPath, fileName, porcelainVersion, { - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); const status = GitStatusParser.parse(data, repoPath, porcelainVersion); if (status == null || !status.files.length) return undefined; @@ -3704,7 +3699,7 @@ export class GitService implements Disposable { const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1; const data = await Git.status__file(repoPath, path, porcelainVersion, { - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); const status = GitStatusParser.parse(data, repoPath, porcelainVersion); if (status == null || !status.files.length) return []; @@ -3719,7 +3714,7 @@ export class GitService implements Disposable { const porcelainVersion = Git.validateVersion(2, 11) ? 2 : 1; const data = await Git.status(repoPath, porcelainVersion, { - similarityThreshold: Container.config.advanced.similarityThreshold, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); const status = GitStatusParser.parse(data, repoPath, porcelainVersion); @@ -3857,8 +3852,8 @@ export class GitService implements Disposable { // TODO: Add caching // Get the most recent commit for this file name ref = await Git.log__file_recent(repoPath, fileName, { - ordering: Container.config.advanced.commitOrdering, - similarityThreshold: Container.config.advanced.similarityThreshold, + ordering: this.container.config.advanced.commitOrdering, + similarityThreshold: this.container.config.advanced.similarityThreshold, }); if (ref == null) return undefined; @@ -3867,7 +3862,7 @@ export class GitService implements Disposable { filters: ['R', 'C', 'D'], format: 'simple', limit: 1, - ordering: Container.config.advanced.commitOrdering, + ordering: this.container.config.advanced.commitOrdering, }); if (data == null || data.length === 0) break; @@ -3937,7 +3932,7 @@ export class GitService implements Disposable { editor = editor ?? window.activeTextEditor; if (editor == null) return false; - const doc = await Container.tracker.getOrAdd(editor.document.uri); + const doc = await this.container.tracker.getOrAdd(editor.document.uri); return repoPath === doc?.uri.repoPath; } @@ -4053,7 +4048,7 @@ export class GitService implements Disposable { if (!options.tool) { const cc = Logger.getCorrelationContext(); - options.tool = Container.config.advanced.externalDiffTool || (await this.getDiffTool(repoPath)); + options.tool = this.container.config.advanced.externalDiffTool || (await this.getDiffTool(repoPath)); if (options.tool == null) throw new Error('No diff tool found'); Logger.log(cc, `Using tool=${options.tool}`); @@ -4089,7 +4084,7 @@ export class GitService implements Disposable { if (!tool) { const cc = Logger.getCorrelationContext(); - tool = Container.config.advanced.externalDirectoryDiffTool || (await this.getDiffTool(repoPath)); + tool = this.container.config.advanced.externalDirectoryDiffTool || (await this.getDiffTool(repoPath)); if (tool == null) throw new Error('No diff tool found'); Logger.log(cc, `Using tool=${tool}`); @@ -4154,7 +4149,7 @@ export class GitService implements Disposable { repoPath, blob, ref, - Container.config.advanced.commitOrdering, + this.container.config.advanced.commitOrdering, fileName, ); if (options?.timeout != null) { @@ -4165,7 +4160,7 @@ export class GitService implements Disposable { } @log() - validateBranchOrTagName(ref: string, repoPath?: string): Promise { + validateBranchOrTagName(repoPath: string, ref: string): Promise { return Git.check_ref_format(ref, repoPath); } diff --git a/src/git/gitUri.ts b/src/git/gitUri.ts index 3b2fb89..4aea930 100644 --- a/src/git/gitUri.ts +++ b/src/git/gitUri.ts @@ -215,7 +215,7 @@ export class GitUri extends (Uri as any as UriEx) { static file(path: string, useVslsScheme?: boolean) { const uri = Uri.file(path); - if (Container.vsls.isMaybeGuest && useVslsScheme !== false) { + if (Container.instance.vsls.isMaybeGuest && useVslsScheme !== false) { return uri.with({ scheme: DocumentSchemes.Vsls }); } @@ -257,7 +257,7 @@ export class GitUri extends (Uri as any as UriEx) { static async fromUri(uri: Uri): Promise { if (GitUri.is(uri)) return uri; - if (!Container.git.isTrackable(uri)) return new GitUri(uri); + if (!Container.instance.git.isTrackable(uri)) return new GitUri(uri); if (uri.scheme === DocumentSchemes.GitLens) return new GitUri(uri); @@ -266,7 +266,7 @@ export class GitUri extends (Uri as any as UriEx) { try { const data: { path: string; ref: string } = JSON.parse(uri.query); - const repoPath = await Container.git.getRepoPath(data.path); + const repoPath = await Container.instance.git.getRepoPath(data.path); let ref; switch (data.ref) { @@ -309,7 +309,7 @@ export class GitUri extends (Uri as any as UriEx) { if (repoPath.endsWith(data.fileName)) { repoPath = repoPath.substr(0, repoPath.length - data.fileName.length - 1); } else { - repoPath = (await Container.git.getRepoPath(uri.fsPath))!; + repoPath = (await Container.instance.git.getRepoPath(uri.fsPath))!; } const commitish: GitCommitish = { @@ -321,7 +321,7 @@ export class GitUri extends (Uri as any as UriEx) { } catch {} } - return new GitUri(uri, await Container.git.getRepoPath(uri)); + return new GitUri(uri, await Container.instance.git.getRepoPath(uri)); } static getDirectory(fileName: string, relativeTo?: string): string { diff --git a/src/git/models/branch.ts b/src/git/models/branch.ts index 5a9f937..5aea521 100644 --- a/src/git/models/branch.ts +++ b/src/git/models/branch.ts @@ -180,7 +180,7 @@ export class GitBranch implements GitBranchReference { const remote = await this.getRemote(); if (remote == null) return undefined; - return Container.git.getPullRequestForBranch(this.getNameWithoutRemote(), remote, options); + return Container.instance.git.getPullRequestForBranch(this.getNameWithoutRemote(), remote, options); } @memoize() @@ -205,7 +205,7 @@ export class GitBranch implements GitBranchReference { const remoteName = this.getRemoteName(); if (remoteName == null) return undefined; - const remotes = await Container.git.getRemotes(this.repoPath); + const remotes = await Container.instance.git.getRemotes(this.repoPath); if (remotes.length === 0) return undefined; return remotes.find(r => r.name === remoteName); @@ -231,7 +231,7 @@ export class GitBranch implements GitBranchReference { return GitBranchStatus.UpToDate; } - const remotes = await Container.git.getRemotes(this.repoPath); + const remotes = await Container.instance.git.getRemotes(this.repoPath); if (remotes.length > 0) return GitBranchStatus.Unpublished; return GitBranchStatus.Local; @@ -250,16 +250,16 @@ export class GitBranch implements GitBranchReference { } get starred() { - const starred = Container.context.workspaceState.get(WorkspaceState.StarredBranches); + const starred = Container.instance.context.workspaceState.get(WorkspaceState.StarredBranches); return starred !== undefined && starred[this.id] === true; } async star() { - await (await Container.git.getRepository(this.repoPath))?.star(this); + await (await Container.instance.git.getRepository(this.repoPath))?.star(this); } async unstar() { - await (await Container.git.getRepository(this.repoPath))?.unstar(this); + await (await Container.instance.git.getRepository(this.repoPath))?.unstar(this); } static formatDetached(sha: string): string { diff --git a/src/git/models/commit.ts b/src/git/models/commit.ts index f527b2e..45c4500 100644 --- a/src/git/models/commit.ts +++ b/src/git/models/commit.ts @@ -148,10 +148,10 @@ export abstract class GitCommit implements GitRevisionReference { @memoize() async getAssociatedPullRequest(options?: { timeout?: number }): Promise { - const remote = await Container.git.getRichRemoteProvider(this.repoPath); + const remote = await Container.instance.git.getRichRemoteProvider(this.repoPath); if (remote?.provider == null) return undefined; - return Container.git.getPullRequestForCommit(this.ref, remote, options); + return Container.instance.git.getPullRequestForCommit(this.ref, remote, options); } @memoize( @@ -160,14 +160,14 @@ export abstract class GitCommit implements GitRevisionReference { getPreviousLineDiffUris(uri: Uri, editorLine: number, ref: string | undefined) { if (!this.isFile) return Promise.resolve(undefined); - return Container.git.getPreviousLineDiffUris(this.repoPath, uri, editorLine, ref); + return Container.instance.git.getPreviousLineDiffUris(this.repoPath, uri, editorLine, ref); } @memoize() getWorkingUri(): Promise { if (!this.isFile) return Promise.resolve(undefined); - return Container.git.getWorkingUri(this.repoPath, this.uri); + return Container.instance.git.getWorkingUri(this.repoPath, this.uri); } @memoize() diff --git a/src/git/models/models.ts b/src/git/models/models.ts index e807331..a69dcf1 100644 --- a/src/git/models/models.ts +++ b/src/git/models/models.ts @@ -77,7 +77,7 @@ export namespace GitRevision { if (!force && !isShaLike(ref)) return ref; // Don't allow shas to be shortened to less than 5 characters - const len = Math.max(5, Container.config.advanced.abbreviatedShaLength); + const len = Math.max(5, Container.instance.config.advanced.abbreviatedShaLength); // If we have a suffix, append it const match = shaShortenRegex.exec(ref); diff --git a/src/git/models/remote.ts b/src/git/models/remote.ts index 0a27476..b5b3215 100644 --- a/src/git/models/remote.ts +++ b/src/git/models/remote.ts @@ -59,7 +59,7 @@ export class GitRemote(WorkspaceState.DefaultRemote); + const defaultRemote = Container.instance.context.workspaceState.get(WorkspaceState.DefaultRemote); return this.id === defaultRemote; } @@ -79,12 +79,15 @@ export class GitRemote { - return Container.git.getBranches(this.path, options); + return Container.instance.git.getBranches(this.path, options); } getBranchesAndOrTags( @@ -561,19 +565,19 @@ export class Repository implements Disposable { sort?: boolean | { branches?: BranchSortOptions; tags?: TagSortOptions }; } = {}, ) { - return Container.git.getBranchesAndOrTags(this.path, options); + return Container.instance.git.getBranchesAndOrTags(this.path, options); } getChangedFilesCount(sha?: string): Promise { - return Container.git.getChangedFilesCount(this.path, sha); + return Container.instance.git.getChangedFilesCount(this.path, sha); } getCommit(ref: string): Promise { - return Container.git.getCommit(this.path, ref); + return Container.instance.git.getCommit(this.path, ref); } getContributors(options?: { all?: boolean; ref?: string; stats?: boolean }): Promise { - return Container.git.getContributors(this.path, options); + return Container.instance.git.getContributors(this.path, options); } private _lastFetched: number | undefined; @@ -581,7 +585,7 @@ export class Repository implements Disposable { async getLastFetched(): Promise { if (this._lastFetched == null) { const hasRemotes = await this.hasRemotes(); - if (!hasRemotes || Container.vsls.isMaybeGuest) return 0; + if (!hasRemotes || Container.instance.vsls.isMaybeGuest) return 0; } try { @@ -598,11 +602,11 @@ export class Repository implements Disposable { } getMergeStatus(): Promise { - return Container.git.getMergeStatus(this.path); + return Container.instance.git.getMergeStatus(this.path); } getRebaseStatus(): Promise { - return Container.git.getRebaseStatus(this.path); + return Container.instance.git.getRebaseStatus(this.path); } async getRemote(remote: string): Promise { @@ -617,7 +621,7 @@ export class Repository implements Disposable { } // Since we are caching the results, always sort - this._remotes = Container.git.getRemotesCore(this.path, this._providers, { sort: true }); + this._remotes = Container.instance.git.getRemotesCore(this.path, this._providers, { sort: true }); void this.subscribeToRemotes(this._remotes); } @@ -625,7 +629,9 @@ export class Repository implements Disposable { } async getRichRemote(connectedOnly: boolean = false): Promise | undefined> { - return Container.git.getRichRemoteProvider(await this.getRemotes(), { includeDisconnected: !connectedOnly }); + return Container.instance.git.getRichRemoteProvider(await this.getRemotes(), { + includeDisconnected: !connectedOnly, + }); } private async subscribeToRemotes(remotes: Promise) { @@ -642,15 +648,15 @@ export class Repository implements Disposable { } getStash(): Promise { - return Container.git.getStash(this.path); + return Container.instance.git.getStash(this.path); } getStatus(): Promise { - return Container.git.getStatusForRepo(this.path); + return Container.instance.git.getStatusForRepo(this.path); } getTags(options?: { filter?: (t: GitTag) => boolean; sort?: boolean | TagSortOptions }): Promise { - return Container.git.getTags(this.path, options); + return Container.instance.git.getTags(this.path, options); } async hasRemotes(): Promise { @@ -698,7 +704,7 @@ export class Repository implements Disposable { this.path, )); } else if (configuration.getAny(BuiltInGitConfiguration.FetchOnPull, Uri.file(this.path))) { - void (await Container.git.fetch(this.path)); + void (await Container.instance.git.fetch(this.path)); } this.fireChange(RepositoryChange.Unknown); @@ -735,7 +741,7 @@ export class Repository implements Disposable { } private async showCreatePullRequestPrompt(remoteName: string, branch: GitBranchReference) { - if (!Container.actionRunners.count('createPullRequest')) return; + if (!Container.instance.actionRunners.count('createPullRequest')) return; if (!(await Messages.showCreatePullRequestPrompt(branch.name))) return; const remote = await this.getRemote(remoteName); @@ -871,11 +877,11 @@ export class Repository implements Disposable { search: SearchPattern, options: { limit?: number; skip?: number } = {}, ): Promise { - return Container.git.getLogForSearch(this.path, search, options); + return Container.instance.git.getLogForSearch(this.path, search, options); } get starred() { - const starred = Container.context.workspaceState.get(WorkspaceState.StarredRepositories); + const starred = Container.instance.context.workspaceState.get(WorkspaceState.StarredRepositories); return starred != null && starred[this.id] === true; } @@ -886,7 +892,7 @@ export class Repository implements Disposable { @gate(() => '') @log() async stashApply(stashName: string, options: { deleteAfter?: boolean } = {}) { - void (await Container.git.stashApply(this.path, stashName, options)); + void (await Container.instance.git.stashApply(this.path, stashName, options)); this.fireChange(RepositoryChange.Stash); } @@ -894,7 +900,7 @@ export class Repository implements Disposable { @gate(() => '') @log() async stashDelete(stashName: string, ref?: string) { - void (await Container.git.stashDelete(this.path, stashName, ref)); + void (await Container.instance.git.stashDelete(this.path, stashName, ref)); this.fireChange(RepositoryChange.Stash); } @@ -902,7 +908,7 @@ export class Repository implements Disposable { @gate(() => '') @log() async stashSave(message?: string, uris?: Uri[], options: { includeUntracked?: boolean; keepIndex?: boolean } = {}) { - void (await Container.git.stashSave(this.path, message, uris, options)); + void (await Container.instance.git.stashSave(this.path, message, uris, options)); this.fireChange(RepositoryChange.Stash); } @@ -925,7 +931,7 @@ export class Repository implements Disposable { private async switchCore(ref: string, options: { createBranch?: string } = {}) { try { - void (await Container.git.checkout(this.path, ref, options)); + void (await Container.instance.git.checkout(this.path, ref, options)); this.fireChange(RepositoryChange.Unknown); } catch (ex) { @@ -954,7 +960,7 @@ export class Repository implements Disposable { } private async updateStarredCore(key: WorkspaceState, id: string, star: boolean) { - let starred = Container.context.workspaceState.get(key); + let starred = Container.instance.context.workspaceState.get(key); if (starred === undefined) { starred = Object.create(null) as Starred; } @@ -965,7 +971,7 @@ export class Repository implements Disposable { const { [id]: _, ...rest } = starred; starred = rest; } - await Container.context.workspaceState.update(key, starred); + await Container.instance.context.workspaceState.update(key, starred); this.fireChange(RepositoryChange.Starred); } @@ -1081,7 +1087,7 @@ export class Repository implements Disposable { this._pendingFileSystemChange = undefined; - const uris = await Container.git.excludeIgnoredUris(this.path, e.uris); + const uris = await Container.instance.git.excludeIgnoredUris(this.path, e.uris); if (uris.length === 0) return; if (uris.length !== e.uris.length) { diff --git a/src/git/models/stashCommit.ts b/src/git/models/stashCommit.ts index 6130913..53825af 100644 --- a/src/git/models/stashCommit.ts +++ b/src/git/models/stashCommit.ts @@ -58,7 +58,7 @@ export class GitStashCommit extends GitLogCommit { // Check for any untracked files -- since git doesn't return them via `git stash list` :( // See https://stackoverflow.com/questions/12681529/ - const commit = await Container.git.getCommit(this.repoPath, `${this.stashName}^3`); + const commit = await Container.instance.git.getCommit(this.repoPath, `${this.stashName}^3`); if (commit != null && commit.files.length !== 0) { // Since these files are untracked -- make them look that way const files = commit.files.map(s => ({ diff --git a/src/git/models/status.ts b/src/git/models/status.ts index a2209e4..9bd7cf6 100644 --- a/src/git/models/status.ts +++ b/src/git/models/status.ts @@ -234,7 +234,7 @@ export class GitStatus { async getRemote(): Promise { if (this.upstream == null) return undefined; - const remotes = await Container.git.getRemotes(this.repoPath); + const remotes = await Container.instance.git.getRemotes(this.repoPath); if (remotes.length === 0) return undefined; const remoteName = GitBranch.getRemote(this.upstream); diff --git a/src/git/remotes/github.ts b/src/git/remotes/github.ts index 63a1528..63cfc2d 100644 --- a/src/git/remotes/github.ts +++ b/src/git/remotes/github.ts @@ -188,7 +188,7 @@ export class GitHubRemote extends RichRemoteProvider { }, ): Promise { const [owner, repo] = this.splitPath(); - return (await Container.github)?.getAccountForCommit(this, accessToken, owner, repo, ref, { + return (await Container.instance.github)?.getAccountForCommit(this, accessToken, owner, repo, ref, { ...options, baseUrl: this.apiBaseUrl, }); @@ -202,7 +202,7 @@ export class GitHubRemote extends RichRemoteProvider { }, ): Promise { const [owner, repo] = this.splitPath(); - return (await Container.github)?.getAccountForEmail(this, accessToken, owner, repo, email, { + return (await Container.instance.github)?.getAccountForEmail(this, accessToken, owner, repo, email, { ...options, baseUrl: this.apiBaseUrl, }); @@ -212,7 +212,7 @@ export class GitHubRemote extends RichRemoteProvider { accessToken, }: AuthenticationSession): Promise { const [owner, repo] = this.splitPath(); - return (await Container.github)?.getDefaultBranch(this, accessToken, owner, repo, { + return (await Container.instance.github)?.getDefaultBranch(this, accessToken, owner, repo, { baseUrl: this.apiBaseUrl, }); } @@ -221,7 +221,7 @@ export class GitHubRemote extends RichRemoteProvider { id: string, ): Promise { const [owner, repo] = this.splitPath(); - return (await Container.github)?.getIssueOrPullRequest(this, accessToken, owner, repo, Number(id), { + return (await Container.instance.github)?.getIssueOrPullRequest(this, accessToken, owner, repo, Number(id), { baseUrl: this.apiBaseUrl, }); } @@ -237,7 +237,7 @@ export class GitHubRemote extends RichRemoteProvider { const [owner, repo] = this.splitPath(); const { include, ...opts } = options ?? {}; - return (await Container.github)?.getPullRequestForBranch(this, accessToken, owner, repo, branch, { + return (await Container.instance.github)?.getPullRequestForBranch(this, accessToken, owner, repo, branch, { ...opts, include: include?.map(s => GitHubPullRequest.toState(s)), baseUrl: this.apiBaseUrl, @@ -249,7 +249,7 @@ export class GitHubRemote extends RichRemoteProvider { ref: string, ): Promise { const [owner, repo] = this.splitPath(); - return (await Container.github)?.getPullRequestForCommit(this, accessToken, owner, repo, ref, { + return (await Container.instance.github)?.getPullRequestForCommit(this, accessToken, owner, repo, ref, { baseUrl: this.apiBaseUrl, }); } diff --git a/src/git/remotes/provider.ts b/src/git/remotes/provider.ts index f468e32..b7c4d07 100644 --- a/src/git/remotes/provider.ts +++ b/src/git/remotes/provider.ts @@ -281,7 +281,7 @@ export abstract class RichRemoteProvider extends RemoteProvider { constructor(domain: string, path: string, protocol?: string, name?: string, custom?: boolean) { super(domain, path, protocol, name, custom); - Container.context.subscriptions.push( + Container.instance.context.subscriptions.push( // TODO@eamodio revisit how connections are linked or not Authentication.onDidChange(e => { if (e.key !== this.key) return; @@ -346,7 +346,7 @@ export abstract class RichRemoteProvider extends RemoteProvider { this._session = null; if (disconnected) { - void Container.context.workspaceState.update(this.connectedKey, false); + void Container.instance.context.workspaceState.update(this.connectedKey, false); this._onDidChange.fire(); if (!silent) { @@ -570,11 +570,11 @@ export abstract class RichRemoteProvider extends RemoteProvider { private async ensureSession(createIfNeeded: boolean): Promise { if (this._session != null) return this._session; - if (!Container.config.integrations.enabled) return undefined; + if (!Container.instance.config.integrations.enabled) return undefined; if (createIfNeeded) { - await Container.context.workspaceState.update(this.connectedKey, undefined); - } else if (Container.context.workspaceState.get(this.connectedKey) === false) { + await Container.instance.context.workspaceState.update(this.connectedKey, undefined); + } else if (Container.instance.context.workspaceState.get(this.connectedKey) === false) { return undefined; } @@ -584,7 +584,7 @@ export abstract class RichRemoteProvider extends RemoteProvider { createIfNone: createIfNeeded, }); } catch (ex) { - await Container.context.workspaceState.update(this.connectedKey, undefined); + await Container.instance.context.workspaceState.update(this.connectedKey, undefined); if (ex instanceof Error && ex.message.includes('User did not consent')) { return undefined; @@ -594,14 +594,14 @@ export abstract class RichRemoteProvider extends RemoteProvider { } if (session === undefined && !createIfNeeded) { - await Container.context.workspaceState.update(this.connectedKey, undefined); + await Container.instance.context.workspaceState.update(this.connectedKey, undefined); } this._session = session ?? null; this.invalidClientExceptionCount = 0; if (session != null) { - await Container.context.workspaceState.update(this.connectedKey, true); + await Container.instance.context.workspaceState.update(this.connectedKey, true); this._onDidChange.fire(); _onDidChangeAuthentication.fire({ reason: 'connected', key: this.key }); diff --git a/src/hovers/hovers.ts b/src/hovers/hovers.ts index ea8697b..d506691 100644 --- a/src/hovers/hovers.ts +++ b/src/hovers/hovers.ts @@ -50,11 +50,11 @@ export namespace Hovers { editorLine = commitLine.line - 1; // TODO: Doesn't work with dirty files -- pass in editor? or contents? - hunkLine = await Container.git.getDiffForLine(uri, editorLine, ref, documentRef, originalFileName); + hunkLine = await Container.instance.git.getDiffForLine(uri, editorLine, ref, documentRef, originalFileName); // If we didn't find a diff & ref is undefined (meaning uncommitted), check for a staged diff if (hunkLine == null && ref == null) { - hunkLine = await Container.git.getDiffForLine( + hunkLine = await Container.instance.git.getDiffForLine( uri, editorLine, undefined, @@ -200,7 +200,7 @@ export namespace Hovers { dateFormat = 'MMMM Do, YYYY h:mma'; } - const remotes = await Container.git.getRemotes(commit.repoPath, { sort: true }); + const remotes = await Container.instance.git.getRemotes(commit.repoPath, { sort: true }); const [previousLineDiffUris, autolinkedIssuesOrPullRequests, pr, presence] = await Promise.all([ commit.isUncommitted ? commit.getPreviousLineDiffUris(uri, editorLine, uri.sha) : undefined, @@ -218,7 +218,7 @@ export namespace Hovers { 'pullRequestState', ), }), - Container.vsls.maybeGetPresence(commit.email), + Container.instance.vsls.maybeGetPresence(commit.email), ]); const details = await CommitFormatter.fromTemplateAsync(format, commit, { @@ -247,7 +247,7 @@ export namespace Hovers { } function getDiffFromHunkLine(hunkLine: GitDiffHunkLine, diffStyle?: 'line' | 'hunk'): string { - if (diffStyle === 'hunk' || (diffStyle == null && Container.config.hovers.changesDiff === 'hunk')) { + if (diffStyle === 'hunk' || (diffStyle == null && Container.instance.config.hovers.changesDiff === 'hunk')) { return getDiffFromHunk(hunkLine.hunk); } @@ -263,16 +263,16 @@ export namespace Hovers { const start = process.hrtime(); if ( - !Container.config.hovers.autolinks.enabled || - !Container.config.hovers.autolinks.enhanced || - !CommitFormatter.has(Container.config.hovers.detailsMarkdownFormat, 'message') + !Container.instance.config.hovers.autolinks.enabled || + !Container.instance.config.hovers.autolinks.enhanced || + !CommitFormatter.has(Container.instance.config.hovers.detailsMarkdownFormat, 'message') ) { Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`); return undefined; } - const remote = await Container.git.getRichRemoteProvider(remotes); + const remote = await Container.instance.git.getRichRemoteProvider(remotes); if (remote?.provider == null) { Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`); @@ -283,7 +283,7 @@ export namespace Hovers { const timeout = 250; try { - const autolinks = await Container.autolinks.getIssueOrPullRequestLinks(message, remote, { + const autolinks = await Container.instance.autolinks.getIssueOrPullRequestLinks(message, remote, { timeout: timeout, }); @@ -347,7 +347,7 @@ export namespace Hovers { return undefined; } - const remote = await Container.git.getRichRemoteProvider(remotes, { includeDisconnected: true }); + const remote = await Container.instance.git.getRichRemoteProvider(remotes, { includeDisconnected: true }); if (remote?.provider == null) { Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`); @@ -363,7 +363,7 @@ export namespace Hovers { } try { - const pr = await Container.git.getPullRequestForCommit(ref, provider, { timeout: 250 }); + const pr = await Container.instance.git.getPullRequestForCommit(ref, provider, { timeout: 250 }); Logger.debug(cc, `completed ${GlyphChars.Dot} ${Strings.getDurationMilliseconds(start)} ms`); diff --git a/src/hovers/lineHoverController.ts b/src/hovers/lineHoverController.ts index 3b47bf6..f5e2380 100644 --- a/src/hovers/lineHoverController.ts +++ b/src/hovers/lineHoverController.ts @@ -24,32 +24,38 @@ export class LineHoverController implements Disposable { private _hoverProviderDisposable: Disposable | undefined; private _uri: Uri | undefined; - constructor() { - this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); - this.onConfigurationChanged(); + constructor(private readonly container: Container) { + this._disposable = Disposable.from( + container.onReady(this.onReady, this), + configuration.onDidChange(this.onConfigurationChanged, this), + ); } dispose() { this.unregister(); - Container.lineTracker.stop(this); + this.container.lineTracker.stop(this); this._disposable.dispose(); } + private onReady(): void { + this.onConfigurationChanged(); + } + private onConfigurationChanged(e?: ConfigurationChangeEvent) { if (!configuration.changed(e, 'hovers.enabled') && !configuration.changed(e, 'hovers.currentLine.enabled')) { return; } - if (Container.config.hovers.enabled && Container.config.hovers.currentLine.enabled) { - Container.lineTracker.start( + if (this.container.config.hovers.enabled && this.container.config.hovers.currentLine.enabled) { + this.container.lineTracker.start( this, - Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this), + this.container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this), ); this.register(window.activeTextEditor); } else { - Container.lineTracker.stop(this); + this.container.lineTracker.stop(this); this.unregister(); } } @@ -88,21 +94,21 @@ export class LineHoverController implements Disposable { position: Position, _token: CancellationToken, ): Promise { - if (!Container.lineTracker.includes(position.line)) return undefined; + if (!this.container.lineTracker.includes(position.line)) return undefined; - const lineState = Container.lineTracker.getState(position.line); + const lineState = this.container.lineTracker.getState(position.line); const commit = lineState?.commit; if (commit == null) return undefined; // Avoid double annotations if we are showing the whole-file hover blame annotations - if (Container.config.hovers.annotations.details) { - const fileAnnotations = await Container.fileAnnotations.getAnnotationType(window.activeTextEditor); + if (this.container.config.hovers.annotations.details) { + const fileAnnotations = await this.container.fileAnnotations.getAnnotationType(window.activeTextEditor); if (fileAnnotations === FileAnnotationType.Blame) return undefined; } - const wholeLine = Container.config.hovers.currentLine.over === 'line'; + const wholeLine = this.container.config.hovers.currentLine.over === 'line'; // If we aren't showing the hover over the whole line, make sure the annotation is on - if (!wholeLine && Container.lineAnnotations.suspended) return undefined; + if (!wholeLine && this.container.lineAnnotations.suspended) return undefined; const range = document.validateRange( new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER), @@ -112,7 +118,7 @@ export class LineHoverController implements Disposable { // Get the full commit message -- since blame only returns the summary let logCommit = lineState?.logCommit; if (logCommit == null && !commit.isUncommitted) { - logCommit = await Container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, { + logCommit = await this.container.git.getCommitForFile(commit.repoPath, commit.uri.fsPath, { ref: commit.sha, }); if (logCommit != null) { @@ -131,19 +137,19 @@ export class LineHoverController implements Disposable { const commitLine = commit.lines.find(l => l.line === line) ?? commit.lines[0]; editorLine = commitLine.originalLine - 1; - const trackedDocument = await Container.tracker.get(document); + const trackedDocument = await this.container.tracker.get(document); if (trackedDocument == null) return undefined; const message = await Hovers.detailsMessage( logCommit ?? commit, trackedDocument.uri, editorLine, - Container.config.hovers.detailsMarkdownFormat, - Container.config.defaultDateFormat, + this.container.config.hovers.detailsMarkdownFormat, + this.container.config.defaultDateFormat, { - autolinks: Container.config.hovers.autolinks.enabled, + autolinks: this.container.config.hovers.autolinks.enabled, pullRequests: { - enabled: Container.config.hovers.pullRequests.enabled, + enabled: this.container.config.hovers.pullRequests.enabled, }, }, ); @@ -162,28 +168,28 @@ export class LineHoverController implements Disposable { position: Position, _token: CancellationToken, ): Promise { - if (!Container.lineTracker.includes(position.line)) return undefined; + if (!this.container.lineTracker.includes(position.line)) return undefined; - const lineState = Container.lineTracker.getState(position.line); + const lineState = this.container.lineTracker.getState(position.line); const commit = lineState?.commit; if (commit == null) return undefined; // Avoid double annotations if we are showing the whole-file hover blame annotations - if (Container.config.hovers.annotations.changes) { - const fileAnnotations = await Container.fileAnnotations.getAnnotationType(window.activeTextEditor); + if (this.container.config.hovers.annotations.changes) { + const fileAnnotations = await this.container.fileAnnotations.getAnnotationType(window.activeTextEditor); if (fileAnnotations === FileAnnotationType.Blame) return undefined; } - const wholeLine = Container.config.hovers.currentLine.over === 'line'; + const wholeLine = this.container.config.hovers.currentLine.over === 'line'; // If we aren't showing the hover over the whole line, make sure the annotation is on - if (!wholeLine && Container.lineAnnotations.suspended) return undefined; + if (!wholeLine && this.container.lineAnnotations.suspended) return undefined; const range = document.validateRange( new Range(position.line, wholeLine ? 0 : Number.MAX_SAFE_INTEGER, position.line, Number.MAX_SAFE_INTEGER), ); if (!wholeLine && range.start.character !== position.character) return undefined; - const trackedDocument = await Container.tracker.get(document); + const trackedDocument = await this.container.tracker.get(document); if (trackedDocument == null) return undefined; const message = await Hovers.changesMessage(commit, trackedDocument.uri, position.line); @@ -201,7 +207,7 @@ export class LineHoverController implements Disposable { if (editor == null) return; - const cfg = Container.config.hovers; + const cfg = this.container.config.hovers; if (!cfg.enabled || !cfg.currentLine.enabled || (!cfg.currentLine.details && !cfg.currentLine.changes)) return; this._uri = editor.document.uri; diff --git a/src/partners.ts b/src/partners.ts index 0bd4915..4fc58ce 100644 --- a/src/partners.ts +++ b/src/partners.ts @@ -48,33 +48,37 @@ export function registerPartnerActionRunners(context: ExtensionContext): void { function registerLiveShare(context: ExtensionContext) { context.subscriptions.push( - Container.actionRunners.registerBuiltInPartner('liveshare', 'hover.commands', { - name: 'Live Share', - label: (context: ActionContext) => { - if (context.type === 'hover.commands') { - if (context.commit.author.name !== 'You') { - return `$(live-share) Invite ${context.commit.author.name}${ - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - context.commit.author.presence?.statusText - ? ` (${context.commit.author.presence?.statusText})` - : '' - } to a Live Share Session`; + Container.instance.actionRunners.registerBuiltInPartner( + 'liveshare', + 'hover.commands', + { + name: 'Live Share', + label: (context: ActionContext) => { + if (context.type === 'hover.commands') { + if (context.commit.author.name !== 'You') { + return `$(live-share) Invite ${context.commit.author.name}${ + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + context.commit.author.presence?.statusText + ? ` (${context.commit.author.presence?.statusText})` + : '' + } to a Live Share Session`; + } } - } - return '$(live-share) Start a Live Share Session'; - }, - run: async (context: ActionContext) => { - if (context.type !== 'hover.commands' || context.commit.author.name === 'You') { - await executeCommand(Commands.InviteToLiveShare, {}); + return '$(live-share) Start a Live Share Session'; + }, + run: async (context: ActionContext) => { + if (context.type !== 'hover.commands' || context.commit.author.name === 'You') { + await executeCommand(Commands.InviteToLiveShare, {}); - return; - } + return; + } - await executeCommand(Commands.InviteToLiveShare, { - email: context.commit.author.email, - }); + await executeCommand(Commands.InviteToLiveShare, { + email: context.commit.author.email, + }); + }, }, - }), + ), ); } diff --git a/src/quickpicks/commitPicker.ts b/src/quickpicks/commitPicker.ts index 2335d69..292592c 100644 --- a/src/quickpicks/commitPicker.ts +++ b/src/quickpicks/commitPicker.ts @@ -100,7 +100,7 @@ export namespace CommitPicker { let scope: KeyboardScope | undefined; if (options?.keys != null && options.keys.length !== 0 && options?.onDidPressKey !== null) { - scope = Container.keyboard.createScope( + scope = Container.instance.keyboard.createScope( Object.fromEntries( options.keys.map(key => [ key, diff --git a/src/quickpicks/commitQuickPickItems.ts b/src/quickpicks/commitQuickPickItems.ts index 06a644e..7fa78e6 100644 --- a/src/quickpicks/commitQuickPickItems.ts +++ b/src/quickpicks/commitQuickPickItems.ts @@ -101,7 +101,7 @@ export class CommitCompareWithHEADCommandQuickPickItem extends CommandQuickPickI } override execute(_options: { preserveFocus?: boolean; preview?: boolean }): Promise { - return Container.searchAndCompareView.compare(this.commit.repoPath, this.commit.ref, 'HEAD'); + return Container.instance.searchAndCompareView.compare(this.commit.repoPath, this.commit.ref, 'HEAD'); } } @@ -111,7 +111,7 @@ export class CommitCompareWithWorkingCommandQuickPickItem extends CommandQuickPi } override execute(_options: { preserveFocus?: boolean; preview?: boolean }): Promise { - return Container.searchAndCompareView.compare(this.commit.repoPath, this.commit.ref, ''); + return Container.instance.searchAndCompareView.compare(this.commit.repoPath, this.commit.ref, ''); } } diff --git a/src/quickpicks/modePicker.ts b/src/quickpicks/modePicker.ts index 1bfa6f2..c6dbc64 100644 --- a/src/quickpicks/modePicker.ts +++ b/src/quickpicks/modePicker.ts @@ -9,13 +9,13 @@ export interface ModesQuickPickItem extends QuickPickItem { export namespace ModePicker { export async function show(): Promise { - if (Container.config.modes == null) return undefined; + if (Container.instance.config.modes == null) return undefined; - const modes = Container.config.modes; + const modes = Container.instance.config.modes; const modeKeys = Object.keys(modes); if (modeKeys.length === 0) return undefined; - const mode = Container.config.mode.active; + const mode = Container.instance.config.mode.active; const items = modeKeys.map(key => { const modeCfg = modes[key]; diff --git a/src/quickpicks/quickPicksItems.ts b/src/quickpicks/quickPicksItems.ts index 97cd770..eace950 100644 --- a/src/quickpicks/quickPicksItems.ts +++ b/src/quickpicks/quickPicksItems.ts @@ -226,7 +226,7 @@ export class SearchForCommitQuickPickItem extends CommandQuickPickItem { } override async execute(options?: { preserveFocus?: boolean; preview?: boolean }): Promise { - void (await Container.searchAndCompareView.search( + void (await Container.instance.searchAndCompareView.search( this.reference.repoPath, { pattern: SearchPattern.fromCommit(this.reference), diff --git a/src/quickpicks/referencePicker.ts b/src/quickpicks/referencePicker.ts index bf2e5ea..95b807c 100644 --- a/src/quickpicks/referencePicker.ts +++ b/src/quickpicks/referencePicker.ts @@ -52,7 +52,7 @@ export namespace ReferencePicker { let scope: KeyboardScope | undefined; if (options?.keys != null && options.keys.length !== 0 && options?.onDidPressKey !== null) { - scope = Container.keyboard.createScope( + scope = Container.instance.keyboard.createScope( Object.fromEntries( options.keys.map(key => [ key, @@ -89,14 +89,17 @@ export namespace ReferencePicker { quickpick.show(); - const getValidateGitReference = getValidateGitReferenceFn((await Container.git.getRepository(repoPath))!, { - buttons: [QuickCommandButtons.RevealInSideBar], - ranges: - // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions - options?.allowEnteringRefs && typeof options.allowEnteringRefs !== 'boolean' - ? options.allowEnteringRefs.ranges - : undefined, - }); + const getValidateGitReference = getValidateGitReferenceFn( + (await Container.instance.git.getRepository(repoPath))!, + { + buttons: [QuickCommandButtons.RevealInSideBar], + ranges: + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + options?.allowEnteringRefs && typeof options.allowEnteringRefs !== 'boolean' + ? options.allowEnteringRefs.ranges + : undefined, + }, + ); quickpick.items = await items; @@ -162,7 +165,7 @@ export namespace ReferencePicker { include = include ?? ReferencesQuickPickIncludes.BranchesAndTags; const items: ReferencesQuickPickItem[] = await getBranchesAndOrTags( - (await Container.git.getRepository(repoPath))!, + (await Container.instance.git.getRepository(repoPath))!, include && ReferencesQuickPickIncludes.BranchesAndTags ? ['branches', 'tags'] : include && ReferencesQuickPickIncludes.Branches diff --git a/src/quickpicks/remoteProviderPicker.ts b/src/quickpicks/remoteProviderPicker.ts index 6e69d4b..4b7e1d4 100644 --- a/src/quickpicks/remoteProviderPicker.ts +++ b/src/quickpicks/remoteProviderPicker.ts @@ -53,7 +53,7 @@ export class CopyOrOpenRemoteCommandQuickPickItem extends CommandQuickPickItem { } else if (resource.type === RemoteResourceType.CreatePullRequest) { let branch = resource.base.branch; if (branch == null) { - branch = await Container.git.getDefaultBranchName(this.remote.repoPath, this.remote.name); + branch = await Container.instance.git.getDefaultBranchName(this.remote.repoPath, this.remote.name); if (branch == null && this.remote.provider.hasApi()) { const defaultBranch = await this.remote.provider.getDefaultBranch?.(); branch = defaultBranch?.name; @@ -73,7 +73,7 @@ export class CopyOrOpenRemoteCommandQuickPickItem extends CommandQuickPickItem { // Since Bitbucket can't support branch names in the url (other than with the default branch), // turn this into a `Revision` request const { branchOrTag } = resource; - const branchesOrTags = await Container.git.getBranchesAndOrTags(this.remote.repoPath, { + const branchesOrTags = await Container.instance.git.getBranchesAndOrTags(this.remote.repoPath, { filter: { branches: b => b.name === branchOrTag || GitBranch.getNameWithoutRemote(b.name) === branchOrTag, tags: b => b.name === branchOrTag, diff --git a/src/quickpicks/repositoryPicker.ts b/src/quickpicks/repositoryPicker.ts index 47c81c7..a1319d3 100644 --- a/src/quickpicks/repositoryPicker.ts +++ b/src/quickpicks/repositoryPicker.ts @@ -12,7 +12,7 @@ export namespace RepositoryPicker { repositories?: Repository[], ): Promise { const items: RepositoryQuickPickItem[] = await Promise.all([ - ...Iterables.map(repositories ?? (await Container.git.getOrderedRepositories()), r => + ...Iterables.map(repositories ?? (await Container.instance.git.getOrderedRepositories()), r => RepositoryQuickPickItem.create(r, undefined, { branch: true, status: true }), ), ]); diff --git a/src/statusbar/statusBarController.ts b/src/statusbar/statusBarController.ts index a060389..5b1f617 100644 --- a/src/statusbar/statusBarController.ts +++ b/src/statusbar/statusBarController.ts @@ -30,9 +30,11 @@ export class StatusBarController implements Disposable { private _statusBarBlame: StatusBarItem | undefined; private _statusBarMode: StatusBarItem | undefined; - constructor() { - this._disposable = Disposable.from(configuration.onDidChange(this.onConfigurationChanged, this)); - this.onConfigurationChanged(); + constructor(private readonly container: Container) { + this._disposable = Disposable.from( + container.onReady(this.onReady, this), + configuration.onDidChange(this.onConfigurationChanged, this), + ); } dispose() { @@ -41,19 +43,23 @@ export class StatusBarController implements Disposable { this._statusBarBlame?.dispose(); this._statusBarMode?.dispose(); - Container.lineTracker.stop(this); + this.container.lineTracker.stop(this); this._disposable.dispose(); } + private onReady(): void { + this.onConfigurationChanged(); + } + private onConfigurationChanged(e?: ConfigurationChangeEvent) { if (configuration.changed(e, 'mode')) { const mode = - Container.config.mode.active && Container.config.mode.statusBar.enabled - ? Container.config.modes?.[Container.config.mode.active] + this.container.config.mode.active && this.container.config.mode.statusBar.enabled + ? this.container.config.modes?.[this.container.config.mode.active] : undefined; if (mode?.statusBarItemName) { const alignment = - Container.config.mode.statusBar.alignment !== 'left' + this.container.config.mode.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left; @@ -87,9 +93,11 @@ export class StatusBarController implements Disposable { if (!configuration.changed(e, 'statusBar')) return; - if (Container.config.statusBar.enabled) { + if (this.container.config.statusBar.enabled) { const alignment = - Container.config.statusBar.alignment !== 'left' ? StatusBarAlignment.Right : StatusBarAlignment.Left; + this.container.config.statusBar.alignment !== 'left' + ? StatusBarAlignment.Right + : StatusBarAlignment.Left; if (configuration.changed(e, 'statusBar.alignment')) { if (this._statusBarBlame?.alignment !== alignment) { @@ -106,16 +114,16 @@ export class StatusBarController implements Disposable { alignment === StatusBarAlignment.Right ? 1000 : 0, ); this._statusBarBlame.name = 'GitLens Current Line Blame'; - this._statusBarBlame.command = Container.config.statusBar.command; + this._statusBarBlame.command = this.container.config.statusBar.command; if (configuration.changed(e, 'statusBar.enabled')) { - Container.lineTracker.start( + this.container.lineTracker.start( this, - Container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this), + this.container.lineTracker.onDidChangeActiveLines(this.onActiveLinesChanged, this), ); } } else if (configuration.changed(e, 'statusBar.enabled')) { - Container.lineTracker.stop(this); + this.container.lineTracker.stop(this); this._statusBarBlame?.dispose(); this._statusBarBlame = undefined; @@ -133,12 +141,12 @@ export class StatusBarController implements Disposable { private onActiveLinesChanged(e: LinesChangeEvent) { // If we need to reduceFlicker, don't clear if only the selected lines changed let clear = !( - Container.config.statusBar.reduceFlicker && + this.container.config.statusBar.reduceFlicker && e.reason === 'selection' && (e.pending || e.selections != null) ); if (!e.pending && e.selections != null) { - const state = Container.lineTracker.getState(e.selections[0].active); + const state = this.container.lineTracker.getState(e.selections[0].active); if (state?.commit != null) { void this.updateBlame(e.editor!, state.commit); @@ -163,7 +171,7 @@ export class StatusBarController implements Disposable { @debug({ args: false }) private async updateBlame(editor: TextEditor, commit: GitBlameCommit, options?: { pr?: PullRequest | null }) { - const cfg = Container.config.statusBar; + const cfg = this.container.config.statusBar; if (!cfg.enabled || this._statusBarBlame == null || !isTextEditor(editor)) return; const cc = Logger.getCorrelationContext(); @@ -191,7 +199,7 @@ export class StatusBarController implements Disposable { const timeout = 100; const [getBranchAndTagTips, pr] = await Promise.all([ CommitFormatter.has(cfg.format, 'tips') || CommitFormatter.has(cfg.tooltipFormat, 'tips') - ? Container.git.getBranchesAndTagsTipsFn(commit.repoPath) + ? this.container.git.getBranchesAndTagsTipsFn(commit.repoPath) : undefined, showPullRequests && options?.pr === undefined ? this.getPullRequest(commit, { timeout: timeout }) @@ -205,7 +213,7 @@ export class StatusBarController implements Disposable { } this._statusBarBlame.text = `$(git-commit) ${CommitFormatter.fromTemplate(cfg.format, commit, { - dateFormat: cfg.dateFormat === null ? Container.config.defaultDateFormat : cfg.dateFormat, + dateFormat: cfg.dateFormat === null ? this.container.config.defaultDateFormat : cfg.dateFormat, getBranchAndTagTips: getBranchAndTagTips, messageTruncateAtNewLine: true, pullRequestOrRemote: pr, @@ -322,12 +330,12 @@ export class StatusBarController implements Disposable { commit: GitBlameCommit, { timeout }: { timeout?: number } = {}, ): Promise> | undefined> { - const remote = await Container.git.getRichRemoteProvider(commit.repoPath); + const remote = await this.container.git.getRichRemoteProvider(commit.repoPath); if (remote?.provider == null) return undefined; const { provider } = remote; try { - return await Container.git.getPullRequestForCommit(commit.ref, provider, { timeout: timeout }); + return await this.container.git.getPullRequestForCommit(commit.ref, provider, { timeout: timeout }); } catch (ex) { return ex instanceof Promises.CancellationError ? ex : undefined; } @@ -356,8 +364,8 @@ export class StatusBarController implements Disposable { commit, commit.toGitUri(), commit.lines[0].line, - Container.config.statusBar.tooltipFormat, - Container.config.defaultDateFormat, + this.container.config.statusBar.tooltipFormat, + this.container.config.defaultDateFormat, { autolinks: true, getBranchAndTagTips: getBranchAndTagTips, diff --git a/src/system/path.ts b/src/system/path.ts index 664ad8c..2f7c4d3 100644 --- a/src/system/path.ts +++ b/src/system/path.ts @@ -1,9 +1,68 @@ 'use strict'; import * as paths from 'path'; +import { Uri } from 'vscode'; import { normalizePath } from './string'; const slash = '/'; +export function isChild(uri: Uri, baseUri: Uri): boolean; +export function isChild(uri: Uri, basePath: string): boolean; +export function isChild(path: string, basePath: string): boolean; +export function isChild(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean { + if (typeof baseUriOrPath === 'string') { + if (!baseUriOrPath.startsWith('/')) { + baseUriOrPath = `/${baseUriOrPath}`; + } + + return ( + isDescendent(uriOrPath, baseUriOrPath) && + (typeof uriOrPath === 'string' ? uriOrPath : uriOrPath.path) + .substr(baseUriOrPath.length + (baseUriOrPath.endsWith('/') ? 0 : 1)) + .split('/').length === 1 + ); + } + + return ( + isDescendent(uriOrPath, baseUriOrPath) && + (typeof uriOrPath === 'string' ? uriOrPath : uriOrPath.path) + .substr(baseUriOrPath.path.length + (baseUriOrPath.path.endsWith('/') ? 0 : 1)) + .split('/').length === 1 + ); +} + +export function isDescendent(uri: Uri, baseUri: Uri): boolean; +export function isDescendent(uri: Uri, basePath: string): boolean; +export function isDescendent(path: string, basePath: string): boolean; +export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean; +export function isDescendent(uriOrPath: Uri | string, baseUriOrPath: Uri | string): boolean { + if (typeof baseUriOrPath === 'string') { + if (!baseUriOrPath.startsWith('/')) { + baseUriOrPath = `/${baseUriOrPath}`; + } + + return ( + baseUriOrPath.length === 1 || + (typeof uriOrPath === 'string' ? uriOrPath : uriOrPath.path).startsWith( + baseUriOrPath.endsWith('/') ? baseUriOrPath : `${baseUriOrPath}/`, + ) + ); + } + + if (typeof uriOrPath === 'string') { + return ( + baseUriOrPath.path.length === 1 || + uriOrPath.startsWith(baseUriOrPath.path.endsWith('/') ? baseUriOrPath.path : `${baseUriOrPath.path}/`) + ); + } + + return ( + baseUriOrPath.scheme === uriOrPath.scheme && + baseUriOrPath.authority === uriOrPath.authority && + (baseUriOrPath.path.length === 1 || + uriOrPath.path.startsWith(baseUriOrPath.path.endsWith('/') ? baseUriOrPath.path : `${baseUriOrPath.path}/`)) + ); +} + export function splitPath(fileName: string, repoPath: string | undefined, extract: boolean = true): [string, string] { if (repoPath) { fileName = normalizePath(fileName); diff --git a/src/terminal.ts b/src/terminal.ts index 6bd54e6..3d4a646 100644 --- a/src/terminal.ts +++ b/src/terminal.ts @@ -19,7 +19,7 @@ function ensureTerminal(cwd: string): Terminal { } }); - Container.context.subscriptions.push(_disposable); + Container.instance.context.subscriptions.push(_disposable); _terminalCwd = undefined; } diff --git a/src/terminal/linkProvider.ts b/src/terminal/linkProvider.ts index 9bf5653..7c983ad 100644 --- a/src/terminal/linkProvider.ts +++ b/src/terminal/linkProvider.ts @@ -26,7 +26,7 @@ interface GitTerminalLink extends TerminalLink { export class GitTerminalLinkProvider implements Disposable, TerminalLinkProvider { private disposable: Disposable; - constructor() { + constructor(private readonly container: Container) { this.disposable = window.registerTerminalLinkProvider(this); } @@ -37,12 +37,12 @@ export class GitTerminalLinkProvider implements Disposable, TerminalLinkProvider async provideTerminalLinks(context: TerminalLinkContext): Promise { if (context.line.trim().length === 0) return []; - const repoPath = Container.git.getHighlanderRepoPath(); + const repoPath = this.container.git.getHighlanderRepoPath(); if (repoPath == null) return []; const links: GitTerminalLink[] = []; - const branchesAndTags = await Container.git.getBranchesAndOrTags(repoPath); + const branchesAndTags = await this.container.git.getBranchesAndOrTags(repoPath); // Don't use the shared regex instance directly, because we can be called reentrantly (because of the awaits below) const refRegex = new RegExp(refRegexShared, refRegexShared.flags); @@ -134,7 +134,7 @@ export class GitTerminalLinkProvider implements Disposable, TerminalLinkProvider continue; } - if (await Container.git.validateReference(repoPath, ref)) { + if (await this.container.git.validateReference(repoPath, ref)) { const link: GitTerminalLink = { startIndex: match.index, length: ref.length, diff --git a/src/trackers/documentTracker.ts b/src/trackers/documentTracker.ts index 7254f0b..f50aaff 100644 --- a/src/trackers/documentTracker.ts +++ b/src/trackers/documentTracker.ts @@ -18,6 +18,7 @@ import { } from 'vscode'; import { configuration } from '../configuration'; import { ContextKeys, DocumentSchemes, isActiveDocument, isTextEditor, setContext } from '../constants'; +import { Container } from '../container'; import { GitUri } from '../git/gitUri'; import { Functions } from '../system'; import { DocumentBlameStateChangeEvent, TrackedDocument } from './trackedDocument'; @@ -63,11 +64,12 @@ export class DocumentTracker implements Disposable { } private _dirtyIdleTriggerDelay!: number; - private readonly _disposable: Disposable | undefined; + private readonly _disposable: Disposable; private readonly _documentMap = new Map>>(); - constructor() { + constructor(protected readonly container: Container) { this._disposable = Disposable.from( + container.onReady(this.onReady, this), configuration.onDidChange(this.onConfigurationChanged, this), window.onDidChangeActiveTextEditor(this.onActiveTextEditorChanged, this), // window.onDidChangeVisibleTextEditors(Functions.debounce(this.onVisibleEditorsChanged, 5000), this), @@ -75,17 +77,16 @@ export class DocumentTracker implements Disposable { workspace.onDidCloseTextDocument(this.onTextDocumentClosed, this), workspace.onDidSaveTextDocument(this.onTextDocumentSaved, this), ); - - void this.onConfigurationChanged(); } dispose() { - this._disposable?.dispose(); + this._disposable.dispose(); void this.clear(); } - initialize() { + private onReady(): void { + void this.onConfigurationChanged(); void this.onActiveTextEditorChanged(window.activeTextEditor); } @@ -263,7 +264,7 @@ export class DocumentTracker implements Disposable { // If we can't find the file, assume it is because the file has been renamed or deleted at some point document = new MissingRevisionTextDocument(documentOrId); - // const [fileName, repoPath] = await Container.git.findWorkingFileName(documentOrId, undefined, ref); + // const [fileName, repoPath] = await this.container.git.findWorkingFileName(documentOrId, undefined, ref); // if (fileName == null) throw new Error(`Failed to add tracking for document: ${documentOrId}`); // documentOrId = await workspace.openTextDocument(path.resolve(repoPath!, fileName)); @@ -296,9 +297,15 @@ export class DocumentTracker implements Disposable { const key = GitUri.toKey(document.uri); // Always start out false, so we will fire the event if needed - const doc = TrackedDocument.create(document, key, false, { - onDidBlameStateChange: (e: DocumentBlameStateChangeEvent) => this._onDidChangeBlameState.fire(e), - }); + const doc = TrackedDocument.create( + document, + key, + false, + { + onDidBlameStateChange: (e: DocumentBlameStateChangeEvent) => this._onDidChangeBlameState.fire(e), + }, + this.container, + ); this._documentMap.set(document, doc); this._documentMap.set(key, doc); diff --git a/src/trackers/gitLineTracker.ts b/src/trackers/gitLineTracker.ts index 6eea9e8..68568c1 100644 --- a/src/trackers/gitLineTracker.ts +++ b/src/trackers/gitLineTracker.ts @@ -21,6 +21,10 @@ export class GitLineState { } export class GitLineTracker extends LineTracker { + constructor(private readonly container: Container) { + super(); + } + protected override async fireLinesChanged(e: LinesChangeEvent) { this.reset(); @@ -39,15 +43,15 @@ export class GitLineTracker extends LineTracker { return Disposable.from( { dispose: () => this.onSuspend() }, - Container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this), - Container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this), - Container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this), + this.container.tracker.onDidChangeBlameState(this.onBlameStateChanged, this), + this.container.tracker.onDidChangeDirtyState(this.onDirtyStateChanged, this), + this.container.tracker.onDidTriggerDirtyIdle(this.onDirtyIdleTriggered, this), ); } protected override onResume(): void { if (this._subscriptionOnlyWhenActive == null) { - this._subscriptionOnlyWhenActive = Container.tracker.onDidChangeContent(this.onContentChanged, this); + this._subscriptionOnlyWhenActive = this.container.tracker.onDidChangeContent(this.onContentChanged, this); } } @@ -95,7 +99,7 @@ export class GitLineTracker extends LineTracker { }, }) private onDirtyIdleTriggered(e: DocumentDirtyIdleTriggerEvent) { - const maxLines = Container.config.advanced.blame.sizeThresholdAfterEdit; + const maxLines = this.container.config.advanced.blame.sizeThresholdAfterEdit; if (maxLines > 0 && e.document.lineCount > maxLines) return; this.resume(); @@ -136,7 +140,7 @@ export class GitLineTracker extends LineTracker { return false; } - const trackedDocument = await Container.tracker.getOrAdd(editor.document); + const trackedDocument = await this.container.tracker.getOrAdd(editor.document); if (!trackedDocument.isBlameable) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} document is not blameable`; @@ -147,12 +151,12 @@ export class GitLineTracker extends LineTracker { if (selections.length === 1) { const blameLine = editor.document.isDirty - ? await Container.git.getBlameForLineContents( + ? await this.container.git.getBlameForLineContents( trackedDocument.uri, selections[0].active, editor.document.getText(), ) - : await Container.git.getBlameForLine(trackedDocument.uri, selections[0].active); + : await this.container.git.getBlameForLine(trackedDocument.uri, selections[0].active); if (blameLine === undefined) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} blame failed`; @@ -164,8 +168,8 @@ export class GitLineTracker extends LineTracker { this.setState(blameLine.line.line - 1, new GitLineState(blameLine.commit)); } else { const blame = editor.document.isDirty - ? await Container.git.getBlameForFileContents(trackedDocument.uri, editor.document.getText()) - : await Container.git.getBlameForFile(trackedDocument.uri); + ? await this.container.git.getBlameForFileContents(trackedDocument.uri, editor.document.getText()) + : await this.container.git.getBlameForFile(trackedDocument.uri); if (blame === undefined) { if (cc != null) { cc.exitDetails = ` ${GlyphChars.Dot} blame failed`; diff --git a/src/trackers/trackedDocument.ts b/src/trackers/trackedDocument.ts index 1637afd..dec8d8f 100644 --- a/src/trackers/trackedDocument.ts +++ b/src/trackers/trackedDocument.ts @@ -25,8 +25,9 @@ export class TrackedDocument implements Disposable { key: string, dirty: boolean, eventDelegates: { onDidBlameStateChange(e: DocumentBlameStateChangeEvent): void }, + container: Container, ) { - const doc = new TrackedDocument(document, key, dirty, eventDelegates); + const doc = new TrackedDocument(document, key, dirty, eventDelegates, container); await doc.initialize(); return doc; } @@ -48,6 +49,7 @@ export class TrackedDocument implements Disposable { public readonly key: string, public dirty: boolean, private _eventDelegates: { onDidBlameStateChange(e: DocumentBlameStateChangeEvent): void }, + private readonly container: Container, ) {} dispose() { @@ -58,23 +60,10 @@ export class TrackedDocument implements Disposable { private initializing = true; private async initialize(): Promise { - const uri = this._document.uri; - - // Since there is a bit of a chicken & egg problem with the DocumentTracker and the GitService, wait for the GitService to load if it isn't - if (Container.git == null) { - if (!(await Functions.waitUntil(() => Container.git != null, 2000))) { - Logger.log( - `TrackedDocument.initialize(${uri.toString(true)})`, - 'Timed out waiting for the GitService to start', - ); - throw new Error('TrackedDocument timed out waiting for the GitService to start'); - } - } - - this._uri = await GitUri.fromUri(uri); + this._uri = await GitUri.fromUri(this._document.uri); if (this._disposed) return undefined; - const repo = await Container.git.getRepository(this._uri); + const repo = await this.container.git.getRepository(this._uri); this._repo = repo; if (this._disposed) return undefined; @@ -203,7 +192,7 @@ export class TrackedDocument implements Disposable { const active = getEditorIfActive(this._document); const wasBlameable = forceBlameChange ? undefined : this.isBlameable; - this._isTracked = await Container.git.isTracked(this._uri); + this._isTracked = await this.container.git.isTracked(this._uri); let repo = undefined; if (this._isTracked) { diff --git a/src/views/branchesView.ts b/src/views/branchesView.ts index 3698377..8385683 100644 --- a/src/views/branchesView.ts +++ b/src/views/branchesView.ts @@ -73,7 +73,7 @@ export class BranchesViewNode extends ViewNode { async getChildren(): Promise { if (this.children == null) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) { this.view.message = 'No branches could be found.'; @@ -142,8 +142,8 @@ export class BranchesViewNode extends ViewNode { export class BranchesView extends ViewBase { protected readonly configKey = 'branches'; - constructor() { - super('gitlens.views.branches', 'Branches'); + constructor(container: Container) { + super('gitlens.views.branches', 'Branches', container); } getRoot() { @@ -151,7 +151,7 @@ export class BranchesView extends ViewBase } protected registerCommands(): Disposable[] { - void Container.viewCommands; + void this.container.viewCommands; return [ commands.registerCommand( @@ -162,7 +162,7 @@ export class BranchesView extends ViewBase commands.registerCommand( this.getQualifiedCommand('refresh'), async () => { - await Container.git.resetCaches('branches'); + await this.container.git.resetCaches('branches'); return this.refresh(true); }, this, @@ -268,7 +268,7 @@ export class BranchesView extends ViewBase const repoNodeId = RepositoryNode.getId(commit.repoPath); // Get all the branches the commit is on - const branches = await Container.git.getCommitBranches(commit.repoPath, commit.ref); + const branches = await this.container.git.getCommitBranches(commit.repoPath, commit.ref); if (branches.length === 0) return undefined; return this.findNode((n: any) => n.commit?.ref === commit.ref, { diff --git a/src/views/commitsView.ts b/src/views/commitsView.ts index 5dc3f94..049bb27 100644 --- a/src/views/commitsView.ts +++ b/src/views/commitsView.ts @@ -47,7 +47,7 @@ export class CommitsRepositoryNode extends RepositoryFolderNode$`]; } @@ -128,7 +128,7 @@ export class CommitsViewNode extends ViewNode { async getChildren(): Promise { if (this.children == null) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) { this.view.message = 'No commits could be found.'; @@ -205,8 +205,8 @@ interface CommitsViewState { export class CommitsView extends ViewBase { protected readonly configKey = 'commits'; - constructor() { - super('gitlens.views.commits', 'Commits'); + constructor(container: Container) { + super('gitlens.views.commits', 'Commits', container); } private readonly _state: CommitsViewState = {}; @@ -219,7 +219,7 @@ export class CommitsView extends ViewBase { } protected registerCommands(): Disposable[] { - void Container.viewCommands; + void this.container.viewCommands; return [ commands.registerCommand( @@ -230,7 +230,7 @@ export class CommitsView extends ViewBase { commands.registerCommand( this.getQualifiedCommand('refresh'), async () => { - await Container.git.resetCaches('branches', 'status', 'tags'); + await this.container.git.resetCaches('branches', 'status', 'tags'); return this.refresh(true); }, this, @@ -313,11 +313,13 @@ export class CommitsView extends ViewBase { async findCommit(commit: GitLogCommit | { repoPath: string; ref: string }, token?: CancellationToken) { const repoNodeId = RepositoryNode.getId(commit.repoPath); - const branch = await Container.git.getBranch(commit.repoPath); + const branch = await this.container.git.getBranch(commit.repoPath); if (branch == null) return undefined; // Check if the commit exists on the current branch - if (!(await Container.git.branchContainsCommit(commit.repoPath, branch.name, commit.ref))) return undefined; + if (!(await this.container.git.branchContainsCommit(commit.repoPath, branch.name, commit.ref))) { + return undefined; + } return this.findNode((n: any) => n.commit?.ref === commit.ref, { allowPaging: true, diff --git a/src/views/contributorsView.ts b/src/views/contributorsView.ts index 859d4f3..637bc60 100644 --- a/src/views/contributorsView.ts +++ b/src/views/contributorsView.ts @@ -48,7 +48,7 @@ export class ContributorsViewNode extends ViewNode { async getChildren(): Promise { if (this.children == null) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) { this.view.message = 'No contributors could be found.'; @@ -72,13 +72,13 @@ export class ContributorsViewNode extends ViewNode { const children = await child.getChildren(); - // const all = Container.config.views.contributors.showAllBranches; + // const all = Container.instance.config.views.contributors.showAllBranches; // let ref: string | undefined; // // If we aren't getting all branches, get the upstream of the current branch if there is one // if (!all) { // try { - // const branch = await Container.git.getBranch(this.uri.repoPath); + // const branch = await Container.instance.git.getBranch(this.uri.repoPath); // if (branch?.upstream?.name != null && !branch.upstream.missing) { // ref = '@{u}'; // } @@ -132,8 +132,8 @@ export class ContributorsViewNode extends ViewNode { export class ContributorsView extends ViewBase { protected readonly configKey = 'contributors'; - constructor() { - super('gitlens.views.contributors', 'Contributors'); + constructor(container: Container) { + super('gitlens.views.contributors', 'Contributors', container); } getRoot() { @@ -141,7 +141,7 @@ export class ContributorsView extends ViewBase { - await Container.git.resetCaches('contributors'); + await this.container.git.resetCaches('contributors'); return this.refresh(true); }, this, diff --git a/src/views/fileHistoryView.ts b/src/views/fileHistoryView.ts index f335645..032db5d 100644 --- a/src/views/fileHistoryView.ts +++ b/src/views/fileHistoryView.ts @@ -15,8 +15,8 @@ export class FileHistoryView extends ViewBase { protected readonly configKey = 'lineHistory'; - constructor() { - super('gitlens.views.lineHistory', 'Line History'); + constructor(container: Container) { + super('gitlens.views.lineHistory', 'Line History', container); void setContext(ContextKeys.ViewsLineHistoryEditorFollowing, true); } @@ -26,7 +26,7 @@ export class LineHistoryView extends ViewBase - Container.git.getCommitCount(this.branch.repoPath, this.branch.name), + Container.instance.git.getCommitCount(this.branch.repoPath, this.branch.name), ), ); } @@ -370,7 +370,7 @@ export class BranchNode } } else { const providers = GitRemote.getHighlanderProviders( - await Container.git.getRemotes(this.branch.repoPath), + await Container.instance.git.getRemotes(this.branch.repoPath), ); const providerName = providers?.length ? providers[0].name : undefined; @@ -403,8 +403,8 @@ export class BranchNode item.iconPath = this.options.showAsCommits ? new ThemeIcon('git-commit', color) : { - dark: Container.context.asAbsolutePath(`images/dark/icon-branch${iconSuffix}.svg`), - light: Container.context.asAbsolutePath(`images/light/icon-branch${iconSuffix}.svg`), + dark: Container.instance.context.asAbsolutePath(`images/dark/icon-branch${iconSuffix}.svg`), + light: Container.instance.context.asAbsolutePath(`images/light/icon-branch${iconSuffix}.svg`), }; item.tooltip = tooltip; item.resourceUri = Uri.parse( @@ -450,7 +450,7 @@ export class BranchNode limit = Math.min(this.branch.state.ahead + 1, limit * 2); } - this._log = await Container.git.getLog(this.uri.repoPath!, { + this._log = await Container.instance.git.getLog(this.uri.repoPath!, { limit: limit, ref: this.ref.ref, authors: this.options?.authors, diff --git a/src/views/nodes/branchTrackingStatusFilesNode.ts b/src/views/nodes/branchTrackingStatusFilesNode.ts index 24e8b35..97eb79c 100644 --- a/src/views/nodes/branchTrackingStatusFilesNode.ts +++ b/src/views/nodes/branchTrackingStatusFilesNode.ts @@ -45,7 +45,7 @@ export class BranchTrackingStatusFilesNode extends ViewNode { } async getChildren(): Promise { - const log = await Container.git.getLog(this.repoPath, { + const log = await Container.instance.git.getLog(this.repoPath, { limit: 0, ref: GitRevision.createRange( this.status.upstream, @@ -103,7 +103,7 @@ export class BranchTrackingStatusFilesNode extends ViewNode { } async getTreeItem(): Promise { - const stats = await Container.git.getChangedFilesCount( + const stats = await Container.instance.git.getChangedFilesCount( this.repoPath, `${this.status.upstream}${this.direction === 'behind' ? '..' : '...'}`, ); diff --git a/src/views/nodes/branchTrackingStatusNode.ts b/src/views/nodes/branchTrackingStatusNode.ts index ec1eab9..74e457e 100644 --- a/src/views/nodes/branchTrackingStatusNode.ts +++ b/src/views/nodes/branchTrackingStatusNode.ts @@ -79,7 +79,10 @@ export class BranchTrackingStatusNode extends ViewNode impleme commits = [...log.commits.values()]; const commit = commits[commits.length - 1]; if (commit.previousSha == null) { - const previousLog = await Container.git.getLog(this.uri.repoPath!, { limit: 2, ref: commit.sha }); + const previousLog = await Container.instance.git.getLog(this.uri.repoPath!, { + limit: 2, + ref: commit.sha, + }); if (previousLog != null) { commits[commits.length - 1] = Iterables.first(previousLog.commits.values()); } @@ -148,7 +151,7 @@ export class BranchTrackingStatusNode extends ViewNode impleme let lastFetched = 0; if (this.upstreamType !== 'none') { - const repo = await Container.git.getRepository(this.repoPath); + const repo = await Container.instance.git.getRepository(this.repoPath); lastFetched = (await repo?.getLastFetched()) ?? 0; } @@ -225,7 +228,7 @@ export class BranchTrackingStatusNode extends ViewNode impleme break; } case 'none': { - const remotes = await Container.git.getRemotes(this.branch.repoPath); + const remotes = await Container.instance.git.getRemotes(this.branch.repoPath); const providers = GitRemote.getHighlanderProviders(remotes); const providerName = providers?.length ? providers[0].name : undefined; @@ -276,7 +279,7 @@ export class BranchTrackingStatusNode extends ViewNode impleme ? GitRevision.createRange(this.status.upstream, this.status.ref) : GitRevision.createRange(this.status.ref, this.status.upstream); - this._log = await Container.git.getLog(this.uri.repoPath!, { + this._log = await Container.instance.git.getLog(this.uri.repoPath!, { limit: this.limit ?? this.view.config.defaultItemLimit, ref: range, }); diff --git a/src/views/nodes/commitFileNode.ts b/src/views/nodes/commitFileNode.ts index 61fc549..ea93ade 100644 --- a/src/views/nodes/commitFileNode.ts +++ b/src/views/nodes/commitFileNode.ts @@ -49,7 +49,7 @@ export class CommitFileNode { const label = CommitFormatter.fromTemplate(this.view.config.formats.commits.label, this.commit, { - dateFormat: Container.config.defaultDateFormat, + dateFormat: Container.instance.config.defaultDateFormat, getBranchAndTagTips: (sha: string) => this.getBranchAndTagTips?.(sha, { compact: true }), messageTruncateAtNewLine: true, }); @@ -98,14 +98,14 @@ export class CommitNode extends ViewRefNode this.getBranchAndTagTips?.(sha, { compact: true }), messageTruncateAtNewLine: true, }); item.iconPath = this.unpublished ? new ThemeIcon('arrow-up', new ThemeColor(Colors.UnpublishedCommitIconColor)) : this.view.config.avatars - ? await this.commit.getAvatarUri({ defaultStyle: Container.config.defaultGravatarsStyle }) + ? await this.commit.getAvatarUri({ defaultStyle: Container.instance.config.defaultGravatarsStyle }) : new ThemeIcon('git-commit'); // item.tooltip = this.tooltip; @@ -137,16 +137,16 @@ export class CommitNode extends ViewRefNode Promise, ) { super(unknownGitUri, view, parent); diff --git a/src/views/nodes/compareBranchNode.ts b/src/views/nodes/compareBranchNode.ts index 0f0a02a..dd4fa27 100644 --- a/src/views/nodes/compareBranchNode.ts +++ b/src/views/nodes/compareBranchNode.ts @@ -67,12 +67,13 @@ export class CompareBranchNode extends ViewNode { - let files = await Container.git.getDiffStatus( + let files = await Container.instance.git.getDiffStatus( this.repoPath, GitRevision.createRange(this._compareWith?.ref || 'HEAD', this.branch.ref || 'HEAD', '...'), ); if (this.compareWithWorkingTree) { - const workingFiles = await Container.git.getDiffStatus(this.repoPath, 'HEAD'); + const workingFiles = await Container.instance.git.getDiffStatus(this.repoPath, 'HEAD'); if (workingFiles != null) { if (files != null) { for (const wf of workingFiles) { @@ -277,7 +278,7 @@ export class CompareBranchNode extends ViewNode { - const files = await Container.git.getDiffStatus( + const files = await Container.instance.git.getDiffStatus( this.uri.repoPath!, GitRevision.createRange(this.branch.ref, this._compareWith?.ref || 'HEAD', '...'), ); @@ -291,7 +292,7 @@ export class CompareBranchNode extends ViewNode Promise { const repoPath = this.uri.repoPath!; return async (limit: number | undefined) => { - const log = await Container.git.getLog(repoPath, { + const log = await Container.instance.git.getLog(repoPath, { limit: limit, ref: range, }); @@ -321,7 +322,7 @@ export class CompareBranchNode extends ViewNode(WorkspaceState.BranchComparisons); + const comparisons = Container.instance.context.workspaceState.get( + WorkspaceState.BranchComparisons, + ); const id = `${this.branch.id}${this.branch.current ? '+current' : ''}`; const compareWith = comparisons?.[id]; @@ -348,7 +351,9 @@ export class CompareBranchNode extends ViewNode(WorkspaceState.BranchComparisons); + let comparisons = Container.instance.context.workspaceState.get( + WorkspaceState.BranchComparisons, + ); if (comparisons == null) { comparisons = Object.create(null) as BranchComparisons; } @@ -361,6 +366,6 @@ export class CompareBranchNode extends ViewNode { let description; if (repoPath !== undefined) { - if ((await Container.git.getRepositoryCount()) > 1) { - const repo = await Container.git.getRepository(repoPath); + if ((await Container.instance.git.getRepositoryCount()) > 1) { + const repo = await Container.instance.git.getRepository(repoPath); description = repo?.formattedName ?? repoPath; } } diff --git a/src/views/nodes/compareResultsNode.ts b/src/views/nodes/compareResultsNode.ts index ce18d28..b8603e7 100644 --- a/src/views/nodes/compareResultsNode.ts +++ b/src/views/nodes/compareResultsNode.ts @@ -74,12 +74,13 @@ export class CompareResultsNode extends ViewNode { const ahead = this.ahead; const behind = this.behind; - const aheadBehindCounts = await Container.git.getAheadBehindCommitCount(this.repoPath, [ + const aheadBehindCounts = await Container.instance.git.getAheadBehindCommitCount(this.repoPath, [ GitRevision.createRange(behind.ref1 || 'HEAD', behind.ref2, '...'), ]); const mergeBase = - (await Container.git.getMergeBase(this.repoPath, behind.ref1, behind.ref2, { forkPoint: true })) ?? - (await Container.git.getMergeBase(this.repoPath, behind.ref1, behind.ref2)); + (await Container.instance.git.getMergeBase(this.repoPath, behind.ref1, behind.ref2, { + forkPoint: true, + })) ?? (await Container.instance.git.getMergeBase(this.repoPath, behind.ref1, behind.ref2)); this._children = [ new ResultsCommitsNode( @@ -143,8 +144,8 @@ export class CompareResultsNode extends ViewNode { async getTreeItem(): Promise { let description; - if ((await Container.git.getRepositoryCount()) > 1) { - const repo = await Container.git.getRepository(this.uri.repoPath!); + if ((await Container.instance.git.getRepositoryCount()) > 1) { + const repo = await Container.instance.git.getRepository(this.uri.repoPath!); description = repo?.formattedName ?? this.uri.repoPath; } @@ -226,13 +227,13 @@ export class CompareResultsNode extends ViewNode { } private async getAheadFilesQuery(): Promise { - let files = await Container.git.getDiffStatus( + let files = await Container.instance.git.getDiffStatus( this.repoPath, GitRevision.createRange(this._compareWith?.ref || 'HEAD', this._ref.ref || 'HEAD', '...'), ); if (this._ref.ref === '') { - const workingFiles = await Container.git.getDiffStatus(this.repoPath, 'HEAD'); + const workingFiles = await Container.instance.git.getDiffStatus(this.repoPath, 'HEAD'); if (workingFiles != null) { if (files != null) { for (const wf of workingFiles) { @@ -256,13 +257,13 @@ export class CompareResultsNode extends ViewNode { } private async getBehindFilesQuery(): Promise { - let files = await Container.git.getDiffStatus( + let files = await Container.instance.git.getDiffStatus( this.repoPath, GitRevision.createRange(this._ref.ref || 'HEAD', this._compareWith.ref || 'HEAD', '...'), ); if (this._compareWith.ref === '') { - const workingFiles = await Container.git.getDiffStatus(this.repoPath, 'HEAD'); + const workingFiles = await Container.instance.git.getDiffStatus(this.repoPath, 'HEAD'); if (workingFiles != null) { if (files != null) { for (const wf of workingFiles) { @@ -288,7 +289,7 @@ export class CompareResultsNode extends ViewNode { private getCommitsQuery(range: string): (limit: number | undefined) => Promise { const repoPath = this.repoPath; return async (limit: number | undefined) => { - const log = await Container.git.getLog(repoPath, { + const log = await Container.instance.git.getLog(repoPath, { limit: limit, ref: range, }); @@ -318,7 +319,7 @@ export class CompareResultsNode extends ViewNode { comparison = `${this._compareWith.ref}..${this._ref.ref}`; } - const files = await Container.git.getDiffStatus(this.uri.repoPath!, comparison); + const files = await Container.instance.git.getDiffStatus(this.uri.repoPath!, comparison); return { label: `${Strings.pluralize('file', files?.length ?? 0, { zero: 'No' })} changed`, diff --git a/src/views/nodes/contributorNode.ts b/src/views/nodes/contributorNode.ts index 6786efc..1fd174e 100644 --- a/src/views/nodes/contributorNode.ts +++ b/src/views/nodes/contributorNode.ts @@ -47,7 +47,7 @@ export class ContributorNode extends ViewNode { if (this._children == null) { - const all = Container.config.views.contributors.showAllBranches; + const all = Container.instance.config.views.contributors.showAllBranches; let ref: string | undefined; // If we aren't getting all branches, get the upstream of the current branch if there is one if (!all) { try { - const branch = await Container.git.getBranch(this.uri.repoPath); + const branch = await Container.instance.git.getBranch(this.uri.repoPath); if (branch?.upstream?.name != null && !branch.upstream.missing) { ref = '@{u}'; } } catch {} } - const stats = Container.config.views.contributors.showStatistics; + const stats = Container.instance.config.views.contributors.showStatistics; const contributors = await this.repo.getContributors({ all: all, ref: ref, stats: stats }); if (contributors.length === 0) return [new MessageNode(this.view, this, 'No contributors could be found.')]; @@ -98,6 +98,6 @@ export class ContributorsNode extends ViewNode c.current)?.email; if (email == null) return undefined; - return Container.vsls.getContactsPresence([email]); + return Container.instance.vsls.getContactsPresence([email]); } } diff --git a/src/views/nodes/fileHistoryNode.ts b/src/views/nodes/fileHistoryNode.ts index 8e48dbc..8730aec 100644 --- a/src/views/nodes/fileHistoryNode.ts +++ b/src/views/nodes/fileHistoryNode.ts @@ -58,18 +58,18 @@ export class FileHistoryNode extends SubscribeableViewNode impl const children: ViewNode[] = []; - const range = this.branch != null ? await Container.git.getBranchAheadRange(this.branch) : undefined; + const range = this.branch != null ? await Container.instance.git.getBranchAheadRange(this.branch) : undefined; const [log, fileStatuses, currentUser, getBranchAndTagTips, unpublishedCommits] = await Promise.all([ this.getLog(), this.uri.sha == null - ? Container.git.getStatusForFiles(this.uri.repoPath!, this.getPathOrGlob()) + ? Container.instance.git.getStatusForFiles(this.uri.repoPath!, this.getPathOrGlob()) : undefined, - this.uri.sha == null ? Container.git.getCurrentUser(this.uri.repoPath!) : undefined, + this.uri.sha == null ? Container.instance.git.getCurrentUser(this.uri.repoPath!) : undefined, this.branch != null - ? Container.git.getBranchesAndTagsTipsFn(this.uri.repoPath, this.branch.name) + ? Container.instance.git.getBranchesAndTagsTipsFn(this.uri.repoPath, this.branch.name) : undefined, range - ? Container.git.getLogRefsOnly(this.uri.repoPath!, { + ? Container.instance.git.getLogRefsOnly(this.uri.repoPath!, { limit: 0, ref: range, }) @@ -169,7 +169,7 @@ export class FileHistoryNode extends SubscribeableViewNode impl @debug() protected async subscribe() { - const repo = await Container.git.getRepository(this.uri); + const repo = await Container.instance.git.getRepository(this.uri); if (repo == null) return undefined; const subscription = Disposable.from( @@ -233,7 +233,7 @@ export class FileHistoryNode extends SubscribeableViewNode impl private _log: GitLog | undefined; private async getLog() { if (this._log == null) { - this._log = await Container.git.getLogForFile(this.uri.repoPath, this.getPathOrGlob(), { + this._log = await Container.instance.git.getLogForFile(this.uri.repoPath, this.getPathOrGlob(), { limit: this.limit ?? this.view.config.pageItemLimit, ref: this.uri.sha, }); diff --git a/src/views/nodes/fileHistoryTrackerNode.ts b/src/views/nodes/fileHistoryTrackerNode.ts index 43c9f42..12d9e1f 100644 --- a/src/views/nodes/fileHistoryTrackerNode.ts +++ b/src/views/nodes/fileHistoryTrackerNode.ts @@ -65,9 +65,9 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode b.name === commitish.sha, }); } @@ -111,7 +111,7 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode e.document?.uri.path === this.uri.path)) ) { return true; @@ -167,7 +167,7 @@ export class FileHistoryTrackerNode extends SubscribeableViewNode this._options.getBranchAndTagTips?.(sha, { compact: true }), messageTruncateAtNewLine: true, }), @@ -111,7 +111,7 @@ export class FileRevisionAsCommitNode extends ViewRefFileNode this._options.getBranchAndTagTips?.(sha, { compact: true }), messageTruncateAtNewLine: true, }); @@ -121,14 +121,14 @@ export class FileRevisionAsCommitNode extends ViewRefFileNode { if (!this.commit.hasConflicts) return undefined; - const mergeBase = await Container.git.getMergeBase(this.repoPath, 'MERGE_HEAD', 'HEAD'); + const mergeBase = await Container.instance.git.getMergeBase(this.repoPath, 'MERGE_HEAD', 'HEAD'); return GitUri.fromFile(this.file, this.repoPath, mergeBase ?? 'HEAD'); } private async getTooltip() { - const remotes = await Container.git.getRemotes(this.commit.repoPath); - const remote = await Container.git.getRichRemoteProvider(remotes); + const remotes = await Container.instance.git.getRemotes(this.commit.repoPath); + const remote = await Container.instance.git.getRichRemoteProvider(remotes); let autolinkedIssuesOrPullRequests; let pr; if (remote?.provider != null) { [autolinkedIssuesOrPullRequests, pr] = await Promise.all([ - Container.autolinks.getIssueOrPullRequestLinks(this.commit.message, remote), - Container.git.getPullRequestForCommit(this.commit.ref, remote.provider), + Container.instance.autolinks.getIssueOrPullRequestLinks(this.commit.message, remote), + Container.instance.git.getPullRequestForCommit(this.commit.ref, remote.provider), ]); } @@ -234,7 +234,7 @@ export class FileRevisionAsCommitNode extends ViewRefFileNode b.name === commitish.sha, }); } @@ -123,7 +123,7 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode e.document?.uri.path === this.uri.path)) ) { return true; @@ -211,13 +211,13 @@ export class LineHistoryTrackerNode extends SubscribeableViewNode { + Container.instance.lineTracker.onDidChangeActiveLines((e: LinesChangeEvent) => { if (e.pending) return; onActiveLinesChanged(e); diff --git a/src/views/nodes/mergeConflictCurrentChangesNode.ts b/src/views/nodes/mergeConflictCurrentChangesNode.ts index ac3a507..1b04750 100644 --- a/src/views/nodes/mergeConflictCurrentChangesNode.ts +++ b/src/views/nodes/mergeConflictCurrentChangesNode.ts @@ -25,7 +25,7 @@ export class MergeConflictCurrentChangesNode extends ViewNode { - const commit = await Container.git.getCommit(this.status.repoPath, 'HEAD'); + const commit = await Container.instance.git.getCommit(this.status.repoPath, 'HEAD'); const item = new TreeItem('Current changes', TreeItemCollapsibleState.None); item.contextValue = ContextValues.MergeConflictCurrentChanges; @@ -33,7 +33,7 @@ export class MergeConflictCurrentChangesNode extends ViewNode { - const commit = await Container.git.getCommit( + const commit = await Container.instance.git.getCommit( this.status.repoPath, this.status.type === 'rebase' ? this.status.steps.current.commit.ref : this.status.HEAD.ref, ); @@ -38,7 +38,7 @@ export class MergeConflictIncomingChangesNode extends ViewNode { ); } - const commit = await Container.git.getCommit( + const commit = await Container.instance.git.getCommit( this.rebaseStatus.repoPath, this.rebaseStatus.steps.current.commit.ref, ); @@ -163,7 +163,7 @@ export class RebaseCommitNode extends ViewRefNode implements PageableVi item.contextValue = ContextValues.Reflog; item.description = 'experimental'; item.iconPath = { - dark: Container.context.asAbsolutePath('images/dark/icon-activity.svg'), - light: Container.context.asAbsolutePath('images/light/icon-activity.svg'), + dark: Container.instance.context.asAbsolutePath('images/dark/icon-activity.svg'), + light: Container.instance.context.asAbsolutePath('images/light/icon-activity.svg'), }; return item; @@ -71,7 +71,7 @@ export class ReflogNode extends ViewNode implements PageableVi private _reflog: GitReflog | undefined; private async getReflog() { if (this._reflog === undefined) { - this._reflog = await Container.git.getIncomingActivity(this.repo.path, { + this._reflog = await Container.instance.git.getIncomingActivity(this.repo.path, { all: true, limit: this.limit ?? this.view.config.defaultItemLimit, }); diff --git a/src/views/nodes/reflogRecordNode.ts b/src/views/nodes/reflogRecordNode.ts index 533801b..6862e59 100644 --- a/src/views/nodes/reflogRecordNode.ts +++ b/src/views/nodes/reflogRecordNode.ts @@ -90,7 +90,7 @@ export class ReflogRecordNode extends ViewNode implements Page private async getLog() { if (this._log === undefined) { const range = `${this.record.previousSha}..${this.record.sha}`; - this._log = await Container.git.getLog(this.uri.repoPath!, { + this._log = await Container.instance.git.getLog(this.uri.repoPath!, { limit: this.limit ?? this.view.config.defaultItemLimit, ref: range, }); diff --git a/src/views/nodes/remoteNode.ts b/src/views/nodes/remoteNode.ts index 2bc172e..3aded68 100644 --- a/src/views/nodes/remoteNode.ts +++ b/src/views/nodes/remoteNode.ts @@ -117,8 +117,8 @@ export class RemoteNode extends ViewNode { provider.icon === 'remote' ? new ThemeIcon('cloud') : { - dark: Container.context.asAbsolutePath(`images/dark/icon-${provider.icon}.svg`), - light: Container.context.asAbsolutePath(`images/light/icon-${provider.icon}.svg`), + dark: Container.instance.context.asAbsolutePath(`images/dark/icon-${provider.icon}.svg`), + light: Container.instance.context.asAbsolutePath(`images/light/icon-${provider.icon}.svg`), }; if (provider.hasApi()) { diff --git a/src/views/nodes/repositoriesNode.ts b/src/views/nodes/repositoriesNode.ts index cb9a6ad..c246b6c 100644 --- a/src/views/nodes/repositoriesNode.ts +++ b/src/views/nodes/repositoriesNode.ts @@ -36,7 +36,7 @@ export class RepositoriesNode extends SubscribeableViewNode { async getChildren(): Promise { if (this._children === undefined) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) return [new MessageNode(this.view, this, 'No repositories could be found.')]; this._children = repositories.map(r => new RepositoryNode(GitUri.fromRepoPath(r.path), this.view, this, r)); @@ -65,7 +65,7 @@ export class RepositoriesNode extends SubscribeableViewNode { return; } - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0 && (this._children === undefined || this._children.length === 0)) return; if (repositories.length === 0) { @@ -98,7 +98,7 @@ export class RepositoriesNode extends SubscribeableViewNode { @debug() protected subscribe() { - const subscriptions = [Container.git.onDidChangeRepositories(this.onRepositoriesChanged, this)]; + const subscriptions = [Container.instance.git.onDidChangeRepositories(this.onRepositoriesChanged, this)]; if (this.view.config.autoReveal) { subscriptions.push( diff --git a/src/views/nodes/repositoryNode.ts b/src/views/nodes/repositoryNode.ts index f77103d..1c7b247 100644 --- a/src/views/nodes/repositoryNode.ts +++ b/src/views/nodes/repositoryNode.ts @@ -87,8 +87,8 @@ export class RepositoryNode extends SubscribeableViewNode { } const [mergeStatus, rebaseStatus] = await Promise.all([ - Container.git.getMergeStatus(status.repoPath), - Container.git.getRebaseStatus(status.repoPath), + Container.instance.git.getMergeStatus(status.repoPath), + Container.instance.git.getRebaseStatus(status.repoPath), ]); if (mergeStatus != null) { @@ -211,7 +211,9 @@ export class RepositoryNode extends SubscribeableViewNode { let providerName; if (status.upstream != null) { - const providers = GitRemote.getHighlanderProviders(await Container.git.getRemotes(status.repoPath)); + const providers = GitRemote.getHighlanderProviders( + await Container.instance.git.getRemotes(status.repoPath), + ); providerName = providers?.length ? providers[0].name : undefined; } else { const remote = await status.getRemote(); @@ -265,8 +267,8 @@ export class RepositoryNode extends SubscribeableViewNode { : '' }`; item.iconPath = { - dark: Container.context.asAbsolutePath(`images/dark/icon-repo${iconSuffix}.svg`), - light: Container.context.asAbsolutePath(`images/light/icon-repo${iconSuffix}.svg`), + dark: Container.instance.context.asAbsolutePath(`images/dark/icon-repo${iconSuffix}.svg`), + light: Container.instance.context.asAbsolutePath(`images/light/icon-repo${iconSuffix}.svg`), }; item.tooltip = new MarkdownString(tooltip, true); diff --git a/src/views/nodes/resultsCommitsNode.ts b/src/views/nodes/resultsCommitsNode.ts index ded52b0..30fad93 100644 --- a/src/views/nodes/resultsCommitsNode.ts +++ b/src/views/nodes/resultsCommitsNode.ts @@ -69,7 +69,7 @@ export class ResultsCommitsNode | undefined; private async getCommitsQueryResults() { if (this._commitsQueryResults == null) { - this._commitsQueryResults = this._results.query(this.limit ?? Container.config.advanced.maxSearchItems); + this._commitsQueryResults = this._results.query( + this.limit ?? Container.instance.config.advanced.maxSearchItems, + ); const results = await this._commitsQueryResults; this._hasMore = results.hasMore; diff --git a/src/views/nodes/resultsFileNode.ts b/src/views/nodes/resultsFileNode.ts index d2b76e0..98cfdb7 100644 --- a/src/views/nodes/resultsFileNode.ts +++ b/src/views/nodes/resultsFileNode.ts @@ -49,8 +49,8 @@ export class ResultsFileNode extends ViewRefFileNode implements FileNode { const statusIcon = GitFile.getStatusIcon(this.file.status); item.iconPath = { - dark: Container.context.asAbsolutePath(paths.join('images', 'dark', statusIcon)), - light: Container.context.asAbsolutePath(paths.join('images', 'light', statusIcon)), + dark: Container.instance.context.asAbsolutePath(paths.join('images', 'dark', statusIcon)), + light: Container.instance.context.asAbsolutePath(paths.join('images', 'light', statusIcon)), }; item.command = this.getCommand(); diff --git a/src/views/nodes/resultsFilesNode.ts b/src/views/nodes/resultsFilesNode.ts index 12b6d05..7b15e04 100644 --- a/src/views/nodes/resultsFilesNode.ts +++ b/src/views/nodes/resultsFilesNode.ts @@ -184,14 +184,18 @@ export class ResultsFilesNode extends ViewNode { const ref = this.filter === 'left' ? this.ref2 : this.ref1; - const mergeBase = await Container.git.getMergeBase(this.repoPath, this.ref1 || 'HEAD', this.ref2 || 'HEAD'); + const mergeBase = await Container.instance.git.getMergeBase( + this.repoPath, + this.ref1 || 'HEAD', + this.ref2 || 'HEAD', + ); if (mergeBase != null) { - const files = await Container.git.getDiffStatus(this.uri.repoPath!, `${mergeBase}..${ref}`); + const files = await Container.instance.git.getDiffStatus(this.uri.repoPath!, `${mergeBase}..${ref}`); if (files != null) { filterTo = new Set(files.map(f => f.fileName)); } } else { - const commit = await Container.git.getCommit(this.uri.repoPath!, ref || 'HEAD'); + const commit = await Container.instance.git.getCommit(this.uri.repoPath!, ref || 'HEAD'); if (commit?.files != null) { filterTo = new Set(commit.files.map(f => f.fileName)); } diff --git a/src/views/nodes/searchResultsNode.ts b/src/views/nodes/searchResultsNode.ts index 5d98a96..5af0fd2 100644 --- a/src/views/nodes/searchResultsNode.ts +++ b/src/views/nodes/searchResultsNode.ts @@ -132,8 +132,8 @@ export class SearchResultsNode extends ViewNode implements const item = await this.ensureResults().getTreeItem(); item.id = this.id; item.contextValue = `${ContextValues.SearchResults}${this._pinned ? '+pinned' : ''}`; - if ((await Container.git.getRepositoryCount()) > 1) { - const repo = await Container.git.getRepository(this.repoPath); + if ((await Container.instance.git.getRepositoryCount()) > 1) { + const repo = await Container.instance.git.getRepository(this.repoPath); item.description = repo?.formattedName ?? this.repoPath; } if (this._pinned) { @@ -264,7 +264,7 @@ export class SearchResultsNode extends ViewNode implements let useCacheOnce = true; return async (limit: number | undefined) => { - log = await (log ?? Container.git.getLogForSearch(this.repoPath, this.search)); + log = await (log ?? Container.instance.git.getLogForSearch(this.repoPath, this.search)); if (!useCacheOnce && log != null && log.query != null) { log = await log.query(limit); diff --git a/src/views/nodes/stashNode.ts b/src/views/nodes/stashNode.ts index 98afd7d..33cca4d 100644 --- a/src/views/nodes/stashNode.ts +++ b/src/views/nodes/stashNode.ts @@ -61,18 +61,18 @@ export class StashNode extends ViewRefNode { item.contextValue = ContextValues.Stashes; item.iconPath = { - dark: Container.context.asAbsolutePath('images/dark/icon-stash.svg'), - light: Container.context.asAbsolutePath('images/light/icon-stash.svg'), + dark: Container.instance.context.asAbsolutePath('images/dark/icon-stash.svg'), + light: Container.instance.context.asAbsolutePath('images/light/icon-stash.svg'), }; return item; diff --git a/src/views/nodes/statusFileNode.ts b/src/views/nodes/statusFileNode.ts index c316af0..febf10d 100644 --- a/src/views/nodes/statusFileNode.ts +++ b/src/views/nodes/statusFileNode.ts @@ -111,8 +111,8 @@ export class StatusFileNode extends ViewNode implements FileNo const icon = GitFile.getStatusIcon(this.file.status); item.iconPath = { - dark: Container.context.asAbsolutePath(paths.join('images', 'dark', icon)), - light: Container.context.asAbsolutePath(paths.join('images', 'light', icon)), + dark: Container.instance.context.asAbsolutePath(paths.join('images', 'dark', icon)), + light: Container.instance.context.asAbsolutePath(paths.join('images', 'light', icon)), }; } diff --git a/src/views/nodes/statusFilesNode.ts b/src/views/nodes/statusFilesNode.ts index aa0f989..5bd9e93 100644 --- a/src/views/nodes/statusFilesNode.ts +++ b/src/views/nodes/statusFilesNode.ts @@ -57,7 +57,7 @@ export class StatusFilesNode extends ViewNode { let log: GitLog | undefined; if (this.range != null) { - log = await Container.git.getLog(repoPath, { limit: 0, ref: this.range }); + log = await Container.instance.git.getLog(repoPath, { limit: 0, ref: this.range }); if (log != null) { files = [ ...Iterables.flatMap(log.commits.values(), c => @@ -135,7 +135,10 @@ export class StatusFilesNode extends ViewNode { if (this.range != null) { if (this.status.upstream != null && this.status.state.ahead > 0) { if (files > 0) { - const aheadFiles = await Container.git.getDiffStatus(this.repoPath, `${this.status.upstream}...`); + const aheadFiles = await Container.instance.git.getDiffStatus( + this.repoPath, + `${this.status.upstream}...`, + ); if (aheadFiles != null) { const uniques = new Set(); @@ -149,7 +152,10 @@ export class StatusFilesNode extends ViewNode { files = uniques.size; } } else { - const stats = await Container.git.getChangedFilesCount(this.repoPath, `${this.status.upstream}...`); + const stats = await Container.instance.git.getChangedFilesCount( + this.repoPath, + `${this.status.upstream}...`, + ); if (stats != null) { files += stats.files; } else { @@ -164,8 +170,8 @@ export class StatusFilesNode extends ViewNode { item.id = this.id; item.contextValue = ContextValues.StatusFiles; item.iconPath = { - dark: Container.context.asAbsolutePath('images/dark/icon-diff.svg'), - light: Container.context.asAbsolutePath('images/light/icon-diff.svg'), + dark: Container.instance.context.asAbsolutePath('images/dark/icon-diff.svg'), + light: Container.instance.context.asAbsolutePath('images/light/icon-diff.svg'), }; return item; diff --git a/src/views/nodes/tagNode.ts b/src/views/nodes/tagNode.ts index 4887756..fb2b7b0 100644 --- a/src/views/nodes/tagNode.ts +++ b/src/views/nodes/tagNode.ts @@ -45,7 +45,10 @@ export class TagNode extends ViewRefNode - Container.git.getCommitCount(this.tag.repoPath, this.tag.name), + Container.instance.git.getCommitCount(this.tag.repoPath, this.tag.name), ), ); } @@ -95,7 +98,7 @@ export class TagNode extends ViewRefNode { async getChildren(): Promise { if (this.children == null) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) { this.view.message = 'No remotes could be found.'; @@ -136,8 +136,8 @@ export class RemotesViewNode extends ViewNode { export class RemotesView extends ViewBase { protected readonly configKey = 'remotes'; - constructor() { - super('gitlens.views.remotes', 'Remotes'); + constructor(container: Container) { + super('gitlens.views.remotes', 'Remotes', container); } getRoot() { @@ -145,7 +145,7 @@ export class RemotesView extends ViewBase { } protected registerCommands(): Disposable[] { - void Container.viewCommands; + void this.container.viewCommands; return [ commands.registerCommand( @@ -156,7 +156,7 @@ export class RemotesView extends ViewBase { commands.registerCommand( this.getQualifiedCommand('refresh'), async () => { - await Container.git.resetCaches('branches', 'remotes'); + await this.container.git.resetCaches('branches', 'remotes'); return this.refresh(true); }, this, @@ -259,7 +259,7 @@ export class RemotesView extends ViewBase { const repoNodeId = RepositoryNode.getId(commit.repoPath); // Get all the remote branches the commit is on - const branches = await Container.git.getCommitBranches(commit.repoPath, commit.ref, { remotes: true }); + const branches = await this.container.git.getCommitBranches(commit.repoPath, commit.ref, { remotes: true }); if (branches.length === 0) return undefined; const remotes = branches.map(b => b.split('/', 1)[0]); diff --git a/src/views/repositoriesView.ts b/src/views/repositoriesView.ts index 5b7324a..a17dd95 100644 --- a/src/views/repositoriesView.ts +++ b/src/views/repositoriesView.ts @@ -49,8 +49,8 @@ import { ViewBase } from './viewBase'; export class RepositoriesView extends ViewBase { protected readonly configKey = 'repositories'; - constructor() { - super('gitlens.views.repositories', 'Repositories'); + constructor(container: Container) { + super('gitlens.views.repositories', 'Repositories', container); } private _onDidChangeAutoRefresh = new EventEmitter(); @@ -63,7 +63,7 @@ export class RepositoriesView extends ViewBase { - await Container.git.resetCaches('branches', 'contributors', 'remotes', 'stashes', 'status', 'tags'); + await this.container.git.resetCaches( + 'branches', + 'contributors', + 'remotes', + 'stashes', + 'status', + 'tags', + ); return this.refresh(true); }, this, @@ -106,12 +113,12 @@ export class RepositoriesView extends ViewBase this.setAutoRefresh(Container.config.views.repositories.autoRefresh, true), + () => this.setAutoRefresh(this.container.config.views.repositories.autoRefresh, true), this, ), commands.registerCommand( this.getQualifiedCommand('setAutoRefreshToOff'), - () => this.setAutoRefresh(Container.config.views.repositories.autoRefresh, false), + () => this.setAutoRefresh(this.container.config.views.repositories.autoRefresh, false), this, ), commands.registerCommand( @@ -262,7 +269,7 @@ export class RepositoriesView extends ViewBase(WorkspaceState.ViewsRepositoriesAutoRefresh, true) + this.container.context.workspaceState.get(WorkspaceState.ViewsRepositoriesAutoRefresh, true) ); } @@ -328,7 +335,7 @@ export class RepositoriesView extends ViewBase n.commit !== undefined && n.commit.ref === commit.ref, { allowPaging: true, @@ -359,7 +366,7 @@ export class RepositoriesView extends ViewBase b.split('/', 1)[0]); @@ -663,12 +670,12 @@ export class RepositoriesView extends ViewBase( + workspaceEnabled = this.container.context.workspaceState.get( WorkspaceState.ViewsRepositoriesAutoRefresh, true, ); } else { - await Container.context.workspaceState.update( + await this.container.context.workspaceState.update( WorkspaceState.ViewsRepositoriesAutoRefresh, workspaceEnabled, ); diff --git a/src/views/searchAndCompareView.ts b/src/views/searchAndCompareView.ts index 8ffdd15..a0357e3 100644 --- a/src/views/searchAndCompareView.ts +++ b/src/views/searchAndCompareView.ts @@ -254,8 +254,8 @@ export class SearchAndCompareViewNode extends ViewNode { export class SearchAndCompareView extends ViewBase { protected readonly configKey = 'searchAndCompare'; - constructor() { - super('gitlens.views.searchAndCompare', 'Search & Compare'); + constructor(container: Container) { + super('gitlens.views.searchAndCompare', 'Search & Compare', container); void setContext(ContextKeys.ViewsSearchAndCompareKeepResults, this.keepResults); } @@ -265,7 +265,7 @@ export class SearchAndCompareView extends ViewBase this.clear(), this), @@ -353,7 +353,10 @@ export class SearchAndCompareView extends ViewBase(WorkspaceState.ViewsSearchAndCompareKeepResults, true); + return this.container.context.workspaceState.get( + WorkspaceState.ViewsSearchAndCompareKeepResults, + true, + ); } clear() { @@ -431,12 +434,12 @@ export class SearchAndCompareView extends ViewBase( + let savedPins = this.container.context.workspaceState.get( WorkspaceState.ViewsSearchAndComparePinnedItems, ); if (savedPins == null) { // Migrate any deprecated pinned items - const deprecatedPins = Container.context.workspaceState.get( + const deprecatedPins = this.container.context.workspaceState.get( WorkspaceState.Deprecated_PinnedComparisons, ); if (deprecatedPins == null) return []; @@ -452,8 +455,11 @@ export class SearchAndCompareView extends ViewBase(WorkspaceState.ViewsSearchAndComparePinnedItems); + let pinned = this.container.context.workspaceState.get( + WorkspaceState.ViewsSearchAndComparePinnedItems, + ); if (pinned == null) { pinned = Object.create(null) as PinnedItems; } @@ -486,7 +494,7 @@ export class SearchAndCompareView extends ViewBase { async getChildren(): Promise { if (this.children == null) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) { this.view.message = 'No stashes could be found.'; @@ -117,8 +117,8 @@ export class StashesViewNode extends ViewNode { export class StashesView extends ViewBase { protected readonly configKey = 'stashes'; - constructor() { - super('gitlens.views.stashes', 'Stashes'); + constructor(container: Container) { + super('gitlens.views.stashes', 'Stashes', container); } getRoot() { @@ -126,7 +126,7 @@ export class StashesView extends ViewBase { } protected registerCommands(): Disposable[] { - void Container.viewCommands; + void this.container.viewCommands; return [ commands.registerCommand( @@ -137,7 +137,7 @@ export class StashesView extends ViewBase { commands.registerCommand( this.getQualifiedCommand('refresh'), async () => { - await Container.git.resetCaches('stashes'); + await this.container.git.resetCaches('stashes'); return this.refresh(true); }, this, diff --git a/src/views/tagsView.ts b/src/views/tagsView.ts index 5c37606..ba830b6 100644 --- a/src/views/tagsView.ts +++ b/src/views/tagsView.ts @@ -55,7 +55,7 @@ export class TagsViewNode extends ViewNode { async getChildren(): Promise { if (this.children == null) { - const repositories = await Container.git.getOrderedRepositories(); + const repositories = await Container.instance.git.getOrderedRepositories(); if (repositories.length === 0) { this.view.message = 'No tags could be found.'; @@ -124,8 +124,8 @@ export class TagsViewNode extends ViewNode { export class TagsView extends ViewBase { protected readonly configKey = 'tags'; - constructor() { - super('gitlens.views.tags', 'Tags'); + constructor(container: Container) { + super('gitlens.views.tags', 'Tags', container); } getRoot() { @@ -133,7 +133,7 @@ export class TagsView extends ViewBase { } protected registerCommands(): Disposable[] { - void Container.viewCommands; + void this.container.viewCommands; return [ commands.registerCommand( @@ -144,7 +144,7 @@ export class TagsView extends ViewBase { commands.registerCommand( this.getQualifiedCommand('refresh'), async () => { - await Container.git.resetCaches('tags'); + await this.container.git.resetCaches('tags'); return this.refresh(true); }, this, diff --git a/src/views/viewBase.ts b/src/views/viewBase.ts index 67667d8..b887539 100644 --- a/src/views/viewBase.ts +++ b/src/views/viewBase.ts @@ -114,8 +114,10 @@ export abstract class ViewBase< private readonly _lastKnownLimits = new Map(); - constructor(public readonly id: string, public readonly name: string) { - if (Logger.isDebugging || Container.config.debug) { + constructor(public readonly id: string, public readonly name: string, protected readonly container: Container) { + this.disposables.push(container.onReady(this.onReady, this)); + + if (Logger.isDebugging || this.container.config.debug) { function addDebuggingInfo(item: TreeItem, node: ViewNode, parent: ViewNode | undefined) { if (item.tooltip == null) { item.tooltip = new MarkdownString( @@ -164,9 +166,14 @@ export abstract class ViewBase< } this.disposables.push(...this.registerCommands()); + } - this.initialize({ showCollapseAll: this.showCollapseAll }); + dispose() { + Disposable.from(...this.disposables).dispose(); + } + private onReady() { + this.initialize({ showCollapseAll: this.showCollapseAll }); setImmediate(() => this.onConfigurationChanged()); } @@ -184,11 +191,6 @@ export abstract class ViewBase< return false; } - - dispose() { - Disposable.from(...this.disposables).dispose(); - } - private _title: string | undefined; get title(): string | undefined { return this._title; @@ -385,7 +387,7 @@ export abstract class ViewBase< ): Promise { const queue: (ViewNode | undefined)[] = [root, undefined]; - const defaultPageSize = Container.config.advanced.maxListItems; + const defaultPageSize = this.container.config.advanced.maxListItems; let depth = 0; let node: ViewNode | undefined; @@ -572,12 +574,15 @@ export abstract class ViewBase< private _config: (ViewConfig & ViewsCommonConfig) | undefined; get config(): ViewConfig & ViewsCommonConfig { if (this._config == null) { - const cfg = { ...Container.config.views }; + const cfg = { ...this.container.config.views }; for (const view of viewsConfigKeys) { delete cfg[view]; } - this._config = { ...(cfg as ViewsCommonConfig), ...(Container.config.views[this.configKey] as ViewConfig) }; + this._config = { + ...(cfg as ViewsCommonConfig), + ...(this.container.config.views[this.configKey] as ViewConfig), + }; } return this._config; diff --git a/src/views/viewCommands.ts b/src/views/viewCommands.ts index 4d22fe0..7c89037 100644 --- a/src/views/viewCommands.ts +++ b/src/views/viewCommands.ts @@ -63,7 +63,7 @@ interface CompareSelectedInfo { } export class ViewCommands { - constructor() { + constructor(private readonly container: Container) { commands.registerCommand('gitlens.views.clearNode', (n: ViewNode) => canClearNode(n) && n.clear(), this); commands.registerCommand( 'gitlens.views.copy', @@ -293,7 +293,9 @@ export class ViewCommands { ? node.branch : undefined; if (from == null) { - const branch = await Container.git.getBranch(node?.repoPath ?? (await Container.git.getActiveRepoPath())); + const branch = await this.container.git.getBranch( + node?.repoPath ?? (await this.container.git.getActiveRepoPath()), + ); from = branch; } return GitActions.Branch.create(node?.repoPath, from); @@ -341,7 +343,9 @@ export class ViewCommands { ? node.branch : undefined; if (from == null) { - const branch = await Container.git.getBranch(node?.repoPath ?? (await Container.git.getActiveRepoPath())); + const branch = await this.container.git.getBranch( + node?.repoPath ?? (await this.container.git.getActiveRepoPath()), + ); from = branch; } return GitActions.Tag.create(node?.repoPath, from); @@ -391,7 +395,7 @@ export class ViewCommands { } void (await this.openFile(node, { preserveFocus: true, preview: true })); - void (await Container.fileAnnotations.toggle( + void (await this.container.fileAnnotations.toggle( window.activeTextEditor, FileAnnotationType.Changes, { sha: node.ref.ref }, @@ -413,7 +417,7 @@ export class ViewCommands { } void (await this.openFile(node, { preserveFocus: true, preview: true })); - void (await Container.fileAnnotations.toggle( + void (await this.container.fileAnnotations.toggle( window.activeTextEditor, FileAnnotationType.Changes, { sha: node.ref.ref, only: true }, @@ -625,7 +629,7 @@ export class ViewCommands { return; } - void (await Container.git.stageFile(node.repoPath, node.file.fileName)); + void (await this.container.git.stageFile(node.repoPath, node.file.fileName)); void node.triggerChange(); } @@ -633,7 +637,7 @@ export class ViewCommands { private async stageDirectory(node: FolderNode) { if (!(node instanceof FolderNode) || !node.relativePath) return; - void (await Container.git.stageDirectory(node.repoPath, node.relativePath)); + void (await this.container.git.stageDirectory(node.repoPath, node.relativePath)); void node.triggerChange(); } @@ -653,7 +657,7 @@ export class ViewCommands { @debug() private switch(node?: ViewRefNode | BranchesNode) { if (node == null) { - return GitActions.switchTo(Container.git.getHighlanderRepoPath()); + return GitActions.switchTo(this.container.git.getHighlanderRepoPath()); } if (!(node instanceof ViewRefNode) && !(node instanceof BranchesNode)) return Promise.resolve(); @@ -702,7 +706,7 @@ export class ViewCommands { return; } - void (await Container.git.unStageFile(node.repoPath, node.file.fileName)); + void (await this.container.git.unStageFile(node.repoPath, node.file.fileName)); void node.triggerChange(); } @@ -710,7 +714,7 @@ export class ViewCommands { private async unstageDirectory(node: FolderNode) { if (!(node instanceof FolderNode) || !node.relativePath) return; - void (await Container.git.unStageDirectory(node.repoPath, node.relativePath)); + void (await this.container.git.unStageDirectory(node.repoPath, node.relativePath)); void node.triggerChange(); } @@ -731,7 +735,7 @@ export class ViewCommands { private compareHeadWith(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return Promise.resolve(); - return Container.searchAndCompareView.compare(node.repoPath, 'HEAD', node.ref); + return this.container.searchAndCompareView.compare(node.repoPath, 'HEAD', node.ref); } @debug() @@ -739,27 +743,27 @@ export class ViewCommands { if (!(node instanceof BranchNode)) return Promise.resolve(); if (node.branch.upstream == null) return Promise.resolve(); - return Container.searchAndCompareView.compare(node.repoPath, node.ref, node.branch.upstream.name); + return this.container.searchAndCompareView.compare(node.repoPath, node.ref, node.branch.upstream.name); } @debug() private compareWorkingWith(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return Promise.resolve(); - return Container.searchAndCompareView.compare(node.repoPath, '', node.ref); + return this.container.searchAndCompareView.compare(node.repoPath, '', node.ref); } @debug() private async compareAncestryWithWorking(node: BranchNode) { if (!(node instanceof BranchNode)) return undefined; - const branch = await Container.git.getBranch(node.repoPath); + const branch = await this.container.git.getBranch(node.repoPath); if (branch == null) return undefined; - const commonAncestor = await Container.git.getMergeBase(node.repoPath, branch.ref, node.ref.ref); + const commonAncestor = await this.container.git.getMergeBase(node.repoPath, branch.ref, node.ref.ref); if (commonAncestor == null) return undefined; - return Container.searchAndCompareView.compare( + return this.container.searchAndCompareView.compare( node.repoPath, { ref: commonAncestor, label: `ancestry with ${node.ref.ref} (${GitRevision.shorten(commonAncestor)})` }, '', @@ -770,14 +774,14 @@ export class ViewCommands { private compareWithSelected(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return; - Container.searchAndCompareView.compareWithSelected(node.repoPath, node.ref); + this.container.searchAndCompareView.compareWithSelected(node.repoPath, node.ref); } @debug() private selectForCompare(node: ViewRefNode) { if (!(node instanceof ViewRefNode)) return; - Container.searchAndCompareView.selectForCompare(node.repoPath, node.ref); + this.container.searchAndCompareView.selectForCompare(node.repoPath, node.ref); } @debug() diff --git a/src/vsls/host.ts b/src/vsls/host.ts index ad2e425..3bcba14 100644 --- a/src/vsls/host.ts +++ b/src/vsls/host.ts @@ -50,13 +50,13 @@ export class VslsHostService implements Disposable { static ServiceId = 'proxy'; @log() - static async share(api: LiveShare) { + static async share(api: LiveShare, container: Container) { const service = await api.shareService(this.ServiceId); if (service == null) { throw new Error('Failed to share host service'); } - return new VslsHostService(api, service); + return new VslsHostService(api, service, container); } private readonly _disposable: Disposable; @@ -65,7 +65,11 @@ export class VslsHostService implements Disposable { private _sharedPathsRegex: RegExp | undefined; private _sharedToLocalPaths = new Map(); - constructor(private readonly _api: LiveShare, private readonly _service: SharedService) { + constructor( + private readonly _api: LiveShare, + private readonly _service: SharedService, + private readonly container: Container, + ) { _service.onDidChangeIsServiceAvailable(this.onAvailabilityChanged.bind(this)); this._disposable = Disposable.from(workspace.onDidChangeWorkspaceFolders(this.onWorkspaceFoldersChanged, this)); @@ -210,7 +214,7 @@ export class VslsHostService implements Disposable { const normalized = Strings.normalizePath(uri.fsPath, { stripTrailingSlash: true }).toLowerCase(); const repos = [ - ...Iterables.filterMap(await Container.git.getRepositories(), r => { + ...Iterables.filterMap(await this.container.git.getRepositories(), r => { if (!r.normalizedPath.startsWith(normalized)) return undefined; const vslsUri = this.convertLocalUriToShared(r.folder.uri); diff --git a/src/vsls/vsls.ts b/src/vsls/vsls.ts index 3120281..4453510 100644 --- a/src/vsls/vsls.ts +++ b/src/vsls/vsls.ts @@ -33,7 +33,7 @@ function contactStatusToPresence(status: string | undefined): ContactPresence { } export class VslsController implements Disposable { - private _disposable: Disposable | undefined; + private _disposable: Disposable; private _guest: VslsGuestService | undefined; private _host: VslsHostService | undefined; @@ -42,16 +42,20 @@ export class VslsController implements Disposable { private _api: Promise | undefined; - constructor() { - void this.initialize(); + constructor(private readonly container: Container) { + this._disposable = Disposable.from(container.onReady(this.onReady, this)); } dispose() { - this._disposable?.dispose(); + this._disposable.dispose(); this._host?.dispose(); this._guest?.dispose(); } + private onReady(): void { + void this.initialize(); + } + private async initialize() { try { // If we have a vsls: workspace open, we might be a guest, so wait until live share transitions into a mode @@ -76,6 +80,7 @@ export class VslsController implements Disposable { void setContext(ContextKeys.Vsls, true); this._disposable = Disposable.from( + this._disposable, api.onDidChangeSession(e => this.onLiveShareSessionChanged(api, e), this), ); } catch (ex) { @@ -157,7 +162,7 @@ export class VslsController implements Disposable { @debug() @timeout(250) maybeGetPresence(email: string | undefined): Promise { - return Container.vsls.getContactPresence(email); + return this.getContactPresence(email); } async invite(email: string | undefined) { @@ -197,8 +202,8 @@ export class VslsController implements Disposable { case 1 /*Role.Host*/: this.setReadonly(false); void setContext(ContextKeys.Vsls, 'host'); - if (Container.config.liveshare.allowGuestAccess) { - this._host = await VslsHostService.share(api); + if (this.container.config.liveshare.allowGuestAccess) { + this._host = await VslsHostService.share(api, this.container); } break; case 2 /*Role.Guest*/: diff --git a/src/webviews/rebaseEditor.ts b/src/webviews/rebaseEditor.ts index 6fc6926..90a92cf 100644 --- a/src/webviews/rebaseEditor.ts +++ b/src/webviews/rebaseEditor.ts @@ -97,7 +97,7 @@ interface RebaseEditorContext { export class RebaseEditorProvider implements CustomTextEditorProvider, Disposable { private readonly _disposable: Disposable; - constructor() { + constructor(private readonly container: Container) { this._disposable = Disposable.from( window.registerCustomEditorProvider('gitlens.rebase', this, { supportsMultipleEditorsPerDocument: false, @@ -166,7 +166,7 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl @debug({ args: false }) async resolveCustomTextEditor(document: TextDocument, panel: WebviewPanel, _token: CancellationToken) { const repoPath = Strings.normalizePath(Uri.joinPath(document.uri, '..', '..', '..').fsPath); - const repo = await Container.git.getRepository(repoPath); + const repo = await this.container.git.getRepository(repoPath); const subscriptions: Disposable[] = []; const context: RebaseEditorContext = { @@ -242,8 +242,8 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl } private async parseState(context: RebaseEditorContext): Promise { - const branch = await Container.git.getBranch(context.repoPath); - const state = await parseRebaseTodo(context.document.getText(), context.repoPath, branch?.name); + const branch = await this.container.git.getBranch(context.repoPath); + const state = await parseRebaseTodo(this.container, context.document.getText(), context.repoPath, branch?.name); return state; } @@ -474,13 +474,13 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl } private async getHtml(context: RebaseEditorContext): Promise { - const uri = Uri.joinPath(Container.context.extensionUri, 'dist', 'webviews', 'rebase.html'); + const uri = Uri.joinPath(this.container.context.extensionUri, 'dist', 'webviews', 'rebase.html'); const content = new TextDecoder('utf8').decode(await workspace.fs.readFile(uri)); const bootstrap = await this.parseState(context); const cspSource = context.panel.webview.cspSource; const cspNonce = randomBytes(16).toString('base64'); - const root = context.panel.webview.asWebviewUri(Container.context.extensionUri).toString(); + const root = context.panel.webview.asWebviewUri(this.container.context.extensionUri).toString(); const html = content .replace(/#{(head|body|endOfBody)}/i, (_substring, token) => { @@ -511,6 +511,7 @@ export class RebaseEditorProvider implements CustomTextEditorProvider, Disposabl } async function parseRebaseTodo( + container: Container, contents: string | { entries: RebaseEntry[]; onto: string }, repoPath: string, branch: string | undefined, @@ -527,7 +528,7 @@ async function parseRebaseTodo( const authors = new Map(); const commits: Commit[] = []; - const log = await Container.git.getLogForSearch(repoPath, { + const log = await container.git.getLogForSearch(repoPath, { pattern: `${onto ? `#:${onto} ` : ''}${Iterables.join( Iterables.map(entries, e => `#:${e.ref}`), ' ', @@ -541,7 +542,7 @@ async function parseRebaseTodo( authors.set(ontoCommit.author, { author: ontoCommit.author, avatarUrl: ( - await ontoCommit.getAvatarUri({ defaultStyle: Container.config.defaultGravatarsStyle }) + await ontoCommit.getAvatarUri({ defaultStyle: container.config.defaultGravatarsStyle }) ).toString(true), email: ontoCommit.email, }); @@ -550,7 +551,7 @@ async function parseRebaseTodo( commits.push({ ref: ontoCommit.ref, author: ontoCommit.author, - date: ontoCommit.formatDate(Container.config.defaultDateFormat), + date: ontoCommit.formatDate(container.config.defaultDateFormat), dateFromNow: ontoCommit.formatDateFromNow(), message: ontoCommit.message || 'root', }); @@ -570,7 +571,7 @@ async function parseRebaseTodo( authors.set(commit.author, { author: commit.author, avatarUrl: ( - await commit.getAvatarUri({ defaultStyle: Container.config.defaultGravatarsStyle }) + await commit.getAvatarUri({ defaultStyle: container.config.defaultGravatarsStyle }) ).toString(true), email: commit.email, }); @@ -579,7 +580,7 @@ async function parseRebaseTodo( commits.push({ ref: commit.ref, author: commit.author, - date: commit.formatDate(Container.config.defaultDateFormat), + date: commit.formatDate(container.config.defaultDateFormat), dateFromNow: commit.formatDateFromNow(), message: commit.message, }); diff --git a/src/webviews/settingsWebview.ts b/src/webviews/settingsWebview.ts index dfdf655..a5684b7 100644 --- a/src/webviews/settingsWebview.ts +++ b/src/webviews/settingsWebview.ts @@ -2,6 +2,7 @@ import { commands, Disposable, workspace } from 'vscode'; import { Commands } from '../commands'; import { configuration } from '../configuration'; +import { Container } from '../container'; import { IpcMessage, onIpcCommand, @@ -16,8 +17,8 @@ const anchorRegex = /.*?#(.*)/; export class SettingsWebview extends WebviewBase { private _pendingJumpToAnchor: string | undefined; - constructor() { - super(Commands.ShowSettingsPage); + constructor(container: Container) { + super(Commands.ShowSettingsPage, container); this.disposable = Disposable.from( this.disposable, diff --git a/src/webviews/webviewBase.ts b/src/webviews/webviewBase.ts index fed46df..3a274d8 100644 --- a/src/webviews/webviewBase.ts +++ b/src/webviews/webviewBase.ts @@ -54,7 +54,7 @@ export abstract class WebviewBase implements Disposable { private _disposablePanel: Disposable | undefined; private _panel: WebviewPanel | undefined; - constructor(showCommand: Commands, private readonly _column?: ViewColumn) { + constructor(showCommand: Commands, protected readonly container: Container, private readonly _column?: ViewColumn) { this.disposable = Disposable.from( configuration.onDidChange(this.onConfigurationChanged, this), configuration.onDidChangeAny(this.onAnyConfigurationChanged, this), @@ -103,8 +103,8 @@ export abstract class WebviewBase implements Disposable { 'rebaseEditor.enabled', { name: 'workbench.editorAssociations', - enabled: () => Container.rebaseEditor.enabled, - update: Container.rebaseEditor.setEnabled, + enabled: () => this.container.rebaseEditor.enabled, + update: this.container.rebaseEditor.setEnabled, }, ], ]); @@ -214,10 +214,10 @@ export abstract class WebviewBase implements Disposable { let includePullRequest = false; switch (params.key) { case configuration.name('currentLine.format'): - includePullRequest = Container.config.currentLine.pullRequests.enabled; + includePullRequest = this.container.config.currentLine.pullRequests.enabled; break; case configuration.name('statusBar.format'): - includePullRequest = Container.config.statusBar.pullRequests.enabled; + includePullRequest = this.container.config.statusBar.pullRequests.enabled; break; } @@ -243,7 +243,7 @@ export abstract class WebviewBase implements Disposable { let preview; try { preview = CommitFormatter.fromTemplate(params.format, commit, { - dateFormat: Container.config.defaultDateFormat, + dateFormat: this.container.config.defaultDateFormat, pullRequestOrRemote: pr, messageTruncateAtNewLine: true, }); @@ -301,7 +301,7 @@ export abstract class WebviewBase implements Disposable { }, ); - this._panel.iconPath = Uri.file(Container.context.asAbsolutePath('images/gitlens-icon.png')); + this._panel.iconPath = Uri.file(this.container.context.asAbsolutePath('images/gitlens-icon.png')); this._disposablePanel = Disposable.from( this._panel, this._panel.onDidDispose(this.onPanelDisposed, this), @@ -323,7 +323,7 @@ export abstract class WebviewBase implements Disposable { } private async getHtml(webview: Webview): Promise { - const uri = Uri.joinPath(Container.context.extensionUri, 'dist', 'webviews', this.filename); + const uri = Uri.joinPath(this.container.context.extensionUri, 'dist', 'webviews', this.filename); const content = new TextDecoder('utf8').decode(await workspace.fs.readFile(uri)); const [head, body, endOfBody] = await Promise.all([ @@ -334,7 +334,7 @@ export abstract class WebviewBase implements Disposable { const cspSource = webview.cspSource; const cspNonce = randomBytes(16).toString('base64'); - const root = webview.asWebviewUri(Container.context.extensionUri).toString(); + const root = webview.asWebviewUri(this.container.context.extensionUri).toString(); const html = content .replace(/#{(head|body|endOfBody)}/i, (_substring, token) => { diff --git a/src/webviews/welcomeWebview.ts b/src/webviews/welcomeWebview.ts index 06b980f..49dcd4a 100644 --- a/src/webviews/welcomeWebview.ts +++ b/src/webviews/welcomeWebview.ts @@ -5,8 +5,8 @@ import { WelcomeState } from './protocol'; import { WebviewBase } from './webviewBase'; export class WelcomeWebview extends WebviewBase { - constructor() { - super(Commands.ShowWelcomePage); + constructor(container: Container) { + super(Commands.ShowWelcomePage, container); } get filename(): string { @@ -23,7 +23,7 @@ export class WelcomeWebview extends WebviewBase { override renderEndOfBody() { const bootstrap: WelcomeState = { - config: Container.config, + config: this.container.config, }; return `