|
|
- 'use strict';
- import {
- CancellationToken,
- commands,
- ConfigurationChangeEvent,
- ProgressLocation,
- TreeItem,
- TreeItemCollapsibleState,
- window,
- } from 'vscode';
- import { configuration, StashesViewConfig, ViewFilesLayout } from '../configuration';
- import { Container } from '../container';
- import { GitReference, GitStashReference, Repository, RepositoryChange, RepositoryChangeEvent } from '../git/git';
- import { GitUri } from '../git/gitUri';
- import {
- ContextValues,
- MessageNode,
- RepositoryNode,
- StashesNode,
- StashNode,
- SubscribeableViewNode,
- unknownGitUri,
- ViewNode,
- } from './nodes';
- import { debug, gate } from '../system';
- import { ViewBase } from './viewBase';
-
- export class StashesRepositoryNode extends SubscribeableViewNode<StashesView> {
- protected splatted = true;
- private child: StashesNode | undefined;
-
- constructor(uri: GitUri, view: StashesView, parent: ViewNode, public readonly repo: Repository, splatted: boolean) {
- super(uri, view, parent);
-
- this.splatted = splatted;
- }
-
- get id(): string {
- return RepositoryNode.getId(this.repo.path);
- }
-
- async getChildren(): Promise<ViewNode[]> {
- if (this.child == null) {
- this.child = new StashesNode(this.uri, this.view, this, this.repo);
- }
-
- return this.child.getChildren();
- }
-
- getTreeItem(): TreeItem {
- this.splatted = false;
-
- const item = new TreeItem(
- this.repo.formattedName ?? this.uri.repoPath ?? '',
- TreeItemCollapsibleState.Expanded,
- );
- item.contextValue = ContextValues.RepositoryFolder;
-
- return item;
- }
-
- async getSplattedChild() {
- if (this.child == null) {
- await this.getChildren();
- }
-
- return this.child;
- }
-
- @gate()
- @debug()
- async refresh(reset: boolean = false) {
- await this.child?.triggerChange(reset);
-
- await this.ensureSubscription();
- }
-
- @debug()
- protected subscribe() {
- return this.repo.onDidChange(this.onRepositoryChanged, this);
- }
-
- @debug({
- args: {
- 0: (e: RepositoryChangeEvent) =>
- `{ repository: ${e.repository?.name ?? ''}, changes: ${e.changes.join()} }`,
- },
- })
- private onRepositoryChanged(e: RepositoryChangeEvent) {
- if (e.changed(RepositoryChange.Closed)) {
- this.dispose();
- void this.parent?.triggerChange(true);
-
- return;
- }
-
- if (e.changed(RepositoryChange.Config) || e.changed(RepositoryChange.Stash)) {
- void this.triggerChange(true);
- }
- }
- }
-
- export class StashesViewNode extends ViewNode<StashesView> {
- protected splatted = true;
- private children: StashesRepositoryNode[] | undefined;
-
- constructor(view: StashesView) {
- super(unknownGitUri, view);
- }
-
- async getChildren(): Promise<ViewNode[]> {
- if (this.children == null) {
- const repositories = await Container.git.getOrderedRepositories();
- if (repositories.length === 0) return [new MessageNode(this.view, this, 'No stashes could be found.')];
-
- const splat = repositories.length === 1;
- this.children = repositories.map(
- r => new StashesRepositoryNode(GitUri.fromRepoPath(r.path), this.view, this, r, splat),
- );
- }
-
- if (this.children.length === 1) {
- const [child] = this.children;
-
- const stash = await child.repo.getStash();
- this.view.title = `Stashes (${stash?.commits.size ?? 0})`;
-
- return child.getChildren();
- }
-
- return this.children;
- }
-
- getTreeItem(): TreeItem {
- const item = new TreeItem('Stashes', TreeItemCollapsibleState.Expanded);
- return item;
- }
-
- async getSplattedChild() {
- if (this.children == null) {
- await this.getChildren();
- }
-
- return this.children?.length === 1 ? this.children[0] : undefined;
- }
-
- @gate()
- @debug()
- refresh(reset: boolean = false) {
- if (reset && this.children != null) {
- for (const child of this.children) {
- child.dispose();
- }
- this.children = undefined;
- }
- }
- }
-
- export class StashesView extends ViewBase<StashesViewNode, StashesViewConfig> {
- protected readonly configKey = 'stashes';
-
- constructor() {
- super('gitlens.views.stashes', 'Stashes');
- }
-
- getRoot() {
- return new StashesViewNode(this);
- }
-
- protected registerCommands() {
- void Container.viewCommands;
-
- commands.registerCommand(
- this.getQualifiedCommand('copy'),
- () => commands.executeCommand('gitlens.views.copy', this.selection),
- this,
- );
- commands.registerCommand(this.getQualifiedCommand('refresh'), () => this.refresh(true), this);
- commands.registerCommand(
- this.getQualifiedCommand('setFilesLayoutToAuto'),
- () => this.setFilesLayout(ViewFilesLayout.Auto),
- this,
- );
- commands.registerCommand(
- this.getQualifiedCommand('setFilesLayoutToList'),
- () => this.setFilesLayout(ViewFilesLayout.List),
- this,
- );
- commands.registerCommand(
- this.getQualifiedCommand('setFilesLayoutToTree'),
- () => this.setFilesLayout(ViewFilesLayout.Tree),
- this,
- );
- }
-
- protected filterConfigurationChanged(e: ConfigurationChangeEvent) {
- const changed = super.filterConfigurationChanged(e);
- if (
- !changed &&
- !configuration.changed(e, 'defaultDateFormat') &&
- !configuration.changed(e, 'defaultDateSource') &&
- !configuration.changed(e, 'defaultDateStyle') &&
- !configuration.changed(e, 'defaultGravatarsStyle')
- ) {
- return false;
- }
-
- return true;
- }
-
- findStash(stash: GitStashReference, token?: CancellationToken) {
- const repoNodeId = RepositoryNode.getId(stash.repoPath);
-
- return this.findNode(StashNode.getId(stash.repoPath, stash.ref), {
- maxDepth: 2,
- canTraverse: n => {
- if (n instanceof StashesViewNode) return true;
-
- if (n instanceof StashesRepositoryNode) {
- return n.id.startsWith(repoNodeId);
- }
-
- return false;
- },
- token: token,
- });
- }
-
- @gate(() => '')
- async revealStash(
- stash: GitStashReference,
- options?: {
- select?: boolean;
- focus?: boolean;
- expand?: boolean | number;
- },
- ) {
- return window.withProgress(
- {
- location: ProgressLocation.Notification,
- title: `Revealing ${GitReference.toString(stash, { icon: false })} in the side bar...`,
- cancellable: true,
- },
- async (progress, token) => {
- const node = await this.findStash(stash, token);
- if (node == null) return undefined;
-
- await this.ensureRevealNode(node, options);
-
- return node;
- },
- );
- }
-
- private setFilesLayout(layout: ViewFilesLayout) {
- return configuration.updateEffective('views', this.configKey, 'files', 'layout', layout);
- }
- }
|