|
|
@ -1,10 +1,11 @@ |
|
|
|
'use strict'; |
|
|
|
import { CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode'; |
|
|
|
import { CancellationToken, CancellationTokenSource, QuickPickItem, QuickPickOptions, window } from 'vscode'; |
|
|
|
import { GlyphChars } from '../constants'; |
|
|
|
import { Container } from '../container'; |
|
|
|
import { GitBranch, GitTag } from '../git/gitService'; |
|
|
|
import { KeyNoopCommand } from '../keyboard'; |
|
|
|
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut, showQuickPickProgress } from './commonQuickPicks'; |
|
|
|
import { Functions, Iterables } from '../system'; |
|
|
|
import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './commonQuickPicks'; |
|
|
|
|
|
|
|
export class BranchOrTagQuickPickItem implements QuickPickItem { |
|
|
|
label: string; |
|
|
@ -12,12 +13,15 @@ export class BranchOrTagQuickPickItem implements QuickPickItem { |
|
|
|
detail: string | undefined; |
|
|
|
|
|
|
|
constructor( |
|
|
|
public readonly branchOrTag: GitBranch | GitTag |
|
|
|
public readonly branchOrTag: GitBranch | GitTag, |
|
|
|
checked?: boolean |
|
|
|
) { |
|
|
|
if (branchOrTag instanceof GitBranch) { |
|
|
|
this.label = `${branchOrTag.current ? `$(check)${GlyphChars.Space}` : GlyphChars.Space.repeat(4)} ${ |
|
|
|
branchOrTag.name |
|
|
|
}`;
|
|
|
|
this.label = `${ |
|
|
|
checked === true || (checked === undefined && branchOrTag.current) |
|
|
|
? `$(check)${GlyphChars.Space}` |
|
|
|
: GlyphChars.Space.repeat(4) |
|
|
|
} ${branchOrTag.name}`;
|
|
|
|
this.description = branchOrTag.remote ? `${GlyphChars.Space.repeat(2)} remote branch` : ''; |
|
|
|
} |
|
|
|
else { |
|
|
@ -26,6 +30,10 @@ export class BranchOrTagQuickPickItem implements QuickPickItem { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
get current() { |
|
|
|
return this.branchOrTag instanceof GitBranch ? this.branchOrTag.current : false; |
|
|
|
} |
|
|
|
|
|
|
|
get name() { |
|
|
|
return this.branchOrTag.name; |
|
|
|
} |
|
|
@ -36,45 +44,83 @@ export class BranchOrTagQuickPickItem implements QuickPickItem { |
|
|
|
} |
|
|
|
|
|
|
|
export class BranchesAndTagsQuickPick { |
|
|
|
static showProgress(placeHolder: string) { |
|
|
|
return showQuickPickProgress(placeHolder, { |
|
|
|
left: KeyNoopCommand, |
|
|
|
',': KeyNoopCommand, |
|
|
|
'.': KeyNoopCommand |
|
|
|
}); |
|
|
|
} |
|
|
|
constructor( |
|
|
|
public readonly repoPath: string |
|
|
|
) {} |
|
|
|
|
|
|
|
static async show( |
|
|
|
branches: GitBranch[], |
|
|
|
tags: GitTag[], |
|
|
|
async show( |
|
|
|
placeHolder: string, |
|
|
|
options: { goBackCommand?: CommandQuickPickItem; progressCancellation?: CancellationTokenSource } = {} |
|
|
|
options: { checked?: string; goBack?: CommandQuickPickItem } = {} |
|
|
|
): Promise<BranchOrTagQuickPickItem | CommandQuickPickItem | undefined> { |
|
|
|
const items = [ |
|
|
|
...branches.filter(b => !b.remote).map(b => new BranchOrTagQuickPickItem(b)), |
|
|
|
...tags.map(t => new BranchOrTagQuickPickItem(t)), |
|
|
|
...branches.filter(b => b.remote).map(b => new BranchOrTagQuickPickItem(b)) |
|
|
|
] as (BranchOrTagQuickPickItem | CommandQuickPickItem)[]; |
|
|
|
const cancellation = new CancellationTokenSource(); |
|
|
|
|
|
|
|
if (options.goBackCommand !== undefined) { |
|
|
|
items.splice(0, 0, options.goBackCommand); |
|
|
|
} |
|
|
|
try { |
|
|
|
const items = this.getItems(options, cancellation.token); |
|
|
|
const scope = await Container.keyboard.beginScope({ left: options.goBack || KeyNoopCommand }); |
|
|
|
|
|
|
|
const pick = await window.showQuickPick(items, { |
|
|
|
placeHolder: placeHolder, |
|
|
|
ignoreFocusOut: getQuickPickIgnoreFocusOut() |
|
|
|
} as QuickPickOptions); |
|
|
|
|
|
|
|
if (options.progressCancellation !== undefined && options.progressCancellation.token.isCancellationRequested) { |
|
|
|
return undefined; |
|
|
|
if (pick === undefined) { |
|
|
|
cancellation.cancel(); |
|
|
|
} |
|
|
|
await scope.dispose(); |
|
|
|
|
|
|
|
return pick; |
|
|
|
} |
|
|
|
finally { |
|
|
|
cancellation.dispose(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const scope = await Container.keyboard.beginScope({ left: options.goBackCommand || KeyNoopCommand }); |
|
|
|
private async getItems( |
|
|
|
options: { checked?: string; goBack?: CommandQuickPickItem } = {}, |
|
|
|
token: CancellationToken |
|
|
|
) { |
|
|
|
const result = await Functions.cancellable( |
|
|
|
Promise.all([Container.git.getBranches(this.repoPath), Container.git.getTags(this.repoPath)]), |
|
|
|
token |
|
|
|
); |
|
|
|
if (result === undefined || token.isCancellationRequested) return []; |
|
|
|
|
|
|
|
options.progressCancellation && options.progressCancellation.cancel(); |
|
|
|
const [branches, tags] = result; |
|
|
|
|
|
|
|
const pick = await window.showQuickPick(items, { |
|
|
|
placeHolder: placeHolder, |
|
|
|
ignoreFocusOut: getQuickPickIgnoreFocusOut() |
|
|
|
} as QuickPickOptions); |
|
|
|
const items = [ |
|
|
|
...Iterables.filterMap( |
|
|
|
branches, |
|
|
|
b => |
|
|
|
!b.remote |
|
|
|
? new BranchOrTagQuickPickItem( |
|
|
|
b, |
|
|
|
options.checked !== undefined ? b.name === options.checked : undefined |
|
|
|
) |
|
|
|
: undefined |
|
|
|
), |
|
|
|
...Iterables.filterMap( |
|
|
|
branches, |
|
|
|
b => |
|
|
|
b.remote |
|
|
|
? new BranchOrTagQuickPickItem( |
|
|
|
b, |
|
|
|
options.checked !== undefined ? b.name === options.checked : undefined |
|
|
|
) |
|
|
|
: undefined |
|
|
|
), |
|
|
|
...tags.map( |
|
|
|
t => |
|
|
|
new BranchOrTagQuickPickItem( |
|
|
|
t, |
|
|
|
options.checked !== undefined ? t.name === options.checked : undefined |
|
|
|
) |
|
|
|
) |
|
|
|
] as (BranchOrTagQuickPickItem | CommandQuickPickItem)[]; |
|
|
|
|
|
|
|
await scope.dispose(); |
|
|
|
if (options.goBack !== undefined) { |
|
|
|
items.splice(0, 0, options.goBack); |
|
|
|
} |
|
|
|
|
|
|
|
return pick; |
|
|
|
return items; |
|
|
|
} |
|
|
|
} |