From d4a62ce398f9b7935999bada34a0a56431b2c3ae Mon Sep 17 00:00:00 2001 From: Keith Daulton Date: Thu, 5 Jan 2023 15:23:52 -0500 Subject: [PATCH] Implements events for file and commit selection - visual file history listens for files and sends commit selection - commit details listens for commits - rebase editor, commits, stashes and graph views send commit selection --- src/plus/webviews/graph/graphWebview.ts | 51 +++++++++++++----- src/plus/webviews/timeline/timelineWebviewView.ts | 32 +++++++++-- src/views/commitsView.ts | 40 +++++++++++++- src/views/stashesView.ts | 35 +++++++++++- .../commitDetails/commitDetailsWebviewView.ts | 62 ++++------------------ src/webviews/rebase/rebaseEditor.ts | 20 ++++--- 6 files changed, 165 insertions(+), 75 deletions(-) diff --git a/src/plus/webviews/graph/graphWebview.ts b/src/plus/webviews/graph/graphWebview.ts index 8342049..fdf5506 100644 --- a/src/plus/webviews/graph/graphWebview.ts +++ b/src/plus/webviews/graph/graphWebview.ts @@ -480,11 +480,18 @@ export class GraphWebview extends WebviewBase { const { activeSelection } = this; if (activeSelection == null) return; - void GitActions.Commit.showDetailsView(activeSelection, { - pin: false, - preserveFocus: true, - preserveVisibility: this._showDetailsView === false, - }); + this.container.events.fire( + 'commit:selected', + { + commit: activeSelection, + pin: false, + preserveFocus: true, + preserveVisibility: this._showDetailsView === false, + }, + { + source: this.id, + }, + ); } protected override onVisibilityChanged(visible: boolean): void { @@ -645,7 +652,18 @@ export class GraphWebview extends WebviewBase { } } else if (e.type === 'row' && e.row) { const commit = this.getRevisionReference(this.repository?.path, e.row.id, e.row.type); - if (commit != null) return GitActions.Commit.showDetailsView(commit, { preserveFocus: e.preserveFocus }); + if (commit != null) { + this.container.events.fire( + 'commit:selected', + { + commit: commit, + preserveFocus: e.preserveFocus, + }, + { + source: this.id, + }, + ); + } } return Promise.resolve(); @@ -942,13 +960,20 @@ export class GraphWebview extends WebviewBase { if (commits == null) return; - void GitActions.Commit.showDetailsView(commits[0], { - pin: false, - preserveFocus: true, - preserveVisibility: this._firstSelection - ? this._showDetailsView === false - : this._showDetailsView !== 'selection', - }); + this.container.events.fire( + 'commit:selected', + { + commit: commits[0], + pin: false, + preserveFocus: true, + preserveVisibility: this._firstSelection + ? this._showDetailsView === false + : this._showDetailsView !== 'selection', + }, + { + source: this.id, + }, + ); this._firstSelection = false; } diff --git a/src/plus/webviews/timeline/timelineWebviewView.ts b/src/plus/webviews/timeline/timelineWebviewView.ts index 0e219eb..b731796 100644 --- a/src/plus/webviews/timeline/timelineWebviewView.ts +++ b/src/plus/webviews/timeline/timelineWebviewView.ts @@ -1,10 +1,10 @@ 'use strict'; import type { Disposable, TextEditor } from 'vscode'; import { commands, Uri, window } from 'vscode'; -import { GitActions } from '../../../commands/gitCommands.actions'; import { configuration } from '../../../configuration'; import { Commands, ContextKeys } from '../../../constants'; import type { Container } from '../../../container'; +import type { EventBusPackage } from '../../../eventBus'; import { PlusFeatures } from '../../../features'; import type { RepositoriesChangeEvent } from '../../../git/gitProviderService'; import { GitUri } from '../../../git/gitUri'; @@ -83,6 +83,7 @@ export class TimelineWebviewView extends WebviewViewBase { return [ this.container.subscription.onDidChange(this.onSubscriptionChanged, this), window.onDidChangeActiveTextEditor(debounce(this.onActiveEditorChanged, 250), this), + this.container.events.on('file:selected', this.onFileSelected, this), this.container.git.onDidChangeRepository(this.onRepositoryChanged, this), this.container.git.onDidChangeRepositories(this.onRepositoriesChanged, this), ]; @@ -133,7 +134,13 @@ export class TimelineWebviewView extends WebviewViewBase { const commit = await repository.getCommit(params.data.id); if (commit == null) return; - void GitActions.Commit.showDetailsView(commit, { pin: false, preserveFocus: true }); + this.container.events.fire( + 'commit:selected', + { + commit: commit, + }, + { source: this.id }, + ); }); break; @@ -165,6 +172,23 @@ export class TimelineWebviewView extends WebviewViewBase { } @debug({ args: false }) + private onFileSelected(event: EventBusPackage) { + if (event.data == null) return; + + let uri: Uri | undefined = event.data as Uri; + + if (uri != null) { + if (!this.container.git.isTrackable(uri)) { + uri = undefined; + } + } + + if (!this.updatePendingUri(uri)) return; + + this.updateState(); + } + + @debug({ args: false }) private onRepositoriesChanged(e: RepositoriesChangeEvent) { const changed = this.updatePendingUri(this._context.uri); @@ -371,7 +395,9 @@ export class TimelineWebviewView extends WebviewViewBase { private updateState(immediate: boolean = false) { if (!this.isReady || !this.visible) return; - this.updatePendingEditor(window.activeTextEditor); + if (this._pendingContext == null) { + this.updatePendingEditor(window.activeTextEditor); + } if (immediate) { void this.notifyDidChangeState(); diff --git a/src/views/commitsView.ts b/src/views/commitsView.ts index 671c83d..601d4c8 100644 --- a/src/views/commitsView.ts +++ b/src/views/commitsView.ts @@ -1,4 +1,9 @@ -import type { CancellationToken, ConfigurationChangeEvent } from 'vscode'; +import type { + CancellationToken, + ConfigurationChangeEvent, + TreeViewSelectionChangeEvent, + TreeViewVisibilityChangeEvent, +} from 'vscode'; import { Disposable, ProgressLocation, ThemeIcon, TreeItem, TreeItemCollapsibleState, window } from 'vscode'; import type { CommitsViewConfig } from '../configuration'; import { configuration, ViewFilesLayout, ViewShowBranchComparison } from '../configuration'; @@ -19,7 +24,10 @@ import { disposableInterval } from '../system/function'; import type { UsageChangeEvent } from '../usageTracker'; import { BranchNode } from './nodes/branchNode'; import { BranchTrackingStatusNode } from './nodes/branchTrackingStatusNode'; +import { CommitFileNode } from './nodes/commitFileNode'; +import { CommitNode } from './nodes/commitNode'; import { CommandMessageNode } from './nodes/common'; +import { FileRevisionAsCommitNode } from './nodes/fileRevisionAsCommitNode'; import { RepositoryNode } from './nodes/repositoryNode'; import type { ViewNode } from './nodes/viewNode'; import { RepositoriesSubscribeableNode, RepositoryFolderNode } from './nodes/viewNode'; @@ -288,6 +296,36 @@ export class CommitsView extends ViewBase { return true; } + protected override onSelectionChanged(e: TreeViewSelectionChangeEvent) { + super.onSelectionChanged(e); + this.notifySelections(); + } + + protected override onVisibilityChanged(e: TreeViewVisibilityChangeEvent) { + super.onVisibilityChanged(e); + + if (e.visible) { + this.notifySelections(); + } + } + + private notifySelections() { + const node = this.selection?.[0]; + + if ( + node != null && + (node instanceof CommitNode || node instanceof FileRevisionAsCommitNode || node instanceof CommitFileNode) + ) { + this.container.events.fire( + 'commit:selected', + { + commit: node.commit, + }, + { source: this.id }, + ); + } + } + async findCommit(commit: GitCommit | { repoPath: string; ref: string }, token?: CancellationToken) { const repoNodeId = RepositoryNode.getId(commit.repoPath); diff --git a/src/views/stashesView.ts b/src/views/stashesView.ts index 51c1dce..91b0573 100644 --- a/src/views/stashesView.ts +++ b/src/views/stashesView.ts @@ -1,4 +1,10 @@ -import type { CancellationToken, ConfigurationChangeEvent, Disposable } from 'vscode'; +import type { + CancellationToken, + ConfigurationChangeEvent, + Disposable, + TreeViewSelectionChangeEvent, + TreeViewVisibilityChangeEvent, +} from 'vscode'; import { ProgressLocation, TreeItem, TreeItemCollapsibleState, window } from 'vscode'; import type { StashesViewConfig } from '../configuration'; import { configuration, ViewFilesLayout } from '../configuration'; @@ -13,6 +19,7 @@ import { executeCommand } from '../system/command'; import { gate } from '../system/decorators/gate'; import { RepositoryNode } from './nodes/repositoryNode'; import { StashesNode } from './nodes/stashesNode'; +import { StashFileNode } from './nodes/stashFileNode'; import { StashNode } from './nodes/stashNode'; import type { ViewNode } from './nodes/viewNode'; import { RepositoriesSubscribeableNode, RepositoryFolderNode } from './nodes/viewNode'; @@ -149,6 +156,32 @@ export class StashesView extends ViewBase { return true; } + protected override onSelectionChanged(e: TreeViewSelectionChangeEvent) { + super.onSelectionChanged(e); + this.notifySelections(); + } + + protected override onVisibilityChanged(e: TreeViewVisibilityChangeEvent) { + super.onVisibilityChanged(e); + if (e.visible) { + this.notifySelections(); + } + } + + private notifySelections() { + const node = this.selection?.[0]; + + if (node != null && (node instanceof StashNode || node instanceof StashFileNode)) { + this.container.events.fire( + 'commit:selected', + { + commit: node.commit, + }, + { source: this.id }, + ); + } + } + findStash(stash: GitStashReference, token?: CancellationToken) { const repoNodeId = RepositoryNode.getId(stash.repoPath); diff --git a/src/webviews/commitDetails/commitDetailsWebviewView.ts b/src/webviews/commitDetails/commitDetailsWebviewView.ts index c52514f..e699020 100644 --- a/src/webviews/commitDetails/commitDetailsWebviewView.ts +++ b/src/webviews/commitDetails/commitDetailsWebviewView.ts @@ -1,10 +1,4 @@ -import type { - CancellationToken, - ConfigurationChangeEvent, - TextDocumentShowOptions, - TreeViewSelectionChangeEvent, - TreeViewVisibilityChangeEvent, -} from 'vscode'; +import type { CancellationToken, ConfigurationChangeEvent, TextDocumentShowOptions } from 'vscode'; import { CancellationTokenSource, Disposable, Uri, ViewColumn, window } from 'vscode'; import { serializeAutolink } from '../../annotations/autolinks'; import type { CopyShaToClipboardCommandArgs } from '../../commands'; @@ -13,6 +7,7 @@ import { configuration } from '../../configuration'; import { Commands, ContextKeys, CoreCommands } from '../../constants'; import type { Container } from '../../container'; import { getContext } from '../../context'; +import type { EventBusPackage } from '../../eventBus'; import { CommitFormatter } from '../../git/formatters/commitFormatter'; import type { GitCommit } from '../../git/models/commit'; import { isCommit } from '../../git/models/commit'; @@ -43,7 +38,6 @@ import { CommitNode } from '../../views/nodes/commitNode'; import { FileRevisionAsCommitNode } from '../../views/nodes/fileRevisionAsCommitNode'; import { StashFileNode } from '../../views/nodes/stashFileNode'; import { StashNode } from '../../views/nodes/stashNode'; -import type { ViewNode } from '../../views/nodes/viewNode'; import type { IpcMessage } from '../protocol'; import { onIpc } from '../protocol'; import { WebviewViewBase } from '../webviewViewBase'; @@ -117,6 +111,12 @@ export class CommitDetailsWebviewView extends WebviewViewBase({ args: { 0: o => @@ -253,13 +253,10 @@ export class CommitDetailsWebviewView extends WebviewViewBase) { - const node = e.selection?.[0]; - if ( - node != null && - (node instanceof CommitNode || node instanceof FileRevisionAsCommitNode || node instanceof CommitFileNode) - ) { - this.updateCommit(node.commit); - } - } - - private onCommitsViewVisibilityChanged(e: TreeViewVisibilityChangeEvent) { - if (!e.visible) return; - - const node = this.container.commitsView.activeSelection; - if ( - node != null && - (node instanceof CommitNode || node instanceof FileRevisionAsCommitNode || node instanceof CommitFileNode) - ) { - this.updateCommit(node.commit); - } - } - - private onStashesViewSelectionChanged(e: TreeViewSelectionChangeEvent) { - const node = e.selection?.[0]; - if (node != null && (node instanceof StashNode || node instanceof StashFileNode)) { - this.updateCommit(node.commit); - } - } - - private onStashesViewVisibilityChanged(e: TreeViewVisibilityChangeEvent) { - if (!e.visible) return; - - const node = this.container.stashesView.activeSelection; - if (node != null && (node instanceof StashNode || node instanceof StashFileNode)) { - this.updateCommit(node.commit); - } - } - private _cancellationTokenSource: CancellationTokenSource | undefined = undefined; @debug({ args: false }) @@ -865,6 +824,7 @@ export class CommitDetailsWebviewView extends WebviewViewBase c.sha.startsWith(sha!))?.sha ?? sha; - void GitActions.Commit.showDetailsView(GitReference.create(sha, context.repoPath, { refType: 'revision' }), { - pin: false, - preserveFocus: true, - preserveVisibility: context.firstSelection ? showDetailsView === false : showDetailsView !== 'selection', - }); + this.container.events.fire( + 'commit:selected', + { + commit: GitReference.create(sha, context.repoPath, { refType: 'revision' }), + pin: false, + preserveFocus: true, + preserveVisibility: context.firstSelection + ? showDetailsView === false + : showDetailsView !== 'selection', + }, + { + source: 'gitlens.rebase', + }, + ); context.firstSelection = false; }