diff --git a/extensions/git-base/package.json b/extensions/git-base/package.json index f4ac7fa32f4..708f3ae5df3 100644 --- a/extensions/git-base/package.json +++ b/extensions/git-base/package.json @@ -99,9 +99,6 @@ } ] }, - "dependencies": { - "vscode-nls": "^5.2.0" - }, "devDependencies": { "@types/node": "16.x" }, diff --git a/extensions/git-base/src/remoteSource.ts b/extensions/git-base/src/remoteSource.ts index 134af197316..38729dc6194 100644 --- a/extensions/git-base/src/remoteSource.ts +++ b/extensions/git-base/src/remoteSource.ts @@ -3,14 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { QuickPickItem, window, QuickPick, QuickPickItemKind } from 'vscode'; -import * as nls from 'vscode-nls'; +import { QuickPickItem, window, QuickPick, QuickPickItemKind, l10n } from 'vscode'; import { RemoteSourceProvider, RemoteSource, PickRemoteSourceOptions, PickRemoteSourceResult } from './api/git-base'; import { Model } from './model'; import { throttle, debounce } from './decorators'; -const localize = nls.loadMessageBundle(); - async function getQuickPickResult(quickpick: QuickPick): Promise { const result = await new Promise(c => { quickpick.onDidAccept(() => c(quickpick.selectedItems[0])); @@ -33,10 +30,10 @@ class RemoteSourceProviderQuickPick { this.quickpick = window.createQuickPick(); this.quickpick.ignoreFocusOut = true; if (this.provider.supportsQuery) { - this.quickpick.placeholder = this.provider.placeholder ?? localize('type to search', "Repository name (type to search)"); + this.quickpick.placeholder = this.provider.placeholder ?? l10n.t('Repository name (type to search)'); this.quickpick.onDidChangeValue(this.onDidChangeValue, this); } else { - this.quickpick.placeholder = this.provider.placeholder ?? localize('type to filter', "Repository name"); + this.quickpick.placeholder = this.provider.placeholder ?? l10n.t('Repository name'); } } } @@ -57,7 +54,7 @@ class RemoteSourceProviderQuickPick { if (remoteSources.length === 0) { this.quickpick!.items = [{ - label: localize('none found', "No remote repositories found."), + label: l10n.t('No remote repositories found.'), alwaysShow: true }]; } else { @@ -70,7 +67,7 @@ class RemoteSourceProviderQuickPick { })); } } catch (err) { - this.quickpick!.items = [{ label: localize('error', "{0} Error: {1}", '$(error)', err.message), alwaysShow: true }]; + this.quickpick!.items = [{ label: l10n.t('{0} Error: {1}', '$(error)', err.message), alwaysShow: true }]; console.error(err); } finally { this.quickpick!.busy = false; @@ -118,19 +115,19 @@ export async function pickRemoteSource(model: Model, options: PickRemoteSourceOp } const items = [ - { kind: QuickPickItemKind.Separator, label: localize('remote sources', 'remote sources') }, + { kind: QuickPickItemKind.Separator, label: l10n.t('remote sources') }, ...remoteProviders, - { kind: QuickPickItemKind.Separator, label: localize('recently opened', 'recently opened') }, + { kind: QuickPickItemKind.Separator, label: l10n.t('recently opened') }, ...recentSources.sort((a, b) => b.timestamp - a.timestamp) ]; quickpick.placeholder = options.placeholder ?? (remoteProviders.length === 0 - ? localize('provide url', "Provide repository URL") - : localize('provide url or pick', "Provide repository URL or pick a repository source.")); + ? l10n.t('Provide repository URL') + : l10n.t('Provide repository URL or pick a repository source.')); const updatePicks = (value?: string) => { if (value) { - const label = (typeof options.urlLabel === 'string' ? options.urlLabel : options.urlLabel?.(value)) ?? localize('url', "URL"); + const label = (typeof options.urlLabel === 'string' ? options.urlLabel : options.urlLabel?.(value)) ?? l10n.t('URL'); quickpick.items = [{ label: label, description: value, @@ -170,7 +167,7 @@ async function pickProviderSource(provider: RemoteSourceProvider, options: PickR if (typeof remote.url === 'string') { url = remote.url; } else if (remote.url.length > 0) { - url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: localize('pick url', "Choose a URL to clone from.") }); + url = await window.showQuickPick(remote.url, { ignoreFocusOut: true, placeHolder: l10n.t('Choose a URL to clone from.') }); } } @@ -189,7 +186,7 @@ async function pickProviderSource(provider: RemoteSourceProvider, options: PickR } const branch = await window.showQuickPick(branches, { - placeHolder: localize('branch name', "Branch name") + placeHolder: l10n.t('Branch name') }); if (!branch) { diff --git a/extensions/git-base/yarn.lock b/extensions/git-base/yarn.lock index efe3c44327d..cad6a8475b8 100644 --- a/extensions/git-base/yarn.lock +++ b/extensions/git-base/yarn.lock @@ -6,8 +6,3 @@ version "16.11.21" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.21.tgz#474d7589a30afcf5291f59bd49cca9ad171ffde4" integrity sha512-Pf8M1XD9i1ksZEcCP8vuSNwooJ/bZapNmIzpmsMaL+jMI+8mEYU3PKvs+xDNuQcJWF/x24WzY4qxLtB0zNow9A== - -vscode-nls@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f" - integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng== diff --git a/extensions/git/package.json b/extensions/git/package.json index 442fce28eca..72bbec88e42 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -2737,7 +2737,6 @@ "file-type": "16.5.4", "jschardet": "3.0.0", "picomatch": "2.3.1", - "vscode-nls": "^5.2.0", "vscode-uri": "^2.0.0", "which": "^1.3.0" }, diff --git a/extensions/git/src/actionButton.ts b/extensions/git/src/actionButton.ts index c0bd4624ee3..ce553a14721 100644 --- a/extensions/git/src/actionButton.ts +++ b/extensions/git/src/actionButton.ts @@ -3,15 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -import { Command, Disposable, Event, EventEmitter, SourceControlActionButton, Uri, workspace } from 'vscode'; +import { Command, Disposable, Event, EventEmitter, SourceControlActionButton, Uri, workspace, l10n } from 'vscode'; import { Branch, Status } from './api/git'; import { CommitCommandsCenter } from './postCommitCommands'; import { Repository, Operation } from './repository'; import { dispose } from './util'; -const localize = nls.loadMessageBundle(); - interface ActionButtonState { readonly HEAD: Branch | undefined; readonly isCommitInProgress: boolean; @@ -106,8 +103,8 @@ export class ActionButtonCommand { if (this.state.isRebaseInProgress) { return { command: 'git.commit', - title: localize('scm button continue title', "{0} Continue", '$(check)'), - tooltip: this.state.isCommitInProgress ? localize('scm button continuing tooltip', "Continuing Rebase...") : localize('scm button continue tooltip', "Continue Rebase"), + title: l10n.t('{0} Continue', '$(check)'), + tooltip: this.state.isCommitInProgress ? l10n.t('Continuing Rebase...') : l10n.t('Continue Rebase'), arguments: [this.repository.sourceControl, ''] }; } @@ -143,10 +140,10 @@ export class ActionButtonCommand { return { command: { command: 'git.publish', - title: localize({ key: 'scm publish branch action button title', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }, "{0} Publish Branch", '$(cloud-upload)'), + title: l10n.t({ message: '{0} Publish Branch', args: ['$(cloud-upload)'], comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }), tooltip: this.state.isSyncInProgress ? - localize({ key: 'scm button publish branch running', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }, "Publishing Branch...") : - localize({ key: 'scm button publish branch', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }, "Publish Branch"), + l10n.t({ message: 'Publishing Branch...', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }) : + l10n.t({ message: 'Publish Branch', comment: ['{Locked="Branch"}', 'Do not translate "Branch" as it is a git term'] }), arguments: [this.repository.sourceControl], }, enabled: !this.state.isSyncInProgress @@ -170,11 +167,11 @@ export class ActionButtonCommand { command: 'git.sync', title: `${icon}${behind}${ahead}`, tooltip: this.state.isSyncInProgress ? - localize('syncing changes', "Synchronizing Changes...") + l10n.t('Synchronizing Changes...') : this.repository.syncTooltip, arguments: [this.repository.sourceControl], }, - description: localize('scm button sync description', "{0} Sync Changes{1}{2}", icon, behind, ahead), + description: l10n.t('{0} Sync Changes{1}{2}', icon, behind, ahead), enabled: !this.state.isSyncInProgress }; } diff --git a/extensions/git/src/askpass-main.ts b/extensions/git/src/askpass-main.ts index 405122a4a0b..fe6bcdcbeb7 100644 --- a/extensions/git/src/askpass-main.ts +++ b/extensions/git/src/askpass-main.ts @@ -4,13 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import * as fs from 'fs'; -import * as nls from 'vscode-nls'; +import { l10n } from 'vscode'; import { IPCClient } from './ipc/ipcClient'; -const localize = nls.loadMessageBundle(); - function fatal(err: any): void { - console.error(localize('missOrInvalid', "Missing or invalid credentials.")); + console.error(l10n.t('Missing or invalid credentials.')); console.error(err); process.exit(1); } diff --git a/extensions/git/src/askpass.ts b/extensions/git/src/askpass.ts index b92b1daa009..ffd299bfdf3 100644 --- a/extensions/git/src/askpass.ts +++ b/extensions/git/src/askpass.ts @@ -3,16 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -import { window, InputBoxOptions, Uri, Disposable, workspace, QuickPickOptions } from 'vscode'; +import { window, InputBoxOptions, Uri, Disposable, workspace, QuickPickOptions, l10n } from 'vscode'; import { IDisposable, EmptyDisposable, toDisposable } from './util'; import * as path from 'path'; import { IIPCHandler, IIPCServer } from './ipc/ipcServer'; import { CredentialsProvider, Credentials } from './api/git'; import { ITerminalEnvironmentProvider } from './terminal'; -const localize = nls.loadMessageBundle(); - export class Askpass implements IIPCHandler, ITerminalEnvironmentProvider { private env: { [key: string]: string }; @@ -102,7 +99,7 @@ export class Askpass implements IIPCHandler, ITerminalEnvironmentProvider { if (/passphrase/i.test(request)) { const options: InputBoxOptions = { password: true, - placeHolder: localize('ssh passphrase', "Passphrase"), + placeHolder: l10n.t('Passphrase'), prompt: `SSH Key: ${file}`, ignoreFocusOut: true }; @@ -114,13 +111,10 @@ export class Askpass implements IIPCHandler, ITerminalEnvironmentProvider { const options: QuickPickOptions = { canPickMany: false, ignoreFocusOut: true, - placeHolder: localize('ssh authenticity prompt', "Are you sure you want to continue connecting?"), - title: localize('ssh authenticity title', "\"{0}\" has fingerprint \"{1}\"", host, fingerprint) + placeHolder: l10n.t('Are you sure you want to continue connecting?'), + title: l10n.t('"{0}" has fingerprint "{1}"', host ?? '', fingerprint ?? '') }; - const items = [ - localize('ssh authenticity prompt yes', "yes"), - localize('ssh authenticity prompt no', "no") - ]; + const items = [l10n.t('yes'), l10n.t('no')]; return await window.showQuickPick(items, options) ?? ''; } diff --git a/extensions/git/src/autofetch.ts b/extensions/git/src/autofetch.ts index 75180de6303..6c1271f24b9 100644 --- a/extensions/git/src/autofetch.ts +++ b/extensions/git/src/autofetch.ts @@ -3,14 +3,11 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget, Uri, ConfigurationChangeEvent } from 'vscode'; +import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget, Uri, ConfigurationChangeEvent, l10n } from 'vscode'; import { Repository, Operation } from './repository'; import { eventToPromise, filterEvent, onceEvent } from './util'; -import * as nls from 'vscode-nls'; import { GitErrorCodes } from './api/git'; -const localize = nls.loadMessageBundle(); - function isRemoteOperation(operation: Operation): boolean { return operation === Operation.Pull || operation === Operation.Push || operation === Operation.Sync || operation === Operation.Fetch; } @@ -51,10 +48,10 @@ export class AutoFetcher { return; } - const yes: MessageItem = { title: localize('yes', "Yes") }; - const no: MessageItem = { isCloseAffordance: true, title: localize('no', "No") }; - const askLater: MessageItem = { title: localize('not now', "Ask Me Later") }; - const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like Code to [periodically run 'git fetch']({0})?", 'https://go.microsoft.com/fwlink/?linkid=865294'), yes, no, askLater); + const yes: MessageItem = { title: l10n.t('Yes') }; + const no: MessageItem = { isCloseAffordance: true, title: l10n.t('No') }; + const askLater: MessageItem = { title: l10n.t('Ask Me Later') }; + const result = await window.showInformationMessage(l10n.t('Would you like Code to [periodically run "git fetch"]({0})?', 'https://go.microsoft.com/fwlink/?linkid=865294'), yes, no, askLater); if (result === askLater) { return; diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index 2c2c1344c18..bc5d4ed162a 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -5,9 +5,8 @@ import * as os from 'os'; import * as path from 'path'; -import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge, QuickPickItemKind, TextDocument, LogOutputChannel } from 'vscode'; +import { Command, commands, Disposable, LineChange, MessageOptions, Position, ProgressLocation, QuickPickItem, Range, SourceControlResourceState, TextDocumentShowOptions, TextEditor, Uri, ViewColumn, window, workspace, WorkspaceEdit, WorkspaceFolder, TimelineItem, env, Selection, TextDocumentContentProvider, InputBoxValidationSeverity, TabInputText, TabInputTextMerge, QuickPickItemKind, TextDocument, LogOutputChannel, l10n } from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; -import * as nls from 'vscode-nls'; import { uniqueNamesGenerator, adjectives, animals, colors, NumberDictionary } from '@joaomoreno/unique-names-generator'; import { Branch, ForcePushMode, GitErrorCodes, Ref, RefType, Status, CommitOptions, RemoteSourcePublisher, Remote } from './api/git'; import { Git, Stash } from './git'; @@ -20,8 +19,6 @@ import { GitTimelineItem } from './timelineProvider'; import { ApiRepository } from './api/api1'; import { pickRemoteSource } from './remoteSource'; -const localize = nls.loadMessageBundle(); - class CheckoutItem implements QuickPickItem { protected get shortCommit(): string { return (this.ref.commit || '').substr(0, 8); } @@ -56,7 +53,7 @@ class CheckoutTagItem extends CheckoutItem { override get label(): string { return `$(tag) ${this.ref.name || this.shortCommit}`; } override get description(): string { - return localize('tag at', "Tag at {0}", this.shortCommit); + return l10n.t('Tag at {0}', this.shortCommit); } override async run(opts?: { detached?: boolean }): Promise { @@ -72,7 +69,7 @@ class CheckoutRemoteHeadItem extends CheckoutItem { override get label(): string { return `$(cloud) ${this.ref.name || this.shortCommit}`; } override get description(): string { - return localize('remote branch at', "Remote branch at {0}", this.shortCommit); + return l10n.t('Remote branch at {0}', this.shortCommit); } override async run(opts?: { detached?: boolean }): Promise { @@ -134,19 +131,19 @@ class RebaseItem implements QuickPickItem { } class CreateBranchItem implements QuickPickItem { - get label(): string { return '$(plus) ' + localize('create branch', 'Create new branch...'); } + get label(): string { return '$(plus) ' + l10n.t('Create new branch...'); } get description(): string { return ''; } get alwaysShow(): boolean { return true; } } class CreateBranchFromItem implements QuickPickItem { - get label(): string { return '$(plus) ' + localize('create branch from', 'Create new branch from...'); } + get label(): string { return '$(plus) ' + l10n.t('Create new branch from...'); } get description(): string { return ''; } get alwaysShow(): boolean { return true; } } class CheckoutDetachedItem implements QuickPickItem { - get label(): string { return '$(debug-disconnect) ' + localize('checkout detached', 'Checkout detached...'); } + get label(): string { return '$(debug-disconnect) ' + l10n.t('Checkout detached...'); } get description(): string { return ''; } get alwaysShow(): boolean { return true; } } @@ -165,7 +162,7 @@ class AddRemoteItem implements QuickPickItem { constructor(private cc: CommandCenter) { } - get label(): string { return '$(plus) ' + localize('add remote', 'Add a new remote...'); } + get label(): string { return '$(plus) ' + l10n.t('Add a new remote...'); } get description(): string { return ''; } get alwaysShow(): boolean { return true; } @@ -188,7 +185,7 @@ class RemoteItem implements QuickPickItem { } class FetchAllRemotesItem implements QuickPickItem { - get label(): string { return localize('fetch all remotes', "{0} Fetch all remotes", '$(cloud-download)'); } + get label(): string { return l10n.t('{0} Fetch all remotes', '$(cloud-download)'); } constructor(private readonly repository: Repository) { } @@ -440,11 +437,11 @@ export class CommandCenter { console.error(error); } - const current: InputData = { uri: mergeUris.ours, title: localize('Current', 'Current') }; - const incoming: InputData = { uri: mergeUris.theirs, title: localize('Incoming', 'Incoming') }; + const current: InputData = { uri: mergeUris.ours, title: l10n.t('Current') }; + const incoming: InputData = { uri: mergeUris.theirs, title: l10n.t('Incoming') }; if (isStashConflict) { - incoming.title = localize('stashedChanges', 'Stashed Changes'); + incoming.title = l10n.t('Stashed Changes'); } try { @@ -515,8 +512,8 @@ export class CommandCenter { async cloneRepository(url?: string, parentPath?: string, options: { recursive?: boolean; ref?: string } = {}): Promise { if (!url || typeof url !== 'string') { url = await pickRemoteSource({ - providerLabel: provider => localize('clonefrom', "Clone from {0}", provider.name), - urlLabel: localize('repourl', "Clone from URL") + providerLabel: provider => l10n.t('Clone from {0}', provider.name), + urlLabel: l10n.t('Clone from URL') }); } @@ -543,8 +540,8 @@ export class CommandCenter { canSelectFolders: true, canSelectMany: false, defaultUri: Uri.file(defaultCloneDirectory), - title: localize('selectFolderTitle', "Choose a folder to clone {0} into", url), - openLabel: localize('selectFolder', "Select Repository Location") + title: l10n.t('Choose a folder to clone {0} into', url), + openLabel: l10n.t('Select Repository Location') }); if (!uris || uris.length === 0) { @@ -565,7 +562,7 @@ export class CommandCenter { try { const opts = { location: ProgressLocation.Notification, - title: localize('cloning', "Cloning git repository '{0}'...", url), + title: l10n.t('Cloning git repository "{0}"...', url), cancellable: true }; @@ -589,14 +586,14 @@ export class CommandCenter { } if (action === undefined) { - let message = localize('proposeopen', "Would you like to open the cloned repository?"); - const open = localize('openrepo', "Open"); - const openNewWindow = localize('openreponew', "Open in New Window"); + let message = l10n.t('Would you like to open the cloned repository?'); + const open = l10n.t('Open'); + const openNewWindow = l10n.t('Open in New Window'); const choices = [open, openNewWindow]; - const addToWorkspace = localize('add', "Add to Workspace"); + const addToWorkspace = l10n.t('Add to Workspace'); if (workspace.workspaceFolders) { - message = localize('proposeopen2', "Would you like to open the cloned repository, or add it to the current workspace?"); + message = l10n.t('Would you like to open the cloned repository, or add it to the current workspace?'); choices.push(addToWorkspace); } @@ -670,8 +667,8 @@ export class CommandCenter { repositoryPath = workspace.workspaceFolders[0].uri.fsPath; askToOpen = false; } else { - const placeHolder = localize('init', "Pick workspace folder to initialize git repo in"); - const pick = { label: localize('choose', "Choose Folder...") }; + const placeHolder = l10n.t('Pick workspace folder to initialize git repo in'); + const pick = { label: l10n.t('Choose Folder...') }; const items: { label: string; folder?: WorkspaceFolder }[] = [ ...workspace.workspaceFolders.map(folder => ({ label: folder.name, description: folder.uri.fsPath, folder })), pick @@ -698,7 +695,7 @@ export class CommandCenter { canSelectFolders: true, canSelectMany: false, defaultUri, - openLabel: localize('init repo', "Initialize Repository") + openLabel: l10n.t('Initialize Repository') }); if (!result || result.length === 0) { @@ -708,8 +705,8 @@ export class CommandCenter { const uri = result[0]; if (homeUri.toString().startsWith(uri.toString())) { - const yes = localize('create repo', "Initialize Repository"); - const answer = await window.showWarningMessage(localize('are you sure', "This will create a Git repository in '{0}'. Are you sure you want to continue?", uri.fsPath), yes); + const yes = l10n.t('Initialize Repository'); + const answer = await window.showWarningMessage(l10n.t('This will create a Git repository in "{0}". Are you sure you want to continue?', uri.fsPath), yes); if (answer !== yes) { return; @@ -725,18 +722,18 @@ export class CommandCenter { await this.git.init(repositoryPath); - let message = localize('proposeopen init', "Would you like to open the initialized repository?"); - const open = localize('openrepo', "Open"); - const openNewWindow = localize('openreponew', "Open in New Window"); + let message = l10n.t('Would you like to open the initialized repository?'); + const open = l10n.t('Open'); + const openNewWindow = l10n.t('Open in New Window'); const choices = [open, openNewWindow]; if (!askToOpen) { return; } - const addToWorkspace = localize('add', "Add to Workspace"); + const addToWorkspace = l10n.t('Add to Workspace'); if (workspace.workspaceFolders) { - message = localize('proposeopen2 init', "Would you like to open the initialized repository, or add it to the current workspace?"); + message = l10n.t('Would you like to open the initialized repository, or add it to the current workspace?'); choices.push(addToWorkspace); } @@ -762,7 +759,7 @@ export class CommandCenter { canSelectFolders: true, canSelectMany: false, defaultUri: Uri.file(os.homedir()), - openLabel: localize('open repo', "Open Repository") + openLabel: l10n.t('Open Repository') }); if (!result || result.length === 0) { @@ -880,7 +877,7 @@ export class CommandCenter { const title = `${basename} (HEAD)`; if (!HEAD) { - window.showWarningMessage(localize('HEAD not available', "HEAD version of '{0}' is not available.", path.basename(resource.resourceUri.fsPath))); + window.showWarningMessage(l10n.t('HEAD version of "{0}" is not available.', path.basename(resource.resourceUri.fsPath))); return; } @@ -969,10 +966,10 @@ export class CommandCenter { if (unresolved.length > 0) { const message = unresolved.length > 1 - ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", unresolved.length) - : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(unresolved[0].resourceUri.fsPath)); + ? l10n.t('Are you sure you want to stage {0} files with merge conflicts?', unresolved.length) + : l10n.t('Are you sure you want to stage {0} with merge conflicts?', path.basename(unresolved[0].resourceUri.fsPath)); - const yes = localize('yes', "Yes"); + const yes = l10n.t('Yes'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick !== yes) { @@ -1028,9 +1025,9 @@ export class CommandCenter { } if (resource.type === Status.DELETED_BY_THEM) { - const keepIt = localize('keep ours', "Keep Our Version"); - const deleteIt = localize('delete', "Delete File"); - const result = await window.showInformationMessage(localize('deleted by them', "File '{0}' was deleted by them and modified by us.\n\nWhat would you like to do?", path.basename(uri.fsPath)), { modal: true }, keepIt, deleteIt); + const keepIt = l10n.t('Keep Our Version'); + const deleteIt = l10n.t('Delete File'); + const result = await window.showInformationMessage(l10n.t('File "{0}" was deleted by them and modified by us.\n\nWhat would you like to do?', path.basename(uri.fsPath)), { modal: true }, keepIt, deleteIt); if (result === keepIt) { await repository.add([uri]); @@ -1040,9 +1037,9 @@ export class CommandCenter { throw new Error('Cancelled'); } } else if (resource.type === Status.DELETED_BY_US) { - const keepIt = localize('keep theirs', "Keep Their Version"); - const deleteIt = localize('delete', "Delete File"); - const result = await window.showInformationMessage(localize('deleted by us', "File '{0}' was deleted by us and modified by them.\n\nWhat would you like to do?", path.basename(uri.fsPath)), { modal: true }, keepIt, deleteIt); + const keepIt = l10n.t('Keep Their Version'); + const deleteIt = l10n.t('Delete File'); + const result = await window.showInformationMessage(l10n.t('File "{0}" was deleted by us and modified by them.\n\nWhat would you like to do?', path.basename(uri.fsPath)), { modal: true }, keepIt, deleteIt); if (result === keepIt) { await repository.add([uri]); @@ -1091,10 +1088,10 @@ export class CommandCenter { if (unresolved.length > 0) { const message = unresolved.length > 1 - ? localize('confirm stage files with merge conflicts', "Are you sure you want to stage {0} files with merge conflicts?", merge.length) - : localize('confirm stage file with merge conflicts', "Are you sure you want to stage {0} with merge conflicts?", path.basename(merge[0].resourceUri.fsPath)); + ? l10n.t('Are you sure you want to stage {0} files with merge conflicts?', merge.length) + : l10n.t('Are you sure you want to stage {0} with merge conflicts?', path.basename(merge[0].resourceUri.fsPath)); - const yes = localize('yes', "Yes"); + const yes = l10n.t('Yes'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick !== yes) { @@ -1421,30 +1418,30 @@ export class CommandCenter { const untrackedCount = scmResources.reduce((s, r) => s + (r.type === Status.UNTRACKED ? 1 : 0), 0); let message: string; - let yes = localize('discard', "Discard Changes"); + let yes = l10n.t('Discard Changes'); if (scmResources.length === 1) { if (untrackedCount > 0) { - message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST if you proceed.", path.basename(scmResources[0].resourceUri.fsPath)); - yes = localize('delete file', "Delete file"); + message = l10n.t('Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST if you proceed.', path.basename(scmResources[0].resourceUri.fsPath)); + yes = l10n.t('Delete file'); } else { if (scmResources[0].type === Status.DELETED) { - yes = localize('restore file', "Restore file"); - message = localize('confirm restore', "Are you sure you want to restore {0}?", path.basename(scmResources[0].resourceUri.fsPath)); + yes = l10n.t('Restore file'); + message = l10n.t('Are you sure you want to restore {0}?', path.basename(scmResources[0].resourceUri.fsPath)); } else { - message = localize('confirm discard', "Are you sure you want to discard changes in {0}?", path.basename(scmResources[0].resourceUri.fsPath)); + message = l10n.t('Are you sure you want to discard changes in {0}?', path.basename(scmResources[0].resourceUri.fsPath)); } } } else { if (scmResources.every(resource => resource.type === Status.DELETED)) { - yes = localize('restore files', "Restore files"); - message = localize('confirm restore multiple', "Are you sure you want to restore {0} files?", scmResources.length); + yes = l10n.t('Restore files'); + message = l10n.t('Are you sure you want to restore {0} files?', scmResources.length); } else { - message = localize('confirm discard multiple', "Are you sure you want to discard changes in {0} files?", scmResources.length); + message = l10n.t('Are you sure you want to discard changes in {0} files?', scmResources.length); } if (untrackedCount > 0) { - message = `${message}\n\n${localize('warn untracked', "This will DELETE {0} untracked files!\nThis is IRREVERSIBLE!\nThese files will be FOREVER LOST.", untrackedCount)}`; + message = `${message}\n\n${l10n.t('This will DELETE {0} untracked files!\nThis is IRREVERSIBLE!\nThese files will be FOREVER LOST.', untrackedCount)}`; } } @@ -1477,16 +1474,16 @@ export class CommandCenter { await this._cleanUntrackedChanges(repository, resources); } else { // resources.length > 1 && untrackedResources.length > 0 && trackedResources.length > 0 const untrackedMessage = untrackedResources.length === 1 - ? localize('there are untracked files single', "The following untracked file will be DELETED FROM DISK if discarded: {0}.", path.basename(untrackedResources[0].resourceUri.fsPath)) - : localize('there are untracked files', "There are {0} untracked files which will be DELETED FROM DISK if discarded.", untrackedResources.length); + ? l10n.t('The following untracked file will be DELETED FROM DISK if discarded: {0}.', path.basename(untrackedResources[0].resourceUri.fsPath)) + : l10n.t('There are {0} untracked files which will be DELETED FROM DISK if discarded.', untrackedResources.length); - const message = localize('confirm discard all 2', "{0}\n\nThis is IRREVERSIBLE, your current working set will be FOREVER LOST.", untrackedMessage, resources.length); + const message = l10n.t('{0}\n\nThis is IRREVERSIBLE, your current working set will be FOREVER LOST.', untrackedMessage, resources.length); const yesTracked = trackedResources.length === 1 - ? localize('yes discard tracked', "Discard 1 Tracked File", trackedResources.length) - : localize('yes discard tracked multiple', "Discard {0} Tracked Files", trackedResources.length); + ? l10n.t('Discard 1 Tracked File', trackedResources.length) + : l10n.t('Discard {0} Tracked Files', trackedResources.length); - const yesAll = localize('discardAll', "Discard All {0} Files", resources.length); + const yesAll = l10n.t('Discard All {0} Files', resources.length); const pick = await window.showWarningMessage(message, { modal: true }, yesTracked, yesAll); if (pick === yesTracked) { @@ -1529,11 +1526,11 @@ export class CommandCenter { private async _cleanTrackedChanges(repository: Repository, resources: Resource[]): Promise { const message = resources.length === 1 - ? localize('confirm discard all single', "Are you sure you want to discard changes in {0}?", path.basename(resources[0].resourceUri.fsPath)) - : localize('confirm discard all', "Are you sure you want to discard ALL changes in {0} files?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST if you proceed.", resources.length); + ? l10n.t('Are you sure you want to discard changes in {0}?', path.basename(resources[0].resourceUri.fsPath)) + : l10n.t('Are you sure you want to discard ALL changes in {0} files?\nThis is IRREVERSIBLE!\nYour current working set will be FOREVER LOST if you proceed.', resources.length); const yes = resources.length === 1 - ? localize('discardAll multiple', "Discard 1 File") - : localize('discardAll', "Discard All {0} Files", resources.length); + ? l10n.t('Discard 1 File') + : l10n.t('Discard All {0} Files', resources.length); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick !== yes) { @@ -1544,8 +1541,8 @@ export class CommandCenter { } private async _cleanUntrackedChange(repository: Repository, resource: Resource): Promise { - const message = localize('confirm delete', "Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST if you proceed.", path.basename(resource.resourceUri.fsPath)); - const yes = localize('delete file', "Delete file"); + const message = l10n.t('Are you sure you want to DELETE {0}?\nThis is IRREVERSIBLE!\nThis file will be FOREVER LOST if you proceed.', path.basename(resource.resourceUri.fsPath)); + const yes = l10n.t('Delete file'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick !== yes) { @@ -1556,8 +1553,8 @@ export class CommandCenter { } private async _cleanUntrackedChanges(repository: Repository, resources: Resource[]): Promise { - const message = localize('confirm delete multiple', "Are you sure you want to DELETE {0} files?\nThis is IRREVERSIBLE!\nThese files will be FOREVER LOST if you proceed.", resources.length); - const yes = localize('delete files', "Delete Files"); + const message = l10n.t('Are you sure you want to DELETE {0} files?\nThis is IRREVERSIBLE!\nThese files will be FOREVER LOST if you proceed.', resources.length); + const yes = l10n.t('Delete Files'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick !== yes) { @@ -1598,10 +1595,10 @@ export class CommandCenter { if (documents.length > 0) { const message = documents.length === 1 - ? localize('unsaved files single', "The following file has unsaved changes which won't be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?", path.basename(documents[0].uri.fsPath)) - : localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before committing?", documents.length); - const saveAndCommit = localize('save and commit', "Save All & Commit"); - const commit = localize('commit', "Commit Staged Changes"); + ? l10n.t('The following file has unsaved changes which won\'t be included in the commit if you proceed: {0}.\n\nWould you like to save it before committing?', path.basename(documents[0].uri.fsPath)) + : l10n.t('There are {0} unsaved files.\n\nWould you like to save them before committing?', documents.length); + const saveAndCommit = l10n.t('Save All & Commit'); + const commit = l10n.t('Commit Staged Changes'); const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit); if (pick === saveAndCommit) { @@ -1625,10 +1622,10 @@ export class CommandCenter { } // prompt the user if we want to commit all or not - const message = localize('no staged changes', "There are no staged changes to commit.\n\nWould you like to stage all your changes and commit them directly?"); - const yes = localize('yes', "Yes"); - const always = localize('always', "Always"); - const never = localize('never', "Never"); + const message = l10n.t('There are no staged changes to commit.\n\nWould you like to stage all your changes and commit them directly?'); + const yes = l10n.t('Yes'); + const always = l10n.t('Always'); + const never = l10n.t('Never'); const pick = await window.showWarningMessage(message, { modal: true }, yes, always, never); if (pick === always) { @@ -1679,8 +1676,8 @@ export class CommandCenter { // rebase not in progress && repository.rebaseCommit === undefined ) { - const commitAnyway = localize('commit anyway', "Create Empty Commit"); - const answer = await window.showInformationMessage(localize('no changes', "There are no changes to commit."), commitAnyway); + const commitAnyway = l10n.t('Create Empty Commit'); + const answer = await window.showInformationMessage(l10n.t('There are no changes to commit.'), commitAnyway); if (answer !== commitAnyway) { return false; @@ -1691,14 +1688,14 @@ export class CommandCenter { if (opts.noVerify) { if (!config.get('allowNoVerifyCommit')) { - await window.showErrorMessage(localize('no verify commit not allowed', "Commits without verification are not allowed, please enable them with the 'git.allowNoVerifyCommit' setting.")); + await window.showErrorMessage(l10n.t('Commits without verification are not allowed, please enable them with the "git.allowNoVerifyCommit" setting.')); return false; } if (config.get('confirmNoVerifyCommit')) { - const message = localize('confirm no verify commit', "You are about to commit your changes without verification, this skips pre-commit hooks and can be undesirable.\n\nAre you sure to continue?"); - const yes = localize('ok', "OK"); - const neverAgain = localize('never ask again', "OK, Don't Ask Again"); + const message = l10n.t('You are about to commit your changes without verification, this skips pre-commit hooks and can be undesirable.\n\nAre you sure to continue?'); + const yes = l10n.t('OK'); + const neverAgain = l10n.t('OK, Don\'t Ask Again'); const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain); if (pick === neverAgain) { @@ -1726,13 +1723,13 @@ export class CommandCenter { // Branch protection const branchProtectionPrompt = config.get<'alwaysCommit' | 'alwaysCommitToNewBranch' | 'alwaysPrompt'>('branchProtectionPrompt')!; if (repository.isBranchProtected() && (branchProtectionPrompt === 'alwaysPrompt' || branchProtectionPrompt === 'alwaysCommitToNewBranch')) { - const commitToNewBranch = localize('commit to branch', "Commit to a New Branch"); + const commitToNewBranch = l10n.t('Commit to a New Branch'); let pick: string | undefined = commitToNewBranch; if (branchProtectionPrompt === 'alwaysPrompt') { - const message = localize('confirm branch protection commit', "You are trying to commit to a protected branch and you might not have permission to push your commits to the remote.\n\nHow would you like to proceed?"); - const commit = localize('commit changes', "Commit Anyway"); + const message = l10n.t('You are trying to commit to a protected branch and you might not have permission to push your commits to the remote.\n\nHow would you like to proceed?'); + const commit = l10n.t('Commit Anyway'); pick = await window.showWarningMessage(message, { modal: true }, commitToNewBranch, commit); } @@ -1774,15 +1771,15 @@ export class CommandCenter { let placeHolder: string; if (branchName) { - placeHolder = localize('commitMessageWithHeadLabel2', "Message (commit on '{0}')", branchName); + placeHolder = l10n.t('Message (commit on "{0}")', branchName); } else { - placeHolder = localize('commit message', "Commit message"); + placeHolder = l10n.t('Commit message'); } _message = await window.showInputBox({ value, placeHolder, - prompt: localize('provide commit message', "Please provide a commit message"), + prompt: l10n.t('Please provide a commit message'), ignoreFocusOut: true }); } @@ -1883,9 +1880,9 @@ export class CommandCenter { const shouldPrompt = config.get('confirmEmptyCommits') === true; if (shouldPrompt) { - const message = localize('confirm empty commit', "Are you sure you want to create an empty commit?"); - const yes = localize('yes', "Yes"); - const neverAgain = localize('yes never again', "Yes, Don't Show Again"); + const message = l10n.t('Are you sure you want to create an empty commit?'); + const yes = l10n.t('Yes'); + const neverAgain = l10n.t('Yes, Don\'t Show Again'); const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain); if (pick === neverAgain) { @@ -1953,15 +1950,15 @@ export class CommandCenter { const HEAD = repository.HEAD; if (!HEAD || !HEAD.commit) { - window.showWarningMessage(localize('no more', "Can't undo because HEAD doesn't point to any commit.")); + window.showWarningMessage(l10n.t('Can\'t undo because HEAD doesn\'t point to any commit.')); return; } const commit = await repository.getCommit('HEAD'); if (commit.parents.length > 1) { - const yes = localize('undo commit', "Undo merge commit"); - const result = await window.showWarningMessage(localize('merge commit', "The last commit was a merge commit. Are you sure you want to undo it?"), { modal: true }, yes); + const yes = l10n.t('Undo merge commit'); + const result = await window.showWarningMessage(l10n.t('The last commit was a merge commit. Are you sure you want to undo it?'), { modal: true }, yes); if (result !== yes) { return; @@ -2008,8 +2005,8 @@ export class CommandCenter { const quickpick = window.createQuickPick(); quickpick.items = picks; quickpick.placeholder = opts?.detached - ? localize('select a ref to checkout detached', 'Select a ref to checkout in detached mode') - : localize('select a ref to checkout', 'Select a ref to checkout'); + ? l10n.t('Select a ref to checkout in detached mode') + : l10n.t('Select a ref to checkout'); quickpick.show(); @@ -2036,9 +2033,9 @@ export class CommandCenter { throw err; } - const force = localize('force', "Force Checkout"); - const stash = localize('stashcheckout', "Stash & Checkout"); - const choice = await window.showWarningMessage(localize('local changes', "Your local changes would be overwritten by checkout."), { modal: true }, force, stash); + const force = l10n.t('Force Checkout'); + const stash = l10n.t('Stash & Checkout'); + const choice = await window.showWarningMessage(l10n.t('Your local changes would be overwritten by checkout.'), { modal: true }, force, stash); if (choice === force) { await this.cleanAll(repository); @@ -2128,8 +2125,8 @@ export class CommandCenter { initialValue.startsWith(branchPrefix) ? [branchPrefix.length, initialValue.length] : undefined; rawBranchName = await window.showInputBox({ - placeHolder: localize('branch name', "Branch name"), - prompt: localize('provide branch name', "Please provide a new branch name"), + placeHolder: l10n.t('Branch name'), + prompt: l10n.t('Please provide a new branch name'), value: initialValue, valueSelection: initialValueSelection, ignoreFocusOut: true, @@ -2143,12 +2140,12 @@ export class CommandCenter { return name === sanitizedName ? null : { - message: localize('branch name does not match sanitized', "The new branch will be '{0}'", sanitizedName), + message: l10n.t('The new branch will be "{0}"', sanitizedName), severity: InputBoxValidationSeverity.Info }; } - return localize('branch name format invalid', "Branch name needs to match regex: {0}", branchValidationRegex); + return l10n.t('Branch name needs to match regex: {0}', branchValidationRegex); } }); } @@ -2167,7 +2164,7 @@ export class CommandCenter { if (from) { const picks = [new HEADItem(repository), ...createCheckoutItems(repository)]; - const placeHolder = localize('select a ref to create a new branch from', 'Select a ref to create the \'{0}\' branch from', branchName); + const placeHolder = l10n.t('Select a ref to create the "{0}" branch from', branchName); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2192,7 +2189,7 @@ export class CommandCenter { const heads = repository.refs.filter(ref => ref.type === RefType.Head && ref.name !== currentHead) .map(ref => new BranchDeleteItem(ref)); - const placeHolder = localize('select branch to delete', 'Select a branch to delete'); + const placeHolder = l10n.t('Select a branch to delete'); const choice = await window.showQuickPick(heads, { placeHolder }); if (!choice || !choice.branchName) { @@ -2209,8 +2206,8 @@ export class CommandCenter { throw err; } - const message = localize('confirm force delete branch', "The branch '{0}' is not fully merged. Delete anyway?", name); - const yes = localize('delete branch', "Delete Branch"); + const message = l10n.t('The branch "{0}" is not fully merged. Delete anyway?', name); + const yes = l10n.t('Delete Branch'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick === yes) { @@ -2233,10 +2230,10 @@ export class CommandCenter { } catch (err) { switch (err.gitErrorCode) { case GitErrorCodes.InvalidBranchName: - window.showErrorMessage(localize('invalid branch name', 'Invalid branch name')); + window.showErrorMessage(l10n.t('Invalid branch name')); return; case GitErrorCodes.BranchAlreadyExists: - window.showErrorMessage(localize('branch already exists', "A branch named '{0}' already exists", branchName)); + window.showErrorMessage(l10n.t('A branch named "{0}" already exists', branchName)); return; default: throw err; @@ -2259,7 +2256,7 @@ export class CommandCenter { .map(ref => new MergeItem(ref as Branch)); const picks = [...heads, ...remoteHeads]; - const placeHolder = localize('select a branch to merge from', 'Select a branch to merge from'); + const placeHolder = l10n.t('Select a branch to merge from'); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2302,7 +2299,7 @@ export class CommandCenter { } } - const placeHolder = localize('select a branch to rebase onto', 'Select a branch to rebase onto'); + const placeHolder = l10n.t('Select a branch to rebase onto'); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2315,8 +2312,8 @@ export class CommandCenter { @command('git.createTag', { repository: true }) async createTag(repository: Repository): Promise { const inputTagName = await window.showInputBox({ - placeHolder: localize('tag name', "Tag name"), - prompt: localize('provide tag name', "Please provide a tag name"), + placeHolder: l10n.t('Tag name'), + prompt: l10n.t('Please provide a tag name'), ignoreFocusOut: true }); @@ -2325,8 +2322,8 @@ export class CommandCenter { } const inputMessage = await window.showInputBox({ - placeHolder: localize('tag message', "Message"), - prompt: localize('provide tag message', "Please provide a message to annotate the tag"), + placeHolder: l10n.t('Message'), + prompt: l10n.t('Please provide a message to annotate the tag'), ignoreFocusOut: true }); @@ -2340,11 +2337,11 @@ export class CommandCenter { .map(ref => new TagItem(ref)); if (picks.length === 0) { - window.showWarningMessage(localize('no tags', "This repository has no tags.")); + window.showWarningMessage(l10n.t('This repository has no tags.')); return; } - const placeHolder = localize('select a tag to delete', 'Select a tag to delete'); + const placeHolder = l10n.t('Select a tag to delete'); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2357,7 +2354,7 @@ export class CommandCenter { @command('git.fetch', { repository: true }) async fetch(repository: Repository): Promise { if (repository.remotes.length === 0) { - window.showWarningMessage(localize('no remotes to fetch', "This repository has no remotes configured to fetch from.")); + window.showWarningMessage(l10n.t('This repository has no remotes configured to fetch from.')); return; } @@ -2379,7 +2376,7 @@ export class CommandCenter { } const quickpick = window.createQuickPick(); - quickpick.placeholder = localize('select a remote to fetch', 'Select a remote to fetch'); + quickpick.placeholder = l10n.t('Select a remote to fetch'); quickpick.canSelectMany = false; quickpick.items = [...remoteItems, { label: '', kind: QuickPickItemKind.Separator }, new FetchAllRemotesItem(repository)]; @@ -2400,7 +2397,7 @@ export class CommandCenter { @command('git.fetchPrune', { repository: true }) async fetchPrune(repository: Repository): Promise { if (repository.remotes.length === 0) { - window.showWarningMessage(localize('no remotes to fetch', "This repository has no remotes configured to fetch from.")); + window.showWarningMessage(l10n.t('This repository has no remotes configured to fetch from.')); return; } @@ -2411,7 +2408,7 @@ export class CommandCenter { @command('git.fetchAll', { repository: true }) async fetchAll(repository: Repository): Promise { if (repository.remotes.length === 0) { - window.showWarningMessage(localize('no remotes to fetch', "This repository has no remotes configured to fetch from.")); + window.showWarningMessage(l10n.t('This repository has no remotes configured to fetch from.')); return; } @@ -2423,12 +2420,12 @@ export class CommandCenter { const remotes = repository.remotes; if (remotes.length === 0) { - window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); + window.showWarningMessage(l10n.t('Your repository has no remotes configured to pull from.')); return; } const remotePicks = remotes.filter(r => r.fetchUrl !== undefined).map(r => ({ label: r.name, description: r.fetchUrl! })); - const placeHolder = localize('pick remote pull repo', "Pick a remote to pull the branch from"); + const placeHolder = l10n.t('Pick a remote to pull the branch from'); const remotePick = await window.showQuickPick(remotePicks, { placeHolder }); if (!remotePick) { @@ -2438,7 +2435,7 @@ export class CommandCenter { const remoteRefs = repository.refs; const remoteRefsFiltered = remoteRefs.filter(r => (r.remote === remotePick.label)); const branchPicks = remoteRefsFiltered.map(r => ({ label: r.name! })); - const branchPlaceHolder = localize('pick branch pull', "Pick a branch to pull from"); + const branchPlaceHolder = l10n.t('Pick a branch to pull from'); const branchPick = await window.showQuickPick(branchPicks, { placeHolder: branchPlaceHolder }); if (!branchPick) { @@ -2455,7 +2452,7 @@ export class CommandCenter { const remotes = repository.remotes; if (remotes.length === 0) { - window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); + window.showWarningMessage(l10n.t('Your repository has no remotes configured to pull from.')); return; } @@ -2467,7 +2464,7 @@ export class CommandCenter { const remotes = repository.remotes; if (remotes.length === 0) { - window.showWarningMessage(localize('no remotes to pull', "Your repository has no remotes configured to pull from.")); + window.showWarningMessage(l10n.t('Your repository has no remotes configured to pull from.')); return; } @@ -2482,8 +2479,8 @@ export class CommandCenter { return; } - const addRemote = localize('addremote', 'Add Remote'); - const result = await window.showWarningMessage(localize('no remotes to push', "Your repository has no remotes configured to push to."), addRemote); + const addRemote = l10n.t('Add Remote'); + const result = await window.showWarningMessage(l10n.t('Your repository has no remotes configured to push to.'), addRemote); if (result === addRemote) { await this.addRemote(repository); @@ -2497,16 +2494,16 @@ export class CommandCenter { if (pushOptions.forcePush) { if (!config.get('allowForcePush')) { - await window.showErrorMessage(localize('force push not allowed', "Force push is not allowed, please enable it with the 'git.allowForcePush' setting.")); + await window.showErrorMessage(l10n.t('Force push is not allowed, please enable it with the "git.allowForcePush" setting.')); return; } forcePushMode = config.get('useForcePushWithLease') === true ? ForcePushMode.ForceWithLease : ForcePushMode.Force; if (config.get('confirmForcePush')) { - const message = localize('confirm force push', "You are about to force push your changes, this can be destructive and could inadvertently overwrite changes made by others.\n\nAre you sure to continue?"); - const yes = localize('ok', "OK"); - const neverAgain = localize('never ask again', "OK, Don't Ask Again"); + const message = l10n.t('You are about to force push your changes, this can be destructive and could inadvertently overwrite changes made by others.\n\nAre you sure to continue?'); + const yes = l10n.t('OK'); + const neverAgain = l10n.t('OK, Don\'t Ask Again'); const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain); if (pick === neverAgain) { @@ -2528,7 +2525,7 @@ export class CommandCenter { if (!repository.HEAD || !repository.HEAD.name) { if (!pushOptions.silent) { - window.showWarningMessage(localize('nobranch', "Please check out a branch to push to a remote.")); + window.showWarningMessage(l10n.t('Please check out a branch to push to a remote.')); } return; } @@ -2546,8 +2543,8 @@ export class CommandCenter { } const branchName = repository.HEAD.name; - const message = localize('confirm publish branch', "The branch '{0}' has no remote branch. Would you like to publish this branch?", branchName); - const yes = localize('ok', "OK"); + const message = l10n.t('The branch "{0}" has no remote branch. Would you like to publish this branch?', branchName); + const yes = l10n.t('OK'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick === yes) { @@ -2559,7 +2556,7 @@ export class CommandCenter { if (!pushOptions.pushTo?.remote) { const addRemote = new AddRemoteItem(this); const picks = [...remotes.filter(r => r.pushUrl !== undefined).map(r => ({ label: r.name, description: r.pushUrl })), addRemote]; - const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName); + const placeHolder = l10n.t('Pick a remote to publish the branch "{0}" to:', branchName); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2604,8 +2601,8 @@ export class CommandCenter { @command('git.cherryPick', { repository: true }) async cherryPick(repository: Repository): Promise { const hash = await window.showInputBox({ - placeHolder: localize('commit hash', "Commit Hash"), - prompt: localize('provide commit hash', "Please provide the commit hash"), + placeHolder: l10n.t('Commit Hash'), + prompt: l10n.t('Please provide the commit hash'), ignoreFocusOut: true }); @@ -2634,8 +2631,8 @@ export class CommandCenter { @command('git.addRemote', { repository: true }) async addRemote(repository: Repository): Promise { const url = await pickRemoteSource({ - providerLabel: provider => localize('addfrom', "Add remote from {0}", provider.name), - urlLabel: localize('addFrom', "Add remote from URL") + providerLabel: provider => l10n.t('Add remote from {0}', provider.name), + urlLabel: l10n.t('Add remote from URL') }); if (!url) { @@ -2643,14 +2640,14 @@ export class CommandCenter { } const resultName = await window.showInputBox({ - placeHolder: localize('remote name', "Remote name"), - prompt: localize('provide remote name', "Please provide a remote name"), + placeHolder: l10n.t('Remote name'), + prompt: l10n.t('Please provide a remote name'), ignoreFocusOut: true, validateInput: (name: string) => { if (!sanitizeRemoteName(name)) { - return localize('remote name format invalid', "Remote name format invalid"); + return l10n.t('Remote name format invalid'); } else if (repository.remotes.find(r => r.name === name)) { - return localize('remote already exists', "Remote '{0}' already exists.", name); + return l10n.t('Remote "{0}" already exists.', name); } return null; @@ -2673,12 +2670,12 @@ export class CommandCenter { const remotes = repository.remotes; if (remotes.length === 0) { - window.showErrorMessage(localize('no remotes added', "Your repository has no remotes.")); + window.showErrorMessage(l10n.t('Your repository has no remotes.')); return; } const picks = remotes.map(r => r.name); - const placeHolder = localize('remove remote', "Pick a remote to remove"); + const placeHolder = l10n.t('Pick a remote to remove'); const remoteName = await window.showQuickPick(picks, { placeHolder }); @@ -2696,8 +2693,8 @@ export class CommandCenter { return; } else if (!HEAD.upstream) { const branchName = HEAD.name; - const message = localize('confirm publish branch', "The branch '{0}' has no remote branch. Would you like to publish this branch?", branchName); - const yes = localize('ok', "OK"); + const message = l10n.t('The branch "{0}" has no remote branch. Would you like to publish this branch?', branchName ?? ''); + const yes = l10n.t('OK'); const pick = await window.showWarningMessage(message, { modal: true }, yes); if (pick === yes) { @@ -2714,9 +2711,9 @@ export class CommandCenter { const shouldPrompt = !isReadonly && config.get('confirmSync') === true; if (shouldPrompt) { - const message = localize('sync is unpredictable', "This action will pull and push commits from and to '{0}/{1}'.", HEAD.upstream.remote, HEAD.upstream.name); - const yes = localize('ok', "OK"); - const neverAgain = localize('never again', "OK, Don't Show Again"); + const message = l10n.t('This action will pull and push commits from and to "{0}/{1}".', HEAD.upstream.remote, HEAD.upstream.name); + const yes = l10n.t('OK'); + const neverAgain = l10n.t('OK, Don\'t Show Again'); const pick = await window.showWarningMessage(message, { modal: true }, yes, neverAgain); if (pick === neverAgain) { @@ -2783,7 +2780,7 @@ export class CommandCenter { const publishers = this.model.getRemoteSourcePublishers(); if (publishers.length === 0) { - window.showWarningMessage(localize('no remotes to publish', "Your repository has no remotes configured to publish to.")); + window.showWarningMessage(l10n.t('Your repository has no remotes configured to publish to.')); return; } @@ -2793,8 +2790,8 @@ export class CommandCenter { publisher = publishers[0]; } else { const picks = publishers - .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + localize('publish to', "Publish to {0}", provider.name), alwaysShow: true, provider })); - const placeHolder = localize('pick provider', "Pick a provider to publish the branch '{0}' to:", branchName); + .map(provider => ({ label: (provider.icon ? `$(${provider.icon}) ` : '') + l10n.t('Publish to {0}', provider.name), alwaysShow: true, provider })); + const placeHolder = l10n.t('Pick a provider to publish the branch "{0}" to:', branchName); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2819,7 +2816,7 @@ export class CommandCenter { const addRemote = new AddRemoteItem(this); const picks = [...repository.remotes.map(r => ({ label: r.name, description: r.pushUrl })), addRemote]; - const placeHolder = localize('pick remote', "Pick a remote to publish the branch '{0}' to:", branchName); + const placeHolder = l10n.t('Pick a remote to publish the branch "{0}" to:', branchName); const choice = await window.showQuickPick(picks, { placeHolder }); if (!choice) { @@ -2900,7 +2897,7 @@ export class CommandCenter { const noStagedChanges = repository.indexGroup.resourceStates.length === 0; if (noUnstagedChanges && noStagedChanges) { - window.showInformationMessage(localize('no changes stash', "There are no changes to stash.")); + window.showInformationMessage(l10n.t('There are no changes to stash.')); return; } @@ -2918,10 +2915,10 @@ export class CommandCenter { if (documents.length > 0) { const message = documents.length === 1 - ? localize('unsaved stash files single', "The following file has unsaved changes which won't be included in the stash if you proceed: {0}.\n\nWould you like to save it before stashing?", path.basename(documents[0].uri.fsPath)) - : localize('unsaved stash files', "There are {0} unsaved files.\n\nWould you like to save them before stashing?", documents.length); - const saveAndStash = localize('save and stash', "Save All & Stash"); - const stash = localize('stash', "Stash Anyway"); + ? l10n.t('The following file has unsaved changes which won\'t be included in the stash if you proceed: {0}.\n\nWould you like to save it before stashing?', path.basename(documents[0].uri.fsPath)) + : l10n.t('There are {0} unsaved files.\n\nWould you like to save them before stashing?', documents.length); + const saveAndStash = l10n.t('Save All & Stash'); + const stash = l10n.t('Stash Anyway'); const pick = await window.showWarningMessage(message, { modal: true }, saveAndStash, stash); if (pick === saveAndStash) { @@ -2940,8 +2937,8 @@ export class CommandCenter { message = await window.showInputBox({ value: message, - prompt: localize('provide stash message', "Optionally provide a stash message"), - placeHolder: localize('stash message', "Stash message") + prompt: l10n.t('Optionally provide a stash message'), + placeHolder: l10n.t('Stash message') }); if (typeof message === 'undefined') { @@ -2963,7 +2960,7 @@ export class CommandCenter { @command('git.stashPop', { repository: true }) async stashPop(repository: Repository): Promise { - const placeHolder = localize('pick stash to pop', "Pick a stash to pop"); + const placeHolder = l10n.t('Pick a stash to pop'); const stash = await this.pickStash(repository, placeHolder); if (!stash) { @@ -2978,7 +2975,7 @@ export class CommandCenter { const stashes = await repository.getStashes(); if (stashes.length === 0) { - window.showInformationMessage(localize('no stashes', "There are no stashes in the repository.")); + window.showInformationMessage(l10n.t('There are no stashes in the repository.')); return; } @@ -2987,7 +2984,7 @@ export class CommandCenter { @command('git.stashApply', { repository: true }) async stashApply(repository: Repository): Promise { - const placeHolder = localize('pick stash to apply', "Pick a stash to apply"); + const placeHolder = l10n.t('Pick a stash to apply'); const stash = await this.pickStash(repository, placeHolder); if (!stash) { @@ -3002,7 +2999,7 @@ export class CommandCenter { const stashes = await repository.getStashes(); if (stashes.length === 0) { - window.showInformationMessage(localize('no stashes', "There are no stashes in the repository.")); + window.showInformationMessage(l10n.t('There are no stashes in the repository.')); return; } @@ -3011,7 +3008,7 @@ export class CommandCenter { @command('git.stashDrop', { repository: true }) async stashDrop(repository: Repository): Promise { - const placeHolder = localize('pick stash to drop', "Pick a stash to drop"); + const placeHolder = l10n.t('Pick a stash to drop'); const stash = await this.pickStash(repository, placeHolder); if (!stash) { @@ -3019,9 +3016,9 @@ export class CommandCenter { } // request confirmation for the operation - const yes = localize('yes', "Yes"); + const yes = l10n.t('Yes'); const result = await window.showWarningMessage( - localize('sure drop', "Are you sure you want to drop the stash: {0}?", stash.description), + l10n.t('Are you sure you want to drop the stash: {0}?', stash.description), yes ); if (result !== yes) { @@ -3036,15 +3033,15 @@ export class CommandCenter { const stashes = await repository.getStashes(); if (stashes.length === 0) { - window.showInformationMessage(localize('no stashes', "There are no stashes in the repository.")); + window.showInformationMessage(l10n.t('There are no stashes in the repository.')); return; } // request confirmation for the operation - const yes = localize('yes', "Yes"); + const yes = l10n.t('Yes'); const question = stashes.length === 1 ? - localize('drop one stash', "Are you sure you want to drop ALL stashes? There is 1 stash that will be subject to pruning, and MAY BE IMPOSSIBLE TO RECOVER.") : - localize('drop all stashes', "Are you sure you want to drop ALL stashes? There are {0} stashes that will be subject to pruning, and MAY BE IMPOSSIBLE TO RECOVER.", stashes.length); + l10n.t('Are you sure you want to drop ALL stashes? There is 1 stash that will be subject to pruning, and MAY BE IMPOSSIBLE TO RECOVER.') : + l10n.t('Are you sure you want to drop ALL stashes? There are {0} stashes that will be subject to pruning, and MAY BE IMPOSSIBLE TO RECOVER.', stashes.length); const result = await window.showWarningMessage(question, yes); if (result !== yes) { @@ -3058,7 +3055,7 @@ export class CommandCenter { const stashes = await repository.getStashes(); if (stashes.length === 0) { - window.showInformationMessage(localize('no stashes', "There are no stashes in the repository.")); + window.showInformationMessage(l10n.t('There are no stashes in the repository.')); return; } @@ -3093,17 +3090,17 @@ export class CommandCenter { let title; if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') { - title = localize('git.title.workingTree', '{0} (Working Tree)', basename); + title = l10n.t('{0} (Working Tree)', basename); } else if (item.previousRef === 'HEAD' && item.ref === '~') { - title = localize('git.title.index', '{0} (Index)', basename); + title = l10n.t('{0} (Index)', basename); } else { - title = localize('git.title.diffRefs', '{0} ({1}) ↔ {0} ({2})', basename, item.shortPreviousRef, item.shortRef); + title = l10n.t('{0} ({1}) ↔ {0} ({2})', basename, item.shortPreviousRef, item.shortRef); } return { command: 'vscode.diff', - title: localize('git.timeline.openDiffCommand', "Open Comparison"), + title: l10n.t('Open Comparison'), arguments: [toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title, options] }; } @@ -3149,26 +3146,26 @@ export class CommandCenter { const basename = path.basename(uri.fsPath); let leftTitle; if ((selected.previousRef === 'HEAD' || selected.previousRef === '~') && selected.ref === '') { - leftTitle = localize('git.title.workingTree', '{0} (Working Tree)', basename); + leftTitle = l10n.t('{0} (Working Tree)', basename); } else if (selected.previousRef === 'HEAD' && selected.ref === '~') { - leftTitle = localize('git.title.index', '{0} (Index)', basename); + leftTitle = l10n.t('{0} (Index)', basename); } else { - leftTitle = localize('git.title.ref', '{0} ({1})', basename, selected.shortRef); + leftTitle = l10n.t('{0} ({1})', basename, selected.shortRef); } let rightTitle; if ((item.previousRef === 'HEAD' || item.previousRef === '~') && item.ref === '') { - rightTitle = localize('git.title.workingTree', '{0} (Working Tree)', basename); + rightTitle = l10n.t('{0} (Working Tree)', basename); } else if (item.previousRef === 'HEAD' && item.ref === '~') { - rightTitle = localize('git.title.index', '{0} (Index)', basename); + rightTitle = l10n.t('{0} (Index)', basename); } else { - rightTitle = localize('git.title.ref', '{0} ({1})', basename, item.shortRef); + rightTitle = l10n.t('{0} ({1})', basename, item.shortRef); } - const title = localize('git.title.diff', '{0} ↔ {1}', leftTitle, rightTitle); + const title = l10n.t('{0} ↔ {1}', leftTitle, rightTitle); await commands.executeCommand('vscode.diff', selected.ref === '' ? uri : toGitUri(uri, selected.ref), item.ref === '' ? uri : toGitUri(uri, item.ref), title); } @@ -3177,7 +3174,7 @@ export class CommandCenter { if (repository.rebaseCommit) { await repository.rebaseAbort(); } else { - await window.showInformationMessage(localize('no rebase', "No rebase in progress.")); + await window.showInformationMessage(l10n.t('No rebase in progress.')); } } @@ -3231,11 +3228,11 @@ export class CommandCenter { let type: 'error' | 'warning' | 'information' = 'error'; const choices = new Map void>(); - const openOutputChannelChoice = localize('open git log', "Open Git Log"); + const openOutputChannelChoice = l10n.t('Open Git Log'); const outputChannelLogger = this.logger; choices.set(openOutputChannelChoice, () => outputChannelLogger.show()); - const showCommandOutputChoice = localize('show command output', "Show Command Output"); + const showCommandOutputChoice = l10n.t('Show Command Output'); if (err.stderr) { choices.set(showCommandOutputChoice, async () => { const timestamp = new Date().getTime(); @@ -3262,18 +3259,18 @@ export class CommandCenter { switch (err.gitErrorCode) { case GitErrorCodes.DirtyWorkTree: - message = localize('clean repo', "Please clean your repository working tree before checkout."); + message = l10n.t('Please clean your repository working tree before checkout.'); break; case GitErrorCodes.PushRejected: - message = localize('cant push', "Can't push refs to remote. Try running 'Pull' first to integrate your changes."); + message = l10n.t('Can\'t push refs to remote. Try running "Pull" first to integrate your changes.'); break; case GitErrorCodes.Conflict: - message = localize('merge conflicts', "There are merge conflicts. Resolve them before committing."); + message = l10n.t('There are merge conflicts. Resolve them before committing.'); type = 'warning'; options.modal = false; break; case GitErrorCodes.StashConflict: - message = localize('stash merge conflicts', "There were merge conflicts while applying the stash."); + message = l10n.t('There were merge conflicts while applying the stash.'); type = 'warning'; options.modal = false; break; @@ -3282,17 +3279,17 @@ export class CommandCenter { const match = regex.exec(err.stderr || String(err)); message = match - ? localize('auth failed specific', "Failed to authenticate to git remote:\n\n{0}", match[1]) - : localize('auth failed', "Failed to authenticate to git remote."); + ? l10n.t('Failed to authenticate to git remote:\n\n{0}', match[1]) + : l10n.t('Failed to authenticate to git remote.'); break; } case GitErrorCodes.NoUserNameConfigured: case GitErrorCodes.NoUserEmailConfigured: - message = localize('missing user info', "Make sure you configure your 'user.name' and 'user.email' in git."); - choices.set(localize('learn more', "Learn More"), () => commands.executeCommand('vscode.open', Uri.parse('https://aka.ms/vscode-setup-git'))); + message = l10n.t('Make sure you configure your "user.name" and "user.email" in git.'); + choices.set(l10n.t('Learn More'), () => commands.executeCommand('vscode.open', Uri.parse('https://aka.ms/vscode-setup-git'))); break; case GitErrorCodes.EmptyCommitMessage: - message = localize('empty commit', "Commit operation was cancelled due to empty commit message."); + message = l10n.t('Commit operation was cancelled due to empty commit message.'); choices.clear(); type = 'information'; options.modal = false; @@ -3306,8 +3303,8 @@ export class CommandCenter { [0]; message = hint - ? localize('git error details', "Git: {0}", hint) - : localize('git error', "Git error"); + ? l10n.t('Git: {0}', hint) + : l10n.t('Git error'); break; } diff --git a/extensions/git/src/main.ts b/extensions/git/src/main.ts index d8afa73f8a4..87ddb61e4ca 100644 --- a/extensions/git/src/main.ts +++ b/extensions/git/src/main.ts @@ -3,10 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -const localize = nls.loadMessageBundle(); - -import { env, ExtensionContext, workspace, window, Disposable, commands, Uri, version as vscodeVersion, WorkspaceFolder, LogOutputChannel } from 'vscode'; +import { env, ExtensionContext, workspace, window, Disposable, commands, Uri, version as vscodeVersion, WorkspaceFolder, LogOutputChannel, l10n } from 'vscode'; import { findGit, Git, IGit } from './git'; import { Model } from './model'; import { CommandCenter } from './commands'; @@ -50,7 +47,7 @@ async function createModel(context: ExtensionContext, logger: LogOutputChannel, } const info = await findGit(pathHints, gitPath => { - logger.info(localize('validating', "Validating found git in: {0}", gitPath)); + logger.info(l10n.t('Validating found git in: "{0}"', gitPath)); if (excludes.length === 0) { return true; } @@ -58,7 +55,7 @@ async function createModel(context: ExtensionContext, logger: LogOutputChannel, const normalized = path.normalize(gitPath).replace(/[\r\n]+$/, ''); const skip = excludes.some(e => normalized.startsWith(e)); if (skip) { - logger.info(localize('skipped', "Skipped found git in: {0}", gitPath)); + logger.info(l10n.t('Skipped found git in: "{0}"', gitPath)); } return !skip; }); @@ -81,7 +78,7 @@ async function createModel(context: ExtensionContext, logger: LogOutputChannel, const terminalEnvironmentManager = new TerminalEnvironmentManager(context, [askpass, gitEditor, ipcServer]); disposables.push(terminalEnvironmentManager); - logger.info(localize('using git', "Using git {0} from {1}", info.version, info.path)); + logger.info(l10n.t('Using git "{0}" from "{1}"', info.version, info.path)); const git = new Git({ gitPath: info.path, @@ -159,10 +156,10 @@ async function warnAboutMissingGit(): Promise { return; } - const download = localize('downloadgit', "Download Git"); - const neverShowAgain = localize('neverShowAgain', "Don't Show Again"); + const download = l10n.t('Download Git'); + const neverShowAgain = l10n.t('Don\'t Show Again'); const choice = await window.showWarningMessage( - localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."), + l10n.t('Git not found. Install it or configure it using the "git.path" setting.'), download, neverShowAgain ); @@ -249,11 +246,11 @@ async function checkGitv1(info: IGit): Promise { return; } - const update = localize('updateGit', "Update Git"); - const neverShowAgain = localize('neverShowAgain', "Don't Show Again"); + const update = l10n.t('Update Git'); + const neverShowAgain = l10n.t('Don\'t Show Again'); const choice = await window.showWarningMessage( - localize('git20', "You seem to have git {0} installed. Code works best with git >= 2", info.version), + l10n.t('You seem to have git "{0}" installed. Code works best with git >= 2', info.version), update, neverShowAgain ); @@ -277,10 +274,10 @@ async function checkGitWindows(info: IGit): Promise { return; } - const update = localize('updateGit', "Update Git"); - const neverShowAgain = localize('neverShowAgain', "Don't Show Again"); + const update = l10n.t('Update Git'); + const neverShowAgain = l10n.t('Don\'t Show Again'); const choice = await window.showWarningMessage( - localize('git2526', "There are known issues with the installed Git {0}. Please update to Git >= 2.27 for the git features to work correctly.", info.version), + l10n.t('There are known issues with the installed Git "{0}". Please update to Git >= 2.27 for the git features to work correctly.', info.version), update, neverShowAgain ); diff --git a/extensions/git/src/model.ts b/extensions/git/src/model.ts index f17c4f3484b..939d2ce97f6 100644 --- a/extensions/git/src/model.ts +++ b/extensions/git/src/model.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, commands, LogOutputChannel } from 'vscode'; +import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, commands, LogOutputChannel, l10n } from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; import { Operation, Repository, RepositoryState } from './repository'; import { memoize, sequentialize, debounce } from './decorators'; @@ -11,7 +11,6 @@ import { dispose, anyEvent, filterEvent, isDescendant, pathEquals, toDisposable, import { Git } from './git'; import * as path from 'path'; import * as fs from 'fs'; -import * as nls from 'vscode-nls'; import { fromGitUri } from './uri'; import { APIState as State, CredentialsProvider, PushErrorHandler, PublishEvent, RemoteSourcePublisher, PostCommitCommandsProvider } from './api/git'; import { Askpass } from './askpass'; @@ -20,8 +19,6 @@ import { ApiRepository } from './api/api1'; import { IRemoteSourcePublisherRegistry } from './remotePublisher'; import { IPostCommitCommandsProviderRegistry } from './postCommitCommands'; -const localize = nls.loadMessageBundle(); - class RepositoryPick implements QuickPickItem { @memoize get label(): string { return path.basename(this.repository.root); @@ -187,7 +184,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand } if (path.isAbsolute(scanPath)) { - const notSupportedMessage = localize('not supported', "Absolute paths not supported in 'git.scanRepositories' setting."); + const notSupportedMessage = l10n.t('Absolute paths not supported in "git.scanRepositories" setting.'); this.logger.warn(notSupportedMessage); console.warn(notSupportedMessage); continue; @@ -376,7 +373,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand if (!isRepoInWorkspaceFolders) { if (this.showRepoOnHomeDriveRootWarning) { - window.showWarningMessage(localize('repoOnHomeDriveRootWarning', "Unable to automatically open the git repository at '{0}'. To open that git repository, open it directly as a folder in VS Code.", repositoryRoot)); + window.showWarningMessage(l10n.t('Unable to automatically open the git repository at "{0}". To open that git repository, open it directly as a folder in VS Code.', repositoryRoot)); this.showRepoOnHomeDriveRootWarning = false; } @@ -439,7 +436,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand } if (repository.submodules.length > submodulesLimit) { - window.showWarningMessage(localize('too many submodules', "The '{0}' repository has {1} submodules which won't be opened automatically. You can still open each one individually by opening a file within.", path.basename(repository.root), repository.submodules.length)); + window.showWarningMessage(l10n.t('The "{0}" repository has {1} submodules which won\'t be opened automatically. You can still open each one individually by opening a file within.', path.basename(repository.root), repository.submodules.length)); statusListener.dispose(); } @@ -513,7 +510,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand async pickRepository(): Promise { if (this.openRepositories.length === 0) { - throw new Error(localize('no repositories', "There are no available repositories")); + throw new Error(l10n.t('There are no available repositories')); } const picks = this.openRepositories.map((e, index) => new RepositoryPick(e.repository, index)); @@ -526,7 +523,7 @@ export class Model implements IRemoteSourcePublisherRegistry, IPostCommitCommand picks.unshift(...picks.splice(index, 1)); } - const placeHolder = localize('pick repo', "Choose a repository"); + const placeHolder = l10n.t('Choose a repository'); const pick = await window.showQuickPick(picks, { placeHolder }); return pick && pick.repository; diff --git a/extensions/git/src/postCommitCommands.ts b/extensions/git/src/postCommitCommands.ts index a8f2dae794b..02ce108139c 100644 --- a/extensions/git/src/postCommitCommands.ts +++ b/extensions/git/src/postCommitCommands.ts @@ -3,8 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -import { Command, commands, Disposable, Event, EventEmitter, Memento, Uri, workspace } from 'vscode'; +import { Command, commands, Disposable, Event, EventEmitter, Memento, Uri, workspace, l10n } from 'vscode'; import { PostCommitCommandsProvider } from './api/git'; import { Operation, Repository } from './repository'; import { ApiRepository } from './api/api1'; @@ -17,8 +16,6 @@ export interface IPostCommitCommandsProviderRegistry { registerPostCommitCommandsProvider(provider: PostCommitCommandsProvider): Disposable; } -const localize = nls.loadMessageBundle(); - export class GitPostCommitCommandsProvider implements PostCommitCommandsProvider { getCommands(apiRepository: ApiRepository): Command[] { const config = workspace.getConfiguration('git', Uri.file(apiRepository.repository.root)); @@ -34,33 +31,33 @@ export class GitPostCommitCommandsProvider implements PostCommitCommandsProvider // Tooltip (default) let pushCommandTooltip = !alwaysCommitToNewBranch ? - localize('scm button commit and push tooltip', "Commit & Push Changes") : - localize('scm button commit to new branch and push tooltip', "Commit to New Branch & Push Changes"); + l10n.t('Commit & Push Changes') : + l10n.t('Commit to New Branch & Push Changes'); let syncCommandTooltip = !alwaysCommitToNewBranch ? - localize('scm button commit and sync tooltip', "Commit & Sync Changes") : - localize('scm button commit to new branch and sync tooltip', "Commit to New Branch & Synchronize Changes"); + l10n.t('Commit & Sync Changes') : + l10n.t('Commit to New Branch & Synchronize Changes'); // Tooltip (in progress) if (apiRepository.repository.operations.isRunning(Operation.Commit)) { pushCommandTooltip = !alwaysCommitToNewBranch ? - localize('scm button committing and pushing tooltip', "Committing & Pushing Changes...") : - localize('scm button committing to new branch and pushing tooltip', "Committing to New Branch & Pushing Changes..."); + l10n.t('Committing & Pushing Changes...') : + l10n.t('Committing to New Branch & Pushing Changes...'); syncCommandTooltip = !alwaysCommitToNewBranch ? - localize('scm button committing and syncing tooltip', "Committing & Synchronizing Changes...") : - localize('scm button committing to new branch and syncing tooltip', "Committing to New Branch & Synchronizing Changes..."); + l10n.t('Committing & Synchronizing Changes...') : + l10n.t('Committing to New Branch & Synchronizing Changes...'); } return [ { command: 'git.push', - title: localize('scm button commit and push title', "{0} Commit & Push", icon ?? '$(arrow-up)'), + title: l10n.t('{0} Commit & Push', icon ?? '$(arrow-up)'), tooltip: pushCommandTooltip }, { command: 'git.sync', - title: localize('scm button commit and sync title', "{0} Commit & Sync", icon ?? '$(sync)'), + title: l10n.t('{0} Commit & Sync', icon ?? '$(sync)'), tooltip: syncCommandTooltip }, ]; @@ -151,17 +148,17 @@ export class CommitCommandsCenter { // Tooltip (default) let tooltip = !alwaysCommitToNewBranch ? - localize('scm button commit tooltip', "Commit Changes") : - localize('scm button commit to new branch tooltip', "Commit Changes to New Branch"); + l10n.t('Commit Changes') : + l10n.t('Commit Changes to New Branch'); // Tooltip (in progress) if (this.repository.operations.isRunning(Operation.Commit)) { tooltip = !alwaysCommitToNewBranch ? - localize('scm button committing tooltip', "Committing Changes...") : - localize('scm button committing to new branch tooltip', "Committing Changes to New Branch..."); + l10n.t('Committing Changes...') : + l10n.t('Committing Changes to New Branch...'); } - return { command: 'git.commit', title: localize('scm button commit title', "{0} Commit", icon ?? '$(check)'), tooltip, arguments: [this.repository.sourceControl, ''] }; + return { command: 'git.commit', title: l10n.t('{0} Commit', icon ?? '$(check)'), tooltip, arguments: [this.repository.sourceControl, ''] }; } private getPostCommitCommandStringFromSetting(): string | undefined { diff --git a/extensions/git/src/protocolHandler.ts b/extensions/git/src/protocolHandler.ts index 950327b12f8..00f58173014 100644 --- a/extensions/git/src/protocolHandler.ts +++ b/extensions/git/src/protocolHandler.ts @@ -3,10 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -const localize = nls.loadMessageBundle(); - -import { UriHandler, Uri, window, Disposable, commands, LogOutputChannel } from 'vscode'; +import { UriHandler, Uri, window, Disposable, commands, LogOutputChannel, l10n } from 'vscode'; import { dispose } from './util'; import * as querystring from 'querystring'; @@ -76,8 +73,8 @@ export class GitProtocolHandler implements UriHandler { if (!(await commands.getCommands(true)).includes('git.clone')) { this.logger.error('Could not complete git clone operation as git installation was not found.'); - const errorMessage = localize('no git', 'Could not clone your repository as Git is not installed.'); - const downloadGit = localize('download git', 'Download Git'); + const errorMessage = l10n.t('Could not clone your repository as Git is not installed.'); + const downloadGit = l10n.t('Download Git'); if (await window.showErrorMessage(errorMessage, { modal: true }, downloadGit) === downloadGit) { commands.executeCommand('vscode.open', Uri.parse('https://aka.ms/vscode-download-git')); diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index 45ccebf7dee..08d538ecc74 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -6,9 +6,8 @@ import * as fs from 'fs'; import * as path from 'path'; import * as picomatch from 'picomatch'; -import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern, CancellationTokenSource, LogOutputChannel, LogLevel, CancellationError } from 'vscode'; +import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, Tab, TabInputTextDiff, TabInputNotebookDiff, RelativePattern, CancellationTokenSource, LogOutputChannel, LogLevel, CancellationError, l10n } from 'vscode'; import TelemetryReporter from '@vscode/extension-telemetry'; -import * as nls from 'vscode-nls'; import { Branch, Change, ForcePushMode, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions, BranchQuery, FetchOptions } from './api/git'; import { AutoFetcher } from './autofetch'; import { debounce, memoize, throttle } from './decorators'; @@ -25,7 +24,6 @@ import { IPostCommitCommandsProviderRegistry, CommitCommandsCenter } from './pos const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); -const localize = nls.loadMessageBundle(); const iconsRootPath = path.join(path.dirname(__dirname), 'resources', 'icons'); function getIconUri(iconName: string, theme: string): Uri { @@ -48,23 +46,23 @@ export class Resource implements SourceControlResourceState { static getStatusText(type: Status) { switch (type) { - case Status.INDEX_MODIFIED: return localize('index modified', "Index Modified"); - case Status.MODIFIED: return localize('modified', "Modified"); - case Status.INDEX_ADDED: return localize('index added', "Index Added"); - case Status.INDEX_DELETED: return localize('index deleted', "Index Deleted"); - case Status.DELETED: return localize('deleted', "Deleted"); - case Status.INDEX_RENAMED: return localize('index renamed', "Index Renamed"); - case Status.INDEX_COPIED: return localize('index copied', "Index Copied"); - case Status.UNTRACKED: return localize('untracked', "Untracked"); - case Status.IGNORED: return localize('ignored', "Ignored"); - case Status.INTENT_TO_ADD: return localize('intent to add', "Intent to Add"); - case Status.BOTH_DELETED: return localize('both deleted', "Conflict: Both Deleted"); - case Status.ADDED_BY_US: return localize('added by us', "Conflict: Added By Us"); - case Status.DELETED_BY_THEM: return localize('deleted by them', "Conflict: Deleted By Them"); - case Status.ADDED_BY_THEM: return localize('added by them', "Conflict: Added By Them"); - case Status.DELETED_BY_US: return localize('deleted by us', "Conflict: Deleted By Us"); - case Status.BOTH_ADDED: return localize('both added', "Conflict: Both Added"); - case Status.BOTH_MODIFIED: return localize('both modified', "Conflict: Both Modified"); + case Status.INDEX_MODIFIED: return l10n.t('Index Modified'); + case Status.MODIFIED: return l10n.t('Modified'); + case Status.INDEX_ADDED: return l10n.t('Index Added'); + case Status.INDEX_DELETED: return l10n.t('Index Deleted'); + case Status.DELETED: return l10n.t('Deleted'); + case Status.INDEX_RENAMED: return l10n.t('Index Renamed'); + case Status.INDEX_COPIED: return l10n.t('Index Copied'); + case Status.UNTRACKED: return l10n.t('Untracked'); + case Status.IGNORED: return l10n.t('Ignored'); + case Status.INTENT_TO_ADD: return l10n.t('Intent to Add'); + case Status.BOTH_DELETED: return l10n.t('Conflict: Both Deleted'); + case Status.ADDED_BY_US: return l10n.t('Conflict: Added By Us'); + case Status.DELETED_BY_THEM: return l10n.t('Conflict: Deleted By Them'); + case Status.ADDED_BY_THEM: return l10n.t('Conflict: Added By Them'); + case Status.DELETED_BY_US: return l10n.t('Conflict: Deleted By Us'); + case Status.BOTH_ADDED: return l10n.t('Conflict: Both Added'); + case Status.BOTH_MODIFIED: return l10n.t('Conflict: Both Modified'); default: return ''; } } @@ -529,7 +527,7 @@ class FileEventLogger { private onDidChangeLogLevel(logLevel: LogLevel): void { this.eventDisposable.dispose(); - this.logger.appendLine(localize('logLevel', "Log level: {0}", LogLevel[logLevel])); + this.logger.appendLine(l10n.t('Log level: {0}', LogLevel[logLevel])); if (logLevel > LogLevel.Debug) { return; @@ -612,7 +610,7 @@ class ResourceCommandResolver { resolveFileCommand(resource: Resource): Command { return { command: 'vscode.open', - title: localize('open', "Open"), + title: l10n.t('Open'), arguments: [resource.resourceUri] }; } @@ -625,20 +623,20 @@ class ResourceCommandResolver { if (resource.rightUri && workspace.getConfiguration('git').get('mergeEditor', false) && (bothModified || resource.type === Status.BOTH_ADDED)) { return { command: 'git.openMergeEditor', - title: localize('open.merge', "Open Merge"), + title: l10n.t('Open Merge'), arguments: [resource.rightUri] }; } else { return { command: 'vscode.open', - title: localize('open', "Open"), + title: l10n.t('Open'), arguments: [resource.rightUri, { override: bothModified ? false : undefined }, title] }; } } else { return { command: 'vscode.diff', - title: localize('open', "Open"), + title: l10n.t('Open'), arguments: [resource.leftUri, resource.rightUri, title] }; } @@ -718,25 +716,25 @@ class ResourceCommandResolver { case Status.INDEX_MODIFIED: case Status.INDEX_RENAMED: case Status.INDEX_ADDED: - return localize('git.title.index', '{0} (Index)', basename); + return l10n.t('{0} (Index)', basename); case Status.MODIFIED: case Status.BOTH_ADDED: case Status.BOTH_MODIFIED: - return localize('git.title.workingTree', '{0} (Working Tree)', basename); + return l10n.t('{0} (Working Tree)', basename); case Status.INDEX_DELETED: case Status.DELETED: - return localize('git.title.deleted', '{0} (Deleted)', basename); + return l10n.t('{0} (Deleted)', basename); case Status.DELETED_BY_US: - return localize('git.title.theirs', '{0} (Theirs)', basename); + return l10n.t('{0} (Theirs)', basename); case Status.DELETED_BY_THEM: - return localize('git.title.ours', '{0} (Ours)', basename); + return l10n.t('{0} (Ours)', basename); case Status.UNTRACKED: - return localize('git.title.untracked', '{0} (Untracked)', basename); + return l10n.t('{0} (Untracked)', basename); default: return ''; @@ -940,7 +938,7 @@ export class Repository implements Disposable { const root = Uri.file(repository.root); this._sourceControl = scm.createSourceControl('git', 'Git', root); - this._sourceControl.acceptInputCommand = { command: 'git.commit', title: localize('commit', "Commit"), arguments: [this._sourceControl] }; + this._sourceControl.acceptInputCommand = { command: 'git.commit', title: l10n.t('Commit'), arguments: [this._sourceControl] }; this._sourceControl.quickDiffProvider = this; this._sourceControl.inputBox.validateInput = this.validateInput.bind(this); this.disposables.push(this._sourceControl); @@ -948,10 +946,10 @@ export class Repository implements Disposable { this.updateInputBoxPlaceholder(); this.disposables.push(this.onDidRunGitStatus(() => this.updateInputBoxPlaceholder())); - this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes")); - this._indexGroup = this._sourceControl.createResourceGroup('index', localize('staged changes', "Staged Changes")); - this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', localize('changes', "Changes")); - this._untrackedGroup = this._sourceControl.createResourceGroup('untracked', localize('untracked changes', "Untracked Changes")); + this._mergeGroup = this._sourceControl.createResourceGroup('merge', l10n.t('Merge Changes')); + this._indexGroup = this._sourceControl.createResourceGroup('index', l10n.t('Staged Changes')); + this._workingTreeGroup = this._sourceControl.createResourceGroup('workingTree', l10n.t('Changes')); + this._untrackedGroup = this._sourceControl.createResourceGroup('untracked', l10n.t('Untracked Changes')); const updateIndexGroupVisibility = () => { const config = workspace.getConfiguration('git', root); @@ -1011,7 +1009,7 @@ export class Repository implements Disposable { const gitConfig = workspace.getConfiguration('git'); if (gitConfig.get('showPushSuccessNotification')) { - window.showInformationMessage(localize('push success', "Successfully pushed.")); + window.showInformationMessage(l10n.t('Successfully pushed.')); } }, null, this.disposables); @@ -1044,7 +1042,7 @@ export class Repository implements Disposable { let tooManyChangesWarning: SourceControlInputBoxValidation | undefined; if (this.isRepositoryHuge) { tooManyChangesWarning = { - message: localize('tooManyChangesWarning', "Too many changes were detected. Only the first {0} changes will be shown below.", this.isRepositoryHuge.limit), + message: l10n.t('Too many changes were detected. Only the first {0} changes will be shown below.', this.isRepositoryHuge.limit), type: SourceControlInputBoxValidationType.Warning }; } @@ -1052,7 +1050,7 @@ export class Repository implements Disposable { if (this.rebaseCommit) { if (this.rebaseCommit.message !== text) { return { - message: localize('commit in rebase', "It's not possible to change the commit message in the middle of a rebase. Please complete the rebase operation and use interactive rebase instead."), + message: l10n.t('It\'s not possible to change the commit message in the middle of a rebase. Please complete the rebase operation and use interactive rebase instead.'), type: SourceControlInputBoxValidationType.Warning }; } @@ -1067,7 +1065,7 @@ export class Repository implements Disposable { if (/^\s+$/.test(text)) { return { - message: localize('commitMessageWhitespacesOnlyWarning', "Current commit message only contains whitespace characters"), + message: l10n.t('Current commit message only contains whitespace characters'), type: SourceControlInputBoxValidationType.Warning }; } @@ -1102,12 +1100,12 @@ export class Repository implements Disposable { } return { - message: localize('commitMessageCountdown', "{0} characters left in current line", threshold - line.length), + message: l10n.t('{0} characters left in current line', threshold - line.length), type: SourceControlInputBoxValidationType.Information }; } else { return { - message: localize('commitMessageWarning', "{0} characters over {1} in current line", line.length - threshold, threshold), + message: l10n.t('{0} characters over {1} in current line', line.length - threshold, threshold), type: SourceControlInputBoxValidationType.Warning }; } @@ -1606,7 +1604,7 @@ export class Repository implements Disposable { if (supportCancellation) { const opts: ProgressOptions = { location: ProgressLocation.Notification, - title: localize('sync is unpredictable', "Syncing. Cancelling may cause serious damages to the repository"), + title: l10n.t('Syncing. Cancelling may cause serious damages to the repository'), cancellable: true }; @@ -1655,13 +1653,13 @@ export class Repository implements Disposable { return true; } - const always = { title: localize('always pull', "Always Pull") }; - const pull = { title: localize('pull', "Pull") }; - const cancel = { title: localize('dont pull', "Don't Pull") }; + const always = { title: l10n.t('Always Pull') }; + const pull = { title: l10n.t('Pull') }; + const cancel = { title: l10n.t('Don\'t Pull') }; const result = await window.showWarningMessage( currentBranch - ? localize('pull branch maybe rebased', "It looks like the current branch \'{0}\' might have been rebased. Are you sure you still want to pull into it?", currentBranch) - : localize('pull maybe rebased', "It looks like the current branch might have been rebased. Are you sure you still want to pull into it?"), + ? l10n.t('It looks like the current branch "{0}" might have been rebased. Are you sure you still want to pull into it?', currentBranch) + : l10n.t('It looks like the current branch might have been rebased. Are you sure you still want to pull into it?'), always, pull, cancel ); @@ -2054,16 +2052,16 @@ export class Repository implements Disposable { if (didHitLimit && !shouldIgnore && !this.didWarnAboutLimit) { const knownHugeFolderPaths = await this.findKnownHugeFolderPathsToIgnore(); - const gitWarn = localize('huge', "The git repository at '{0}' has too many active changes, only a subset of Git features will be enabled.", this.repository.root); - const neverAgain = { title: localize('neveragain', "Don't Show Again") }; + const gitWarn = l10n.t('The git repository at "{0}" has too many active changes, only a subset of Git features will be enabled.', this.repository.root); + const neverAgain = { title: l10n.t('Don\'t Show Again') }; if (knownHugeFolderPaths.length > 0) { const folderPath = knownHugeFolderPaths[0]; const folderName = path.basename(folderPath); - const addKnown = localize('add known', "Would you like to add '{0}' to .gitignore?", folderName); - const yes = { title: localize('yes', "Yes") }; - const no = { title: localize('no', "No") }; + const addKnown = l10n.t('Would you like to add "{0}" to .gitignore?', folderName); + const yes = { title: l10n.t('Yes') }; + const no = { title: l10n.t('No') }; const result = await window.showWarningMessage(`${gitWarn} ${addKnown}`, yes, no, neverAgain); if (result === yes) { @@ -2076,7 +2074,7 @@ export class Repository implements Disposable { this.didWarnAboutLimit = true; } } else { - const ok = { title: localize('ok', "OK") }; + const ok = { title: l10n.t('OK') }; const result = await window.showWarningMessage(gitWarn, ok, neverAgain); if (result === neverAgain) { config.update('ignoreLimitWarning', true, false); @@ -2297,18 +2295,18 @@ export class Repository implements Disposable { || !this.HEAD.upstream || !(this.HEAD.ahead || this.HEAD.behind) ) { - return localize('sync changes', "Synchronize Changes"); + return l10n.t('Synchronize Changes'); } const remoteName = this.HEAD && this.HEAD.remote || this.HEAD.upstream.remote; const remote = this.remotes.find(r => r.name === remoteName); if ((remote && remote.isReadOnly) || !this.HEAD.ahead) { - return localize('pull n', "Pull {0} commits from {1}/{2}", this.HEAD.behind, this.HEAD.upstream.remote, this.HEAD.upstream.name); + return l10n.t('Pull {0} commits from {1}/{2}', this.HEAD.behind!, this.HEAD.upstream.remote, this.HEAD.upstream.name); } else if (!this.HEAD.behind) { - return localize('push n', "Push {0} commits to {1}/{2}", this.HEAD.ahead, this.HEAD.upstream.remote, this.HEAD.upstream.name); + return l10n.t('Push {0} commits to {1}/{2}', this.HEAD.ahead, this.HEAD.upstream.remote, this.HEAD.upstream.name); } else { - return localize('pull push n', "Pull {0} and push {1} commits between {2}/{3}", this.HEAD.behind, this.HEAD.ahead, this.HEAD.upstream.remote, this.HEAD.upstream.name); + return l10n.t('Pull {0} and push {1} commits between {2}/{3}', this.HEAD.behind, this.HEAD.ahead, this.HEAD.upstream.remote, this.HEAD.upstream.name); } } @@ -2317,9 +2315,9 @@ export class Repository implements Disposable { if (branchName) { // '{0}' will be replaced by the corresponding key-command later in the process, which is why it needs to stay. - this._sourceControl.inputBox.placeholder = localize('commitMessageWithHeadLabel', "Message ({0} to commit on '{1}')", '{0}', branchName); + this._sourceControl.inputBox.placeholder = l10n.t('Message ({0} to commit on "{1}")', '{0}', branchName); } else { - this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message ({0} to commit)"); + this._sourceControl.inputBox.placeholder = l10n.t('Message ({0} to commit)'); } } diff --git a/extensions/git/src/statusbar.ts b/extensions/git/src/statusbar.ts index e24306ff800..7a21b78a28a 100644 --- a/extensions/git/src/statusbar.ts +++ b/extensions/git/src/statusbar.ts @@ -3,15 +3,12 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Disposable, Command, EventEmitter, Event, workspace, Uri } from 'vscode'; +import { Disposable, Command, EventEmitter, Event, workspace, Uri, l10n } from 'vscode'; import { Repository, Operation } from './repository'; import { anyEvent, dispose, filterEvent } from './util'; -import * as nls from 'vscode-nls'; import { Branch, RemoteSourcePublisher } from './api/git'; import { IRemoteSourcePublisherRegistry } from './remotePublisher'; -const localize = nls.loadMessageBundle(); - class CheckoutStatusBar { private _onDidChange = new EventEmitter(); @@ -25,11 +22,11 @@ class CheckoutStatusBar { get command(): Command | undefined { const rebasing = !!this.repository.rebaseCommit; const isBranchProtected = this.repository.isBranchProtected(); - const label = `${this.repository.headLabel}${rebasing ? ` (${localize('rebasing', 'Rebasing')})` : ''}`; + const label = `${this.repository.headLabel}${rebasing ? ` (${l10n.t('Rebasing')})` : ''}`; return { command: 'git.checkout', - tooltip: localize('checkout', "{0}, Checkout branch/tag...", label), + tooltip: l10n.t('{0}, Checkout branch/tag...', label), title: `${isBranchProtected ? '$(lock)' : '$(git-branch)'} ${label}`, arguments: [this.repository.sourceControl] }; @@ -122,8 +119,8 @@ class SyncStatusBar { } const tooltip = this.state.remoteSourcePublishers.length === 1 - ? localize('publish to', "Publish to {0}", this.state.remoteSourcePublishers[0].name) - : localize('publish to...', "Publish to..."); + ? l10n.t('Publish to {0}', this.state.remoteSourcePublishers[0].name) + : l10n.t('Publish to...'); return { command: 'git.publish', @@ -150,7 +147,7 @@ class SyncStatusBar { } else { icon = '$(cloud-upload)'; command = 'git.publish'; - tooltip = localize('publish branch', "Publish Branch"); + tooltip = l10n.t('Publish Branch'); } } else { command = ''; @@ -160,7 +157,7 @@ class SyncStatusBar { if (this.state.isSyncRunning) { icon = '$(sync~spin)'; command = ''; - tooltip = localize('syncing changes', "Synchronizing Changes..."); + tooltip = l10n.t('Synchronizing Changes...'); } return { diff --git a/extensions/git/src/timelineProvider.ts b/extensions/git/src/timelineProvider.ts index 0c86f37214b..8d70c26df75 100644 --- a/extensions/git/src/timelineProvider.ts +++ b/extensions/git/src/timelineProvider.ts @@ -3,16 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import * as nls from 'vscode-nls'; -import { CancellationToken, ConfigurationChangeEvent, Disposable, env, Event, EventEmitter, MarkdownString, ThemeIcon, Timeline, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvider, Uri, workspace } from 'vscode'; +import { CancellationToken, ConfigurationChangeEvent, Disposable, env, Event, EventEmitter, MarkdownString, ThemeIcon, Timeline, TimelineChangeEvent, TimelineItem, TimelineOptions, TimelineProvider, Uri, workspace, l10n } from 'vscode'; import { Model } from './model'; import { Repository, Resource } from './repository'; import { debounce } from './decorators'; import { emojify, ensureEmojis } from './emoji'; import { CommandCenter } from './commands'; -const localize = nls.loadMessageBundle(); - export class GitTimelineItem extends TimelineItem { static is(item: TimelineItem): item is GitTimelineItem { return item instanceof GitTimelineItem; @@ -54,7 +51,7 @@ export class GitTimelineItem extends TimelineItem { this.tooltip = new MarkdownString('', true); if (email) { - const emailTitle = localize('git.timeline.email', "Email"); + const emailTitle = l10n.t('Email'); this.tooltip.appendMarkdown(`$(account) [**${author}**](mailto:${email} "${emailTitle} ${author}")\n\n`); } else { this.tooltip.appendMarkdown(`$(account) **${author}**\n\n`); @@ -79,7 +76,7 @@ export class GitTimelineProvider implements TimelineProvider { } readonly id = 'git-history'; - readonly label = localize('git.timeline.source', 'Git History'); + readonly label = l10n.t('Git History'); private readonly disposable: Disposable; private providerDisposable: Disposable | undefined; @@ -171,7 +168,7 @@ export class GitTimelineProvider implements TimelineProvider { const showAuthor = config.get('showAuthor'); const showUncommitted = config.get('showUncommitted'); - const openComparison = localize('git.timeline.openComparison', "Open Comparison"); + const openComparison = l10n.t('Open Comparison'); const items = commits.map((c, i) => { const date = dateType === 'authored' ? c.authorDate : c.commitDate; @@ -199,13 +196,13 @@ export class GitTimelineProvider implements TimelineProvider { }); if (options.cursor === undefined) { - const you = localize('git.timeline.you', 'You'); + const you = l10n.t('You'); const index = repo.indexGroup.resourceStates.find(r => r.resourceUri.fsPath === uri.fsPath); if (index) { const date = this.repoStatusDate ?? new Date(); - const item = new GitTimelineItem('~', 'HEAD', localize('git.timeline.stagedChanges', 'Staged Changes'), date.getTime(), 'index', 'git:file:index'); + const item = new GitTimelineItem('~', 'HEAD', l10n.t('Staged Changes'), date.getTime(), 'index', 'git:file:index'); // TODO@eamodio: Replace with a better icon -- reflecting its status maybe? item.iconPath = new ThemeIcon('git-commit'); item.description = ''; @@ -228,7 +225,7 @@ export class GitTimelineProvider implements TimelineProvider { if (working) { const date = new Date(); - const item = new GitTimelineItem('', index ? '~' : 'HEAD', localize('git.timeline.uncommitedChanges', 'Uncommitted Changes'), date.getTime(), 'working', 'git:file:working'); + const item = new GitTimelineItem('', index ? '~' : 'HEAD', l10n.t('Uncommitted Changes'), date.getTime(), 'working', 'git:file:working'); item.iconPath = new ThemeIcon('circle-outline'); item.description = ''; item.setItemDetails(you, undefined, dateFormatter.format(date), Resource.getStatusText(working.type)); diff --git a/extensions/git/yarn.lock b/extensions/git/yarn.lock index b5a79f3f238..63b9df35755 100644 --- a/extensions/git/yarn.lock +++ b/extensions/git/yarn.lock @@ -186,11 +186,6 @@ util-deprecate@^1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -vscode-nls@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f" - integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng== - vscode-uri@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.0.tgz#2df704222f72b8a71ff266ba0830ed6c51ac1542" diff --git a/extensions/github/package.json b/extensions/github/package.json index a262e352a11..bdd04a2e4c8 100644 --- a/extensions/github/package.json +++ b/extensions/github/package.json @@ -134,8 +134,7 @@ }, "dependencies": { "@octokit/rest": "19.0.4", - "tunnel": "^0.0.6", - "vscode-nls": "^5.2.0" + "tunnel": "^0.0.6" }, "devDependencies": { "@types/node": "16.x" diff --git a/extensions/github/src/publish.ts b/extensions/github/src/publish.ts index 494da523b1b..3f24b1061cc 100644 --- a/extensions/github/src/publish.ts +++ b/extensions/github/src/publish.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import * as nls from 'vscode-nls'; import { API as GitAPI, Repository } from './typings/git'; import { getOctokit } from './auth'; import { TextEncoder } from 'util'; @@ -12,8 +11,6 @@ import { basename } from 'path'; import { Octokit } from '@octokit/rest'; import { isInCodespaces } from './pushErrorHandler'; -const localize = nls.loadMessageBundle(); - function sanitizeRepositoryName(value: string): string { return value.trim().replace(/[^a-z0-9_.]/ig, '-'); } @@ -41,7 +38,7 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository) folder = vscode.workspace.workspaceFolders[0].uri; } else { const picks = vscode.workspace.workspaceFolders.map(folder => ({ label: folder.name, folder })); - const placeHolder = localize('pick folder', "Pick a folder to publish to GitHub"); + const placeHolder = vscode.l10n.t('Pick a folder to publish to GitHub'); const pick = await vscode.window.showQuickPick(picks, { placeHolder }); if (!pick) { @@ -130,7 +127,7 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository) if (shouldGenerateGitignore) { quickpick = vscode.window.createQuickPick(); - quickpick.placeholder = localize('ignore', "Select which files should be included in the repository."); + quickpick.placeholder = vscode.l10n.t('Select which files should be included in the repository.'); quickpick.canSelectMany = true; quickpick.show(); @@ -171,8 +168,8 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository) const githubRepository = await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, cancellable: false, title: 'Publish to GitHub' }, async progress => { progress.report({ message: isPrivate - ? localize('publishing_private', "Publishing to a private GitHub repository") - : localize('publishing_public', "Publishing to a public GitHub repository"), + ? vscode.l10n.t('Publishing to a private GitHub repository') + : vscode.l10n.t('Publishing to a public GitHub repository'), increment: 25 }); @@ -190,7 +187,7 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository) } if (createdGithubRepository) { - progress.report({ message: localize('publishing_firstcommit', "Creating first commit"), increment: 25 }); + progress.report({ message: vscode.l10n.t('Creating first commit'), increment: 25 }); if (!repository) { repository = await gitAPI.init(folder) || undefined; @@ -202,7 +199,7 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository) await repository.commit('first commit', { all: true, postCommitCommand: null }); } - progress.report({ message: localize('publishing_uploading', "Uploading files"), increment: 25 }); + progress.report({ message: vscode.l10n.t('Uploading files'), increment: 25 }); const branch = await repository.getBranch('HEAD'); const protocol = vscode.workspace.getConfiguration('github').get<'https' | 'ssh'>('gitProtocol'); @@ -218,8 +215,8 @@ export async function publishRepository(gitAPI: GitAPI, repository?: Repository) return; } - const openOnGitHub = localize('openingithub', "Open on GitHub"); - vscode.window.showInformationMessage(localize('publishing_done', "Successfully published the '{0}' repository to GitHub.", `${owner}/${repo}`), openOnGitHub).then(action => { + const openOnGitHub = vscode.l10n.t('Open on GitHub'); + vscode.window.showInformationMessage(vscode.l10n.t('Successfully published the "{0}" repository to GitHub.', `${owner}/${repo}`), openOnGitHub).then(action => { if (action === openOnGitHub) { vscode.commands.executeCommand('vscode.open', vscode.Uri.parse(githubRepository.html_url)); } diff --git a/extensions/github/src/pushErrorHandler.ts b/extensions/github/src/pushErrorHandler.ts index f054df8941d..c337fc5960a 100644 --- a/extensions/github/src/pushErrorHandler.ts +++ b/extensions/github/src/pushErrorHandler.ts @@ -4,14 +4,11 @@ *--------------------------------------------------------------------------------------------*/ import { TextDecoder } from 'util'; -import { commands, env, ProgressLocation, Uri, window, workspace, QuickPickOptions, FileType } from 'vscode'; -import * as nls from 'vscode-nls'; +import { commands, env, ProgressLocation, Uri, window, workspace, QuickPickOptions, FileType, l10n } from 'vscode'; import { getOctokit } from './auth'; import { GitErrorCodes, PushErrorHandler, Remote, Repository } from './typings/git'; import path = require('path'); -const localize = nls.loadMessageBundle(); - type Awaited = T extends PromiseLike ? Awaited : T; export function isInCodespaces(): boolean { @@ -19,9 +16,9 @@ export function isInCodespaces(): boolean { } async function handlePushError(repository: Repository, remote: Remote, refspec: string, owner: string, repo: string): Promise { - const yes = localize('create a fork', "Create Fork"); - const no = localize('no', "No"); - const askFork = localize('fork', "You don't have permissions to push to '{0}/{1}' on GitHub. Would you like to create a fork and push to it instead?", owner, repo); + const yes = l10n.t('Create Fork'); + const no = l10n.t('No'); + const askFork = l10n.t('You don\'t have permissions to push to "{0}/{1}" on GitHub.Would you like to create a fork and push to it instead?', owner, repo); const answer = await window.showInformationMessage(askFork, yes, no); if (answer !== yes) { @@ -32,8 +29,8 @@ async function handlePushError(repository: Repository, remote: Remote, refspec: const localName = match ? match[1] : refspec; let remoteName = match ? match[2] : refspec; - const [octokit, ghRepository] = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: localize('create fork', 'Create GitHub fork') }, async progress => { - progress.report({ message: localize('forking', "Forking '{0}/{1}'...", owner, repo), increment: 33 }); + const [octokit, ghRepository] = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: l10n.t('Create GitHub fork') }, async progress => { + progress.report({ message: l10n.t('Forking "{0}/{1}"...', owner, repo), increment: 33 }); const octokit = await getOctokit(); @@ -68,7 +65,7 @@ async function handlePushError(repository: Repository, remote: Remote, refspec: throw ex; } - progress.report({ message: localize('forking_pushing', "Pushing changes..."), increment: 33 }); + progress.report({ message: l10n.t('Pushing changes...'), increment: 33 }); // Issue: what if there's already an `upstream` repo? await repository.renameRemote(remote.name, 'upstream'); @@ -92,14 +89,14 @@ async function handlePushError(repository: Repository, remote: Remote, refspec: // yield (async () => { - const openOnGitHub = localize('openingithub', "Open on GitHub"); - const createPR = localize('createpr', "Create PR"); - const action = await window.showInformationMessage(localize('forking_done', "The fork '{0}' was successfully created on GitHub.", ghRepository.full_name), openOnGitHub, createPR); + const openOnGitHub = l10n.t('Open on GitHub'); + const createPR = l10n.t('Create PR'); + const action = await window.showInformationMessage(l10n.t('The fork "{0}" was successfully created on GitHub.', ghRepository.full_name), openOnGitHub, createPR); if (action === openOnGitHub) { await commands.executeCommand('vscode.open', Uri.parse(ghRepository.html_url)); } else if (action === createPR) { - const pr = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: localize('createghpr', "Creating GitHub Pull Request...") }, async _ => { + const pr = await window.withProgress({ location: ProgressLocation.Notification, cancellable: false, title: l10n.t('Creating GitHub Pull Request...') }, async _ => { let title = `Update ${remoteName}`; const head = repository.state.HEAD?.name; @@ -138,8 +135,8 @@ async function handlePushError(repository: Repository, remote: Remote, refspec: return pr; }); - const openPR = localize('openpr', "Open PR"); - const action = await window.showInformationMessage(localize('donepr', "The PR '{0}/{1}#{2}' was successfully created on GitHub.", owner, repo, pr.number), openPR); + const openPR = l10n.t('Open PR'); + const action = await window.showInformationMessage(l10n.t('The PR "{0}/{1}#{2}" was successfully created on GitHub.', owner, repo, pr.number), openPR); if (action === openPR) { await commands.executeCommand('vscode.open', Uri.parse(pr.html_url)); @@ -196,14 +193,14 @@ export async function pickPullRequestTemplate(repositoryRootUri: Uri, templates: const quickPickItemFromUri = (x: Uri) => ({ label: path.relative(repositoryRootUri.path, x.path), template: x }); const quickPickItems = [ { - label: localize('no pr template', "No template"), + label: l10n.t('No template'), picked: true, template: undefined, }, ...templates.map(quickPickItemFromUri) ]; const quickPickOptions: QuickPickOptions = { - placeHolder: localize('select pr template', "Select the Pull Request template"), + placeHolder: l10n.t('Select the Pull Request template'), ignoreFocusOut: true }; const pickedTemplate = await window.showQuickPick(quickPickItems, quickPickOptions); diff --git a/extensions/github/yarn.lock b/extensions/github/yarn.lock index 8db5da00683..775f3c139d3 100644 --- a/extensions/github/yarn.lock +++ b/extensions/github/yarn.lock @@ -152,11 +152,6 @@ universal-user-agent@^6.0.0: resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== -vscode-nls@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f" - integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng== - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"