Skip to content

Commit e6ffb93

Browse files
committed
Improves range entry in ref pickers
1 parent e192f31 commit e6ffb93

16 files changed

+75
-44
lines changed

src/commands/copyDeepLink.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ export class CopyFileDeepLinkCommand extends ActiveEditorCommand {
266266
`Copy Link to ${filePath} at Reference`,
267267
'Choose a reference (branch, tag, etc) to copy the file link for',
268268
{
269-
allowRevisions: true,
269+
allowedAdditionalInput: { rev: true },
270270
include: ReferencesQuickPickIncludes.All,
271271
},
272272
);

src/commands/diffFolderWithRevisionFrom.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export class DiffFolderWithRevisionFromCommand extends ActiveEditorCommand {
6060
`Open Folder Changes with Branch or Tag${pad(GlyphChars.Dot, 2, 2)}${relativePath}`,
6161
'Choose a reference (branch, tag, etc) to compare',
6262
{
63-
allowRevisions: true,
63+
allowedAdditionalInput: { rev: true },
6464
include: ReferencesQuickPickIncludes.All,
6565
sort: { branches: { current: true }, tags: {} },
6666
},
@@ -79,7 +79,7 @@ export class DiffFolderWithRevisionFromCommand extends ActiveEditorCommand {
7979
}`,
8080
'Choose a reference (branch, tag, etc) to compare with',
8181
{
82-
allowRevisions: true,
82+
allowedAdditionalInput: { rev: true },
8383
include:
8484
args.rhs === ''
8585
? ReferencesQuickPickIncludes.All & ~ReferencesQuickPickIncludes.WorkingTree

src/commands/diffWithRevisionFrom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export class DiffWithRevisionFromCommand extends ActiveEditorCommand {
7171
`${title}${gitUri.getFormattedFileName({ truncateTo: quickPickTitleMaxChars - title.length })}`,
7272
'Choose a reference (branch, tag, etc) to compare with',
7373
{
74-
allowRevisions: true,
74+
allowedAdditionalInput: { rev: true },
7575
},
7676
);
7777
if (pick == null) return;

src/commands/openDirectoryCompare.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class OpenDirectoryCompareCommand extends ActiveEditorCommand {
7474
'Directory Compare Working Tree with',
7575
'Choose a branch or tag to compare with',
7676
{
77-
allowRevisions: true,
77+
allowedAdditionalInput: { rev: true },
7878
},
7979
);
8080
if (pick == null) return;

src/commands/openFileAtRevisionFrom.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export class OpenFileAtRevisionFromCommand extends ActiveEditorCommand {
6969
`${title}${gitUri.getFormattedFileName({ truncateTo: quickPickTitleMaxChars - title.length })}`,
7070
'Choose a branch or tag to open the file revision from',
7171
{
72-
allowRevisions: true,
72+
allowedAdditionalInput: { rev: true },
7373
keyboard: {
7474
keys: ['right', 'alt+right', 'ctrl+right'],
7575
onDidPressKey: async (_key, item) => {

src/commands/openFileOnRemote.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ export class OpenFileOnRemoteCommand extends ActiveEditorCommand {
165165
: `Open File on Remote From${pad(GlyphChars.Dot, 2, 2)}${gitUri.relativePath}`,
166166
`Choose a branch or tag to ${args.clipboard ? 'copy' : 'open'} the file revision from`,
167167
{
168-
allowRevisions: true,
168+
allowedAdditionalInput: { rev: true },
169169
autoPick: true,
170170
filter: { branches: b => b.remote || b.upstream != null },
171171
picked: args.branchOrTag,

src/commands/quickCommand.steps.ts

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import {
5050
isTagReference,
5151
} from '../git/utils/reference.utils';
5252
import { getHighlanderProviderName } from '../git/utils/remote.utils';
53-
import { createRevisionRange, isRevisionRange } from '../git/utils/revision.utils';
53+
import { createRevisionRange, getRevisionRangeParts, isRevisionRange, isSha } from '../git/utils/revision.utils';
5454
import { getSubscriptionNextPaidPlanId, isSubscriptionPaidPlan } from '../plus/gk/utils/subscription.utils';
5555
import type { LaunchpadCommandArgs } from '../plus/launchpad/launchpad';
5656
import {
@@ -493,27 +493,51 @@ export async function getBranchesAndOrTags(
493493

494494
export function getValidateGitReferenceFn(
495495
repos: Repository | Repository[] | undefined,
496-
options?: { buttons?: QuickInputButton[]; ranges?: boolean },
496+
options?: {
497+
revs?: { allow: boolean; buttons?: QuickInputButton[] };
498+
ranges?: { allow: boolean; buttons?: QuickInputButton[]; validate?: boolean };
499+
},
497500
) {
498501
return async (quickpick: QuickPick<any>, value: string): Promise<boolean> => {
499-
let inRefMode = false;
500-
if (value.startsWith('#')) {
501-
inRefMode = true;
502-
value = value.substring(1);
503-
}
504-
505502
if (repos == null) return false;
506503
if (Array.isArray(repos)) {
507504
if (repos.length !== 1) return false;
508505

509506
repos = repos[0];
510507
}
511508

512-
if (inRefMode && options?.ranges && isRevisionRange(value)) {
509+
let allowRevs = false;
510+
if (value.startsWith('#')) {
511+
allowRevs = options?.revs?.allow ?? true;
512+
value = value.substring(1);
513+
allowRevs = true;
514+
} else if (isSha(value)) {
515+
allowRevs = options?.revs?.allow ?? true;
516+
}
517+
518+
if (options?.ranges?.allow && isRevisionRange(value)) {
519+
if (options?.ranges?.validate) {
520+
// Validate the parts of the range
521+
const parts = getRevisionRangeParts(value);
522+
const [leftResult, rightResult] = await Promise.allSettled([
523+
parts?.left != null ? repos.git.refs.isValidReference(parts.left) : Promise.resolve(true),
524+
parts?.right != null ? repos.git.refs.isValidReference(parts.right) : Promise.resolve(true),
525+
]);
526+
527+
if (!getSettledValue(leftResult, false) || !getSettledValue(rightResult, false)) {
528+
quickpick.items = [
529+
createDirectiveQuickPickItem(Directive.Noop, true, {
530+
label: `Invalid Range: ${value}`,
531+
}),
532+
];
533+
return true;
534+
}
535+
}
536+
513537
quickpick.items = [
514538
createRefQuickPickItem(value, repos.path, true, {
515539
alwaysShow: true,
516-
buttons: options?.buttons,
540+
buttons: options?.ranges?.buttons,
517541
ref: false,
518542
icon: false,
519543
}),
@@ -522,9 +546,9 @@ export function getValidateGitReferenceFn(
522546
}
523547

524548
if (!(await repos.git.refs.isValidReference(value))) {
525-
if (inRefMode) {
549+
if (allowRevs) {
526550
quickpick.items = [
527-
createDirectiveQuickPickItem(Directive.Back, true, {
551+
createDirectiveQuickPickItem(Directive.Noop, true, {
528552
label: 'Enter a reference or commit SHA',
529553
}),
530554
];
@@ -534,7 +558,7 @@ export function getValidateGitReferenceFn(
534558
return false;
535559
}
536560

537-
if (!inRefMode) {
561+
if (!allowRevs) {
538562
if (
539563
await repos.git.refs.hasBranchOrTag({
540564
filter: { branches: b => b.name.includes(value), tags: t => t.name.includes(value) },
@@ -548,7 +572,7 @@ export function getValidateGitReferenceFn(
548572
quickpick.items = [
549573
await createCommitQuickPickItem(commit!, true, {
550574
alwaysShow: true,
551-
buttons: options?.buttons,
575+
buttons: options?.revs?.buttons,
552576
compact: true,
553577
icon: 'avatar',
554578
}),
@@ -1028,7 +1052,10 @@ export function* pickBranchOrTagStep<
10281052
void showCommitInDetailsView(item, { pin: false, preserveFocus: true });
10291053
}
10301054
},
1031-
onValidateValue: getValidateGitReferenceFn(state.repo, { ranges: ranges }),
1055+
onValidateValue: getValidateGitReferenceFn(
1056+
state.repo,
1057+
ranges ? { ranges: { allow: true, validate: true } } : undefined,
1058+
),
10321059
});
10331060

10341061
const selection: StepSelection<typeof step> = yield step;
@@ -1307,7 +1334,7 @@ export async function* pickCommitStep<
13071334
}
13081335
},
13091336
onValidateValue: getValidateGitReferenceFn(state.repo, {
1310-
buttons: [ShowDetailsViewQuickInputButton, RevealInSideBarQuickInputButton],
1337+
revs: { allow: true, buttons: [ShowDetailsViewQuickInputButton, RevealInSideBarQuickInputButton] },
13111338
}),
13121339
});
13131340

src/env/node/git/sub-providers/commits.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ export class CommitsGitSubProvider implements GitCommitsSubProvider {
506506
const log: GitLog = {
507507
repoPath: repoPath,
508508
commits: commits,
509-
sha: rev,
509+
sha: isRevisionRange(rev) ? undefined : rev,
510510
count: commits.size,
511511
limit: limit,
512512
hasMore: overrideHasMore ?? count - countStashChildCommits > commits.size,

src/quickpicks/comparisonPicker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export async function showComparisonPicker(
4747

4848
if (head == null || force) {
4949
const pick = await showReferencePicker2(repoPath, title, placeholder, {
50-
allowRevisions: { ranges: true },
50+
allowedAdditionalInput: { range: true, rev: true },
5151
include: ReferencesQuickPickIncludes.BranchesAndTags | ReferencesQuickPickIncludes.HEAD,
5252
picked: head?.ref,
5353
sort: { branches: { current: true } },
@@ -94,7 +94,7 @@ export async function showComparisonPicker(
9494

9595
const pick = await showReferencePicker2(repoPath, title, placeholder, {
9696
allowBack: true,
97-
allowRevisions: true,
97+
allowedAdditionalInput: { rev: true },
9898
exclude: [head.ref],
9999
include: ReferencesQuickPickIncludes.BranchesAndTags | ReferencesQuickPickIncludes.HEAD,
100100
picked: base?.ref,

src/quickpicks/referencePicker.ts

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const enum ReferencesQuickPickIncludes {
3636
}
3737

3838
export interface ReferencesQuickPickOptions {
39-
allowRevisions?: boolean | { ranges?: boolean };
39+
allowedAdditionalInput?: { range?: boolean; rev?: boolean };
4040
autoPick?: boolean;
4141
picked?: string;
4242
exclude?: string[];
@@ -73,11 +73,17 @@ export async function showReferencePicker2(
7373
const quickpick = window.createQuickPick<ReferencesQuickPickItem | DirectiveQuickPickItem>();
7474
quickpick.ignoreFocusOut = options?.ignoreFocusOut ?? getQuickPickIgnoreFocusOut();
7575

76+
const { range: allowRanges, rev: allowRevs } = options?.allowedAdditionalInput ?? {};
77+
7678
quickpick.title = title;
7779
quickpick.placeholder =
78-
options?.allowRevisions != null && options.allowRevisions !== false
79-
? `${placeholder} (or enter a revision using #)`
80-
: placeholder;
80+
allowRanges && allowRevs
81+
? `${placeholder} (or enter a range, or a revision prefixed with #)`
82+
: allowRanges
83+
? `${placeholder} (or enter a range)`
84+
: allowRevs
85+
? `${placeholder} (or enter a revision prefixed with #)`
86+
: placeholder;
8187
quickpick.matchOnDescription = true;
8288
if (options?.allowBack) {
8389
quickpick.buttons = [QuickInputButtons.Back];
@@ -133,11 +139,8 @@ export async function showReferencePicker2(
133139
quickpick.show();
134140

135141
const getValidateGitReference = getValidateGitReferenceFn(Container.instance.git.getRepository(repoPath), {
136-
buttons: [RevealInSideBarQuickInputButton],
137-
ranges:
138-
options?.allowRevisions && typeof options.allowRevisions !== 'boolean'
139-
? options.allowRevisions.ranges
140-
: undefined,
142+
revs: { allow: allowRevs ?? false, buttons: [RevealInSideBarQuickInputButton] },
143+
ranges: { allow: allowRanges ?? false, validate: true },
141144
});
142145

143146
quickpick.items = await items;
@@ -159,6 +162,8 @@ export async function showReferencePicker2(
159162

160163
const [item] = quickpick.activeItems;
161164
if (isDirectiveQuickPickItem(item)) {
165+
if (item.directive === Directive.Noop) return;
166+
162167
resolve({ directive: item.directive });
163168
} else {
164169
resolve({ value: item?.item });
@@ -174,7 +179,7 @@ export async function showReferencePicker2(
174179
}
175180
}
176181

177-
if (options?.allowRevisions) {
182+
if (options?.allowedAdditionalInput) {
178183
if (!(await getValidateGitReference(quickpick, e))) {
179184
quickpick.items = await items;
180185
}

0 commit comments

Comments
 (0)