@ -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()); | |||||
} | } |
@ -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); | |||||
} | |||||
} |
@ -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); | |||||
} | |||||
} |
@ -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(); | |||||
} | |||||
} |
@ -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(); | |||||
} | |||||
} |
@ -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; | |||||
} | |||||
} | } |
@ -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; | |||||
} | |||||
} |
@ -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; | |||||
} | |||||
} | } |
@ -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; | |||||
} | |||||
} | } |
@ -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 | |||||
] | |||||
}; | |||||
} | |||||
} |
@ -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; | |||||
} | |||||
} | } |