diff --git a/configs/errors.eslintrc.json b/configs/errors.eslintrc.json
index ede72d62b6dec..72706b3b22bc2 100644
--- a/configs/errors.eslintrc.json
+++ b/configs/errors.eslintrc.json
@@ -131,6 +131,7 @@
}
}
],
+ "@theia/localization-check": "error",
"@theia/no-src-import": "error",
"@theia/runtime-import-check": "error",
"@theia/shared-dependencies": "error",
diff --git a/dev-packages/private-eslint-plugin/README.md b/dev-packages/private-eslint-plugin/README.md
index 09232928c5fbe..cca75688e1af9 100644
--- a/dev-packages/private-eslint-plugin/README.md
+++ b/dev-packages/private-eslint-plugin/README.md
@@ -17,6 +17,12 @@ The plugin helps identify problems during development through static analysis in
## Rules
+### `localization-check`:
+
+The rule prevents the following localization related issues:
+- incorrect usage of the `nls.localizeByDefault` function by using an incorrect default value.
+- unnecessary call to `nls.localize` which could be replaced by `nls.localizeByDefault`.
+
### `no-src-import`:
The rule prevents imports using `/src/` rather than `/lib/` as it causes build failures.
diff --git a/dev-packages/private-eslint-plugin/index.js b/dev-packages/private-eslint-plugin/index.js
index 487bebf5930d0..0b1692a6777f0 100644
--- a/dev-packages/private-eslint-plugin/index.js
+++ b/dev-packages/private-eslint-plugin/index.js
@@ -17,6 +17,7 @@
/** @type {{[ruleId: string]: import('eslint').Rule.RuleModule}} */
exports.rules = {
+ "localization-check": require('./rules/localization-check'),
"no-src-import": require('./rules/no-src-import'),
"runtime-import-check": require('./rules/runtime-import-check'),
"shared-dependencies": require('./rules/shared-dependencies')
diff --git a/dev-packages/private-eslint-plugin/package.json b/dev-packages/private-eslint-plugin/package.json
index 66ddf05cc1c48..ac2a077bac027 100644
--- a/dev-packages/private-eslint-plugin/package.json
+++ b/dev-packages/private-eslint-plugin/package.json
@@ -10,6 +10,7 @@
"dependencies": {
"@theia/core": "1.22.1",
"@theia/ext-scripts": "1.22.1",
- "@theia/re-exports": "1.22.1"
+ "@theia/re-exports": "1.22.1",
+ "js-levenshtein": "^1.1.6"
}
}
diff --git a/dev-packages/private-eslint-plugin/rules/localization-check.js b/dev-packages/private-eslint-plugin/rules/localization-check.js
new file mode 100644
index 0000000000000..6decf1cc95276
--- /dev/null
+++ b/dev-packages/private-eslint-plugin/rules/localization-check.js
@@ -0,0 +1,109 @@
+// @ts-check
+/********************************************************************************
+ * Copyright (C) 2021 TypeFox and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the Eclipse
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
+ * with the GNU Classpath Exception which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ ********************************************************************************/
+
+const levenshtein = require('js-levenshtein');
+
+const metadata = require('@theia/core/src/common/i18n/nls.metadata.json');
+const messages = new Set(Object.values(metadata.messages)
+ .reduceRight((prev, curr) => prev.concat(curr), [])
+ .map(e => e.replace(/&&/g, '')));
+
+/** @type {import('eslint').Rule.RuleModule} */
+module.exports = {
+ meta: {
+ type: 'problem',
+ fixable: 'code',
+ docs: {
+ description: 'prevent incorrect use of \'nls.localize\'.',
+ },
+ },
+ create(context) {
+ return {
+ CallExpression(node) {
+ const callee = node.callee;
+ if (callee.type === 'Super') {
+ return;
+ }
+ const { value, byDefault, node: localizeNode } = evaluateLocalize(node);
+ if (value !== undefined) {
+ if (byDefault && !messages.has(value)) {
+ let lowestDistance = Number.MAX_VALUE;
+ let lowestMessage = '';
+ for (const message of messages) {
+ const distance = levenshtein(value, message);
+ if (distance < lowestDistance) {
+ lowestDistance = distance;
+ lowestMessage = message;
+ }
+ }
+ if (lowestMessage) {
+ context.report({
+ node: localizeNode,
+ message: `'${value}' is not a valid default value. Did you mean '${lowestMessage}'?`,
+ fix: function (fixer) {
+ const updatedCall = `'${lowestMessage.replace(/'/g, "\\'")}'`;
+ return fixer.replaceText(localizeNode, updatedCall);
+ }
+ });
+ } else {
+ context.report({
+ node: localizeNode,
+ message: `'${value}' is not a valid default value.`
+ });
+ }
+ } else if (!byDefault && messages.has(value)) {
+ context.report({
+ node,
+ message: `'${value}' can be translated using the 'nls.localizeByDefault' function.`,
+ fix: function (fixer) {
+ const code = context.getSourceCode();
+ const args = node.arguments.slice(1);
+ const argsCode = args.map(e => code.getText(e)).join(', ');
+ const updatedCall = `nls.localizeByDefault(${argsCode})`;
+ return fixer.replaceText(node, updatedCall);
+ }
+ });
+ }
+ }
+ }
+ };
+ function evaluateLocalize(/** @type {import('estree').CallExpression} */ node) {
+ const callee = node.callee;
+ if ('object' in callee && 'name' in callee.object && 'property' in callee && 'name' in callee.property && callee.object.name === 'nls') {
+ if (callee.property.name === 'localize') {
+ const defaultTextNode = node.arguments[1]; // The default text node is the second argument for `nls.localize`
+ if (defaultTextNode && defaultTextNode.type === 'Literal' && typeof defaultTextNode.value === 'string') {
+ return {
+ value: defaultTextNode.value,
+ byDefault: false
+ };
+ }
+ } else if (callee.property.name === 'localizeByDefault') {
+ const defaultTextNode = node.arguments[0]; // The default text node is the first argument for ``nls.localizeByDefault`
+ if (defaultTextNode && defaultTextNode.type === 'Literal' && typeof defaultTextNode.value === 'string') {
+ return {
+ node: defaultTextNode,
+ value: defaultTextNode.value,
+ byDefault: true
+ };
+ }
+ }
+ }
+ return {};
+ }
+ }
+};
diff --git a/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree-widget.tsx b/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree-widget.tsx
index 93a4f53434039..57cae3cc37a5a 100644
--- a/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree-widget.tsx
+++ b/packages/bulk-edit/src/browser/bulk-edit-tree/bulk-edit-tree-widget.tsx
@@ -95,7 +95,7 @@ export class BulkEditTreeWidget extends TreeWidget {
if (CompositeTreeNode.is(model.root) && model.root.children.length > 0) {
return super.renderTree(model);
}
- return
{nls.localizeByDefault('No edits have been detected in the workspace so far.')}
;
+ return {nls.localizeByDefault('Made no edits')}
;
}
protected renderCaption(node: TreeNode, props: NodeProps): React.ReactNode {
diff --git a/packages/core/src/browser/core-preferences.ts b/packages/core/src/browser/core-preferences.ts
index edb18d70405bf..ed3d1760f5e05 100644
--- a/packages/core/src/browser/core-preferences.ts
+++ b/packages/core/src/browser/core-preferences.ts
@@ -140,14 +140,19 @@ export const corePreferenceSchema: PreferenceSchema = {
default: 300,
minimum: 0,
maximum: 2000,
- description: nls.localizeByDefault('Controls the hover feedback delay in milliseconds of the dragging area in between views/editors.')
+ // nls-todo: Will be available with VSCode API 1.55
+ description: nls.localize('theia/core/sashDelay', 'Controls the hover feedback delay in milliseconds of the dragging area in between views/editors.')
},
'workbench.sash.size': {
type: 'number',
default: 4,
minimum: 1,
maximum: 20,
- description: nls.localizeByDefault('Controls the feedback area size in pixels of the dragging area in between views/editors. Set it to a larger value if needed.')
+ // nls-todo: Will be available with VSCode API 1.55
+ description: nls.localize(
+ 'theia/core/sashSize',
+ 'Controls the feedback area size in pixels of the dragging area in between views/editors. Set it to a larger value if needed.'
+ )
},
}
};
diff --git a/packages/core/src/browser/keyboard/browser-keyboard-frontend-contribution.ts b/packages/core/src/browser/keyboard/browser-keyboard-frontend-contribution.ts
index ccfd14bf67d1d..07ba75d004a8f 100644
--- a/packages/core/src/browser/keyboard/browser-keyboard-frontend-contribution.ts
+++ b/packages/core/src/browser/keyboard/browser-keyboard-frontend-contribution.ts
@@ -52,7 +52,7 @@ export class BrowserKeyboardFrontendContribution implements CommandContribution
protected async chooseLayout(): Promise {
const current = this.layoutProvider.currentLayoutData;
const autodetect: QuickPickValue<'autodetect'> = {
- label: nls.localizeByDefault('Auto-detect'),
+ label: nls.localizeByDefault('Auto Detect'),
description: this.layoutProvider.currentLayoutSource !== 'user-choice' ? nls.localize('theia/core/keyboard/current', '(current: {0})', current.name) : undefined,
detail: nls.localize('theia/core/keyboard/tryDetect', 'Try to detect the keyboard layout from browser information and pressed keys.'),
value: 'autodetect'
diff --git a/packages/core/src/electron-browser/menu/electron-menu-contribution.ts b/packages/core/src/electron-browser/menu/electron-menu-contribution.ts
index b7049fd2275b0..2a4539f305ec2 100644
--- a/packages/core/src/electron-browser/menu/electron-menu-contribution.ts
+++ b/packages/core/src/electron-browser/menu/electron-menu-contribution.ts
@@ -233,7 +233,7 @@ export class ElectronMenuContribution extends BrowserMenuBarContribution impleme
protected async handleRequiredRestart(): Promise {
const msgNode = document.createElement('div');
const message = document.createElement('p');
- message.textContent = nls.localizeByDefault('A setting has changed that requires a restart to take effect');
+ message.textContent = nls.localizeByDefault('A setting has changed that requires a restart to take effect.');
const detail = document.createElement('p');
detail.textContent = nls.localizeByDefault(
'Press the restart button to restart {0} and enable the setting.', FrontendApplicationConfigProvider.get().applicationName);
diff --git a/packages/core/src/electron-browser/window/electron-window-preferences.ts b/packages/core/src/electron-browser/window/electron-window-preferences.ts
index ddb742fd3b6df..a975898e1860d 100644
--- a/packages/core/src/electron-browser/window/electron-window-preferences.ts
+++ b/packages/core/src/electron-browser/window/electron-window-preferences.ts
@@ -38,7 +38,7 @@ export const electronWindowPreferencesSchema: PreferenceSchema = {
'maximum': ZoomLevel.MAX,
'scope': 'application',
// eslint-disable-next-line max-len
- 'description': nls.localizeByDefault('Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1.0) or below (e.g. -1.0) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.')
+ 'description': nls.localizeByDefault('Adjust the zoom level of the window. The original size is 0 and each increment above (e.g. 1) or below (e.g. -1) represents zooming 20% larger or smaller. You can also enter decimals to adjust the zoom level with a finer granularity.')
},
'window.titleBarStyle': {
type: 'string',
diff --git a/packages/debug/src/node/vscode/vscode-debug-adapter-contribution.ts b/packages/debug/src/node/vscode/vscode-debug-adapter-contribution.ts
index 19a08b26558ee..adb7435fd19b6 100644
--- a/packages/debug/src/node/vscode/vscode-debug-adapter-contribution.ts
+++ b/packages/debug/src/node/vscode/vscode-debug-adapter-contribution.ts
@@ -14,6 +14,8 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
+/* eslint-disable @theia/localization-check */
+
import * as fs from '@theia/core/shared/fs-extra';
import * as path from 'path';
import { DebugAdapterExecutable, DebugAdapterContribution } from '../debug-model';
diff --git a/packages/editor/src/browser/editor-command.ts b/packages/editor/src/browser/editor-command.ts
index faabea14588b0..01497f9e60365 100644
--- a/packages/editor/src/browser/editor-command.ts
+++ b/packages/editor/src/browser/editor-command.ts
@@ -364,7 +364,7 @@ export class EditorCommandContribution implements CommandContribution {
return;
}
if (editor.document.dirty && isReopenWithEncoding) {
- this.messageService.info(nls.localize('theia/editor/reopenDirty', 'The file is dirty. Please save it first before reopening it with another encoding.'));
+ this.messageService.info(nls.localizeByDefault('The file is dirty. Please save it first before reopening it with another encoding.'));
return;
} else if (selectedFileEncoding.value) {
editor.setEncoding(selectedFileEncoding.value.id, isReopenWithEncoding ? EncodingMode.Decode : EncodingMode.Encode);
diff --git a/packages/editor/src/browser/editor-preferences.ts b/packages/editor/src/browser/editor-preferences.ts
index f80433f0b4f12..2bb9072534be5 100644
--- a/packages/editor/src/browser/editor-preferences.ts
+++ b/packages/editor/src/browser/editor-preferences.ts
@@ -685,7 +685,7 @@ const codeEditorPreferenceProperties = {
'default': false
},
'editor.highlightActiveIndentGuide': {
- 'description': nls.localize('theia/editor/highlightActiveIndentGuide', 'Controls whether the editor should highlight the active indent guide.'),
+ 'description': nls.localizeByDefault('Controls whether the editor should highlight the active indent guide.'),
'type': 'boolean',
'default': true
},
@@ -743,7 +743,7 @@ const codeEditorPreferenceProperties = {
'description': nls.localizeByDefault('Controls the display of line numbers.')
},
'editor.lineNumbersMinChars': {
- 'description': nls.localize('theia/editor/lineNumbersMinChars', 'Controls the line height. Use 0 to compute the line height from the font size.'),
+ 'description': nls.localizeByDefault('Controls the line height. Use 0 to compute the line height from the font size.'),
'type': 'integer',
'default': 5,
'minimum': 1,
@@ -900,15 +900,13 @@ const codeEditorPreferenceProperties = {
'editor.peekWidgetDefaultFocus': {
'enumDescriptions': [
nls.localizeByDefault('Focus the tree when opening peek'),
- nls.localizeByDefault('Focus the editor when opening peek'),
- nls.localizeByDefault('Focus the webview when opening peek')
+ nls.localizeByDefault('Focus the editor when opening peek')
],
'description': nls.localizeByDefault('Controls whether to focus the inline editor or the tree in the peek widget.'),
'type': 'string',
'enum': [
'tree',
- 'editor',
- 'webview'
+ 'editor'
],
'default': 'tree'
},
@@ -1399,7 +1397,7 @@ const codeEditorPreferenceProperties = {
'default': 'off'
},
'editor.tabIndex': {
- 'markdownDescription': nls.localize('theia/editor/tabIndex', 'Controls the wrapping column of the editor when `#editor.wordWrap#` is `wordWrapColumn` or `bounded`.'),
+ 'markdownDescription': nls.localizeByDefault('Controls the wrapping column of the editor when `#editor.wordWrap#` is `wordWrapColumn` or `bounded`.'),
'type': 'integer',
'default': 0,
'minimum': -1,
@@ -1407,9 +1405,9 @@ const codeEditorPreferenceProperties = {
},
'editor.unusualLineTerminators': {
'markdownEnumDescriptions': [
- nls.localize('unusualLineTerminators.auto', 'Unusual line terminators are automatically removed.'),
- nls.localize('unusualLineTerminators.off', 'Unusual line terminators are ignored.'),
- nls.localize('unusualLineTerminators.prompt', 'Unusual line terminators prompt to be removed.')
+ nls.localizeByDefault('Unusual line terminators are automatically removed.'),
+ nls.localizeByDefault('Unusual line terminators are ignored.'),
+ nls.localizeByDefault('Unusual line terminators prompt to be removed.')
],
'description': nls.localizeByDefault('Remove unusual line terminators that might cause problems.'),
'type': 'string',
diff --git a/packages/external-terminal/src/electron-browser/external-terminal-preference.ts b/packages/external-terminal/src/electron-browser/external-terminal-preference.ts
index ef94da7292974..2937f035d02d1 100644
--- a/packages/external-terminal/src/electron-browser/external-terminal-preference.ts
+++ b/packages/external-terminal/src/electron-browser/external-terminal-preference.ts
@@ -92,7 +92,7 @@ export async function getExternalTerminalSchema(externalTerminalService: Externa
},
'terminal.external.osxExec': {
type: 'string',
- description: nls.localizeByDefault('Customizes which terminal to run on macOS.'),
+ description: nls.localizeByDefault('Customizes which terminal application to run on macOS.'),
default: `${isOSX ? hostExec : 'Terminal.app'}`
},
'terminal.external.linuxExec': {
diff --git a/packages/file-search/src/browser/quick-file-open.ts b/packages/file-search/src/browser/quick-file-open.ts
index 6d934a579dd27..418fa4281ff51 100644
--- a/packages/file-search/src/browser/quick-file-open.ts
+++ b/packages/file-search/src/browser/quick-file-open.ts
@@ -19,7 +19,7 @@ import { OpenerService, KeybindingRegistry, QuickAccessRegistry, QuickAccessProv
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import URI from '@theia/core/lib/common/uri';
import { FileSearchService, WHITESPACE_QUERY_SEPARATOR } from '../common/file-search-service';
-import { CancellationToken, Command, MAX_SAFE_INTEGER } from '@theia/core/lib/common';
+import { CancellationToken, Command, nls, MAX_SAFE_INTEGER } from '@theia/core/lib/common';
import { LabelProvider } from '@theia/core/lib/browser/label-provider';
import { NavigationLocationService } from '@theia/editor/lib/browser/navigation/navigation-location-service';
import * as fuzzy from '@theia/core/shared/fuzzy';
@@ -328,10 +328,10 @@ export class QuickFileOpenService implements QuickAccessProvider {
}
private getPlaceHolder(): string {
- let placeholder = 'File name to search (append : to go to line).';
+ let placeholder = nls.localizeByDefault('Search files by name (append {0} to go to line or {1} to go to symbol)', ':', '@');
const keybinding = this.getKeyCommand();
if (keybinding) {
- placeholder += ` (Press ${keybinding} to show/hide ignored files)`;
+ placeholder += nls.localize('theia/file-search/toggleIgnoredFiles', ' (Press {0} to show/hide ignored files)', keybinding);
}
return placeholder;
}
diff --git a/packages/filesystem/src/browser/file-upload-service.ts b/packages/filesystem/src/browser/file-upload-service.ts
index 5ec856dc2f42f..bcf0576f72b49 100644
--- a/packages/filesystem/src/browser/file-upload-service.ts
+++ b/packages/filesystem/src/browser/file-upload-service.ts
@@ -245,9 +245,9 @@ export class FileUploadService {
protected async confirmOverwrite(fileUri: URI): Promise {
const dialog = new ConfirmDialog({
- title: nls.localizeByDefault('Replace file'),
- msg: nls.localizeByDefault('File "{0}" already exists in the destination folder. Do you want to replace it?', fileUri.path.base),
- ok: nls.localizeByDefault('Replace file'),
+ title: nls.localizeByDefault('Replace'),
+ msg: nls.localizeByDefault("A file or folder with the name '{0}' already exists in the destination folder. Do you want to replace it?", fileUri.path.base),
+ ok: nls.localizeByDefault('Replace'),
cancel: Dialog.CANCEL
});
return !!await dialog.open();
diff --git a/packages/getting-started/src/browser/getting-started-widget.tsx b/packages/getting-started/src/browser/getting-started-widget.tsx
index b331ee005a9c1..2f3a9c221d447 100644
--- a/packages/getting-started/src/browser/getting-started-widget.tsx
+++ b/packages/getting-started/src/browser/getting-started-widget.tsx
@@ -245,7 +245,7 @@ export class GettingStartedWidget extends ReactWidget {
{nls.localizeByDefault('Recent')}
- {items.length > 0 ? content : {nls.localizeByDefault('No Recent Workspaces')}
}
+ {items.length > 0 ? content : {nls.localizeByDefault('No recent folders')}
}
{more}
;
}
diff --git a/packages/git/src/browser/git-contribution.ts b/packages/git/src/browser/git-contribution.ts
index b508290d14b30..13cb7f5970bd6 100644
--- a/packages/git/src/browser/git-contribution.ts
+++ b/packages/git/src/browser/git-contribution.ts
@@ -897,7 +897,7 @@ export class GitContribution implements CommandContribution, MenuContribution, T
} catch (e) {
scmRepository.input.issue = {
type: ScmInputIssueType.Warning,
- message: nls.localizeByDefault('Make sure you configure your \'user.name\' and \'user.email\' in git.')
+ message: nls.localize('theia/git/missingUserInfo', 'Make sure you configure your \'user.name\' and \'user.email\' in git.')
};
}
diff --git a/packages/git/src/browser/git-quick-open-service.ts b/packages/git/src/browser/git-quick-open-service.ts
index 11ef547f80e1b..7d5a848ab1366 100644
--- a/packages/git/src/browser/git-quick-open-service.ts
+++ b/packages/git/src/browser/git-quick-open-service.ts
@@ -22,6 +22,7 @@ import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service
import { GitErrorHandler } from './git-error-handler';
import { ProgressService } from '@theia/core/lib/common/progress-service';
import URI from '@theia/core/lib/common/uri';
+import { nls } from '@theia/core/lib/common/nls';
import { LabelProvider, QuickInputService, QuickPick, QuickPickItem } from '@theia/core/lib/browser';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
import { FileStat } from '@theia/filesystem/lib/common/files';
@@ -67,9 +68,14 @@ export class GitQuickOpenService {
return repo.localUri;
}
- this.quickInputService?.showQuickPick([new GitQuickPickItem('Please provide a Git repository location. Press \'Enter\' to confirm or \'Escape\' to cancel.')],
+ this.quickInputService?.showQuickPick(
+ [
+ new GitQuickPickItem(
+ nls.localize('theia/git/cloneQuickInputLabel', 'Please provide a Git repository location. Press \'Enter\' to confirm or \'Escape\' to cancel.')
+ )
+ ],
{
- placeholder: 'Git repository location:',
+ placeholder: nls.localize('vscode.git/dist/commands/selectFolder', 'Select Repository Location'),
onDidChangeValue: (quickPick: QuickPick, filter: string) => this.query(quickPick, filter, folder)
});
});
@@ -81,22 +87,31 @@ export class GitQuickOpenService {
const { git, buildDefaultProjectPath, gitErrorHandler, wrapWithProgress } = this;
try {
- const suffix = "Press 'Enter' to confirm or 'Escape' to cancel.";
-
if (filter === undefined || filter.length === 0) {
- quickPick.items = [new GitQuickPickItem(`Please provide a Git repository location. ${suffix}`)];
+ quickPick.items = [
+ new GitQuickPickItem(
+ nls.localize('theia/git/cloneQuickInputLabel', 'Please provide a Git repository location. Press \'Enter\' to confirm or \'Escape\' to cancel.')
+ )
+ ];
} else {
- quickPick.items = [new GitQuickPickItem(`Clone the Git repository: ${filter}. ${suffix}`,
- wrapWithProgress(async () => {
- try {
- await git.clone(filter, { localUri: await buildDefaultProjectPath(folder, filter) });
- } catch (error) {
- gitErrorHandler.handleError(error);
- }
- }))];
+ quickPick.items = [
+ new GitQuickPickItem(
+ nls.localize(
+ 'theia/git/cloneRepository',
+ 'Clone the Git repository: {0}. Press \'Enter\' to confirm or \'Escape\' to cancel.',
+ filter
+ ),
+ wrapWithProgress(async () => {
+ try {
+ await git.clone(filter, { localUri: await buildDefaultProjectPath(folder, filter) });
+ } catch (error) {
+ gitErrorHandler.handleError(error);
+ }
+ }))
+ ];
}
} catch (err) {
- quickPick.items = [new GitQuickPickItem(`$(error) Error: ${err.message}`)];
+ quickPick.items = [new GitQuickPickItem('$(error) ' + nls.localizeByDefault('Error: {0}', err.message))];
console.error(err);
} finally {
quickPick.busy = false;
@@ -132,7 +147,7 @@ export class GitQuickOpenService {
}
};
const items = remotes.map(remote => new GitQuickPickItem(remote.name, execute, remote, remote.fetch));
- this.quickInputService?.showQuickPick(items, { placeholder: 'Pick a remote to fetch from:' });
+ this.quickInputService?.showQuickPick(items, { placeholder: nls.localize('theia/git/fetchPickRemote', 'Pick a remote to fetch from:') });
});
}
@@ -174,7 +189,9 @@ export class GitQuickOpenService {
};
const items = remotes.map(remote => new GitQuickPickItem(remote.name, execute, remote, remote.push));
const branchName = currentBranch ? `'${currentBranch.name}' ` : '';
- this.quickInputService?.showQuickPick(items, { placeholder: `Pick a remote to push the currently active branch ${branchName}to:` });
+ this.quickInputService?.showQuickPick(items, {
+ placeholder: nls.localize('vscode.git/dist/commands/pick remote', "Pick a remote to publish the branch '{0}' to:", branchName)
+ });
});
}
@@ -209,11 +226,15 @@ export class GitQuickOpenService {
.filter(branch => (branch.name || '').startsWith(`${remoteItem.label}/`))
.map(branch => new GitQuickPickItem(branch.name, executeBranch, branch));
- this.quickInputService?.showQuickPick(branchItems, { placeholder: 'Select the branch to pull the changes from:' });
+ this.quickInputService?.showQuickPick(branchItems, {
+ placeholder: nls.localize('vscode.git/dist/commands/pick branch pull', 'Pick a branch to pull from')
+ });
}
};
const remoteItems = remotes.map(remote => new GitQuickPickItem(remote.name, executeRemote, remote, remote.fetch));
- this.quickInputService?.showQuickPick(remoteItems, { placeholder: 'Pick a remote to pull the branch from:' });
+ this.quickInputService?.showQuickPick(remoteItems, {
+ placeholder: nls.localize('vscode.git/dist/commands/pick remote pull repo', 'Pick a remote to pull the branch from')
+ });
});
}
@@ -233,7 +254,12 @@ export class GitQuickOpenService {
};
const items = branches.map(branch => new GitQuickPickItem(branch.name, execute, branch));
const branchName = currentBranch ? `'${currentBranch.name}' ` : '';
- this.quickInputService?.showQuickPick(items, { placeholder: `Pick a branch to merge into the currently active ${branchName}branch:` });
+ this.quickInputService?.showQuickPick(
+ items,
+ {
+ placeholder: nls.localize('theia/git/mergeQuickPickPlaceholder', 'Pick a branch to merge into the currently active {0} branch:', branchName)
+ }
+ );
});
}
@@ -260,18 +286,26 @@ export class GitQuickOpenService {
const items = branches.map(branch => new GitQuickPickItem(
branch.type === BranchType.Remote ? branch.name : branch.nameWithoutRemote, switchBranch,
branch,
- branch.type === BranchType.Remote ? 'Remote branch at' : '' + `${(branch.tip.sha.length > 8 ? ` ${branch.tip.sha.slice(0, 7)}` : '')}`));
+ branch.type === BranchType.Remote
+ ? nls.localize('vscode.git/dist/commands/remote branch at', 'Remote branch at {0}', (branch.tip.sha.length > 8 ? ` ${branch.tip.sha.slice(0, 7)}` : ''))
+ : (branch.tip.sha.length > 8 ? ` ${branch.tip.sha.slice(0, 7)}` : '')));
const createBranchItem = async () => {
const { git, gitErrorHandler, wrapWithProgress } = this;
const getItems = (lookFor?: string) => {
- const suffix = "Press 'Enter' to confirm or 'Escape' to cancel.";
const dynamicItems: GitQuickPickItem[] = [];
if (lookFor === undefined || lookFor.length === 0) {
- dynamicItems.push(new GitQuickPickItem(`Please provide a branch name. ${suffix}`, () => { }));
+ dynamicItems.push(new GitQuickPickItem(
+ nls.localize('theia/git/checkoutProvideBranchName', 'Please provide a branch name. '),
+ () => { })
+ );
} else {
dynamicItems.push(new GitQuickPickItem(
- `Create a new local branch with name: ${lookFor}. ${suffix}`,
+ nls.localize(
+ 'theia/git/checkoutCreateLocalBranchWithName',
+ "Create a new local branch with name: {0}. Press 'Enter' to confirm or 'Escape' to cancel.",
+ lookFor
+ ),
wrapWithProgress(async () => {
try {
await git.branch(repository, { toCreate: lookFor });
@@ -285,15 +319,15 @@ export class GitQuickOpenService {
return dynamicItems;
};
this.quickInputService?.showQuickPick(getItems(), {
- placeholder: 'The name of the branch:',
+ placeholder: nls.localize('vscode.git/dist/commands/branch name', 'Branch name'),
onDidChangeValue: (quickPick: QuickPick, filter: string) => {
quickPick.items = getItems(filter);
}
});
};
- items.unshift(new GitQuickPickItem('Create new branch...', createBranchItem));
- this.quickInputService?.showQuickPick(items, { placeholder: 'Select a ref to checkout or create a new local branch:' });
+ items.unshift(new GitQuickPickItem(nls.localize('vscode.git/dist/commands/create branch', 'Create new branch...'), createBranchItem));
+ this.quickInputService?.showQuickPick(items, { placeholder: nls.localize('theia/git/checkoutSelectRef', 'Select a ref to checkout or create a new local branch:') });
});
}
@@ -311,29 +345,32 @@ export class GitQuickOpenService {
const tagItems = tags.map(tag => new GitQuickPickItem(tag.name, execute, tag));
this.quickInputService?.showQuickPick([...branchItems, ...tagItems],
- { placeholder: `Pick a branch or tag to compare with the currently active ${branchName} branch:` });
+ { placeholder: nls.localize('theia/git/compareWithBranchOrTag', 'Pick a branch or tag to compare with the currently active {0} branch:', branchName) });
});
}
async commitMessageForAmend(): Promise {
const repository = this.getRepository();
if (!repository) {
- throw new Error('No repositories were selected.');
+ throw new Error(nls.localize('theia/git/noRepositoriesSelected', 'No repositories were selected.'));
}
return this.withProgress(async () => {
const lastMessage = (await this.git.exec(repository, ['log', '--format=%B', '-n', '1'])).stdout.trim();
if (lastMessage.length === 0) {
- throw new Error(`Repository ${repository.localUri} is not yet initialized.`);
+ throw new Error(nls.localize('theia/git/repositoryNotInitialized', 'Repository {0} is not yet initialized.', repository.localUri));
}
const message = lastMessage.replace(/[\r\n]+/g, ' ');
const result = await new Promise(async (resolve, reject) => {
const getItems = (lookFor?: string) => {
const items = [];
if (!lookFor) {
- const label = "To reuse the last commit message, press 'Enter' or 'Escape' to cancel.";
+ const label = nls.localize('theia/git/amendReuseMessag', "To reuse the last commit message, press 'Enter' or 'Escape' to cancel.");
items.push(new GitQuickPickItem(label, () => resolve(lastMessage), label));
} else {
- items.push(new GitQuickPickItem("Rewrite previous commit message. Press 'Enter' to confirm or 'Escape' to cancel.", () => resolve(lookFor)));
+ items.push(new GitQuickPickItem(
+ nls.localize('theia/git/amendRewrite', "Rewrite previous commit message. Press 'Enter' to confirm or 'Escape' to cancel."),
+ () => resolve(lookFor))
+ );
}
return items;
};
@@ -357,18 +394,22 @@ export class GitQuickOpenService {
});
const getItems = (lookFor?: string) => {
const items = [];
- const suffix = "Press 'Enter' to confirm or 'Escape' to cancel.";
if (lookFor === undefined || lookFor.length === 0) {
- items.push(new GitQuickPickItem(`Stash changes. ${suffix}`, () => doStash('')));
+ items.push(new GitQuickPickItem(nls.localize('theia/git/stashChanges', "Stash changes. Press 'Enter' to confirm or 'Escape' to cancel."), () => doStash('')));
} else {
- items.push(new GitQuickPickItem(`Stash changes with message: ${lookFor}. ${suffix}`, () => doStash(lookFor)));
+ items.push(new GitQuickPickItem(
+ nls.localize('theia/git/stashChangesWithMessage', "Stash changes with message: {0}. Press 'Enter' to confirm or 'Escape' to cancel.", lookFor),
+ () => doStash(lookFor))
+ );
}
return items;
};
const updateItems = (quickPick: QuickPick, filter: string) => {
quickPick.items = getItems(filter);
};
- this.quickInputService?.showQuickPick(getItems(), { placeholder: 'Stash message', onDidChangeValue: updateItems });
+ this.quickInputService?.showQuickPick(getItems(), {
+ placeholder: nls.localize('vscode.git/dist/commands/stash message', 'Stash message'), onDidChangeValue: updateItems
+ });
});
}
@@ -397,11 +438,11 @@ export class GitQuickOpenService {
}
async applyStash(): Promise {
- this.doStashAction('apply', 'Select a stash to \'apply\'.');
+ this.doStashAction('apply', nls.localize('vscode.git/dist/commands/pick stash to apply', 'Pick a stash to apply'));
}
async popStash(): Promise {
- this.doStashAction('pop', 'Select a stash to \'pop\'.');
+ this.doStashAction('pop', nls.localize('pick stash to pop', 'Pick a stash to pop'));
}
async dropStash(): Promise {
@@ -409,17 +450,11 @@ export class GitQuickOpenService {
if (!repository) {
return;
}
- this.doStashAction('drop', 'Select a stash entry to remove it from the list of stash entries.',
- async () => {
- const list = await this.git.stash(repository, { action: 'list' });
- let listString = '';
- list.forEach(stashEntry => {
- listString += stashEntry.message + '\n';
- });
- return `Stash successfully removed.
- There ${list.length === 1 ? 'is' : 'are'} ${list.length || 'no'} more entry in stash list.
- \n${listString}`;
- });
+ this.doStashAction(
+ 'drop',
+ nls.localize('vscode.git/dist/commands/pick stash to drop', 'Pick a stash to drop'),
+ async () => nls.localize('theia/git/dropStashMessage', 'Stash successfully removed.')
+ );
}
async applyLatestStash(): Promise {
@@ -458,7 +493,7 @@ export class GitQuickOpenService {
const wsRoots = await this.workspaceService.roots;
if (wsRoots && wsRoots.length > 1) {
const items = wsRoots.map>(root => this.toRepositoryPathQuickOpenItem(root));
- this.quickInputService?.showQuickPick(items, { placeholder: 'Choose workspace root to initialize git repo in' });
+ this.quickInputService?.showQuickPick(items, { placeholder: nls.localize('vscode.git/dist/commands/init', 'Pick workspace folder to initialize git repo in') });
} else {
const rootUri = wsRoots[0].resource;
this.doInitRepository(rootUri.toString());
diff --git a/packages/git/src/common/git-model.ts b/packages/git/src/common/git-model.ts
index 9cdbb96edf808..d550c79fa4fff 100644
--- a/packages/git/src/common/git-model.ts
+++ b/packages/git/src/common/git-model.ts
@@ -108,6 +108,7 @@ export namespace GitFileStatus {
case GitFileStatus.New: return !!staged ? nls.localize('theia/git/added', 'Added') : nls.localize('theia/git/unstaged', 'Unstaged');
case GitFileStatus.Renamed: return nls.localize('theia/git/renamed', 'Renamed');
case GitFileStatus.Copied: return nls.localize('theia/git/copied', 'Copied');
+ // eslint-disable-next-line @theia/localization-check
case GitFileStatus.Modified: return nls.localize('vscode.git/repository/modified', 'Modified');
case GitFileStatus.Deleted: return nls.localize('vscode.git/repository/deleted', 'Deleted');
case GitFileStatus.Conflicted: return nls.localize('theia/git/conflicted', 'Conflicted');
diff --git a/packages/outline-view/src/browser/outline-view-widget.tsx b/packages/outline-view/src/browser/outline-view-widget.tsx
index b0d7fe09733d7..6fdbf649ad111 100644
--- a/packages/outline-view/src/browser/outline-view-widget.tsx
+++ b/packages/outline-view/src/browser/outline-view-widget.tsx
@@ -180,7 +180,7 @@ export class OutlineViewWidget extends TreeWidget {
protected renderTree(model: TreeModel): React.ReactNode {
if (CompositeTreeNode.is(this.model.root) && !this.model.root.children.length) {
- return {nls.localizeByDefault('No outline information available.')}
;
+ return {nls.localizeByDefault('The active editor cannot provide outline information.')}
;
}
return super.renderTree(model);
}
diff --git a/packages/plugin-ext/src/hosted/node/scanners/scanner-theia.ts b/packages/plugin-ext/src/hosted/node/scanners/scanner-theia.ts
index 5fb024c96aaa9..03f776ef19a70 100644
--- a/packages/plugin-ext/src/hosted/node/scanners/scanner-theia.ts
+++ b/packages/plugin-ext/src/hosted/node/scanners/scanner-theia.ts
@@ -14,6 +14,8 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/
+/* eslint-disable @theia/localization-check */
+
import { inject, injectable } from '@theia/core/shared/inversify';
import {
AutoClosingPair,
diff --git a/packages/plugin-ext/src/main/browser/authentication-main.ts b/packages/plugin-ext/src/main/browser/authentication-main.ts
index 3b34515e8a1a8..e4646b70c6a1b 100644
--- a/packages/plugin-ext/src/main/browser/authentication-main.ts
+++ b/packages/plugin-ext/src/main/browser/authentication-main.ts
@@ -210,7 +210,7 @@ export class AuthenticationMainImpl implements AuthenticationMain {
protected async loginPrompt(providerName: string, extensionName: string, recreatingSession: boolean, _detail?: string): Promise {
const message = recreatingSession
- ? nls.localizeByDefault("The extension '{0}' wants you to sign in again using {1}.", extensionName, providerName)
+ ? nls.localize('theia/plugin-ext/signInAgain', "The extension '{0}' wants you to sign in again using {1}.", extensionName, providerName)
: nls.localizeByDefault("The extension '{0}' wants to sign in using {1}.", extensionName, providerName);
const choice = await this.messageService.info(message, 'Allow', 'Cancel');
return choice === 'Allow';
@@ -306,9 +306,9 @@ export class AuthenticationProviderImpl implements AuthenticationProvider {
const accountUsages = await readAccountUsages(this.storageService, this.id, accountName);
const sessionsForAccount = this.accounts.get(accountName);
const result = await this.messageService.info(accountUsages.length
- ? nls.localizeByDefault("The account '{0}' has been used by: \n\n{1}\n\n Sign out from these extensions?", accountName,
+ ? nls.localizeByDefault('The account {0} has been used by: \n\n{1}\n\n Sign out of these features?', accountName,
accountUsages.map(usage => usage.extensionName).join(', '))
- : nls.localizeByDefault("Sign out of '{0}'?", accountName),
+ : nls.localizeByDefault('Sign out of {0}?', accountName),
nls.localizeByDefault('Sign Out'),
Dialog.CANCEL);
diff --git a/packages/preferences/src/browser/preference-transaction-manager.ts b/packages/preferences/src/browser/preference-transaction-manager.ts
index 5ca91e802612a..9bf8021bf2c14 100644
--- a/packages/preferences/src/browser/preference-transaction-manager.ts
+++ b/packages/preferences/src/browser/preference-transaction-manager.ts
@@ -190,6 +190,7 @@ export class PreferenceTransaction extends Transaction<[string, string[], unknow
const saveAndRetry = nls.localizeByDefault('Save and Retry');
const open = nls.localizeByDefault('Open File');
const msg = await this.messageService.error(
+ // eslint-disable-next-line @theia/localization-check
nls.localizeByDefault('Unable to write into {0} settings because the file has unsaved changes. Please save the {0} settings file first and then try again.',
nls.localizeByDefault(PreferenceScope[this.context.getScope()].toLocaleLowerCase())
),
diff --git a/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx b/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx
index 6aa1774e71be4..61fdacf1c6561 100644
--- a/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx
+++ b/packages/property-view/src/browser/resource-property-view/resource-property-view-tree-widget.tsx
@@ -97,12 +97,12 @@ export class ResourcePropertyViewTreeWidget extends TreeWidget implements Proper
this.propertiesTree.set('info', infoNode);
infoNode.children.push(this.createResultLineNode('isDirectory', nls.localize('theia/property-view/directory', 'Directory'), fileStatObject.isDirectory, infoNode));
- infoNode.children.push(this.createResultLineNode('isFile', nls.localize('theia/property-view/file', 'File'), fileStatObject.isFile, infoNode));
+ infoNode.children.push(this.createResultLineNode('isFile', nls.localizeByDefault('File'), fileStatObject.isFile, infoNode));
infoNode.children.push(this.createResultLineNode('isSymbolicLink', nls.localize('theia/property-view/symbolicLink', 'Symbolic link'),
fileStatObject.isSymbolicLink, infoNode));
infoNode.children.push(this.createResultLineNode('location', nls.localize('theia/property-view/location', 'Location'),
this.getLocationString(fileStatObject), infoNode));
- infoNode.children.push(this.createResultLineNode('name', nls.localize('theia/property-view/name', 'Name'), this.getFileName(fileStatObject), infoNode));
+ infoNode.children.push(this.createResultLineNode('name', nls.localizeByDefault('Name'), this.getFileName(fileStatObject), infoNode));
infoNode.children.push(this.createResultLineNode('path', nls.localize('theia/property-view/path', 'Path'), this.getFilePath(fileStatObject), infoNode));
infoNode.children.push(this.createResultLineNode('lastModification', nls.localize('theia/property-view/lastModified', 'Last modified'),
this.getLastModificationString(fileStatObject), infoNode));
@@ -134,7 +134,7 @@ export class ResourcePropertyViewTreeWidget extends TreeWidget implements Proper
}
protected getSizeString(fileStat: FileStat): string {
- return fileStat.size ? nls.localizeByDefault('{0} B', fileStat.size.toString()) : '';
+ return fileStat.size ? nls.localizeByDefault('{0}B', fileStat.size.toString()) : '';
}
/*
diff --git a/packages/scm-extra/src/browser/history/scm-history-widget.tsx b/packages/scm-extra/src/browser/history/scm-history-widget.tsx
index 0625cfb89df6c..ead01a3eeb184 100644
--- a/packages/scm-extra/src/browser/history/scm-history-widget.tsx
+++ b/packages/scm-extra/src/browser/history/scm-history-widget.tsx
@@ -264,7 +264,7 @@ export class ScmHistoryWidget extends ScmNavigableListWidget
} else {
this.status = {
state: 'error',
- errorMessage: {nls.localizeByDefault('There is no repository selected in this workspace.')}
+ errorMessage: {nls.localizeByDefault('No source control providers registered.')}
};
}
}
diff --git a/packages/search-in-workspace/src/browser/search-in-workspace-factory.ts b/packages/search-in-workspace/src/browser/search-in-workspace-factory.ts
index cb15895a45be1..2a79cc9f1bc8f 100644
--- a/packages/search-in-workspace/src/browser/search-in-workspace-factory.ts
+++ b/packages/search-in-workspace/src/browser/search-in-workspace-factory.ts
@@ -23,10 +23,11 @@ import {
WidgetManager
} from '@theia/core/lib/browser';
import { SearchInWorkspaceWidget } from './search-in-workspace-widget';
+import { nls } from '@theia/core/lib/common/nls';
export const SEARCH_VIEW_CONTAINER_ID = 'search-view-container';
export const SEARCH_VIEW_CONTAINER_TITLE_OPTIONS: ViewContainerTitleOptions = {
- label: 'Search',
+ label: nls.localizeByDefault('Search'),
iconClass: codicon('search'),
closeable: true
};
diff --git a/packages/search-in-workspace/src/browser/search-in-workspace-frontend-contribution.ts b/packages/search-in-workspace/src/browser/search-in-workspace-frontend-contribution.ts
index f85abf363b78c..7ff2956f9cfbc 100644
--- a/packages/search-in-workspace/src/browser/search-in-workspace-frontend-contribution.ts
+++ b/packages/search-in-workspace/src/browser/search-in-workspace-frontend-contribution.ts
@@ -50,10 +50,10 @@ export namespace SearchInWorkspaceCommands {
category: SEARCH_CATEGORY,
label: 'Replace in Files'
});
- export const FIND_IN_FOLDER = Command.toLocalizedCommand({
+ export const FIND_IN_FOLDER = Command.toDefaultLocalizedCommand({
id: 'search-in-workspace.in-folder',
category: SEARCH_CATEGORY,
- label: 'Find in Folder'
+ label: 'Find in Folder...'
});
export const REFRESH_RESULTS = Command.toDefaultLocalizedCommand({
id: 'search-in-workspace.refresh',
diff --git a/packages/search-in-workspace/src/browser/search-in-workspace-result-tree-widget.tsx b/packages/search-in-workspace/src/browser/search-in-workspace-result-tree-widget.tsx
index 1894c6ac33e74..0686bcbeb6751 100644
--- a/packages/search-in-workspace/src/browser/search-in-workspace-result-tree-widget.tsx
+++ b/packages/search-in-workspace/src/browser/search-in-workspace-result-tree-widget.tsx
@@ -125,7 +125,7 @@ export class SearchInWorkspaceResultTreeWidget extends TreeWidget {
protected readonly toDisposeOnActiveEditorChanged = new DisposableCollection();
// The default root name to add external search results in the case that a workspace is opened.
- protected readonly defaultRootName = nls.localize('theia/searchResultsView/searchFolderMatch.other.label', 'Other files');
+ protected readonly defaultRootName = nls.localizeByDefault('Other files');
protected forceVisibleRootNode = false;
protected appliedDecorations = new Map();
diff --git a/packages/search-in-workspace/src/browser/search-in-workspace-widget.tsx b/packages/search-in-workspace/src/browser/search-in-workspace-widget.tsx
index 12cc652b40976..07d44c802ae3a 100644
--- a/packages/search-in-workspace/src/browser/search-in-workspace-widget.tsx
+++ b/packages/search-in-workspace/src/browser/search-in-workspace-widget.tsx
@@ -686,7 +686,7 @@ export class SearchInWorkspaceWidget extends BaseWidget implements StatefulWidge
message = nls.localizeByDefault("No results found excluding '{0}' - ",
this.searchInWorkspaceOptions.exclude!.toString());
} else {
- message = nls.localizeByDefault('No results found. - ');
+ message = nls.localizeByDefault('No results found') + ' - ';
}
// We have to trim here as vscode will always add a trailing " - " string
return message.substring(0, message.length - 2).trim();
diff --git a/packages/terminal/src/browser/terminal-preferences.ts b/packages/terminal/src/browser/terminal-preferences.ts
index e21438909d029..acfe89c46ad6e 100644
--- a/packages/terminal/src/browser/terminal-preferences.ts
+++ b/packages/terminal/src/browser/terminal-preferences.ts
@@ -143,12 +143,13 @@ export const TerminalConfigSchema: PreferenceSchema = {
},
'terminal.integrated.confirmOnExit': {
type: 'string',
- description: nls.localizeByDefault('Controls whether to confirm when the window closes if there are active terminal sessions'),
+ // nls-todo: Will be included by default in VSCode version 1.58.0
+ description: nls.localize('theia/terminal/confirmClose', 'Controls whether to confirm when the window closes if there are active terminal sessions.'),
enum: ['never', 'always', 'hasChildProcesses'],
enumDescriptions: [
- nls.localizeByDefault('Never confirm.'),
- nls.localizeByDefault('Always confirm if there are terminals.'),
- nls.localizeByDefault('Confirm if there are any terminals that have child processes.'),
+ nls.localize('theia/terminal/confirmCloseNever', 'Never confirm.'),
+ nls.localize('theia/terminal/confirmCloseAlways', 'Always confirm if there are terminals.'),
+ nls.localize('theia/terminal/confirmCloseChildren', 'Confirm if there are any terminals that have child processes.'),
],
default: 'never'
}
diff --git a/packages/vsx-registry/src/browser/vsx-extension-commands.ts b/packages/vsx-registry/src/browser/vsx-extension-commands.ts
index 02f7e6dba60ae..e4f345a8d5f03 100644
--- a/packages/vsx-registry/src/browser/vsx-extension-commands.ts
+++ b/packages/vsx-registry/src/browser/vsx-extension-commands.ts
@@ -33,8 +33,8 @@ export namespace VSXExtensionsCommands {
category: nls.localizeByDefault(EXTENSIONS_CATEGORY),
originalCategory: EXTENSIONS_CATEGORY,
originalLabel: 'Install from VSIX...',
- label: nls.localize('theia/vsx-registry/installFromVSIX', 'Install from VSIX') + '...',
- dialogLabel: nls.localize('theia/vsx-registry/installFromVSIX', 'Install from VSIX')
+ label: nls.localizeByDefault('Install from VSIX') + '...',
+ dialogLabel: nls.localizeByDefault('Install from VSIX')
};
export const COPY: Command = {
id: 'vsxExtensions.copy'
diff --git a/packages/workspace/src/browser/workspace-commands.ts b/packages/workspace/src/browser/workspace-commands.ts
index c318c00197b0c..4c5ac88107f14 100644
--- a/packages/workspace/src/browser/workspace-commands.ts
+++ b/packages/workspace/src/browser/workspace-commands.ts
@@ -421,21 +421,21 @@ export class WorkspaceCommandContribution implements CommandContribution {
}
// do not allow recursive rename
if (!allowNested && !validFilename(name)) {
- return nls.localizeByDefault('Invalid file or folder name');
+ return nls.localizeByDefault('The name **{0}** is not valid as a file or folder name. Please choose a different name.');
}
if (name.startsWith('/')) {
- return nls.localizeByDefault('Absolute paths or names that starts with / are not allowed');
+ return nls.localizeByDefault('A file or folder name cannot start with a slash.');
} else if (name.startsWith(' ') || name.endsWith(' ')) {
- return nls.localizeByDefault('Names with leading or trailing whitespaces are not allowed');
+ return nls.localizeByDefault('Leading or trailing whitespace detected in file or folder name.');
}
// check and validate each sub-paths
if (name.split(/[\\/]/).some(file => !file || !validFilename(file) || /^\s+$/.test(file))) {
- return nls.localizeByDefault('The name "{0}" is not a valid file or folder name.', this.trimFileName(name));
+ return nls.localizeByDefault('\'{0}\' is not a valid file name', this.trimFileName(name));
}
const childUri = parent.resource.resolve(name);
const exists = await this.fileService.exists(childUri);
if (exists) {
- return nls.localizeByDefault('A file or folder "{0}" already exists at this location.', this.trimFileName(name));
+ return nls.localizeByDefault('A file or folder **{0}** already exists at this location. Please choose a different name.', this.trimFileName(name));
}
return '';
}
diff --git a/packages/workspace/src/browser/workspace-frontend-contribution.ts b/packages/workspace/src/browser/workspace-frontend-contribution.ts
index 3ac0c30a52220..88a47ce95edc4 100644
--- a/packages/workspace/src/browser/workspace-frontend-contribution.ts
+++ b/packages/workspace/src/browser/workspace-frontend-contribution.ts
@@ -568,7 +568,7 @@ export class WorkspaceFrontendContribution implements CommandContribution, Keybi
// Prompt users for confirmation before overwriting.
const confirmed = await new ConfirmDialog({
title: nls.localizeByDefault('Overwrite'),
- msg: nls.localizeByDefault('Do you really want to overwrite "{0}"?', uri.toString())
+ msg: nls.localizeByDefault('{0} already exists. Are you sure you want to overwrite it?', uri.toString())
}).open();
return !!confirmed;
}
diff --git a/packages/workspace/src/browser/workspace-trust-preferences.ts b/packages/workspace/src/browser/workspace-trust-preferences.ts
index cd1708a65f941..d7a4f2c6e1e96 100644
--- a/packages/workspace/src/browser/workspace-trust-preferences.ts
+++ b/packages/workspace/src/browser/workspace-trust-preferences.ts
@@ -39,7 +39,8 @@ export const workspaceTrustPreferenceSchema: PreferenceSchema = {
defaultValue: true
},
[WORKSPACE_TRUST_STARTUP_PROMPT]: {
- description: nls.localizeByDefault('Controls when the startup prompt to trust a workspace is shown.'),
+ // nls-todo: This string will be available in vscode starting from API version 1.57.0
+ description: nls.localize('theia/workspace/trustPrompt', 'Controls when the startup prompt to trust a workspace is shown.'),
enum: Object.values(WorkspaceTrustPrompt),
defaultValue: WorkspaceTrustPrompt.ALWAYS
},
diff --git a/yarn.lock b/yarn.lock
index fd56401ec0061..e4907d6906959 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6995,6 +6995,11 @@ jpeg-js@^0.4.2:
resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.3.tgz#6158e09f1983ad773813704be80680550eff977b"
integrity sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==
+js-levenshtein@^1.1.6:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d"
+ integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==
+
"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"