From 6f05dcb2e9c7a412310306aa463e1dbdb3afb9c8 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Thu, 19 Nov 2020 01:40:15 -0500 Subject: [PATCH] Adds range support to compare refs --- src/git/models/models.ts | 13 +++++++++++++ src/quickpicks/referencePicker.ts | 18 +++++++++++++----- src/views/searchAndCompareView.ts | 13 +++++++++++-- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/git/models/models.ts b/src/git/models/models.ts index c037b11..fd08bd3 100644 --- a/src/git/models/models.ts +++ b/src/git/models/models.ts @@ -5,6 +5,7 @@ import { GlyphChars } from '../../constants'; const emptyStr = ''; +const rangeRegex = /^(\S*?)(\.\.\.?)(\S*)\s*$/; const shaLikeRegex = /(^[0-9a-f]{40}([\^@~:]\S*)?$)|(^[0]{40}(:|-)$)/; const shaRegex = /(^[0-9a-f]{40}$)|(^[0]{40}(:|-)$)/; const shaParentRegex = /(^[0-9a-f]{40})\^[0-3]?$/; @@ -90,6 +91,18 @@ export namespace GitRevision { return ref.substr(0, len); } + + export function splitRange(ref: string): { ref1: string; ref2: string; notation: '..' | '...' } | undefined { + const match = rangeRegex.exec(ref); + if (match == null) return undefined; + + const [, ref1, notation, ref2] = match; + return { + ref1: ref1, + notation: notation as '..' | '...', + ref2: ref2, + }; + } } export interface GitBranchReference { diff --git a/src/quickpicks/referencePicker.ts b/src/quickpicks/referencePicker.ts index 06f4abf..f9a85a9 100644 --- a/src/quickpicks/referencePicker.ts +++ b/src/quickpicks/referencePicker.ts @@ -20,7 +20,7 @@ export enum ReferencesQuickPickIncludes { } export interface ReferencesQuickPickOptions { - allowEnteringRefs?: boolean; + allowEnteringRefs?: boolean | { ranges?: boolean }; autoPick?: boolean; picked?: string; filter?: { branches?(b: GitBranch): boolean; tags?(t: GitTag): boolean }; @@ -41,9 +41,10 @@ export namespace ReferencePicker { quickpick.ignoreFocusOut = getQuickPickIgnoreFocusOut(); quickpick.title = title; - quickpick.placeholder = options.allowEnteringRefs - ? `${placeHolder}${GlyphChars.Space.repeat(3)}(or enter a reference using #)` - : placeHolder; + quickpick.placeholder = + options.allowEnteringRefs != null + ? `${placeHolder}${GlyphChars.Space.repeat(3)}(or enter a reference using #)` + : placeHolder; quickpick.matchOnDescription = true; const disposables: Disposable[] = []; @@ -87,7 +88,13 @@ export namespace ReferencePicker { quickpick.show(); - const getValidateGitReference = getValidateGitReferenceFn((await Container.git.getRepository(repoPath))!); + const getValidateGitReference = getValidateGitReferenceFn((await Container.git.getRepository(repoPath))!, { + ranges: + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + options?.allowEnteringRefs && typeof options.allowEnteringRefs !== 'boolean' + ? options.allowEnteringRefs.ranges + : undefined, + }); quickpick.items = await items; @@ -105,6 +112,7 @@ export namespace ReferencePicker { resolve(quickpick.activeItems[0]); }), quickpick.onDidChangeValue(async e => { + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions if (options.allowEnteringRefs) { if (!(await getValidateGitReference(quickpick, e))) { quickpick.items = await items; diff --git a/src/views/searchAndCompareView.ts b/src/views/searchAndCompareView.ts index 842fda3..c3be656 100644 --- a/src/views/searchAndCompareView.ts +++ b/src/views/searchAndCompareView.ts @@ -189,9 +189,10 @@ export class SearchAndCompareViewNode extends ViewNode { this.removeComparePicker(true); let prompt = options?.prompt ?? false; + let ref2; if (ref == null) { const pick = await ReferencePicker.show(repoPath, 'Compare', 'Choose a reference to compare', { - allowEnteringRefs: true, + allowEnteringRefs: { ranges: true }, // checkmarks: false, include: ReferencesQuickPickIncludes.BranchesAndTags | @@ -210,6 +211,14 @@ export class SearchAndCompareViewNode extends ViewNode { ref = pick.ref; + if (GitRevision.isRange(ref)) { + const range = GitRevision.splitRange(ref); + if (range != null) { + ref = range.ref1 || 'HEAD'; + ref2 = range.ref2 || 'HEAD'; + } + } + prompt = true; } @@ -226,7 +235,7 @@ export class SearchAndCompareViewNode extends ViewNode { await this.view.reveal(this.comparePicker, { focus: false, select: true }); if (prompt) { - await this.compareWithSelected(); + await this.compareWithSelected(repoPath, ref2); } }