Переглянути джерело

Adds an experimental custom view (wip)

main
Eric Amodio 7 роки тому
джерело
коміт
c812a56eac
20 змінених файлів з 1939 додано та 1401 видалено
  1. +4
    -0
      images/dark/icon-commit.svg
  2. +0
    -0
      images/dark/icon-refresh.svg
  3. +4
    -0
      images/light/icon-commit.svg
  4. +1445
    -1384
      package.json
  5. +1
    -0
      src/commands.ts
  6. +14
    -1
      src/commands/common.ts
  7. +31
    -13
      src/commands/openCommitInRemote.ts
  8. +7
    -1
      src/commands/showFileHistory.ts
  9. +30
    -0
      src/commands/showStashList.ts
  10. +7
    -0
      src/configuration.ts
  11. +12
    -2
      src/extension.ts
  12. +41
    -0
      src/views/commitFileNode.ts
  13. +54
    -0
      src/views/commitNode.ts
  14. +15
    -0
      src/views/explorerNode.ts
  15. +29
    -0
      src/views/fileHistoryNode.ts
  16. +62
    -0
      src/views/gitExplorer.ts
  17. +9
    -0
      src/views/gitExplorerNodes.ts
  18. +105
    -0
      src/views/repositoryNode.ts
  19. +40
    -0
      src/views/stashCommitNode.ts
  20. +29
    -0
      src/views/stashNode.ts

+ 4
- 0
images/dark/icon-commit.svg Переглянути файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve">
<path fill="#FFFFFF" fill-rule="evenodd" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path>
</svg>

+ 0
- 0
images/dark/icon-refresh.svg Переглянути файл


+ 4
- 0
images/light/icon-commit.svg Переглянути файл

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256" height="256" viewBox="0 0 14 16" xml:space="preserve">
<path fill="#00000" fill-rule="evenodd" d="M10.86 7c-.45-1.72-2-3-3.86-3-1.86 0-3.41 1.28-3.86 3H0v2h3.14c.45 1.72 2 3 3.86 3 1.86 0 3.41-1.28 3.86-3H14V7h-3.14zM7 10.2c-1.22 0-2.2-.98-2.2-2.2 0-1.22.98-2.2 2.2-2.2 1.22 0 2.2.98 2.2 2.2 0 1.22-.98 2.2-2.2 2.2z"></path>
</svg>

+ 1445
- 1384
package.json
Різницю між файлами не показано, бо вона завелика
Переглянути файл


+ 1
- 0
src/commands.ts Переглянути файл

@ -32,6 +32,7 @@ export * from './commands/showQuickCurrentBranchHistory';
export * from './commands/showQuickFileHistory';
export * from './commands/showQuickRepoStatus';
export * from './commands/showQuickStashList';
export * from './commands/showStashList';
export * from './commands/stashApply';
export * from './commands/stashDelete';
export * from './commands/stashSave';

+ 14
- 1
src/commands/common.ts Переглянути файл

@ -1,5 +1,6 @@
'use strict';
import { commands, Disposable, SourceControlResourceGroup, SourceControlResourceState, TextDocumentShowOptions, TextEditor, TextEditorEdit, Uri, window, workspace } from 'vscode';
import { ExplorerNode } from '../views/gitExplorerNodes';
import { Logger } from '../logger';
import { Telemetry } from '../telemetry';
@ -34,6 +35,7 @@ export type Commands = 'gitlens.closeUnchangedFiles' |
'gitlens.showQuickRepoHistory' |
'gitlens.showQuickRepoStatus' |
'gitlens.showQuickStashList' |
'gitlens.showStashList' |
'gitlens.stashApply' |
'gitlens.stashDelete' |
'gitlens.stashSave' |
@ -73,6 +75,7 @@ export const Commands = {
ShowQuickCurrentBranchHistory: 'gitlens.showQuickRepoHistory' as Commands,
ShowQuickRepoStatus: 'gitlens.showQuickRepoStatus' as Commands,
ShowQuickStashList: 'gitlens.showQuickStashList' as Commands,
ShowStashList: 'gitlens.showStashList' as Commands,
StashApply: 'gitlens.stashApply' as Commands,
StashDelete: 'gitlens.stashDelete' as Commands,
StashSave: 'gitlens.stashSave' as Commands,
@ -116,7 +119,12 @@ export interface CommandUriContext extends CommandBaseContext {
type: 'uri';
}
export type CommandContext = CommandScmGroupsContext | CommandScmStatesContext | CommandUnknownContext | CommandUriContext;
export interface CommandViewContext extends CommandBaseContext {
type: 'view';
node: ExplorerNode;
}
export type CommandContext = CommandScmGroupsContext | CommandScmStatesContext | CommandUnknownContext | CommandUriContext | CommandViewContext;
function isScmResourceGroup(group: any): group is SourceControlResourceGroup {
if (group === undefined) return false;
@ -180,6 +188,11 @@ export abstract class Command extends Disposable {
return [{ type: 'uri', editor: editor, uri: uri }, rest];
}
if (firstArg instanceof ExplorerNode) {
const [node, ...rest] = args as [ExplorerNode, any];
return [{ type: 'view', node: node, uri: node.uri }, rest];
}
if (isScmResourceState(firstArg)) {
const states = [];
let count = 0;

+ 31
- 13
src/commands/openCommitInRemote.ts Переглянути файл

@ -1,11 +1,16 @@
'use strict';
import { Arrays } from '../system';
import { commands, TextEditor, Uri, window } from 'vscode';
import { ActiveEditorCommand, Commands, getCommandUri } from './common';
import { ActiveEditorCommand, CommandContext, Commands, getCommandUri } from './common';
import { GitBlameCommit, GitService, GitUri } from '../gitService';
import { Logger } from '../logger';
import { Messages } from '../messages';
import { OpenInRemoteCommandArgs } from './openInRemote';
import { CommitNode } from '../views/gitExplorer';
export interface OpenCommitInRemoteCommandArgs {
sha?: string;
}
export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
@ -13,7 +18,17 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
super(Commands.OpenCommitInRemote);
}
async execute(editor?: TextEditor, uri?: Uri) {
protected async preExecute(context: CommandContext, args: OpenCommitInRemoteCommandArgs = {}): Promise<any> {
if (context.type === 'view' && context.node instanceof CommitNode) {
args = { ...args };
args.sha = context.node.commit.sha;
return this.execute(context.editor, context.node.commit.uri, args);
}
return this.execute(context.editor, context.uri, args);
}
async execute(editor?: TextEditor, uri?: Uri, args: OpenCommitInRemoteCommandArgs = {}) {
uri = getCommandUri(uri, editor);
if (uri === undefined) return undefined;
if (editor !== undefined && editor.document !== undefined && editor.document.isDirty) return undefined;
@ -21,26 +36,29 @@ export class OpenCommitInRemoteCommand extends ActiveEditorCommand {
const gitUri = await GitUri.fromUri(uri, this.git);
if (!gitUri.repoPath) return undefined;
const line = editor === undefined ? gitUri.offset : editor.selection.active.line;
try {
const blameline = line - gitUri.offset;
if (blameline < 0) return undefined;
if (args.sha === undefined) {
const line = editor === undefined ? gitUri.offset : editor.selection.active.line;
const blameline = line - gitUri.offset;
if (blameline < 0) return undefined;
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open commit in remote provider');
const blame = await this.git.getBlameForLine(gitUri, blameline);
if (blame === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to open commit in remote provider');
let commit = blame.commit;
// If the line is uncommitted, find the previous commit
if (commit.isUncommitted) {
commit = new GitBlameCommit(commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message, []);
}
let commit = blame.commit;
// If the line is uncommitted, find the previous commit
if (commit.isUncommitted) {
commit = new GitBlameCommit(commit.repoPath, commit.previousSha!, commit.previousFileName!, commit.author, commit.date, commit.message, []);
args.sha = commit.sha;
}
const remotes = Arrays.uniqueBy(await this.git.getRemotes(gitUri.repoPath), _ => _.url, _ => !!_.provider);
return commands.executeCommand(Commands.OpenInRemote, uri, {
resource: {
type: 'commit',
sha: commit.sha
sha: args.sha
},
remotes
} as OpenInRemoteCommandArgs);

+ 7
- 1
src/commands/showFileHistory.ts Переглянути файл

@ -2,6 +2,7 @@
import { commands, Position, Range, TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { Commands, EditorCommand, getCommandUri } from './common';
import { BuiltInCommands } from '../constants';
import { GitExplorer } from '../views/gitExplorer';
import { GitService, GitUri } from '../gitService';
import { Messages } from '../messages';
import { Logger } from '../logger';
@ -14,7 +15,7 @@ export interface ShowFileHistoryCommandArgs {
export class ShowFileHistoryCommand extends EditorCommand {
constructor(private git: GitService) {
constructor(private git: GitService, private explorer?: GitExplorer) {
super(Commands.ShowFileHistory);
}
@ -32,6 +33,11 @@ export class ShowFileHistoryCommand extends EditorCommand {
const gitUri = await GitUri.fromUri(uri, this.git);
try {
if (this.explorer !== undefined) {
this.explorer.addHistory(gitUri);
return undefined;
}
const locations = await this.git.getLogLocations(gitUri, args.sha, args.line);
if (locations === undefined) return Messages.showFileNotUnderSourceControlWarningMessage('Unable to show file history');

+ 30
- 0
src/commands/showStashList.ts Переглянути файл

@ -0,0 +1,30 @@
'use strict';
import { TextEditor, TextEditorEdit, Uri, window } from 'vscode';
import { Commands, EditorCommand, getCommandUri } from './common';
import { GitExplorer } from '../views/gitExplorer';
import { GitService, GitUri } from '../gitService';
import { Messages } from '../messages';
import { Logger } from '../logger';
export class ShowStashListCommand extends EditorCommand {
constructor(private git: GitService, private explorer: GitExplorer) {
super(Commands.ShowStashList);
}
async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) {
uri = getCommandUri(uri, editor);
try {
const repoPath = await this.git.getRepoPathFromUri(uri);
if (!repoPath) return Messages.showNoRepositoryWarningMessage(`Unable to show stashed changes`);
this.explorer.addStash(new GitUri(uri, { repoPath: repoPath, fileName: uri!.fsPath }));
return undefined;
}
catch (ex) {
Logger.error(ex, 'ShowStashListCommand');
return window.showErrorMessage(`Unable to show stash list. See output channel for more details`);
}
}
}

+ 7
- 0
src/configuration.ts Переглянути файл

@ -303,6 +303,13 @@ export interface IConfig {
defaultDateFormat: string | null;
explorer: {
commitFormat: string;
commitFileFormat: string;
stashFormat: string;
// dateFormat: string | null;
};
statusBar: {
enabled: boolean;
alignment: 'left' | 'right';

+ 12
- 2
src/extension.ts Переглянути файл

@ -12,13 +12,14 @@ import { ShowBlameHistoryCommand, ShowFileHistoryCommand } from './commands';
import { ShowLastQuickPickCommand } from './commands';
import { ShowQuickBranchHistoryCommand, ShowQuickCurrentBranchHistoryCommand, ShowQuickFileHistoryCommand } from './commands';
import { ShowCommitSearchCommand, ShowQuickCommitDetailsCommand, ShowQuickCommitFileDetailsCommand } from './commands';
import { ShowQuickRepoStatusCommand, ShowQuickStashListCommand } from './commands';
import { ShowQuickRepoStatusCommand, ShowQuickStashListCommand, ShowStashListCommand } from './commands';
import { StashApplyCommand, StashDeleteCommand, StashSaveCommand } from './commands';
import { ToggleCodeLensCommand } from './commands';
import { CodeLensLocations, IConfig, LineHighlightLocations } from './configuration';
import { ApplicationInsightsKey, CommandContext, ExtensionKey, QualifiedExtensionId, setCommandContext, WorkspaceState } from './constants';
import { CurrentLineController, LineAnnotationType } from './currentLineController';
import { GitContentProvider } from './gitContentProvider';
import { GitExplorer } from './views/gitExplorer';
import { GitRevisionCodeLensProvider } from './gitRevisionCodeLensProvider';
import { GitContextTracker, GitService } from './gitService';
import { Keyboard } from './keyboard';
@ -87,6 +88,12 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new Keyboard());
let explorer: GitExplorer | undefined = undefined;
if (cfg.insiders) {
explorer = new GitExplorer(context, git);
context.subscriptions.push(window.registerTreeDataProvider('gitlens-explorer', explorer));
}
context.subscriptions.push(new CloseUnchangedFilesCommand(git));
context.subscriptions.push(new OpenChangedFilesCommand(git));
context.subscriptions.push(new CopyMessageToClipboardCommand(git));
@ -111,7 +118,7 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new ToggleLineBlameCommand(currentLineController));
context.subscriptions.push(new ResetSuppressedWarningsCommand(context));
context.subscriptions.push(new ShowBlameHistoryCommand(git));
context.subscriptions.push(new ShowFileHistoryCommand(git));
context.subscriptions.push(new ShowFileHistoryCommand(git, explorer));
context.subscriptions.push(new ShowLastQuickPickCommand());
context.subscriptions.push(new ShowQuickBranchHistoryCommand(git));
context.subscriptions.push(new ShowQuickCurrentBranchHistoryCommand(git));
@ -121,6 +128,9 @@ export async function activate(context: ExtensionContext) {
context.subscriptions.push(new ShowQuickFileHistoryCommand(git));
context.subscriptions.push(new ShowQuickRepoStatusCommand(git));
context.subscriptions.push(new ShowQuickStashListCommand(git));
if (cfg.insiders) {
context.subscriptions.push(new ShowStashListCommand(git, explorer!));
}
context.subscriptions.push(new StashApplyCommand(git));
context.subscriptions.push(new StashDeleteCommand(git));
context.subscriptions.push(new StashSaveCommand(git));

+ 41
- 0
src/views/commitFileNode.ts Переглянути файл

@ -0,0 +1,41 @@
'use strict';
import { Command, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { Commands, DiffWithPreviousCommandArgs } from '../commands';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitCommit, GitService, GitUri, IGitStatusFile } from '../gitService';
export class CommitFileNode extends ExplorerNode {
readonly resourceType: ResourceType = 'commit-file';
command: Command;
constructor(public status: IGitStatusFile, public commit: GitCommit, uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
this.command = {
title: 'Compare File with Previous',
command: Commands.DiffWithPrevious,
arguments: [
GitUri.fromFileStatus(this.status, this.commit.repoPath),
{
commit: commit,
showOptions: {
preserveFocus: true,
preview: true
}
} as DiffWithPreviousCommandArgs
]
};
}
getChildren(): Promise<ExplorerNode[]> {
return Promise.resolve([]);
}
getTreeItem(): TreeItem {
const item = new TreeItem(`${GitUri.getFormattedPath(this.status.fileName)}`, TreeItemCollapsibleState.None);
item.contextValue = this.resourceType;
item.command = this.command;
return item;
}
}

+ 54
- 0
src/views/commitNode.ts Переглянути файл

@ -0,0 +1,54 @@
'use strict';
import { Iterables } from '../system';
import { Command, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitFileNode } from './commitFileNode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { CommitFormatter, GitCommit, GitService, GitUri } from '../gitService';
export class CommitNode extends ExplorerNode {
readonly resourceType: ResourceType = 'commit';
command: Command;
constructor(public commit: GitCommit, uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
// this.command = {
// title: 'Compare File with Previous',
// command: Commands.DiffWithPrevious,
// arguments: [
// Uri.file(commit.uri.fsPath),
// {
// commit: commit,
// showOptions: {
// preserveFocus: true,
// preview: true
// }
// } as DiffWithPreviousCommandArgs
// ]
// };
}
async getChildren(): Promise<ExplorerNode[]> {
const log = await this.git.getLogForRepo(this.commit.repoPath, this.commit.sha, 1);
if (log === undefined) return [];
const commit = Iterables.first(log.commits.values());
if (commit === undefined) return [];
return [...Iterables.map(commit.fileStatuses, s => new CommitFileNode(s, commit, this.uri, this.context, this.git))];
}
getTreeItem(): TreeItem {
const label = CommitFormatter.fromTemplate(this.git.config.explorer.commitFormat, this.commit, this.git.config.defaultDateFormat);
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
item.contextValue = this.resourceType;
item.iconPath = {
dark: this.context.asAbsolutePath('images/dark/icon-commit.svg'),
light: this.context.asAbsolutePath('images/light/icon-commit.svg')
};
item.command = this.command;
return item;
}
}

+ 15
- 0
src/views/explorerNode.ts Переглянути файл

@ -0,0 +1,15 @@
'use strict';
import { ExtensionContext, TreeItem } from 'vscode';
import { GitService, GitUri } from '../gitService';
export declare type ResourceType = 'status' | 'branches' | 'repository' | 'branch-history' | 'file-history' | 'stash-history' | 'commit' | 'stash-commit' | 'commit-file';
export abstract class ExplorerNode {
abstract readonly resourceType: ResourceType;
constructor(public uri: GitUri, protected context: ExtensionContext, protected git: GitService) { }
abstract getChildren(): ExplorerNode[] | Promise<ExplorerNode[]>;
abstract getTreeItem(): TreeItem | Promise<TreeItem>;
}

+ 29
- 0
src/views/fileHistoryNode.ts Переглянути файл

@ -0,0 +1,29 @@
'use strict';
import { Iterables } from '../system';
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitService, GitUri } from '../gitService';
export class FileHistoryNode extends ExplorerNode {
static readonly rootType: ResourceType = 'file-history';
readonly resourceType: ResourceType = 'file-history';
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
}
async getChildren(): Promise<CommitNode[]> {
const log = await this.git.getLogForFile(this.uri.repoPath, this.uri.fsPath, this.uri.sha);
if (log === undefined) return [];
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.uri, this.context, this.git))];
}
getTreeItem(): TreeItem {
const item = new TreeItem(`History of ${this.uri.getFormattedPath()}`, TreeItemCollapsibleState.Expanded);
item.contextValue = this.resourceType;
return item;
}
}

+ 62
- 0
src/views/gitExplorer.ts Переглянути файл

@ -0,0 +1,62 @@
'use strict';
import { Event, EventEmitter, ExtensionContext, TreeDataProvider, TreeItem, Uri, window } from 'vscode';
import { UriComparer } from '../comparers';
import { ExplorerNode, FileHistoryNode, RepositoryNode, ResourceType, StashNode } from './gitExplorerNodes';
import { GitService, GitUri } from '../gitService';
export * from './gitExplorerNodes';
export class GitExplorer implements TreeDataProvider<ExplorerNode> {
private _onDidChangeTreeData = new EventEmitter<ExplorerNode>();
public get onDidChangeTreeData(): Event<ExplorerNode> {
return this._onDidChangeTreeData.event;
}
private _roots: ExplorerNode[] = [];
constructor(private context: ExtensionContext, private git: GitService) {
const editor = window.activeTextEditor;
const uri = (editor !== undefined && editor.document !== undefined)
? new GitUri(editor.document.uri, { repoPath: git.repoPath, fileName: editor.document.uri.fsPath })
: new GitUri(Uri.file(git.repoPath), { repoPath: git.repoPath, fileName: git.repoPath });
this._roots.push(new RepositoryNode(uri, context, git));
}
async getTreeItem(node: ExplorerNode): Promise<TreeItem> {
return node.getTreeItem();
}
async getChildren(node?: ExplorerNode): Promise<ExplorerNode[]> {
if (this._roots.length === 0) return [];
if (node === undefined) return this._roots;
return node.getChildren();
}
addHistory(uri: GitUri) {
this._add(uri, FileHistoryNode);
}
addStash(uri: GitUri) {
this._add(uri, StashNode);
}
private _add<T extends ExplorerNode>(uri: GitUri, type: { new (uri: GitUri, context: ExtensionContext, git: GitService): T, rootType: ResourceType }) {
if (!this._roots.some(_ => _.resourceType === type.rootType && UriComparer.equals(uri, _.uri))) {
this._roots.push(new type(uri, this.context, this.git));
}
this._onDidChangeTreeData.fire();
}
clear() {
this._roots = [];
this._onDidChangeTreeData.fire();
}
refresh() {
this._onDidChangeTreeData.fire();
}
}

+ 9
- 0
src/views/gitExplorerNodes.ts Переглянути файл

@ -0,0 +1,9 @@
'use strict';
export * from './explorerNode';
export * from './commitFileNode';
export * from './commitNode';
export * from './fileHistoryNode';
export * from './repositoryNode';
export * from './stashCommitNode';
export * from './stashNode';

+ 105
- 0
src/views/repositoryNode.ts Переглянути файл

@ -0,0 +1,105 @@
'use strict';
import { Iterables, Strings } from '../system';
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitNode } from './commitNode';
import { GlyphChars } from '../constants';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitBranch, GitService, GitUri } from '../gitService';
import { StashNode } from './stashNode';
export class RepositoryNode extends ExplorerNode {
static readonly rootType: ResourceType = 'repository';
readonly resourceType: ResourceType = 'repository';
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
}
async getChildren(): Promise<ExplorerNode[]> {
return [
new StatusNode(this.uri, this.context, this.git),
new StashNode(this.uri, this.context, this.git),
new BranchesNode(this.uri, this.context, this.git)
];
}
getTreeItem(): TreeItem {
const item = new TreeItem(`Repository ${GlyphChars.Dash} ${this.uri.repoPath}`, TreeItemCollapsibleState.Expanded);
item.contextValue = this.resourceType;
return item;
}
}
export class BranchesNode extends ExplorerNode {
readonly resourceType: ResourceType = 'branches';
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
}
async getChildren(): Promise<BranchHistoryNode[]> {
const branches = await this.git.getBranches(this.uri.repoPath!);
if (branches === undefined) return [];
return [...Iterables.filterMap(branches.sort(_ => _.current ? 0 : 1), b => b.remote ? undefined : new BranchHistoryNode(b, this.uri, this.context, this.git))];
}
getTreeItem(): TreeItem {
const item = new TreeItem(`Branches`, TreeItemCollapsibleState.Collapsed);
item.contextValue = this.resourceType;
return item;
}
}
export class BranchHistoryNode extends ExplorerNode {
readonly resourceType: ResourceType = 'branch-history';
constructor(public branch: GitBranch, uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
}
async getChildren(): Promise<CommitNode[]> {
const log = await this.git.getLogForRepo(this.uri.repoPath!, this.branch.name);
if (log === undefined) return [];
return [...Iterables.map(log.commits.values(), c => new CommitNode(c, this.uri, this.context, this.git))];
}
getTreeItem(): TreeItem {
const item = new TreeItem(`${this.branch.name}${this.branch.current ? ` ${GlyphChars.Dash} current` : ''}`, TreeItemCollapsibleState.Collapsed);
item.contextValue = this.resourceType;
return item;
}
}
export class StatusNode extends ExplorerNode {
readonly resourceType: ResourceType = 'status';
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
}
async getChildren(): Promise<ExplorerNode[]> {
return [];
// const status = await this.git.getStatusForRepo(this.uri.repoPath!);
// if (status === undefined) return [];
// return [...Iterables.map(status.files, b => new CommitFile(b, this.uri, this.context, this.git))];
}
async getTreeItem(): Promise<TreeItem> {
const status = await this.git.getStatusForRepo(this.uri.repoPath!);
let suffix = '';
if (status !== undefined) {
suffix = ` ${GlyphChars.Dash} ${GlyphChars.ArrowUp} ${status.state.ahead} ${GlyphChars.ArrowDown} ${status.state.behind} ${Strings.pad(GlyphChars.Dot, 1, 1)} ${status.branch} ${GlyphChars.ArrowLeftRight} ${status.upstream}`;
}
const item = new TreeItem(`Status${suffix}`, TreeItemCollapsibleState.Collapsed);
item.contextValue = this.resourceType;
return item;
}
}

+ 40
- 0
src/views/stashCommitNode.ts Переглянути файл

@ -0,0 +1,40 @@
'use strict';
import { Command, ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { CommitFileNode } from './commitFileNode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { CommitFormatter, GitService, GitStashCommit, GitUri } from '../gitService';
export class StashCommitNode extends ExplorerNode {
readonly resourceType: ResourceType = 'stash-commit';
command: Command;
constructor(public commit: GitStashCommit, uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
// this.command = {
// title: 'Show Stash Details',
// command: Commands.ShowQuickCommitDetails,
// arguments: [
// new GitUri(commit.uri, commit),
// {
// commit: commit,
// sha: commit.sha
// } as ShowQuickCommitDetailsCommandArgs
// ]
// };
}
getChildren(): Promise<CommitFileNode[]> {
return Promise.resolve((this.commit as GitStashCommit).fileStatuses.map(_ => new CommitFileNode(_, this.commit, this.uri, this.context, this.git)));
}
getTreeItem(): TreeItem {
const label = CommitFormatter.fromTemplate(this.git.config.explorer.stashFormat, this.commit, this.git.config.defaultDateFormat);
const item = new TreeItem(label, TreeItemCollapsibleState.Collapsed);
item.contextValue = this.resourceType;
item.command = this.command;
return item;
}
}

+ 29
- 0
src/views/stashNode.ts Переглянути файл

@ -0,0 +1,29 @@
'use strict';
import { Iterables } from '../system';
import { ExtensionContext, TreeItem, TreeItemCollapsibleState } from 'vscode';
import { ExplorerNode, ResourceType } from './explorerNode';
import { GitService, GitUri } from '../gitService';
import { StashCommitNode } from './stashCommitNode';
export class StashNode extends ExplorerNode {
static readonly rootType: ResourceType = 'stash-history';
readonly resourceType: ResourceType = 'stash-history';
constructor(uri: GitUri, context: ExtensionContext, git: GitService) {
super(uri, context, git);
}
async getChildren(): Promise<StashCommitNode[]> {
const stash = await this.git.getStashList(this.uri.repoPath!);
if (stash === undefined) return [];
return [...Iterables.map(stash.commits.values(), c => new StashCommitNode(c, this.uri, this.context, this.git))];
}
getTreeItem(): TreeItem {
const item = new TreeItem(`Stashed Changes`, TreeItemCollapsibleState.Collapsed);
item.contextValue = this.resourceType;
return item;
}
}

Завантаження…
Відмінити
Зберегти