From 9eaac0ed54441b77c93f3daf0663fff74a237265 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 27 Sep 2018 23:22:57 -0400 Subject: [PATCH] Removes working status placeholders if not changed in working tree Adds better sorting of working tree file changes Changes non-working tree file changes back to use status icons --- package.json | 2 +- src/git/formatters/statusFormatter.ts | 4 +- src/views/nodes/commitFileNode.ts | 10 +++-- src/views/nodes/explorerNode.ts | 6 ++- src/views/nodes/folderNode.ts | 6 +-- src/views/nodes/resultsFileNode.ts | 4 +- src/views/nodes/resultsFilesNode.ts | 2 +- src/views/nodes/statusFileNode.ts | 85 ++++++++++++++++++++++++++--------- src/views/nodes/statusFilesNode.ts | 2 +- 9 files changed, 84 insertions(+), 37 deletions(-) diff --git a/package.json b/package.json index 2062d3c..b4be288 100644 --- a/package.json +++ b/package.json @@ -3196,7 +3196,7 @@ }, { "command": "gitlens.explorers.openFile", - "when": "viewItem =~ /gitlens:file\\b/", + "when": "viewItem =~ /gitlens:(file|history-file|status:file)\\b/", "group": "inline" }, { diff --git a/src/git/formatters/statusFormatter.ts b/src/git/formatters/statusFormatter.ts index 94839f3..57f07ae 100644 --- a/src/git/formatters/statusFormatter.ts +++ b/src/git/formatters/statusFormatter.ts @@ -61,9 +61,7 @@ export class StatusFileFormatter extends Formatter; } export class FolderNode extends ExplorerNode { - readonly priority: boolean = true; + readonly priority: number = 1; constructor( public readonly repoPath: string, @@ -60,7 +60,7 @@ export class FolderNode extends ExplorerNode { children.sort((a, b) => { return ( (a instanceof FolderNode ? -1 : 1) - (b instanceof FolderNode ? -1 : 1) || - (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || + a.priority - b.priority || a.label!.localeCompare(b.label!) ); }); diff --git a/src/views/nodes/resultsFileNode.ts b/src/views/nodes/resultsFileNode.ts index 7abb2d6..e236b11 100644 --- a/src/views/nodes/resultsFileNode.ts +++ b/src/views/nodes/resultsFileNode.ts @@ -65,8 +65,8 @@ export class ResultsFileNode extends ExplorerNode { this._label = undefined; } - get priority(): boolean { - return false; + get priority(): number { + return 0; } getCommand(): Command | undefined { diff --git a/src/views/nodes/resultsFilesNode.ts b/src/views/nodes/resultsFilesNode.ts index 3f1b0c1..5d807d1 100644 --- a/src/views/nodes/resultsFilesNode.ts +++ b/src/views/nodes/resultsFilesNode.ts @@ -49,7 +49,7 @@ export class ResultsFilesNode extends ExplorerNode { children = (await root.getChildren()) as FileExplorerNode[]; } else { - children.sort((a, b) => (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || a.label!.localeCompare(b.label!)); + children.sort((a, b) => a.priority - b.priority || a.label!.localeCompare(b.label!)); } return children; diff --git a/src/views/nodes/statusFileNode.ts b/src/views/nodes/statusFileNode.ts index 3bc1c38..5763ebd 100644 --- a/src/views/nodes/statusFileNode.ts +++ b/src/views/nodes/statusFileNode.ts @@ -2,6 +2,7 @@ import * as path from 'path'; import { Command, ThemeIcon, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode'; import { Commands, DiffWithPreviousCommandArgs } from '../../commands'; +import { Container } from '../../container'; import { GitFile, GitFileWithCommit, @@ -16,6 +17,9 @@ import { CommitFileNode, CommitFileNodeDisplayAs } from './commitFileNode'; import { ExplorerNode, ResourceType } from './explorerNode'; export class StatusFileNode extends ExplorerNode { + private readonly _hasStagedChanges: boolean = false; + private readonly _hasUnstagedChanges: boolean = false; + constructor( public readonly repoPath: string, public readonly file: GitFile, @@ -24,6 +28,17 @@ export class StatusFileNode extends ExplorerNode { public readonly explorer: Explorer ) { super(GitUri.fromFile(file, repoPath, 'HEAD'), parent); + + for (const c of this.commits) { + if (c.isStagedUncommitted) { + this._hasStagedChanges = true; + } + else if (c.isUncommitted) { + this._hasUnstagedChanges = true; + } + + if (this._hasStagedChanges && this._hasUnstagedChanges) break; + } } async getChildren(): Promise { @@ -45,36 +60,60 @@ export class StatusFileNode extends ExplorerNode { async getTreeItem(): Promise { const item = new TreeItem(this.label, TreeItemCollapsibleState.None); - if (this.commits.length === 1 && this.commit.isUncommitted) { - item.contextValue = ResourceType.StatusFile; - - if (this.commit.isStagedUncommitted) { + if ((this._hasStagedChanges || this._hasUnstagedChanges) && this.commits.length === 1) { + if (this._hasStagedChanges) { + item.contextValue = ResourceType.FileStaged; item.tooltip = StatusFileFormatter.fromTemplate( '${file}\n${directory}/\n\n${status} in Index (staged)', this.file ); } else { + item.contextValue = ResourceType.FileUnstaged; item.tooltip = StatusFileFormatter.fromTemplate( '${file}\n${directory}/\n\n${status} in Working Tree', this.file ); } + + // Use the file icon and decorations + item.resourceUri = Uri.file(path.resolve(this.repoPath, this.file.fileName)); + item.iconPath = ThemeIcon.File; + item.command = this.getCommand(); } else { item.collapsibleState = TreeItemCollapsibleState.Collapsed; - item.contextValue = ResourceType.StatusFileCommits; + if (this._hasStagedChanges || this._hasUnstagedChanges) { + if (this._hasStagedChanges && this._hasUnstagedChanges) { + item.contextValue = ResourceType.FileStagedAndUnstaged; + } + else if (this._hasStagedChanges) { + item.contextValue = ResourceType.FileStaged; + } + else { + item.contextValue = ResourceType.FileUnstaged; + } + + // Use the file icon and decorations + item.resourceUri = Uri.file(path.resolve(this.repoPath, this.file.fileName)); + item.iconPath = ThemeIcon.File; + } + else { + item.contextValue = ResourceType.StatusFileCommits; + + const icon = GitFile.getStatusIcon(this.file.status); + item.iconPath = { + dark: Container.context.asAbsolutePath(path.join('images', 'dark', icon)), + light: Container.context.asAbsolutePath(path.join('images', 'light', icon)) + }; + } item.tooltip = StatusFileFormatter.fromTemplate( `\${file}\n\${directory}/\n\n\${status} in ${this.getChangedIn()}`, this.file ); } - // Use the file icon and decorations - item.resourceUri = Uri.file(path.resolve(this.repoPath, this.file.fileName)); - item.iconPath = ThemeIcon.File; - // Only cache the label for a single refresh this._label = undefined; @@ -110,8 +149,11 @@ export class StatusFileNode extends ExplorerNode { return this.commits[0]; } - get priority(): boolean { - return this.commit.isUncommitted; + get priority(): number { + if (this._hasStagedChanges && !this._hasUnstagedChanges) return -3; + if (this._hasStagedChanges) return -2; + if (this._hasUnstagedChanges) return -1; + return 0; } private _relativePath: string | undefined; @@ -125,20 +167,21 @@ export class StatusFileNode extends ExplorerNode { private getChangedIn(): string { const changedIn = []; + let commits = 0; - for (const c of this.commits) { - if (c.isUncommitted) { - if (c.isStagedUncommitted) { - changedIn.push('Index (staged)'); - } - else { - changedIn.push('Working Tree'); - } - continue; - } + if (this._hasUnstagedChanges) { + commits++; + changedIn.push('Working Tree'); + } + if (this._hasStagedChanges) { commits++; + changedIn.push('Index (staged)'); + } + + if (this.commits.length > commits) { + commits = this.commits.length - commits; } if (commits > 0) { diff --git a/src/views/nodes/statusFilesNode.ts b/src/views/nodes/statusFilesNode.ts index ff7989a..f6d8286 100644 --- a/src/views/nodes/statusFilesNode.ts +++ b/src/views/nodes/statusFilesNode.ts @@ -102,7 +102,7 @@ export class StatusFilesNode extends ExplorerNode { children = (await root.getChildren()) as FileExplorerNode[]; } else { - children.sort((a, b) => (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || a.label!.localeCompare(b.label!)); + children.sort((a, b) => a.priority - b.priority || a.label!.localeCompare(b.label!)); } return children;