Просмотр исходного кода

Adds show explorer(s) commands

main
Eric Amodio 6 лет назад
Родитель
Сommit
26adc2eb06
20 измененных файлов: 658 добавлений и 521 удалений
  1. +5
    -1
      CHANGELOG.md
  2. +33
    -17
      package.json
  3. +102
    -96
      src/commands.ts
  4. +3
    -0
      src/commands/common.ts
  5. +15
    -0
      src/commands/showGitExplorer.ts
  6. +19
    -0
      src/commands/showHistoryExplorer.ts
  7. +14
    -0
      src/commands/showResultsExplorer.ts
  8. +14
    -14
      src/commands/toggleCodeLens.ts
  9. +0
    -5
      src/messages.ts
  10. +0
    -1
      src/ui/config.ts
  11. +31
    -31
      src/views/commitResultsNode.ts
  12. +36
    -36
      src/views/commitsNode.ts
  13. +68
    -68
      src/views/commitsResultsNode.ts
  14. +30
    -5
      src/views/gitExplorer.ts
  15. +19
    -2
      src/views/historyExplorer.ts
  16. +40
    -36
      src/views/repositoriesNode.ts
  17. +17
    -11
      src/views/repositoryNode.ts
  18. +30
    -16
      src/views/resultsExplorer.ts
  19. +99
    -99
      src/views/statusFileNode.ts
  20. +83
    -83
      src/views/statusFilesResultsNode.ts

+ 5
- 1
CHANGELOG.md Просмотреть файл

@ -6,12 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
## [Unreleased]
### Added
- Adds a tree layout option to tags in the *GitLens* explorer — closes [#358](https://github.com/eamodio/vscode-gitlens/issues/358)
- Adds an icon for the *Compare File with Previous Revision* command (`gitlens.diffWithPrevious`) and moves it into the editor toolbar
- Adds an icon for the *Compare File with Next Revision* command (`gitlens.diffWithNext`) and moves it into the editor toolbar
- Adds *Show GitLens Explorer* (`gitlens.showGitExplorer`) command — shows/expands the *GitLens* explorer
- Adds *Show History Explorer* (`gitlens.showHistoryExplorer`) command — shows/expands the *GitLens History* explorer
- Adds *Show Results Explorer* (`gitlens.showResultsExplorer`) command — shows/expands the *GitLens Results* explorer
- Adds a tree layout option to tags in the *GitLens* explorer — closes [#358](https://github.com/eamodio/vscode-gitlens/issues/358)
### Changed
- Moves the *GitLens* explorer, *GitLens History* explorer, and *GitLens Results* explorer under the Source Control activity (in the sidebar) 🎉 — closes [#213](https://github.com/eamodio/vscode-gitlens/issues/213)
- Showing results in the *GitLens Results* explorer now properly shows the explorer first
- Renames *Compare Line Revision with Previous* command (`gitlens.diffLineWithPrevious`) to *Compare Commit with Previous* for consistency with other commands
- Renames *Compare Line Revision with Working File* command (`gitlens.diffLineWithWorking`) to *Compare Commit with Working File* for consistency with other commands
- Renames *Show Commit File Details* command (`gitlens.showQuickCommitFileDetails`) to *Show Commit Details* for consistency with other commands

+ 33
- 17
package.json Просмотреть файл

@ -958,7 +958,6 @@
"suppressGitVersionWarning": false,
"suppressLineUncommittedWarning": false,
"suppressNoRepositoryWarning": false,
"suppressResultsExplorerNotice": false,
"suppressShowKeyBindingsNotice": false
},
"properties": {
@ -990,10 +989,6 @@
"type": "boolean",
"default": false
},
"suppressResultsExplorerNotice": {
"type": "boolean",
"default": false
},
"suppressShowKeyBindingsNotice": {
"type": "boolean",
"default": false
@ -1099,6 +1094,21 @@
"category": "GitLens"
},
{
"command": "gitlens.showGitExplorer",
"title": "Show GitLens Explorer",
"category": "GitLens"
},
{
"command": "gitlens.showHistoryExplorer",
"title": "Show History Explorer",
"category": "GitLens"
},
{
"command": "gitlens.showResultsExplorer",
"title": "Show Results Explorer",
"category": "GitLens"
},
{
"command": "gitlens.diffDirectory",
"title": "Directory Compare Working Tree with...",
"category": "GitLens"
@ -1246,16 +1256,6 @@
"category": "GitLens"
},
{
"command": "gitlens.showGitLensExplorer",
"title": "Show GitLens Explorer",
"category": "GitLens"
},
{
"command": "gitlens.showHistoryExplorer",
"title": "Show History Explorer",
"category": "GitLens"
},
{
"command": "gitlens.showQuickFileHistory",
"title": "Show File History",
"category": "GitLens"
@ -1738,6 +1738,22 @@
"menus": {
"commandPalette": [
{
"command": "gitlens.showGitExplorer",
"when": "gitlens:enabled && gitlens:gitExplorer"
},
{
"command": "gitlens.showHistoryExplorer",
"when": "gitlens:enabled && gitlens:historyExplorer"
},
{
"command": "gitlens.showHistoryExplorer",
"when": "gitlens:enabled && !gitlens:historyExplorer && gitlens:gitExplorer"
},
{
"command": "gitlens.showResultsExplorer",
"when": "gitlens:enabled && gitlens:resultsExplorer"
},
{
"command": "gitlens.diffDirectory",
"when": "gitlens:enabled"
},
@ -1822,11 +1838,11 @@
"when": "gitlens:enabled && gitlens:canToggleCodeLens"
},
{
"command": "gitlens.showLastQuickPick",
"command": "gitlens.showCommitSearch",
"when": "gitlens:enabled"
},
{
"command": "gitlens.showCommitSearch",
"command": "gitlens.showLastQuickPick",
"when": "gitlens:enabled"
},
{

+ 102
- 96
src/commands.ts Просмотреть файл

@ -1,97 +1,103 @@
'use strict';
import { CommandContext, setCommandContext } from './constants';
import { Container } from './container';
export * from './commands/common';
export * from './commands/clearFileAnnotations';
export * from './commands/closeUnchangedFiles';
export * from './commands/copyMessageToClipboard';
export * from './commands/copyShaToClipboard';
export * from './commands/diffBranchWithBranch';
export * from './commands/diffDirectory';
export * from './commands/diffLineWithPrevious';
export * from './commands/diffLineWithWorking';
export * from './commands/diffWith';
export * from './commands/diffWithBranch';
export * from './commands/diffWithNext';
export * from './commands/diffWithPrevious';
export * from './commands/diffWithRevision';
export * from './commands/diffWithWorking';
export * from './commands/externalDiff';
export * from './commands/openChangedFiles';
export * from './commands/openBranchesInRemote';
export * from './commands/openBranchInRemote';
export * from './commands/openCommitInRemote';
export * from './commands/openFileInRemote';
export * from './commands/openFileRevision';
export * from './commands/openInRemote';
export * from './commands/openRepoInRemote';
export * from './commands/openWorkingFile';
export * from './commands/resetSuppressedWarnings';
export * from './commands/showCommitSearch';
export * from './commands/showLastQuickPick';
export * from './commands/showQuickBranchHistory';
export * from './commands/showQuickCommitDetails';
export * from './commands/showQuickCommitFileDetails';
export * from './commands/showQuickCurrentBranchHistory';
export * from './commands/showQuickFileHistory';
export * from './commands/showQuickRepoStatus';
export * from './commands/showQuickStashList';
export * from './commands/stashApply';
export * from './commands/stashDelete';
export * from './commands/stashSave';
export * from './commands/toggleCodeLens';
export * from './commands/toggleFileBlame';
export * from './commands/toggleFileHeatmap';
export * from './commands/toggleFileRecentChanges';
export * from './commands/toggleLineBlame';
import * as Commands from './commands';
export function configureCommands(): void {
setCommandContext(CommandContext.KeyMap, Container.config.keymap);
Container.context.subscriptions.push(new Commands.CloseUnchangedFilesCommand());
Container.context.subscriptions.push(new Commands.OpenChangedFilesCommand());
Container.context.subscriptions.push(new Commands.ExternalDiffCommand());
Container.context.subscriptions.push(new Commands.CopyMessageToClipboardCommand());
Container.context.subscriptions.push(new Commands.CopyShaToClipboardCommand());
Container.context.subscriptions.push(new Commands.DiffBranchWithBranchCommand());
Container.context.subscriptions.push(new Commands.DiffDirectoryCommand());
Container.context.subscriptions.push(new Commands.DiffLineWithPreviousCommand());
Container.context.subscriptions.push(new Commands.DiffLineWithWorkingCommand());
Container.context.subscriptions.push(new Commands.DiffWithCommand());
Container.context.subscriptions.push(new Commands.DiffWithBranchCommand());
Container.context.subscriptions.push(new Commands.DiffWithNextCommand());
Container.context.subscriptions.push(new Commands.DiffWithPreviousCommand());
Container.context.subscriptions.push(new Commands.DiffWithRevisionCommand());
Container.context.subscriptions.push(new Commands.DiffWithWorkingCommand());
Container.context.subscriptions.push(new Commands.OpenBranchesInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenBranchInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenCommitInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenFileInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenFileRevisionCommand());
Container.context.subscriptions.push(new Commands.OpenInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenRepoInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenWorkingFileCommand());
Container.context.subscriptions.push(new Commands.ClearFileAnnotationsCommand());
Container.context.subscriptions.push(new Commands.ToggleFileBlameCommand());
Container.context.subscriptions.push(new Commands.ToggleFileHeatmapCommand());
Container.context.subscriptions.push(new Commands.ToggleFileRecentChangesCommand());
Container.context.subscriptions.push(new Commands.ToggleLineBlameCommand());
Container.context.subscriptions.push(new Commands.ResetSuppressedWarningsCommand());
Container.context.subscriptions.push(new Commands.ShowLastQuickPickCommand());
Container.context.subscriptions.push(new Commands.ShowQuickBranchHistoryCommand());
Container.context.subscriptions.push(new Commands.ShowQuickCurrentBranchHistoryCommand());
Container.context.subscriptions.push(new Commands.ShowQuickCommitDetailsCommand());
Container.context.subscriptions.push(new Commands.ShowQuickCommitFileDetailsCommand());
Container.context.subscriptions.push(new Commands.ShowCommitSearchCommand());
Container.context.subscriptions.push(new Commands.ShowQuickFileHistoryCommand());
Container.context.subscriptions.push(new Commands.ShowQuickRepoStatusCommand());
Container.context.subscriptions.push(new Commands.ShowQuickStashListCommand());
Container.context.subscriptions.push(new Commands.StashApplyCommand());
Container.context.subscriptions.push(new Commands.StashDeleteCommand());
Container.context.subscriptions.push(new Commands.StashSaveCommand());
Container.context.subscriptions.push(new Commands.ToggleCodeLensCommand());
'use strict';
import { CommandContext, setCommandContext } from './constants';
import { Container } from './container';
export * from './commands/common';
export * from './commands/clearFileAnnotations';
export * from './commands/closeUnchangedFiles';
export * from './commands/copyMessageToClipboard';
export * from './commands/copyShaToClipboard';
export * from './commands/diffBranchWithBranch';
export * from './commands/diffDirectory';
export * from './commands/diffLineWithPrevious';
export * from './commands/diffLineWithWorking';
export * from './commands/diffWith';
export * from './commands/diffWithBranch';
export * from './commands/diffWithNext';
export * from './commands/diffWithPrevious';
export * from './commands/diffWithRevision';
export * from './commands/diffWithWorking';
export * from './commands/externalDiff';
export * from './commands/openBranchesInRemote';
export * from './commands/openBranchInRemote';
export * from './commands/openChangedFiles';
export * from './commands/openCommitInRemote';
export * from './commands/openFileInRemote';
export * from './commands/openFileRevision';
export * from './commands/openInRemote';
export * from './commands/openRepoInRemote';
export * from './commands/openWorkingFile';
export * from './commands/resetSuppressedWarnings';
export * from './commands/showCommitSearch';
export * from './commands/showGitExplorer';
export * from './commands/showHistoryExplorer';
export * from './commands/showLastQuickPick';
export * from './commands/showQuickBranchHistory';
export * from './commands/showQuickCommitDetails';
export * from './commands/showQuickCommitFileDetails';
export * from './commands/showQuickCurrentBranchHistory';
export * from './commands/showQuickFileHistory';
export * from './commands/showQuickRepoStatus';
export * from './commands/showQuickStashList';
export * from './commands/showResultsExplorer';
export * from './commands/stashApply';
export * from './commands/stashDelete';
export * from './commands/stashSave';
export * from './commands/toggleCodeLens';
export * from './commands/toggleFileBlame';
export * from './commands/toggleFileHeatmap';
export * from './commands/toggleFileRecentChanges';
export * from './commands/toggleLineBlame';
import * as Commands from './commands';
export function configureCommands(): void {
setCommandContext(CommandContext.KeyMap, Container.config.keymap);
Container.context.subscriptions.push(new Commands.ClearFileAnnotationsCommand());
Container.context.subscriptions.push(new Commands.CloseUnchangedFilesCommand());
Container.context.subscriptions.push(new Commands.CopyMessageToClipboardCommand());
Container.context.subscriptions.push(new Commands.CopyShaToClipboardCommand());
Container.context.subscriptions.push(new Commands.DiffBranchWithBranchCommand());
Container.context.subscriptions.push(new Commands.DiffDirectoryCommand());
Container.context.subscriptions.push(new Commands.DiffLineWithPreviousCommand());
Container.context.subscriptions.push(new Commands.DiffLineWithWorkingCommand());
Container.context.subscriptions.push(new Commands.DiffWithCommand());
Container.context.subscriptions.push(new Commands.DiffWithBranchCommand());
Container.context.subscriptions.push(new Commands.DiffWithNextCommand());
Container.context.subscriptions.push(new Commands.DiffWithPreviousCommand());
Container.context.subscriptions.push(new Commands.DiffWithRevisionCommand());
Container.context.subscriptions.push(new Commands.DiffWithWorkingCommand());
Container.context.subscriptions.push(new Commands.ExternalDiffCommand());
Container.context.subscriptions.push(new Commands.OpenBranchesInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenBranchInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenChangedFilesCommand());
Container.context.subscriptions.push(new Commands.OpenCommitInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenFileInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenFileRevisionCommand());
Container.context.subscriptions.push(new Commands.OpenInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenRepoInRemoteCommand());
Container.context.subscriptions.push(new Commands.OpenWorkingFileCommand());
Container.context.subscriptions.push(new Commands.ResetSuppressedWarningsCommand());
Container.context.subscriptions.push(new Commands.ShowCommitSearchCommand());
Container.context.subscriptions.push(new Commands.ShowGitExplorerCommand());
Container.context.subscriptions.push(new Commands.ShowHistoryExplorerCommand());
Container.context.subscriptions.push(new Commands.ShowLastQuickPickCommand());
Container.context.subscriptions.push(new Commands.ShowQuickBranchHistoryCommand());
Container.context.subscriptions.push(new Commands.ShowQuickCommitDetailsCommand());
Container.context.subscriptions.push(new Commands.ShowQuickCommitFileDetailsCommand());
Container.context.subscriptions.push(new Commands.ShowQuickCurrentBranchHistoryCommand());
Container.context.subscriptions.push(new Commands.ShowQuickFileHistoryCommand());
Container.context.subscriptions.push(new Commands.ShowQuickRepoStatusCommand());
Container.context.subscriptions.push(new Commands.ShowQuickStashListCommand());
Container.context.subscriptions.push(new Commands.ShowResultsExplorerCommand());
Container.context.subscriptions.push(new Commands.StashApplyCommand());
Container.context.subscriptions.push(new Commands.StashDeleteCommand());
Container.context.subscriptions.push(new Commands.StashSaveCommand());
Container.context.subscriptions.push(new Commands.ToggleCodeLensCommand());
Container.context.subscriptions.push(new Commands.ToggleFileBlameCommand());
Container.context.subscriptions.push(new Commands.ToggleFileHeatmapCommand());
Container.context.subscriptions.push(new Commands.ToggleFileRecentChangesCommand());
Container.context.subscriptions.push(new Commands.ToggleLineBlameCommand());
}

+ 3
- 0
src/commands/common.ts Просмотреть файл

@ -41,6 +41,8 @@ export enum Commands {
OpenWorkingFile = 'gitlens.openWorkingFile',
ResetSuppressedWarnings = 'gitlens.resetSuppressedWarnings',
ShowCommitSearch = 'gitlens.showCommitSearch',
ShowGitExplorer = 'gitlens.showGitExplorer',
ShowHistoryExplorer = 'gitlens.showHistoryExplorer',
ShowLastQuickPick = 'gitlens.showLastQuickPick',
ShowQuickCommitDetails = 'gitlens.showQuickCommitDetails',
ShowQuickCommitFileDetails = 'gitlens.showQuickCommitFileDetails',
@ -49,6 +51,7 @@ export enum Commands {
ShowQuickCurrentBranchHistory = 'gitlens.showQuickRepoHistory',
ShowQuickRepoStatus = 'gitlens.showQuickRepoStatus',
ShowQuickStashList = 'gitlens.showQuickStashList',
ShowResultsExplorer = 'gitlens.showResultsExplorer',
ShowSettingsPage = 'gitlens.showSettingsPage',
ShowWelcomePage = 'gitlens.showWelcomePage',
StashApply = 'gitlens.stashApply',

+ 15
- 0
src/commands/showGitExplorer.ts Просмотреть файл

@ -0,0 +1,15 @@
'use strict';
import { Command, Commands } from './common';
import { GitExplorerView } from '../configuration';
import { Container } from '../container';
export class ShowGitExplorerCommand extends Command {
constructor() {
super(Commands.ShowGitExplorer);
}
execute() {
return Container.gitExplorer.show(GitExplorerView.Repository);
}
}

+ 19
- 0
src/commands/showHistoryExplorer.ts Просмотреть файл

@ -0,0 +1,19 @@
'use strict';
import { Command, Commands } from './common';
import { GitExplorerView } from '../configuration';
import { Container } from '../container';
export class ShowHistoryExplorerCommand extends Command {
constructor() {
super(Commands.ShowHistoryExplorer);
}
execute() {
if (Container.config.historyExplorer.enabled) {
return Container.historyExplorer.show();
}
return Container.gitExplorer.show(GitExplorerView.History);
}
}

+ 14
- 0
src/commands/showResultsExplorer.ts Просмотреть файл

@ -0,0 +1,14 @@
'use strict';
import { Command, Commands } from './common';
import { Container } from '../container';
export class ShowResultsExplorerCommand extends Command {
constructor() {
super(Commands.ShowResultsExplorer);
}
execute() {
return Container.resultsExplorer.show();
}
}

+ 14
- 14
src/commands/toggleCodeLens.ts Просмотреть файл

@ -1,14 +1,14 @@
'use strict';
import { Command, Commands } from './common';
import { Container } from '../container';
export class ToggleCodeLensCommand extends Command {
constructor() {
super(Commands.ToggleCodeLens);
}
execute() {
return Container.codeLens.toggleCodeLens();
}
}
'use strict';
import { Command, Commands } from './common';
import { Container } from '../container';
export class ToggleCodeLensCommand extends Command {
constructor() {
super(Commands.ToggleCodeLens);
}
execute() {
return Container.codeLens.toggleCodeLens();
}
}

+ 0
- 5
src/messages.ts Просмотреть файл

@ -13,7 +13,6 @@ export enum SuppressedMessages {
GitVersionWarning = 'suppressGitVersionWarning',
LineUncommittedWarning = 'suppressLineUncommittedWarning',
NoRepositoryWarning = 'suppressNoRepositoryWarning',
ResultsExplorerNotice = 'suppressResultsExplorerNotice',
ShowKeyBindingsNotice = 'suppressShowKeyBindingsNotice'
}
@ -83,10 +82,6 @@ export class Messages {
return Messages.showMessage('warn', `${message}. No repository could be found.`, SuppressedMessages.NoRepositoryWarning);
}
static showResultExplorerInfoMessage(): Promise<MessageItem | undefined> {
return Messages.showMessage('info', `If you can't find your results, click on "GITLENS RESULTS" at the bottom of the Explorer view.`, SuppressedMessages.ResultsExplorerNotice, null);
}
private static async showMessage<T extends MessageItem>(type: 'info' | 'warn' | 'error', message: string, suppressionKey: SuppressedMessages, dontShowAgain: T | null = { title: 'Don\'t Show Again' } as T, ...actions: T[]): Promise<T | undefined> {
Logger.log(`ShowMessage(${type}, '${message}', ${suppressionKey}, ${dontShowAgain})`);

+ 0
- 1
src/ui/config.ts Просмотреть файл

@ -124,7 +124,6 @@ export interface IAdvancedConfig {
suppressGitVersionWarning: boolean;
suppressLineUncommittedWarning: boolean;
suppressNoRepositoryWarning: boolean;
suppressResultsExplorerNotice: boolean;
suppressShowKeyBindingsNotice: boolean;
};

+ 31
- 31
src/views/commitResultsNode.ts Просмотреть файл

@ -1,32 +1,32 @@
'use strict';
import { Strings } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { GlyphChars } from '../constants';
import { Container } from '../container';
import { Explorer, ExplorerNode, MessageNode, ResourceType } from './explorerNode';
import { CommitFormatter, GitLogCommit } from '../gitService';
export class CommitResultsNode extends ExplorerNode {
constructor(
readonly commit: GitLogCommit,
private readonly explorer: Explorer,
private readonly contextValue: ResourceType = ResourceType.Results
) {
super(commit.toGitUri());
}
async getChildren(): Promise<ExplorerNode[]> {
const children = await new CommitNode(this.commit, this.explorer).getChildren();
children.splice(0, 0, new MessageNode(CommitFormatter.fromTemplate('${message}', this.commit, { truncateMessageAtNewLine: true }), CommitFormatter.fromTemplate('${message}', this.commit)));
return children;
}
async getTreeItem(): Promise<TreeItem> {
const label = CommitFormatter.fromTemplate(`Commit \${sha} ${Strings.pad(GlyphChars.Dash, 1, 1)} \${authorAgo}`, this.commit, Container.config.defaultDateFormat);
const item = new TreeItem(label, TreeItemCollapsibleState.Expanded);
item.contextValue = this.contextValue;
return item;
}
'use strict';
import { Strings } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { GlyphChars } from '../constants';
import { Container } from '../container';
import { Explorer, ExplorerNode, MessageNode, ResourceType } from './explorerNode';
import { CommitFormatter, GitLogCommit } from '../gitService';
export class CommitResultsNode extends ExplorerNode {
constructor(
public readonly commit: GitLogCommit,
private readonly explorer: Explorer,
private readonly contextValue: ResourceType = ResourceType.Results
) {
super(commit.toGitUri());
}
async getChildren(): Promise<ExplorerNode[]> {
const children = await new CommitNode(this.commit, this.explorer).getChildren();
children.splice(0, 0, new MessageNode(CommitFormatter.fromTemplate('${message}', this.commit, { truncateMessageAtNewLine: true }), CommitFormatter.fromTemplate('${message}', this.commit)));
return children;
}
async getTreeItem(): Promise<TreeItem> {
const label = CommitFormatter.fromTemplate(`Commit \${sha} ${Strings.pad(GlyphChars.Dash, 1, 1)} \${authorAgo}`, this.commit, Container.config.defaultDateFormat);
const item = new TreeItem(label, TreeItemCollapsibleState.Expanded);
item.contextValue = this.contextValue;
return item;
}
}

+ 36
- 36
src/views/commitsNode.ts Просмотреть файл

@ -1,36 +1,36 @@
'use strict';
import { Iterables } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { Explorer, ExplorerNode, ResourceType, ShowAllNode } from './explorerNode';
import { GitLog, GitUri } from '../gitService';
export class CommitsNode extends ExplorerNode {
readonly supportsPaging: boolean = true;
constructor(
readonly repoPath: string,
private readonly logFn: (maxCount: number | undefined) => Promise<GitLog | undefined>,
private readonly explorer: Explorer
) {
super(GitUri.fromRepoPath(repoPath));
}
async getChildren(): Promise<ExplorerNode[]> {
const log = await this.logFn(this.maxCount);
if (log === undefined) return [];
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))];
if (log.truncated) {
children.push(new ShowAllNode('Show All Commits', this, this.explorer));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const item = new TreeItem('Commits', TreeItemCollapsibleState.Collapsed);
item.contextValue = ResourceType.Commits;
return item;
}
}
'use strict';
import { Iterables } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { Explorer, ExplorerNode, ResourceType, ShowAllNode } from './explorerNode';
import { GitLog, GitUri } from '../gitService';
export class CommitsNode extends ExplorerNode {
readonly supportsPaging: boolean = true;
constructor(
public readonly repoPath: string,
private readonly logFn: (maxCount: number | undefined) => Promise<GitLog | undefined>,
private readonly explorer: Explorer
) {
super(GitUri.fromRepoPath(repoPath));
}
async getChildren(): Promise<ExplorerNode[]> {
const log = await this.logFn(this.maxCount);
if (log === undefined) return [];
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))];
if (log.truncated) {
children.push(new ShowAllNode('Show All Commits', this, this.explorer));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const item = new TreeItem('Commits', TreeItemCollapsibleState.Collapsed);
item.contextValue = ResourceType.Commits;
return item;
}
}

+ 68
- 68
src/views/commitsResultsNode.ts Просмотреть файл

@ -1,69 +1,69 @@
'use strict';
import { Iterables } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { Explorer, ExplorerNode, ResourceType, ShowAllNode } from './explorerNode';
import { GitLog, GitUri } from '../gitService';
export class CommitsResultsNode extends ExplorerNode {
readonly supportsPaging: boolean = true;
private _cache: { label: string, log: GitLog | undefined } | undefined;
constructor(
readonly repoPath: string,
private readonly labelFn: (log: GitLog | undefined) => Promise<string>,
private readonly logFn: (maxCount: number | undefined) => Promise<GitLog | undefined>,
private readonly explorer: Explorer,
private readonly contextValue: ResourceType = ResourceType.ResultsCommits
) {
super(GitUri.fromRepoPath(repoPath));
}
async getChildren(): Promise<ExplorerNode[]> {
const log = await this.getLog();
if (log === undefined) return [];
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))];
if (log.truncated) {
children.push(new ShowAllNode('Show All Results', this, this.explorer));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const log = await this.getLog();
const item = new TreeItem(await this.getLabel(), log && log.count > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None);
item.contextValue = this.contextValue;
return item;
}
refresh() {
this._cache = undefined;
}
private async ensureCache() {
if (this._cache === undefined) {
const log = await this.logFn(this.maxCount);
this._cache = {
label: await this.labelFn(log),
log: log
};
}
return this._cache;
}
private async getLabel() {
const cache = await this.ensureCache();
return cache.label;
}
private async getLog() {
const cache = await this.ensureCache();
return cache.log;
}
'use strict';
import { Iterables } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { Explorer, ExplorerNode, ResourceType, ShowAllNode } from './explorerNode';
import { GitLog, GitUri } from '../gitService';
export class CommitsResultsNode extends ExplorerNode {
readonly supportsPaging: boolean = true;
private _cache: { label: string, log: GitLog | undefined } | undefined;
constructor(
public readonly repoPath: string,
private readonly labelFn: (log: GitLog | undefined) => Promise<string>,
private readonly logFn: (maxCount: number | undefined) => Promise<GitLog | undefined>,
private readonly explorer: Explorer,
private readonly contextValue: ResourceType = ResourceType.ResultsCommits
) {
super(GitUri.fromRepoPath(repoPath));
}
async getChildren(): Promise<ExplorerNode[]> {
const log = await this.getLog();
if (log === undefined) return [];
const children: (CommitNode | ShowAllNode)[] = [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.explorer))];
if (log.truncated) {
children.push(new ShowAllNode('Show All Results', this, this.explorer));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const log = await this.getLog();
const item = new TreeItem(await this.getLabel(), log && log.count > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None);
item.contextValue = this.contextValue;
return item;
}
refresh() {
this._cache = undefined;
}
private async ensureCache() {
if (this._cache === undefined) {
const log = await this.logFn(this.maxCount);
this._cache = {
label: await this.labelFn(log),
log: log
};
}
return this._cache;
}
private async getLabel() {
const cache = await this.ensureCache();
return cache.label;
}
private async getLog() {
const cache = await this.ensureCache();
return cache.log;
}
}

+ 30
- 5
src/views/gitExplorer.ts Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
import { Functions } from '../system';
import { commands, ConfigurationChangeEvent, ConfigurationTarget, Disposable, Event, EventEmitter, TextDocumentShowOptions, TextEditor, TreeDataProvider, TreeItem, Uri, window } from 'vscode';
import { commands, ConfigurationChangeEvent, ConfigurationTarget, Disposable, Event, EventEmitter, TextDocumentShowOptions, TextEditor, TreeDataProvider, TreeItem, TreeView, Uri, window } from 'vscode';
import { UriComparer } from '../comparers';
import { configuration, ExplorerFilesLayout, GitExplorerView, IExplorersConfig, IGitExplorerConfig } from '../configuration';
import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants';
@ -21,6 +21,7 @@ export class GitExplorer extends Disposable implements TreeDataProvider
private _disposable: Disposable | undefined;
private _root?: ExplorerNode;
private _tree: TreeView<ExplorerNode> | undefined;
private _onDidChangeAutoRefresh = new EventEmitter<void>();
public get onDidChangeAutoRefresh(): Event<void> {
@ -103,7 +104,8 @@ export class GitExplorer extends Disposable implements TreeDataProvider
this.setRoot(await this.getRootNode(window.activeTextEditor));
this._disposable = window.registerTreeDataProvider('gitlens.gitExplorer', this);
this._tree = window.createTreeView('gitlens.gitExplorer', { treeDataProvider: this });
this._disposable = this._tree;
return;
}
@ -159,6 +161,10 @@ export class GitExplorer extends Disposable implements TreeDataProvider
this._view = Container.config.historyExplorer.enabled ? GitExplorerView.Repository : value;
}
getParent(element: ExplorerNode): ExplorerNode | undefined {
return undefined;
}
private _loading: Promise<void> | undefined;
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
@ -196,6 +202,8 @@ export class GitExplorer extends Disposable implements TreeDataProvider
this.setRoot(await this.getRootNode(window.activeTextEditor));
}
this._root!.refresh();
this._onDidChangeTreeData.fire();
}
@ -206,6 +214,8 @@ export class GitExplorer extends Disposable implements TreeDataProvider
node.maxCount = args.maxCount;
}
node.refresh();
// Since the root node won't actually refresh, force everything
this._onDidChangeTreeData.fire(node === this._root ? undefined : node);
}
@ -220,7 +230,7 @@ export class GitExplorer extends Disposable implements TreeDataProvider
const requiresRefresh = this.setRoot(await this.getRootNode(window.activeTextEditor));
if (requiresRefresh || force) {
this.refresh(RefreshReason.ViewChanged);
return this.refresh(RefreshReason.ViewChanged);
}
}
@ -272,10 +282,25 @@ export class GitExplorer extends Disposable implements TreeDataProvider
}
}
async show(view: GitExplorerView) {
if (this._root === undefined || this._tree === undefined) return;
await this.switchTo(view);
const [child] = await this._root!.getChildren();
try {
await this._tree.reveal(child, { select: false });
}
catch (ex) {
Logger.error(ex);
}
}
async switchTo(view: GitExplorerView) {
if (this.view === view) return;
if (this.view === view) return false;
this.reset(view, true);
await this.reset(view, true);
return true;
}
// async dockHistory(switchView: boolean = true) {

+ 19
- 2
src/views/historyExplorer.ts Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
import { Functions } from '../system';
import { commands, ConfigurationChangeEvent, Disposable, Event, EventEmitter, TextEditor, TreeDataProvider, TreeItem, window } from 'vscode';
import { commands, ConfigurationChangeEvent, Disposable, Event, EventEmitter, TextEditor, TreeDataProvider, TreeItem, TreeView, window } from 'vscode';
import { configuration, GitExplorerView, IExplorersConfig } from '../configuration';
import { CommandContext, GlyphChars, setCommandContext } from '../constants';
import { Container } from '../container';
@ -15,6 +15,7 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider
private _disposable: Disposable | undefined;
private _root?: ExplorerNode;
private _tree: TreeView<ExplorerNode> | undefined;
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
public get onDidChangeTreeData(): Event<ExplorerNode> {
@ -70,7 +71,8 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider
if (initializing) {
this.setRoot(await this.getRootNode(window.activeTextEditor));
this._disposable = window.registerTreeDataProvider('gitlens.historyExplorer', this);
this._tree = window.createTreeView('gitlens.historyExplorer', { treeDataProvider: this });
this._disposable = this._tree;
}
}
@ -96,6 +98,10 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider
return { ...Container.config.explorers };
}
getParent(element: ExplorerNode): ExplorerNode | undefined {
return undefined;
}
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
if (this._root === undefined) return [new MessageNode(`No active file ${GlyphChars.Dash} no history to show`)];
@ -146,6 +152,17 @@ export class HistoryExplorer extends Disposable implements TreeDataProvider
this._onDidChangeTreeData.fire(this._root === node ? undefined : node);
}
async show() {
if (this._root === undefined || this._tree === undefined) return;
try {
await this._tree.reveal(this._root, { select: false });
}
catch (ex) {
Logger.error(ex);
}
}
async undock(switchView: boolean = true) {
if (switchView) {
await Container.gitExplorer.switchTo(GitExplorerView.Repository);

+ 40
- 36
src/views/repositoriesNode.ts Просмотреть файл

@ -1,37 +1,41 @@
'use strict';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ActiveRepositoryNode } from './activeRepositoryNode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitExplorer } from './gitExplorer';
import { GitUri, Repository } from '../gitService';
import { RepositoryNode } from './repositoryNode';
export class RepositoriesNode extends ExplorerNode {
constructor(
private readonly repositories: Repository[],
private readonly explorer: GitExplorer
) {
super(undefined!);
}
async getChildren(): Promise<ExplorerNode[]> {
this.resetChildren();
this.children = this.repositories
.sort((a, b) => a.index - b.index)
.map(repo => new RepositoryNode(GitUri.fromRepoPath(repo.path), repo, this.explorer));
if (this.children.length > 1) {
this.children.splice(0, 0, new ActiveRepositoryNode(this.explorer));
}
return this.children;
}
getTreeItem(): TreeItem {
const item = new TreeItem(`Repositories`, TreeItemCollapsibleState.Expanded);
item.contextValue = ResourceType.Repositories;
return item;
}
'use strict';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ActiveRepositoryNode } from './activeRepositoryNode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitExplorer } from './gitExplorer';
import { GitUri, Repository } from '../gitService';
import { RepositoryNode } from './repositoryNode';
export class RepositoriesNode extends ExplorerNode {
constructor(
private readonly repositories: Repository[],
private readonly explorer: GitExplorer
) {
super(undefined!);
}
async getChildren(): Promise<ExplorerNode[]> {
if (this.children === undefined) {
this.children = this.repositories
.sort((a, b) => a.index - b.index)
.map(repo => new RepositoryNode(GitUri.fromRepoPath(repo.path), repo, this.explorer));
if (this.children.length > 1) {
this.children.splice(0, 0, new ActiveRepositoryNode(this.explorer));
}
}
return this.children;
}
refresh() {
this.resetChildren();
}
getTreeItem(): TreeItem {
const item = new TreeItem(`Repositories`, TreeItemCollapsibleState.Expanded);
item.contextValue = ResourceType.Repositories;
return item;
}
}

+ 17
- 11
src/views/repositoryNode.ts Просмотреть файл

@ -16,7 +16,7 @@ export class RepositoryNode extends ExplorerNode {
constructor(
uri: GitUri,
readonly repo: Repository,
public readonly repo: Repository,
private readonly explorer: GitExplorer,
private readonly active: boolean = false,
private readonly activeParent?: ExplorerNode
@ -29,16 +29,17 @@ export class RepositoryNode extends ExplorerNode {
}
async getChildren(): Promise<ExplorerNode[]> {
this.resetChildren();
this.updateSubscription();
this.children = [
new StatusNode(this.uri, this.repo, this.explorer, this.active),
new BranchesNode(this.uri, this.repo, this.explorer, this.active),
new RemotesNode(this.uri, this.repo, this.explorer, this.active),
new StashesNode(this.uri, this.repo, this.explorer, this.active),
new TagsNode(this.uri, this.repo, this.explorer, this.active)
];
if (this.children === undefined) {
this.updateSubscription();
this.children = [
new StatusNode(this.uri, this.repo, this.explorer, this.active),
new BranchesNode(this.uri, this.repo, this.explorer, this.active),
new RemotesNode(this.uri, this.repo, this.explorer, this.active),
new StashesNode(this.uri, this.repo, this.explorer, this.active),
new TagsNode(this.uri, this.repo, this.explorer, this.active)
];
}
return this.children;
}
@ -55,6 +56,11 @@ export class RepositoryNode extends ExplorerNode {
return item;
}
refresh() {
this.resetChildren();
this.updateSubscription();
}
private updateSubscription() {
// We only need to subscribe if auto-refresh is enabled, because if it becomes enabled we will be refreshed
if (this.explorer.autoRefresh) {

+ 30
- 16
src/views/resultsExplorer.ts Просмотреть файл

@ -1,6 +1,6 @@
'use strict';
import { Functions, Strings } from '../system';
import { commands, ConfigurationChangeEvent, ConfigurationTarget, Disposable, Event, EventEmitter, TreeDataProvider, TreeItem, window } from 'vscode';
import { commands, ConfigurationChangeEvent, ConfigurationTarget, Disposable, Event, EventEmitter, TreeDataProvider, TreeItem, TreeView, window } from 'vscode';
import { configuration, ExplorerFilesLayout, IExplorersConfig, IResultsExplorerConfig } from '../configuration';
import { CommandContext, GlyphChars, setCommandContext, WorkspaceState } from '../constants';
import { Container } from '../container';
@ -8,7 +8,7 @@ import { RefreshNodeCommandArgs } from './explorerCommands';
import { CommitResultsNode, CommitsResultsNode, ComparisonResultsNode, ExplorerNode, MessageNode, NamedRef, RefreshReason, ResourceType } from './explorerNodes';
import { GitLog, GitLogCommit } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
// import { Messages } from '../messages';
export * from './explorerNodes';
@ -16,6 +16,7 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider
private _disposable: Disposable | undefined;
private _roots: ExplorerNode[] = [];
private _tree: TreeView<ExplorerNode> | undefined;
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
public get onDidChangeTreeData(): Event<ExplorerNode> {
@ -63,7 +64,8 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider
}
if (initializing) {
this._disposable = window.registerTreeDataProvider('gitlens.resultsExplorer', this);
this._tree = window.createTreeView('gitlens.resultsExplorer', { treeDataProvider: this });
this._disposable = this._tree;
}
}
@ -80,6 +82,10 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider
setCommandContext(CommandContext.ResultsExplorer, false);
}
getParent(element: ExplorerNode): ExplorerNode | undefined {
return undefined;
}
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
if (this._roots.length === 0) return [new MessageNode('No results')];
@ -125,14 +131,23 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider
this._onDidChangeTreeData.fire();
}
async show() {
if (this._roots === undefined || this._roots.length === 0 || this._tree === undefined) return;
try {
await this._tree.reveal(this._roots[0], { select: false });
}
catch (ex) {
Logger.error(ex);
}
}
showComparisonInResults(repoPath: string, ref1: string | NamedRef, ref2: string | NamedRef) {
this.addResults(new ComparisonResultsNode(repoPath, typeof ref1 === 'string' ? { ref: ref1 } : ref1, typeof ref2 === 'string' ? { ref: ref2 } : ref2, this));
this.showResults();
this.showResults(this.addResults(new ComparisonResultsNode(repoPath, typeof ref1 === 'string' ? { ref: ref1 } : ref1, typeof ref2 === 'string' ? { ref: ref2 } : ref2, this)));
}
showCommitInResults(commit: GitLogCommit) {
this.addResults(new CommitResultsNode(commit, this));
this.showResults();
this.showResults(this.addResults(new CommitResultsNode(commit, this)));
}
showCommitsInResults(results: GitLog, resultsLabel: string | { label: string, resultsType?: { singular: string, plural: string } }) {
@ -160,18 +175,17 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider
return `${count === 0 ? 'No' : `${count}${truncated ? '+' : ''}`} ${resultsType.plural} for ${resultsLabel.label}${repository}`;
};
this.addResults(new CommitsResultsNode(results.repoPath, labelFn, Functions.seeded(query, results), this, ResourceType.SearchResults));
this.showResults();
this.showResults(this.addResults(new CommitsResultsNode(results.repoPath, labelFn, Functions.seeded(query, results), this, ResourceType.SearchResults)));
}
private async showResults() {
await commands.executeCommand('workbench.view.explorer');
Messages.showResultExplorerInfoMessage();
setCommandContext(CommandContext.ResultsExplorer, true);
private async showResults(results: ExplorerNode) {
await setCommandContext(CommandContext.ResultsExplorer, true);
setTimeout(() => this._tree!.reveal(results, { select: true }), 250);
}
private addResults(results: ExplorerNode): boolean {
if (this._roots.includes(results)) return false;
private addResults(results: ExplorerNode): ExplorerNode {
if (this._roots.includes(results)) return results;
if (this._roots.length > 0 && !this.keepResults) {
this.clearResults();
@ -179,7 +193,7 @@ export class ResultsExplorer extends Disposable implements TreeDataProvider
this._roots.splice(0, 0, results);
this.refreshNode(results);
return true;
return results;
}
private clearResults() {

+ 99
- 99
src/views/statusFileNode.ts Просмотреть файл

@ -1,99 +1,99 @@
'use strict';
import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Commands, DiffWithCommandArgs } from '../commands';
import { Container } from '../container';
import { Explorer, ExplorerNode, ResourceType } from './explorerNode';
import { getGitStatusIcon, GitStatusFile, GitUri, IStatusFormatOptions, StatusFileFormatter } from '../gitService';
import * as path from 'path';
export class StatusFileNode extends ExplorerNode {
constructor(
readonly repoPath: string,
private readonly status: GitStatusFile,
private readonly ref1: string,
private readonly ref2: string,
private readonly explorer: Explorer
) {
super(GitUri.fromFileStatus(status, repoPath));
}
getChildren(): ExplorerNode[] {
return [];
}
getTreeItem(): TreeItem {
const item = new TreeItem(this.label, TreeItemCollapsibleState.None);
item.contextValue = ResourceType.StatusFile;
item.tooltip = StatusFileFormatter.fromTemplate('${file}\n${directory}/\n\n${status}', this.status);
const statusIcon = getGitStatusIcon(this.status.status);
item.iconPath = {
dark: Container.context.asAbsolutePath(path.join('images', 'dark', statusIcon)),
light: Container.context.asAbsolutePath(path.join('images', 'light', statusIcon))
};
item.command = this.getCommand();
return item;
}
private _folderName: string | undefined;
get folderName() {
if (this._folderName === undefined) {
this._folderName = path.dirname(this.uri.getRelativePath());
}
return this._folderName;
}
private _label: string | undefined;
get label() {
if (this._label === undefined) {
this._label = StatusFileFormatter.fromTemplate(this.explorer.config.statusFileFormat, this.status, {
relativePath: this.relativePath
} as IStatusFormatOptions);
}
return this._label;
}
private _relativePath: string | undefined;
get relativePath(): string | undefined {
return this._relativePath;
}
set relativePath(value: string | undefined) {
this._relativePath = value;
this._label = undefined;
}
get priority(): boolean {
return false;
}
getCommand(): Command | undefined {
return {
title: 'Open Changes',
command: Commands.DiffWith,
arguments: [
this.uri,
{
lhs: {
sha: this.ref1,
uri: this.uri
},
rhs: {
sha: this.ref2,
uri: this.status.status === 'R'
? GitUri.fromFileStatus(this.status, this.uri.repoPath!, this.ref2, true)
: this.uri
},
repoPath: this.uri.repoPath!,
line: 0,
showOptions: {
preserveFocus: true,
preview: true
}
} as DiffWithCommandArgs
]
};
}
}
'use strict';
import { Command, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Commands, DiffWithCommandArgs } from '../commands';
import { Container } from '../container';
import { Explorer, ExplorerNode, ResourceType } from './explorerNode';
import { getGitStatusIcon, GitStatusFile, GitUri, IStatusFormatOptions, StatusFileFormatter } from '../gitService';
import * as path from 'path';
export class StatusFileNode extends ExplorerNode {
constructor(
public readonly repoPath: string,
private readonly status: GitStatusFile,
private readonly ref1: string,
private readonly ref2: string,
private readonly explorer: Explorer
) {
super(GitUri.fromFileStatus(status, repoPath));
}
getChildren(): ExplorerNode[] {
return [];
}
getTreeItem(): TreeItem {
const item = new TreeItem(this.label, TreeItemCollapsibleState.None);
item.contextValue = ResourceType.StatusFile;
item.tooltip = StatusFileFormatter.fromTemplate('${file}\n${directory}/\n\n${status}', this.status);
const statusIcon = getGitStatusIcon(this.status.status);
item.iconPath = {
dark: Container.context.asAbsolutePath(path.join('images', 'dark', statusIcon)),
light: Container.context.asAbsolutePath(path.join('images', 'light', statusIcon))
};
item.command = this.getCommand();
return item;
}
private _folderName: string | undefined;
get folderName() {
if (this._folderName === undefined) {
this._folderName = path.dirname(this.uri.getRelativePath());
}
return this._folderName;
}
private _label: string | undefined;
get label() {
if (this._label === undefined) {
this._label = StatusFileFormatter.fromTemplate(this.explorer.config.statusFileFormat, this.status, {
relativePath: this.relativePath
} as IStatusFormatOptions);
}
return this._label;
}
private _relativePath: string | undefined;
get relativePath(): string | undefined {
return this._relativePath;
}
set relativePath(value: string | undefined) {
this._relativePath = value;
this._label = undefined;
}
get priority(): boolean {
return false;
}
getCommand(): Command | undefined {
return {
title: 'Open Changes',
command: Commands.DiffWith,
arguments: [
this.uri,
{
lhs: {
sha: this.ref1,
uri: this.uri
},
rhs: {
sha: this.ref2,
uri: this.status.status === 'R'
? GitUri.fromFileStatus(this.status, this.uri.repoPath!, this.ref2, true)
: this.uri
},
repoPath: this.uri.repoPath!,
line: 0,
showOptions: {
preserveFocus: true,
preview: true
}
} as DiffWithCommandArgs
]
};
}
}

+ 83
- 83
src/views/statusFilesResultsNode.ts Просмотреть файл

@ -1,84 +1,84 @@
'use strict';
import { Arrays, Iterables, Strings } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ExplorerFilesLayout } from '../configuration';
import { Container } from '../container';
import { Explorer, ExplorerNode, ResourceType } from './explorerNode';
import { FolderNode, IFileExplorerNode } from './folderNode';
import { GitStatusFile, GitUri } from '../gitService';
import { StatusFileNode } from './statusFileNode';
import * as path from 'path';
export class StatusFilesResultsNode extends ExplorerNode {
readonly supportsPaging: boolean = true;
private _cache: { label: string, diff: GitStatusFile[] | undefined } | undefined;
constructor(
readonly repoPath: string,
private readonly ref1: string,
private readonly ref2: string,
private readonly explorer: Explorer
) {
super(GitUri.fromRepoPath(repoPath));
}
async getChildren(): Promise<ExplorerNode[]> {
const diff = await this.getDiff();
if (diff === undefined) return [];
let children: IFileExplorerNode[] = [...Iterables.map(diff, s => new StatusFileNode(this.repoPath, s, this.ref1, this.ref2, this.explorer))];
if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) {
const hierarchy = Arrays.makeHierarchical(children, n => n.uri.getRelativePath().split('/'),
(...paths: string[]) => Strings.normalizePath(path.join(...paths)), this.explorer.config.files.compact);
const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this.explorer);
children = await root.getChildren() as IFileExplorerNode[];
}
else {
children.sort((a, b) => (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || a.label!.localeCompare(b.label!));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const diff = await this.getDiff();
const item = new TreeItem(await this.getLabel(), diff && diff.length > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None);
item.contextValue = ResourceType.ResultsFiles;
return item;
}
refresh() {
this._cache = undefined;
}
private async ensureCache() {
if (this._cache === undefined) {
const diff = await Container.git.getDiffStatus(this.uri.repoPath!, this.ref1, this.ref2);
const count = diff !== undefined ? diff.length : 0;
const label = `${count === 0 ? 'No' : count} ${count === 1 ? 'file' : 'files'} changed`;
this._cache = {
label: label,
diff: diff
};
}
return this._cache;
}
private async getDiff() {
const cache = await this.ensureCache();
return cache.diff;
}
private async getLabel() {
const cache = await this.ensureCache();
return cache.label;
}
'use strict';
import { Arrays, Iterables, Strings } from '../system';
import { TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ExplorerFilesLayout } from '../configuration';
import { Container } from '../container';
import { Explorer, ExplorerNode, ResourceType } from './explorerNode';
import { FolderNode, IFileExplorerNode } from './folderNode';
import { GitStatusFile, GitUri } from '../gitService';
import { StatusFileNode } from './statusFileNode';
import * as path from 'path';
export class StatusFilesResultsNode extends ExplorerNode {
readonly supportsPaging: boolean = true;
private _cache: { label: string, diff: GitStatusFile[] | undefined } | undefined;
constructor(
public readonly repoPath: string,
private readonly ref1: string,
private readonly ref2: string,
private readonly explorer: Explorer
) {
super(GitUri.fromRepoPath(repoPath));
}
async getChildren(): Promise<ExplorerNode[]> {
const diff = await this.getDiff();
if (diff === undefined) return [];
let children: IFileExplorerNode[] = [...Iterables.map(diff, s => new StatusFileNode(this.repoPath, s, this.ref1, this.ref2, this.explorer))];
if (this.explorer.config.files.layout !== ExplorerFilesLayout.List) {
const hierarchy = Arrays.makeHierarchical(children, n => n.uri.getRelativePath().split('/'),
(...paths: string[]) => Strings.normalizePath(path.join(...paths)), this.explorer.config.files.compact);
const root = new FolderNode(this.repoPath, '', undefined, hierarchy, this.explorer);
children = await root.getChildren() as IFileExplorerNode[];
}
else {
children.sort((a, b) => (a.priority ? -1 : 1) - (b.priority ? -1 : 1) || a.label!.localeCompare(b.label!));
}
return children;
}
async getTreeItem(): Promise<TreeItem> {
const diff = await this.getDiff();
const item = new TreeItem(await this.getLabel(), diff && diff.length > 0 ? TreeItemCollapsibleState.Expanded : TreeItemCollapsibleState.None);
item.contextValue = ResourceType.ResultsFiles;
return item;
}
refresh() {
this._cache = undefined;
}
private async ensureCache() {
if (this._cache === undefined) {
const diff = await Container.git.getDiffStatus(this.uri.repoPath!, this.ref1, this.ref2);
const count = diff !== undefined ? diff.length : 0;
const label = `${count === 0 ? 'No' : count} ${count === 1 ? 'file' : 'files'} changed`;
this._cache = {
label: label,
diff: diff
};
}
return this._cache;
}
private async getDiff() {
const cache = await this.ensureCache();
return cache.diff;
}
private async getLabel() {
const cache = await this.ensureCache();
return cache.label;
}
}

Загрузка…
Отмена
Сохранить