diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d111de..9da0ecd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ ## Release Notes ### 2.13.0 -- Adds experimental support for `Open in GitHub` to the relevant quick picks -- need to enable it via `"gitlens.experimental.openInHostingProvider": true` +- Adds experimental support for `Open in GitHub` to the relevant quick picks -- need to enable it via `"gitlens.experimental.openInRemote": true` - Adds an update notification for feature releases - Adds `Show Branch History` command (`gitlens.showQuickBranchHistory`) to show the history of the selected branch - Adds `Show Last Opened Quick Pick` command (`gitlens.showLastQuickPick`) to re-open the previously opened quick pick - helps to get back to previous context diff --git a/package.json b/package.json index cc2819b..5c8a700 100644 --- a/package.json +++ b/package.json @@ -351,10 +351,10 @@ "default": false, "description": "Specifies whether or not to toggle whitespace off then showing blame annotations (*may* be required by certain fonts/themes)" }, - "gitlens.experimental.openInHostingProvider": { + "gitlens.experimental.openInRemote": { "type": "boolean", "default": false, - "description": "(experimental) Specifies whether or not to show Open X in Hosting Provider commands in relevant quick picks" + "description": "(experimental) Specifies whether or not to show Open X in Remote commands in relevant quick picks" } } }, @@ -479,13 +479,13 @@ "category": "GitLens" }, { - "command": "gitlens.openCommitInHostingProvider", - "title": "Open Line Commit in Hosting Provider", + "command": "gitlens.openCommitInRemote", + "title": "Open Line Commit in Remote", "category": "GitLens" }, { - "command": "gitlens.openFileInHostingProvider", - "title": "Open File in Hosting Provider", + "command": "gitlens.openFileInRemote", + "title": "Open File in Remote", "category": "GitLens" } ], @@ -584,19 +584,24 @@ "when": "gitlens:enabled" }, { - "command": "gitlens.openCommitInHostingProvider", - "when": "editorTextFocus && gitlens:enabled && gitlens:isBlameable && config.gitlens.experimental.openInHostingProvider" + "command": "gitlens.openCommitInRemote", + "when": "editorTextFocus && gitlens:enabled && gitlens:isBlameable && config.gitlens.experimental.openInRemote" }, { - "command": "gitlens.openFileInHostingProvider", - "when": "editorTextFocus && gitlens:enabled && config.gitlens.experimental.openInHostingProvider" + "command": "gitlens.openFileInRemote", + "when": "editorTextFocus && gitlens:enabled && config.gitlens.experimental.openInRemote" } ], "explorer/context": [ { "command": "gitlens.showQuickFileHistory", "when": "gitlens:enabled", - "group": "gitlens" + "group": "gitlens@1" + }, + { + "command": "gitlens.openFileInRemote", + "when": "gitlens:enabled && config.gitlens.experimental.openInRemote", + "group": "gitlens@2" }, { "command": "gitlens.diffWithPrevious", diff --git a/src/commands.ts b/src/commands.ts index 27b292e..84e2d42 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -16,9 +16,9 @@ export * from './commands/diffWithNext'; export * from './commands/diffWithPrevious'; export * from './commands/diffWithWorking'; export * from './commands/openChangedFiles'; -export * from './commands/openCommitInHostingProvider'; -export * from './commands/openFileInHostingProvider'; -export * from './commands/openInHostingProvider'; +export * from './commands/openCommitInRemote'; +export * from './commands/openFileInRemote'; +export * from './commands/openInRemote'; export * from './commands/showBlame'; export * from './commands/showBlameHistory'; export * from './commands/showFileHistory'; diff --git a/src/commands/commands.ts b/src/commands/commands.ts index 8985f38..cb92e2f 100644 --- a/src/commands/commands.ts +++ b/src/commands/commands.ts @@ -4,7 +4,7 @@ import { BuiltInCommands } from '../constants'; export type Commands = 'gitlens.closeUnchangedFiles' | 'gitlens.copyMessageToClipboard' | 'gitlens.copyShaToClipboard' | 'gitlens.diffDirectory' | 'gitlens.diffWithBranch' | 'gitlens.diffWithNext' | 'gitlens.diffWithPrevious' | 'gitlens.diffLineWithPrevious' | 'gitlens.diffWithWorking' | 'gitlens.diffLineWithWorking' | - 'gitlens.openChangedFiles' | 'gitlens.openCommitInHostingProvider' | 'gitlens.openFileInHostingProvider' | 'gitlens.openInHostingProvider' | + 'gitlens.openChangedFiles' | 'gitlens.openCommitInRemote' | 'gitlens.openFileInRemote' | 'gitlens.openInRemote' | 'gitlens.showBlame' | 'gitlens.showBlameHistory' | 'gitlens.showFileHistory' | 'gitlens.showLastQuickPick' | 'gitlens.showQuickBranchHistory' | 'gitlens.showQuickCommitDetails' | 'gitlens.showQuickCommitFileDetails' | @@ -23,9 +23,9 @@ export const Commands = { DiffWithWorking: 'gitlens.diffWithWorking' as Commands, DiffLineWithWorking: 'gitlens.diffLineWithWorking' as Commands, OpenChangedFiles: 'gitlens.openChangedFiles' as Commands, - OpenCommitInHostingProvider: 'gitlens.openCommitInHostingProvider' as Commands, - OpenFileInHostingProvider: 'gitlens.openFileInHostingProvider' as Commands, - OpenInHostingProvider: 'gitlens.openInHostingProvider' as Commands, + OpenCommitInRemote: 'gitlens.openCommitInRemote' as Commands, + OpenFileInRemote: 'gitlens.openFileInRemote' as Commands, + OpenInRemote: 'gitlens.openInRemote' as Commands, ShowBlame: 'gitlens.showBlame' as Commands, ShowBlameHistory: 'gitlens.showBlameHistory' as Commands, ShowFileHistory: 'gitlens.showFileHistory' as Commands, diff --git a/src/commands/openCommitInHostingProvider.ts b/src/commands/openCommitInRemote.ts similarity index 77% rename from src/commands/openCommitInHostingProvider.ts rename to src/commands/openCommitInRemote.ts index 714e4cd..e42f87f 100644 --- a/src/commands/openCommitInHostingProvider.ts +++ b/src/commands/openCommitInRemote.ts @@ -5,10 +5,10 @@ import { ActiveEditorCommand, Commands } from './commands'; import { GitCommit, GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; -export class OpenCommitInHostingProviderCommand extends ActiveEditorCommand { +export class OpenCommitInRemoteCommand extends ActiveEditorCommand { constructor(private git: GitService, private repoPath: string) { - super(Commands.OpenCommitInHostingProvider); + super(Commands.OpenCommitInRemote); } async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) { @@ -27,7 +27,7 @@ export class OpenCommitInHostingProviderCommand extends ActiveEditorCommand { if (blameline < 0) return undefined; const blame = await this.git.getBlameForLine(gitUri, blameline); - if (!blame) return window.showWarningMessage(`Unable to open commit in hosting provider. File is probably not under source control`); + if (!blame) return window.showWarningMessage(`Unable to open commit in remote provider. File is probably not under source control`); let commit = blame.commit; // If the line is uncommitted, find the previous commit @@ -36,11 +36,11 @@ export class OpenCommitInHostingProviderCommand extends ActiveEditorCommand { } const remotes = Arrays.uniqueBy(await this.git.getRemotes(this.repoPath), _ => _.url, _ => !!_.provider); - return commands.executeCommand(Commands.OpenInHostingProvider, uri, remotes, 'commit', [commit.sha]); + return commands.executeCommand(Commands.OpenInRemote, uri, remotes, 'commit', [commit.sha]); } catch (ex) { - Logger.error('[GitLens.OpenCommitInHostingProviderCommand]', ex); - return window.showErrorMessage(`Unable to open commit in hosting provider. See output channel for more details`); + Logger.error('[GitLens.OpenCommitInRemoteCommand]', ex); + return window.showErrorMessage(`Unable to open commit in remote provider. See output channel for more details`); } } } \ No newline at end of file diff --git a/src/commands/openFileInHostingProvider.ts b/src/commands/openFileInRemote.ts similarity index 68% rename from src/commands/openFileInHostingProvider.ts rename to src/commands/openFileInRemote.ts index 793f24c..fa4f160 100644 --- a/src/commands/openFileInHostingProvider.ts +++ b/src/commands/openFileInRemote.ts @@ -5,10 +5,10 @@ import { ActiveEditorCommand, Commands } from './commands'; import { GitService, GitUri } from '../gitService'; import { Logger } from '../logger'; -export class OpenFileInHostingProviderCommand extends ActiveEditorCommand { +export class OpenFileInRemoteCommand extends ActiveEditorCommand { constructor(private git: GitService, private repoPath: string) { - super(Commands.OpenFileInHostingProvider); + super(Commands.OpenFileInRemote); } async execute(editor: TextEditor, edit: TextEditorEdit, uri?: Uri) { @@ -21,11 +21,11 @@ export class OpenFileInHostingProviderCommand extends ActiveEditorCommand { try { const remotes = Arrays.uniqueBy(await this.git.getRemotes(this.repoPath), _ => _.url, _ => !!_.provider); - return commands.executeCommand(Commands.OpenInHostingProvider, uri, remotes, 'file', [gitUri.getRelativePath(), gitUri.sha]); + return commands.executeCommand(Commands.OpenInRemote, uri, remotes, 'file', [gitUri.getRelativePath(), gitUri.sha]); } catch (ex) { - Logger.error('[GitLens.OpenFileInHostingProviderCommand]', ex); - return window.showErrorMessage(`Unable to open file in hosting provider. See output channel for more details`); + Logger.error('[GitLens.OpenFileInRemoteCommand]', ex); + return window.showErrorMessage(`Unable to open file in remote provider. See output channel for more details`); } } } \ No newline at end of file diff --git a/src/commands/openInHostingProvider.ts b/src/commands/openInRemote.ts similarity index 76% rename from src/commands/openInHostingProvider.ts rename to src/commands/openInRemote.ts index 068787c..d68543f 100644 --- a/src/commands/openInHostingProvider.ts +++ b/src/commands/openInRemote.ts @@ -1,17 +1,17 @@ 'use strict'; import { TextEditor, Uri, window } from 'vscode'; import { ActiveEditorCommand, Commands } from './commands'; -import { GitRemote, HostingProviderOpenType } from '../gitService'; +import { GitRemote, RemoteProviderOpenType } from '../gitService'; import { Logger } from '../logger'; import { CommandQuickPickItem, OpenRemoteCommandQuickPickItem, RemotesQuickPick } from '../quickPicks'; -export class OpenInHostingProviderCommand extends ActiveEditorCommand { +export class OpenInRemoteCommand extends ActiveEditorCommand { constructor() { - super(Commands.OpenInHostingProvider); + super(Commands.OpenInRemote); } - async execute(editor: TextEditor, uri?: Uri, remotes?: GitRemote[], type?: HostingProviderOpenType, args?: string[], name?: string, goBackCommand?: CommandQuickPickItem) { + async execute(editor: TextEditor, uri?: Uri, remotes?: GitRemote[], type?: RemoteProviderOpenType, args?: string[], name?: string, goBackCommand?: CommandQuickPickItem) { if (!(uri instanceof Uri)) { uri = editor && editor.document && editor.document.uri; } @@ -46,8 +46,8 @@ export class OpenInHostingProviderCommand extends ActiveEditorCommand { } catch (ex) { - Logger.error('[GitLens.OpenInHostingProviderCommand]', ex); - return window.showErrorMessage(`Unable to open in hosting provider. See output channel for more details`); + Logger.error('[GitLens.OpenInRemoteCommand]', ex); + return window.showErrorMessage(`Unable to open in remote provider. See output channel for more details`); } } } \ No newline at end of file diff --git a/src/configuration.ts b/src/configuration.ts index 91fa767..f289840 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -124,7 +124,7 @@ export interface IAdvancedConfig { } export interface IExperimentalConfig { - openInHostingProvider: boolean; + openInRemote: boolean; } export interface IConfig { diff --git a/src/extension.ts b/src/extension.ts index dd1f887..6006918 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -6,7 +6,7 @@ import { BlameAnnotationController } from './blameAnnotationController'; import { configureCssCharacters } from './blameAnnotationFormatter'; import { CommandContext, setCommandContext } from './commands'; import { CloseUnchangedFilesCommand, OpenChangedFilesCommand } from './commands'; -import { OpenCommitInHostingProviderCommand, OpenFileInHostingProviderCommand, OpenInHostingProviderCommand } from './commands'; +import { OpenCommitInRemoteCommand, OpenFileInRemoteCommand, OpenInRemoteCommand } from './commands'; import { CopyMessageToClipboardCommand, CopyShaToClipboardCommand } from './commands'; import { DiffDirectoryCommand, DiffLineWithPreviousCommand, DiffLineWithWorkingCommand, DiffWithBranchCommand, DiffWithNextCommand, DiffWithPreviousCommand, DiffWithWorkingCommand} from './commands'; import { ShowBlameCommand, ToggleBlameCommand } from './commands'; @@ -102,9 +102,9 @@ export async function activate(context: ExtensionContext) { context.subscriptions.push(new DiffWithNextCommand(git)); context.subscriptions.push(new DiffWithPreviousCommand(git)); context.subscriptions.push(new DiffWithWorkingCommand(git)); - context.subscriptions.push(new OpenCommitInHostingProviderCommand(git, repoPath)); - context.subscriptions.push(new OpenFileInHostingProviderCommand(git, repoPath)); - context.subscriptions.push(new OpenInHostingProviderCommand()); + context.subscriptions.push(new OpenCommitInRemoteCommand(git, repoPath)); + context.subscriptions.push(new OpenFileInRemoteCommand(git, repoPath)); + context.subscriptions.push(new OpenInRemoteCommand()); context.subscriptions.push(new ShowBlameCommand(annotationController)); context.subscriptions.push(new ToggleBlameCommand(annotationController)); context.subscriptions.push(new ShowBlameHistoryCommand(git)); diff --git a/src/git/git.ts b/src/git/git.ts index d359b95..5a02760 100644 --- a/src/git/git.ts +++ b/src/git/git.ts @@ -10,7 +10,7 @@ export * from './models/models'; export * from './parsers/blameParser'; export * from './parsers/logParser'; export * from './parsers/statusParser'; -export * from './hosting/hostingProvider'; +export * from './remotes/provider'; let git: IGit; diff --git a/src/git/models/remote.ts b/src/git/models/remote.ts index 7650538..dfd2bea 100644 --- a/src/git/models/remote.ts +++ b/src/git/models/remote.ts @@ -1,5 +1,5 @@ 'use strict'; -import { HostingProvider, HostingProviderFactory } from '../hosting/factory'; +import { RemoteProvider, RemoteProviderFactory } from '../remotes/factory'; export type GitRemoteType = 'fetch' | 'push'; @@ -9,7 +9,7 @@ export class GitRemote { url: string; type: GitRemoteType; - provider?: HostingProvider; + provider?: RemoteProvider; constructor(remote: string) { remote = remote.trim(); @@ -22,6 +22,6 @@ export class GitRemote { this.type = typeInfo.substring(1, typeInfo.length - 1) as GitRemoteType; - this.provider = HostingProviderFactory.getHostingProvider(this.url); + this.provider = RemoteProviderFactory.getRemoteProvider(this.url); } } \ No newline at end of file diff --git a/src/git/hosting/factory.ts b/src/git/remotes/factory.ts similarity index 58% rename from src/git/hosting/factory.ts rename to src/git/remotes/factory.ts index e4910cb..ff0ff2f 100644 --- a/src/git/hosting/factory.ts +++ b/src/git/remotes/factory.ts @@ -1,28 +1,28 @@ 'use strict'; -import { HostingProvider } from './hostingProvider'; +import { RemoteProvider } from './provider'; import { GitHubService } from './github'; import { Logger } from '../../logger'; -export { HostingProvider }; +export { RemoteProvider }; -const serviceMap = new Map HostingProvider>([ +const providerMap = new Map RemoteProvider>([ ['github.com', (domain: string, path: string) => new GitHubService(domain, path)] ]); const UrlRegex = /^(?:git:\/\/(.*?)\/|https:\/\/(.*?)\/|http:\/\/(.*?)\/|git@(.*):\/\/|ssh:\/\/git@(.*?)\/)(.*)$/; -export class HostingProviderFactory { +export class RemoteProviderFactory { - static getHostingProvider(url: string): HostingProvider { + static getRemoteProvider(url: string): RemoteProvider { try { const match = UrlRegex.exec(url); const domain = match[1] || match[2] || match[3] || match[4] || match[5]; const path = match[6].replace(/\.git/, ''); - const serviceCreator = serviceMap.get(domain); - if (!serviceCreator) return undefined; + const creator = providerMap.get(domain); + if (!creator) return undefined; - return serviceCreator(domain, path); + return creator(domain, path); } catch (ex) { Logger.error(ex); diff --git a/src/git/hosting/github.ts b/src/git/remotes/github.ts similarity index 84% rename from src/git/hosting/github.ts rename to src/git/remotes/github.ts index ac345aa..07a07ee 100644 --- a/src/git/hosting/github.ts +++ b/src/git/remotes/github.ts @@ -1,7 +1,7 @@ 'use strict'; -import { HostingProvider } from './hostingProvider'; +import { RemoteProvider } from './provider'; -export class GitHubService extends HostingProvider { +export class GitHubService extends RemoteProvider { constructor(public domain: string, public path: string) { super(domain, path); diff --git a/src/git/hosting/hostingProvider.ts b/src/git/remotes/provider.ts similarity index 83% rename from src/git/hosting/hostingProvider.ts rename to src/git/remotes/provider.ts index d281e39..a093b42 100644 --- a/src/git/hosting/hostingProvider.ts +++ b/src/git/remotes/provider.ts @@ -2,9 +2,9 @@ import { commands, Uri } from 'vscode'; import { BuiltInCommands } from '../../constants'; -export type HostingProviderOpenType = 'branch' | 'commit' | 'file'; +export type RemoteProviderOpenType = 'branch' | 'commit' | 'file'; -export abstract class HostingProvider { +export abstract class RemoteProvider { constructor(public domain: string, public path: string) { } @@ -25,8 +25,8 @@ export abstract class HostingProvider { open(type: 'branch', branch: string): Promise<{}>; open(type: 'commit', sha: string): Promise<{}>; open(type: 'file', fileName: string, sha?: string): Promise<{}>; - open(type: HostingProviderOpenType, ...args: string[]): Promise<{}>; - open(type: HostingProviderOpenType, branchOrShaOrFileName: string, sha?: string): Promise<{}> { + open(type: RemoteProviderOpenType, ...args: string[]): Promise<{}>; + open(type: RemoteProviderOpenType, branchOrShaOrFileName: string, sha?: string): Promise<{}> { switch (type) { case 'branch': return this.openBranch(branchOrShaOrFileName); case 'commit': return this.openCommit(branchOrShaOrFileName); diff --git a/src/gitService.ts b/src/gitService.ts index 2f3fd3f..6b0fd59 100644 --- a/src/gitService.ts +++ b/src/gitService.ts @@ -587,7 +587,7 @@ export class GitService extends Disposable { } async getRemotes(repoPath: string): Promise { - if (!this.config.experimental || !this.config.experimental.openInHostingProvider) return Promise.resolve([]); + if (!this.config.experimental || !this.config.experimental.openInRemote) return Promise.resolve([]); Logger.log(`getRemotes('${repoPath}')`); diff --git a/src/quickPicks/remotes.ts b/src/quickPicks/remotes.ts index 7ce6b87..97a7640 100644 --- a/src/quickPicks/remotes.ts +++ b/src/quickPicks/remotes.ts @@ -1,17 +1,17 @@ 'use strict'; import { QuickPickOptions, window } from 'vscode'; import { Commands } from '../commands'; -import { GitRemote, HostingProviderOpenType } from '../gitService'; +import { GitRemote, RemoteProviderOpenType } from '../gitService'; import { CommandQuickPickItem, getQuickPickIgnoreFocusOut } from './quickPicks'; import * as path from 'path'; export class OpenRemoteCommandQuickPickItem extends CommandQuickPickItem { - private type: HostingProviderOpenType; + private type: RemoteProviderOpenType; private remote: GitRemote; - constructor(remote: GitRemote, type: HostingProviderOpenType, ...args: string[]); - constructor(remote: GitRemote, type: HostingProviderOpenType, branchOrShaOrFileName: string, fileSha?: string, name?: string) { + constructor(remote: GitRemote, type: RemoteProviderOpenType, ...args: string[]); + constructor(remote: GitRemote, type: RemoteProviderOpenType, branchOrShaOrFileName: string, fileSha?: string, name?: string) { if (!name) { name = `${type[0].toUpperCase()}${type.substring(1)}`; } @@ -36,7 +36,7 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { constructor(remotes: GitRemote[], type: 'branch', branch: string, goBackCommand?: CommandQuickPickItem); constructor(remotes: GitRemote[], type: 'commit', sha: string, goBackCommand?: CommandQuickPickItem); constructor(remotes: GitRemote[], type: 'file', fileName: string, sha?: string, name?: string, goBackCommand?: CommandQuickPickItem); - constructor(remotes: GitRemote[], type: HostingProviderOpenType, branchOrShaOrFileName: string, shaOrGoBackCommand?: string | CommandQuickPickItem, name?: string, goBackCommand?: CommandQuickPickItem) { + constructor(remotes: GitRemote[], type: RemoteProviderOpenType, branchOrShaOrFileName: string, shaOrGoBackCommand?: string | CommandQuickPickItem, name?: string, goBackCommand?: CommandQuickPickItem) { let fileSha: string; if (typeof shaOrGoBackCommand === 'string') { fileSha = shaOrGoBackCommand; @@ -76,25 +76,25 @@ export class OpenRemotesCommandQuickPickItem extends CommandQuickPickItem { super({ label: `$(link-external) Open ${name} in ${remote.provider.name}`, description: `\u00a0 \u2014 \u00a0\u00a0 $(repo) ${remote.provider.path} \u00a0\u2022\u00a0 ${description}` - }, Commands.OpenInHostingProvider, [undefined, remotes, type, [branchOrShaOrFileName, fileSha], name, goBackCommand]); + }, Commands.OpenInRemote, [undefined, remotes, type, [branchOrShaOrFileName, fileSha], name, goBackCommand]); return; } const provider = remotes.every(_ => _.provider.name === remote.provider.name) ? remote.provider.name - : 'Hosting Provider'; + : 'Remote'; super({ label: `$(link-external) Open ${name} in ${provider}\u2026`, description: `\u00a0 \u2014 \u00a0\u00a0 ${description}` - }, Commands.OpenInHostingProvider, [undefined, remotes, type, [branchOrShaOrFileName, fileSha], name, goBackCommand]); + }, Commands.OpenInRemote, [undefined, remotes, type, [branchOrShaOrFileName, fileSha], name, goBackCommand]); } } export class RemotesQuickPick { - static async show(remotes: GitRemote[], placeHolder: string, type: HostingProviderOpenType, args: string[], name: string, goBackCommand?: CommandQuickPickItem): Promise { + static async show(remotes: GitRemote[], placeHolder: string, type: RemoteProviderOpenType, args: string[], name: string, goBackCommand?: CommandQuickPickItem): Promise { const items = remotes.map(_ => new OpenRemoteCommandQuickPickItem(_, type, ...args, name)) as (OpenRemoteCommandQuickPickItem | CommandQuickPickItem)[];